[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference 7.286::atarist

Title:Atari ST, TT, & Falcon
Notice:Please read note 1.0 and its replies before posting!
Moderator:FUNYET::ANDERSON
Created:Mon Apr 04 1988
Last Modified:Tue May 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:1433
Total number of notes:10312

1286.0. "TSR programming, anyone?" by KERNEL::IMBIERSKI (The sound of electric wood) Wed May 20 1992 17:02

    I've  recently been trying my hand at some  interrupt  programming,  in 
    particular trying to hang a TSR routine from the queue of VBL interrupt 
    routines.  The  book I have does not list what restrictions  there  are 
    when writing such routines.  Is there anyone in here who could  explain 
    why my program doesn't work properly??

    All  the code tries to do is search down the list of vbl entries  until 
    it finds a blank slot. Then it loads the blank slot with the address of 
    my  TSR  routine.  From here on,  the TSR should be called 50  times  a 
    second or so (on a UK colour system).  I'm pretty sure this part  works 
    OK.

    My  TSR  routine simply increments a byte  counter.  When  the  counter 
    overflows it outputs a beep to the monitor via the BIOS conout routine. 
    This  means  that  a beep should be heard every  256/50  seconds  which 
    equals about 5 seconds.

    When I run the program,  it appears to work. The display returns to the 
    desktop and a beep sounds about once every 5 seconds.  When I load  any 
    GEM application,  the beeping continues.  However,  if I then place the 
    mouse on the menu bar so as to make a menu drop down, I get 3 bombs and 
    a hang.

    Is there anything I'm doing that's illegal??

    The assembler code follows.  It includes a module which simply  defines 
    all  the gemdos system routines.  This module is copied after the  main 
    code.

    Tony I

PROGRAM:

; **********************************************************************
; *  This is an example program which sets up a routine to be executed by 
; *  the 20 ms VBL interrupt. The routine counts up to 256 then outputs
; *  a beep (ctrl/g or ascii 7)  
; *
; *
        jmp start
;
progname:       dc.b    "BEEPTSR",0
version:        dc.b    "V1.0",0
verdate:        dc.b    "19-MAY-1991",0
;
; *
; *
; **********************************************************************
; 
;  CONSTANT AND DATA DEFS
;
        NOLIST
        include osbind.equ
        LIST 
vblqueue        = $456
nvbls           = $454
        
        EVEN

mnovec: dc.b    "No spare VBL vectors!",0
count:  dc.b    0
flag:   dc.b    0

        EVEN
start:
        EVEN
        move.l  #vblset,-(sp)           ; address of supervisor mode rtn
        move.w  #supexec,-(sp)          ; execute super rtn ...
        trap    #xbios
        addq.l  #6,sp
        tst.l   d1                      ; if d1=0 then super rtn failed
        beq     vblfail

        move.w  #0,-(sp)                ; status code
        move.l  #zzend,d0
        sub.l   #start,d0
        move.l  d0,-(sp)                ; amount of memory to reserve
        move.w  #ptermres,-(sp)         ; keep process
        trap    #gemdos
vblfail:
        move.l  #mnovec,-(sp)           ; ptr to message
        move.w  #cconws,-(sp)           ; output to console
        trap    #gemdos
        addq.l  #6,sp                   ; balance stack

        move.w  #2,-(sp)                ; wait for console keypress
        move.w  #bconin,-(sp)           ; console input routine
        trap    #bios           
        addq.l  #4,sp                   

        move.w  #pterm0,-(sp)           ; terminate program
        trap    #gemdos

vblset:                                 ; supervisor mode routine
        move.l  #8,d0                   ; d0 = loop counter
        move.l  vblqueue,a0             ; a0 -> vbl vectors
        subq.l  #4,a0
vb10:
        addq.l  #4,a0                   ; bump pointer
        tst.l   (a0)                    ; null pointer?
        beq     vb20                    ; YES - branch
        dbeq    d0,vb10                 ; no - loop
;
;  IF WE GET HERE THERE WAS NO SPARE VBL VECTOR
;  WE COULD COPY THE EXISTING VECTORS TO A LARGER AREA,
;  BUT FOR NOW JUST RETURN FAIL STATUS IN D1!
;
        clr.l   d1                      ; 0 = routine failed status
        rts                             ; return to user mode routine

vb20:                                   ; spare vector was found  
        move.l  #vblrtn,(a0)            ; set our routine address
;       addq.w  #1,nvbls                ; increment count of routines
        move.l  #-1,d1                  ; signal success status
        rts                             ; return to user mode routine

        ; THIS IS THE INTERRUPT ENTRY POINT

        EVEN
vblrtn:
        cmpi.b  #'Y',flag               ; already in interrupt?
        beq     endit                   ; YES - exit quick!
        move.b  #'Y',flag               ; set flag      
        addq.b  #1,count                ; cycle counter
        tst.b   count                   ; counter overflow?
        bne     end0                    ; not yet - end
beep:
        move.w  #7,-(sp)                ; counter expired - output
        move.w  #2,-(sp)                ; bell (CTRL/G)
        move.w  #bconout,-(sp)                
        trap    #bios
        addq.l  #6,sp                   ; balance stack
end0:
        clr.b   flag                    ; set flag back
endit:
        rts     

        ds.b    100                     ; spare space
zzend:
        END                             ; end of program


OSBIND.EQU

**
**
*
* this file contains EQU definitions for use with the atari specific
* functions gemdos,bios and xbios 
*
**

gemdos             EQU      1
bios               EQU      13
xbios              EQU      14

* gemdos functions   trap #1 *

pterm0             EQU      $0
cconin             EQU      $1
cconout            EQU      $2
cauxin             EQU      $3
cauxout            EQU      $4
cprnout            EQU      $5
crawio             EQU      $6
crawcin            EQU      $7
cnecin             EQU      $8
cconws             EQU      $9
cconrs             EQU      $0a
cconis             EQU      $0b
dsetdrv            EQU      $0e
cconos             EQU      $10
cprnos             EQU      $11
cauxis             EQU      $12
cauxos             EQU      $13
dgetdrv            EQU      $19
fsetdta            EQU      $1a
super              EQU      $20
tgetdate           EQU      $2a
tsetdate           EQU      $2b
tgettime           EQU      $2c
tsettime           EQU      $2d
fgetdta            EQU      $2f
sversion           EQU      $30
ptermres           EQU      $31
dfree              EQU      $36
dcreate            EQU      $39
ddelete            EQU      $3a
dsetpath           EQU      $3b
fcreate            EQU      $3c
fopen              EQU      $3d
fclose             EQU      $3e
fread              EQU      $3f
fwrite             EQU      $40
fdelete            EQU      $41
fseek              EQU      $42
fattrib            EQU      $43
fdup               EQU      $45
fforce             EQU      $46
dgetpath           EQU      $47
malloc             EQU      $48
mfree              EQU      $49
mshrink            EQU      $4a
pexec              EQU      $4b
pterm              EQU      $4c
fsfirst            EQU      $4e
fsnext             EQU      $4f
frename            EQU      $56
fdatime            EQU      $57

* bios functions   trap #13 *

bconstat           EQU      1
bconin             EQU      2
bconout            EQU      3
rwabs              EQU      4
setexc             EQU      5
bcostat            EQU      8
mediach            EQU      9
drvmap             EQU      10
getshift           EQU      11

* xbios functions   trap #14 *

initmous           EQU      0
physbase           EQU      2
logbase            EQU      3
getrez             EQU      4
setscreen          EQU      5
setpallete         EQU      6
setcolor           EQU      7
floprd             EQU      8
flopwr             EQU      9
midiws             EQU      12
mfpint             EQU      13
iorec              EQU      14
rsconf             EQU      15
keytbl             EQU      16
random             EQU      17
protobt            EQU      18
flopver            EQU      19
scrdump            EQU      20
cursconf           EQU      21
settime            EQU      22
gettime            EQU      23
bioskeys           EQU      24
ikbdws             EQU      25
jdisint            EQU      26
jenabint           EQU      27
giaccess           EQU      28
offgibit           EQU      29
ongibit            EQU      30
xbtimer            EQU      31
dosound            EQU      32
setprt             EQU      33
kbdvbase           EQU      34
kbrate             EQU      35
prtblk             EQU      36
vsync              EQU      37
supexec            EQU      38

read_only          EQU      0
write_only         EQU      1
read_write         EQU      2


    
T.RTitleUserPersonal
Name
DateLines
1286.1a suggestionMIDIOT::POWERSBill Powers (Or a Facsimili thereof)Fri May 22 1992 11:5619
Tony,

    I can't guarantee this, but what might be happening is that you are
experiencing the non-reentrant nature of the atari's O/S.  What might
be happening is when the mouse gets moved into the top portion of the
menu bar, it may be calling the bios at some point for who knows what
and if your routine goes to send a beep by calling the bios, it might
mess up since the bios uses static memory locations to save values and if
two tasks are trying to use those static locations at the same time,

<CRASH> and burn.

    A suggestion to try to see if this is what is happening, try doing
something else instead of calling the bios to get a beep.  Don't use
the GEMDOS/BIOS/XBIOS routines to do it.  Directly twiddle the hardware
in your code.  If it no longer crashes, that is most likely the problem.

bill powers
1286.2thanksKERNEL::IMBIERSKIThe sound of electric woodSat May 23 1992 08:1313
    Bill,
    
    thanks for your reply. I suspected there might be some restriction in
    calling BIOS routines from this type of code. I will see if I can
    recode it without the BIOS calls. 
    
    Incidentally, my reason for trying this technique is that I am writing
    a midi mixing system for my Korg m3R, and I want a background routine
    to copy data from the midi IN to the OUT ports constantly, thus giving
    me a "soft thru" facility. Does anyone know how the commercial
    sequencers do this?
    
    Tony I
1286.3FIXED!KERNEL::IMBIERSKIThe sound of electric woodSat May 23 1992 09:0514
    I fixed my TSR program, though I'm not exactly sure why this fixed it.
    At the bottom of my code I had a "spare" 100 byte area to make sure
    that when I used the KEEP PROCESS call, all of my executable code was
    well inside the bounds of the saved memory. I changed this to 1000
    bytes, and now the program works fine, even with theBIOS calls. I
    presume it must be something to do with the way GEM rounds off the size
    of the chunk of memory saved when you do a Keep process. I guess my
    program was being overwritten before, the next time I did anything that
    would allocate memory.
    
    Thanks for the help, 
    
    Tony I
          
1286.4CMOTEC::HARRISONWed May 27 1992 05:2414

Tony,

	Do you absolutely need a software THRU facility, or will the normal
hardware THRU suffice ?

I don't know of any details but I heard that the MIDI OUT port has the THRU
connections anyway (although in non-standard positions) therefore all you should
need is a adapter to fit into the MIDI OUT, to give you the OUT & THRU sockets.

Anyone out there with details ??

Brynn.
1286.5KERNEL::IMBIERSKIThe sound of electric woodWed May 27 1992 09:0717
    Brynn,
    
    I do have a book at home which details the pins used on the Atari midi
    out, and I may well end up making a special cable.
    
    I tried the software option first because: a) it's an interesting bit
    of programming b) it's then switchable from within the program and c)
    if it works its a useful technique to use in other programs.
    
    However, I'm having a few problems with it so I will probably use the
    hardware thru. Of course I then have the problem of trying to merge 2
    midi signals to 1 (the Atari out and thru to my SGU midi in), but for
    the application I have in mind it's unlikely that the two will be
    active at the same time so a simple splice should work.
    
    Tony I