home *** CD-ROM | disk | FTP | other *** search
- ; Serial.a
- ; created by John Schultz, 17-Sep-89
- ; last modified 17-April-90
-
- section Serial,CODE
-
- xref _raw
-
- xdef _baudper
- xdef _openserial
- xdef _closeserial
- xdef _sendser
- xdef _readser
- xdef _checkser
- xdef _rawtoascii
- xdef _sendsernobuff
-
-
- _LVOSetIntVector equ $FFFFFF5E
-
- ESCAPE equ 69 ; input-handler rawkey code
-
- CLOCK equ 3579545
- _baudper dc.w (CLOCK/19200)-1 ; defaualt
-
- CUSTOM equ $dff000
- SERDATR equ $000018
- SERDAT equ $000030
- SERPER equ $000032
-
- INTENA equ $00009a
- INTENAR equ $00001c
- INTREQ equ $00009c
-
- TBEQSIZE equ 128 ; buffer size in bytes,
- RBFQSIZE equ 128 ; increase or decrease as needed
-
- LED equ $bfe001 ; toggle power led, audio filter
-
- ledroll dc.b %00010001 ; flash every 4 bytes
- ledpad dc.b 0
-
- oldintena dc.w 0
-
- tbequeue ds.b TBEQSIZE ; circular queue
- tbeqend
- tbehead dc.l tbequeue
- tbetail dc.l tbequeue
-
- oldtbeinterrupt dc.l 0
- oldrbfinterrupt dc.l 0
-
- tbeinterrupt
- dc.l 0 ; ln_succ
- dc.l 0 ; ln_prec
- dc.b 2 ; NT_INTERRUPT
- dc.b 127 ; ln_pri
- dc.l 0 ; ln_name
- dc.l tbehead ; is_data
- dc.l tbehandler ; is_code
-
- rbfinterrupt
- dc.l 0 ; ln_succ
- dc.l 0 ; ln_prec
- dc.b 2 ; NT_INTERRUPT
- dc.b 127 ; ln_pri
- dc.l 0 ; ln_name
- dc.l rbftail ; is_data
- dc.l rbfhandler ; is_code
-
-
- tbehandler
- move.w #1,INTREQ(a0) ; clear TBE interrupt
- move.l (a1),a1 ; a1 = tbehead, (a1) = pointer
- cmp.l tbetail,a1 ; now a1 = pointer
- beq.b 99$
- move.w SERDATR(a0),d0 ; check to make sure emtpy
- btst #13,d0
- beq.b 99$
- move.w #$100,d0
- move.b (a1)+,d0 ; get byte from queue
- move.w d0,SERDAT(a0) ; send byte
- cmpa.l #tbeqend,a1
- bne.b 10$
- lea tbequeue(pc),a1
- 10$ move.l a1,tbehead
- 99$
- rts
-
- rbfqueue ds.b RBFQSIZE
- rbfqend
- rbfhead dc.l rbfqueue
- rbftail dc.l rbfqueue
-
- rbfhandler
- move.w SERDATR(a0),d0 ; a0 = custom
- move.w #$800,INTREQ(a0) ; clear RBF interrupt
- move.l (a1),a0 ; a1 = rbftail, get pointer
- move.b d0,(a0)+ ; write byte to buffer
- cmpa.l #rbfqend,a0
- bne.b 10$
- lea rbfqueue(pc),a0
- 10$ move.l a0,(a1) ; a1 = rbftail
-
- ;99$
- ; move.b ledroll(pc),d0 ; remove from 99$-100$ for more
- ; rol.b #1,d0 ; speed
- ; move.b d0,ledroll
- ; btst #1,d0
- ; beq.b 100$
- ; bchg.b #1,LED ; toggle power led / audio filter
- ;100$
- rts
-
- _openserial
- move.l a6,-(sp)
- lea CUSTOM,a0
- move.w #$4000,INTENA(a0) ; disable
- move.l $4,a6 ; execbase
- lea rbfinterrupt(pc),a1
- moveq.l #11,d0
- jsr _LVOSetIntVector(a6)
- move.l d0,oldrbfinterrupt
- lea tbeinterrupt(pc),a1
- moveq.l #0,d0
- jsr _LVOSetIntVector(a6)
- move.l d0,oldtbeinterrupt
-
- lea CUSTOM,a0
- move.w _baudper,SERPER(a0) ; set period
-
- move.w #$3fff,$bfd0fe ; init handshake lines
- move.w INTENAR(a0),oldintena
- move.w #$8801,INTENA(a0) ; turn on RBF and TBE INTENA
- move.w #$0801,INTREQ(a0) ; clear RBF and TBE INTREQ
- move.w #$c000,INTENA(a0) ; enable
- move.l (sp)+,a6
- rts
-
-
- _closeserial
- move.l a6,-(sp)
- lea CUSTOM,a0
- move.w #$4000,INTENA(a0) ; disable
- move.l $4,a6 ; execbase
- move.l oldrbfinterrupt,a1
- moveq.l #11,d0
- jsr _LVOSetIntVector(a6)
- move.l oldtbeinterrupt,a1
- moveq.l #0,d0
- jsr _LVOSetIntVector(a6)
-
- lea CUSTOM,a0
- move.w #$0801,INTENA(a0) ; turn off RBF and TBE INTENA
- move.w oldintena,d0
- and.w #$0801,d0 ; mask for bit 11 and bit 1.
- bset #15,d0 ; set/clr = 1 (set)
- move.w d0,INTENA(a0) ; reset old RBF and TBE INTENA
-
- bclr.b #1,LED
-
- move.w #$0801,INTREQ(a0) ; clear RBF and TBE INTREQ
- move.w #$c000,INTENA(a0) ; enable
- move.l (sp)+,a6
- rts
-
- _sendser
- lea CUSTOM,a0
- move.w #$4000,INTENA(a0)
-
- move.l tbetail,a1
- cmpa.l tbehead,a1
- beq.b 5$
- move.w #$8001,INTREQ(a0) ; generate a tbe interrupt
- 5$
- move.b d0,(a1)+ ; queue up byte
- cmpa.l #tbeqend,a1
- bne.b 10$
- lea tbequeue(pc),a1
- 10$ move.l a1,tbetail
-
- move.w #$c000,INTENA(a0)
- rts
-
-
- ; send byte in d0 to serial port, non-buffered.
- _sendsernobuff
- lea CUSTOM,a0
- move.w #$4000,INTENA(a0)
- 1$ move.w SERDATR,d1
- btst #13,d1 ; check TBE
- beq.b 1$ ; buffer busy
-
- move.w #$100,d1
- move.b d0,d1
- move.w d1,SERDAT(a0)
- 2$ move.w SERDATR(a0),d1
- btst #13,d1 ; check TBE
- beq.b 2$ ; buffer busy
- move.w #$001,INTREQ(a0) ; clear TBE interrupt
-
- move.w #$c000,INTENA(a0)
- rts
-
-
- ; uses a0
- _readser
- cmp.w #ESCAPE,_raw ; quits on ESC from input handler
- beq.b 20$
- move.l rbfhead,a0
- cmpa.l rbftail,a0
- beq.b _readser
- move.b (a0)+,d0
- cmpa.l #rbfqend,a0
- bne.b 10$
- lea rbfqueue(pc),a0
- 10$ move.l a0,rbfhead
- 20$
- rts
-
- _checkser
- move.l rbfhead,a0
- cmpa.l rbftail,a0
- bne.b dataisin
- moveq.l #0,d0
- rts
- dataisin
- moveq.l #1,d0
- rts
-
-
- ; rawkey in d0
- ; ascii returned in d0
- _rawtoascii
- cmp.b #79,d0
- bls.b getascii
- moveq.l #0,d0
- rts
- getascii
- lea asciitable,a0
- move.b 0(a0,d0),d0
- rts
-
-
- section asciitable,data
-
- ; This is a quick trick, don't do this for anything other than
- ; home use, boys and girls. Use rawkeyconvert, etc.
-
- asciitable
- dc.b '`' ; backquote `
- dc.b '1'
- dc.b '2'
- dc.b '3'
- dc.b '4'
- dc.b '5'
- dc.b '6'
- dc.b '7'
- dc.b '8'
- dc.b '9'
- dc.b '0'
- dc.b '-'
- dc.b '='
- dc.b $0D ; \
- dc.b 0
- dc.b '0' ; keypad 0
- dc.b 'q'
- dc.b 'w'
- dc.b 'e'
- dc.b 'r'
- dc.b 't'
- dc.b 'y'
- dc.b 'u'
- dc.b 'i'
- dc.b 'o'
- dc.b 'p'
- dc.b '['
- dc.b ']'
- dc.b 0
- dc.b '1'
- dc.b '2'
- dc.b '3'
- dc.b 'a'
- dc.b 's'
- dc.b 'd'
- dc.b 'f'
- dc.b 'g'
- dc.b 'h'
- dc.b 'j'
- dc.b 'k'
- dc.b 'l'
- dc.b ';'
- dc.b $27 ; ' single quote
- dc.b 0
- dc.b 0
- dc.b '4'
- dc.b '5'
- dc.b '6'
- dc.b 0
- dc.b 'z'
- dc.b 'x'
- dc.b 'c'
- dc.b 'v'
- dc.b 'b'
- dc.b 'n'
- dc.b 'm'
- dc.b ','
- dc.b '.'
- dc.b '/'
- dc.b 0
- dc.b '.' ; keypad
- dc.b '7'
- dc.b '8'
- dc.b '9'
- dc.b ' '
- dc.b $8 ; backspace
- dc.b $9 ; tab
- dc.b $D ; enter cr
- dc.b $D ; return cr
- dc.b $1B ; ESC
- dc.b $7f ; delete
- dc.b ''
- dc.b 0
- dc.b 0
- dc.b '-' ; keypad
- dc.b 0
- dc.b 0
- dc.b $b ; up arrow
- dc.b $a ; down arrow
- dc.b $20 ; rt arrow
- dc.b $8 ; left arrow
-
- END
-