From: uz Date: Sun, 20 Sep 2009 16:47:30 +0000 (+0000) Subject: Renamed the comlynx source and driver to lynx-comlynx, so it follows the X-Git-Tag: V2.13.0rc1~55 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=95b70fe0fc040f31b8e7f686bd6e9d9b8fd39b4f;p=cc65 Renamed the comlynx source and driver to lynx-comlynx, so it follows the existing naming conventions. git-svn-id: svn://svn.cc65.org/cc65/trunk@4201 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/libsrc/lynx/Makefile b/libsrc/lynx/Makefile index 76643b0b7..b355d9e8b 100644 --- a/libsrc/lynx/Makefile +++ b/libsrc/lynx/Makefile @@ -46,7 +46,6 @@ CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include # Object files OBJS = cgetc.o \ - comlynx.o \ crt0.o \ ctype.o \ eeprom.o \ @@ -65,7 +64,7 @@ JOYS = lynx-stdjoy.joy MOUS = -SERS = +SERS = lynx-comlynx.ser TGIS = lynx-160-102-16.tgi diff --git a/libsrc/lynx/comlynx.s b/libsrc/lynx/comlynx.s deleted file mode 100644 index 8b55e9322..000000000 --- a/libsrc/lynx/comlynx.s +++ /dev/null @@ -1,412 +0,0 @@ -; -; Serial driver for the Atari Lynx ComLynx port. -; -; Karri Kaksonen, 17.09.2009 -; - - .include "lynx.inc" - .include "zeropage.inc" - .include "ser-kernel.inc" - .include "ser-error.inc" - -; ------------------------------------------------------------------------ -; Header. Includes jump table - - .segment "JUMPTABLE" - - ; Driver signature - .byte $73, $65, $72 ; "ser" - .byte SER_API_VERSION ; Serial API version number - - ; Jump table. - .addr INSTALL - .addr UNINSTALL - .addr OPEN - .addr CLOSE - .addr GET - .addr PUT - .addr STATUS - .addr IOCTL - .addr IRQ - -;---------------------------------------------------------------------------- -; Global variables -; -; The ring buffers will be at the fixed place -; Tx buffer $200 - $2ff. Rx buffer $300 - $3ff. -; This memory area can usually not be used for anything as the encryption -; stuff needs it. But for this purpose it fits perfectly. - - .bss - -TxBuffer = $0200 -RxBuffer = $0300 -RxPtrIn: .res 1 -RxPtrOut: .res 1 -TxPtrIn: .res 1 -TxPtrOut: .res 1 -contrl: .res 1 -SerialStat: .res 1 -TxDone: .res 1 - - .code - -;---------------------------------------------------------------------------- -; INSTALL: Is called after the driver is loaded into memory. -; -; Must return an SER_ERR_xx code in a/x. - -INSTALL: - ; Set up IRQ vector ? - -;---------------------------------------------------------------------------- -; UNINSTALL: Is called before the driver is removed from memory. -; No return code required (the driver is removed from memory on return). -; - -UNINSTALL: - -;---------------------------------------------------------------------------- -; CLOSE: Close the port and disable interrupts. Called without parameters. -; Must return an SER_ERR_xx code in a/x. - -CLOSE: - ; Disable interrupts - ; Done, return an error code - lda #SER_ERR_OK - rts - -;---------------------------------------------------------------------------- -; OPEN: A pointer to a ser_params structure is passed in ptr1. -; -; The Lynx has only two correct serial data formats: -; 8 bits, parity mark, 1 stop bit -; 8 bits, parity space, 1 stop bit -; -; It also has two wrong formats; -; 8 bits, even parity, 1 stop bit -; 8 bits, odd parity, 1 stop bit -; -; Unfortunately the parity bit includes itself in the calculation making -; parity not compatible with the rest of the world. -; -; We can only specify a few baud rates. -; Lynx has two non-standard speeds 31250 and 62500 which are -; frequently used in games. -; -; The receiver will always read the parity and report parity errors. -; -; Must return an SER_ERR_xx code in a/x. - -OPEN: - stz RxPtrIn - stz RxPtrOut - stz TxPtrIn - stz TxPtrOut - - ; clock = 8 * 15625 - lda #%00011000 - sta TIM4CTLA - ldy #SER_PARAMS::BAUDRATE - lda (ptr1),y - - ldx #1 - cmp #SER_BAUD_62500 - beq setbaudrate - - ldx #2 - cmp #SER_BAUD_31250 - beq setbaudrate - - ldx #12 - cmp #SER_BAUD_9600 - beq setbaudrate - - ldx #25 - cmp #SER_BAUD_4800 - beq setbaudrate - - ldx #51 - cmp #SER_BAUD_2400 - beq setbaudrate - - ldx #103 - cmp #SER_BAUD_1200 - beq setbaudrate - - ldx #207 - cmp #SER_BAUD_600 - beq setbaudrate - - ; clock = 6 * 15625 - ldx #%00011010 - stx TIM4CTLA - - 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 - cmp #SER_BAUD_300 - beq setprescaler - - ; clock = 6 * 15625 - ldx #%00011110 - cmp #SER_BAUD_150 - beq setprescaler - - ; clock = 1 * 15625 - ldx #%00011111 - stx TIM4CTLA - cmp #SER_BAUD_75 - beq baudsuccess - - ldx #141 - cmp #SER_BAUD_110 - beq setbaudrate - - ; clock = 2 * 15625 - ldx #%00011010 - stx TIM4CTLA - ldx #68 - cmp #SER_BAUD_1800 - beq setbaudrate - - ; clock = 6 * 15625 - ldx #%00011110 - stx TIM4CTLA - ldx #231 - cmp #SER_BAUD_134_5 - beq setbaudrate - - lda #SER_ERR_BAUD_UNAVAIL - rts -setprescaler: - stx TIM4CTLA - bra baudsuccess -setbaudrate: - stx TIM4BKUP -baudsuccess: - ldx #TxOpenColl|ParEven - stx contrl - ldy #SER_PARAMS::DATABITS ; Databits - lda (ptr1),y - cmp #SER_BITS_8 - bne invparameter - ldy #SER_PARAMS::STOPBITS ; Stopbits - lda (ptr1),y - cmp #SER_STOP_1 - bne invparameter - ldy #SER_PARAMS::PARITY ; Parity - lda (ptr1),y - cmp #SER_PAR_NONE - beq invparameter - cmp #SER_PAR_MARK - beq checkhs - cmp #SER_PAR_SPACE - bne @L0 - ldx #TxOpenColl - stx contrl - bra checkhs -@L0: - ldx #TxParEnable|TxOpenColl|ParEven - stx contrl - cmp #SER_PAR_EVEN - beq checkhs - ldx #TxParEnable|TxOpenColl - stx contrl -checkhs: - ldx contrl - stx SERCTL - ldy #SER_PARAMS::HANDSHAKE ; Handshake - lda (ptr1),y - cmp #SER_HS_NONE - bne invparameter - lda SERDAT - lda contrl - ora #RxIntEnable|ResetErr - sta SERCTL - lda #SER_ERR_OK - rts -invparameter: - lda #SER_ERR_INIT_FAILED - rts - -;---------------------------------------------------------------------------- -; GET: Will fetch a character from the receive buffer and store it into the -; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is -; returned. - -GET: - lda RxPtrIn - cmp RxPtrOut - bne GetByte - lda #SER_ERR_NO_DATA - rts -GetByte: - ldy RxPtrOut - lda RxBuffer,y - inc RxPtrOut - ldx #$00 - sta (ptr1,x) - txa ; Return code = 0 - rts - -;---------------------------------------------------------------------------- -; PUT: Output character in A. -; Must return an SER_ERR_xx code in a/x. - -PUT: - tax - lda TxPtrIn - ina - cmp TxPtrOut - bne PutByte - lda #SER_ERR_OVERFLOW - rts -PutByte: - ldy TxPtrIn - txa - sta TxBuffer,y - inc TxPtrIn - - bit TxDone - bmi @L1 - php - sei - lda contrl - ora #TxIntEnable|ResetErr - sta SERCTL ; Allow TX-IRQ to hang RX-IRQ - sta TxDone - plp -@L1: - lda #SER_ERR_INV_IOCTL - rts - -;---------------------------------------------------------------------------- -; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All -; registers are already saved, no parameters are passed, but the carry flag -; is clear on entry. The routine must return with carry set if the interrupt -; was handled, otherwise with carry clear. -; -; Both the Tx and Rx interrupts are level sensitive instead of edge sensitive. -; Due to this bug you have to disable the interrupt before clearing it. - -IRQ: - lda INTSET ; Poll all pending interrupts - and #SERIAL_INTERRUPT - bne @L0 - clc - rts -@L0: - bit TxDone - bmi @tx_irq ; Transmit in progress - ldx SERDAT - lda SERCTL - and #RxParityErr|RxOverrun|RxFrameErr|RxBreak - beq @rx_irq - tsb SerialStat ; Save error condition - bit #RxBreak - beq @noBreak - stz TxPtrIn ; Break received - drop buffers - stz TxPtrOut - stz RxPtrIn - stz RxPtrOut -@noBreak: - lda contrl - ora #RxIntEnable|ResetErr - sta SERCTL - lda #$10 - sta INTRST - bra @IRQexit -@rx_irq: - lda contrl - ora #RxIntEnable|ResetErr - sta SERCTL - txa - ldx RxPtrIn - sta RxBuffer,x - txa - inx - -@cont0: - cpx RxPtrOut - beq @1 - stx RxPtrIn - lda #SERIAL_INTERRUPT - sta INTRST - bra @IRQexit - -@1: - sta RxPtrIn - lda #$80 - tsb SerialStat -@tx_irq: - ldx TxPtrOut ; Has all bytes been sent? - cpx TxPtrIn - beq @allSent - - lda TxBuffer,x ; Send next byte - sta SERDAT - inc TxPtrOut - -@exit1: - lda contrl - ora #TxIntEnable|ResetErr - sta SERCTL - lda #SERIAL_INTERRUPT - sta INTRST - bra @IRQexit - -@allSent: - lda SERCTL ; All bytes sent - bit #TxEmpty - beq @exit1 - bvs @exit1 - stz TxDone - lda contrl - ora #RxIntEnable|ResetErr - sta SERCTL - - lda #SERIAL_INTERRUPT - sta INTRST -@IRQexit: - clc - rts - diff --git a/libsrc/lynx/lynx-comlynx.s b/libsrc/lynx/lynx-comlynx.s new file mode 100644 index 000000000..8b55e9322 --- /dev/null +++ b/libsrc/lynx/lynx-comlynx.s @@ -0,0 +1,412 @@ +; +; Serial driver for the Atari Lynx ComLynx port. +; +; Karri Kaksonen, 17.09.2009 +; + + .include "lynx.inc" + .include "zeropage.inc" + .include "ser-kernel.inc" + .include "ser-error.inc" + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + .segment "JUMPTABLE" + + ; Driver signature + .byte $73, $65, $72 ; "ser" + .byte SER_API_VERSION ; Serial API version number + + ; Jump table. + .addr INSTALL + .addr UNINSTALL + .addr OPEN + .addr CLOSE + .addr GET + .addr PUT + .addr STATUS + .addr IOCTL + .addr IRQ + +;---------------------------------------------------------------------------- +; Global variables +; +; The ring buffers will be at the fixed place +; Tx buffer $200 - $2ff. Rx buffer $300 - $3ff. +; This memory area can usually not be used for anything as the encryption +; stuff needs it. But for this purpose it fits perfectly. + + .bss + +TxBuffer = $0200 +RxBuffer = $0300 +RxPtrIn: .res 1 +RxPtrOut: .res 1 +TxPtrIn: .res 1 +TxPtrOut: .res 1 +contrl: .res 1 +SerialStat: .res 1 +TxDone: .res 1 + + .code + +;---------------------------------------------------------------------------- +; INSTALL: Is called after the driver is loaded into memory. +; +; Must return an SER_ERR_xx code in a/x. + +INSTALL: + ; Set up IRQ vector ? + +;---------------------------------------------------------------------------- +; UNINSTALL: Is called before the driver is removed from memory. +; No return code required (the driver is removed from memory on return). +; + +UNINSTALL: + +;---------------------------------------------------------------------------- +; CLOSE: Close the port and disable interrupts. Called without parameters. +; Must return an SER_ERR_xx code in a/x. + +CLOSE: + ; Disable interrupts + ; Done, return an error code + lda #SER_ERR_OK + rts + +;---------------------------------------------------------------------------- +; OPEN: A pointer to a ser_params structure is passed in ptr1. +; +; The Lynx has only two correct serial data formats: +; 8 bits, parity mark, 1 stop bit +; 8 bits, parity space, 1 stop bit +; +; It also has two wrong formats; +; 8 bits, even parity, 1 stop bit +; 8 bits, odd parity, 1 stop bit +; +; Unfortunately the parity bit includes itself in the calculation making +; parity not compatible with the rest of the world. +; +; We can only specify a few baud rates. +; Lynx has two non-standard speeds 31250 and 62500 which are +; frequently used in games. +; +; The receiver will always read the parity and report parity errors. +; +; Must return an SER_ERR_xx code in a/x. + +OPEN: + stz RxPtrIn + stz RxPtrOut + stz TxPtrIn + stz TxPtrOut + + ; clock = 8 * 15625 + lda #%00011000 + sta TIM4CTLA + ldy #SER_PARAMS::BAUDRATE + lda (ptr1),y + + ldx #1 + cmp #SER_BAUD_62500 + beq setbaudrate + + ldx #2 + cmp #SER_BAUD_31250 + beq setbaudrate + + ldx #12 + cmp #SER_BAUD_9600 + beq setbaudrate + + ldx #25 + cmp #SER_BAUD_4800 + beq setbaudrate + + ldx #51 + cmp #SER_BAUD_2400 + beq setbaudrate + + ldx #103 + cmp #SER_BAUD_1200 + beq setbaudrate + + ldx #207 + cmp #SER_BAUD_600 + beq setbaudrate + + ; clock = 6 * 15625 + ldx #%00011010 + stx TIM4CTLA + + 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 + cmp #SER_BAUD_300 + beq setprescaler + + ; clock = 6 * 15625 + ldx #%00011110 + cmp #SER_BAUD_150 + beq setprescaler + + ; clock = 1 * 15625 + ldx #%00011111 + stx TIM4CTLA + cmp #SER_BAUD_75 + beq baudsuccess + + ldx #141 + cmp #SER_BAUD_110 + beq setbaudrate + + ; clock = 2 * 15625 + ldx #%00011010 + stx TIM4CTLA + ldx #68 + cmp #SER_BAUD_1800 + beq setbaudrate + + ; clock = 6 * 15625 + ldx #%00011110 + stx TIM4CTLA + ldx #231 + cmp #SER_BAUD_134_5 + beq setbaudrate + + lda #SER_ERR_BAUD_UNAVAIL + rts +setprescaler: + stx TIM4CTLA + bra baudsuccess +setbaudrate: + stx TIM4BKUP +baudsuccess: + ldx #TxOpenColl|ParEven + stx contrl + ldy #SER_PARAMS::DATABITS ; Databits + lda (ptr1),y + cmp #SER_BITS_8 + bne invparameter + ldy #SER_PARAMS::STOPBITS ; Stopbits + lda (ptr1),y + cmp #SER_STOP_1 + bne invparameter + ldy #SER_PARAMS::PARITY ; Parity + lda (ptr1),y + cmp #SER_PAR_NONE + beq invparameter + cmp #SER_PAR_MARK + beq checkhs + cmp #SER_PAR_SPACE + bne @L0 + ldx #TxOpenColl + stx contrl + bra checkhs +@L0: + ldx #TxParEnable|TxOpenColl|ParEven + stx contrl + cmp #SER_PAR_EVEN + beq checkhs + ldx #TxParEnable|TxOpenColl + stx contrl +checkhs: + ldx contrl + stx SERCTL + ldy #SER_PARAMS::HANDSHAKE ; Handshake + lda (ptr1),y + cmp #SER_HS_NONE + bne invparameter + lda SERDAT + lda contrl + ora #RxIntEnable|ResetErr + sta SERCTL + lda #SER_ERR_OK + rts +invparameter: + lda #SER_ERR_INIT_FAILED + rts + +;---------------------------------------------------------------------------- +; GET: Will fetch a character from the receive buffer and store it into the +; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is +; returned. + +GET: + lda RxPtrIn + cmp RxPtrOut + bne GetByte + lda #SER_ERR_NO_DATA + rts +GetByte: + ldy RxPtrOut + lda RxBuffer,y + inc RxPtrOut + ldx #$00 + sta (ptr1,x) + txa ; Return code = 0 + rts + +;---------------------------------------------------------------------------- +; PUT: Output character in A. +; Must return an SER_ERR_xx code in a/x. + +PUT: + tax + lda TxPtrIn + ina + cmp TxPtrOut + bne PutByte + lda #SER_ERR_OVERFLOW + rts +PutByte: + ldy TxPtrIn + txa + sta TxBuffer,y + inc TxPtrIn + + bit TxDone + bmi @L1 + php + sei + lda contrl + ora #TxIntEnable|ResetErr + sta SERCTL ; Allow TX-IRQ to hang RX-IRQ + sta TxDone + plp +@L1: + lda #SER_ERR_INV_IOCTL + rts + +;---------------------------------------------------------------------------- +; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All +; registers are already saved, no parameters are passed, but the carry flag +; is clear on entry. The routine must return with carry set if the interrupt +; was handled, otherwise with carry clear. +; +; Both the Tx and Rx interrupts are level sensitive instead of edge sensitive. +; Due to this bug you have to disable the interrupt before clearing it. + +IRQ: + lda INTSET ; Poll all pending interrupts + and #SERIAL_INTERRUPT + bne @L0 + clc + rts +@L0: + bit TxDone + bmi @tx_irq ; Transmit in progress + ldx SERDAT + lda SERCTL + and #RxParityErr|RxOverrun|RxFrameErr|RxBreak + beq @rx_irq + tsb SerialStat ; Save error condition + bit #RxBreak + beq @noBreak + stz TxPtrIn ; Break received - drop buffers + stz TxPtrOut + stz RxPtrIn + stz RxPtrOut +@noBreak: + lda contrl + ora #RxIntEnable|ResetErr + sta SERCTL + lda #$10 + sta INTRST + bra @IRQexit +@rx_irq: + lda contrl + ora #RxIntEnable|ResetErr + sta SERCTL + txa + ldx RxPtrIn + sta RxBuffer,x + txa + inx + +@cont0: + cpx RxPtrOut + beq @1 + stx RxPtrIn + lda #SERIAL_INTERRUPT + sta INTRST + bra @IRQexit + +@1: + sta RxPtrIn + lda #$80 + tsb SerialStat +@tx_irq: + ldx TxPtrOut ; Has all bytes been sent? + cpx TxPtrIn + beq @allSent + + lda TxBuffer,x ; Send next byte + sta SERDAT + inc TxPtrOut + +@exit1: + lda contrl + ora #TxIntEnable|ResetErr + sta SERCTL + lda #SERIAL_INTERRUPT + sta INTRST + bra @IRQexit + +@allSent: + lda SERCTL ; All bytes sent + bit #TxEmpty + beq @exit1 + bvs @exit1 + stz TxDone + lda contrl + ora #RxIntEnable|ResetErr + sta SERCTL + + lda #SERIAL_INTERRUPT + sta INTRST +@IRQexit: + clc + rts +