1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-26 02:30:17 +00:00

Merge pull request #2166 from colinleroy/rfc-serial-optimisation

Possible serial driver optimisations
This commit is contained in:
Bob Andrews 2023-09-08 18:42:39 +02:00 committed by GitHub
commit caf8186565
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 113 additions and 124 deletions

View File

@ -26,6 +26,7 @@
.include "ser-error.inc" .include "ser-error.inc"
.macpack module .macpack module
.macpack cpu
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Header. Includes jump table ; Header. Includes jump table
@ -57,9 +58,13 @@
;---------------------------------------------------------------------------- ;----------------------------------------------------------------------------
; I/O definitions ; I/O definitions
.if (.cpu .bitand CPU_ISET_65C02)
ACIA = $C088
.else
Offset = $8F ; Move 6502 false read out of I/O to page $BF Offset = $8F ; Move 6502 false read out of I/O to page $BF
ACIA = $C088-Offset ACIA = $C088-Offset
.endif
ACIA_DATA = ACIA+0 ; Data register ACIA_DATA = ACIA+0 ; Data register
ACIA_STATUS = ACIA+1 ; Status register ACIA_STATUS = ACIA+1 ; Status register
ACIA_CMD = ACIA+2 ; Command register ACIA_CMD = ACIA+2 ; Command register
@ -200,7 +205,9 @@ SER_OPEN:
asl asl
asl asl
asl asl
.if .not (.cpu .bitand CPU_ISET_65C02)
adc #Offset ; Assume carry to be clear adc #Offset ; Assume carry to be clear
.endif
tax tax
; Check if the handshake setting is valid ; Check if the handshake setting is valid
@ -284,14 +291,9 @@ InvBaud:lda #SER_ERR_BAUD_UNAVAIL
SER_GET: SER_GET:
ldx Index ldx Index
ldy SendFreeCnt ; Send data if necessary
iny ; Y == $FF?
beq :+
lda #$00 ; TryHard = false
jsr TryToSend
; Check for buffer empty ; Check for buffer empty
: lda RecvFreeCnt ; (25) lda RecvFreeCnt ; (25)
cmp #$FF cmp #$FF
bne :+ bne :+
lda #SER_ERR_NO_DATA lda #SER_ERR_NO_DATA
@ -315,7 +317,11 @@ SER_GET:
inc RecvHead inc RecvHead
inc RecvFreeCnt inc RecvFreeCnt
ldx #$00 ; (59) ldx #$00 ; (59)
.if (.cpu .bitand CPU_ISET_65C02)
sta (ptr1)
.else
sta (ptr1,x) sta (ptr1,x)
.endif
txa ; Return code = 0 txa ; Return code = 0
rts rts
@ -328,20 +334,21 @@ SER_PUT:
; Try to send ; Try to send
ldy SendFreeCnt ldy SendFreeCnt
iny ; Y = $FF? cpy #$FF ; Nothing to flush
beq :+ beq :+
pha pha
lda #$00 ; TryHard = false lda #$00 ; TryHard = false
jsr TryToSend jsr TryToSend
pla pla
; Put byte into send buffer & send ; Reload SendFreeCnt after TryToSend
: ldy SendFreeCnt ldy SendFreeCnt
bne :+ bne :+
lda #SER_ERR_OVERFLOW lda #SER_ERR_OVERFLOW
ldx #0 ; return value is char ldx #0 ; return value is char
rts rts
; Put byte into send buffer & send
: ldy SendTail : ldy SendTail
sta SendBuf,y sta SendBuf,y
inc SendTail inc SendTail
@ -404,19 +411,19 @@ SER_IRQ:
and #$08 and #$08
beq Done ; Jump if no ACIA interrupt beq Done ; Jump if no ACIA interrupt
lda ACIA_DATA,x ; Get byte from ACIA lda ACIA_DATA,x ; Get byte from ACIA
ldy RecvFreeCnt ; Check if we have free space left ldx RecvFreeCnt ; Check if we have free space left
beq Flow ; Jump if no space in receive buffer beq Flow ; Jump if no space in receive buffer
ldy RecvTail ; Load buffer pointer ldy RecvTail ; Load buffer pointer
sta RecvBuf,y ; Store received byte in buffer sta RecvBuf,y ; Store received byte in buffer
inc RecvTail ; Increment buffer pointer inc RecvTail ; Increment buffer pointer
dec RecvFreeCnt ; Decrement free space counter dec RecvFreeCnt ; Decrement free space counter
ldy RecvFreeCnt ; Check for buffer space low cpx #33 ; Check for buffer space low
cpy #33
bcc Flow ; Assert flow control if buffer space low bcc Flow ; Assert flow control if buffer space low
rts ; Interrupt handled (carry already set) rts ; Interrupt handled (carry already set)
; Assert flow control if buffer space too low ; Assert flow control if buffer space too low
Flow: lda RtsOff Flow: ldx Index
lda RtsOff
sta ACIA_CMD,x sta ACIA_CMD,x
sta Stopped sta Stopped
sec ; Interrupt handled sec ; Interrupt handled
@ -427,12 +434,13 @@ Done: rts
TryToSend: TryToSend:
sta tmp1 ; Remember tryHard flag sta tmp1 ; Remember tryHard flag
Again: lda SendFreeCnt NextByte:
lda SendFreeCnt
cmp #$FF cmp #$FF
beq Quit ; Bail out beq Quit ; Bail out
; Check for flow stopped ; Check for flow stopped
lda Stopped Again: lda Stopped
bne Quit ; Bail out bne Quit ; Bail out
; Check that ACIA is ready to send ; Check that ACIA is ready to send
@ -449,4 +457,4 @@ Send: ldy SendHead
sta ACIA_DATA,x sta ACIA_DATA,x
inc SendHead inc SendHead
inc SendFreeCnt inc SendFreeCnt
jmp Again jmp NextByte

View File

@ -227,14 +227,8 @@ InvBaud:lda #<SER_ERR_BAUD_UNAVAIL
; returned. ; returned.
SER_GET: SER_GET:
ldy SendFreeCnt ; Send data if necessary
iny ; Y == $FF?
beq :+
lda #$00 ; TryHard = false
jsr TryToSend
; Check for buffer empty ; Check for buffer empty
: lda RecvFreeCnt ; (25) lda RecvFreeCnt ; (25)
cmp #$FF cmp #$FF
bne :+ bne :+
lda #SER_ERR_NO_DATA lda #SER_ERR_NO_DATA
@ -269,20 +263,21 @@ SER_GET:
SER_PUT: SER_PUT:
; Try to send ; Try to send
ldy SendFreeCnt ldy SendFreeCnt
iny ; Y = $FF? cpy #$FF ; Nothing to flush
beq :+ beq :+
pha pha
lda #$00 ; TryHard = false lda #$00 ; TryHard = false
jsr TryToSend jsr TryToSend
pla pla
; Put byte into send buffer & send ; Reload SendFreeCnt after TryToSend
: ldy SendFreeCnt ldy SendFreeCnt
bne :+ bne :+
lda #SER_ERR_OVERFLOW lda #SER_ERR_OVERFLOW
ldx #0 ; return value is char ldx #0 ; return value is char
rts rts
; Put byte into send buffer & send
: ldy SendTail : ldy SendTail
sta SendBuf,y sta SendBuf,y
inc SendTail inc SendTail
@ -329,19 +324,19 @@ SER_IRQ:
and #$08 and #$08
beq Done ; Jump if no ACIA interrupt beq Done ; Jump if no ACIA interrupt
lda ACIA::DATA,x ; Get byte from ACIA lda ACIA::DATA,x ; Get byte from ACIA
ldy RecvFreeCnt ; Check if we have free space left ldx RecvFreeCnt ; Check if we have free space left
beq Flow ; Jump if no space in receive buffer beq Flow ; Jump if no space in receive buffer
ldy RecvTail ; Load buffer pointer ldy RecvTail ; Load buffer pointer
sta RecvBuf,y ; Store received byte in buffer sta RecvBuf,y ; Store received byte in buffer
inc RecvTail ; Increment buffer pointer inc RecvTail ; Increment buffer pointer
dec RecvFreeCnt ; Decrement free space counter dec RecvFreeCnt ; Decrement free space counter
ldy RecvFreeCnt ; Check for buffer space low cpx #33
cpy #33
bcc Flow ; Assert flow control if buffer space low bcc Flow ; Assert flow control if buffer space low
rts ; Interrupt handled (carry already set) rts ; Interrupt handled (carry already set)
; Assert flow control if buffer space too low ; Assert flow control if buffer space too low
Flow: lda RtsOff Flow: ldx Index ; Reload port
lda RtsOff
sta ACIA::CMD,x sta ACIA::CMD,x
sta Stopped sta Stopped
sec ; Interrupt handled sec ; Interrupt handled
@ -352,12 +347,13 @@ Done: rts
TryToSend: TryToSend:
sta tmp1 ; Remember tryHard flag sta tmp1 ; Remember tryHard flag
Again: lda SendFreeCnt NextByte:
lda SendFreeCnt
cmp #$FF cmp #$FF
beq Quit ; Bail out beq Quit ; Bail out
; Check for flow stopped ; Check for flow stopped
lda Stopped Again: lda Stopped
bne Quit ; Bail out bne Quit ; Bail out
; Check that ACIA is ready to send ; Check that ACIA is ready to send
@ -374,4 +370,4 @@ Send: ldy SendHead
sta ACIA::DATA sta ACIA::DATA
inc SendHead inc SendHead
inc SendFreeCnt inc SendFreeCnt
jmp Again jmp NextByte

View File

@ -314,15 +314,10 @@ SER_CLOSE:
; ;
SER_GET: SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
jsr TryToSend
; Check for buffer empty ; Check for buffer empty
@L1: lda RecvFreeCnt ; (25) lda RecvFreeCnt ; (25)
cmp #$ff cmp #$ff
bne @L2 bne @L2
lda #SER_ERR_NO_DATA lda #SER_ERR_NO_DATA
@ -362,21 +357,23 @@ SER_PUT:
; Try to send ; Try to send
ldx SendFreeCnt ldx SendFreeCnt
inx ; X = $ff? cpx #$FF ; Nothing to flush
beq @L2 beq @L2
pha pha
lda #$00 lda #$00
jsr TryToSend jsr TryToSend
pla pla
; Put byte into send buffer & send ; Reload SendFreeCnt after TryToSend
@L2: ldx SendFreeCnt ldx SendFreeCnt
bne @L3 bne @L2
lda #SER_ERR_OVERFLOW ; X is already zero lda #SER_ERR_OVERFLOW ; X is already zero
rts rts
@L3: ldx SendTail ; Put byte into send buffer & send
@L2: ldx SendTail
sta SendBuf,x sta SendBuf,x
inc SendTail inc SendTail
dec SendFreeCnt dec SendFreeCnt
@ -466,25 +463,25 @@ NmiHandler:
sta tmp1 ; Remember tryHard flag sta tmp1 ; Remember tryHard flag
@L0: lda SendFreeCnt @L0: lda SendFreeCnt
cmp #$ff cmp #$ff
beq @L3 ; Bail out beq @L2 ; Bail out
; Check for flow stopped ; Check for flow stopped
@L1: lda Stopped @L1: lda Stopped
bne @L3 ; Bail out bne @L2 ; Bail out
; Check that swiftlink is ready to send ; Check that swiftlink is ready to send
@L2: lda ACIA_STATUS lda ACIA_STATUS
and #$10 and #$10
bne @L4 bne @L3
bit tmp1 ;keep trying if must try hard bit tmp1 ;keep trying if must try hard
bmi @L0 bmi @L1
@L3: rts @L2: rts
; Send byte and try again ; Send byte and try again
@L4: ldx SendHead @L3: ldx SendHead
lda SendBuf,x lda SendBuf,x
sta ACIA_DATA sta ACIA_DATA
inc SendHead inc SendHead

View File

@ -288,15 +288,10 @@ SER_CLOSE:
; ;
SER_GET: SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
jsr TryToSend
; Check for buffer empty ; Check for buffer empty
@L1: lda RecvFreeCnt ; (25) lda RecvFreeCnt ; (25)
cmp #$ff cmp #$ff
bne @L2 bne @L2
lda #SER_ERR_NO_DATA lda #SER_ERR_NO_DATA
@ -336,21 +331,23 @@ SER_PUT:
; Try to send ; Try to send
ldx SendFreeCnt ldx SendFreeCnt
inx ; X = $ff? cpx #$FF ; Nothing to flush
beq @L2 beq @L2
pha pha
lda #$00 lda #$00
jsr TryToSend jsr TryToSend
pla pla
; Put byte into send buffer & send ; Reload SendFreeCnt after TryToSend
@L2: ldx SendFreeCnt ldx SendFreeCnt
bne @L3 bne @L2
lda #SER_ERR_OVERFLOW ; X is already zero lda #SER_ERR_OVERFLOW ; X is already zero
rts rts
@L3: ldx SendTail ; Put byte into send buffer & send
@L2: ldx SendTail
sta SendBuf,x sta SendBuf,x
inc SendTail inc SendTail
dec SendFreeCnt dec SendFreeCnt
@ -443,25 +440,25 @@ NmiHandler:
sta tmp1 ; Remember tryHard flag sta tmp1 ; Remember tryHard flag
@L0: lda SendFreeCnt @L0: lda SendFreeCnt
cmp #$ff cmp #$ff
beq @L3 ; Bail out beq @L2 ; Bail out
; Check for flow stopped ; Check for flow stopped
@L1: lda Stopped @L1: lda Stopped
bne @L3 ; Bail out bne @L2 ; Bail out
; Check that swiftlink is ready to send ; Check that swiftlink is ready to send
@L2: lda ACIA_STATUS lda ACIA_STATUS
and #$10 and #$10
bne @L4 bne @L3
bit tmp1 ;keep trying if must try hard bit tmp1 ;keep trying if must try hard
bmi @L0 bmi @L1
@L3: rts @L2: rts
; Send byte and try again ; Send byte and try again
@L4: ldx SendHead @L3: ldx SendHead
lda SendBuf,x lda SendBuf,x
sta ACIA_DATA sta ACIA_DATA
inc SendHead inc SendHead

View File

@ -244,15 +244,10 @@ InvBaud:
; ;
SER_GET: SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
jsr TryToSend
; Check for buffer empty ; Check for buffer empty
@L1: lda RecvFreeCnt lda RecvFreeCnt
cmp #$ff cmp #$ff
bne @L2 bne @L2
lda #SER_ERR_NO_DATA lda #SER_ERR_NO_DATA
@ -292,21 +287,23 @@ SER_PUT:
; Try to send ; Try to send
ldx SendFreeCnt ldx SendFreeCnt
inx ; X = $ff? cpx #$FF ; Nothing to flush
beq @L2 beq @L2
pha pha
lda #$00 lda #$00
jsr TryToSend jsr TryToSend
pla pla
; Put byte into send buffer & send ; Reload SendFreeCnt after TryToSend
@L2: ldx SendFreeCnt ldx SendFreeCnt
bne @L3 bne @L2
lda #SER_ERR_OVERFLOW ; X is already zero lda #SER_ERR_OVERFLOW ; X is already zero
rts rts
@L3: ldx SendTail ; Put byte into send buffer & send
@L2: ldx SendTail
sta SendBuf,x sta SendBuf,x
inc SendTail inc SendTail
dec SendFreeCnt dec SendFreeCnt
@ -395,31 +392,31 @@ SER_IRQ:
sta IndReg ; Switch to the system bank sta IndReg ; Switch to the system bank
@L0: lda SendFreeCnt @L0: lda SendFreeCnt
cmp #$ff cmp #$ff
beq @L3 ; Bail out beq @L2 ; Bail out
; Check for flow stopped ; Check for flow stopped
@L1: lda Stopped @L1: lda Stopped
bne @L3 ; Bail out bne @L2 ; Bail out
; Check that swiftlink is ready to send ; Check that swiftlink is ready to send
@L2: ldy #ACIA::STATUS ldy #ACIA::STATUS
lda (acia),y lda (acia),y
and #$10 and #$10
bne @L4 bne @L3
bit tmp1 ; Keep trying if must try hard bit tmp1 ; Keep trying if must try hard
bmi @L0 bmi @L1
; Switch back the bank and return ; Switch back the bank and return
@L3: lda ExecReg @L2: lda ExecReg
sta IndReg sta IndReg
rts rts
; Send byte and try again ; Send byte and try again
@L4: ldx SendHead @L3: ldx SendHead
lda SendBuf,x lda SendBuf,x
ldy #ACIA::DATA ldy #ACIA::DATA
sta (acia),y sta (acia),y

View File

@ -245,15 +245,10 @@ InvBaud:
; ;
SER_GET: SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
jsr TryToSend
; Check for buffer empty ; Check for buffer empty
@L1: lda RecvFreeCnt lda RecvFreeCnt
cmp #$ff cmp #$ff
bne @L2 bne @L2
lda #SER_ERR_NO_DATA lda #SER_ERR_NO_DATA
@ -293,21 +288,23 @@ SER_PUT:
; Try to send ; Try to send
ldx SendFreeCnt ldx SendFreeCnt
inx ; X = $ff? cpx #$ff ; Nothing to flush
beq @L2 beq @L2
pha pha
lda #$00 lda #$00
jsr TryToSend jsr TryToSend
pla pla
; Put byte into send buffer & send ; Reload SendFreeCnt after TryToSend
@L2: ldx SendFreeCnt ldx SendFreeCnt
bne @L3 bne @L2
lda #SER_ERR_OVERFLOW ; X is already zero lda #SER_ERR_OVERFLOW ; X is already zero
rts rts
@L3: ldx SendTail ; Put byte into send buffer & send
@L2: ldx SendTail
sta SendBuf,x sta SendBuf,x
inc SendTail inc SendTail
dec SendFreeCnt dec SendFreeCnt
@ -395,31 +392,31 @@ SER_IRQ:
sta IndReg ; Switch to the system bank sta IndReg ; Switch to the system bank
@L0: lda SendFreeCnt @L0: lda SendFreeCnt
cmp #$ff cmp #$ff
beq @L3 ; Bail out beq @L2 ; Bail out
; Check for flow stopped ; Check for flow stopped
@L1: lda Stopped @L1: lda Stopped
bne @L3 ; Bail out bne @L2 ; Bail out
; Check that swiftlink is ready to send ; Check that swiftlink is ready to send
@L2: ldy #ACIA::STATUS ldy #ACIA::STATUS
lda (acia),y lda (acia),y
and #$10 and #$10
bne @L4 bne @L3
bit tmp1 ; Keep trying if must try hard bit tmp1 ; Keep trying if must try hard
bmi @L0 bmi @L1
; Switch back the bank and return ; Switch back the bank and return
@L3: lda ExecReg @L2: lda ExecReg
sta IndReg sta IndReg
rts rts
; Send byte and try again ; Send byte and try again
@L4: ldx SendHead @L3: ldx SendHead
lda SendBuf,x lda SendBuf,x
ldy #ACIA::DATA ldy #ACIA::DATA
sta (acia),y sta (acia),y

View File

@ -252,15 +252,10 @@ InvBaud:
; ;
SER_GET: SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
jsr TryToSend
; Check for buffer empty ; Check for buffer empty
@L1: lda RecvFreeCnt ; (25) lda RecvFreeCnt ; (25)
cmp #$ff cmp #$ff
bne @L2 bne @L2
lda #SER_ERR_NO_DATA lda #SER_ERR_NO_DATA
@ -300,21 +295,23 @@ SER_PUT:
; Try to send ; Try to send
ldx SendFreeCnt ldx SendFreeCnt
inx ; X = $ff? cpx #$ff ; Nothing to flush
beq @L2 beq @L2
pha pha
lda #$00 lda #$00
jsr TryToSend jsr TryToSend
pla pla
; Put byte into send buffer & send ; Reload SendFreeCnt after TryToSend
@L2: ldx SendFreeCnt ldx SendFreeCnt
bne @L3 bne @L2
lda #SER_ERR_OVERFLOW ; X is already zero lda #SER_ERR_OVERFLOW ; X is already zero
rts rts
@L3: ldx SendTail ; Put byte into send buffer & send
@L2: ldx SendTail
sta SendBuf,x sta SendBuf,x
inc SendTail inc SendTail
dec SendFreeCnt dec SendFreeCnt
@ -387,25 +384,25 @@ SER_IRQ:
sta tmp1 ; Remember tryHard flag sta tmp1 ; Remember tryHard flag
@L0: lda SendFreeCnt @L0: lda SendFreeCnt
cmp #$ff cmp #$ff
beq @L3 ; Bail out beq @L2 ; Bail out
; Check for flow stopped ; Check for flow stopped
@L1: lda Stopped @L1: lda Stopped
bne @L3 ; Bail out bne @L2 ; Bail out
; Check that swiftlink is ready to send ; Check that swiftlink is ready to send
@L2: lda ACIA_STATUS lda ACIA_STATUS
and #$10 and #$10
bne @L4 bne @L3
bit tmp1 ;keep trying if must try hard bit tmp1 ;keep trying if must try hard
bmi @L0 bmi @L1
@L3: rts @L2: rts
; Send byte and try again ; Send byte and try again
@L4: ldx SendHead @L3: ldx SendHead
lda SendBuf,x lda SendBuf,x
sta ACIA_DATA sta ACIA_DATA
inc SendHead inc SendHead