Line 39... |
Line 39... |
; d
|
; d
|
; Returns:
|
; Returns:
|
; none
|
; none
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
|
setdp $FFC
|
|
|
InitSerial:
|
InitSerial:
|
SerialInit:
|
SerialInit:
|
|
pshs dpr
|
|
lda #$FFC
|
|
tfr a,dpr
|
clra
|
clra
|
clrb
|
clrb
|
std SerHeadRcv-1
|
clr SerHeadRcv
|
std SerTailRcv-1
|
clr SerTailRcv
|
std SerHeadXmit-1
|
clr SerHeadXmit
|
std SerTailXmit-1
|
clr SerTailXmit
|
clr SerRcvXon
|
clr SerRcvXon
|
clr SerRcvXoff
|
clr SerRcvXoff
|
lda COREID
|
lda COREID
|
sini1:
|
sini1:
|
cmpa IOFocusID
|
cmpa IOFocusID
|
bne sini1
|
bne sini1
|
ldb #$09 ; dtr,rts active, rxint enabled, no parity
|
ldb #$0B ; dtr,rts active, rxint enabled (bit 1=0), no parity
|
stb ACIA+ACIA_CMD
|
stb ACIA+ACIA_CMD
|
ldb #$1F ; baud 9600, 1 stop bit, 8 bit, internal baud gen
|
ldb #$1E ; baud 9600, 1 stop bit, 8 bit, internal baud gen
|
stb ACIA+ACIA_CTRL
|
stb ACIA+ACIA_CTRL
|
ldb #$0A6 ; diable fifos, reset fifos
|
ldb #$0AC ; disable fifos (bit zero, one), reset fifos
|
stb ACIA+ACIA_CTRL2
|
stb ACIA+ACIA_CTRL2
|
rts
|
puls dpr,pc
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; SerialGetChar
|
; SerialGetChar
|
;
|
;
|
; Check the serial port buffer to see if there's a char available. If there's
|
; Check the serial port buffer to see if there's a char available. If there's
|
; a char available then return it. If the buffer is almost empty then send an
|
; a char available then return it. If the buffer is almost empty then send an
|
; XON.
|
; XON.
|
;
|
;
|
; Stack Space:
|
; Stack Space:
|
; 2 words
|
; 3 words
|
; Parameters:
|
; Parameters:
|
; none
|
; none
|
; Modifies:
|
; Modifies:
|
; none
|
; none
|
; Returns:
|
; Returns:
|
; d = character or -1
|
; d = character or -1
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialGetChar:
|
SerialGetChar:
|
pshs x,y
|
pshs ccr,x,y,dpr
|
ldy #0
|
lda #$FFC
|
|
tfr a,dpr
|
sei ; disable interrupts
|
sei ; disable interrupts
|
bsr SerialRcvCount ; check number of chars in receive buffer
|
bsr SerialRcvCount ; check number of chars in receive buffer
|
cmpb #8 ; less than 8?
|
cmpb #8 ; less than 8?
|
bhi sgc2
|
bhi sgc2
|
ldb SerRcvXon ; skip sending XON if already sent
|
ldb SerRcvXon ; skip sending XON if already sent
|
Line 95... |
Line 101... |
bsr SerialPutChar
|
bsr SerialPutChar
|
sgc2:
|
sgc2:
|
ldb SerHeadRcv ; check if anything is in buffer
|
ldb SerHeadRcv ; check if anything is in buffer
|
cmpb SerTailRcv
|
cmpb SerTailRcv
|
beq sgcNoChars ; no?
|
beq sgcNoChars ; no?
|
ldx #SerRcvBuf
|
leax SerRcvBuf ; x = buffer address
|
clra
|
clra
|
ldb b,x ; get byte from buffer
|
ldb b,x ; get byte from buffer
|
inc SerHeadRcv ; 4k wrap around
|
inc SerHeadRcv ; 4k wrap around
|
bra sgcXit
|
bra sgcXit
|
sgcNoChars:
|
sgcNoChars:
|
ldd #-1
|
ldd #-1
|
sgcXit:
|
sgcXit:
|
cli
|
puls ccr,x,y,dpr,pc
|
puls x,y,pc
|
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; SerialPeekChar
|
; SerialPeekChar
|
;
|
;
|
; Check the serial port buffer to see if there's a char available. If there's
|
; Check the serial port buffer to see if there's a char available. If there's
|
; a char available then return it. But don't update the buffer indexes. No need
|
; a char available then return it. But don't update the buffer indexes. No need
|
; to send an XON here.
|
; to send an XON here.
|
;
|
;
|
; Stack Space:
|
; Stack Space:
|
; 0 words
|
; 2 words
|
; Parameters:
|
; Parameters:
|
; none
|
; none
|
; Modifies:
|
; Modifies:
|
; none
|
; none
|
; Returns:
|
; Returns:
|
; d = character or -1
|
; d = character or -1
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialPeekChar:
|
SerialPeekChar:
|
pshs x,ccr
|
pshs x,ccr,dpr
|
|
lda #$FFC
|
|
tfr a,dpr
|
sei
|
sei
|
ldb SerHeadRcv ; check if anything is in buffer
|
ldb SerHeadRcv ; check if anything is in buffer
|
cmpb SerTailRcv
|
cmpb SerTailRcv
|
beq spcNoChars ; no?
|
beq spcNoChars ; no?
|
ldx #SerRcvBuf
|
leax SerRcvBuf
|
clra
|
clra
|
ldb b,x ; get byte from buffer
|
ldb b,x ; get byte from buffer
|
bra spcXit
|
bra spcXit
|
spcNoChars:
|
spcNoChars:
|
ldd #-1
|
ldd #-1
|
spcXit:
|
spcXit:
|
puls x,ccr,pc
|
puls x,ccr,dpr,pc
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; SerialPeekChar
|
; SerialPeekChar
|
; Get a character directly from the I/O port. This bypasses the input
|
; Get a character directly from the I/O port. This bypasses the input
|
; buffer.
|
; buffer.
|
Line 154... |
Line 161... |
; Returns:
|
; Returns:
|
; d = character or -1
|
; d = character or -1
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialPeekCharDirect:
|
SerialPeekCharDirect:
|
|
pshs ccr,dpr
|
|
lda #$FFC
|
|
tfr a,dpr
|
lda COREID ; Ensure we have the IO Focus
|
lda COREID ; Ensure we have the IO Focus
|
cmpa IOFocusID
|
cmpa IOFocusID
|
bne spcd0001
|
bne spcd0001
|
; Disallow interrupts between status read and rx read.
|
; Disallow interrupts between status read and rx read.
|
sei
|
sei
|
ldb ACIA+ACIA_STAT
|
ldb ACIA+ACIA_STAT
|
bitb #8 ; look for Rx not empty
|
bitb #8 ; look for Rx not empty
|
beq spcd0001
|
beq spcd0001
|
clra
|
clra
|
ldb ACIA+ACIA_RX
|
ldb ACIA+ACIA_RX
|
cli
|
puls ccr,dpr,pc
|
rts
|
|
spcd0001:
|
spcd0001:
|
ldd #-1
|
ldd #-1
|
cli
|
puls ccr,dpr,pc
|
rts
|
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; SerialPutChar
|
; SerialPutChar
|
; Put a character to the serial transmitter. This routine blocks until the
|
; Put a character to the serial transmitter. This routine blocks until the
|
; transmitter is empty.
|
; transmitter is empty.
|
Line 185... |
Line 193... |
; Modifies:
|
; Modifies:
|
; none
|
; none
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialPutChar:
|
SerialPutChar:
|
pshs a,ccr
|
pshs a,ccr,dpr
|
|
lda #$FFC
|
|
tfr a,dpr
|
spc0001:
|
spc0001:
|
lda COREID ; Ensure we have the IO Focus
|
lda COREID ; Ensure we have the IO Focus
|
cmpa IOFocusID
|
cmpa IOFocusID
|
bne spc0001
|
bne spc0001
|
cli ; provide a window for an interrupt to occur
|
cli ; provide a window for an interrupt to occur
|
Line 198... |
Line 208... |
; intervening interrupt.
|
; intervening interrupt.
|
lda ACIA+ACIA_STAT ; wait until the uart indicates tx empty
|
lda ACIA+ACIA_STAT ; wait until the uart indicates tx empty
|
bita #16 ; bit #4 of the status reg
|
bita #16 ; bit #4 of the status reg
|
beq spc0001 ; branch if transmitter is not empty
|
beq spc0001 ; branch if transmitter is not empty
|
stb ACIA+ACIA_TX ; send the byte
|
stb ACIA+ACIA_TX ; send the byte
|
puls a,ccr,pc
|
puls a,ccr,dpr,pc
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Calculate number of character in input buffer
|
; Calculate number of character in input buffer. Direct page must be set
|
|
; already.
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; y = 0 if current core, otherwise reference to core memory area $Cyxxxx
|
; none
|
; Returns:
|
; Returns:
|
; d = number of bytes in buffer.
|
; d = number of bytes in buffer.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialRcvCount:
|
SerialRcvCount:
|
clra
|
clra
|
ldb SerTailRcv,y
|
ldb SerTailRcv
|
subb SerHeadRcv,y
|
subb SerHeadRcv
|
bge srcXit
|
bge srcXit
|
ldd #$1000
|
ldd #$1000
|
subd SerHeadRcv,y
|
subd SerHeadRcv
|
addd SerTailRcv,y
|
addd SerTailRcv
|
srcXit:
|
srcXit:
|
rts
|
rts
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Serial IRQ routine
|
; Serial IRQ routine
|
Line 236... |
Line 247... |
; Returns:
|
; Returns:
|
; none
|
; none
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
SerialIRQ:
|
SerialIRQ:
|
|
pshs dpr ; set direct page register to boot variables
|
|
lda #$FFC
|
|
tfr a,dpr
|
|
lda PIC+$D3 ; Serial active interrupt flag
|
|
beq notSerInt
|
sirqNxtByte:
|
sirqNxtByte:
|
|
ldb ACIA+ACIA_IRQS ; look for IRQs
|
|
bpl notSerInt ; quick test for any irqs
|
ldb ACIA+ACIA_STAT ; check the status
|
ldb ACIA+ACIA_STAT ; check the status
|
bitb #$08 ; bit 3 = rx full
|
bitb #$08 ; bit 3 = rx full (not empty)
|
beq notRxInt
|
beq notRxInt1
|
ldb ACIA+ACIA_RX ; get data from Rx buffer to clear interrupt
|
ldb ACIA+ACIA_RX ; get data from Rx buffer to clear interrupt
|
cmpb #CTRLT ; detect special keystroke
|
lda SerTailRcv ; check if recieve buffer full
|
bne sirq0001
|
|
; bsr DumpTraceQueue
|
|
sirq0001:
|
|
pshs b
|
|
; Compute receive buffer address
|
|
lda IOFocusID
|
|
asla
|
|
asla
|
|
asla
|
|
asla
|
|
ora #$C00
|
|
clrb
|
|
tfr d,y
|
|
puls b
|
|
lda SerTailRcv,y ; check if recieve buffer full
|
|
inca
|
inca
|
cmpa SerHeadRcv,y
|
cmpa SerHeadRcv
|
beq sirqRxFull
|
beq sirqRxFull
|
sta SerTailRcv,y ; update tail pointer
|
sta SerTailRcv ; update tail pointer
|
deca ; backup
|
deca ; backup
|
exg a,b
|
exg a,b
|
leax SerRcvBuf,y ; x = buffer address
|
leax SerRcvBuf ; x = buffer address
|
sta b,x ; store recieved byte in buffer
|
sta b,x ; store recieved byte in buffer
|
tst SerRcvXoff,y ; check if xoff already sent
|
tst SerRcvXoff ; check if xoff already sent
|
bne sirqNxtByte
|
bne sirqNxtByte
|
bsr SerialRcvCount ; if more than 4080 chars in buffer
|
bsr SerialRcvCount ; if more than 4070 chars in buffer
|
cmpb #4080
|
cmpb #4070
|
blo sirqNxtByte
|
blo sirqNxtByte
|
ldb #XOFF ; send an XOFF
|
ldb #XOFF ; send an XOFF
|
clr SerRcvXon,y ; clear XON status
|
clr SerRcvXon ; clear XON status
|
stb SerRcvXoff,y ; set XOFF status
|
stb SerRcvXoff ; set XOFF status
|
stb ACIA+ACIA_TX
|
stb ACIA+ACIA_TX
|
bra sirqNxtByte ; check the status for another byte
|
bra sirqNxtByte ; check the status for another byte
|
|
; Process other serial IRQs
|
|
notRxInt1:
|
|
puls dpr,pc
|
sirqRxFull:
|
sirqRxFull:
|
notRxInt:
|
notRxInt:
|
rts
|
notSerInt:
|
|
puls dpr,pc
|
|
|
nmeSerial:
|
nmeSerial:
|
fcb "Serial",0
|
fcb "Serial",0
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
Line 336... |
Line 343... |
puls d,pc
|
puls d,pc
|
|
|
msgSerialTest:
|
msgSerialTest:
|
fcb "Serial port test",CR,LF,0
|
fcb "Serial port test",CR,LF,0
|
|
|
|
setdp $000
|