From: cuz Date: Thu, 8 Sep 2005 21:03:46 +0000 (+0000) Subject: Serial driver for the SSC card by Oliver Schmidt X-Git-Tag: V2.12.0~219 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=6ea56144935db2582733d6cdd66aa93c1137e0b9;p=cc65 Serial driver for the SSC card by Oliver Schmidt git-svn-id: svn://svn.cc65.org/cc65/trunk@3627 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/libsrc/Makefile b/libsrc/Makefile index 9a168ead2..5537591ef 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -42,29 +42,31 @@ all: # Apple ][ apple2lib: - for i in apple2 common runtime conio dbg em joystick tgi zlib; do \ + for i in apple2 common runtime conio dbg em joystick serial tgi zlib; do \ $(MAKE) SYS=apple2 -C $$i || exit 1; \ $(AR) a apple2.lib $$i/*.o;\ done mv apple2/crt0.o apple2.o cp apple2/apple2-lc.emd a2.lc.emd - cp apple2/apple2-280-192-6.tgi a2.hi.tgi - cp apple2/apple2-40-40-16.tgi a2.lo.tgi cp apple2/apple2-stdjoy.joy a2.stdjoy.joy + cp apple2/apple2-ssc.ser a2.ssc.ser + cp apple2/apple2-40-40-16.tgi a2.lo.tgi + cp apple2/apple2-280-192-6.tgi a2.hi.tgi #----------------------------------------------------------------------------- # Apple //e apple2enhlib: - for i in apple2enh common runtime conio dbg em joystick tgi zlib; do \ + for i in apple2enh common runtime conio dbg em joystick serial tgi zlib; do \ $(MAKE) SYS=apple2enh -C $$i || exit 1; \ $(AR) a apple2enh.lib $$i/*.o;\ done mv apple2enh/crt0.o apple2enh.o cp apple2enh/apple2-lc.emd a2e.lc.emd - cp apple2enh/apple2-280-192-6.tgi a2e.hi.tgi - cp apple2enh/apple2-40-40-16.tgi a2e.lo.tgi cp apple2enh/apple2-stdjoy.joy a2e.stdjoy.joy + cp apple2enh/apple2-ssc.ser a2e.ssc.ser + cp apple2enh/apple2-40-40-16.tgi a2e.lo.tgi + cp apple2enh/apple2-280-192-6.tgi a2e.hi.tgi #----------------------------------------------------------------------------- # Atari diff --git a/libsrc/apple2/Makefile b/libsrc/apple2/Makefile index 2030c0797..b8b55119d 100644 --- a/libsrc/apple2/Makefile +++ b/libsrc/apple2/Makefile @@ -32,6 +32,9 @@ CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include %.joy: %.o ../runtime/zeropage.o @$(LD) -t module -o $@ $^ +%.ser: %.o ../runtime/zeropage.o + @$(LD) -t module -o $@ $^ + %.tgi: %.o ../runtime/zeropage.o @$(LD) -t module -o $@ $^ @@ -106,7 +109,7 @@ EMDS = apple2-lc.emd JOYS = apple2-stdjoy.joy -SERS = +SERS = apple2-ssc.ser TGIS = apple2-40-40-16.tgi apple2-280-192-6.tgi diff --git a/libsrc/apple2/apple2-ssc.s b/libsrc/apple2/apple2-ssc.s new file mode 100644 index 000000000..b7e14a9ae --- /dev/null +++ b/libsrc/apple2/apple2-ssc.s @@ -0,0 +1,436 @@ +; +; Serial driver for the Apple II Super Serial Card. +; +; Oliver Schmidt, 21.04.2005 +; +; The driver is based on the cc65 rs232 module, which in turn is based on +; Craig Bruce device driver for the Switftlink/Turbo-232. +; +; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998. +; +; This software is Public Domain. It is in Buddy assembler format. +; +; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from +; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232 +; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also +; supports the "hacked" SwiftLink with a 1.8432 MHz crystal. +; +; The code assumes that the kernal + I/O are in context. On the C128, call +; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable +; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the +; interrupt handling assumes that the 65816 is in 6502-emulation mode. +; + + .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 + +;---------------------------------------------------------------------------- +; I/O definitions + +ACIA = $C088 +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 + + .bss + +RecvHead: .res 1 ; Head of receive buffer +RecvTail: .res 1 ; Tail of receive buffer +RecvFreeCnt: .res 1 ; Number of 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 + +Stopped: .res 1 ; Flow-stopped flag +RtsOff: .res 1 ; + +RecvBuf: .res 256 ; Receive buffers: 256 bytes +SendBuf: .res 256 ; Send buffers: 256 bytes + +Index: .res 1 ; I/O register index + + .data + +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 + .byte $FF ; SER_BAUD_45_5 + .byte $01 ; SER_BAUD_50 + .byte $02 ; SER_BAUD_75 + .byte $03 ; SER_BAUD_110 + .byte $04 ; SER_BAUD_134_5 + .byte $05 ; SER_BAUD_150 + .byte $06 ; SER_BAUD_300 + .byte $07 ; SER_BAUD_600 + .byte $08 ; SER_BAUD_1200 + .byte $09 ; SER_BAUD_1800 + .byte $0A ; SER_BAUD_2400 + .byte $0B ; SER_BAUD_3600 + .byte $0C ; SER_BAUD_4800 + .byte $0D ; SER_BAUD_7200 + .byte $0E ; SER_BAUD_9600 + .byte $0F ; SER_BAUD_19200 + .byte $FF ; SER_BAUD_38400 + .byte $FF ; SER_BAUD_57600 + .byte $FF ; SER_BAUD_115200 + .byte $FF ; SER_BAUD_230400 +BitTable: + .byte $60 ; SER_BITS_5 + .byte $40 ; SER_BITS_6 + .byte $20 ; SER_BITS_7 + .byte $00 ; SER_BITS_8 +StopTable: + .byte $00 ; SER_STOP_1 + .byte $80 ; SER_STOP_2 +ParityTable: + .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 +IdOfsTable: + .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: + .byte $38 ; Fixed + .byte $18 ; Fixed + .byte $01 ; Fixed + .byte $31 ; Serial or parallel I/O card type 1 + +IdTableLen = * - IdValTable + + .code + +;---------------------------------------------------------------------------- +; INSTALL: Is called after the driver is loaded into memory. If possible, +; check if the hardware is present. Must return an SER_ERR_xx code in a/x. +; +; Since we don't have to manage the IRQ vector on the Apple II, this is +; actually the same as: +; +; UNINSTALL: Is called before the driver is removed from memory. +; No return code required (the driver is removed from memory on return). +; +; and: +; +; CLOSE: Close the port and disable interrupts. Called without parameters. +; Must return an SER_ERR_xx code in a/x. + +INSTALL: +UNINSTALL: +CLOSE: + ldx Index ; Check for open port + beq :+ + + ; Deactivate DTR and disable 6551 interrupts + lda #%00001010 + sta ACIA_CMD,x + + ; Done, return an error code +: lda #SER_ERR_NO_DEVICE + rts + + ; Invalid parameter +InvParam:lda #SER_ERR_INIT_FAILED + rts + + ; Baud rate not available +InvBaud:lda #SER_ERR_BAUD_UNAVAIL + 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: + ldx Index + ldy SendFreeCnt ; Send data if necessary + iny ; Y == $FF? + beq :+ + lda #$00 ; TryHard = false + jsr TryToSend + + ; Check for buffer empty +: lda RecvFreeCnt ; (25) + cmp #$FF + bne :+ + lda #SER_ERR_NO_DATA + rts + + ; Check for flow stopped & enough free: release flow control +: ldy Stopped ; (34) + beq :+ + cmp #63 + bcc :+ + lda #$00 + sta Stopped + lda RtsOff + ora #%00001000 + sta ACIA_CMD,x + + ; Get byte from buffer +: ldy RecvHead ; (41) + lda RecvBuf,y + inc RecvHead + inc RecvFreeCnt + ldx #$00 ; (59) + sta (ptr1,x) + txa ; Return code = 0 + rts + +;---------------------------------------------------------------------------- +; PUT: Output character in A. +; Must return an SER_ERR_xx code in a/x. + +PUT: + ldx Index + + ; Try to send + ldy SendFreeCnt + iny ; Y = $FF? + beq :+ + pha + lda #$00 ; TryHard = false + jsr TryToSend + pla + + ; Put byte into send buffer & send +: ldy SendFreeCnt + bne :+ + lda #SER_ERR_OVERFLOW + rts + +: ldy SendTail + sta SendBuf,y + inc SendTail + dec SendFreeCnt + lda #$FF ; TryHard = true + jsr TryToSend + 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. + +IRQ: + ldx Index ; Check for open port + beq Done + lda ACIA_STATUS,x ; Check ACIA status for receive interrupt + and #$08 + beq Done ; Jump if no ACIA interrupt + lda ACIA_DATA,x ; Get byte from ACIA + ldy RecvFreeCnt ; Check if we have free space left + beq Flow ; Jump if no space in receive buffer + ldy RecvTail ; Load buffer pointer + sta RecvBuf,y ; Store received byte in buffer + inc RecvTail ; Increment buffer pointer + dec RecvFreeCnt ; Decrement free space counter + ldy RecvFreeCnt ; Check for buffer space low + cpy #33 + bcc Flow ; Assert flow control if buffer space low + rts ; Interrupt handled (carry already set) + + ; Assert flow control if buffer space too low +Flow: lda RtsOff + sta ACIA_CMD,x + sta Stopped + sec ; Interrupt handled +Done: rts + +;---------------------------------------------------------------------------- +; Try to send a byte. Internal routine. A = TryHard + +TryToSend: + sta tmp1 ; Remember tryHard flag +Again: lda SendFreeCnt + cmp #$FF + beq Quit ; Bail out + + ; Check for flow stopped + lda Stopped + bne Quit ; Bail out + + ; Check that ACIA is ready to send + lda ACIA_STATUS,x + and #$10 + bne Send + bit tmp1 ; Keep trying if must try hard + bmi Again +Quit: rts + + ; Send byte and try again +Send: ldy SendHead + lda SendBuf,y + sta ACIA_DATA,x + inc SendHead + inc SendFreeCnt + jmp Again diff --git a/libsrc/apple2/crt0.s b/libsrc/apple2/crt0.s index bd2c9d836..4be1d0eb7 100644 --- a/libsrc/apple2/crt0.s +++ b/libsrc/apple2/crt0.s @@ -41,9 +41,12 @@ _exit: ldx #exit jsr reset ; Setup RESET vector + ; Call module destructors + jsr donelib + ; Check for valid interrupt vector table entry number lda intnum - beq :+ + beq exit ; Deallocate interrupt vector table entry dec params ; Adjust parameter count @@ -51,9 +54,6 @@ _exit: ldx #