mirror of
https://github.com/cc65/cc65.git
synced 2025-02-19 06:30:53 +00:00
Fixes to serial driver implementation
This commit is contained in:
parent
3dfe033000
commit
788ae82d30
@ -267,22 +267,26 @@ MIKEYHREV = $FD88
|
|||||||
MIKEYSREV = $FD89
|
MIKEYSREV = $FD89
|
||||||
IODIR = $FD8A
|
IODIR = $FD8A
|
||||||
IODAT = $FD8B
|
IODAT = $FD8B
|
||||||
TxIntEnable = %10000000
|
|
||||||
RxIntEnable = %01000000
|
|
||||||
TxParEnable = %00010000
|
|
||||||
ResetErr = %00001000
|
|
||||||
TxOpenColl = %00000100
|
|
||||||
TxBreak = %00000010
|
|
||||||
ParEven = %00000001
|
|
||||||
TxReady = %10000000
|
|
||||||
RxReady = %01000000
|
|
||||||
TxEmpty = %00100000
|
|
||||||
RxParityErr = %00010000
|
|
||||||
RxOverrun = %00001000
|
|
||||||
RxFrameErr = %00000100
|
|
||||||
RxBreak = %00000010
|
|
||||||
ParityBit = %00000001
|
|
||||||
SERCTL = $FD8C
|
SERCTL = $FD8C
|
||||||
|
; SERCTL bit definitions for write operations
|
||||||
|
TXINTEN = $80
|
||||||
|
RXINTEN = $40
|
||||||
|
PAREN = $10
|
||||||
|
RESETERR = $08
|
||||||
|
TXOPEN = $04
|
||||||
|
TXBRK = $02
|
||||||
|
PAREVEN = $01
|
||||||
|
; SERCTL bit definitions for read operations
|
||||||
|
TXRDY = $80
|
||||||
|
RXRDY = $40
|
||||||
|
TXEMPTY = $20
|
||||||
|
PARERR = $10
|
||||||
|
OVERRUN = $08
|
||||||
|
FRAMERR = $04
|
||||||
|
RXBRK = $02
|
||||||
|
PARBIT = $01
|
||||||
|
|
||||||
SERDAT = $FD8D
|
SERDAT = $FD8D
|
||||||
SDONEACK = $FD90
|
SDONEACK = $FD90
|
||||||
CPUSLEEP = $FD91
|
CPUSLEEP = $FD91
|
||||||
|
@ -68,7 +68,7 @@ MikeyInitData: .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$2
|
|||||||
|
|
||||||
; Disable the TX/RX IRQ; set to 8E1.
|
; Disable the TX/RX IRQ; set to 8E1.
|
||||||
|
|
||||||
lda #%00011101
|
lda #PAREN|RESETERR|TXOPEN|PAREVEN ; #%00011101
|
||||||
sta SERCTL
|
sta SERCTL
|
||||||
|
|
||||||
; Clear all pending interrupts.
|
; Clear all pending interrupts.
|
||||||
|
@ -73,7 +73,12 @@ SER_UNINSTALL:
|
|||||||
; Must return an SER_ERR_xx code in a/x.
|
; Must return an SER_ERR_xx code in a/x.
|
||||||
|
|
||||||
SER_CLOSE:
|
SER_CLOSE:
|
||||||
; Disable interrupts
|
; Disable interrupts and stop timer 4 (serial)
|
||||||
|
lda #$0C ; TXOPEN|RESETERR
|
||||||
|
sta SERCTL
|
||||||
|
lda #$00 ; Disable count and no reload
|
||||||
|
sta TIM4CTLA
|
||||||
|
|
||||||
; Done, return an error code
|
; Done, return an error code
|
||||||
lda #SER_ERR_OK
|
lda #SER_ERR_OK
|
||||||
.assert SER_ERR_OK = 0, error
|
.assert SER_ERR_OK = 0, error
|
||||||
@ -108,7 +113,7 @@ SER_OPEN:
|
|||||||
stz TxPtrIn
|
stz TxPtrIn
|
||||||
stz TxPtrOut
|
stz TxPtrOut
|
||||||
|
|
||||||
; clock = 8 * 15625
|
; source period is 1 us
|
||||||
lda #%00011000
|
lda #%00011000
|
||||||
sta TIM4CTLA
|
sta TIM4CTLA
|
||||||
ldy #SER_PARAMS::BAUDRATE
|
ldy #SER_PARAMS::BAUDRATE
|
||||||
@ -118,7 +123,7 @@ SER_OPEN:
|
|||||||
cmp #SER_BAUD_62500
|
cmp #SER_BAUD_62500
|
||||||
beq setbaudrate
|
beq setbaudrate
|
||||||
|
|
||||||
ldx #2
|
ldx #3
|
||||||
cmp #SER_BAUD_31250
|
cmp #SER_BAUD_31250
|
||||||
beq setbaudrate
|
beq setbaudrate
|
||||||
|
|
||||||
@ -194,13 +199,14 @@ SER_OPEN:
|
|||||||
lda #SER_ERR_BAUD_UNAVAIL
|
lda #SER_ERR_BAUD_UNAVAIL
|
||||||
ldx #0 ; return value is char
|
ldx #0 ; return value is char
|
||||||
rts
|
rts
|
||||||
|
|
||||||
setprescaler:
|
setprescaler:
|
||||||
stx TIM4CTLA
|
stx TIM4CTLA
|
||||||
bra baudsuccess
|
bra baudsuccess
|
||||||
setbaudrate:
|
setbaudrate:
|
||||||
stx TIM4BKUP
|
stx TIM4BKUP
|
||||||
baudsuccess:
|
baudsuccess:
|
||||||
ldx #TxOpenColl|ParEven
|
ldx #TXOPEN|PAREVEN
|
||||||
stx contrl
|
stx contrl
|
||||||
ldy #SER_PARAMS::DATABITS ; Databits
|
ldy #SER_PARAMS::DATABITS ; Databits
|
||||||
lda (ptr1),y
|
lda (ptr1),y
|
||||||
@ -218,15 +224,15 @@ baudsuccess:
|
|||||||
beq checkhs
|
beq checkhs
|
||||||
cmp #SER_PAR_SPACE
|
cmp #SER_PAR_SPACE
|
||||||
bne @L0
|
bne @L0
|
||||||
ldx #TxOpenColl
|
ldx #TXOPEN
|
||||||
stx contrl
|
stx contrl
|
||||||
bra checkhs
|
bra checkhs
|
||||||
@L0:
|
@L0:
|
||||||
ldx #TxParEnable|TxOpenColl|ParEven
|
ldx #PAREN|TXOPEN|PAREVEN
|
||||||
stx contrl
|
stx contrl
|
||||||
cmp #SER_PAR_EVEN
|
cmp #SER_PAR_EVEN
|
||||||
beq checkhs
|
beq checkhs
|
||||||
ldx #TxParEnable|TxOpenColl
|
ldx #PAREN|TXOPEN
|
||||||
stx contrl
|
stx contrl
|
||||||
checkhs:
|
checkhs:
|
||||||
ldx contrl
|
ldx contrl
|
||||||
@ -237,7 +243,7 @@ checkhs:
|
|||||||
bne invparameter
|
bne invparameter
|
||||||
lda SERDAT
|
lda SERDAT
|
||||||
lda contrl
|
lda contrl
|
||||||
ora #RxIntEnable|ResetErr
|
ora #RXINTEN|RESETERR ; Turn on interrupts for receive
|
||||||
sta SERCTL
|
sta SERCTL
|
||||||
lda #SER_ERR_OK
|
lda #SER_ERR_OK
|
||||||
.assert SER_ERR_OK = 0, error
|
.assert SER_ERR_OK = 0, error
|
||||||
@ -279,24 +285,26 @@ SER_PUT:
|
|||||||
ina
|
ina
|
||||||
cmp TxPtrOut
|
cmp TxPtrOut
|
||||||
bne PutByte
|
bne PutByte
|
||||||
|
|
||||||
lda #SER_ERR_OVERFLOW
|
lda #SER_ERR_OVERFLOW
|
||||||
ldx #0 ; return value is char
|
ldx #0 ; return value is char
|
||||||
rts
|
rts
|
||||||
|
|
||||||
PutByte:
|
PutByte:
|
||||||
ldy TxPtrIn
|
ldy TxPtrIn
|
||||||
txa
|
txa
|
||||||
sta TxBuffer,y
|
sta TxBuffer,y
|
||||||
inc TxPtrIn
|
inc TxPtrIn
|
||||||
|
|
||||||
bit TxDone
|
bit TxDone ; Check bit 7 of TxDone (TXINTEN)
|
||||||
bmi @L1
|
bmi @L1 ; Was TXINTEN already set?
|
||||||
php
|
php
|
||||||
sei
|
sei
|
||||||
lda contrl
|
lda contrl ; contrl does not include RXINTEN setting
|
||||||
ora #TxIntEnable|ResetErr
|
ora #TXINTEN|RESETERR
|
||||||
sta SERCTL ; Allow TX-IRQ to hang RX-IRQ
|
sta SERCTL ; Allow TX-IRQ to hang RX-IRQ (no receive while transmitting)
|
||||||
sta TxDone
|
sta TxDone
|
||||||
plp
|
plp ; Restore processor and interrupt enable
|
||||||
@L1:
|
@L1:
|
||||||
lda #SER_ERR_OK
|
lda #SER_ERR_OK
|
||||||
.assert SER_ERR_OK = 0, error
|
.assert SER_ERR_OK = 0, error
|
||||||
@ -308,7 +316,7 @@ PutByte:
|
|||||||
; Must return an SER_ERR_xx code in a/x.
|
; Must return an SER_ERR_xx code in a/x.
|
||||||
|
|
||||||
SER_STATUS:
|
SER_STATUS:
|
||||||
ldy SerialStat
|
lda SerialStat
|
||||||
ldx #$00
|
ldx #$00
|
||||||
sta (ptr1,x)
|
sta (ptr1,x)
|
||||||
txa ; Return code = 0
|
txa ; Return code = 0
|
||||||
@ -342,27 +350,32 @@ SER_IRQ:
|
|||||||
@L0:
|
@L0:
|
||||||
bit TxDone
|
bit TxDone
|
||||||
bmi @tx_irq ; Transmit in progress
|
bmi @tx_irq ; Transmit in progress
|
||||||
ldx SERDAT
|
|
||||||
lda SERCTL
|
ldx SERDAT ; Read received data
|
||||||
and #RxParityErr|RxOverrun|RxFrameErr|RxBreak
|
lda contrl
|
||||||
beq @rx_irq
|
and #PAREN ; Parity enabled implies SER_PAR_EVEN or SER_PAR_ODD
|
||||||
|
ora #OVERRUN|FRAMERR|RXBRK
|
||||||
|
bit SERCTL ; Compare with SERCTL
|
||||||
|
|
||||||
|
beq @rx_irq ; No errors so far
|
||||||
|
|
||||||
tsb SerialStat ; Save error condition
|
tsb SerialStat ; Save error condition
|
||||||
bit #RxBreak
|
bit #RXBRK ; Check for break signal
|
||||||
beq @noBreak
|
beq @noBreak
|
||||||
|
|
||||||
stz TxPtrIn ; Break received - drop buffers
|
stz TxPtrIn ; Break received - drop buffers
|
||||||
stz TxPtrOut
|
stz TxPtrOut
|
||||||
stz RxPtrIn
|
stz RxPtrIn
|
||||||
stz RxPtrOut
|
stz RxPtrOut
|
||||||
@noBreak:
|
@noBreak:
|
||||||
lda contrl
|
lda contrl
|
||||||
ora #RxIntEnable|ResetErr
|
ora #RXINTEN|RESETERR
|
||||||
sta SERCTL
|
sta SERCTL
|
||||||
lda #$10
|
|
||||||
sta INTRST
|
|
||||||
bra @IRQexit
|
bra @IRQexit
|
||||||
|
|
||||||
@rx_irq:
|
@rx_irq:
|
||||||
lda contrl
|
lda contrl
|
||||||
ora #RxIntEnable|ResetErr
|
ora #RXINTEN|RESETERR
|
||||||
sta SERCTL
|
sta SERCTL
|
||||||
txa
|
txa
|
||||||
ldx RxPtrIn
|
ldx RxPtrIn
|
||||||
@ -370,20 +383,22 @@ SER_IRQ:
|
|||||||
txa
|
txa
|
||||||
inx
|
inx
|
||||||
|
|
||||||
@cont0:
|
|
||||||
cpx RxPtrOut
|
cpx RxPtrOut
|
||||||
beq @1
|
beq @1
|
||||||
stx RxPtrIn
|
stx RxPtrIn
|
||||||
lda #SERIAL_INTERRUPT
|
|
||||||
sta INTRST
|
|
||||||
bra @IRQexit
|
bra @IRQexit
|
||||||
|
|
||||||
@1:
|
@1:
|
||||||
sta RxPtrIn
|
sta RxPtrIn
|
||||||
lda #$80
|
lda #$80
|
||||||
tsb SerialStat
|
tsb SerialStat
|
||||||
|
lda contrl
|
||||||
|
ora #RXINTEN|RESETERR
|
||||||
|
sta SERCTL
|
||||||
|
bra @IRQexit
|
||||||
|
|
||||||
@tx_irq:
|
@tx_irq:
|
||||||
ldx TxPtrOut ; Has all bytes been sent?
|
ldx TxPtrOut ; Have all bytes been sent?
|
||||||
cpx TxPtrIn
|
cpx TxPtrIn
|
||||||
beq @allSent
|
beq @allSent
|
||||||
|
|
||||||
@ -393,24 +408,22 @@ SER_IRQ:
|
|||||||
|
|
||||||
@exit1:
|
@exit1:
|
||||||
lda contrl
|
lda contrl
|
||||||
ora #TxIntEnable|ResetErr
|
ora #TXINTEN|RESETERR
|
||||||
sta SERCTL
|
sta SERCTL
|
||||||
lda #SERIAL_INTERRUPT
|
|
||||||
sta INTRST
|
|
||||||
bra @IRQexit
|
bra @IRQexit
|
||||||
|
|
||||||
@allSent:
|
@allSent:
|
||||||
lda SERCTL ; All bytes sent
|
lda SERCTL ; All bytes sent
|
||||||
bit #TxEmpty
|
bit #TXEMPTY
|
||||||
beq @exit1
|
beq @exit1
|
||||||
bvs @exit1
|
bvs @exit1
|
||||||
stz TxDone
|
stz TxDone
|
||||||
lda contrl
|
lda contrl
|
||||||
ora #RxIntEnable|ResetErr
|
ora #RXINTEN|RESETERR ; Re-enable receive interrupt
|
||||||
sta SERCTL
|
sta SERCTL
|
||||||
|
|
||||||
|
@IRQexit:
|
||||||
lda #SERIAL_INTERRUPT
|
lda #SERIAL_INTERRUPT
|
||||||
sta INTRST
|
sta INTRST
|
||||||
@IRQexit:
|
|
||||||
clc
|
clc
|
||||||
rts
|
rts
|
||||||
|
Loading…
x
Reference in New Issue
Block a user