mirror of
https://github.com/cc65/cc65.git
synced 2024-12-22 12:30:41 +00:00
Complete redesign of the CBM610 support.
Use wrappers to call the kernal in bank 15 instead of implementing kernal functionality within the cc65 libs (eats performance but is much smaller and simpler). Improved startup/shutdown code allows a return to the system bank without calling the BASIC cold start vector. git-svn-id: svn://svn.cc65.org/cc65/trunk@2793 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
018a68a2fe
commit
a7042ddbe4
@ -144,7 +144,7 @@ c128lib:
|
||||
# Commdore P500 / CBM 5x0
|
||||
|
||||
cbm510lib:
|
||||
for i in cbm510 cbm common runtime conio dbg em joystick tgi zlib; do \
|
||||
for i in cbm510 cbm common runtime conio dbg em joystick serial tgi zlib; do \
|
||||
CC=$(CC) \
|
||||
AS=$(AS) \
|
||||
LD=$(LD) \
|
||||
@ -161,7 +161,7 @@ cbm510lib:
|
||||
# PET-II series
|
||||
|
||||
cbm610lib:
|
||||
for i in cbm610 cbm common runtime conio dbg em joystick tgi zlib; do \
|
||||
for i in cbm610 cbm common runtime conio dbg em joystick serial tgi zlib; do \
|
||||
CC=$(CC) \
|
||||
AS=$(AS) \
|
||||
LD=$(LD) \
|
||||
@ -172,6 +172,7 @@ cbm610lib:
|
||||
done
|
||||
mv cbm610/crt0.o cbm610.o
|
||||
cp cbm610/*.emd .
|
||||
cp cbm610/*.ser .
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# GEOS on the C64/128
|
||||
|
@ -1,3 +1,5 @@
|
||||
*.emd
|
||||
*.joy
|
||||
*.ser
|
||||
*.tgi
|
||||
|
||||
|
||||
|
@ -14,10 +14,13 @@
|
||||
%.o: %.s
|
||||
@$(AS) -g -o $@ $(AFLAGS) $<
|
||||
|
||||
%.emd: %.o ../runtime/zeropage.o
|
||||
%.emd: %.o ../runtime/zeropage.o extzp.o
|
||||
@$(LD) -t module -o $@ $^
|
||||
|
||||
%.tgi: %.o ../runtime/zeropage.o
|
||||
%.ser: %.o ../runtime/zeropage.o extzp.o
|
||||
@$(LD) -t module -o $@ $^
|
||||
|
||||
%.tgi: %.o ../runtime/zeropage.o extzp.o
|
||||
@$(LD) -t module -o $@ $^
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
@ -32,48 +35,47 @@ OBJS = _scrsize.o \
|
||||
cputc.o \
|
||||
crt0.o \
|
||||
crtc.o \
|
||||
extzp.o \
|
||||
kbhit.o \
|
||||
kiec.o \
|
||||
kernal.o \
|
||||
kiobase.o \
|
||||
kirq.o \
|
||||
kplot.o \
|
||||
kopen.o \
|
||||
krdtim.o \
|
||||
kreadst.o \
|
||||
kscnkey.o \
|
||||
kscreen.o \
|
||||
ksetlfs.o \
|
||||
ksetnam.o \
|
||||
ksettim.o \
|
||||
kudtim.o \
|
||||
kupdst.o \
|
||||
mainargs.o \
|
||||
peeksys.o \
|
||||
pokesys.o \
|
||||
randomize.o \
|
||||
revers.o \
|
||||
rs232.o \
|
||||
sysuname.o
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Drivers
|
||||
|
||||
TGIS =
|
||||
|
||||
EMDS = cbm610-ram.emd
|
||||
|
||||
JOYS =
|
||||
|
||||
SERS = cbm610-stdser.ser
|
||||
|
||||
TGIS =
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Targets
|
||||
|
||||
.PHONY: all clean zap
|
||||
|
||||
all: $(OBJS) $(EMDS) $(TGIS)
|
||||
all: $(OBJS) $(EMDS) $(JOYS) $(SERS) $(TGIS)
|
||||
|
||||
../runtime/zeropage.o:
|
||||
$(MAKE) -C $(dir $@) $(notdir $@)
|
||||
|
||||
clean:
|
||||
@$(RM) $(OBJS) $(EMDS:.emd=.o) $(TGIS:.tgi=.o)
|
||||
@$(RM) $(OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(SERS:.ser=.o) $(TGIS:.tgi=.o)
|
||||
|
||||
zap: clean
|
||||
@$(RM) $(EMDS) $(TGIS)
|
||||
@$(RM) $(EMDS) $(JOYS) $(SERS) $(TGIS)
|
||||
|
||||
|
@ -5,15 +5,8 @@
|
||||
;
|
||||
|
||||
.export screensize
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
.proc screensize
|
||||
|
||||
ldx #XSIZE
|
||||
ldy #YSIZE
|
||||
rts
|
||||
|
||||
.endproc
|
||||
.import SCREEN
|
||||
|
||||
screensize = SCREEN
|
||||
|
||||
|
||||
|
@ -5,16 +5,16 @@
|
||||
;
|
||||
|
||||
.export set_bank, sys_bank, restore_bank
|
||||
.importzp ptr1
|
||||
.importzp ptr1, segsave
|
||||
|
||||
.include "cbm610.inc"
|
||||
.include "cbm610.inc"
|
||||
|
||||
.code
|
||||
|
||||
.proc sys_bank
|
||||
pha
|
||||
lda IndReg
|
||||
sta IndSegSave
|
||||
sta segsave
|
||||
lda #$0F
|
||||
sta IndReg
|
||||
pla
|
||||
@ -24,7 +24,7 @@
|
||||
.proc set_bank
|
||||
pha
|
||||
lda IndReg
|
||||
sta IndSegSave
|
||||
sta segsave
|
||||
pla
|
||||
sta IndReg
|
||||
rts
|
||||
@ -32,7 +32,7 @@
|
||||
|
||||
.proc restore_bank
|
||||
pha
|
||||
lda IndSegSave
|
||||
lda segsave
|
||||
sta IndReg
|
||||
pla
|
||||
rts
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
.export _set_brk, _reset_brk
|
||||
.export _brk_a, _brk_x, _brk_y, _brk_sr, _brk_pc
|
||||
.import _atexit
|
||||
.import _atexit, BRKVec
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
@ -74,6 +74,8 @@ L1: lda #<brk_handler ; Set the break vector to our routine
|
||||
|
||||
.proc brk_handler
|
||||
|
||||
pla
|
||||
sta _brk_01
|
||||
pla
|
||||
sta _brk_y
|
||||
pla
|
||||
@ -90,15 +92,11 @@ L1: lda #<brk_handler ; Set the break vector to our routine
|
||||
pla ; PC high
|
||||
sbc #0
|
||||
sta _brk_pc+1
|
||||
lda IndReg
|
||||
sta _brk_01
|
||||
lda ExecReg
|
||||
sta IndReg
|
||||
|
||||
jsr uservec ; Call the user's routine
|
||||
|
||||
lda _brk_01
|
||||
sta IndReg
|
||||
sta IndReg
|
||||
|
||||
lda _brk_pc+1
|
||||
pha
|
||||
|
@ -63,15 +63,20 @@ pagecount: .res 1 ; Number of available pages
|
||||
INSTALL:
|
||||
lda #$FF
|
||||
sta curpage ; Invalidate the current page
|
||||
sta pagecount ; Assume all memory available
|
||||
|
||||
ldx UsrMemTop+2
|
||||
cpx #RAMBANK ; Top of memory in bank 2?
|
||||
sec
|
||||
jsr $FF99 ; MEMTOP
|
||||
|
||||
cmp #RAMBANK ; Top of memory in bank 2?
|
||||
bne @L1 ; No: We can use all the memory
|
||||
clc
|
||||
adc UsrMemTop+1
|
||||
@L1: sta pagecount
|
||||
txa
|
||||
sub #OFFS
|
||||
tya
|
||||
sbc #$00
|
||||
sta pagecount
|
||||
|
||||
lda #<EM_ERR_OK
|
||||
@L1: lda #<EM_ERR_OK
|
||||
ldx #>EM_ERR_OK
|
||||
; rts ; Run into UNINSTALL instead
|
||||
|
||||
|
454
libsrc/cbm610/cbm610-stdser.s
Normal file
454
libsrc/cbm610/cbm610-stdser.s
Normal file
@ -0,0 +1,454 @@
|
||||
;
|
||||
; Serial driver for the builtin 6551 ACIA of the Commodore 610.
|
||||
;
|
||||
; 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 "cbm610.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
|
||||
|
@ -12,178 +12,31 @@
|
||||
ExecReg = $0000
|
||||
IndReg = $0001
|
||||
|
||||
; Up to $20 and $60-8F used by runtime and fixed values
|
||||
; -----------------------------------
|
||||
|
||||
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
|
||||
|
||||
FNAM_ADR := $90 ; File name address
|
||||
FNAM_SEG := $92 ; Unused
|
||||
SaveAdrLow = $93
|
||||
SaveAdrHi = $94
|
||||
SaveAdrSeg = $95
|
||||
EndAdrLow = $96
|
||||
EndAdrHi = $97
|
||||
EndAdrSeg = $98
|
||||
StartAdrLow = $99
|
||||
StartAdrHi = $9A
|
||||
StartAdrSeg = $9B
|
||||
ST := $9C ; Status
|
||||
FNAM_LEN := $9D
|
||||
LFN := $9E
|
||||
DEVNUM := $9F
|
||||
SECADR := $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
|
||||
CharPtr = $C8
|
||||
CURS_Y = $CA
|
||||
CURS_X = $CB
|
||||
;CharPtr = $C8
|
||||
;CURS_Y = $CA
|
||||
;CURS_X = $CB
|
||||
GrafMode = $CC
|
||||
LastIndex = $CD
|
||||
LastLine = $CE
|
||||
LastCol = $CF
|
||||
crsw = $D0
|
||||
KeyIndex = $D1
|
||||
QuoteSw = $D2
|
||||
Insrt = $D3
|
||||
Config = $D4
|
||||
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
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Page 3 variables
|
||||
|
||||
;
|
||||
; system ram vectors
|
||||
;
|
||||
|
||||
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
|
||||
|
||||
;
|
||||
;
|
||||
;
|
||||
|
||||
LogicalAdrTable = $0334
|
||||
FirstAdrTable = $033E
|
||||
SecondAdrTable = $0348
|
||||
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
|
||||
PgmKeySize = $0383
|
||||
RVS = $0397
|
||||
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
|
||||
FUNKEY_VEC = $03B5 ; Vector for function key handline
|
||||
FunKeyTmp = $03B7
|
||||
sedt3 = $03B9
|
||||
MoniSegSave = $03f0
|
||||
wstvec = $03F8
|
||||
WstFlag = $03FA ; Warm start flag
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
@ -274,11 +127,12 @@ Env3 = $1C
|
||||
|
||||
; 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
|
||||
|
@ -5,44 +5,69 @@
|
||||
;
|
||||
|
||||
.export _cgetc
|
||||
.import plot, write_crtc
|
||||
.import plot, write_crtc, sys_bank, restore_bank
|
||||
.import cursor
|
||||
.import sysp0: zp, sysp3: zp
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
|
||||
_cgetc: lda KeyIndex ; Get number of characters
|
||||
_cgetc: lda IndReg
|
||||
pha
|
||||
lda #$0F
|
||||
sta IndReg ; Switch to the system bank
|
||||
|
||||
ldy #$D1
|
||||
lda (sysp0),y ; Get number of keys in keyboard buffer
|
||||
bne L2 ; Jump if there are already chars waiting
|
||||
|
||||
; Switch on the cursor if needed
|
||||
|
||||
lda cursor
|
||||
beq L1 ; Jump if no cursor
|
||||
beq L0 ; Jump if no cursor
|
||||
|
||||
jsr plot ; Set the current cursor position
|
||||
ldy #$D4
|
||||
lda (sysp0),y ; Get the cursor format
|
||||
ldy #10
|
||||
lda Config ; Cursor format
|
||||
jsr write_crtc ; Set the cursor formar
|
||||
jsr write_crtc ; Set the cursor format
|
||||
|
||||
L1: lda KeyIndex
|
||||
beq L1
|
||||
L0: ldy #$D1
|
||||
L1: lda (sysp0),y ; Get the number of keys in the buffer
|
||||
beq L1 ; Wait until we have some keys
|
||||
|
||||
ldy #10
|
||||
lda #$20 ; Cursor off
|
||||
jsr write_crtc
|
||||
|
||||
L2: ldx #$00 ; Get index
|
||||
ldy KeyBuf ; Get first character in the buffer
|
||||
sei
|
||||
L3: lda KeyBuf+1,x ; Move up the remaining chars
|
||||
sta KeyBuf,x
|
||||
inx
|
||||
cpx KeyIndex
|
||||
bne L3
|
||||
dec KeyIndex
|
||||
cli
|
||||
L2: ldy #$D1
|
||||
lda (sysp0),y ; Get number of chars in buffer
|
||||
tax
|
||||
ldy #$AB
|
||||
lda (sysp3),y ; Get first char from keyboard buffer
|
||||
sta c ; Save for return
|
||||
dex
|
||||
txa
|
||||
ldy #$D1
|
||||
sta (sysp0),y
|
||||
sei
|
||||
jmp L4
|
||||
L3: iny
|
||||
lda (sysp3),y
|
||||
dey
|
||||
sta (sysp3),y
|
||||
iny
|
||||
L4: dex
|
||||
bpl L3
|
||||
cli
|
||||
|
||||
pla
|
||||
sta IndReg ; Restore old segment
|
||||
|
||||
ldx #$00 ; High byte
|
||||
tya ; First char from buffer
|
||||
lda c ; First char from buffer
|
||||
rts
|
||||
|
||||
.bss
|
||||
|
||||
c: .byte 0
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
.export _clrscr
|
||||
.import plot
|
||||
.import CURS_X: zp, CURS_Y: zp, CharPtr: zp
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
|
@ -5,13 +5,13 @@
|
||||
; void cputc (char c);
|
||||
;
|
||||
|
||||
.export _cputcxy, _cputc, cputdirect, putchar
|
||||
.export newline, plot
|
||||
.exportzp CURS_X, CURS_Y
|
||||
.export _cputcxy, _cputc, cputdirect, putchar
|
||||
.export newline, plot
|
||||
|
||||
.import PLOT
|
||||
.import _gotoxy
|
||||
.import popa
|
||||
.import _gotoxy
|
||||
.import popa
|
||||
|
||||
.import ktmp: zp, crtc: zp, CURS_X: zp, CURS_Y: zp, CharPtr: zp
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
@ -79,13 +79,6 @@ L10: and #$7F
|
||||
L11: ora #$40
|
||||
bne cputdirect ; Branch always
|
||||
|
||||
; Set cursor position, calculate RAM pointers
|
||||
|
||||
plot: ldy CURS_X
|
||||
ldx CURS_Y
|
||||
clc
|
||||
jmp PLOT
|
||||
|
||||
; Write one character to the screen without doing anything else, return X
|
||||
; position in Y
|
||||
|
||||
@ -99,4 +92,61 @@ putchar:
|
||||
stx IndReg
|
||||
rts
|
||||
|
||||
; Set cursor position, calculate RAM pointers
|
||||
|
||||
plot: ldx CURS_Y
|
||||
lda LineLSBTab,x
|
||||
sta CharPtr
|
||||
lda LineMSBTab,x
|
||||
sta CharPtr+1
|
||||
|
||||
lda IndReg
|
||||
pha
|
||||
lda #$0F
|
||||
sta IndReg
|
||||
|
||||
ldy #$00
|
||||
clc
|
||||
sei
|
||||
sta (crtc),y
|
||||
lda CharPtr
|
||||
adc CURS_X
|
||||
iny
|
||||
sta (crtc),y
|
||||
dey
|
||||
lda #$0E
|
||||
sta (crtc),y
|
||||
iny
|
||||
lda (crtc),y
|
||||
and #$F8
|
||||
sta ktmp
|
||||
lda CharPtr+1
|
||||
adc #$00
|
||||
and #$07
|
||||
ora ktmp
|
||||
sta (crtc),y
|
||||
cli
|
||||
|
||||
pla
|
||||
sta IndReg
|
||||
rts
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; Low bytes of the start address of the screen lines
|
||||
|
||||
.rodata
|
||||
|
||||
LineLSBTab:
|
||||
.byte $00,$50,$A0,$F0,$40,$90,$E0,$30
|
||||
.byte $80,$D0,$20,$70,$C0,$10,$60,$B0
|
||||
.byte $00,$50,$A0,$F0,$40,$90,$E0,$30
|
||||
.byte $80
|
||||
; -------------------------------------------------------------------------
|
||||
; High bytes of the start address of the screen lines
|
||||
|
||||
LineMSBTab:
|
||||
.byte $D0,$D0,$D0,$D0,$D1,$D1,$D1,$D2
|
||||
.byte $D2,$D2,$D3,$D3,$D3,$D4,$D4,$D4
|
||||
.byte $D5,$D5,$D5,$D5,$D6,$D6,$D6,$D7
|
||||
.byte $D7
|
||||
|
||||
|
@ -4,17 +4,16 @@
|
||||
; This must be the *first* file on the linker command line
|
||||
;
|
||||
|
||||
.export _exit
|
||||
.exportzp crtc, sid, IPCcia, cia, acia, tpi1, tpi2, ktab1
|
||||
.exportzp ktab2, ktab3, ktab4, time, RecvBuf, SendBuf
|
||||
.export _exit, BRKVec, UDTIM
|
||||
|
||||
.import initlib, donelib
|
||||
.import condes, initlib, donelib
|
||||
.import push0, callmain
|
||||
.import __BSS_RUN__, __BSS_SIZE__
|
||||
.import irq, nmi
|
||||
.import k_irq, k_nmi
|
||||
.import __BSS_RUN__, __BSS_SIZE__, __EXTZP_RUN__
|
||||
.import __IRQFUNC_TABLE__, __IRQFUNC_COUNT__
|
||||
.import SCNKEY
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "extzp.inc"
|
||||
.include "cbm610.inc"
|
||||
|
||||
|
||||
@ -47,51 +46,31 @@
|
||||
; that is overwritten later.
|
||||
;
|
||||
|
||||
.code
|
||||
.segment "BASICHDR"
|
||||
|
||||
; To make things more simple, make the code of this module absolute.
|
||||
|
||||
.org $0001
|
||||
Head: .byte $03,$00,$11,$00,$0a,$00,$81,$20,$49,$b2,$30,$20,$a4,$20,$34,$00
|
||||
.byte $03,$00,$11,$00,$0a,$00,$81,$20,$49,$b2,$30,$20,$a4,$20,$34,$00
|
||||
.byte $19,$00,$14,$00,$87,$20,$4a,$00,$27,$00,$1e,$00,$97,$20,$32,$35
|
||||
.byte $36,$aa,$49,$2c,$4a,$00,$2f,$00,$28,$00,$82,$20,$49,$00,$39,$00
|
||||
.byte $32,$00,$9e,$20,$32,$35,$36,$00,$4f,$00,$3c,$00,$83,$20,$31,$32
|
||||
.byte $30,$2c,$31,$36,$39,$2c,$31,$2c,$31,$33,$33,$2c,$30,$00,$00,$00
|
||||
|
||||
; Since we need some vectors to access stuff in the system bank for our own,
|
||||
; we will include them here, starting from $60:
|
||||
|
||||
.res $60-*
|
||||
|
||||
crtc: .word $d800
|
||||
sid: .word $da00
|
||||
IPCcia: .word $db00
|
||||
cia: .word $dc00
|
||||
acia: .word $dd00
|
||||
tpi1: .word $de00
|
||||
tpi2: .word $df00
|
||||
ktab1: .word $ea29
|
||||
ktab2: .word $ea89
|
||||
ktab3: .word $eae9
|
||||
ktab4: .word $eb49
|
||||
time: .dword $0000
|
||||
RecvBuf: .word $0100 ; RS232 received buffer
|
||||
SendBuf: .word $0200 ; RS232 send buffer
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; The code in the target bank when switching back will be put at the bottom
|
||||
; of the stack. We will jump here to switch segments. The range $F2..$FF is
|
||||
; not used by any kernal routine.
|
||||
|
||||
.res $F8-*
|
||||
Back: ldx spsave
|
||||
.segment "STARTUP"
|
||||
|
||||
Back: sei
|
||||
ldx spsave
|
||||
txs
|
||||
lda IndReg
|
||||
sta ExecReg
|
||||
|
||||
; The following code is a copy of the code that is poked in the system bank
|
||||
; memory by the basic header program, it's only for documentation and not
|
||||
; actually used here:
|
||||
;------------------------------------------------------------------------------
|
||||
; We are at $100 now. The following snippet is a copy of the code that is poked
|
||||
; in the system bank memory by the basic header program, it's only for
|
||||
; documentation and not actually used here:
|
||||
|
||||
sei
|
||||
lda #$01
|
||||
@ -99,57 +78,132 @@ Back: ldx spsave
|
||||
|
||||
; This is the actual starting point of our code after switching banks for
|
||||
; startup. Beware: The following code will get overwritten as soon as we
|
||||
; use the stack (since it's in page 1)!
|
||||
; use the stack (since it's in page 1)! We jump to another location, since
|
||||
; we need some space for subroutines that aren't used later.
|
||||
|
||||
tsx
|
||||
stx spsave ; Save the system stackpointer
|
||||
ldx #$FF
|
||||
txs ; Set up our own stack
|
||||
jmp Origin
|
||||
|
||||
; Hardware vectors, copied to $FFFA
|
||||
|
||||
.proc vectors
|
||||
sta ExecReg
|
||||
rts
|
||||
nop
|
||||
.word nmi ; NMI vector
|
||||
.word 0 ; Reset - not used
|
||||
.word irq ; IRQ vector
|
||||
.endproc
|
||||
|
||||
; Initializers for the extended zeropage. See extzp.s
|
||||
|
||||
.proc extzp
|
||||
.word $0100 ; sysp1
|
||||
.word $0300 ; sysp3
|
||||
.word $d800 ; crtc
|
||||
.word $da00 ; sid
|
||||
.word $db00 ; ipccia
|
||||
.word $dc00 ; cia
|
||||
.word $dd00 ; acia
|
||||
.word $de00 ; tpi1
|
||||
.word $df00 ; tpi2
|
||||
.word $ea29 ; ktab1
|
||||
.word $ea89 ; ktab2
|
||||
.word $eae9 ; ktab3
|
||||
.word $eb49 ; ktab4
|
||||
.endproc
|
||||
|
||||
; The following code is part of the kernal call subroutine. It is copied
|
||||
; to $FFAE
|
||||
|
||||
.proc callsysbank_15
|
||||
php
|
||||
pha
|
||||
lda #$0F ; Bank 15
|
||||
sta IndReg
|
||||
sei
|
||||
.endproc
|
||||
|
||||
; Save the old stack pointer from the system bank and setup our hw sp
|
||||
|
||||
Origin: tsx
|
||||
stx spsave ; Save the system stackpointer
|
||||
ldx #$FE ; Leave $1FF untouched for cross bank calls
|
||||
txs ; Set up our own stack
|
||||
|
||||
; Initialize the extended zeropage
|
||||
|
||||
ldx #.sizeof(extzp)-1
|
||||
L1: lda extzp,x
|
||||
sta <__EXTZP_RUN__,x
|
||||
dex
|
||||
bpl L1
|
||||
|
||||
; Set the interrupt, NMI and other vectors
|
||||
|
||||
ldy #vectors_size-1
|
||||
L0: lda vectors,y
|
||||
sta $10000 - vectors_size,y
|
||||
ldy #.sizeof(vectors)-1
|
||||
L2: lda vectors,y
|
||||
sta $10000 - .sizeof(vectors),y
|
||||
dey
|
||||
bpl L0
|
||||
bpl L2
|
||||
|
||||
; Switch the indirect segment to the system bank
|
||||
|
||||
lda #$0F
|
||||
sta IndReg
|
||||
|
||||
; Copy the kernal zero page ($90-$F2) from the system bank
|
||||
; Setup the C stack
|
||||
|
||||
lda #$90
|
||||
sta ptr1
|
||||
lda #$00
|
||||
sta ptr1+1
|
||||
ldy #$62-1
|
||||
L1: lda (ptr1),y
|
||||
sta $90,y
|
||||
dey
|
||||
bpl L1
|
||||
lda #.lobyte($FEB5 - .sizeof(callsysbank_15))
|
||||
sta sp
|
||||
lda #.hibyte($FEB5 - .sizeof(callsysbank_15))
|
||||
sta sp+1
|
||||
|
||||
; Copy the page 3 vectors in place
|
||||
; Setup the subroutine and jump vector table that redirects kernal calls to
|
||||
; the system bank. Copy the bank switch routines starting at $FEB5 from the
|
||||
; system bank into the current bank.
|
||||
|
||||
ldy #$00
|
||||
L2: lda p3vectors,y
|
||||
sta $300,y
|
||||
iny
|
||||
cpy #p3vectors_size
|
||||
bne L2
|
||||
|
||||
; Copy the rest of page 3 from the system bank
|
||||
ldy #.sizeof(callsysbank_15)-1 ; Copy the modified part
|
||||
@L1: lda callsysbank_15,y
|
||||
sta $FEB5 - .sizeof(callsysbank_15),y
|
||||
dey
|
||||
bpl @L1
|
||||
|
||||
lda #$00
|
||||
sta ptr1
|
||||
lda #$03
|
||||
sta ptr1+1
|
||||
L3: lda (ptr1),y
|
||||
sta $300,y
|
||||
iny
|
||||
bne L3
|
||||
lda #.lobyte($FEB5) ; Copy the ROM part
|
||||
sta ptr1
|
||||
lda #.hibyte($FEB5)
|
||||
sta ptr1+1
|
||||
ldy #$00
|
||||
@L2: lda (ptr1),y
|
||||
sta $FEB5,y
|
||||
iny
|
||||
cpy #<($FF6F-$FEB5)
|
||||
bne @L2
|
||||
|
||||
; Setup the jump vector table
|
||||
|
||||
ldy #$00
|
||||
ldx #45-1 ; Number of vectors
|
||||
@L3: lda #$20 ; JSR opcode
|
||||
sta $FF6F,y
|
||||
iny
|
||||
lda #.lobyte($FEB5 - .sizeof(callsysbank_15))
|
||||
sta $FF6F,y
|
||||
iny
|
||||
lda #.hibyte($FEB5 - .sizeof(callsysbank_15))
|
||||
sta $FF6F,y
|
||||
iny
|
||||
dex
|
||||
bpl @L3
|
||||
|
||||
; Copy the stack from the system bank into page 3
|
||||
|
||||
ldy #$FF
|
||||
L4: lda (sysp1),y
|
||||
sta $300,y
|
||||
dey
|
||||
cpy spsave
|
||||
bne L4
|
||||
|
||||
; Set the indirect segment to bank we're executing in
|
||||
|
||||
@ -186,64 +240,19 @@ Z3: sta (ptr1),y
|
||||
iny
|
||||
dex
|
||||
bne Z3
|
||||
Z4:
|
||||
|
||||
; Setup the C stack
|
||||
|
||||
lda #<$FF81
|
||||
sta sp
|
||||
lda #>$FF81
|
||||
sta sp+1
|
||||
|
||||
; We expect to be in page 2 now
|
||||
|
||||
.if (* < $1FD)
|
||||
jmp $200
|
||||
.res $200-*
|
||||
.endif
|
||||
.if (* < $200)
|
||||
.res $200-*,$EA
|
||||
.endif
|
||||
.if (* >= $2F0)
|
||||
.error "Code range invalid"
|
||||
.endif
|
||||
|
||||
; This code is in page 2, so we may now start calling subroutines safely,
|
||||
; since the code we execute is no longer in the stack page.
|
||||
; Call module constructors
|
||||
|
||||
jsr initlib
|
||||
|
||||
; Execute the program code
|
||||
|
||||
jmp Start
|
||||
Z4: jmp Init
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Additional data that we need for initialization and that's overwritten
|
||||
; later
|
||||
; We are at $200 now. We may now start calling subroutines safely, since
|
||||
; the code we execute is no longer in the stack page.
|
||||
|
||||
vectors:
|
||||
sta ExecReg
|
||||
rts
|
||||
.byte $01 ; Filler
|
||||
.word nmi
|
||||
.word 0 ; Reset - not used
|
||||
.word irq
|
||||
vectors_size = * - vectors
|
||||
.segment "PAGE2"
|
||||
|
||||
p3vectors:
|
||||
.word k_irq ; IRQ user vector
|
||||
.word k_brk ; BRK user vector
|
||||
.word k_nmi ; NMI user vector
|
||||
p3vectors_size = * - p3vectors
|
||||
; Call module constructors, enable chained IRQs afterwards.
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; This is the program code after setup. It starts at $400
|
||||
|
||||
.res $400-*
|
||||
|
||||
Start:
|
||||
Init: jsr initlib
|
||||
lda #.lobyte(__IRQFUNC_COUNT__*2)
|
||||
sta irqcount
|
||||
|
||||
; Enable interrupts
|
||||
|
||||
@ -253,51 +262,140 @@ Start:
|
||||
|
||||
jsr callmain
|
||||
|
||||
; Call module destructors. This is also the _exit entry.
|
||||
; Disable Call module destructors. This is also the _exit entry and the default entry
|
||||
; point for the break vector.
|
||||
|
||||
_exit: jsr donelib ; Run module destructors
|
||||
_exit: lda #$00
|
||||
sta irqcount ; Disable custom irq handlers
|
||||
jsr donelib ; Run module destructors
|
||||
|
||||
; Clear the start of the zero page, since it will be interpreted as a
|
||||
; (garbage) BASIC program otherwise. This is also the default entry for
|
||||
; the break vector.
|
||||
; Adress the system bank
|
||||
|
||||
k_brk: sei
|
||||
lda #$00
|
||||
ldx #$3E
|
||||
Clear: sta $02,x
|
||||
dex
|
||||
bne Clear
|
||||
lda #$0F
|
||||
sta IndReg
|
||||
|
||||
; Setup the welcome code at the stack bottom in the system bank. Use
|
||||
; the F4/F5 vector to access the system bank
|
||||
; Copy back the old system bank stack contents
|
||||
|
||||
lda #$0F
|
||||
sta IndReg
|
||||
ldy #$00
|
||||
sty $F4
|
||||
iny
|
||||
sty $F5
|
||||
ldy #reset_size-1
|
||||
@L1: lda reset,y
|
||||
sta ($F4),y
|
||||
dey
|
||||
bne @L1
|
||||
jmp Back
|
||||
ldy #$FF
|
||||
@L1: lda $300,y
|
||||
sta (sysp1),y
|
||||
dey
|
||||
cpy spsave
|
||||
bne @L1
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Code that is copied into the system bank at $100 when switching back
|
||||
; Setup the welcome code at the stack bottom in the system bank.
|
||||
|
||||
reset: cli
|
||||
jmp $8000 ; BASIC cold start
|
||||
reset_size = * - reset
|
||||
ldy #$00
|
||||
lda #$58 ; CLI opcode
|
||||
sta (sysp1),y
|
||||
iny
|
||||
lda #$60 ; RTS opcode
|
||||
sta (sysp1),y
|
||||
jmp Back
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; Data area - switch back to relocatable mode
|
||||
; The IRQ handler goes into PAGE2. For performance reasons, and to allow
|
||||
; easier chaining, we do handle the IRQs in the execution bank (instead of
|
||||
; passing them to the system bank).
|
||||
|
||||
.reloc
|
||||
; This is the mapping of the active irq register of the 6525 (tpi1):
|
||||
;
|
||||
; Bit 7 6 5 4 3 2 1 0
|
||||
; | | | | ^ 50 Hz
|
||||
; | | | ^ SRQ IEEE 488
|
||||
; | | ^ cia
|
||||
; | ^ IRQB ext. Port
|
||||
; ^ acia
|
||||
|
||||
irq: pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
lda IndReg
|
||||
pha
|
||||
lda ExecReg
|
||||
sta IndReg ; Be sure to address our segment
|
||||
tsx
|
||||
lda $105,x ; Get the flags from the stack
|
||||
and #$10 ; Test break flag
|
||||
bne dobrk
|
||||
|
||||
; It's an IRQ
|
||||
|
||||
cld
|
||||
|
||||
; Call chained IRQ handlers
|
||||
|
||||
ldy irqcount
|
||||
beq irqskip
|
||||
lda #<__IRQFUNC_TABLE__
|
||||
ldx #>__IRQFUNC_TABLE__
|
||||
jsr condes ; Call the functions
|
||||
|
||||
; Done with chained IRQ handlers, check the TPI for IRQs and handle them
|
||||
|
||||
irqskip:lda #$0F
|
||||
sta IndReg
|
||||
ldy #TPI::AIR
|
||||
lda (tpi1),y ; Interrupt Register 6525
|
||||
beq noirq
|
||||
|
||||
; 50/60Hz interrupt
|
||||
|
||||
cmp #%00000001 ; ticker irq?
|
||||
bne irqend
|
||||
jsr SCNKEY ; Poll the keyboard
|
||||
jsr UDTIM ; Bump the time
|
||||
|
||||
; Done
|
||||
|
||||
irqend: ldy #TPI::AIR
|
||||
sta (tpi1),y ; Clear interrupt
|
||||
|
||||
noirq: pla
|
||||
sta IndReg
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
nmi: rti
|
||||
|
||||
dobrk: jmp (BRKVec)
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; udtim routine for the 610. We will not check for the stop key here, since
|
||||
; C programs will not use it.
|
||||
;
|
||||
|
||||
.proc UDTIM
|
||||
|
||||
inc time
|
||||
bne L9
|
||||
inc time+1
|
||||
bne L9
|
||||
inc time+2
|
||||
bne L9
|
||||
inc time+3
|
||||
L9: rts
|
||||
|
||||
.endproc
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; Page 3
|
||||
|
||||
.segment "PAGE3"
|
||||
|
||||
BRKVec: .addr _exit ; BRK indirect vector
|
||||
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; Data area.
|
||||
|
||||
.data
|
||||
spsave: .res 1
|
||||
|
||||
|
||||
.bss
|
||||
irqcount: .byte 0
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
;
|
||||
|
||||
.export write_crtc, read_crtc
|
||||
.importzp crtc
|
||||
.importzp crtc, ktmp
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
; Write a value to the CRTC. The index is in Y, the value in A
|
||||
|
||||
.proc write_crtc
|
||||
sta sedt1
|
||||
sta ktmp
|
||||
lda IndReg
|
||||
pha
|
||||
lda #$0F
|
||||
@ -23,23 +23,23 @@
|
||||
sei
|
||||
sta (crtc),y
|
||||
iny
|
||||
lda sedt1
|
||||
lda ktmp
|
||||
sta (crtc),y
|
||||
cli
|
||||
pla
|
||||
sta IndReg
|
||||
lda sedt1
|
||||
lda ktmp
|
||||
rts
|
||||
.endproc
|
||||
|
||||
|
||||
.proc read_crtc
|
||||
sty sedt1
|
||||
sty ktmp
|
||||
lda IndReg
|
||||
pha
|
||||
lda #$0F
|
||||
sta IndReg
|
||||
lda sedt1
|
||||
lda ktmp
|
||||
ldy #$00
|
||||
sei
|
||||
sta (crtc),y
|
||||
@ -50,7 +50,7 @@
|
||||
pla
|
||||
sta IndReg
|
||||
tya
|
||||
ldy sedt1
|
||||
ldy ktmp
|
||||
rts
|
||||
.endproc
|
||||
|
||||
|
13
libsrc/cbm610/extzp.inc
Normal file
13
libsrc/cbm610/extzp.inc
Normal file
@ -0,0 +1,13 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2003-12-20
|
||||
;
|
||||
; Additional zero page locations for the CBM610.
|
||||
;
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.globalzp sysp1, sysp3, crtc, sid, ipccia, cia, acia, tpi1, tpi2
|
||||
.globalzp ktab1, ktab2, ktab3, ktab4
|
||||
|
||||
.globalzp sysp0, time, segsave, ktmp, CURS_X, CURS_Y, CharPtr
|
||||
|
44
libsrc/cbm610/extzp.s
Normal file
44
libsrc/cbm610/extzp.s
Normal file
@ -0,0 +1,44 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2003-12-20
|
||||
;
|
||||
; Additional zero page locations for the CBM610.
|
||||
; NOTE: This file is actually linked to an application with its full contents,
|
||||
; so the program comes up with the values given in this file.
|
||||
;
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.include "extzp.inc"
|
||||
|
||||
.segment "EXTZP" : zeropage
|
||||
|
||||
; The following values get initialized from a table in the startup code.
|
||||
; While this sounds crazy, it has reasons that have to do with modules (and
|
||||
; we have the space anyway). So when changing anything, be sure to adjust the
|
||||
; initializer table
|
||||
sysp1: .word $0000
|
||||
sysp3: .word $0000
|
||||
crtc: .word $0000
|
||||
sid: .word $0000
|
||||
ipccia: .word $0000
|
||||
cia: .word $0000
|
||||
acia: .word $0000
|
||||
tpi1: .word $0000
|
||||
tpi2: .word $0000
|
||||
ktab1: .word $0000
|
||||
ktab2: .word $0000
|
||||
ktab3: .word $0000
|
||||
ktab4: .word $0000
|
||||
|
||||
sysp0: .word $0000
|
||||
time: .dword $0000
|
||||
segsave: .byte 0
|
||||
scanbuf: .byte 0
|
||||
ktmp: .byte 0
|
||||
CURS_X: .byte 0
|
||||
CURS_Y: .byte 0
|
||||
CharPtr: .word 0
|
||||
|
||||
|
||||
|
||||
|
@ -1,16 +1,23 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 06.08.1998
|
||||
; Ullrich von Bassewitz, 2003-12-20
|
||||
;
|
||||
; int kbhit (void);
|
||||
;
|
||||
|
||||
.export _kbhit
|
||||
|
||||
.importzp sysp0
|
||||
.import return0, return1
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
.proc _kbhit
|
||||
lda KeyIndex ; Get number of characters
|
||||
ldx IndReg
|
||||
lda #$0F
|
||||
sta IndReg
|
||||
ldy #$D1 ; Number of keys in kbd buffer
|
||||
lda (sysp0),y
|
||||
stx IndReg
|
||||
bne L1
|
||||
jmp return0
|
||||
L1: jmp return1
|
||||
|
84
libsrc/cbm610/kernal.s
Normal file
84
libsrc/cbm610/kernal.s
Normal file
@ -0,0 +1,84 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2003-12-20
|
||||
;
|
||||
; CBM610 kernal functions
|
||||
;
|
||||
|
||||
.export CINT
|
||||
.export IOINIT
|
||||
.export RAMTAS
|
||||
.export RESTOR
|
||||
.export VECTOR
|
||||
.export SETMSG
|
||||
.export SECOND
|
||||
.export TKSA
|
||||
.export MEMTOP
|
||||
.export MEMBOT
|
||||
.export SCNKEY
|
||||
.export SETTMO
|
||||
.export ACPTR
|
||||
.export CIOUT
|
||||
.export UNTLK
|
||||
.export UNLSN
|
||||
.export LISTEN
|
||||
.export TALK
|
||||
.export SETLFS
|
||||
.export CLOSE
|
||||
.export CHKIN
|
||||
.export CKOUT
|
||||
.export CLRCH
|
||||
.export BASIN
|
||||
.export BSOUT
|
||||
.export LOAD
|
||||
.export SAVE
|
||||
.export STOP
|
||||
.export GETIN
|
||||
.export CLALL
|
||||
.export PLOT
|
||||
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; All functions are available in the kernal jump table. Functions having
|
||||
; replacements (usually short ones where the overhead of the cross bank call
|
||||
; is not worth the trouble) are commented out.
|
||||
|
||||
CINT = $FF81
|
||||
IOINIT = $FF84
|
||||
RAMTAS = $FF87
|
||||
RESTOR = $FF8A
|
||||
VECTOR = $FF8D
|
||||
SETMSG = $FF90
|
||||
SECOND = $FF93
|
||||
TKSA = $FF96
|
||||
MEMTOP = $FF99
|
||||
MEMBOT = $FF9C
|
||||
SCNKEY = $FF9F
|
||||
SETTMO = $FFA2
|
||||
ACPTR = $FFA5
|
||||
CIOUT = $FFA8
|
||||
UNTLK = $FFAB
|
||||
UNLSN = $FFAE
|
||||
LISTEN = $FFB1
|
||||
TALK = $FFB4
|
||||
;READST = $FFB7
|
||||
SETLFS = $FFBA
|
||||
;SETNAM = $FFBD
|
||||
;OPEN = $FFC0
|
||||
CLOSE = $FFC3
|
||||
CHKIN = $FFC6
|
||||
CKOUT = $FFC9
|
||||
CLRCH = $FFCC
|
||||
BASIN = $FFCF
|
||||
BSOUT = $FFD2
|
||||
LOAD = $FFD5
|
||||
SAVE = $FFD8
|
||||
;SETTIM = $FFDB
|
||||
;RDTIM = $FFDE
|
||||
STOP = $FFE1
|
||||
GETIN = $FFE4
|
||||
CLALL = $FFE7
|
||||
;UDTIM = $FFEA
|
||||
;SCREEN = $FFED
|
||||
PLOT = $FFF0
|
||||
;IOBASE = $FFF3
|
||||
|
@ -1,246 +0,0 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2003-12-18
|
||||
;
|
||||
; IEC bus routines for the 610.
|
||||
;
|
||||
|
||||
.export TALK, LISTEN, SECOND, TKSA, CIOUT, UNTLK, UNLSN, ACPTR
|
||||
|
||||
.import UPDST
|
||||
.import tpi1: zp, cia: zp
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; TALK subroutine
|
||||
|
||||
TALK: ora #$40
|
||||
bne talk_listen
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; LISTEN subroutine
|
||||
|
||||
LISTEN: ora #$20
|
||||
|
||||
talk_listen:
|
||||
pha
|
||||
lda #$3F
|
||||
ldy #TPI::DDRA
|
||||
sta (tpi1),y
|
||||
lda #$FF
|
||||
ldy #CIA::PRA
|
||||
sta (cia),y
|
||||
ldy #CIA::DDRA
|
||||
sta (cia),y
|
||||
lda #$FA
|
||||
ldy #TPI::PRA
|
||||
sta (tpi1),y
|
||||
lda CTemp
|
||||
bpl LF268
|
||||
lda (tpi1),y
|
||||
and #$DF
|
||||
sta (tpi1),y
|
||||
lda snsw1
|
||||
jsr transfer_byte
|
||||
lda CTemp
|
||||
and #$7F
|
||||
sta CTemp
|
||||
ldy #TPI::PRA
|
||||
lda (tpi1),y
|
||||
ora #$20
|
||||
sta (tpi1),y
|
||||
|
||||
LF268: lda (tpi1),y ; TPI::PRA
|
||||
and #$F7
|
||||
sta (tpi1),y
|
||||
pla
|
||||
; jmp transfer_byte
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; Output A (without EOF flag)
|
||||
|
||||
transfer_byte:
|
||||
eor #$FF
|
||||
ldy #CIA::PRA
|
||||
sta (cia),y
|
||||
ldy #TPI::PRA
|
||||
lda (tpi1),y
|
||||
ora #$12
|
||||
sta (tpi1),y
|
||||
lda (tpi1),y
|
||||
and #%11000000
|
||||
beq LF2D4
|
||||
lda #$80
|
||||
jsr UPDST
|
||||
bne LF304 ; Branch always
|
||||
|
||||
; Wait until NRFD is high
|
||||
|
||||
LF2D4: lda (tpi1),y
|
||||
bpl LF2D4
|
||||
and #$EF
|
||||
sta (tpi1),y
|
||||
|
||||
LF2DE: jsr SetTimB32ms
|
||||
bcc LF2E4 ; Branch always
|
||||
|
||||
LF2E3: sec
|
||||
LF2E4: ldy #TPI::PRA
|
||||
lda (tpi1),y
|
||||
and #$40
|
||||
bne LF2FC
|
||||
ldy #CIA::ICR
|
||||
lda (cia),y
|
||||
and #$02
|
||||
beq LF2E4
|
||||
lda TimOut
|
||||
bmi LF2DE
|
||||
bcc LF2E3
|
||||
lda #$01
|
||||
jsr UPDST
|
||||
|
||||
LF2FC: ldy #TPI::PRA
|
||||
lda (tpi1),y
|
||||
ora #$10
|
||||
sta (tpi1),y
|
||||
|
||||
LF304: lda #$FF
|
||||
ldy #CIA::PRA
|
||||
sta (cia),y
|
||||
rts
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; Output secondary address after listen
|
||||
|
||||
SECOND: jsr transfer_byte
|
||||
|
||||
scatn: ldy #TPI::PRA
|
||||
lda (tpi1),y
|
||||
ora #$08
|
||||
sta (tpi1),y
|
||||
rts
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; Output secondary address
|
||||
|
||||
TKSA: jsr transfer_byte
|
||||
|
||||
LF283: ldy #TPI::PRA
|
||||
lda (tpi1),y
|
||||
and #$39
|
||||
|
||||
; A -> IEC control, data ready for input
|
||||
|
||||
set_listen:
|
||||
ldy #TPI::PRA
|
||||
sta (tpi1),y
|
||||
lda #$C7
|
||||
ldy #TPI::DDRA
|
||||
sta (tpi1),y
|
||||
lda #$00
|
||||
ldy #CIA::DDRA
|
||||
sta (cia),y
|
||||
jmp scatn
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; CIOUT routine
|
||||
|
||||
CIOUT: pha
|
||||
lda CTemp
|
||||
bpl @L1
|
||||
lda snsw1
|
||||
jsr transfer_byte
|
||||
lda CTemp
|
||||
@L1: ora #$80
|
||||
sta CTemp
|
||||
pla
|
||||
sta snsw1
|
||||
rts
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; UNTALK/UNLISTEN
|
||||
|
||||
UNTLK: lda #$5F
|
||||
bne LF2B1
|
||||
UNLSN: lda #$3F
|
||||
LF2B1: jsr talk_listen
|
||||
lda #$F9
|
||||
jmp set_listen
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; ACPTR routine
|
||||
|
||||
ACPTR: ldy #TPI::PRA
|
||||
lda (tpi1),y
|
||||
and #$B9
|
||||
ora #$81
|
||||
sta (tpi1),y
|
||||
|
||||
LF314: jsr SetTimB32ms
|
||||
bcc LF31A
|
||||
|
||||
LF319: sec
|
||||
|
||||
LF31A: ldy #TPI::PRA
|
||||
lda (tpi1),y
|
||||
and #$10
|
||||
beq LF33F
|
||||
ldy #CIA::ICR
|
||||
lda (cia),y
|
||||
and #$02
|
||||
beq LF31A ; Loop if not timeout
|
||||
|
||||
lda TimOut
|
||||
bmi LF314
|
||||
bcc LF319
|
||||
lda #$02
|
||||
jsr UPDST
|
||||
ldy #TPI::PRA
|
||||
lda (tpi1),y
|
||||
and #$3D
|
||||
sta (tpi1),y
|
||||
lda #$0D
|
||||
rts
|
||||
|
||||
LF33F: lda (tpi1),y ; TPI::PRA
|
||||
and #$7F
|
||||
sta (tpi1),y
|
||||
and #$20
|
||||
bne LF350
|
||||
lda #$40
|
||||
jsr UPDST
|
||||
|
||||
LF350: ldy #CIA::PRA
|
||||
lda (cia),y
|
||||
eor #$FF
|
||||
pha
|
||||
ldy #TPI::PRA
|
||||
lda (tpi1),y
|
||||
ora #$40
|
||||
sta (tpi1),y
|
||||
|
||||
LF35E: lda (tpi1),y ; TPI::PRA
|
||||
and #$10
|
||||
beq LF35E
|
||||
lda (tpi1),y
|
||||
and #$BF
|
||||
sta (tpi1),y
|
||||
pla
|
||||
rts
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; Set timer B to 32,64 ms and start it
|
||||
|
||||
SetTimB32ms:
|
||||
lda #$FF ; 255*256*0,5 µs
|
||||
ldy #CIA::TBHI
|
||||
sta (cia),y ; as high byte, low byte = 0
|
||||
lda #$11
|
||||
ldy #CIA::CRB
|
||||
sta (cia),y ; Start the timer
|
||||
ldy #CIA::ICR
|
||||
lda (cia),y ; Clear the interrupt flag
|
||||
clc
|
||||
rts
|
||||
|
@ -1,98 +0,0 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 28.09.1998
|
||||
;
|
||||
; IRQ routine for the 610.
|
||||
;
|
||||
|
||||
.export irq, nmi, k_irq, k_nmi
|
||||
.import SCNKEY, UDTIM, k_rs232
|
||||
.importzp tpi1
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; This is the mapping of the active irq register of the 6525 (tpi1):
|
||||
;
|
||||
; Bit 7 6 5 4 3 2 1 0
|
||||
; | | | | ^ 50 Hz
|
||||
; | | | ^ SRQ IEEE 488
|
||||
; | | ^ cia
|
||||
; | ^ IRQB ext. Port
|
||||
; ^ acia
|
||||
|
||||
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; IRQ entry point
|
||||
|
||||
.proc irq
|
||||
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
tsx
|
||||
lda $104,x ; Get the flags from the stack
|
||||
and #$10 ; Test break flag
|
||||
bne L1
|
||||
jmp (IRQVec)
|
||||
L1: jmp (BRKVec)
|
||||
|
||||
.endproc
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; NMI entry point
|
||||
|
||||
.proc nmi
|
||||
|
||||
jmp (NMIVec)
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; Kernal irq entry point. The IRQvec points here (usually).
|
||||
|
||||
k_irq:
|
||||
lda IndReg ; Ind. Segment retten
|
||||
pha
|
||||
cld
|
||||
lda #$0F
|
||||
sta IndReg
|
||||
ldy #TPI::AIR
|
||||
lda (tpi1),y ; Interrupt Register 6525
|
||||
beq noirq
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; 50/60Hz interrupt
|
||||
|
||||
cmp #%00000001 ; ticker irq?
|
||||
bne irq1
|
||||
jsr SCNKEY ; Poll the keyboard
|
||||
jsr UDTIM ; Bump the time
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; UART interrupt
|
||||
|
||||
irq1: cmp #%00010000 ; interrupt from uart?
|
||||
bne irqend
|
||||
jsr k_rs232 ; Read character from uart
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; Done
|
||||
|
||||
irqend: ldy #TPI::AIR
|
||||
sta (tpi1),y ; Clear interrupt
|
||||
|
||||
noirq: pla
|
||||
sta IndReg
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
k_nmi: rti
|
||||
|
||||
|
22
libsrc/cbm610/kopen.s
Normal file
22
libsrc/cbm610/kopen.s
Normal file
@ -0,0 +1,22 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2003-12-20
|
||||
;
|
||||
; OPEN kernal call.
|
||||
;
|
||||
; NOTE: The OPEN system call in the CBM610 kernal is different from the
|
||||
; standard. It evaluates the carry flag and does a normal open if carry clear
|
||||
; and some strange things (output sa 15 + name on IEC) if carry set. To be
|
||||
; compatible with our CBM file stuff, we have to clear the carry before
|
||||
; calling the real OPEN.
|
||||
|
||||
.export OPEN
|
||||
|
||||
.proc OPEN
|
||||
|
||||
clc
|
||||
jmp $FFC0
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
|
@ -1,76 +0,0 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 28.09.1998
|
||||
;
|
||||
; PLOT routine for the 610.
|
||||
;
|
||||
|
||||
.export PLOT
|
||||
.importzp crtc
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
|
||||
.proc PLOT
|
||||
|
||||
bcc set
|
||||
ldx CURS_Y
|
||||
ldy CURS_X
|
||||
rts
|
||||
|
||||
set: stx CURS_Y
|
||||
sty CURS_X
|
||||
lda LineLSBTab,x
|
||||
sta CharPtr
|
||||
lda LineMSBTab,x
|
||||
sta CharPtr+1
|
||||
|
||||
lda IndReg
|
||||
pha
|
||||
lda #$0F
|
||||
sta IndReg
|
||||
|
||||
ldy #$00
|
||||
clc
|
||||
sei
|
||||
sta (crtc),y
|
||||
lda CharPtr
|
||||
adc CURS_X
|
||||
iny
|
||||
sta (crtc),y
|
||||
dey
|
||||
lda #$0E
|
||||
sta (crtc),y
|
||||
iny
|
||||
lda (crtc),y
|
||||
and #$F8
|
||||
sta sedt1
|
||||
lda CharPtr+1
|
||||
adc #$00
|
||||
and #$07
|
||||
ora sedt1
|
||||
sta (crtc),y
|
||||
cli
|
||||
|
||||
pla
|
||||
sta IndReg
|
||||
rts
|
||||
.endproc
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
; Low bytes of the start address of the screen lines
|
||||
|
||||
.rodata
|
||||
|
||||
LineLSBTab:
|
||||
.byte $00,$50,$A0,$F0,$40,$90,$E0,$30
|
||||
.byte $80,$D0,$20,$70,$C0,$10,$60,$B0
|
||||
.byte $00,$50,$A0,$F0,$40,$90,$E0,$30
|
||||
.byte $80
|
||||
; -------------------------------------------------------------------------
|
||||
; High bytes of the start address of the screen lines
|
||||
|
||||
LineMSBTab:
|
||||
.byte $D0,$D0,$D0,$D0,$D1,$D1,$D1,$D2
|
||||
.byte $D2,$D2,$D3,$D3,$D3,$D4,$D4,$D4
|
||||
.byte $D5,$D5,$D5,$D5,$D6,$D6,$D6,$D7
|
||||
.byte $D7
|
@ -6,13 +6,20 @@
|
||||
|
||||
.export READST
|
||||
|
||||
.import sys_bank, restore_bank
|
||||
.import sysp0: zp, ktmp: zp
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
|
||||
.proc READST
|
||||
|
||||
lda ST ; Load status
|
||||
rts ; Return to caller
|
||||
jsr sys_bank
|
||||
sty ktmp ; Save Y register
|
||||
ldy #ST
|
||||
lda (sysp0),y ; Load ST from system bank
|
||||
ldy ktmp
|
||||
jmp restore_bank ; Will set condition codes on A
|
||||
|
||||
.endproc
|
||||
|
||||
|
@ -1,144 +0,0 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 28.09.1998
|
||||
;
|
||||
; Keyboard polling stuff for the 610.
|
||||
;
|
||||
|
||||
.export SCNKEY
|
||||
.importzp tpi2, ktab1, ktab2, ktab3, ktab4
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
|
||||
.proc SCNKEY
|
||||
|
||||
lda #$FF
|
||||
sta ModKey
|
||||
sta NorKey
|
||||
lda #$00
|
||||
sta KbdScanBuf
|
||||
ldy #TPI::PRB
|
||||
sta (tpi2),y
|
||||
ldy #TPI::PRA
|
||||
sta (tpi2),y
|
||||
jsr Poll
|
||||
and #$3F
|
||||
eor #$3F
|
||||
bne L1
|
||||
jmp NoKey
|
||||
|
||||
L1: lda #$FF
|
||||
ldy #TPI::PRA
|
||||
sta (tpi2),y
|
||||
asl a
|
||||
ldy #TPI::PRB
|
||||
sta (tpi2),y
|
||||
jsr Poll
|
||||
pha
|
||||
sta ModKey
|
||||
ora #$30
|
||||
bne L3 ; Branch always
|
||||
|
||||
L2: jsr Poll
|
||||
L3: ldx #$05
|
||||
ldy #$00
|
||||
L4: lsr a
|
||||
bcc L5
|
||||
inc KbdScanBuf
|
||||
dex
|
||||
bpl L4
|
||||
sec
|
||||
ldy #TPI::PRB
|
||||
lda (tpi2),y
|
||||
rol a
|
||||
sta (tpi2),y
|
||||
ldy #TPI::PRA
|
||||
lda (tpi2),y
|
||||
rol a
|
||||
sta (tpi2),y
|
||||
bcs L2
|
||||
pla
|
||||
bcc NoKey ; Branch always
|
||||
|
||||
L5: ldy KbdScanBuf
|
||||
sty NorKey
|
||||
pla
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
bcc L6
|
||||
bmi L7
|
||||
lda (ktab2),y ; Shifted normal key
|
||||
ldx GrafMode
|
||||
beq L8
|
||||
lda (ktab3),y ; Shifted key in graph mode
|
||||
bne L8
|
||||
|
||||
L6: lda (ktab4),y ; Key with ctrl pressed
|
||||
bne L8
|
||||
L7: lda (ktab1),y ; Normal key
|
||||
L8: tax
|
||||
cpx #$FF ; Valid key?
|
||||
beq Done
|
||||
cpy LastIndex
|
||||
beq Repeat
|
||||
ldx #$13
|
||||
stx RepeatDelay
|
||||
ldx KeyIndex
|
||||
cpx #$09
|
||||
beq NoKey
|
||||
cpy #$59
|
||||
bne PutKey
|
||||
cpx #$08
|
||||
beq NoKey
|
||||
sta KeyBuf,x
|
||||
inx
|
||||
bne PutKey
|
||||
|
||||
NoKey: ldy #$FF
|
||||
Done: sty LastIndex
|
||||
End: lda #$7F
|
||||
ldy #TPI::PRA
|
||||
sta (tpi2),y
|
||||
ldy #TPI::PRB
|
||||
lda #$FF
|
||||
sta (tpi2),y
|
||||
rts
|
||||
|
||||
Repeat: dec RepeatDelay
|
||||
bpl End
|
||||
inc RepeatDelay
|
||||
dec RepeatCount
|
||||
bpl End
|
||||
inc RepeatCount
|
||||
ldx KeyIndex
|
||||
bne End
|
||||
|
||||
PutKey: sta KeyBuf,x
|
||||
inx
|
||||
stx KeyIndex
|
||||
ldx #$03
|
||||
stx RepeatCount
|
||||
bne Done
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
; Poll the keyboard port until it's stable
|
||||
|
||||
.proc Poll
|
||||
ldy #TPI::PRC
|
||||
L1: lda (tpi2),y
|
||||
sta KeySave
|
||||
lda (tpi2),y
|
||||
cmp KeySave
|
||||
bne L1
|
||||
rts
|
||||
.endproc
|
||||
|
||||
|
||||
.bss
|
||||
|
||||
KeySave: .res 1
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2003-12-18
|
||||
;
|
||||
; SETLFS replacement function
|
||||
;
|
||||
|
||||
.export SETLFS
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
|
||||
.proc SETLFS
|
||||
sta LFN
|
||||
stx DEVNUM
|
||||
sty SECADR
|
||||
rts ; Return to caller
|
||||
.endproc
|
||||
|
||||
|
@ -10,14 +10,35 @@
|
||||
|
||||
.export SETNAM
|
||||
|
||||
.import sys_bank, restore_bank
|
||||
.import sysp0: zp, ktmp: zp
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
|
||||
.proc SETNAM
|
||||
|
||||
sta FNAM_LEN
|
||||
stx FNAM_ADR
|
||||
sty FNAM_ADR+1
|
||||
rts
|
||||
pha
|
||||
jsr sys_bank
|
||||
sty ktmp
|
||||
|
||||
txa
|
||||
ldy #FNAM_ADR
|
||||
sta (sysp0),y
|
||||
|
||||
lda ktmp
|
||||
iny
|
||||
sta (sysp0),y
|
||||
|
||||
lda ExecReg ; Assume name is always in this segment
|
||||
ldy #FNAM_SEG
|
||||
sta (sysp0),y
|
||||
|
||||
ldy #FNAM_LEN
|
||||
pla
|
||||
sta (sysp0),y
|
||||
ldy ktmp
|
||||
jmp restore_bank
|
||||
|
||||
.endproc
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 28.09.1998
|
||||
;
|
||||
; udtim routine for the 610. We will not check for the stop key here, since
|
||||
; C programs will not use it.
|
||||
;
|
||||
|
||||
.export UDTIM
|
||||
.importzp time
|
||||
|
||||
|
||||
.proc UDTIM
|
||||
|
||||
inc time
|
||||
bne L9
|
||||
inc time+1
|
||||
bne L9
|
||||
inc time+2
|
||||
bne L9
|
||||
inc time+3
|
||||
L9: rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2003-12-18
|
||||
;
|
||||
; UPDST kernal call.
|
||||
;
|
||||
|
||||
.export UPDST
|
||||
|
||||
.include "cbm610.inc"
|
||||
|
||||
.proc UPDST
|
||||
|
||||
ora ST
|
||||
sta ST
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user