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