This commit was generated by cvs2svn to compensate for changes in r2,

which included commits to RCS files with non-trunk default branches.


git-svn-id: svn://svn.cc65.org/cc65/trunk@3 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz
2000-05-28 13:40:48 +00:00
parent 579491e8a4
commit 53dd513176
847 changed files with 91345 additions and 0 deletions

29
libsrc/cbm610/Makefile Normal file
View File

@@ -0,0 +1,29 @@
#
# makefile for CC65 runtime library
#
.SUFFIXES: .o .s .c
%.o: %.c
@echo $<
@$(CC) $(CFLAGS) $<
@$(AS) -o $@ $(AFLAGS) $(*).s
%.o: %.s
@echo $<
@$(AS) -g -o $@ $(AFLAGS) $<
C_OBJS =
S_OBJS = crt0.o kbhit.o conio.o clrscr.o cputc.o cgetc.o\
color.o break.o banking.o crtc.o pokesys.o\
kscnkey.o kplot.o kudtim.o kirq.o rs232.o
all: $(C_OBJS) $(S_OBJS)
clean:
@rm -f $(C_OBJS:.c=.s)
@rm -f $(C_OBJS)
@rm -f $(S_OBJS)
@rm -f crt0.o

41
libsrc/cbm610/banking.s Normal file
View File

@@ -0,0 +1,41 @@
;
; Ullrich von Bassewitz, 28.09.1998
;
; Banking routines for the 610.
;
.export set_bank, sys_bank, restore_bank
.importzp ptr1
.include "zeropage.inc"
.code
.proc sys_bank
pha
lda IndReg
sta IndSegSave
lda #$0F
sta IndReg
pla
rts
.endproc
.proc set_bank
pha
lda IndReg
sta IndSegSave
pla
sta IndReg
rts
.endproc
.proc restore_bank
pha
lda IndSegSave
sta IndReg
pla
rts
.endproc

117
libsrc/cbm610/break.s Normal file
View File

@@ -0,0 +1,117 @@
;
; Ullrich von Bassewitz, 27.09.1998
;
; void set_brk (unsigned Addr);
; void reset_brk (void);
;
.export _set_brk, _reset_brk
.export _brk_a, _brk_x, _brk_y, _brk_sr, _brk_pc
.import _atexit
.include "zeropage.inc"
.include "page3.inc"
.bss
_brk_a: .res 1
_brk_x: .res 1
_brk_y: .res 1
_brk_sr: .res 1
_brk_pc: .res 2
_brk_01: .res 1
oldvec: .res 2 ; Old vector
.data
uservec: jmp $FFFF ; Patched at runtime
.code
; Set the break vector
.proc _set_brk
sta uservec+1
stx uservec+2 ; Set the user vector
lda oldvec
ora oldvec+1 ; Did we save the vector already?
bne L1 ; Jump if we installed the handler already
lda BRKVec
sta oldvec
lda BRKVec+1
sta oldvec+1 ; Save the old vector
lda #<_reset_brk
ldx #>_reset_brk
jsr _atexit ; Install an exit handler
L1: lda #<brk_handler ; Set the break vector to our routine
sta BRKVec
lda #>brk_handler
sta BRKVec+1
rts
.endproc
; Reset the break vector
.proc _reset_brk
lda oldvec
sta BRKVec
lda oldvec+1
sta BRKVec+1
rts
.endproc
; Break handler, called if a break occurs
.proc brk_handler
pla
sta _brk_y
pla
sta _brk_x
pla
sta _brk_a
pla
and #$EF ; Clear break bit
sta _brk_sr
pla ; PC low
sec
sbc #2 ; Point to start of brk
sta _brk_pc
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
lda _brk_pc+1
pha
lda _brk_pc
pha
lda _brk_sr
pha
ldx _brk_x
ldy _brk_y
lda _brk_a
rti ; Jump back...
.endproc

17
libsrc/cbm610/cbm610.inc Normal file
View File

@@ -0,0 +1,17 @@
;
; CBM610 generic definitions.
;
; ---------------------------------------------------------------------------
; Vector and other locations
FUNKEY_VEC = $03B5
; ---------------------------------------------------------------------------
; I/O
CRTC = $D800
CRTC_ADDR = $00
CRTC_DATA = $01

49
libsrc/cbm610/cgetc.s Normal file
View File

@@ -0,0 +1,49 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; char cgetc (void);
;
.export _cgetc
.import plot, write_crtc
.import cursor
.include "zeropage.inc"
.include "page3.inc"
_cgetc: lda KeyIndex ; Get number of characters
bne L2 ; Jump if there are already chars waiting
; Switch on the cursor if needed
lda cursor
beq L1 ; Jump if no cursor
jsr plot ; Set the current cursor position
ldy #10
lda Config ; Cursor format
jsr write_crtc ; Set the cursor formar
L1: lda KeyIndex
beq L1
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
ldx #$00 ; High byte
tya ; First char from buffer
rts

42
libsrc/cbm610/clrscr.s Normal file
View File

@@ -0,0 +1,42 @@
;
; Ullrich von Bassewitz, 22.09.1998
;
; void clrscr (void);
;
.export _clrscr
.import plot
.include "zeropage.inc"
.proc _clrscr
lda #0
sta CURS_X
sta CURS_Y
jsr plot ; Set cursor to top left corner
lda IndReg
pha
lda #$0F
sta IndReg ; Switch to the system bank
ldx #8
ldy #$00
lda #$20 ; Screencode for blank
L1: sta (CharPtr),y
iny
bne L1
inc CharPtr+1
dex
bne L1
pla
sta IndReg ; Restore old indirect segment
jmp plot ; Set screen pointer again
.endproc

20
libsrc/cbm610/color.s Normal file
View File

@@ -0,0 +1,20 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; unsigned char __fastcall__ textcolor (unsigned char color);
; unsigned char __fastcall__ bgcolor (unsigned char color);
; unsigned char __fastcall__ bordercolor (unsigned char color);
;
.export _textcolor, _bgcolor, _bordercolor
.import return0, return1
.include "cbm610.inc"
_textcolor = return1
_bgcolor = return0
_bordercolor = return0

19
libsrc/cbm610/conio.s Normal file
View File

@@ -0,0 +1,19 @@
;
; Ullrich von Bassewitz, 22.09.1998
;
; Low level stuff for screen output/console input
;
.export initconio
.import xsize, ysize
.include "cbm610.inc"
initconio:
lda #80
sta xsize
lda #25
sta ysize
rts

102
libsrc/cbm610/cputc.s Normal file
View File

@@ -0,0 +1,102 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; void cputcxy (unsigned char x, unsigned char y, char c);
; void cputc (char c);
;
.export _cputcxy, _cputc, cputdirect, putchar
.export advance, newline, plot
.exportzp CURS_X, CURS_Y
.import _gotoxy
.import popa
.import xsize, revers
.include "cbm610.inc"
.include "zeropage.inc"
.include "../cbm/cbm.inc"
_cputcxy:
pha ; Save C
jsr popa ; Get Y
jsr _gotoxy ; Set cursor, drop x
pla ; Restore C
; Plot a character - also used as internal function
_cputc: cmp #$0D ; CR?
bne L1
lda #0
sta CURS_X
beq plot ; Recalculate pointers
L1: cmp #$0A ; LF?
bne L2
ldy CURS_Y
iny
bne newline ; Recalculate pointers
; Printable char of some sort
L2: cmp #' '
bcc cputdirect ; Other control char
tay
bmi L10
cmp #$60
bcc L3
and #$DF
bne cputdirect ; Branch always
L3: and #$3F
cputdirect:
jsr putchar ; Write the character to the screen
; Advance cursor position
advance:
iny
cpy xsize
bne L9
ldy #0 ; new line
newline:
clc
lda xsize
adc CharPtr
sta CharPtr
bcc L4
inc CharPtr+1
L4: inc CURS_Y
L9: sty CURS_X
rts
; Handle character if high bit set
L10: and #$7F
cmp #$7E ; PI?
bne L11
lda #$5E ; Load screen code for PI
bne cputdirect
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
putchar:
ldx IndReg
ldy #$0F
sty IndReg
ora revers ; Set revers bit
ldy CURS_X
sta (CharPtr),y ; Set char
stx IndReg
rts

411
libsrc/cbm610/crt0.s Normal file
View File

@@ -0,0 +1,411 @@
;
; Startup code for cc65 (Plus/4 version)
;
; This must be the *first* file on the linker command line
;
.export _exit
.import __hinit, push0, doatexit, _main
.import initconio
.import __BSS_RUN__, __BSS_SIZE__
.import irq, nmi
.import k_irq, k_nmi, k_plot, k_udtim, k_scnkey
.include "zeropage.inc"
.include "io.inc"
; ------------------------------------------------------------------------
; Define and export the ZP variables for the CBM610 runtime
.exportzp sp, sreg, regsave
.exportzp ptr1, ptr2, ptr3, ptr4
.exportzp tmp1, tmp2, tmp3, tmp4
.exportzp regbank, zpspace
.exportzp crtc, sid, IPCcia, cia, acia, tpi1, tpi2
.exportzp ktab1, ktab2, ktab3, ktab4, time, RecvBuf, SendBuf
sp = $02 ; stack pointer
sreg = $04 ; secondary register/high 16 bit for longs
regsave = $06 ; slot to save/restore (E)AX into
ptr1 = $0A ;
ptr2 = $0C
ptr3 = $0E
ptr4 = $10
tmp1 = $12
tmp2 = $13
tmp3 = $14
tmp4 = $15
regbank = $16 ; 6 byte register bank
zpspace = $1A ; Zero page space allocated
; ------------------------------------------------------------------------
; BASIC header and a small BASIC program. Since it is not possible to start
; programs in other banks using SYS, the BASIC program will write a small
; machine code program into memory at $100 and start that machine code
; program. The machine code program will then start the machine language
; code in bank 1, which will initialize the system by copying stuff from
; the system bank, and start the application.
;
; Here's the basic program that's in the following lines:
;
; 10 for i=0 to 4
; 20 read j
; 30 poke 256+i,j
; 40 next i
; 50 sys 256
; 60 data 120,169,1,133,0
;
; The machine program in the data lines is:
;
; sei
; lda #$01
; sta $00 <-- Switch to bank 1 after this command
;
; Initialization is not only complex because of the jumping from one bank
; into another. but also because we want to save memory, and because of
; this, we will use the system memory ($00-$3FF) for initialization stuff
; that is overwritten later.
;
; 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 $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
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:
sei
lda #$01
sta ExecReg
; 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)!
tsx
stx spsave ; Save the system stackpointer
ldx #$FF
txs ; Set up our own stack
; Set the interrupt, NMI and other vectors
ldy #vectable_size
L0: lda vectable-1,y
sta $FF80,y
dey
bne L0
; Switch the indirect segment to the system bank
lda #$0F
sta IndReg
; Copy the kernal zero page ($90-$F2) from the system bank
lda #$90
sta ptr1
lda #$00
sta ptr1+1
ldy #$62-1
L1: lda (ptr1),y
sta $90,y
dey
bpl L1
; Copy the page 3 vectors in place
ldy #$00
L2: lda p3vectable,y
sta $300,y
iny
cpy #p3vectable_size
bne L2
; Copy the rest of page 3 from the system bank
lda #$00
sta ptr1
lda #$03
sta ptr1+1
L3: lda (ptr1),y
sta $300,y
iny
bne L3
; Set the indirect segment to bank we're executing in
lda ExecReg
sta IndReg
; Zero the BSS segment. We will do that here instead calling the routine
; in the common library, since we have the memory anyway, and this way,
; it's reused later.
lda #<__BSS_RUN__
sta ptr1
lda #>__BSS_RUN__
sta ptr1+1
lda #0
tay
; Clear full pages
ldx #>__BSS_SIZE__
beq Z2
Z1: sta (ptr1),y
iny
bne Z1
inc ptr1+1 ; Next page
dex
bne Z1
; Clear the remaining page
Z2: ldx #<__BSS_SIZE__
beq Z4
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.
jsr __hinit ; Initialize the heap
jsr initconio ; Initialize conio stuff
; Create the (empty) command line for the program
jsr push0 ; argc
jsr push0 ; argv
; Execute the program code
jmp Start
; ------------------------------------------------------------------------
; Additional data that we need for initialization and that's overwritten
; later
vectable:
jmp $0000 ; CINT
jmp $0000 ; IOINIT
jmp $0000 ; RAMTAS
jmp $0000 ; RESTOR
jmp $0000 ; VECTOR
jmp $0000 ; SETMSG
jmp $0000 ; SECOND
jmp $0000 ; TKSA
jmp $0000 ; MEMTOP
jmp $0000 ; MEMBOT
jmp k_scnkey ; SCNKEY
jmp $0000 ; SETTMO
jmp $0000 ; ACPTR
jmp $0000 ; CIOUT
jmp $0000 ; UNTLK
jmp $0000 ; UNLSN
jmp $0000 ; LISTEN
jmp $0000 ; TALK
jmp $0000 ; READST
jmp k_setlfs ; SETLFS
jmp k_setnam ; SETNAM
jmp $0000 ; OPEN
jmp $0000 ; CLOSE
jmp $0000 ; CHKIN
jmp $0000 ; CKOUT
jmp $0000 ; CLRCH
jmp $0000 ; BASIN
jmp $0000 ; BSOUT
jmp $0000 ; LOAD
jmp $0000 ; SAVE
jmp k_settim ; SETTIM
jmp k_rdtim ; RDTIM
jmp $0000 ; STOP
jmp $0000 ; GETIN
jmp $0000 ; CLALL
jmp k_udtim ; UDTIM
jmp k_screen ; SCREEN
jmp k_plot ; PLOT
jmp k_iobase ; IOBASE
sta ExecReg
rts
.byte $01 ; Filler
.word nmi
.word 0 ; Reset - not used
.word irq
vectable_size = * - vectable
p3vectable:
.word k_irq ; IRQ user vector
.word k_brk ; BRK user vector
.word k_nmi ; NMI user vector
p3vectable_size = * - p3vectable
; ------------------------------------------------------------------------
; This is the program code after setup. It starts at $400
.res $400-*
Start:
; Enable interrupts
cli
; Call the user code
ldy #4 ; Argument size
jsr _main ; call the users code
; Fall thru to exit.
_exit: jsr doatexit ; call exit functions
; 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.
k_brk: sei
lda #$00
ldx #$3E
Clear: sta $02,x
dex
bne Clear
; Setup the welcome code at the stack bottom in the system bank. Use
; the F4/F5 vector to access the system bank
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
; ------------------------------------------------------------------------
; Code that is copied into the system bank at $100 when switching back
reset: cli
jmp $8000 ; BASIC cold start
reset_size = * - reset
; ------------------------------------------------------------------------
; Code for a few simpler kernal calls goes here
k_iobase:
ldx cia
ldy cia+1
rts
k_screen:
ldx #80 ; Columns
ldy #25 ; Lines
rts
k_setlfs:
sta LogicalAdr
stx FirstAdr
sty SecondAdr
rts
k_setnam:
sta FileNameLen
lda $00,x
sta FileNameAdrLo
lda $01,x
sta FileNameAdrHi
lda $02,x
sta FileNameAdrSeg
rts
k_rdtim:
sei
lda time+0
ldx time+1
ldy time+2
cli
rts
k_settim:
sei
sta time+0
stx time+1
sty time+2
cli
rts
; -------------------------------------------------------------------------
; Data area - switch back to relocatable mode
.reloc
.data
spsave: .res 1

58
libsrc/cbm610/crtc.s Normal file
View File

@@ -0,0 +1,58 @@
;
; Ullrich von Bassewitz, 28.09.1998
;
; Write to the CRTC.
;
.export write_crtc, read_crtc
.importzp crtc
.include "cbm610.inc"
.include "zeropage.inc"
; Write a value to the CRTC. The index is in Y, the value in A
.proc write_crtc
sta sedt1
lda IndReg
pha
lda #$0F
sta IndReg
tya
ldy #$00
sei
sta (crtc),y
iny
lda sedt1
sta (crtc),y
cli
pla
sta IndReg
lda sedt1
rts
.endproc
.proc read_crtc
sty sedt1
lda IndReg
pha
lda #$0F
sta IndReg
lda sedt1
ldy #$00
sei
sta (crtc),y
iny
lda (crtc),y
cli
tay
pla
sta IndReg
tya
ldy sedt1
rts
.endproc

108
libsrc/cbm610/io.inc Normal file
View File

@@ -0,0 +1,108 @@
;
; I/O definitions for the CBM 610
;
; Taken from a kernal disassembly done by myself in 1987.
;
; Ullrich von Bassewitz, 28.09.1998
; I/O $d800: CRTC 6545
; crtc = $d800
CAdrReg = $00
CDataReg = $01
; I/O $da00: SID 6581
; sid = $da00
Osc1 = $00
Osc2 = $07
Osc3 = $0e
FreqLo = $00
FreqHi = $01
PulseF = $02
PulseC = $03
OscCtl = $04
AtkDcy = $05
SusRel = $06
FiCtlLo = $15
FiCtlHi = $16
Resonance = $17
Volume = $18
PotX = $19
PotY = $1A
Random = $1B
Env3 = $1C
; I/O $db00: CIA 6526 Inter Process Communication
; IPCcia = $db00
PortA = $00
PortB = $01
DDRA = $02
DDRB = $03
TimALo = $04
TimAHi = $05
TimBLo = $06
TimBHi = $07
TOD10 = $08
TODsec = $09
TODmin = $0A
TODhour = $0B
SerDataReg = $0C
IntCtrReg = $0D
CtrlA = $0E
CtrlB = $0F
; I/O $dc00: CIA 6526
; cia = $dc00
; I/O $dd00: ACIA 6551
; acia = $dd00
ADataReg = $00
AStatusReg = $01
ACmdReg = $02
ACtrlReg = $03
; 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

23
libsrc/cbm610/kbhit.s Normal file
View File

@@ -0,0 +1,23 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; int kbhit (void);
;
.export _kbhit
.import return0, return1
.include "zeropage.inc"
.proc _kbhit
lda KeyIndex ; Get number of characters
bne L1
jmp return0
L1: jmp return1
.endproc

100
libsrc/cbm610/kirq.s Normal file
View File

@@ -0,0 +1,100 @@
;
; Ullrich von Bassewitz, 28.09.1998
;
; IRQ routine for the 610.
;
.export irq, nmi, k_irq, k_nmi
.import k_scnkey, k_udtim, k_rs232
.importzp tpi1
.include "zeropage.inc"
.include "io.inc"
.include "page3.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 #tpiActIntReg
lda (tpi1),y ; Interrupt Register 6525
beq noirq
; -------------------------------------------------------------------------
; 50/60Hz interrupt
cmp #%00000001 ; ticker irq?
bne irq1
jsr k_scnkey ; Poll the keyboard
jsr k_udtim ; Bump the time
; -------------------------------------------------------------------------
; UART interrupt
irq1: cmp #%00010000 ; interrupt from uart?
bne irqend
jsr k_rs232 ; Read character from uart
; -------------------------------------------------------------------------
; Done
irqend: ldy #tpiActIntReg
sta (tpi1),y ; Clear interrupt
noirq: pla
sta IndReg
pla
tay
pla
tax
pla
k_nmi: rti

76
libsrc/cbm610/kplot.s Normal file
View File

@@ -0,0 +1,76 @@
;
; Ullrich von Bassewitz, 28.09.1998
;
; PLOT routine for the 610.
;
.export k_plot
.importzp crtc
.include "zeropage.inc"
.proc k_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

146
libsrc/cbm610/kscnkey.s Normal file
View File

@@ -0,0 +1,146 @@
;
; Ullrich von Bassewitz, 28.09.1998
;
; Keyboard polling stuff for the 610.
;
.export k_scnkey
.importzp tpi2, ktab1, ktab2, ktab3, ktab4
.include "zeropage.inc"
.include "io.inc"
.include "page3.inc"
.proc k_scnkey
lda #$FF
sta ModKey
sta NorKey
lda #$00
sta KbdScanBuf
ldy #tpiPortB
sta (tpi2),y
ldy #tpiPortA
sta (tpi2),y
jsr Poll
and #$3F
eor #$3F
bne L1
jmp NoKey
L1: lda #$FF
ldy #tpiPortA
sta (tpi2),y
asl a
ldy #tpiPortB
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 #tpiPortB
lda (tpi2),y
rol a
sta (tpi2),y
ldy #tpiPortA
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 #tpiPortA
sta (tpi2),y
ldy #tpiPortB
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 #tpiPortC
L1: lda (tpi2),y
sta KeySave
lda (tpi2),y
cmp KeySave
bne L1
rts
.endproc
.bss
KeySave: .res 1

25
libsrc/cbm610/kudtim.s Normal file
View File

@@ -0,0 +1,25 @@
;
; 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 k_udtim
.importzp time
.proc k_udtim
inc time
bne L9
inc time+1
bne L9
inc time+2
bne L9
inc time+3
L9: rts
.endproc

94
libsrc/cbm610/page3.inc Normal file
View File

@@ -0,0 +1,94 @@
;
; Page 3 variables for the CBM 610
;
; Taken from a kernal disassembly done by myself in 1987.
;
; Ullrich von Bassewitz, 28.09.1998
;
; 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
rvsFlag = $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
funvec = $03B5 ; Vector for function key handline
FunKeyTmp = $03B7
sedt3 = $03B9
MoniSegSave = $03f0
wstvec = $03F8
WstFlag = $03FA ; Warm start flag

38
libsrc/cbm610/pokesys.s Normal file
View File

@@ -0,0 +1,38 @@
;
; Ullrich von Bassewitz, 29.09.1998
;
; void pokebsys (unsigned Addr, unsigned char Val);
; void pokewsys (unsigned Addr, unsigned Val);
.export _pokebsys, _pokewsys
.import popsreg
.importzp sreg, tmp1
.include "zeropage.inc"
_pokebsys:
jsr popsreg ; Get the address
ldx IndReg
ldy #$0F
sty IndReg ; Switch to the system bank
ldy #$00
sta (sreg),y
stx IndReg
rts
_pokewsys:
stx tmp1 ; Save high byte
jsr popsreg ; Get the address
ldx IndReg
ldy #$0F
sty IndReg ; Switch to the system bank
ldy #$00
sta (sreg),y
iny
lda tmp1
sta (sreg),y
stx IndReg
rts

631
libsrc/cbm610/rs232.s Normal file
View File

@@ -0,0 +1,631 @@
;
; 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 "zeropage.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 #2 ; 2MHz
@L2: ldx #203 ;(2)
@L3: dex ;(2)
bne @L3 ;(3) // 1017 cycles
dey
bne @L2
sec
sbc #1
bne @L1
rts
.end

100
libsrc/cbm610/zeropage.inc Normal file
View File

@@ -0,0 +1,100 @@
;
; Zero page variables for the CBM 610
;
; Taken from a kernal disassembly done by myself in 1987.
;
; Ullrich von Bassewitz, 28.09.1998
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
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
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