From: cuz Date: Fri, 26 Dec 2003 21:43:18 +0000 (+0000) Subject: Cleanup and preparation for the new design X-Git-Tag: V2.12.0~978 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=86369149640c9197f90055a73f87e75e1a5f0f7c;p=cc65 Cleanup and preparation for the new design git-svn-id: svn://svn.cc65.org/cc65/trunk@2839 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/libsrc/Makefile b/libsrc/Makefile index 5cd29a41d..71a19a899 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -158,6 +158,7 @@ cbm510lib: mv cbm510/crt0.o cbm510.o cp cbm510/*.emd . cp cbm510/*.joy . + cp cbm510/cbm510-stdser.ser cbm510-std.ser #----------------------------------------------------------------------------- # PET-II series diff --git a/libsrc/cbm510/.cvsignore b/libsrc/cbm510/.cvsignore index 7e84fe058..b531b0495 100644 --- a/libsrc/cbm510/.cvsignore +++ b/libsrc/cbm510/.cvsignore @@ -1,4 +1,5 @@ *.emd *.joy +*.ser *.tgi diff --git a/libsrc/cbm510/Makefile b/libsrc/cbm510/Makefile index ed58d70e7..27c0966c0 100644 --- a/libsrc/cbm510/Makefile +++ b/libsrc/cbm510/Makefile @@ -20,6 +20,9 @@ %.joy: %.o ../runtime/zeropage.o extzp.o @$(LD) -t module -o $@ $^ +%.ser: %.o ../runtime/zeropage.o extzp.o + @$(LD) -t module -o $@ $^ + %.tgi: %.o ../runtime/zeropage.o extzp.o @$(LD) -t module -o $@ $^ @@ -54,7 +57,6 @@ OBJS = _scrsize.o \ pokesys.o \ randomize.o \ revers.o \ - rs232.o \ sysuname.o \ tgi_mode_table.o @@ -65,6 +67,8 @@ EMDS = cbm510-ram.emd JOYS = cbm510-stdjoy.joy +SERS = cbm510-stdser.ser + TGIS = #-------------------------------------------------------------------------- @@ -72,14 +76,14 @@ TGIS = .PHONY: all clean zap -all: $(OBJS) $(EMDS) $(JOYS) $(TGIS) +all: $(OBJS) $(EMDS) $(JOYS) $(SERS) $(TGIS) ../runtime/zeropage.o: $(MAKE) -C $(dir $@) $(notdir $@) clean: - @$(RM) $(OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(TGIS:.tgi=.o) + @$(RM) $(OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(SERS:.ser=.o) $(TGIS:.tgi=.o) zap: clean - @$(RM) $(EMDS) $(JOYS) $(TGIS) + @$(RM) $(EMDS) $(JOYS) $(SERS) $(TGIS) diff --git a/libsrc/cbm510/cbm510-stdjoy.s b/libsrc/cbm510/cbm510-stdjoy.s index 5f5a26b15..5dc5e024f 100644 --- a/libsrc/cbm510/cbm510-stdjoy.s +++ b/libsrc/cbm510/cbm510-stdjoy.s @@ -95,13 +95,13 @@ READ: ldx #$0F ; Switch to the system bank ; Get the direction bits - ldy #CIA_PRB + ldy #CIA::PRB lda (cia2),y ; Read joystick inputs sta tmp1 ; Get the fire bits - ldy #CIA_PRA + ldy #CIA::PRA lda (cia2),y ; Make the result value diff --git a/libsrc/cbm510/cbm510-stdser.s b/libsrc/cbm510/cbm510-stdser.s new file mode 100644 index 000000000..59675e0fe --- /dev/null +++ b/libsrc/cbm510/cbm510-stdser.s @@ -0,0 +1,454 @@ +; +; Serial driver for the builtin 6551 ACIA of the Commodore 510. +; +; Ullrich von Bassewitz, 2003-12-18 +; +; 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 "extzp.inc" + .include "ser-kernel.inc" + .include "ser-error.inc" + .include "cbm510.inc" + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + +.segment "JUMPTABLE" + +; Driver signature + + .byte $73, $65, $72 ; "ser" + .byte SER_API_VERSION ; Serial API version number + +; Jump table. + + .word INSTALL + .word UNINSTALL + .word OPEN + .word CLOSE + .word GET + .word PUT + .word STATUS + .word IOCTL + .word IRQ + +;---------------------------------------------------------------------------- +; +; 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 ; + +; Send and receive buffers: 256 bytes each +RecvBuf: .res 256 +SendBuf: .res 256 + +.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 + +.code + +;---------------------------------------------------------------------------- +; INSTALL routine. 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 Plus/4, this is actually +; the same as: +; +; UNINSTALL routine. Is called before the driver is removed from memory. +; Must return an SER_ERR_xx code in a/x. + + +INSTALL: +UNINSTALL: + +; Deactivate DTR and disable 6551 interrupts + + lda #%00001010 + jsr write_cmd + +; Done, return an error code + + lda #SER_ERR_INIT_FAILED + rts + +; Baud rate not available + +InvBaud: + lda #SER_ERR_BAUD_UNAVAIL + rts + +;---------------------------------------------------------------------------- +; CLOSE: Close the port, disable interrupts and flush the buffer. Called +; without parameters. Must return an error code in a/x. +; + +CLOSE: + +; Stop interrupts, drop DTR + + lda #%00001010 + jsr write_cmd + +; Initalize buffers. + + jsr InitBuffers + +; Return OK + + lda #SER_ERR_NO_DATA + rts + +; Check for flow stopped & enough free: release flow control + +@L2: ldx Stopped + beq @L3 + cmp #63 + bcc @L3 + lda #$00 + sta Stopped + lda RtsOff + ora #%00001000 + jsr write_cmd + +; Get byte from buffer + +@L3: ldx RecvHead + lda RecvBuf,x + inc RecvHead + inc RecvFreeCnt + ldx #$00 + sta (ptr1,x) + txa ; Return code = 0 + rts + +;---------------------------------------------------------------------------- +; PUT: Output character in A. +; Must return an error code in a/x. +; + +PUT: + +; Try to send + + ldx SendFreeCnt + inx ; X = $ff? + beq @L2 + pha + lda #$00 + jsr TryToSend + pla + +; Put byte into send buffer & send + +@L2: ldx SendFreeCnt + bne @L3 + lda #SER_ERR_INV_IOCTL + rts + +;---------------------------------------------------------------------------- +; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All +; registers are already save, no parameters are passed and no return code +; is expected. +; + +IRQ: lda #$0F + sta IndReg ; Switch to the system bank + ldy #ACIA::STATUS + lda (acia),y ; Check ACIA status for receive interrupt + and #$08 + beq @L9 ; Jump if no ACIA interrupt + ldy #ACIA::DATA + lda (acia),y ; Get byte from ACIA + ldx RecvFreeCnt ; Check if we have free space left + beq @L1 ; 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 + cpx #33 ; Check for buffer space low + bcs @L9 ; Assert flow control if buffer space low + +; Assert flow control if buffer space too low + +@L1: lda RtsOff + ldy #ACIA::CMD + sta (acia),y + sta Stopped + +; Done, switch back to the execution segment + +@L9: lda ExecReg + sta IndReg + rts + +;---------------------------------------------------------------------------- +; Try to send a byte. Internal routine. A = TryHard + +.proc TryToSend + + sta tmp1 ; Remember tryHard flag + lda #$0F + sta IndReg ; Switch to the system bank +@L0: lda SendFreeCnt + cmp #$ff + beq @L3 ; Bail out + +; Check for flow stopped + +@L1: lda Stopped + bne @L3 ; Bail out + +; Check that swiftlink is ready to send + +@L2: ldy #ACIA::STATUS + lda (acia),y + and #$10 + bne @L4 + bit tmp1 ; Keep trying if must try hard + bmi @L0 + +; Switch back the bank and return + +@L3: lda ExecReg + sta IndReg + rts + +; Send byte and try again + +@L4: ldx SendHead + lda SendBuf,x + ldy #ACIA::DATA + sta (acia),y + inc SendHead + inc SendFreeCnt + jmp @L0 + +.endproc + + +;---------------------------------------------------------------------------- +; Initialize buffers + +InitBuffers: + ldx #0 + stx Stopped + stx RecvHead + stx RecvTail + stx SendHead + stx SendTail + dex ; X = 255 + stx RecvFreeCnt + stx SendFreeCnt + rts + +;---------------------------------------------------------------------------- +; Write to the ACIA changing the indirect segment. Offset is in Y, value in A. + +write_cmd: + ldy #ACIA::CMD +write: pha + lda #$0F + sta IndReg + pla + sta (acia),y + lda ExecReg + sta IndReg + rts + diff --git a/libsrc/cbm510/cbm510.inc b/libsrc/cbm510/cbm510.inc index 384770d61..dd0861cb9 100644 --- a/libsrc/cbm510/cbm510.inc +++ b/libsrc/cbm510/cbm510.inc @@ -16,60 +16,15 @@ IndReg = $0001 ; ----------------------------------- KbdScanBuf = $20 ; Intermediate for keyboard scan -; RS232 stuff -RecvHead = $21 ; Head of receive buffer -RecvTail = $22 ; Tail of receive buffer -RecvFreeCnt = $23 ; Number of bytes in receive buffer -SendHead = $24 ; Head of send buffer -SendTail = $25 ; Tail of send buffer -SendFreeCnt = $26 ; Number of bytes free in send buffer FileNameAdrLo = $90 FileNameAdrHi = $91 FileNameAdrSeg = $92 -SaveAdrLow = $93 -SaveAdrHi = $94 -SaveAdrSeg = $95 -EndAdrLow = $96 -EndAdrHi = $97 -EndAdrSeg = $98 -StartAdrLow = $99 -StartAdrHi = $9A -StartAdrSeg = $9B -Status = $9C FileNameLen = $9D LogicalAdr = $9E FirstAdr = $9F SecondAdr = $A0 -DefInpDev = $A1 -DefOutDev = $A2 -TapeBufPtr = $A3 -TapeBufPtrSeg = $A5 -rs232BufPtr = $A6 -rs232BufPtrSeg = $A8 -StopKeyFlag = $A9 -CTemp = $AA -snsw1 = $AB -SegChgPtr = $AC -PChighSave = $AE -PClowSave = $AF -SRSave = $B0 -ACSave = $B1 -XRSave = $B2 -YRSave = $B3 -SPSave = $B4 IndSegSave = $B5 -IRQSaveHi = $B7 -IRQSaveLo = $B8 -Adr1 = $B9 -Adr2 = $BB -MoniCntr = $BD -MoniTmp = $BE -MoniDevNr = $BF -PgmKeyBuf = $C0 -PgmKeyPtr = $C2 -sedsal = $C4 -sedeal = $C6 SCREEN_PTR = $C8 CURS_Y = $CA CURS_X = $CB @@ -86,25 +41,14 @@ LastLinePos = $D5 PgmKeyIndex = $D6 RepeatCount = $D7 RepeatDelay = $D8 -sedt1 = $D9 ; Temp -sedt2 = $DA ; Temp, frequently used -PrtData = $DB -ScreenTop = $DC -ScreenBot = $DD -ScreenLeft = $DE -ScreenRight = $DF ModKey = $E0 NorKey = $E1 -BitTable = $E2 CURS_FLAG = $E6 ; 1 = no cursor CURS_BLINK = $E7 ; cursor blink counter CRAM_PTR = $E8 -TempColor = $EA CURS_STATE = $EB ; Cursor blink state CHARCOLOR = $EC CURS_COLOR = $ED ; Color behind cursor -OutCharTmp = $EE -ScreenSeq = $EF ; Segment of video RAM ;----------------------------------------------------------------------------- ; Page 3 variables @@ -116,29 +60,6 @@ ScreenSeq = $EF ; Segment of video RAM IRQVec = $0300 BRKVec = $0302 NMIVec = $0304 -openVec = $0306 -closeVec = $0308 -chkinVec = $030A -ckoutVec = $030C -clrchVec = $030E -basinVec = $0310 -bsoutVec = $0312 -stopVec = $0314 -getinVec = $0316 -clallVec = $0318 -loadVec = $031A -saveVec = $031C -usrcmd = $031E -escvec = $0320 -ctrlvec = $0322 -secndVec = $0324 -tksaVec = $0326 -acptrVec = $0328 -cioutVec = $032A -untlkVec = $032C -unlsnVec = $032E -listnVec = $0330 -talkVec = $0332 ; ; @@ -151,46 +72,19 @@ SysMemBot = $0352 SysMemTop = $0355 UsrMemBot = $0358 UsrMemTop = $035B -TimOut = $035E -VerifyFlag = $035F DevTabIndex = $0360 -MsgFlag = $0361 -CassBufPtr = $0362 -t1 = $0363 -t2 = $0364 -XSave = $0365 -SaveX = $0366 -SaveXt = $0367 -temp = $0368 -alarm = $0369 -TapeVec = $036A -LoadStAdr = $036F -CassMotFlag = $0375 -m6551Ctrl = $0376 -m6551Cmd = $0377 -rs232status = $037A -dcddsr = $037B -rs232head = $037C -rs232tail = $037D PgmKeyEnd = $0380 PgmKeySeg = $0382 RVS = $0383 -linetmp = $0398 LastPrtChar = $0399 InsertFlag = $039A ScrollFlag = $039B -FktTemp = $039C PgmKeyIdx = $039D LogScrollFlag = $039E BellMode = $039F ; Bell on/off 00 = an SegSave = $03A0 TabStopTable = $03A1 ; 80 bits for tabstops KeyBuf = $03AB ; Keyboard buffer -funvec = $03B5 ; Vector for function key handline -sedt3 = $03B9 -MoniSegSave = $03f0 -wstvec = $03F8 -WstFlag = $03FA ; Warm start flag ; --------------------------------------------------------------------------- ; Screen size @@ -295,47 +189,65 @@ SID_Read3 = $1C ; I/O $db00: CIA 6526 Inter Process Communication ; I/O $dc00: CIA 6526 -CIA_PRA = $00 -CIA_PRB = $01 -CIA_DDRA = $02 -CIA_DDRB = $03 -CIA_ICR = $0D -CIA_CRA = $0E -CIA_CRB = $0F +.struct CIA + PRA .byte + PRB .byte + DDRA .byte + DDRB .byte + .union + .struct + TALO .byte + TAHI .byte + .endstruct + TA .word + .endunion + .union + .struct + TBLO .byte + TBHI .byte + .endstruct + TB .word + .endunion + TOD10 .byte + TODSEC .byte + TODMIN .byte + TODHR .byte + SDR .byte + ICR .byte + CRA .byte + CRB .byte +.endstruct ; I/O $dd00: ACIA 6551 -; acia = $dd00 - - ADataReg = $00 - AStatusReg = $01 - ACmdReg = $02 - ACtrlReg = $03 - +.struct ACIA + DATA .byte + STATUS .byte + CMD .byte + CTRL .BYTE +.endstruct ; I/O $de00: Triport #1 6525 - -; tpi1 = $de00 - - tpiPortA = $00 - tpiPortB = $01 - tpiPortC = $02 - tpiIntLatch = $02 - tpiDDRA = $03 - tpiDDRB = $04 - tpiDDRC = $05 - tpiIntMask = $05 - tpiCtrlReg = $06 - tpiActIntReg = $07 - - - ; I/O $df00: Triport #2 6525 -; tpi2 = $df00 - +.struct TPI + PRA .byte + PRB .byte + .union + PRC .byte + INT .byte + .endunion + DDRA .byte + DDRB .byte + .union + DDRC .byte + IMR .byte + .endunion + CR .byte + AIR .byte +.endstruct ; Out video memory address diff --git a/libsrc/cbm510/crt0.s b/libsrc/cbm510/crt0.s index 2296106a0..46f5d0b20 100644 --- a/libsrc/cbm510/crt0.s +++ b/libsrc/cbm510/crt0.s @@ -244,7 +244,7 @@ ccopy2: lda __VIDRAM_START__,y ; CA (STATVID) = 0 ; CB (VICDOTSEL) = 0 - ldy #tpiCtrlReg + ldy #TPI::CR lda (tpi1),y sta vidsave+0 and #%00001111 @@ -254,7 +254,7 @@ ccopy2: lda __VIDRAM_START__,y ; Set bit 14/15 of the VIC address range to the high bits of __VIDRAM_START__ ; PC6/PC7 (VICBANKSEL 0/1) = 11 - ldy #tpiPortC + ldy #TPI::PRC lda (tpi2),y sta vidsave+1 and #$3F @@ -388,11 +388,11 @@ _exit: jsr donelib ; Run module destructors ; Switch back the video to the system bank - ldy #tpiCtrlReg + ldy #TPI::CR lda vidsave+0 sta (tpi1),y - ldy #tpiPortC + ldy #TPI::PRC lda vidsave+1 sta (tpi2),y diff --git a/libsrc/cbm510/extzp.inc b/libsrc/cbm510/extzp.inc index e80c27bc4..2352224ca 100644 --- a/libsrc/cbm510/extzp.inc +++ b/libsrc/cbm510/extzp.inc @@ -7,5 +7,5 @@ ; ------------------------------------------------------------------------ .globalzp vic, sid, cia1, cia2, acia, tpi1, tpi2, ktab1 - .globalzp ktab2, ktab3, ktab4, time, RecvBuf, SendBuf + .globalzp ktab2, ktab3, ktab4, time diff --git a/libsrc/cbm510/extzp.s b/libsrc/cbm510/extzp.s index d411c8a6c..986871975 100644 --- a/libsrc/cbm510/extzp.s +++ b/libsrc/cbm510/extzp.s @@ -25,6 +25,4 @@ ktab2: .res 2 ktab3: .res 2 ktab4: .res 2 time: .res 4 -RecvBuf: .res 2 ; RS232 receive buffer -SendBuf: .res 2 ; RS232 transmit buffer diff --git a/libsrc/cbm510/kirq.s b/libsrc/cbm510/kirq.s index 357fe8e68..dc63ee3c0 100644 --- a/libsrc/cbm510/kirq.s +++ b/libsrc/cbm510/kirq.s @@ -63,7 +63,7 @@ k_irq: cld lda #$0F sta IndReg - ldy #tpiActIntReg + ldy #TPI::AIR lda (tpi1),y ; Interrupt Register 6525 beq noirq @@ -96,7 +96,7 @@ irq1: cmp #%00010000 ; interrupt from uart? ; ------------------------------------------------------------------------- ; Done -irqend: ldy #tpiActIntReg +irqend: ldy #TPI::AIR sta (tpi1),y ; Clear interrupt noirq: pla diff --git a/libsrc/cbm510/kscnkey.s b/libsrc/cbm510/kscnkey.s index 95657508e..af4edadc6 100644 --- a/libsrc/cbm510/kscnkey.s +++ b/libsrc/cbm510/kscnkey.s @@ -1,4 +1,4 @@ -; +; ; Ullrich von Bassewitz, 13.09.2001 ; ; Keyboard polling stuff for the 510. @@ -17,9 +17,9 @@ sta NorKey lda #$00 sta KbdScanBuf - ldy #tpiPortB + ldy #TPI::PRB sta (tpi2),y - ldy #tpiPortA + ldy #TPI::PRA sta (tpi2),y jsr Poll and #$3F @@ -28,10 +28,10 @@ jmp NoKey L1: lda #$FF - ldy #tpiPortA + ldy #TPI::PRA sta (tpi2),y asl a - ldy #tpiPortB + ldy #TPI::PRB sta (tpi2),y jsr Poll pha @@ -48,11 +48,11 @@ L4: lsr a dex bpl L4 sec - ldy #tpiPortB + ldy TPI::PRB lda (tpi2),y rol a sta (tpi2),y - ldy #tpiPortA + ldy #TPI::PRA lda (tpi2),y rol a sta (tpi2),y @@ -98,9 +98,9 @@ L8: tax NoKey: ldy #$FF Done: sty LastIndex End: lda #$7F - ldy #tpiPortA + ldy #TPI::PRA sta (tpi2),y - ldy #tpiPortB + ldy #TPI::PRB lda #$FF sta (tpi2),y rts @@ -127,7 +127,7 @@ PutKey: sta KeyBuf,x ; Poll the keyboard port until it's stable .proc Poll - ldy #tpiPortC + ldy TPI::PRC L1: lda (tpi2),y sta KeySave lda (tpi2),y diff --git a/libsrc/cbm510/rs232.s b/libsrc/cbm510/rs232.s deleted file mode 100644 index b45b0403d..000000000 --- a/libsrc/cbm510/rs232.s +++ /dev/null @@ -1,631 +0,0 @@ -; -; 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. -; -;-------------------------------------------------------------------------- -; -; Adapted for the use with the cc65 runtime library by -; Ullrich von Bassewitz (uz@musoftware.de) 02-May-1999. -; -; All external functions are C callable, the return value is an error code. -; - - - .importzp ptr1, ptr2, tmp1, tmp2 - .importzp acia, RecvBuf, SendBuf - .import popa, popax - .import sys_bank, restore_bank - .export _rs232_init, _rs232_params, _rs232_done, _rs232_get - .export _rs232_put, _rs232_pause, _rs232_unpause, _rs232_status - .export k_rs232 - - .include "cbm510.inc" - - -;---------------------------------------------------------------------------- -; -; Global variables -; - -.bss -DropCnt: .res 4 ; Number of bytes lost from rx buffer full -Initialized: .res 1 ; Flag indicating driver is initialized -Stopped: .res 1 ; Flow-stopped flag -RtsOff: .res 1 ; -Errors: .res 1 ; Number of bytes received in error, low byte -BaudCode: .res 1 ; Current baud in effect - -; Segment, the RS232 buffers are in -BufferSeg = 2 - -; UART register offsets -RegData = 0 ; Data register -RegStatus = 1 ; Status register -RegCommand = 2 ; Command register -RegControl = 3 ; Control register - -; Error codes. Beware: The codes must match the codes in the C header file -ErrNotInitialized = $01 -ErrBaudTooFast = $02 -ErrBaudNotAvail = $03 -ErrNoData = $04 -ErrOverflow = $05 - - -.code - -;---------------------------------------------------------------------------- -; -; unsigned char __fastcall__ rs232_init (char hacked); -; /* Initialize the serial port, install the interrupt handler. The parameter -; * must be true (non zero) for a hacked swiftlink and false (zero) otherwise. -; */ -; - -_rs232_init: - bit Initialized ;** shut down if started - bpl @L1 - pha - jsr _rs232_done - pla - -; Initialize buffers & control - -@L1: lda #0 - sta RecvHead - sta SendHead - sta RecvTail - sta SendTail - sta Errors - sta Stopped - lda #255 - sta RecvFreeCnt - sta SendFreeCnt - -; Set default to 2400-8N1, enable interrupts - - jsr sys_bank ; Switch indirect to system bank - - ldy #RegData - lda (acia),y - ldy #RegStatus - lda (acia),y - lda #$18 - ldy #RegControl - sta (acia),y - - lda #$01 - sta RtsOff - ora #$08 - ldy #RegCommand - sta (acia),y - lda #$06 - sta BaudCode - - jsr restore_bank - - lda #$ff - sta Initialized - lda #$00 - tax - rts - -;---------------------------------------------------------------------------- -; -; unsigned char __fastcall__ rs232_params (unsigned char params, unsigned char parity); -; /* Set the port parameters. Use a combination of the #defined values above. */ -; -; Set communication parameters. -; -; baud rates stops word | parity -; --------------------- ----- ----- | --------- -; $00=50 $08=9600 $00=1 $00=8 | $00=none -; $01=110 $09=19200 $80=2 $20=7 | $20=odd -; $02=134.5 $0a=38400 $40=6 | $60=even -; $03=300 $0b=57600 $60=5 | $A0=mark -; $04=600 $0c=115200 | $E0=space -; $05=1200 $0d=230400 -; $06=2400 $0e=future -; $07=4800 $0f=future -; - -_rs232_params: - jsr CheckInitialized ;** check initialized - bcc @L1 - rts - -; Save new parity - -@L1: and #%11100000 - ora #%00000001 - sta tmp2 - -; Set baud/parameters - - jsr popa - sta tmp1 - and #$0f - tax - lda Bauds,x - cmp #$ff - bne @L5 - lda #ErrBaudNotAvail - bne @L9 - -@L5: jsr sys_bank ; Indirect segment to system bank - tax - lda tmp1 - and #$0f - sta BaudCode - lda tmp1 - and #%11100000 - ora #%00010000 - sta tmp1 - txa - and #$0f - ora tmp1 - ldy #RegControl - sta (acia),y - -; Set new parity - -@L7: lda tmp2 - sta RtsOff - ora #%00001000 - ldy #RegCommand - sta (acia),y - jsr restore_bank ; Restore indirect bank - lda #0 -@L9: ldx #0 - rts - -.rodata -Bauds: - .byte $01,$03,$04,$06,$07,$08,$0a,$0c,$0e,$0f,$ff,$ff,$ff,$ff,$ff,$ff - ;in: 0 1 2 3 4 5 6 7 8 9 a b c d e f - ;baud50 110 134 3 6 12 24 48 96 19 38 57 115 230 exp exp - ;out masks: $0F=Baud, val$FF=err -.code - -;---------------------------------------------------------------------------- -; -; unsigned char __fastcall__ rs232_done (void); -; /* Close the port, deinstall the interrupt hander. You MUST call this function -; * before terminating the program, otherwise the machine may crash later. If -; * in doubt, install an exit handler using atexit(). The function will do -; * nothing, if it was already called. -; */ -; - - -_rs232_done: - bit Initialized ;** check initialized - bpl @L9 - -; Stop interrupts, drop DTR - - lda RtsOff - and #%11100010 - ora #%00000010 - ldx IndReg - ldy #$0F - sty IndReg ; Set indirect to system bank - ldy #RegCommand - sta (acia),y - stx IndReg ; Restore old indirect bank - -; Flag uninitialized - -@L9: lda #$00 - sta Initialized - tax - rts - -;---------------------------------------------------------------------------- -; -; unsigned char __fastcall__ rs232_get (char* B); -; /* Get a character from the serial port. If no characters are available, the -; * function will return RS_ERR_NO_DATA, so this is not a fatal error. -; */ -; - -_rs232_get: - jsr CheckInitialized ; Check if initialized - bcc @L1 - rts - -; Check for bytes to send - -@L1: sta ptr1 - stx ptr1+1 ; Store pointer to received char - ldx SendFreeCnt - cpx #$ff - beq @L2 - lda #$00 - jsr TryToSend - -; Check for buffer empty - -@L2: lda RecvFreeCnt - cmp #$ff - bne @L3 - lda #ErrNoData - ldx #0 - rts - -; Check for flow stopped & enough free: release flow control - -@L3: ldx Stopped - beq @L4 - cmp #63 - bcc @L4 - lda #$00 - sta Stopped - lda RtsOff - ora #%00001000 - ldx IndReg - ldy #$0F ; Set indirect to system bank - sty IndReg - ldy #RegCommand - sta (acia),y - stx IndReg - -; Get byte from buffer - -@L4: ldx IndReg - lda #BufferSeg ; Set indirect to buffer bank - sta IndReg - ldy RecvHead - lda (RecvBuf),y - stx IndReg ; Restore indirect bank - inc RecvHead - inc RecvFreeCnt - ldx #$00 - sta (ptr1,x) - txa ; Return code = 0 - rts - -;---------------------------------------------------------------------------- -; -; unsigned char __fastcall__ rs232_put (char B); -; /* Send a character via the serial port. There is a transmit buffer, but -; * transmitting is not done via interrupt. The function returns -; * RS_ERR_OVERFLOW if there is no space left in the transmit buffer. -; */ -; - -_rs232_put: - jsr CheckInitialized ; Check initialized - bcc @L1 - rts - -; Try to send - -@L1: ldx SendFreeCnt - cpx #$ff - beq @L2 - pha - lda #$00 - jsr TryToSend - pla - -; Put byte into send buffer & send - -@L2: ldx SendFreeCnt - bne @L3 - lda #ErrOverflow - ldx #$00 - rts - -; There is enough room (character still in A) - -@L3: ldx IndReg - ldy #BufferSeg ; Set indirect to buffer segment - sty IndReg - ldy SendTail - sta (SendBuf),y - stx IndReg ; Restore indirect bank - inc SendTail - dec SendFreeCnt - lda #$ff - jsr TryToSend - lda #$00 - tax - rts - -;---------------------------------------------------------------------------- -; -; unsigned char __fastcall__ rs232_pause (void); -; /* Assert flow control and disable interrupts. */ -; - -_rs232_pause: -; Check initialized - jsr CheckInitialized - bcc @L1 - rts - -; Assert flow control - -@L1: lda RtsOff - sta Stopped - jsr sys_bank ; Set indirect to system bank - ldy #RegCommand - sta (acia),y - -; Delay for flow stop to be received - - ldx BaudCode - lda PauseTimes,x - jsr DelayMs - -; Stop rx interrupts - - lda RtsOff - ora #$02 - ldy #RegCommand - sta (acia),y - jsr restore_bank ; Restore indirect segment - lda #0 - tax - rts - - -.rodata -; Delay times: 32 byte-receive times in milliseconds, or 100 max. -; Formula = 320,000 / baud -PauseTimes: - .byte 100,100,100,100,100,100,100,067,034,017,009,006,003,002,001,001 - ;in: 0 1 2 3 4 5 6 7 8 9 a b c d e f - ;baud50 110 134 3 6 12 24 48 96 19 38 57 115 230 exp exp -.code - -;---------------------------------------------------------------------------- -; -; unsigned char __fastcall__ rs232_unpause (void); -; /* Re-enable interrupts and release flow control */ -; - -_rs232_unpause: -; Check initialized - jsr CheckInitialized - bcc @L1 - rts - -; Re-enable rx interrupts & release flow control - -@L1: lda #$00 - sta Stopped - lda RtsOff - ora #%00001000 - ldx IndReg - ldy #$0F - sty IndReg ; Set indirect to system bank - ldy #RegCommand - sta (acia),y - stx IndReg ; Restore indirect bank - -; Poll for stalled char & exit - - jsr PollReceive - lda #0 - tax - rts - -;---------------------------------------------------------------------------- -; -; unsigned char __fastcall__ rs232_status (unsigned char* status, -; unsigned char* errors); -; /* Return the serial port status. */ -; - -_rs232_status: - sta ptr2 - stx ptr2+1 - jsr popax - sta ptr1 - stx ptr1+1 - jsr CheckInitialized - bcs @L9 - -; Get status - - ldx IndReg ; Save indirect segment - lda #$0F - sta IndReg ; Set system bank as indirect segment - ldy #RegStatus - lda (acia),y ; Read status register - stx IndReg - ldy #0 - sta (ptr1),y - jsr PollReceive ; bug-recovery hack - lda Errors - ldy #0 - sta (ptr2),y - tya - tax -@L9: rts - -;---------------------------------------------------------------------------- -; -; RS232 interrupt handler. -; The RS232 handler will be called with the system bank as indirect bank -; and all registers saved. -; - -k_rs232: - ldy #RegStatus - lda (acia),y ; check for byte received - and #$08 - beq @L9 ; Nothing to receive - lda (acia),y ; check for receive errors - and #$07 - beq @L1 - inc Errors -@L1: ldy #RegData - lda (acia),y ; get byte and put into receive buffer - ldx RecvFreeCnt - beq @L3 - ldy #BufferSeg - sty IndReg - ldy RecvTail - sta (RecvBuf),y ; Store received character - lda #$0F - sta IndReg ; Restore indirect segment - inc RecvTail - dec RecvFreeCnt - cpx #33 ; check for buffer space low - bcs @L9 - -; Assert flow control - -@L2: lda RtsOff ; assert flow control if buffer space too low - ldy #RegCommand - sta (acia),y - sta Stopped - rts - -; Drop this char - -@L3: inc DropCnt+0 ;not time-critical - bne @L9 - inc DropCnt+1 - bne @L9 - inc DropCnt+2 - bne @L9 - inc DropCnt+3 -@L9: rts - - -;---------------------------------------------------------------------------- -; -; CheckInitialized - internal check if initialized -; Set carry and an error code if not initialized, clear carry and do not -; change any registers if initialized. -; - -CheckInitialized: - bit Initialized - bmi @L1 - lda #ErrNotInitialized - ldx #0 - sec - rts - -@L1: clc - rts - -;---------------------------------------------------------------------------- -; Try to send a byte. Internal routine. A = TryHard - -TryToSend: - sta tmp1 ; Remember tryHard flag - ldx IndReg ; Save indirect segment - lda #$0F - sta IndReg ; Set system segment as indirect segment -@L0: lda SendFreeCnt - cmp #$ff - beq @L3 ; Bail out - -; Check for flow stopped - -@L1: lda Stopped - bne @L3 ; Bail out - -; Check that the UART is ready to send - -@L2: ldy #RegStatus - lda (acia),y - and #$10 - bne @L4 - bit tmp1 ; Keep trying if must try hard - bmi @L0 -@L3: stx IndReg ; Restore indirect segment - rts - -; Send byte and try again - -@L4: lda #BufferSeg - sta IndReg - ldy SendHead - lda (SendBuf),y - ldy #$0F - sty IndReg - ldy #RegData - sta (acia),y - inc SendHead - inc SendFreeCnt - jmp @L0 - - -;---------------------------------------------------------------------------- -; -; PollReceive - poll for rx char -; This function is useful in odd cases where the 6551 has a character in -; it but it fails to raise an NMI. It might be edge-triggering conditions? -; Actually, I'm not entirely sure that this condition can still arrise, but -; calling this function does no harm. -; - -PollReceive: - ldx IndReg ; Save indirect segment - lda #$0F - sta IndReg ; Set system bank as indirect segment - ldy #RegStatus - lda (acia),y - and #$08 - beq @L9 - lda (acia),y ; Read a second time? ### - and #$08 - beq @L9 - ldy #RegData - lda (acia),y - ldy RecvFreeCnt - beq @L9 - ldy #BufferSeg - sty IndReg - ldy RecvTail - sta (RecvBuf),y - inc RecvTail - dec RecvFreeCnt -@L9: stx IndReg ; Restore indirect segment - rts - -;---------------------------------------------------------------------------- -; -; DelayMs : delay for given number of milliseconds -; This implementation isn't very rigerous; it merely delays for the -; approximate number of clock cycles for the processor speed. -; Algorithm: -; repeat for number of milliseconds: -; repeat for number of MHz of cpu speed: -; delay for 1017 clock cycles -; - -DelayMs: ;( .A=milliseconds ) -@L1: ldy #1 ; 1MHz -@L2: ldx #203 ;(2) -@L3: dex ;(2) - bne @L3 ;(3) // 1017 cycles - dey - bne @L2 - sec - sbc #1 - bne @L1 - rts - -.end - - -