mirror of
https://github.com/cc65/cc65.git
synced 2025-01-03 01:31:55 +00:00
Cleanup and preparation for the new design
git-svn-id: svn://svn.cc65.org/cc65/trunk@2839 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
b9327d23f8
commit
8636914964
@ -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
|
||||
|
@ -1,4 +1,5 @@
|
||||
*.emd
|
||||
*.joy
|
||||
*.ser
|
||||
*.tgi
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
454
libsrc/cbm510/cbm510-stdser.s
Normal file
454
libsrc/cbm510/cbm510-stdser.s
Normal file
@ -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_OK
|
||||
tax ; A is zero
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
|
||||
; Must return an SER_ERR_xx code in a/x.
|
||||
|
||||
OPEN:
|
||||
|
||||
; Check if the handshake setting is valid
|
||||
|
||||
ldy #SER_PARAMS::HANDSHAKE ; Handshake
|
||||
lda (ptr1),y
|
||||
cmp #SER_HS_HW ; This is all we support
|
||||
bne InvParam
|
||||
|
||||
; Initialize buffers
|
||||
|
||||
jsr InitBuffers
|
||||
|
||||
; 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
|
||||
tay
|
||||
lda BaudTable,y ; Get 6551 value
|
||||
bmi InvBaud ; Branch if rate not supported
|
||||
sta tmp1
|
||||
|
||||
ldy #SER_PARAMS::DATABITS ; Databits
|
||||
lda (ptr1),y
|
||||
tay
|
||||
lda BitTable,y
|
||||
ora tmp1
|
||||
sta tmp1
|
||||
|
||||
ldy #SER_PARAMS::STOPBITS ; Stopbits
|
||||
lda (ptr1),y
|
||||
tay
|
||||
lda StopTable,y
|
||||
ora tmp1
|
||||
ora #%00010000 ; Receiver clock source = baudrate
|
||||
ldy #ACIA::CTRL
|
||||
jsr write
|
||||
|
||||
; 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
|
||||
tay
|
||||
lda ParityTable,y
|
||||
ora #%00000001 ; DTR active
|
||||
sta RtsOff
|
||||
ora #%00001000 ; Enable receive interrupts
|
||||
jsr write_cmd
|
||||
|
||||
; Done
|
||||
|
||||
lda #<SER_ERR_OK
|
||||
tax ; A is zero
|
||||
rts
|
||||
|
||||
; Invalid parameter
|
||||
|
||||
InvParam:
|
||||
lda #<SER_ERR_INIT_FAILED
|
||||
ldx #>SER_ERR_INIT_FAILED
|
||||
rts
|
||||
|
||||
; Baud rate not available
|
||||
|
||||
InvBaud:
|
||||
lda #<SER_ERR_BAUD_UNAVAIL
|
||||
ldx #>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_OK
|
||||
tax ; A is zero
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; GET: Will fetch a character from the receive buffer and store it into the
|
||||
; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
|
||||
; return.
|
||||
;
|
||||
|
||||
GET: ldx SendFreeCnt ; Send data if necessary
|
||||
inx ; X == $FF?
|
||||
beq @L1
|
||||
lda #$00
|
||||
jsr TryToSend
|
||||
|
||||
; Check for buffer empty
|
||||
|
||||
@L1: lda RecvFreeCnt
|
||||
cmp #$ff
|
||||
bne @L2
|
||||
lda #<SER_ERR_NO_DATA
|
||||
ldx #>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_OVERFLOW ; X is already zero
|
||||
rts
|
||||
|
||||
@L3: ldx SendTail
|
||||
sta SendBuf,x
|
||||
inc SendTail
|
||||
dec SendFreeCnt
|
||||
lda #$ff
|
||||
jsr TryToSend
|
||||
lda #<SER_ERR_OK
|
||||
tax
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; STATUS: Return the status in the variable pointed to by ptr1.
|
||||
; Must return an error code in a/x.
|
||||
;
|
||||
|
||||
STATUS: lda #$0F
|
||||
sta IndReg
|
||||
ldy #ACIA::STATUS
|
||||
lda (acia),y
|
||||
ldx #0
|
||||
sta (ptr1,x)
|
||||
lda IndReg
|
||||
sta ExecReg
|
||||
txa ; SER_ERR_OK
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
|
||||
; specific data in ptr1, and the ioctl code in A.
|
||||
; Must return an error code in a/x.
|
||||
;
|
||||
|
||||
IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
|
||||
ldx #>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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user