From 788ae82d30bcf29da0e160cd47532594780fe22b Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Fri, 9 Feb 2024 00:09:16 +0000 Subject: [PATCH 1/8] Fixes to serial driver implementation --- asminc/lynx.inc | 34 +++++++------- libsrc/lynx/crt0.s | 2 +- libsrc/lynx/ser/lynx-comlynx.s | 81 ++++++++++++++++++++-------------- 3 files changed, 67 insertions(+), 50 deletions(-) diff --git a/asminc/lynx.inc b/asminc/lynx.inc index 5ae17f6ef..d65b7f8a9 100644 --- a/asminc/lynx.inc +++ b/asminc/lynx.inc @@ -267,22 +267,26 @@ MIKEYHREV = $FD88 MIKEYSREV = $FD89 IODIR = $FD8A 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 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 SDONEACK = $FD90 CPUSLEEP = $FD91 diff --git a/libsrc/lynx/crt0.s b/libsrc/lynx/crt0.s index 238a2c99d..030f523e9 100644 --- a/libsrc/lynx/crt0.s +++ b/libsrc/lynx/crt0.s @@ -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. - lda #%00011101 + lda #PAREN|RESETERR|TXOPEN|PAREVEN ; #%00011101 sta SERCTL ; Clear all pending interrupts. diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 8aa3c838e..85703867b 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -73,7 +73,12 @@ SER_UNINSTALL: ; Must return an SER_ERR_xx code in a/x. 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 lda #SER_ERR_OK .assert SER_ERR_OK = 0, error @@ -108,7 +113,7 @@ SER_OPEN: stz TxPtrIn stz TxPtrOut - ; clock = 8 * 15625 + ; source period is 1 us lda #%00011000 sta TIM4CTLA ldy #SER_PARAMS::BAUDRATE @@ -118,7 +123,7 @@ SER_OPEN: cmp #SER_BAUD_62500 beq setbaudrate - ldx #2 + ldx #3 cmp #SER_BAUD_31250 beq setbaudrate @@ -194,13 +199,14 @@ SER_OPEN: lda #SER_ERR_BAUD_UNAVAIL ldx #0 ; return value is char rts + setprescaler: stx TIM4CTLA bra baudsuccess setbaudrate: stx TIM4BKUP baudsuccess: - ldx #TxOpenColl|ParEven + ldx #TXOPEN|PAREVEN stx contrl ldy #SER_PARAMS::DATABITS ; Databits lda (ptr1),y @@ -218,15 +224,15 @@ baudsuccess: beq checkhs cmp #SER_PAR_SPACE bne @L0 - ldx #TxOpenColl + ldx #TXOPEN stx contrl bra checkhs @L0: - ldx #TxParEnable|TxOpenColl|ParEven + ldx #PAREN|TXOPEN|PAREVEN stx contrl cmp #SER_PAR_EVEN beq checkhs - ldx #TxParEnable|TxOpenColl + ldx #PAREN|TXOPEN stx contrl checkhs: ldx contrl @@ -237,7 +243,7 @@ checkhs: bne invparameter lda SERDAT lda contrl - ora #RxIntEnable|ResetErr + ora #RXINTEN|RESETERR ; Turn on interrupts for receive sta SERCTL lda #SER_ERR_OK .assert SER_ERR_OK = 0, error @@ -279,24 +285,26 @@ SER_PUT: ina cmp TxPtrOut bne PutByte + lda #SER_ERR_OVERFLOW ldx #0 ; return value is char rts + PutByte: ldy TxPtrIn txa sta TxBuffer,y inc TxPtrIn - bit TxDone - bmi @L1 + bit TxDone ; Check bit 7 of TxDone (TXINTEN) + bmi @L1 ; Was TXINTEN already set? php sei - lda contrl - ora #TxIntEnable|ResetErr - sta SERCTL ; Allow TX-IRQ to hang RX-IRQ + lda contrl ; contrl does not include RXINTEN setting + ora #TXINTEN|RESETERR + sta SERCTL ; Allow TX-IRQ to hang RX-IRQ (no receive while transmitting) sta TxDone - plp + plp ; Restore processor and interrupt enable @L1: lda #SER_ERR_OK .assert SER_ERR_OK = 0, error @@ -308,7 +316,7 @@ PutByte: ; Must return an SER_ERR_xx code in a/x. SER_STATUS: - ldy SerialStat + lda SerialStat ldx #$00 sta (ptr1,x) txa ; Return code = 0 @@ -342,27 +350,32 @@ SER_IRQ: @L0: bit TxDone bmi @tx_irq ; Transmit in progress - ldx SERDAT - lda SERCTL - and #RxParityErr|RxOverrun|RxFrameErr|RxBreak - beq @rx_irq + + ldx SERDAT ; Read received data + lda contrl + 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 - bit #RxBreak + bit #RXBRK ; Check for break signal beq @noBreak + stz TxPtrIn ; Break received - drop buffers stz TxPtrOut stz RxPtrIn stz RxPtrOut @noBreak: lda contrl - ora #RxIntEnable|ResetErr + ora #RXINTEN|RESETERR sta SERCTL - lda #$10 - sta INTRST bra @IRQexit + @rx_irq: lda contrl - ora #RxIntEnable|ResetErr + ora #RXINTEN|RESETERR sta SERCTL txa ldx RxPtrIn @@ -370,20 +383,22 @@ SER_IRQ: txa inx -@cont0: cpx RxPtrOut beq @1 stx RxPtrIn - lda #SERIAL_INTERRUPT - sta INTRST bra @IRQexit @1: sta RxPtrIn lda #$80 tsb SerialStat + lda contrl + ora #RXINTEN|RESETERR + sta SERCTL + bra @IRQexit + @tx_irq: - ldx TxPtrOut ; Has all bytes been sent? + ldx TxPtrOut ; Have all bytes been sent? cpx TxPtrIn beq @allSent @@ -393,24 +408,22 @@ SER_IRQ: @exit1: lda contrl - ora #TxIntEnable|ResetErr + ora #TXINTEN|RESETERR sta SERCTL - lda #SERIAL_INTERRUPT - sta INTRST bra @IRQexit @allSent: lda SERCTL ; All bytes sent - bit #TxEmpty + bit #TXEMPTY beq @exit1 bvs @exit1 stz TxDone lda contrl - ora #RxIntEnable|ResetErr + ora #RXINTEN|RESETERR ; Re-enable receive interrupt sta SERCTL +@IRQexit: lda #SERIAL_INTERRUPT sta INTRST -@IRQexit: clc rts From 014f85f226b38f434722ecc085d621e9d3d730d1 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Fri, 9 Feb 2024 10:42:52 +0000 Subject: [PATCH 2/8] Fixed baud rates --- libsrc/lynx/ser/lynx-comlynx.s | 86 +++++++++++++--------------------- 1 file changed, 33 insertions(+), 53 deletions(-) diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 85703867b..9564bcb4f 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -113,12 +113,12 @@ SER_OPEN: stz TxPtrIn stz TxPtrOut - ; source period is 1 us - lda #%00011000 - sta TIM4CTLA ldy #SER_PARAMS::BAUDRATE lda (ptr1),y + ; Source period is 1 us + ldy #%00011000 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_1 + ldx #1 cmp #SER_BAUD_62500 beq setbaudrate @@ -139,6 +139,10 @@ SER_OPEN: cmp #SER_BAUD_2400 beq setbaudrate + ldx #68 + cmp #SER_BAUD_1800 + beq setbaudrate + ldx #103 cmp #SER_BAUD_1200 beq setbaudrate @@ -147,65 +151,48 @@ SER_OPEN: cmp #SER_BAUD_600 beq setbaudrate - ; clock = 6 * 15625 - ldx #%00011010 - stx TIM4CTLA + ; Source period is 4 us + ldy #%00011011 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_8 - ldx #12 - cmp #SER_BAUD_7200 - beq setbaudrate - - ldx #25 - cmp #SER_BAUD_3600 - beq setbaudrate - - ldx #207 - stx TIM4BKUP - - ; clock = 4 * 15625 - ldx #%00011100 + ldx #51 cmp #SER_BAUD_300 - beq setprescaler + beq setbaudrate - ; clock = 6 * 15625 - ldx #%00011110 + ldx #103 cmp #SER_BAUD_150 - beq setprescaler + beq setbaudrate - ; clock = 1 * 15625 - ldx #%00011111 - stx TIM4CTLA - cmp #SER_BAUD_75 - beq baudsuccess + ldx #115 + cmp #SER_BAUD_134_5 + beq setbaudrate ldx #141 cmp #SER_BAUD_110 beq setbaudrate - ; clock = 2 * 15625 - ldx #%00011010 - stx TIM4CTLA - ldx #68 - cmp #SER_BAUD_1800 + ; Source period is 32 us + ldy #%00011101 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_32 + + ldx #51 + cmp #SER_BAUD_75 beq setbaudrate - ; clock = 6 * 15625 - ldx #%00011110 - stx TIM4CTLA - ldx #231 - cmp #SER_BAUD_134_5 + ldx #68 + cmp #SER_BAUD_56_875 + beq setbaudrate + + ldx #77 + cmp #SER_BAUD_50 beq setbaudrate lda #SER_ERR_BAUD_UNAVAIL ldx #0 ; return value is char rts -setprescaler: - stx TIM4CTLA - bra baudsuccess setbaudrate: + sty TIM4CTLA stx TIM4BKUP -baudsuccess: + ldx #TXOPEN|PAREVEN stx contrl ldy #SER_PARAMS::DATABITS ; Databits @@ -368,15 +355,9 @@ SER_IRQ: stz RxPtrIn stz RxPtrOut @noBreak: - lda contrl - ora #RXINTEN|RESETERR - sta SERCTL - bra @IRQexit + bra @exit0 @rx_irq: - lda contrl - ora #RXINTEN|RESETERR - sta SERCTL txa ldx RxPtrIn sta RxBuffer,x @@ -392,10 +373,7 @@ SER_IRQ: sta RxPtrIn lda #$80 tsb SerialStat - lda contrl - ora #RXINTEN|RESETERR - sta SERCTL - bra @IRQexit + bra @exit0 @tx_irq: ldx TxPtrOut ; Have all bytes been sent? @@ -418,6 +396,8 @@ SER_IRQ: beq @exit1 bvs @exit1 stz TxDone + +@exit0: lda contrl ora #RXINTEN|RESETERR ; Re-enable receive interrupt sta SERCTL From 65bce9ecdeda7a2214a27fafa4ccbfcd5daa5449 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Fri, 9 Feb 2024 12:54:00 +0000 Subject: [PATCH 3/8] Implemented mark and space checks. --- libsrc/lynx/ser/lynx-comlynx.s | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 9564bcb4f..3b6f18af6 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -151,7 +151,7 @@ SER_OPEN: cmp #SER_BAUD_600 beq setbaudrate - ; Source period is 4 us + ; Source period is 8 us ldy #%00011011 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_8 ldx #51 @@ -341,8 +341,9 @@ SER_IRQ: ldx SERDAT ; Read received data lda contrl and #PAREN ; Parity enabled implies SER_PAR_EVEN or SER_PAR_ODD + tay ora #OVERRUN|FRAMERR|RXBRK - bit SERCTL ; Compare with SERCTL + bit SERCTL ; Check error flags in SERCTL beq @rx_irq ; No errors so far @@ -358,6 +359,15 @@ SER_IRQ: bra @exit0 @rx_irq: + tya + bne @2 ; Parity was enabled so no marker bit check needed + + lda contrl + eor SERCTL ; Should match current parity bit + and #PARBIT ; Check for mark or space value + bne @exit0 + +@2: txa ldx RxPtrIn sta RxBuffer,x From 6cf8ee8eb563f50ceef74605a95e202054e2991c Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Sat, 10 Feb 2024 21:15:05 +0000 Subject: [PATCH 4/8] Removed baud rates from 150 and lower. Fixed tab Replaced uploader references to SERIAL_INTERRUPT --- libsrc/lynx/ser/lynx-comlynx.s | 31 ++----------------------------- libsrc/lynx/uploader.s | 6 +++--- 2 files changed, 5 insertions(+), 32 deletions(-) diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 3b6f18af6..486981184 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -158,33 +158,6 @@ SER_OPEN: cmp #SER_BAUD_300 beq setbaudrate - ldx #103 - cmp #SER_BAUD_150 - beq setbaudrate - - ldx #115 - cmp #SER_BAUD_134_5 - beq setbaudrate - - ldx #141 - cmp #SER_BAUD_110 - beq setbaudrate - - ; Source period is 32 us - ldy #%00011101 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_32 - - ldx #51 - cmp #SER_BAUD_75 - beq setbaudrate - - ldx #68 - cmp #SER_BAUD_56_875 - beq setbaudrate - - ldx #77 - cmp #SER_BAUD_50 - beq setbaudrate - lda #SER_ERR_BAUD_UNAVAIL ldx #0 ; return value is char rts @@ -342,8 +315,8 @@ SER_IRQ: lda contrl and #PAREN ; Parity enabled implies SER_PAR_EVEN or SER_PAR_ODD tay - ora #OVERRUN|FRAMERR|RXBRK - bit SERCTL ; Check error flags in SERCTL + ora #OVERRUN|FRAMERR|RXBRK + bit SERCTL ; Check presence of relevant error flags in SERCTL beq @rx_irq ; No errors so far diff --git a/libsrc/lynx/uploader.s b/libsrc/lynx/uploader.s index df3e5df40..5ce21b489 100644 --- a/libsrc/lynx/uploader.s +++ b/libsrc/lynx/uploader.s @@ -40,14 +40,14 @@ cont1: bra loop1 read_byte: - bit SERCTL + bit SERCTL ; Check for RXRDY ($40) bvc read_byte lda SERDAT rts _UpLoaderIRQ: lda INTSET - and #$10 + and #SERIAL_INTERRUPT bne @L0 clc rts @@ -69,7 +69,7 @@ again: ; last action : clear interrupt ; exit: - lda #$10 + lda #SERIAL_INTERRUPT sta INTRST clc rts From acff429eb8788ab6f1b1e40bb8cef0ac7de94930 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Sun, 11 Feb 2024 15:33:22 +0000 Subject: [PATCH 5/8] Added redeye check for SER_HS_SW handshake --- asminc/lynx.inc | 16 +++++++++++++--- libsrc/lynx/ser/lynx-comlynx.s | 12 ++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/asminc/lynx.inc b/asminc/lynx.inc index d65b7f8a9..0d34e1c7c 100644 --- a/asminc/lynx.inc +++ b/asminc/lynx.inc @@ -259,16 +259,26 @@ SND_INTERRUPT = TIMER7_INTERRUPT INTRST = $FD80 INTSET = $FD81 + MAGRDY0 = $FD84 MAGRDY1 = $FD85 AUDIN = $FD86 SYSCTL1 = $FD87 MIKEYHREV = $FD88 MIKEYSREV = $FD89 -IODIR = $FD8A -IODAT = $FD8B -SERCTL = $FD8C +IODIR = $FD8A +IODAT = $FD8B +; IODIR and IODAT bit definitions +AUDIN_BIT = $10 ; Note that there is also the address AUDIN +READ_ENABLE = $10 ; Same bit for AUDIN_BIT +RESTLESS = $08 +NOEXP = $04 ; If set, redeye is not connected +CART_ADDR_DATA = $02 +CART_POWER_OFF = $02 ; Same bit for CART_ADDR_DATA +EXTERNAL_POWER = $01 + +SERCTL = $FD8C ; SERCTL bit definitions for write operations TXINTEN = $80 RXINTEN = $40 diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 486981184..7201264b7 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -200,7 +200,18 @@ checkhs: ldy #SER_PARAMS::HANDSHAKE ; Handshake lda (ptr1),y cmp #SER_HS_NONE + beq redeye_ok + cmp #SER_HS_SW ; Software handshake will check for connected redeye bne invparameter + + lda IODAT + and #NOEXP ; Check if redeye bit flag is unset + beq redeye_ok + lda #SER_ERR_NO_DEVICE ; ComLynx cable is not inserted + ldx #0 + rts + +redeye_ok: lda SERDAT lda contrl ora #RXINTEN|RESETERR ; Turn on interrupts for receive @@ -209,6 +220,7 @@ checkhs: .assert SER_ERR_OK = 0, error tax rts + invparameter: lda #SER_ERR_INIT_FAILED ldx #0 ; return value is char From 1deb9e52aec938ae338168035c743b04b91e20d0 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Sun, 11 Feb 2024 15:46:23 +0000 Subject: [PATCH 6/8] Replaced last literal value for SERCTL --- libsrc/lynx/ser/lynx-comlynx.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 7201264b7..9b007c6e0 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -74,7 +74,7 @@ SER_UNINSTALL: SER_CLOSE: ; Disable interrupts and stop timer 4 (serial) - lda #$0C ; TXOPEN|RESETERR + lda #TXOPEN|RESETERR sta SERCTL lda #$00 ; Disable count and no reload sta TIM4CTLA From 8b172e05bc4c39b53ee1dd05be082c01fea0d7e0 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Sun, 11 Feb 2024 20:59:08 +0000 Subject: [PATCH 7/8] Applied optimization as per review 42Bastian --- libsrc/lynx/ser/lynx-comlynx.s | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 9b007c6e0..aa4d71ad3 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -76,8 +76,7 @@ SER_CLOSE: ; Disable interrupts and stop timer 4 (serial) lda #TXOPEN|RESETERR sta SERCTL - lda #$00 ; Disable count and no reload - sta TIM4CTLA + stz TIM4CTLA ; Disable count and no reload ; Done, return an error code lda #SER_ERR_OK From 7d6f3d24d434953679c176708c67a0abc845eaa0 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Sun, 11 Feb 2024 23:12:27 +0000 Subject: [PATCH 8/8] Changed sta (ptr1,x) to sta (ptr1) Reset serial status on ser_close Fixed error for saving serial state --- libsrc/lynx/ser/lynx-comlynx.s | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index aa4d71ad3..c4ae3d5b6 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -76,7 +76,8 @@ SER_CLOSE: ; Disable interrupts and stop timer 4 (serial) lda #TXOPEN|RESETERR sta SERCTL - stz TIM4CTLA ; Disable count and no reload + stz TIM4CTLA ; Disable count and no reload + stz SerialStat ; Reset status ; Done, return an error code lda #SER_ERR_OK @@ -241,8 +242,8 @@ GetByte: ldy RxPtrOut lda RxBuffer,y inc RxPtrOut + sta (ptr1) ldx #$00 - sta (ptr1,x) txa ; Return code = 0 rts @@ -288,8 +289,8 @@ PutByte: SER_STATUS: lda SerialStat + sta (ptr1) ldx #$00 - sta (ptr1,x) txa ; Return code = 0 rts @@ -327,7 +328,7 @@ SER_IRQ: and #PAREN ; Parity enabled implies SER_PAR_EVEN or SER_PAR_ODD tay ora #OVERRUN|FRAMERR|RXBRK - bit SERCTL ; Check presence of relevant error flags in SERCTL + and SERCTL ; Check presence of relevant error flags in SERCTL beq @rx_irq ; No errors so far