[comp.sys.atari.st] Programming problem

paulr@syma.sussex.ac.uk (Paul T Russell) (09/24/90)

I've been trying to get a simple program working on an Atari ST using FastBASIC.
The idea is to connect a heart rate monitor to a suitable input (parallel port
status line or serial port handshake input) and use a VBI interrupt routine to
count heart beats. Unfortunately I get a crash as soon as I install the VBI
interrupt routine, so I guess I must be doing something wrong. Since I don't
normally program Atari ST's and I have no debugging tools and very little
information at my disposal I was wondering if anyone could cast their eye over
the following short test program and see if they can spot where I'm going 
wrong. The program halts with a bus error at the CALL to "init".

Thanks in advance,

//Paul

REM ---------------------------------------------------------------------------
REM Demo program to test interrupt handler for using parallel port
REM status line or serial port CTS/DCD/RI lines as input for timing
REM and counting (eg: for use with heart rate monitor).
REM
REM Paul Russell, Department of Experimental Psychology,
REM University of Sussex, 19th September 1990
REM ---------------------------------------------------------------------------
PRINT "Assembling..."
RESERVE code,$100               : REM reserve some memory for machine code
FOR pass = 1 TO 2               : REM humour the assembler
[
        OPT pass
        ORG code
port    EQU     $FFFA01         \ address of I/O port
vblq    EQU     $456            \ address of pointer to VBI queue
init    MOVEA.L vblq,A0         \ get address of VBI queue
        LEA     handler(PC),A1  \ get address of our handler
        MOVE.L  A1,4(A0)        \ stash it in the VBI queue
        RTS
quit    MOVEA.L vblq,A0         \ get address of VBI queue
        LEA     0,A1            \ get null address
        MOVE.L  A1,4(A0)        \ stash it in the VBI queue     
        RTS
handler LEA     tim(PC),A0      \ increment timer
        MOVE.W  (A0),D0
        ADDQ.W  #1,D0
        MOVE.W  D0,(A0)
        LEA     port,A0         \ get port state
        MOVE.B  (A0),D0
        ANDI.B  #$0F,D0         \ clear high 4 bits
        LEA     old(PC),A0      \ compare with old state
        CMP.B   (A0),D0
        BEQ.S   nochng          \ if unchanged then skip
        MOVE.B  D0,(A0)         \ else save new state
        LEA     cnt(PC),A0      \ get edge count
        MOVE.W  (A0),D0
        ADDQ.W  #1,D0           \ increment it
        MOVE.W  D0,(A0)         \ and save it
nochng  RTS
reset   LEA     tim(PC),A0      \ clear timer
        CLR.W   (A0)
        LEA     cnt(PC),A0      \ clear counter
        CLR.W   (A0)
        RTS
readt   LEA     tim(PC),A0      \ read timer
        MOVE.W  (A0),D0
        RTS
readc   LEA     cnt(PC),A0      \ read counter
        MOVE.W  (A0),D0
        RTS
tim     DC.W    0               \ timer (counts VBI interrupts)
cnt     DC.W    0               \ counter (counts edges)
old     DC.B    0               \ old state of port
        EVEN                    \ make sure we are word aligned
]
NEXT
REM ---------------------------------------------------------------------------
PRINT "Here we go..."
REM --- First, try reading the timer and counter values without the ---
REM --- interrupt handler installed (should just display zero's)    ---
PRINT "No interrupt handler..."
REPEAT                          : REM repeat
  t%=USR(readt)                 : REM   read timer
  c%=USR(readc)                 : REM   read counter
  PRINT t%,c%                   : REM   display values
UNTIL inkey$<>""                : REM until key pressed
REM --- Now try it with the interrupt handler installed - should    ---
REM --- see a steadily increasing timer value with a counter value  ---
REM --- which increments whenever one of the input lines is toggled ---
PRINT "Installing interrupt handler..."
CALL init                       : REM install interrupt handler (-> Bus Error)
REPEAT                          : REM repeat
  t%=USR(readt)                 : REM   read timer
  c%=USR(readc)                 : REM   read counter
  PRINT t%,c%                   : REM   display values
UNTIL inkey$<>""                : REM until key pressed
CALL quit                       : REM remove interrupt handler
REM ---------------------------------------------------------------------------

           Paul Russell, Department of Experimental Psychology
         University of Sussex, Falmer, Brighton BN1 9QG, England
     Janet: paulr@uk.ac.sussex.syma  Nsfnet: paulr@syma.sussex.ac.uk
    Bitnet: paulr%sussex.syma@ukacrl.bitnet  Usenet: ...ukc!syma!paulr