mirror of
https://github.com/cc65/cc65.git
synced 2025-01-01 03:30:20 +00:00
Cleanup coding style a bit
This commit is contained in:
parent
4ff917816e
commit
df4902157a
@ -38,8 +38,8 @@
|
||||
.endif
|
||||
|
||||
; Driver signature
|
||||
.byte $73, $65, $72 ; "ser"
|
||||
.byte SER_API_VERSION ; Serial API version number
|
||||
.byte $73, $65, $72 ; "ser"
|
||||
.byte SER_API_VERSION ; Serial API version number
|
||||
|
||||
; Library reference
|
||||
.addr $0000
|
||||
@ -59,16 +59,16 @@
|
||||
; I/O definitions
|
||||
|
||||
.if (.cpu .bitand CPU_ISET_65C02)
|
||||
ACIA = $C088
|
||||
ACIA := $C088
|
||||
.else
|
||||
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_STATUS = ACIA+1 ; Status register
|
||||
ACIA_CMD = ACIA+2 ; Command register
|
||||
ACIA_CTRL = ACIA+3 ; Control register
|
||||
ACIA_DATA := ACIA+0 ; Data register
|
||||
ACIA_STATUS := ACIA+1 ; Status register
|
||||
ACIA_CMD := ACIA+2 ; Command register
|
||||
ACIA_CTRL := ACIA+3 ; Control register
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Global variables
|
||||
@ -77,16 +77,17 @@ ACIA_CTRL = ACIA+3 ; Control register
|
||||
|
||||
RecvHead: .res 1 ; Head of receive buffer
|
||||
RecvTail: .res 1 ; Tail of receive buffer
|
||||
RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
|
||||
RecvFreeCnt: .res 1 ; Number of free bytes in receive buffer
|
||||
SendHead: .res 1 ; Head of send buffer
|
||||
SendTail: .res 1 ; Tail of send buffer
|
||||
SendFreeCnt: .res 1 ; Number of bytes in send buffer
|
||||
SendFreeCnt: .res 1 ; Number of free bytes in send buffer
|
||||
|
||||
Stopped: .res 1 ; Flow-stopped flag
|
||||
RtsOff: .res 1 ;
|
||||
RtsOff: .res 1 ; Cached value of command register with
|
||||
; flow stopped
|
||||
|
||||
RecvBuf: .res 256 ; Receive buffers: 256 bytes
|
||||
SendBuf: .res 256 ; Send buffers: 256 bytes
|
||||
RecvBuf: .res 256 ; Receive buffer: 256 bytes
|
||||
SendBuf: .res 256 ; Send buffer: 256 bytes
|
||||
|
||||
Index: .res 1 ; I/O register index
|
||||
|
||||
@ -96,8 +97,9 @@ Slot: .byte $02 ; Default to SSC in slot 2
|
||||
|
||||
.rodata
|
||||
|
||||
; Tables used to translate RS232 params into register values
|
||||
BaudTable: ; bit7 = 1 means setting is invalid
|
||||
BaudTable: ; Table used to translate RS232 baudrate param
|
||||
; into control register value
|
||||
; bit7 = 1 means setting is invalid
|
||||
.byte $FF ; SER_BAUD_45_5
|
||||
.byte $01 ; SER_BAUD_50
|
||||
.byte $02 ; SER_BAUD_75
|
||||
@ -118,49 +120,55 @@ BaudTable: ; bit7 = 1 means setting is invalid
|
||||
.byte $FF ; SER_BAUD_57600
|
||||
.byte $FF ; SER_BAUD_115200
|
||||
.byte $FF ; SER_BAUD_230400
|
||||
BitTable:
|
||||
|
||||
BitTable: ; Table used to translate RS232 databits param
|
||||
; into control register value
|
||||
.byte $60 ; SER_BITS_5
|
||||
.byte $40 ; SER_BITS_6
|
||||
.byte $20 ; SER_BITS_7
|
||||
.byte $00 ; SER_BITS_8
|
||||
StopTable:
|
||||
|
||||
StopTable: ; Table used to translate RS232 stopbits param
|
||||
; into control register value
|
||||
.byte $00 ; SER_STOP_1
|
||||
.byte $80 ; SER_STOP_2
|
||||
ParityTable:
|
||||
|
||||
ParityTable: ; Table used to translate RS232 parity param
|
||||
; into command register value
|
||||
.byte $00 ; SER_PAR_NONE
|
||||
.byte $20 ; SER_PAR_ODD
|
||||
.byte $60 ; SER_PAR_EVEN
|
||||
.byte $A0 ; SER_PAR_MARK
|
||||
.byte $E0 ; SER_PAR_SPACE
|
||||
|
||||
; Check five bytes at known positions on the
|
||||
; slot's firmware to make sure this is an SSC
|
||||
; (or Apple //c comm port) firmware that drives
|
||||
; an ACIA 6551 chip.
|
||||
;
|
||||
; The SSC firmware and the Apple //c(+) comm
|
||||
; port firmware all begin with a BIT instruction.
|
||||
; The IIgs, on the other hand, has a
|
||||
; Zilog Z8530 chip and its firmware starts with
|
||||
; a SEP instruction. We don't want to load this
|
||||
; driver on the IIgs' serial port. We'll
|
||||
; differentiate the firmware on this byte.
|
||||
;
|
||||
; The next four bytes we check are the Pascal
|
||||
; Firmware Protocol Bytes that identify a
|
||||
; serial card. Those are the same bytes for
|
||||
; SSC firmwares, Apple //c firmwares and IIgs
|
||||
; Zilog Z8530 firmwares - which is the reason
|
||||
; we have to check for the firmware's first
|
||||
; instruction too.
|
||||
|
||||
IdOfsTable:
|
||||
IdOfsTable: ; Table of bytes positions, used to check five
|
||||
; specific bytes on the slot's firmware to make
|
||||
; sure this is an SSC (or Apple //c comm port)
|
||||
; firmware that drives an ACIA 6551 chip.
|
||||
;
|
||||
; The SSC firmware and the Apple //c(+) comm
|
||||
; port firmware all begin with a BIT instruction.
|
||||
; The IIgs, on the other hand, has a
|
||||
; Zilog Z8530 chip and its firmware starts with
|
||||
; a SEP instruction. We don't want to load this
|
||||
; driver on the IIgs' serial port. We'll
|
||||
; differentiate the firmware on this byte.
|
||||
;
|
||||
; The next four bytes we check are the Pascal
|
||||
; Firmware Protocol Bytes that identify a
|
||||
; serial card. Those are the same bytes for
|
||||
; SSC firmwares, Apple //c firmwares and IIgs
|
||||
; Zilog Z8530 firmwares - which is the reason
|
||||
; we have to check for the firmware's first
|
||||
; instruction too.
|
||||
.byte $00 ; First instruction
|
||||
.byte $05 ; Pascal 1.0 ID byte
|
||||
.byte $07 ; Pascal 1.0 ID byte
|
||||
.byte $0B ; Pascal 1.1 generic signature byte
|
||||
.byte $0C ; Device signature byte
|
||||
IdValTable:
|
||||
|
||||
IdValTable: ; Table of expected values for the five checked
|
||||
; bytes
|
||||
.byte $2C ; BIT
|
||||
.byte $38 ; ID Byte 0 (from Pascal 1.0), fixed
|
||||
.byte $18 ; ID Byte 1 (from Pascal 1.0), fixed
|
||||
@ -193,12 +201,10 @@ SER_CLOSE:
|
||||
ldx Index ; Check for open port
|
||||
beq :+
|
||||
|
||||
; Deactivate DTR and disable 6551 interrupts
|
||||
lda #%00001010
|
||||
lda #%00001010 ; Deactivate DTR and disable 6551 interrupts
|
||||
sta ACIA_CMD,x
|
||||
|
||||
; Done, return an error code
|
||||
: lda #SER_ERR_OK
|
||||
: lda #SER_ERR_OK ; Done, return an error code
|
||||
.assert SER_ERR_OK = 0, error
|
||||
tax
|
||||
stx Index ; Mark port as closed
|
||||
@ -215,98 +221,96 @@ SER_OPEN:
|
||||
ora Slot
|
||||
sta ptr2+1
|
||||
|
||||
; Check Pascal 1.1 Firmware Protocol ID bytes
|
||||
: ldy IdOfsTable,x
|
||||
: ldy IdOfsTable,x ; Check Pascal 1.1 Firmware Protocol ID bytes
|
||||
lda IdValTable,x
|
||||
cmp (ptr2),y
|
||||
bne NoDevice
|
||||
bne NoDev
|
||||
inx
|
||||
cpx #IdTableLen
|
||||
bcc :-
|
||||
|
||||
; Convert slot to I/O register index
|
||||
lda Slot
|
||||
lda Slot ; Convert slot to I/O register index
|
||||
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
|
||||
|
||||
; Check if the handshake setting is valid
|
||||
ldy #SER_PARAMS::HANDSHAKE ; Handshake
|
||||
ldy #SER_PARAMS::HANDSHAKE
|
||||
lda (ptr1),y
|
||||
cmp #SER_HS_HW ; This is all we support
|
||||
bne InvParam
|
||||
cmp #SER_HS_HW ; This is all we support
|
||||
bne InvParm
|
||||
|
||||
; Initialize buffers
|
||||
ldy #$00
|
||||
ldy #$00 ; Initialize buffers
|
||||
sty Stopped
|
||||
sty RecvHead
|
||||
sty RecvTail
|
||||
sty SendHead
|
||||
sty SendTail
|
||||
dey ; Y = 255
|
||||
dey ; Y = 255
|
||||
sty RecvFreeCnt
|
||||
sty SendFreeCnt
|
||||
|
||||
; Set the value for the control register, which contains stop bits,
|
||||
; word length and the baud rate.
|
||||
ldy #SER_PARAMS::BAUDRATE
|
||||
lda (ptr1),y ; Baudrate index
|
||||
lda (ptr1),y ; Baudrate index
|
||||
tay
|
||||
lda BaudTable,y ; Get 6551 value
|
||||
bmi InvBaud ; Branch if rate not supported
|
||||
lda BaudTable,y ; Get 6551 value
|
||||
bmi InvBaud ; Branch if rate not supported
|
||||
sta tmp1
|
||||
|
||||
ldy #SER_PARAMS::DATABITS ; Databits
|
||||
lda (ptr1),y
|
||||
ldy #SER_PARAMS::DATABITS
|
||||
lda (ptr1),y ; Databits index
|
||||
tay
|
||||
lda BitTable,y
|
||||
lda BitTable,y ; Get 6551 value
|
||||
ora tmp1
|
||||
sta tmp1
|
||||
|
||||
ldy #SER_PARAMS::STOPBITS ; Stopbits
|
||||
lda (ptr1),y
|
||||
ldy #SER_PARAMS::STOPBITS
|
||||
lda (ptr1),y ; Stopbits index
|
||||
tay
|
||||
lda StopTable,y
|
||||
lda StopTable,y ; Get 6551 value
|
||||
ora tmp1
|
||||
ora #%00010000 ; Receiver clock source = baudrate
|
||||
ora #%00010000 ; Set receiver clock source = baudrate
|
||||
sta ACIA_CTRL,x
|
||||
|
||||
; Set the value for the command register. We remember the base value
|
||||
; in RtsOff, since we will have to manipulate ACIA_CMD often.
|
||||
ldy #SER_PARAMS::PARITY ; Parity
|
||||
lda (ptr1),y
|
||||
ldy #SER_PARAMS::PARITY
|
||||
lda (ptr1),y ; Parity index
|
||||
tay
|
||||
lda ParityTable,y
|
||||
ora #%00000001 ; DTR active
|
||||
sta RtsOff
|
||||
ora #%00001000 ; Enable receive interrupts
|
||||
lda ParityTable,y ; Get 6551 value
|
||||
|
||||
ora #%00000001 ; Set DTR active
|
||||
sta RtsOff ; Store value to easily handle flow control later
|
||||
ora #%00001000 ; Enable receive interrupts (RTS low)
|
||||
sta ACIA_CMD,x
|
||||
|
||||
; Done
|
||||
stx Index ; Mark port as open
|
||||
stx Index ; Mark port as open
|
||||
lda #SER_ERR_OK
|
||||
.assert SER_ERR_OK = 0, error
|
||||
tax
|
||||
rts
|
||||
|
||||
; Device (hardware) not found
|
||||
NoDevice:lda #SER_ERR_NO_DEVICE
|
||||
ldx #0 ; return value is char
|
||||
NoDev: lda #SER_ERR_NO_DEVICE
|
||||
ldx #$00 ; return value is char
|
||||
rts
|
||||
|
||||
; Invalid parameter
|
||||
InvParam:lda #SER_ERR_INIT_FAILED
|
||||
ldx #0 ; return value is char
|
||||
InvParm:lda #SER_ERR_INIT_FAILED
|
||||
ldx #$00 ; return value is char
|
||||
rts
|
||||
|
||||
; Baud rate not available
|
||||
InvBaud:lda #SER_ERR_BAUD_UNAVAIL
|
||||
ldx #0 ; return value is char
|
||||
ldx #$00 ; return value is char
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
@ -317,21 +321,19 @@ InvBaud:lda #SER_ERR_BAUD_UNAVAIL
|
||||
SER_GET:
|
||||
ldx Index
|
||||
|
||||
; Check for buffer empty
|
||||
lda RecvFreeCnt ; (25)
|
||||
lda RecvFreeCnt ; Check for buffer empty
|
||||
cmp #$FF
|
||||
bne :+
|
||||
lda #SER_ERR_NO_DATA
|
||||
ldx #0 ; return value is char
|
||||
ldx #$00 ; return value is char
|
||||
rts
|
||||
|
||||
; Check for flow stopped & enough free: release flow control
|
||||
: ldy Stopped ; (34)
|
||||
: ldy Stopped ; Check for flow stopped
|
||||
beq :+
|
||||
cmp #63
|
||||
cmp #63 ; Enough free?
|
||||
bcc :+
|
||||
.if (.cpu .bitand CPU_ISET_65C02)
|
||||
stz Stopped
|
||||
stz Stopped ; Release flow control
|
||||
.else
|
||||
lda #$00
|
||||
sta Stopped
|
||||
@ -340,14 +342,13 @@ SER_GET:
|
||||
ora #%00001000
|
||||
sta ACIA_CMD,x
|
||||
|
||||
; Get byte from buffer
|
||||
: ldy RecvHead ; (41)
|
||||
: ldy RecvHead ; Get byte from buffer
|
||||
lda RecvBuf,y
|
||||
inc RecvHead
|
||||
inc RecvFreeCnt
|
||||
ldx #$00 ; (59)
|
||||
ldx #$00
|
||||
.if (.cpu .bitand CPU_ISET_65C02)
|
||||
sta (ptr1)
|
||||
sta (ptr1) ; Store it for caller
|
||||
.else
|
||||
sta (ptr1,x)
|
||||
.endif
|
||||
@ -361,29 +362,26 @@ SER_GET:
|
||||
SER_PUT:
|
||||
ldx Index
|
||||
|
||||
; Try to send
|
||||
ldy SendFreeCnt
|
||||
cpy #$FF ; Nothing to flush
|
||||
ldy SendFreeCnt ; Anything to send first?
|
||||
cpy #$FF ; No
|
||||
beq :+
|
||||
pha
|
||||
lda #$00 ; TryHard = false
|
||||
jsr TryToSend
|
||||
jsr TryToSend ; Try to flush send buffer
|
||||
pla
|
||||
|
||||
; Reload SendFreeCnt after TryToSend
|
||||
ldy SendFreeCnt
|
||||
ldy SendFreeCnt ; Reload SendFreeCnt after TryToSend
|
||||
bne :+
|
||||
lda #SER_ERR_OVERFLOW
|
||||
ldx #0 ; return value is char
|
||||
ldx #$00 ; return value is char
|
||||
rts
|
||||
|
||||
; Put byte into send buffer & send
|
||||
: ldy SendTail
|
||||
: ldy SendTail ; Put byte into send buffer
|
||||
sta SendBuf,y
|
||||
inc SendTail
|
||||
dec SendFreeCnt
|
||||
lda #$FF ; TryHard = true
|
||||
jsr TryToSend
|
||||
jsr TryToSend ; Flush send buffer
|
||||
lda #SER_ERR_OK
|
||||
.assert SER_ERR_OK = 0, error
|
||||
tax
|
||||
@ -405,26 +403,25 @@ SER_STATUS:
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
|
||||
; specific data in ptr1, and the ioctl code in A.
|
||||
; The ioctl data is the slot number to open.
|
||||
; Must return an SER_ERR_xx code in a/x.
|
||||
|
||||
SER_IOCTL:
|
||||
; Check data msb and code to be 0
|
||||
ora ptr1+1
|
||||
ora ptr1+1 ; Check data msb and code to be 0
|
||||
bne :+
|
||||
|
||||
; Check data lsb to be [1..7]
|
||||
ldx ptr1
|
||||
ldx ptr1 ; Check data lsb to be [1..7]
|
||||
beq :+
|
||||
cpx #7+1
|
||||
bcs :+
|
||||
|
||||
stx Slot
|
||||
stx Slot ; Store slot
|
||||
.assert SER_ERR_OK = 0, error
|
||||
tax
|
||||
rts
|
||||
|
||||
: lda #SER_ERR_INV_IOCTL
|
||||
ldx #0 ; return value is char
|
||||
ldx #$00 ; return value is char
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
@ -450,8 +447,7 @@ SER_IRQ:
|
||||
bcc Flow ; Assert flow control if buffer space low
|
||||
rts ; Interrupt handled (carry already set)
|
||||
|
||||
; Assert flow control if buffer space too low
|
||||
Flow: ldx Index
|
||||
Flow: ldx Index ; Assert flow control if buffer space too low
|
||||
lda RtsOff
|
||||
sta ACIA_CMD,x
|
||||
sta Stopped
|
||||
@ -464,26 +460,23 @@ Done: rts
|
||||
TryToSend:
|
||||
sta tmp1 ; Remember tryHard flag
|
||||
NextByte:
|
||||
lda SendFreeCnt
|
||||
cmp #$FF
|
||||
beq Quit ; Bail out
|
||||
lda SendFreeCnt ; Is there anything to send? This can happen if
|
||||
cmp #$FF ; we got interrupted by RX while sending, and
|
||||
beq Quit ; flow control was asserted.
|
||||
|
||||
; Check for flow stopped
|
||||
Again: lda Stopped
|
||||
bne Quit ; Bail out
|
||||
Again: lda Stopped ; Is flow stopped?
|
||||
bne Quit ; Yes, Bail out
|
||||
|
||||
; Check that ACIA is ready to send
|
||||
lda ACIA_STATUS,x
|
||||
lda ACIA_STATUS,x ; Check that ACIA is ready to send
|
||||
and #$10
|
||||
bne Send
|
||||
bne Send ; It is!
|
||||
bit tmp1 ; Keep trying if must try hard
|
||||
bmi Again
|
||||
Quit: rts
|
||||
|
||||
; Send byte and try again
|
||||
Send: ldy SendHead
|
||||
Send: ldy SendHead ; Get first byte to send
|
||||
lda SendBuf,y
|
||||
sta ACIA_DATA,x
|
||||
sta ACIA_DATA,x ; Send it
|
||||
inc SendHead
|
||||
inc SendFreeCnt
|
||||
jmp NextByte
|
||||
jmp NextByte ; And try next one
|
||||
|
Loading…
Reference in New Issue
Block a user