Browse Source

added KERNAL_C128_03

pull/3/head
Michael Steil 6 years ago
parent
commit
5856785bc9
  1. 234
      KERNAL_C128_03/channelio.src
  2. 94
      KERNAL_C128_03/clall.src
  3. 144
      KERNAL_C128_03/close.src
  4. 690
      KERNAL_C128_03/declare.src
  5. 47
      KERNAL_C128_03/disclaim.src
  6. 34
      KERNAL_C128_03/entries.src
  7. 68
      KERNAL_C128_03/errors.src
  8. 516
      KERNAL_C128_03/init.src
  9. 124
      KERNAL_C128_03/interrupt.src
  10. 40
      KERNAL_C128_03/kernal.src
  11. 496
      KERNAL_C128_03/load.src
  12. 35
      KERNAL_C128_03/messages.src
  13. 254
      KERNAL_C128_03/open.src
  14. 135
      KERNAL_C128_03/openchnl.src
  15. 49
      KERNAL_C128_03/primm.src
  16. 447
      KERNAL_C128_03/relnotes.src
  17. 640
      KERNAL_C128_03/routines.src
  18. 190
      KERNAL_C128_03/rs232io.src
  19. 154
      KERNAL_C128_03/rs232nmi.src
  20. 145
      KERNAL_C128_03/rs232rcvr.src
  21. 164
      KERNAL_C128_03/rs232xmit.src
  22. 154
      KERNAL_C128_03/save.src
  23. 503
      KERNAL_C128_03/serial.src
  24. 537
      KERNAL_C128_03/sysdoc.src
  25. 211
      KERNAL_C128_03/tapectlr.src
  26. 198
      KERNAL_C128_03/tapefile.src
  27. 37
      KERNAL_C128_03/tapeirq.src
  28. 504
      KERNAL_C128_03/taperead.src
  29. 248
      KERNAL_C128_03/tapewrite.src
  30. 91
      KERNAL_C128_03/time.src
  31. 85
      KERNAL_C128_03/vectors.src
  32. 8
      README.md

234
KERNAL_C128_03/channelio.src

@ -0,0 +1,234 @@
.page
.subttl channel I/O (09/17/84): c/128
; ***********************************************
; * getin -- get a character from open channel *
; * *
; * channel is determined by dfltn. *
; * *
; * the keyboard and rs-232 (dfltn= 0 or 2) *
; * are serviced here by taking a character *
; * from the appropriate buffer. if nothing *
; * is available then = is returned. *
; * *
; * all other devices advance to 'basin'. *
; ***********************************************
ngetin
lda dfltn ;check default input device
bne 1$ ;...branch if not keyboard
lda ndx ;keyboard queue index
ora kyndx ;function key index
beq getrts ;...branch if nothing to get
sei ;freeze buffer
jmp lp2 ;goto editor to remove a character
1$ cmp #2
bne bn10 ;...branch if not rs-232
get232 sty xsav ;preserve .y
jsr bsi232 ;remove a character from rs-232 buffer
ldy xsav
getrts
clc ;signal a good return
rts
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; ***********************************************
; * basin - input a character from open channel *
; * *
; * channel is determined by dfltn. *
; * *
; * input from the keyboard or rs-232 is *
; * different than an get. input requires *
; * buffering an entire line which is then *
; * passed to 'basin' a character at a time *
; * up to the <cr>. *
; * *
; * the device assignments are: *
; * *
; * 0 = keyboard *
; * 1 = cassette *
; * 2 = rs-232 *
; * 3 = video display *
; * 4-31 = serial bus *
; ***********************************************
nbasin
lda dfltn ;check default input device
bne bn10 ;...branch if not the keyboard
; input from keyboard
lda pntr ;save current cursor position
sta lstp ;column
lda tblx
sta lsxp ;row
jmp loop5 ;goto screen editor, which will pass chr & rts
bn10
cmp #3 ;input from screen?
bne bn20 ;no...
sta crsw ;fake a carriage return for editor
lda scrt
sta indx ;point to right window margin as eol
jmp loop5 ;goto screen editor to pick up characters
bn20
bcs bn30 ;...branch if serial bus (device >3)
cmp #2
beq bn50 ;...branch if rs-232
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; input from cassette buffer
stx xsav ;preserve .x
jsr jtget
bcs 3$ ;...branch if <stop> or error
pha ;save character
jsr jtget
bcs 2$ ;...branch if <stop> or error
bne 1$ ;not an end of file
lda #64
jsr udst ;eof: update status
1$ dec bufpt ;one less chr in buffer
ldx xsav ;restore .x
pla ;restore character (.c=0 from 'jtget')
rts
2$ tax ;save error info
pla ;toss data
txa ;restore error
3$ ldx xsav ;restore .x (.c=1 from 'jtget')
rts
; routine to get a character from cassette buffer
jtget
jsr jtp20 ;buffer pointer wrap?
bne 1$ ;...branch if not
jsr rblk ;read next block from tape into buffer
bcs 2$ ;...branch if <stop> or error (.c=1)
lda #0
sta bufpt ;reset buffer index to beginning
beq jtget ;always
1$ lda (tape1),y ;get a character from cassette buffer
clc ;signal a good return
2$ rts
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; input from serial bus
bn30
lda status ;recall status from last serial operation
bne bn40 ;...branch if bad
jmp acptr ;ok...read a character off serial bus
bn40 lda #cr ;bad prior...fake null input
bn41 clc ; ...fake valid data
bn42 rts
; input from rs-232
bn50
jsr get232 ;get a character from rs-232 buffer
bcs bn41 ;...branch if error (.c=1, rts)
cmp #0
bne bn42 ;...branch if valid data (.c=0, rts)
lda rsstat ;null input?
and #$60 ;check for 'dsr' or 'dcd' error
bne bn40 ;...branch if error, fake a <cr>
beq bn50 ;loop until character received
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; ***********************************************
; * basout - output a character to open channel *
; * *
; * channel is determined by dflto: *
; * *
; * 0 = keyboard <invalid> *
; * 1 = cassette *
; * 2 = rs-232 *
; * 3 = video display *
; * 4-31 = serial bus *
; ***********************************************
nbsout
pha ;preserve .a (character to output)
lda dflto ;check default output device
cmp #3
bne 1$ ;...branch if not the screen
; print to video display device
pla ;restore data
jmp print ;goto editor to print to display
1$
bcc 2$ ;...branch if not serial
; output to serial bus
pla ;restore character to output
jmp ciout ;send chr out serial bus
2$
lsr a ;flag: .c=0=rs232, .c=1=cassette
pla ;restore character to output
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
casout ;////// entry from 'close' for cassette eot mark (.c=1)
sta t1 ;pass character in 't1'
txa
pha ;preserve x & y
tya
pha
bcc out232 ;...branch if rs-232 output
jsr jtp20 ;check cassette buffer index
bne 3$ ;...branch if not at end
jsr wblk ;write full buffer
bcs rstor ;...abort on <stop> key
lda #bdf ;output buffer type byte
ldy #0
sta (tape1),y
iny ;reset cassette buffer index
sty bufpt ; (.y=1)
3$
lda t1
sta (tape1),y ;put character into cassette buffer
rstoa clc ;signal good return
rstor
pla ;restore x & y
tay
pla
tax
lda t1 ;restore character for return
bcc 4$ ;...branch if no error
lda #0 ;return .a=0 & .c=1 if <stop> or error
4$ rts
; output to rs232 buffer
out232
jsr bso232 ;character to output is in 't1'
jmp rstoa ;always good
;.end

94
KERNAL_C128_03/clall.src

@ -0,0 +1,94 @@
.page
.subttl close all files (04/04/85)
; **********************************************
; * clall -- clear all logical files *
; * *
; * > deletes all table entries *
; * > clears serial port channels *
; * > restores default i/o channels *
; * *
; * ***WARNING: this call DOES NOT CLOSE *
; * open files!!! *
; * *
; **********************************************
nclall
lda #0
sta ldtnd ;reset table index, fall into 'clrch'
; **********************************************
; * clrch -- clear I/O channels *
; * *
; * > unlisten or untalk serial devices *
; * > restore default I/O channels *
; * *
; **********************************************
nclrch
ldx #3
cpx dflto ;check default output channel
bcs 1$ ;...branch if not serial
jsr unlsn ;unlisten serial device
1$ cpx dfltn ;check default input channel
bcs 2$ ;...branch if not serial
jsr untlk ;untalk serial device
; restore default i/o devices
2$ stx dflto ;default output channel = 3 (screen)
lda #0
sta dfltn ;default input channel = 0 (keyboard)
rts
.page
; **********************************************
; * close_all - closes all files on a *
; * given device. *
; * *
; * > search tables for given fa & do a *
; * proper close for all matches. *
; * *
; * > IF one of the closed entries is the *
; * current I/O channel THEN the default *
; * channel will be restored. *
; * *
; * entry: .a = device (fa) to close *
; * *
; **********************************************
close_all
sta fa ;save device to shut down
cmp dflto
bne 10$ ;...branch if not current output device
lda #3
sta dflto ;restore screen output
.byte $2c
10$ cmp dfltn
bne 20$ ;...branch if not current input device
lda #0
sta dfltn ;restore keyboard input
20$ lda fa
ldx ldtnd ;lat, fat, sat table index
30$ dex
bmi 40$ ;...branch if end of table
cmp fat,x
bne 30$ ;...loop until match
lda lat,x ;a match- extract logical channel data
jsr close ;close it via indirect
bcc 20$ ;always
40$ rts
;.end

144
KERNAL_C128_03/close.src

@ -0,0 +1,144 @@
.page
.subttl close file (03/15/85)
; ***********************************************
; * close function *
; * *
; * closes the file whose la is in .a and *
; * updates the logical file tables. *
; * *
; * the keyboard, screen and any unopened files *
; * pass thru. cassette files opened for writes *
; * are closed by writing the last buffer and *
; * (optionally) an eot mark. serial files are *
; * closed by sending a 'close' cmd if a sa was *
; * specified when it was opened. *
; * *
; * special handling for basic's dos routines: *
; * *
; * IF .c=1 AND fa=serial disk AND sa=15 *
; * THEN don't do a real close, just *
; * remove the table entry. this *
; * allows the disk cmd chnl to come *
; * and go without the disk closing *
; * ALL files on its end. *
; * *
; ***********************************************
nclose
ror svxt ;save .c for serial close
jsr jltlk ;look file up
bne clrts ;...branch if file not open (simply clc / rts)
1$ jsr getlfs ;extract table data
txa ;save table index
pha
lda fa ;check device number
beq jx150 ;...branch if keyboard (done)
cmp #3
beq jx150 ;...branch if screen (done)
bcs jx120 ;...branch if serial
cmp #2
bne jx115 ;...branch if cassette
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; close rs-232 file
pla ;restore table index
jsr jxrmv ;remove from table
jmp cln232 ;clean up rs232 for close, rts
; close cassette file
jx115 lda sa
and #$0f
beq jx150 ;...branch if tape read
jsr tapadr ;close tape write file
lda #0 ;end of file character
sec ;.c=1 for 'casout' to specify tape (not rs-232)
jsr casout ;put eof into buffer
jsr wblk ;output last tape block
bcc 1$ ;...branch if no errors
pla ;clean stack for error
lda #0 ;break key error
rts ; (.c=1)
1$ lda sa
cmp #$62
bne jx150 ;...branch if no eot mark to be written
lda #eot
jsr tapeh ;write end of tape block
jmp jx150
; close serial file
jx120 bit svxt ;special close for basic dos?
bpl jx130 ;...branch if not & do a real close
lda fa
cmp #8
bcc jx130 ;...branch if device not a serial disk
lda sa
and #$0f
cmp #$0f
beq jx150 ;...branch if sa=disk cmd chnl & skip real close
jx130
jsr clsei ;close a serial file, fall into 'jx150'
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; enter here to remove a given logical file entry from
; the table of logical, primary and secondary addresses.
jx150
pla ;restore table index
jxrmv ;////// entry for rs-232 file close
tax
dec ldtnd ;one less entry in table
cpx ldtnd
beq 1$ ;...branch if entry is last one in table (easy)
ldy ldtnd ;swap last entry with one to be closed
lda lat,y
sta lat,x
lda fat,y
sta fat,x
lda sat,y
sta sat,x
1$ clc ;signal good close
rts
lookup ;lookup logical file in table
lda #0
sta status ;clear previous i/o status
txa
jltlk
ldx ldtnd
1$ dex
bmi 2$ ;...branch if entry not found
cmp lat,x
bne 1$
2$ rts
getlfs
lda lat,x ;routine to fetch table entries
sta la
lda sat,x
sta sa
lda fat,x
sta fa ; (return with .p status of fa!)
rts
;.end

690
KERNAL_C128_03/declare.src

@ -0,0 +1,690 @@
.page
.subttl C/128 KERNAL & EDITOR DECLARATIONS (05/14/85)
* = $0000
d6510 *=*+1 ;6510 data direction register
r6510 *=*+1 ;6510 data register
bank *=*+1 ;monitor & long call/jump registers
pc_hi *=*+1
pc_lo *=*+1
s_reg *=*+1
a_reg *=*+1
x_reg *=*+1
y_reg *=*+1
stkptr *=*+1
* = $0090 ;kernal/editor allocations start here
status *=*+1 ;i/o operation status byte
stkey *=*+1 ;stop key flag
svxt *=*+1 ;tape temporary
verck *=*+1 ;load or verify flag
c3p0 *=*+1 ;serial buffered char flag
bsour *=*+1 ;char buffer for serial
syno *=*+1 ;cassette sync #
xsav *=*+1 ;temp for basin
ldtnd *=*+1 ;index to logical file
dfltn *=*+1 ;default input device #
dflto *=*+1 ;default output device #
prty *=*+1 ;cassette parity
dpsw *=*+1 ;cassette dipole switch
msgflg *=*+1 ;os message flag
ptr1 ;cassette error pass1
t1 *=*+1 ;temporary 1
ptr2 ;cassette error pass2
t2 *=*+1 ;temporary 2
time *=*+3 ;24 hour clock in 1/60th seconds
r2d2 ;serial bus usage
pcntr *=*+1 ;cassette stuff
bsour1 ;temp used by serial routine
firt *=*+1
count ;temp used by serial routine
cntdn *=*+1 ;cassette sync countdown
bufpt *=*+1 ;cassette buffer pointer
inbit ;rs-232 rcvr input bit storage
shcnl *=*+1 ;cassette short count
bitci ;rs-232 rcvr bit count in
rer *=*+1 ;cassette read error
rinone ;rs-232 rcvr flag for start bit check
rez *=*+1 ;cassete reading zeroes
ridata ;rs-232 rcvr byte buffer
rdflg *=*+1 ;cassette read mode
riprty ;rs-232 rcvr parity storage
shcnh *=*+1 ;cassette short cnt
sal *=*+1
sah *=*+1
eal *=*+1
eah *=*+1
cmp0 *=*+1
temp *=*+1
tape1 *=*+2 ;address of tape buffer
bitts ;rs-232 trns bit count
snsw1 *=*+1
nxtbit ;rs-232 trns next bit to be sent
diff *=*+1
rodata ;rs-232 trns byte buffer
prp *=*+1
fnlen *=*+1 ;length current file n str
la *=*+1 ;current file logical addr
sa *=*+1 ;current file 2nd addr
fa *=*+1 ;current file primary addr
fnadr *=*+2 ;addr current file name str
roprty ;rs-232 trns parity buffer
ochar *=*+1
fsblk *=*+1 ;cassette read block count
drive
mych *=*+1
cas1 *=*+1 ;cassette manual/controlled switch (updated during irq)
track
stal *=*+1
sector
stah *=*+1
memuss ;cassette load temps (2 bytes)
tmp2 *=*+2
data *=*+1 ;tape read/write data
ba *=*+1 ;bank for current load/save/verify operation
fnbank *=*+1 ;bank where current filename is found (at 'fnadr')
ribuf *=*+2 ;rs-232 input buffer pointer
robuf *=*+2 ;rs-232 output buffer pointer
.page
; 40/80 column S C R E E N E D I T O R declarations
;
; GLOBAL screen editor variables
keytab *=*+2 ;keyscan table pointer
imparm *=*+2 ;PRIMM utility string pointer
ndx *=*+1 ;index to keyboard queue
kyndx *=*+1 ;pending function key flag
keyidx *=*+1 ;index into pending function key string
shflag *=*+1 ;keyscan shift key status
sfdx *=*+1 ;keyscan current key index
lstx *=*+1 ;keyscan last key index
crsw *=*+1 ;<cr> input flag
mode *=*+1 ;40/80 column mode flag
graphm *=*+1 ;text/graphic mode flag
charen *=*+1 ;ram/rom vic character character fetch flag (bit-2)
; the following locations are shared by several editor routines
.share
sedsal *=*+2 ;pointers for MOVLIN
sedeal *=*+2 ;
sedt1 *=*+1 ;SAVPOS
sedt2 *=*+1 ;
.unshare
*=.share
keysiz *=*+1 ;programmable key variables
keylen *=*+1 ;
keynum *=*+1 ;
keynxt *=*+1 ;
keybnk *=*+1 ;
keytmp *=*+1 ;
*=.share
bitmsk *=*+1 ;temporary for TAB & line wrap routines
saver *=*+1 ;yet another temporary place to save a register
*=.unshare
.page
; LOCAL screen editor variables (swapped-out when 40/80 MODE changes)
.swapbeg
pnt *=*+2 ;pointer to current line (text)
user *=*+2 ;pointer to current line (attribute)
scbot *=*+1 ;window lower limit
sctop *=*+1 ;window upper limit
sclf *=*+1 ;window left margin
scrt *=*+1 ;window right margin
lsxp *=*+1 ;current input column start
lstp *=*+1 ;current input line start
indx *=*+1 ;current input line end
tblx *=*+1 ;current cursor line
pntr *=*+1 ;current cursor column
lines *=*+1 ;maximum number of screen lines
columns *=*+1 ;maximum number of screen columns
datax *=*+1 ;current character to print
lstchr *=*+1 ;previous character printed (for <esc> test)
color *=*+1 ;current attribute to print (default fgnd color)
tcolor *=*+1 ;saved attribute to print ('insert' & 'delete')
rvs *=*+1 ;reverse mode flag
qtsw *=*+1 ;quote mode flag
insrt *=*+1 ;insert mode flag
insflg *=*+1 ;auto-insert mode flag
locks *=*+1 ;disables <c=><shift>, <ctrl>-S
scroll *=*+1 ;disables screen scroll, line linker
beeper *=*+1 ;disables <ctrl>-G
.swapend
; remaining ZERO PAGE to be reserved for application software
.applications_zp
* = $ff
.basic_reserved_zp
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; PAGE ONE declarations (processor STACK)
;
* = $0100
bad *=*+1 ;tape read errors (this area also used by basic)
; PAGE TWO declarations (input buffer & kernal RAM code)
;
* = $0200
buf *=*+161 ;input buffer (used by basic & monitor)
* = $02a2
fetch *=*+13 ;LDA(-),y from any bank
fetvec = fetch+8
stash *=*+15 ;STA(-),y to any bank
stavec = stash+10
cmpare *=*+15 ;CMP(-),y to any bank
cmpvec = cmpare+10
jsrfar *=*+22 ;JSR xxxx to any bank & return
jmpfar *=*+25 ;JMP xxxx to any bank
; NOTE: basic indirect vectors start at $2fc !!
; ***** ALL UNUSED RAM LOCATIONS BELOW $1300 ARE RESERVED *****
; ***** FOR SYSTEM USE AND MUST NOT BE USED BY APPLICATIONS *****
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; PAGE THREE declarations (indirect vectors, kernal tables, basic RAM code)
* = $02fc ;basic indirect vectors
* = $0314 ;kernal indirect vectors
iirq *=*+2 ;irq
ibrk *=*+2 ;brk
inmi *=*+2 ;nmi
iopen *=*+2 ;
iclose *=*+2 ; conforms to kernal spec 8/19/80
ichkin *=*+2
ickout *=*+2
iclrch *=*+2
ibasin *=*+2
ibsout *=*+2
istop *=*+2
igetin *=*+2
iclall *=*+2
exmon *=*+2 ;monitor command indirect
iload *=*+2
isave *=*+2
;editor indirect vectors
ctlvec *=*+2 ;editor: print 'contrl' indirect
shfvec *=*+2 ;editor: print 'shiftd' indirect
escvec *=*+2 ;editor: print 'escape' indirect
keyvec *=*+2 ;editor: keyscan logic indirect
keychk *=*+2 ;editor: store key indirect
decode *=*+12 ;vectors to keyboard matrix decode tables
* = $34a
keyd *=*+10 ;irq keyboard buffer
tabmap *=*+10 ;bitmap of tab stops
bitabl *=*+4 ;bitmap of line wraps
lat *=*+10 ;logical file numbers
fat *=*+10 ;primary device numbers
sat *=*+10 ;secondary addresses
* = $0380 ;basic ram code here
* = $03f0 ;basic/kernal dma request ram code
do_dma
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; PAGE FOUR & HIGHER declarations (****** beginning of bankable ram ******)
;
* = $0400 ;video matrix #1: vic 40-column text screen
vicscn *=*+1024
* = $0800 ;basic run-time stack (512 bytes)
; ABSOLUTE kernal variables
;
* = $0a00
system_vector *=*+2 ;vector to restart system (usually BASIC warm start)
dejavu *=*+1 ;kernal warm/cold initialization status byte
palnts *=*+1 ;pal/ntsc system flag
init_status *=*+1 ;flags reset vs. nmi status for initialization routines
memstr *=*+2 ;pointer to bottom of available memory in system bank
memsiz *=*+2 ;pointer to top of available memory in system bank
irqtmp *=*+2 ;tape handler preserves irq indirect here
caston *=*+1 ;tod sense during tape operations
kika26 *=*+1 ;tape read temporary
stupid *=*+1 ;tape read d1irq indicator
timout *=*+1 ;fast serial timeout flag
enabl *=*+1 ;rs-232 enables
m51ctr *=*+1 ;rs-232 control register
m51cdr *=*+1 ;rs-232 command register
m51ajb *=*+2 ;rs-232 user baud rate
rsstat *=*+1 ;rs-232 status register
bitnum *=*+1 ;rs-232 number of bits to send
baudof *=*+2 ;rs-232 baud rate full bit time (created by OPEN)
ridbe *=*+1 ;rs-232 input buffer index to end
ridbs *=*+1 ;rs-232 input buffer index to start
rodbs *=*+1 ;rs-232 output buffer index to start
rodbe *=*+1 ;rs-232 output buffer index to end
serial *=*+1 ;fast serial internal/external flag
timer *=*+3 ;decrementing jiffie register
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; GLOBAL ABSOLUTE screen editor declarations
xmax *=*+1 ;keyboard queue maximum size
pause *=*+1 ;<ctrl>-S flag
rptflg *=*+1 ;enable key repeats
kount *=*+1 ;delay between key repeats
delay *=*+1 ;delay before a key starts repeating
lstshf *=*+1 ;delay between <C=><shft> toggles
blnon *=*+1 ;vic cursor mode (blinking, solid)
blnsw *=*+1 ;vic cursor disable
blnct *=*+1 ;vic cursor blink counter
gdbln *=*+1 ;vic cursor character before blink
gdcol *=*+1 ;vic cursor color before blink
curmod *=*+1 ;vdc cursor mode (when enabled)
vm1 *=*+1 ;vic text screen/character base pointer
vm2 *=*+1 ;vic bit-map base pointer
vm3 *=*+1 ;vdc text screen base
vm4 *=*+1 ;vdc attribute base
lintmp *=*+1 ;temporary pointer to last line for LOOP4
sav80a *=*+1 ;temporary for 80-col routines
sav80b *=*+1 ;temporary for 80-col routines
curcol *=*+1 ;vdc cursor color before blink
split *=*+1 ;vic split screen raster value
fnadrx *=*+1 ;save .x during bank operations
palcnt *=*+1 ;counter for pal systems (jiffie adjustment)
speed *=*+1 ;save system speed during tape & serial bus ops
sprites *=*+1 ;save sprite enables during tape & serial bus ops
blanking *=*+1 ;save blanking status during tape ops
hold_off *=*+1 ;flag set by user wanting full control of vic reserved
ldtb1_sa *=*+1 ;high byte of sa of vic screen (use with vm1 to move screen)
clr_ea_lo *=*+1 ;????? 8563 block fill kludge
clr_ea_hi *=*+1 ;????? 8563 block fill kludge
.page
; LOCAL screen editor variable swap area
;
* = $0a40
.swapout ;local variables
* = $0a60
.swapmap ;local tab map & wrap tables
; MONITOR absolute declarations
;
* = $0a80
.monitor_abs
; FUNCTION KEY ROM CARD tables
;
* = $0ac0
curbnk *=*+1 ;current function key rom bank being polled
pat *=*+4 ;physical address table (id's of logged-in cards)
dk_flag *=*+1 ;reserved for foreign screen editors
; ***** ALL UNUSED RAM LOCATIONS BELOW $1300 ARE RESERVED *****
; ***** FOR SYSTEM USE AND MUST NOT BE USED BY APPLICATIONS *****
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
* = $0b00
bufsz =192 ;tape buffer size
tbuffr *=*+bufsz ;cassette buffer
* = $0c00 ;rs-232 input buffer
rs232i
* = $0d00 ;rs-232 output buffer
rs232o
* = $0e00 ;sprite definition area (must be below $1000 !!)
* = $1000 ;programmable function key definitions
pkynum =10 ;number of definable keys (f1-f8, <shft>run, help)
pkybuf *=*+pkynum ;programmable function key lengths table
pkydef *=*+256-pkynum ;programmable function key strings
* = $1100 ;cp/m reset code, basic dos & vsp variables
* = $1200 ;basic absolute variables
* = $1300 ;unallocated absolute ram
.applications_abs
* = $1800 ;reserved for function key software applications
* = $1c00 ;video matrix #2 (1KB, bitmap color, if allocated)
rambot ;basic text starts here (kernal sets 'membot' here)
* = $2000 ;vic bitmap (8KB, if allocated)
* = $4000 ;************** beginning of rom over ram *************
* = $fc80 ;foreign language reserved rom (thru $feff)
.foreign_rom
* = $ff05 ;kernal interrupt ram code here (all ram banks)
* = $ffd0 ;cp/m transfer-processor-control ram code here (first ram bank only)
.cpm_ram_code
* = $fff5 ;'CBM' key goes here in ram1
locker
* = $fffa ;kernal hardware interrupt ram vectors here (all ram banks)
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;//////////////////// I / O D E V I C E M A P S \\\\\\\\\\\\\\\\\\\
vicchr = $d000 ;vic character rom
vicreg = $d000 ;vic registers
sidreg = $d400 ;sid registers
mmu_lo = $d500 ;mmu primary registers
vdc = $d600 ;8563 registers
viccol = $d800 ;vic color nybbles
cia1 = $dc00 ;6526 #1
cia2 = $dd00 ;6526 #2
io1 = $de00 ;expansion i/o slot (reserved)
io2 = $df00 ;expansion i/o slot (reserved: optional DMA ctlr for expansion ram)
mmu_hi = $ff00 ;mmu secondary registers (*** not in i/o block! ***)
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; c/128 memory management unit
; implements c/128, c/64, & cp/m 3.0 modes
;
* = mmu_lo
mmucrl *=*+1 ;configuration register (primary)
pcra *=*+1 ;preconfiguration register a
pcrb *=*+1 ;preconfiguration register b
pcrc *=*+1 ;preconfiguration register c
pcrd *=*+1 ;preconfiguration register d
mmumcr *=*+1 ;mode configuration register
mmurcr *=*+1 ;ram configuration register
mmup0l *=*+1 ;page 0 pointer low
mmup0h *=*+1 ;page 0 pointer high
mmup1l *=*+1 ;page 1 pointer low
mmup1h *=*+1 ;page 1 pointer high
mmuver *=*+1 ;mmu version number (*** prototype: reset latch ***)
* = mmu_hi
mmucr *=*+1 ;configuration register (secondary)
lcra *=*+1 ;load configuration register a
lcrb *=*+1 ;load configuration register b
lcrc *=*+1 ;load configuration register c
lcrd *=*+1 ;load configuration register d
; c/128 80-column video display controller
;
* = vdc
vdcadr *=*+1 ;8563 address register
vdcdat *=*+1 ;8563 data register
vdcscn = $0000 ;8563 80-column screen (2KB)
vdccol = $0800 ;8563 attribute area (2KB)
vdcchr = $2000 ;8563 character ram (4KB: 256 chrs, 8x16)
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; 6526 cia complex interface adapter #1
; keyboard / joystick / paddles / lightpen / fast disk
;
; pra0 : keybd output c0 / joystick #1 direction
; pra1 : keybd output c1 / joystick #1 direction
; pra2 : keybd output c2 / joystick #1 direction / paddle fire button
; pra3 : keybd output c3 / joystick #1 direction / paddle fire button
; pra4 : keybd output c4 / joystick #1 fire button
; pra5 : keybd output c5 /
; pra6 : keybd output c6 / / select port #1 paddles
; pra7 : keybd output c7 / / select port #2 paddles
;
; prb0 : keybd input r0 / joystick #2 direction /
; prb1 : keybd input r1 / joystick #2 direction / paddle fire button
; prb2 : keybd input r2 / joystick #2 direction / paddle fire button
; prb3 : keybd input r3 / joystick #2 direction /
; prb4 : keybd input r4 / joystick #2 fire button
; prb5 : keybd input r5 /
; prb6 : keybd input r6 / timer b: toggle/pulse output
; prb7 : keybd input r7 / timer a: toggle/pulse output
;
; timer 1 & cra : fast disk
; timer 2 & crb : cassette
;
; tod :
; sdr :
; icr :
* = cia1 ;device #1: 6526
colm
d1pra *=*+1 ;keyboard outputs / joystick / paddles / lightpen
rows
d1prb *=*+1 ;keyboard inputs / joystick / paddles
d1ddra *=*+1
d1ddrb *=*+1
d1t1l *=*+1
d1t1h *=*+1
d1t2l *=*+1
d1t2h *=*+1
d1tod1 *=*+1
d1tods *=*+1
d1todm *=*+1
d1todh *=*+1
d1sdr *=*+1
d1icr *=*+1
d1cra *=*+1
d1crb *=*+1
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; 6526 cia complex interface adapter #2
; user port / rs232 / serial bus / vic memory / nmi
;
; pra0 : va14
; pra1 : va15
; pra2 : rs232 DATA output
; pra3 : serial ATN output
; pra4 : serial CLK output
; pra5 : serial DATA output
; pra6 : serial CLK input
; pra7 : serial DATA input
;
; prb0 : user port / rs232 received data
; prb1 : user port / rs232 request to send
; prb2 : user port / rs232 data terminal ready
; prb3 : user port / rs232 ring indicator
; prb4 : user port / rs232 carrier detect
; prb5 : user port
; prb6 : user port / rs232 clear to send
; prb7 : user port / rs232 data set ready
;
; timer 1 & cra : rs232 baud rate
; timer 2 & crb : rs232 bit check
;
; tod :
; sdr :
; icr : nmi (/irq)
* = cia2 ;device #2: 6526
d2pra *=*+1 ;serial bus / rs232 / va14,15
d2prb *=*+1 ;user port / rs232
d2ddra *=*+1
d2ddrb *=*+1
d2t1l *=*+1
d2t1h *=*+1
d2t2l *=*+1
d2t2h *=*+1
d2tod1 *=*+1
d2tods *=*+1
d2todm *=*+1
d2todh *=*+1
d2sdr *=*+1
d2icr *=*+1 ;nmi's
d2cra *=*+1
d2crb *=*+1
timrb = $19 ;6526 crb enable one-shot tb
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; c/128 DMA controller for expansion RAM access (***PRELIMINARY***)
;
; (optional device mapped into IO2 block via system Expansion Port)
;
* = io2
dma_st *=*+1 ;DMA controller status register
dma_cmd *=*+1 ;DMA controller command register
dma_adl *=*+1 ;lsb of internal (c128) address to access
dma_adh *=*+1 ;msb of internal (c128) address to access
dma_lo *=*+1 ;lsb of external expansion ram to access
dma_hi *=*+1 ;msb of external expansion ram to access
dma_bnk *=*+1 ;64K external ram bank
dma_dal *=*+1 ;lsb of byte count
dma_dah *=*+1 ;msb of byte count (block count)
dma_sum *=*+1 ;checksum of last data transfer ????????????
dma_ver *=*+1 ;DMA version & memory limits
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; MISCELLANEOUS KERNAL & EDITOR EQUATES
eot =5 ;end of tape
blf =1 ;basic load file
bdf =2 ;basic data file
plf =3 ;fixed program type
bdfh =4 ;basic data file header
bakcol =11 ;VIC background screen color
forcol =13 ;VIC foreground screen color
bodcol =13 ;VIC screen border color
lf =10 ;line feed
cr =13 ;carriage return
esc =27 ;escape
space =32 ;space
quote =34 ;dbl quote
sysbnk = %00000000 ;mmu configuration: ram0, system roms, i/o
; configurations per 'config' table:
ram0 = 0 ;ram0, no roms, no i/o
ram1 = 1 ;ram1, no roms, no i/o
romram0 = 15 ;ram0, system roms, i/o (corresponds to 'sysbnk')
;.end

47
KERNAL_C128_03/disclaim.src

@ -0,0 +1,47 @@
.subttl *** COPYRIGHT (C) 1985 by COMMODORE BUSINESS MACHINES, INC. ***
; ******************************************************************
; * // *
; * CCCCCCC // 111 2222222 8888888 *
; * CCC CCC // 1111 222 222 888 888 *
; * CCC // 111 222 888 888 *
; * CCC // 111 222 88888 *
; * CCC // 111 222 888 888 *
; * CCC CCC // 111 222 222 888 888 *
; * CCCCCCC // 1111111 222222222 8888888 *
; * // *
; * *
; * KKK KKK EEEEEEEEE RRRRRRRR NNN NN AAA LLL *
; * KKK KKK EEE RRR RRR NNNN NN AA AA LLL *
; * KKK KKK EEE RRR RRR NNNNN NN AAA AAA LLL *
; * KKKKK EEEEEE RRRRRRRR NNN NN NN AAAAAAAAA LLL *
; * KKK KKK EEE RRR RRR NNN NNNN AAA AAA LLL *
; * KKK KKK EEE RRR RRR NNN NNN AAA AAA LLL *
; * KKK KKK EEEEEEEEE RRR RRR NNN NN AAA AAA LLLLLLL *
; * *
; * *
; * COPYRIGHT (C)1985 BY COMMODORE BUSINESS MACHINES, INC. *
; * *
; ******************************************************************
; ******************************************************************
; * *
; * THIS LISTING CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION *
; * OF CBM, INC. REPRODUCTION, DISSEMINATION OR DISCLOSURE TO *
; * OTHERS WITHOUT EXPRESS WRITTEN PERMISSION IS PROHIBITED. THIS *
; * SOFTWARE IS INTENDED FOR USE IN COMMODORE C/128 SYSTEMS ONLY. *
; * *
; * THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE *
; * WITHOUT NOTICE. *
; * *
; * NO RESPONSIBILITY IS ASSUMED FOR THE RELIABILITY OF THIS *
; * SOFTWARE. *
; * *
; ******************************************************************
;.end

34
KERNAL_C128_03/entries.src

@ -0,0 +1,34 @@
.page
.subttl C/128 KERNAL & EDITOR ENTRIES (12/18/84)
; entry definitions for c/128 EDITOR
cint = $c000 ;editor: initialization
display = $c003 ;editor: display chr in .a, color in .x
lp2 = $c006 ;editor: get a key from irq buffer
loop5 = $c009 ;editor: get a chr from screen
print = $c00c ;editor: print a chr to screen
scrorg = $c00f ;editor: return screen size of local display device
key = $c012 ;editor: general key scan
repeat = $c015 :editor: repeat key logic & 'ckit2' to store decoded key
plot = $c018 ;editor: read or set cursor position
cursor = $c01b ;editor: move 8563 hardware cursor
escape = $c01e ;editor: escape sequence handler, chr in .a
pfkey = $c021 ;editor: program function key
edirq = $c024 ;editor: irq entry
dlchr = $c027 ;editor: download 80-col character ram
swapper = $c02a ;editor: swap to alternate display device
; entry definitions for c/128 MONITOR
monitr = $b000 ;monitor: call entry
monbrk = $b003 ;monitor: brk entry
moncmd = $b006 ;monitor: monitor command parser
; entry definitions for c/128 BASIC
basic = $4000 ;basic: cold entry
basicw = $4003 ;basic: warm entry
basirq = $4006 ;basic: irq entry
;.end

68
KERNAL_C128_03/errors.src

@ -0,0 +1,68 @@
.page
.subttl error handler (09/17/84): c/128
; *******************************************************
; * stop *
; * *
; * >check stop key flag and return = if true. if true *
; * then close active channels & flush keyboard queue *
; * *
; * >note: returns scan from last keyboard row in .a *
; *******************************************************
nstop
lda stkey ;value of last row
cmp #$7f ;check stop key position
bne 1$ ;not down
php
jsr clrch ;clear channels
sta ndx ;flush queue
plp
1$ rts
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; *******************************************************
; * error handler *
; * *
; * > prints kernal error message if display enabled. *
; * > returns with error # in .a and .c=1 *
; *******************************************************
error1 lda #1 ;too many files
.byte $2c
error2 lda #2 ;file open
.byte $2c
error3 lda #3 ;file not open
.byte $2c
error4 lda #4 ;file not found
.byte $2c
error5 lda #5 ;device not present
.byte $2c
error6 lda #6 ;not input file
.byte $2c
error7 lda #7 ;not output file
.byte $2c
error8 lda #8 ;missing file name
.byte $2c
error9 lda #9 ;bad device #
.byte $2c
error16 lda #16 ;out of memory
pha ;error number on stack
jsr clrch ;restore i/o channels
ldy #ms1-ms1
bit msgflg
bvc 1$ ;...branch if display disabled
jsr msg ;print 'i/o error #'
pla
pha
ora #$30 ;make error # ascii
jsr bsout ;print it
1$ pla ;restore error code
sec ;signal error
rts
;.end

516
KERNAL_C128_03/init.src

@ -0,0 +1,516 @@
.page
.subttl C/128 KERNAL INITIALIZATION (04/29/85)
;//////////// S Y S T E M I N I T I A L I Z A T I O N \\\\\\\\\\\\
start ldx #$ff ;normal /reset entry
sei
txs
cld
lda #0
sta mmucr ;configure system map: c/128 mode, i/o in, ram0
ldx #10
10$ lda mmutbl,x
sta mmu_lo,x ;reset all mmu registers
dex
bpl 10$
sta init_status ;flags a reset (vs. nmi) for initialization routines
jsr install ;download kernal ram code
jsr secure ;an ounce of protection for ram-based software
jsr poll ;examine cartridge slots (& go if autostart)
jsr ioinit ;initialize I/O devices, determine NTSC or PAL
jsr ud60 ;test for <run/stop> AND cold reset
pha ; (save for 'jmp to monitor/c64 mode' test later)
bmi 20$ ;...branch to full init if <run/stop> not down
lda #$a5
cmp dejavu ;test for 'cold' or 'warm' reset
beq 30$ ;...branch to partial init if 'warm'
20$ jsr ramtas ;determine ram size, init system ram & ram code
30$ jsr restor ;initialize kernal indirect vectors
jsr cint ;initialize video displays (40 & 80)
pla
cli ;start system
bmi 40$ ;...branch if no <run/stop> key at <reset>
jmp monitr ;...start MONITOR
40$ cmp #$df
beq 50$ ;...branch if <C=> key at <reset>
jmp (system_vector) ;...start BASIC (usually)
50$ jmp c64mode ;...start C/64 mode
mmutbl .byte $00,$00,$00,$00,$00,$bf,$04,$00,$00,$01,$00
.page
;////////////////////// R E S T O R E \\\\\\\\\\\\\\\\\\\\\\\\\\
restor ;initialize kernal system indirect vectors
ldx #<vectss
ldy #>vectss
clc
; vector - set kernal indirect and vectors (user)
;
; enter with .c=0 to init, .c=1 to copy
vector
stx tmp2 ;x & y specify address low & high
sty tmp2+1
ldy #vectse-vectss-1
1$ lda iirq,y ;get from storage
bcs 2$ ;...c=1, want storage to user
lda (tmp2),y ;...c=0, want user to storage
2$ sta iirq,y ;put in storage
bcc 3$
sta (tmp2),y ;put in user
3$ dey
bpl 1$
rts
vectss
.word nirq ;irq handler
.word monbrk ;brk handler
.word nnmi ;nmi handler
.word nopen ;open
.word nclose ;close
.word nchkin ;chkin
.word nckout ;ckout
.word nclrch ;clrch
.word nbasin ;basin
.word nbsout ;bsout
.word nstop ;stop key scan
.word ngetin ;getin
.word nclall ;clall
.word moncmd ;monitor command parser
.word nload ;load
.word nsave ;save
vectse
.page
;/////////////////////// R A M T A S \\\\\\\\\\\\\\\\\\\\\\\\\\\
ramtas ;ram test and system ram initialization
lda #0
tay
1$ sta $0002,y ;clear all page 0 ram
iny
bne 1$
ldy #>tbuffr
sty tape1+1 ;allocate cassette & rs-232 buffers
sta tape1
ldy #>rs232i
sty ribuf+1
sta ribuf
ldy #>rs232o
sty robuf+1
sta robuf
clc ;set top of memory
ldy #>mmucr
ldx #<mmucr
jsr settop
ldy #>rambot ;set bottom of memory
ldx #<rambot
jsr setbot
ldy #>basic ;init system vector to basic cold start
ldx #<basic
sty system_vector+1
stx system_vector
lda #$a5 ;system ram now initialize, set 'warm' flag
sta dejavu
rts
.page
;/////////////////////// I N S T A L L \\\\\\\\\\\\\\\\\\\\\\\\\\
; initialize top of ram in each bank (assumes maximum of 4-64k ram banks)
install
ldy #3 ;for banks 0 to 3
1$ lda 10$,y ;get configuration for current bank
sta mmucr ;configure & copy kernal rom code (assumes bleed-thru)
ldx #.interrupt_end-.interrupt_code-1
2$ lda .interrupt_code,x
sta .interrupt_code,x
dex
bpl 2$
ldx #5 ;also copy nmi, reset, irq hardware vectors
3$ lda $fffa,x
sta $fffa,x
dex
bpl 3$
dey
bpl 1$ ;loop until done all banks (last bank must be ram0)
; initialize common ram code area in bottom of ram bank 0
ldx #dl_end-dl_beg-1
4$ lda dl_beg,x
sta fetch,x ;download 'FETCH, STASH, CMPARE, JSRFAR, JMPFAR' ram code
dex
bpl 4$
ldx #dl_dma-dl_end-1
5$ lda dl_end,x
sta do_dma,x ;download 'DO_DMA' ram code (***preliminary***)
dex
bpl 5$
rts
10$ .byte $00,$40,$80,$c0 ;configurations for system roms & ram0/1/2/3
.page
;//////////////////////// I O I N I T \\\\\\\\\\\\\\\\\\\\\\\\\\\
ioinit
lda #$7f ;kill timer interrupts
sta d1icr
sta d2icr
sta d1pra ;turn on stop key
lda #%00001000 ;shut off timers
sta d1cra
sta d2cra
sta d1crb
sta d2crb
ldx #0
stx d1ddrb ;set up keyboard inputs
stx d2ddrb ;set up user port (no rs-232)
dex ;($ff)
stx d1ddra ;set up keyboard outputs
lda #%00000111 ;set serial/va14/15 (clkhi)
sta d2pra
lda #%00111111 ;set serial in/out, va14/15out
sta d2ddra
lda #%11100011 ;initialize 6510 port: kybd, cassette, vic control
sta r6510
lda #%00101111 ;6510 ddr
sta d6510
ldx #$ff ;setup for PAL/NTSC test
10$ lda vicreg+17
bpl 10$ ;...branch until raster at bottom
20$ lda #$08
cmp vicreg+18
bcc 30$ ;...branch if >264: PAL system
lda vicreg+17
bmi 20$ ;...branch until raster wraps to top
inx ;NTSC system
30$ stx palnts
lda #0
sta speed ;init 1/2MHz flag
sta blanking ;clear vic blanking bit used by tape ops
sta irqtmp+1 ;clear irq redirection flag used by tape ops
sta hold_off ;clear user vic control flag
sta palcnt ;init counter for pal adjustment
sta dfltn ;set default input device (keyboard)
lda #3
sta dflto ;set default output device (screen)
.page
ldx #48
40$ lda victbl,x ;initialize vic
sta vicreg,x
dex
bpl 40$
ldx #0 ;initialize 8563 (NTSC)
jsr vdc_init
lda vdcadr
and #$07
beq 50$ ;...branch if old 8563R7
ldx #vdcpat-vdctbl
jsr vdc_init ;...else apply -R8 patches
50$ bit palnts
bpl 60$ ;...branch if NTSC
ldx #vdcpal-vdctbl
jsr vdc_init ;...else apply PAL patches
60$ lda init_status
bmi 70$ ;...branch if character set installed (this is an nmi or user call)
jsr dlchr ;initialize 8563 character definitions
lda #$80
ora init_status
sta init_status ;flag installation
ldx #$ff
ldy #$ff
65$ dey ;kludge to provide delay for vic-1541 reset to finish (only during reset)
bne 65$ ; (delay >300ms)
dex
bne 65$
70$ lda #0
ldx #24
80$ sta sidreg,x ;initialize sid
dex
bpl 80$
.page
iokeys ;////// entry from 'tape write' to restore normal irq's
ldx #$01
stx vicreg+26 ;enable vic raster irq (60HZ keyscan)
dex
stx serial ;reset fast serial flags to slow
stx enabl ;reset rs232 enable flag
dex
stx d1t2l ;unleash one timer for basic (random # generator)
stx d1t2h
ldx #%00010001
stx d1crb
jsr spinp ;toggle serial i/o (for fast drives)
jsr spout ;...out
jsr spinp ;...in
jmp clklo ;release the clock line & rts
vdc_init
ldy vdctbl,x ;get 8563 register #
bmi 10$ ;...branch if end-of-table
inx
lda vdctbl,x ;get data for this register
inx
sty vdcadr
sta vdcdat
bpl vdc_init ;always
10$ inx
rts
.page
;//////////////////////// S E C U R E \\\\\\\\\\\\\\\\\\\\\\\\\\\
;
; 1/ IF the system has just powered up, install a key & init vector.
; This is recognized by the missing 'CBM' key planted in 2nd RAM bank.
;
; 2/ IF a RESET entry (i.e., key was found) JMP indirectly
; through the SYSTEM vector in the 2nd RAM bank.
; a/ At power-up the Kernal will initialize this vector to
; affect a return to the normal INIT mechanisms.
; b/ All normal system paths to C64 mode redirect this vector
; to cause a return to C64 mode upon RESET, thus protecting
; most existing C64 software and necessitating a power-down
; sequence, destroying RAM contents, to escape.
; c/ C128 users may aim this vector much the same way the NMI
; indirect is manipulated, thus providing C128 software with
; RESET control and the means to protect themselves.
;
; Note that the jump thru the SYSTEM vector occurs from within a
; Kernal ROM subroutine. An RTS will continue normal initialization.
;
secure
ldx #<locker
ldy #>locker
stx tmp2
sty tmp2+1
lda #tmp2
sta fetvec
ldy #2
1$ ldx #$7f ;the key is in ram1
jsr fetch ;look for key
cmp cbmkey,y
bne c128mode ;not there, can only assume this is power-up
dey
bpl 1$
ldx #<system ;the vector is in ram1- move it to common ram
ldy #>system
stx tmp2
sty tmp2+1
ldy #1
2$ ldx #$7f
jsr fetch
sta bank,y
dey
bpl 2$
jmp (bank) ;got the key, take 'er out for a spin!
.page
c128mode
lda #$40 ;want ram1
sta mmucr
lda #<c128mode ;default 'system' /reset vector points to here!
ldy #>c128mode
sta system ; (still bleeding thru)
sty system+1
ldx #3 ;plant 'CBM' key in ram1
1$ lda cbmkey-1,x
sta locker-1,x ; (bleeds thru)
dex
bne 1$
stx mmucr ;restore system configuration (.x=0) & continue initialization
rts
.page
;//////////////////////// P O L L \\\\\\\\\\\\\\\\\\\\\\\\\\\
;
; 1/ IF any C64 cards installed GOTO C64 mode now. They are
; recognized by either /game or /exrom lines pulled low.
;
; 2/ IF any C128 cards installed THEN:
; a/ log its ID into the Physical Address Table (PAT).
; b/ IF its ID=1 CALL its cold_start vector (it may RTS).
;
; note: there are 4 slots (2 internal, 2 external, 16k each).
; the signature must match the following format:
;
; $x000 --> cold_start vector
; $x003 --> warm_start vector
; $x006 --> ID. (any ID=1 indicates an auto-start card)
; $x007 --> CBM
;
; where x= $8000 and $C000 16k blocks.
;
; non-autostart cards & any autostarters RTSing to POLL
; will be called by PHOENIX routine after kernal inits.
poll lda mmumcr ;(port sensitized prior to call!)
and #$30 ;examine /game & /exrom lines for c/64 cartridges
cmp #$30
beq poll_128 ;...branch if none
c64mode
lda #%11100011 ;initialize 6510 port
sta r6510
lda #%00101111 ;6510 ddr
sta d6510
ldx #c64end-c64beg
1$ lda c64beg-1,x ;download 'go_to_64_mode_code'
sta bank-1,x
dex
bne 1$
stx vicreg+48 ;force 1MHz mode
jmp bank ;abracadabra, we're a 64!
c64beg
lda #$f7 ;be sure /fsdir bit clear!
sta mmumcr ;tell mmu to configure system like a c/64
jmp ($fffc) ;simulate a reset
c64end
.page
poll_128
ldx #3 ;poll for c128 function key roms, in following order:
stx curbnk ; 1/ext-lo 2/ext-hi 3/int-lo 4/int-hi
lda #0
1$ sta pat,x ;initialize 'Physical Address Table'
dex
bpl 1$
sta ptr1 ;addr lo ($00 always)
2$ ldy #9
ldx curbnk
lda fkaddr,x
sta ptr1+1 ;addr hi (function rom high or low)
lda fkbank,x
sta bank ;bank (function rom internal or external)
3$ ldx bank
lda #ptr1
jsr indfet ; LDA (ptr1),Y from bank BA
cmp cbmkey-7,y
bne 4$ ;...branch if no key found here
dey
cpy #7
bcs 3$ ;...loop until entire key matches
ldx bank ;key found, log it in
lda #ptr1
jsr indfet ;id
ldx curbnk
sta pat,x
cmp #1
bne 4$ ;...branch if not an auto-start function rom
lda ptr1
ldy ptr1+1
sta pc_lo
sty pc_hi
jsr jsrfar ;call its cold-start routine
4$ dec curbnk
bpl 2$ ;...loop until all function roms polled
rts
fkaddr .byte $c0,$80,$c0,$80 ;function rom lo/hi table
fkbank .byte 4, 4, 8, 8 ;function rom banks (see 'config')
cbmkey .byte 'CBM' ;key
.page
victbl .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;reg 0-16 (sprite pos)
.byte $1b,$ff,0,0,0,$08,0,$14,$ff,1,0,0,0,0,0 ;reg 17-31 (control)
.byte bodcol,bakcol,1,2,3,1,2,0,1,2,3,4,5,6,7 ;reg 32-46 (colors)
.byte $ff,$fc ;reg 47-48 (keylines & 2MHz)
vdctbl .byte 0,$7e, 1,$50, 2,$66, 3,$49, 4,$20, 5,$00, 6,$19, 7,$1d ;8563 NTSC
.byte 8,$00, 9,$07,10,$20,11,$07,12,$00,13,$00,14,$00,15,$00
.byte 20,$08,21,$00,23,$08,24,$20,25,$40,26,$f0,27,$00,28,$20
.byte 29,$07,34,$7d,35,$64,36,$05,22,$78,$ff
vdcpat .byte 25,$47, $ff ;8563 patches
vdcpal .byte 4,$27, 7,$20,$ff ;8563 PAL
;.end

124
KERNAL_C128_03/interrupt.src

@ -0,0 +1,124 @@
.page
.subttl interrupt handler (03/11/85)
;///////////////// N M I I N T E R R U P T C O D E \\\\\\\\\\\\\\\\\\\\
nnmi
cld ;just in case there's a nerd out there
lda #$7f
sta d2icr ;disable nmi's by clearing mask register
ldy d2icr ; (must save icr in .y!)
bmi 1$ ;...branch if interrupt came from here (not <restore>)
jsr ud60 ;sets up keyports to last row (preserve .y!)
jsr stop ;scan for <stop> key (preserve .y!)
bne 1$ ;...branch if no <stop> key
jsr restor ;restore system indirects
jsr ioinit ;restore default i/o parameters
jsr cint ;restore default screen parameters
jmp (system_vector) ;<stop><restore> key convention- warm start BASIC
1$ jsr nmi232 ;go handle an rs-232 interrupt
jmp prend ;rti
;///////////// I R Q & B R K I N T E R R U P T C O D E \\\\\\\\\\\\
nirq ;////// kernal irq handler
cld ;just in case there's a nerd out there
jsr edirq ;blink cursor, scan keyboard, split screen stuff
bcc 1$ ;...branch if irq was only for split screen handler
jsr udtim ;update jiffie clock & scan stop key (ud60)
jsr tapeirq ;check cassette switches
lda d1icr ;clear alien irqs?
lda init_status
lsr a
bcc 1$ ;...branch if basic not installed
jsr basirq ;do basic's irq stuff
1$ jmp prend ;rti
.kernal_mid_check
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;////////////// I N T E R R U P T D I S P A T C H C O D E \\\\\\\\\\\\\
* = $ff05
.interrupt_code ;this code is copied into each ram bank at this address
nmi
sei ;disable irq's (could interfere with cassette ops)
pha ;save registers
txa
pha
tya
pha
lda mmucr ;save current memory configuration
pha
lda #sysbnk ;configure memory for system
sta mmucr
jmp (inmi) ;nmi indirect
irq ;////// hardware irq always comes here!
pha
txa
pha
tya
pha
lda mmucr ;save current memory configuration
pha
lda #sysbnk ;configure memory for system
sta mmucr
tsx ;determine if interrupt was an irq or brk
lda $105,x ;get processor status at interrupt time
and #$10 ;test break flag
beq 1$
jmp (ibrk) ;...taken if brk (goto monitor)
1$ jmp (iirq) ;...taken if irq
.page
prend ;////// entry from other kernal routines
pla
sta mmucr ;restore memory configuration
pla
tay ;restore registers
pla
tax
pla
rti
reset
lda #sysbnk ;force system configuration
sta mmucr
jmp start ;a new beginning...
.interrupt_end
.kernal_top_check
; * = $ffd0
;
;.cpm_ram ;cp/m puts its transfer-processor-control code here in first ram bank
;.end

40
KERNAL_C128_03/kernal.src

@ -0,0 +1,40 @@
.nam C/128 KERNAL (318020_03 RELEASE: 05/14/85)
.forml 60
.include disclaim
.include sysdoc
.include relnotes
.include declare
.include entries
*=$e000
.kernal_beg_check
.include init
.include serial
.include rs232xmit
.include rs232rcvr
.include rs232io
.include rs232nmi
.include tapefile
.include tapectlr
.include taperead
.include tapewrite
.include tapeirq
.include channelio
.include open
.include openchnl
.include close
.include clall
.include load
.include save
.include time
.include errors
.include messages
.include routines
.include interrupt ;contains an ORG $ff05 (& upper limit @ $fc80)
.include vectors
.subttl KERNAL CROSS REFERENCE
.end

496
KERNAL_C128_03/load.src

@ -0,0 +1,496 @@
.page
.subttl load (03/29/85)
; **********************************************
; * load memory from mass storage *
; * *
; * fa: 0= keyboard <invalid> *
; * 1= cassette *
; * 2= screen <invalid> *
; * 3= rs-232 <invalid> *
; * 4-31= serial *
; * *
; * sa: 0= alternate load *
; * (x,y= starting addr) *
; * 1= normal load *
; * (load starting addr) *
; * *
; * ba: 0-15= destination bank *
; * *
; * .a: 0= load memory *
; * >0= verify only *
; * *
; * ending address returned in x,y *
; **********************************************
loadsp ;////////// jump table entry: x & y have load address
stx memuss
sty memuss+1
load ;////////// old monitor entry (not c/128 monitor)
jmp (iload)
nload
sta verck ;preserve load/verify flag (load if = 0)
lda #0
sta status ;clear status
lda fa ;dispatch per device number
cmp #4
bcs lddisk ;load from serial device
jmp ldtape ;load from cassette tape
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; load memory from serial device (disk)
lddisk
lda serial ;assume slow disk, but attempt burst first
and #%10111110 ;clear external fast flag & burst load flag
sta serial
ldx sa
stx t1 ;save sa: flags normal/alternate load
ldy fnlen ;must have filename
bne 1$ ;...branch if so
jmp err8
1$ sty t2 ;save fnlen too
jsr luking ;'searching for...'
jsr burst ;try a burst load
bcs 2$ ;...branch if failed- retry as normal load
jmp lddone ;burst done
2$ ldy t2
sty fnlen ;restore fnlen
lda #$60
sta sa ;pass 'load' command to disk in sa
jsr openi ;open the file
lda fa
jsr talk ;establish the channel
lda sa
jsr tksa ;send 'load' command
jsr acptr ;get first byte (load adr lo)
sta eal
jsr acptr ;get second byte (load adr hi)
sta eah
lda status ;test status for error
lsr a
lsr a
bcs err4 ;...branch if 'file not found' error
lda t1 ;restore user sa (normal/alt load adr)
bne 10$ ;...branch if load address read from disk (normal)
lda memuss
sta eal ;load address given by user (alternate)
lda memuss+1
sta eah
10$ jsr loding ;'loading...'
20$ lda #$fd ;mask out timeout status bit
and status
sta status
jsr stop ;scan for keyboard <stop> key
beq brkerr ;...abort load operation
jsr acptr ;read a byte from serial bus
tax ;save data byte
lda status ;check status for timeout
lsr a
lsr a
bcs 20$ ;...branch if timeout occurred: try again
txa ;restore data byte
ldy verck
beq 30$ ;...branch if loading memory
sta ochar
ldy #0
jsr eally ;lda (eal),y ;verify memory
cmp ochar
beq 40$ ;...branch if good compare
lda #sperr ;set 'read error' bit to flag 'verify error'
jsr udst ;update i/o status byte
bne 40$ ;always
30$ jsr ealsy ;sta (eal),y
40$ inc eal ;increment load address for next data byte
bne 50$
inc eah
lda eah
cmp #$ff ;check for 'out of memory'
beq err16
50$ bit status
bvc 20$ ;...branch if not end_of_file
jsr untlk ;close channel
jsr clsei ;close the file
jmp lddone ;load operation done
err4 jmp error4 ;file not found
err8 jmp error8 ;missing filename
err9 jmp error9 ;illegal device
err16 jmp error16 ;out of memory
brkerr jmp break ;abort
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; load memory from cassette
ldtape
cmp #1
bne err9 ;...branch if 'illegal device' error
jsr tapadr ;setup pointers to cassette buffer
bcc err9 ;...branch if deallocated (error)
jsr cste1 ;prompt user 'press play...' & wait for it
bcs ldrts ;...branch if aborted by <stop> key
jsr luking ;'searching...'
1$ lda fnlen ;filename is optional for tape
beq 2$ ;...branch if none given (load any file)
jsr faf ;find a specified file on tape
bcc 3$ ;...branch if found
beq ldrts ;...branch if aborted by <stop> key
bcs err4 ;...branch if file not found (eot)
2$ jsr fah ;find next file on tape
beq ldrts ;...branch if aborted by <stop> key
bcs err4 ;...branch if file not found (eot)
3$ sec
lda status ;check i/o status of header read
and #sperr
bne ldrts ;...branch if read error (.c=1)
cpx #blf ;check file type read from header
beq 5$ ;...branch if relocatable load file (eg: basic pgm)
cpx #plf
bne 1$ ;...branch if not a load type file (eg: data file)
4$ ldy #1 ;load non-relocatable data (eg: asm pgm)
lda (tape1),y
sta memuss ;get load address from buffer
iny
lda (tape1),y
sta memuss+1
bcs 6$ ;always
5$ lda sa ;load relocatable data: test user's sa
bne 4$ ;...branch if normal load (ie: use load adr from tape)
6$ ldy #3 ;calculate # of bytes to load:
lda (tape1),y
ldy #1 ; (tape_ending_adr - tape_starting_adr)
sbc (tape1),y ; (.c=1)
tax ;low to .x
ldy #4
lda (tape1),y
ldy #2
sbc (tape1),y
tay ;high to .y
clc ;calculate true ending address
txa
adc memuss ; (memuss + #_of_bytes)
sta eal
tya
adc memuss+1
sta eah
cmp #$ff
beq err16 ;...'out of memory'
lda memuss ;set up load address for tape handler
sta stal
lda memuss+1
sta stah
jsr loding ;'loading...'
jsr trd ;load the file from tape
.byte $24 ;preserve status in .c from tape handler
lddone clc ;signal good load
ldx eal ;return ending address in x & y
ldy eah
ldrts rts ;done load
.page (*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)
burst
ldy #0
jsr fnadry ;examine filename
cmp #'$'
beq ldrts ;...branch if directory load (rts with .c=1 to load slow)
ldx fa ;fa: device #
ldy #15 ;sa: disk command channel
lda #0 ;la: use reserved la
jsr setlfs
sta fnlen ;no name just yet
jsr open ;open command channel to disk
ldx la
jsr ckout ;make it an output channel
bcc 10$ ;...branch if okay so far
jsr burst_end ;shut 'er down
pla
pla
jmp error5 ;device not present error
10$ ldy #3
20$ lda burst_cmd-1,y
jsr bsout ;send burst_load command
dey
bne 20$
30$ jsr fnadry
jsr bsout ;send filename
iny
cpy t2 ;fnlen
bne 30$
jsr clrch ;release clock & drop disk channel
bit serial ;was it good for you babe?
bvs 35$ ;...branch if fast (don't stop, don't stop! faster, faster!)
jsr burst_end
sec
rts ;return .c=1 & attempt a slow load
35$ lda t2
sta fnlen ;restore user fnlen
sei
jsr clkhi ;clk must be high
jsr spinp ;setup for input
bit d1icr ;clear byte pending
jsr wiggle ;toggle clk
jsr burst_byt ;read status byte
cmp #2
bne 40$ ;...branch if status ok
jsr burst_end ;shut 'er down
pla
pla
jmp error4 ;file not found error
40$ pha ;save last burst status
cmp #$1f ;by the way, was it eoi?
bne 45$ ;naaa
jsr wiggle ;toggle clk
jsr burst_byt ;yes- get # bytes to follow
sta count
jmp 46$
45$ cmp #2
bcc 46$
pla ;(pop saved status)
bcs burst_err
46$ jsr loding ;'loading...'
jsr wiggle ;toggle clk
jsr burst_byt ;read load address from disk
sta eal
jsr wiggle ;toggle clk
jsr burst_byt
sta eah
ldx t1 ;recall sa
bne 50$ ;...branch if default load (use disk load adr)
lda memuss
ldx memuss+1
sta eal ;replace load address with user's
stx eah
50$ lda eal ;preserve load address for basic 'boot & go' cmd
ldx eah
sta sal
stx sah
pla ;pop last burst status
cmp #$1f
beq burst_eoi ;...branch if current (first) block is the last block
60$ jsr wiggle ;toggle clk
lda #252 ;********** load first sector **********
sta count
70$ jsr ud60 ;scan stop key
jsr stop ;user requests abort?
beq burst_brk ;...yes
jsr burst_blk ;load a block (.x = # bytes to load)
bcs burst_errm ;...branch on error (out of memory)
jsr burst_byt ;check burst status
cmp #2 ;status ok?
bcc 80$ ;...branch if good
cmp #$1f
beq 90$ ;...branch if next block is the last block (eoi)
bne burst_err ;...branch on any other error (read error)
80$ jsr wiggle ;toggle clk
lda #254 ;********** load middle sectors **********
sta count
bne 70$ ;bra
90$ jsr wiggle ;toggle it ok...
jsr burst_byt ;eoi: read # bytes to load from last sector
sta count
burst_eoi
jsr wiggle
jsr burst_blk
bcs burst_errm ;...branch on error (memory)
lda #$40
jsr udst ;set eoi status bit
burst_end
jsr clkhi ;wave goodbye
cli ;shed a tear
lda la
sec ;not a full close
jsr close ;just clean up tables
clc ;signal successful burst load
rts
burst_err
lda #$02 ;all errors 'timeout'
jsr udst ;update i/o status byte
jsr burst_end ;shut down
pla
pla
lda #41
sec ;signal 'file read' error
rts ;return to user
burst_brk
jsr burst_end ;shut down our end
lda #0
sta sa ;kludge to prevent closing cmd channel
pla
pla
jmp break ;unlisten disk & return break error
burst_errm
jsr burst_end ;out of memory error
pla
pla
jmp error16
burst_byt
lda #$08
1$ bit d1icr ;wait for byte ready
beq 1$
lda d1sdr ;get byte
rts
burst_blk
lda #$08
99$ bit d1icr ;wait for byte ready
beq 99$ ;rewrite for speed
ldy d1sdr ;get byte
lda d2pra ;handshake (toggle clock)
eor #$10
sta d2pra
tya ;put data in .a
ldy verck
beq 1$ ;...branch if loading
sta ochar
ldy #0
jsr eally ; lda (eal),y from bank
cmp ochar
beq 2$ ;...branch if match
lda #sperr ;verify error: set 'read error' status bit
jsr udst
bne 2$ ;...always
1$ jsr ealsy ; sta (eal),y to bank
2$ inc eal ;increment address for next byte
bne 3$
inc eah
lda eah
cmp #$ff
beq 4$ ;...branch if out of memory error (.c=1)
3$ dec count
bne burst_blk ;...loop until .x bytes read
clc
4$ rts ;.c=0 for normal return. .c=1 for error return
wiggle lda d2pra ;handshake (toggle clock)
eor #$10
sta d2pra
rts
burst_cmd .byte %00011111,'0U' ;burst cmd string (backwards!)
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; subroutine to print to display: 'searching [for <filename>]'
luking
lda msgflg
bpl lurts ;...branch if display output disabled
ldy #ms5-ms1
jsr msg ;print 'searching '
lda fnlen
beq lurts ;...branch if no filename given
ldy #ms6-ms1
jsr msg ;print 'for ' & fall thru to display filename
; subroutine to print filename
outfn
ldy fnlen
beq lurts ;...branch if no filename given
ldy #0
1$
jsr fnadry ;lda (fnadr),y
jsr bsout ;print <filename>
iny
cpy fnlen
bne 1$
lurts
rts
; subroutine to print: 'loading' or 'verifying'
loding
ldy #ms10-ms1 ;setup 'loading'
lda verck
beq 1$ ;...branch if loading
ldy #ms21-ms1 ;setup 'verifying'
1$
jmp spmsg ;test for display enabled, print it, rts
;.end

35
KERNAL_C128_03/messages.src

@ -0,0 +1,35 @@
.page
.subttl kernal messages (09/17/84): c/128
msgtbl
ms1 .byte cr,'I/O ERROR ','#'+$80
ms5 .byte cr,'SEARCHING',' '+$80
ms6 .byte 'FOR',' '+$80
ms7 .byte cr,'PRESS PLAY ON TAP','E'+$80
ms8 .byte 'PRESS RECORD & PLAY ON TAP','E'+$80
ms10 .byte cr,'LOADIN','G'+$80
ms11 .byte cr,'SAVING',' '+$80
ms21 .byte cr,'VERIFYIN','G'+$80
ms17 .byte cr,'FOUND',' '+$80
ms18 .byte cr,'OK',cr+$80
.page
; print message to screen (only if output enabled)
spmsg
bit msgflg ;printing messages?
bpl msgrts ;no...
msg
lda msgtbl,y
php
and #$7f
jsr bsout
iny
plp
bpl msg
msgrts clc
rts
;.end

254
KERNAL_C128_03/open.src

@ -0,0 +1,254 @@
.page
.subttl open file (03/27/85)
; ***********************************************
; * open function *
; * *
; * creates an entry in the logical file tables *
; * necessary for kernal I/O consisting of: *
; * *
; * la - logical file number *
; * fa - device number (0-31) *
; * sa - secondary address (cmd) *
; * *
; * > call 'setlfs' first to set these up. *
; * > call 'setnam' first to set up filename. *
; * > call 'setbnk' first to specify fn bank. *
; ***********************************************
nopen ldx la ;check file number
jsr lookup ;see if in table
beq err2 ;...branch if file already open
ldx ldtnd ;logical device table end
cpx #10 ;check for maximum # of open files
bcs err1 ;...branch if too many files
inc ldtnd ;one more entry in table
lda la
sta lat,x ;store logical file #
lda sa
ora #$60 ;make sa an serial command
sta sa
sta sat,x ;store command #
lda fa
sta fat,x ;store device #
; perform device specific open tasks
beq opnrts ;...branch if keyboard (done)
cmp #2
beq opn232 ;...branch if rs-232
bcc opncas ;...branch if cassette
cmp #3
beq opnrts ;...branch if screen (done)
jsr openi ;open serial file
opnrts clc ;signal good return
rts
err1 jmp error1 ;too many open files
err2 jmp error2 ;file already open
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; open cassette file
opncas jsr tapadr ;see if tape buffer allocated
bcs 1$
jmp error9 ;...branch if deallocated (error)
1$ lda sa
and #$0f ;mask off command
bne 4$ ;...branch if open for tape write
; open cassette tape file to read
jsr cste1 ;prompt 'press play'
bcs 7$ ;...branch if <stop> key pressed (rts)
jsr luking ;prompt 'searching'
lda fnlen ;a filename given?
beq 3$ ;no...
jsr faf ;looking for a specific file
bcc 5$ ;...branch if found
beq 7$ ;...branch if aborted by <stop> key (rts)
2$ jmp error4 ;'file not found' error
3$ jsr fah ;looking for any file
bcc 5$ ;...branch if found
beq 7$ ;...branch if aborted by <stop> key (rts)
bcs 2$ ;...branch if file not found (always)
; open cassette tape file for write
4$ jsr cste2 ;prompt 'press play and record'
bcs 7$ ;...branch if <stop> key pressed (rts)
lda #bdfh ;data file header type
jsr tapeh ;write it
; finish open for cassette tape read/write
5$ lda #bufsz-1 ;assume force read
ldy sa
cpy #$60 ;open for read?
beq 6$
; set pointers for buffering data
ldy #0
lda #bdf ;type flag for block
sta (tape1),y ;to begin of buffer
tya
6$ sta bufpt ;point to data
clc ;signal good open
7$ rts
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; opn232 - open an rs-232 or parallel port file
;
; variables initialized:
;
; bitnum - # of bits to be sent calc from m51ctr
; baudof - baud rate full
; rsstat - rs-232 status reg
; m51ctr - 6551 control reg
; m51cdr - 6551 command reg
; m51ajb - user baud rate (clock/baud/2-100)
; enabl - 6526 nmi enables (1-nmi bit on)
opn232
jsr cln232 ;set up rs232, .y=0 on return
sty rsstat ;clear status
1$ cpy fnlen ;check if at end of filename
beq 2$ ;yes...
jsr fnadry ;lda (fnadr),y- move configuration data to m51-registers
sta m51ctr,y
iny
cpy #4 ; (only 4 possible parameters)
bne 1$
2$ jsr bitcnt ;calculate # of bits
stx bitnum
lda m51ctr ;calculate baud rate
and #$0f
beq 5$
; calculate start-test rate...
asl a ;get offset into tables
tax
lda palnts ;get tv standard
bne 3$
ldy baudo-1,x ; (ntsc standard)
lda baudo-2,x
jmp 4$
3$ ldy baudop-1,x ; (pal standard)
lda baudop-2,x
4$ sty m51ajb+1 ;hold start rate in m51ajb
sta m51ajb
5$ lda m51ajb ;calculate baud rate
asl a
tax
lda m51ajb+1 ;m51ajb = freq/baud/2-100
rol a
tay
txa
adc #cbit+cbit
sta baudof
tya
adc #0
sta baudof+1
lda m51cdr ;check for 3- or x-line response
lsr a ; (test bit 0 of m51cdr)
bcc 6$ ;...branch if 3-line
lda d2prb ;check for x-line proper states
asl a
bcs 6$
jsr ckdsrx ; (change from jmp to prevent system damage in c/64)
6$ lda ridbe ;set up buffer pointers (dbe=dbs)
sta ridbs
lda rodbe
sta rodbs
rts
; cln232 - cleans up rs-232 system for open/close
; - set up ddrb and cb2 for rs-232
cln232
lda #$7f ;clear nmi's
sta d2icr
lda #%00000110 ;ddrb
sta d2ddrb
sta d2prb ;dtr,rts high
lda #$04 ;output high pa2
ora d2pra
sta d2pra
ldy #0
sty enabl ;clear enables
rts
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; open a serial device file
openi
lda sa
bmi 1$ ;...branch if no sa (done, tables already updated)
ldy fnlen
bne 2$ ;...branch if file name given, else done
1$ clc
rts
2$ lda #0 ;clear the serial status
sta status
lda fa
jsr listn ;device la to listen
bit status ;check serial status
bmi 3$ ;...branch if no response to 'listen' command
lda sa
ora #$f0
jsr secnd ;send secondary address (cmd)
lda status ;check serial status
bpl 4$ ;...branch if ok
; this routine is called by other kernal routines which are called
; directly by os. must trash their return address to return to os.
3$ pla
pla
jmp error5 ;'device not present' error
4$ lda fnlen
beq 6$ ;...branch if no file name to send
ldy #0
5$ jsr fnadry ;lda (fnadr),y (routine uses .x!)
jsr ciout ;send filename
iny
cpy fnlen
bne 5$
6$ jmp cunlsn ;done: do 'jsr unlsn / clc / rts'
;.end

135
KERNAL_C128_03/openchnl.src

@ -0,0 +1,135 @@
.page
.subttl open channel for I/O (12/18/84)
; ******************************************************
; * chkin -- open channel for input *
; * *
; * looks up given logical file in table and performs *
; * device specific open tasks. checks for files not *
; * opened (not in table), write-only files, & devices *
; * not present, reporting any errors. *
; * *
; * >enter with .x = logical file # *
; * >exits with .c=0 & dfltn= device # from table *
; * or .c=1 if error *
; ******************************************************
nchkin
jsr lookup ;search table for la (passed in .x)
bne err3 ;...branch if 'file not open' error
jsr getlfs ;copy table info into la, fa, sa
beq ckirts ;...branch if keyboard (done)
cmp #3
beq ckirts ;...branch if screen (done)
bcs ckiser ;...branch if serial device
cmp #2
bne ckitap ;...branch if cassette
jmp cki232 ;goto rs-232 handler
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; open cassette file for input
ckitap ldx sa
cpx #$60
bne err6 ;...branch if file not open for input
ckirts sta dfltn ;make all future input come from fa in .a
clc ;signal good return
rts
; open serial device for input (make it a talker)
ckiser tax ;preserve fa (device #)
jsr talk ;establish device as a talker
bit status ;anybody home?
bmi err5 ;...branch if no response
lda sa ;get secondary adr (command)
bpl 1$ ;...branch if something to send
jsr tkatn ;no...let go
bpl 2$ ;always
1$ jsr tksa ;send command & let go
2$ txa ;restore fa (device #)
bit status
bpl ckirts ;...branch if device responded, else fall into 'err5'
err5 jmp error5 ;device not present
err6 jmp error6 ;not an input file
err7 jmp error7 ;not an output file
err3 jmp error3 ;file not open
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; ******************************************************
; * ckout -- open channel for output *
; * *
; * looks up given logical file in table and performs *
; * device specific open tasks. checks for files not *
; * opened (not in table), read-only files, & devices *
; * not present, reporting any errors. *
; * *
; * >enter with .x = logical file # *
; * >exits with .c=0 & dflto= device # from table *
; * or .c=1 if error *
; ******************************************************
nckout
jsr lookup ;search table for la (passed in .x)
bne err3 ;...branch if 'file not open' error
jsr getlfs ;copy table info into la, fa, sa
beq err7 ;...branch if keyboard (error: not an output file)
cmp #3
beq ckorts ;...branch if screen (done)
bcs ckoser ;...branch if serial device
cmp #2
bne ckotap ;...branch if cassette
jmp cko232 ;goto rs-232 handler
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; open cassette file for output
;
ckotap ldx sa
cpx #$60
beq err7 ;...branch if file not opened for output
ckorts sta dflto ;make all future output go to fa in .a
clrts clc ;signal good return
rts
; open serial device for output (make it a listener)
ckoser tax ;preserve fa (device #)
jsr listn ;establish device as a listener
bit status ;anybody home?
bmi err5 ;...branch if no response
lda sa ;get secondary adr (command)
bpl 1$ ;...branch if something to send
jsr scatn ;no...release channel
bne 2$ ;always
1$ jsr secnd ;send command & release channel
2$ txa ;restore fa (device #)
bit status
bpl ckorts ;...branch if device responded
bmi err5 ;...branch if device not present (always)
;.end

49
KERNAL_C128_03/primm.src

@ -0,0 +1,49 @@
primm pha ;protect a,x,y
txa
pha
tya
pha
tsx ;get sp
inx ;make it point to return addr low
inx
inx
inx
lda $0100,x ;get it
sta imparm ;in base ptr.
inx ;point to hi
lda $0100,x ;get it
sta imparm+1 ;in base ptr.
inc imparm ;this was actually a return addr minus 1
bne 1$ ;...note that a string of only a $0 will work
inc imparm+1
1$ ldy #0 ;we're pointing to 1st byte of string
2$ lda (imparm),y ;loop to output string
beq 3$
jsr bsout
iny
bne 2$
3$ tya ;y has offset to add onto imparm base
tsx ;shove true return addr in the stack
inx ;x points to ret adr lo
inx
inx
inx
clc
adc imparm
sta $0100,x ;new lo ret adr
lda #0
adc imparm+1
sta $0101,x ;new hi ret adr
pla
tay
pla
tax
pla
rts

447
KERNAL_C128_03/relnotes.src

@ -0,0 +1,447 @@
.page
.subttl RELEASE NOTES: BETA-5 03/05/85
; THE FOLLOWING MODIFICATIONS HAVE BEEN MADE TO THE BETA-4 CODE TO CREATE THE
; BETA-5 VERSION RELEASED ON 03/05/85. THE BETA-5 RELEASE IS A PRE-PRODUCTION
; VERSION INTENDED FOR SYSTEM TEST AND EVALUATION AND PRELIMINARY APPLICATION
; SOFTWARE DEVELOPMENT ONLY.
;
;
; The following changes have been made to the MONITOR:
;
; 1/ The MONITOR now accepts binary, octal, decimal and hexidecimal
; values for any numeric field. This was accomplished by totally
; re-coding PARSE and portions of ASSEM, and installing a new
; routine called EVAL. Numbers prefixed by one of the characters
; $ + & % are interpreted by EVAL as base 16, 10, 8, or 2 values
; respectively. In the absence of a prefix, the base defaults to
; hexidecimal always. ASSEM will use the zero-page form wherever
; possible unless the value is preceeded by extra zeros to force
; the absolute form (except binary notation).
;
; 2/ The MONITOR now performs limited number conversion. Additions
; were made to MAIN1 and CMDCHR and a new routine called CONVERT
; was installed to handle the conversions. Any of the characters
; $ + & % entered as a command and prefixing a numeric value are
; PARSEd (see #1 above) and the hexidecimal value printed. Full
; conversion between bases may be added in a later release.
;
;
;
; The following changes have been made to the EDITOR:
;
; 1/ PLOT (SET) now performs range checking. The cursor position
; sought must lie within the currently defined window. If it does,
; the position is changed and .C=0 returned, else NO CHANGE made
; and .C=1 returned.
;
; 2/ PLOT (READ) now returns the current cursor position within the
; current window (with respect to the window's origin) and NOT
; necessarily the screen origin.
;
; 3/ SCRORG was changed in a previous release to return the current
; window size in .X and .Y and NOT the screen size. SCRORG will
; now return the maximum screen width (39 or 79) as well in .A.
;
; 4/ The entire data file, ED7.SRC, has been relocated to $FA00 to
; allow a reserved area in ROM for foreign language systems. The
; reserved area shall be $FC80 thru $FEFF. This affects the MODE
; tables, COLor tables, BITS, local variable init table, and all
; PKY function key tables.
;
; 5/ The default screen colors for the 80-column screen have been
; changed to BLACK background and CYAN characters. This was done
; to make a more presentable screen for systems using monochrome
; monitors and allow a full pallet of colors without background
; interference for systems using RGBI monitors.
;
;
;
; The following changes have been made to the KERNAL:
;
; 1/ IOINIT now initializes the 8563 chip from an updated table now
; that the tower has been removed. Also changed were the default
; screen colors (see #5 above) and adjustments for PAL systems.
;
; 2/ IOINIT now has a delay loop of approximately 300ms incorporated
; into it to allow older versions of the VIC-1541 disk drives to
; finish their reset sequence. The system previously hung in the
; auto-boot routine if in 40-column mode with old 1541's.
;
.page
.subttl RELEASE NOTES: BETA-6 03/20/85
; THE FOLLOWING MODIFICATIONS HAVE BEEN MADE TO THE BETA-5 CODE TO CREATE THE
; BETA-6 VERSION RELEASED ON 03/20/85. THE BETA-6 RELEASE IS A PRE-PRODUCTION
; VERSION INTENDED FOR SYSTEM TEST AND EVALUATION AND PRELIMINARY APPLICATION
; SOFTWARE DEVELOPMENT ONLY. NOTE THE CHANGE TO THE CHARACTER ROM ALSO.
;
;
;
; The following changes have been made to the MONITOR:
;
; 1/ Number conversion from/to all bases (hex,dec,oct,bin) fully
; functional. Display format different from beta-5 also.
;
; 2/ The monitor DOS parser now provides DIRECTORY display using
; the syntax: @[unit#],$[drive:filespec]
;
;
;
; The following changes have been made to the EDITOR:
;
; 1/ The KEYSCAN routine was corrected to properly leave the COLM
; driver port energizing only PB7. (Previously if no keys were
; down all lines were left energized.) Also the scan of the
; CAPS LOCK key was moved to the beginning of the KEYSCAN loop
; where it will always be scanned and SHFLAG correctly updated.
; (Previously if no matrix keys were down it was not scanned.)
;
; 2/ The CLRLIN and MOVLIN routines have had all the 'kludge' code
; removed as it is no longer necessary using 8563R7 parts. Two
; absolute variables consequently have disappeared, SAV80C & D.
;
; 3/ The various tables used by the screen editor have been shifted
; around to allow better utilization of free ROM. The MODEx tables
; now start at $FA80. All other tables now float above editor code.
;
;
;
; The following changes have been made to the KERNAL:
;
; 1/ The interrupt handlers now clear decimal mode (via CLD). This
; is done AFTER the indirect jumps are made. The correct mode is
; restored upon return from the interrupt code as usual.
;
; 2/ The SERIAL & TAPE routines now work at either 1 or 2MHz speed.
; This was accomplished by replacing 'SEI' and 'CLI' opcodes in
; time sensitive routines with JSR's to new code which saves the
; current states & forces sprites off & 1MHz speed, and then re-
; stores them all when through. This required minor changes to the
; TAPE routines, but the serial ACPTR routine was totally re-coded.
; Several absolute variables to store the states have been added
; as well as one called HOLD_OFF which, if B7 is set, will cause
; these new SEI/CLI routines to be skipped & require the user to
; assume full responsibility for controlling system speed & sprites
; during tape or serial I/O operations.
;
; 3/ The space key now correctly skips the current 'found' file during
; TAPE loads. (The C= key or <no> action will initiate program load.)
;
; 4/ The CLOSE routine now saves the CARRY status in SVXT and not VERCK.
; This corrects a conflict with the LOAD routine's use of VERCK.
;
; 5/ The BURST routine now correctly reports a 'device not present'. It
; previously reported 'illegal device number'.
;
; 6/ Improved TKSA (serial routine) turnaround by putting DEBPIA inline.
;
; 7/ The OPEN routine now JSR's to OPENI for serial operations. This
; corrects a problem that occurred when the device was not present.
; OPENI pops the return address and JMPs to ERROR5 at such time.
;
; 8/ The INSTALL routine now downloads to RAM the correct code for the
; DMA Controller. Previously the wrong subroutine was downloaded.
; Also, a NOP was added to the RAM code after the DMA request.
;
;
;
; The following changes have been made to the CHARACTER ROM:
;
; 1/ Part number 315010-02 has a minor error in the font definition
; for the lower case reverse field 'v'. This has been corrected in
; part number 315010-03.
;
; 2/ Part number 315010-03 also includes a modification to the lower
; case 'm' character (both normal & reverse fields) due to several
; complaints about its appearance.
;
.page
.subttl RELEASE NOTES: BETA-7 04/08/85
; THE FOLLOWING MODIFICATIONS HAVE BEEN MADE TO THE BETA-6 CODE TO CREATE THE
; BETA-7 VERSION RELEASED ON 04/08/85. THE BETA-7 RELEASE IS A PRE-PRODUCTION
; VERSION INTENDED FOR SYSTEM TEST AND EVALUATION AND PRELIMINARY APPLICATION
; SOFTWARE DEVELOPMENT ONLY. NOTE THE CHANGE TO THE CHARACTER ROM ALSO.
;
;
;
; The following changes have been made to the MONITOR:
;
; 1/ Previously the HUNT command treated <colon> and <question> in
; ASCII strings as terminators, hence they could not be hunted
; for. This has been corrected.
;
; The following changes have been made to the KERNAL:
;
; 1/ Previously the GO64 routine redirected the soft RESET vector
; back to itself thus providing a degree of protection to C/64
; software as the system had to be powered down to escape C/64
; mode. Unfortunately DRAM devices are not as volatile as they
; used to be and many systems required as much as 30 seconds to
; elapse before they would power up into C/128 mode. The RESET
; vector is still present but the GO64 code no longer redirects
; it. Applications using RESET should note the problem and pro-
; vide a friendly escape mechanism after protecting themselves.
;
; 2/ Previously it was possible to enter C64 mode running at 2MHz.
; This has been corrected. Note it is possible from C64 mode to
; access the 1-2MHz bit (VIC register 48) to speed up certain
; operations if so desired.
;
; 3/ Several minor changes to SERIAL code. Some inaccessable code
; was removed from TALK/LISTEN routine. TKSA now errors out if
; the SA could not be sent.
;
; 4/ Previously the BOOT routine returned without reporting any
; errors. BOOT now returns errors in the same manner as LOADs,
; with the carry set and error code in the accumulator.
;
; 5/ Previously the BURST load mechanism caused open disk channels
; to be flushed. This has been corrected and now preserves open
; user channels as the C/64 LOAD had (e.g. chaining programs).
; Note however that BOOT loads will cause all open files for
; the given device to be closed (see CLOSE_ALL note below).
;
; 6/ BURST must UNLISTEN the 1571 when a break occurs (STOP key)
; to signal the drive to abort the operation. Previously the
; drive stayed in its burst routine waiting to send the next
; block of data. This fix will prompt the drive to abort too.
;
; 7/ The DMA controller routine (for RAMDISK) has been modified to
; meet the latest RAMDISK specification.
;
; 8/ A new Kernal JUMP TABLE entry has been created for an all new
; Kernal subroutine, CLOSE_ALL. Unlike CLALL, which simply
; cleared the LAT, FAT, SAT tables and restored the default I/O
; devices without properly closing files, CLOSE_ALL is passed a
; device number (fa) and properly closes ALL open files on that
; device. If that device was the current I/O device, only then
; will CLOSE_ALL restore the appropriate default device. This
; new jump vector is located at $FF4A.
;
; 9/ The Kernal IOINIT routine will recognize 8563-R8 & initialize
; register #25 (horz. smooth scroll) to $47 per 8563 spec mods.
; Previously this register was initialized to $40. Note that
; the lower 3 bits of the 8563 status register will return the
; revision level of the 8563 part (0=R7, 1=R8, etc.)
;
;
; The following changes have been made to the CHARACTER ROM:
;
; 1/ The hardware now supports an 8K byte character ROM. The lower
; 4K contains the C/64 character set (P/N 901225-01), and the
; upper 4K contains the C/128 character set (P/N 315010-03).
; In domestic systems the switching mechanism is the /64-128
; MMU signal and is therefore transparent to the user. It has
; been proposed that international units replace one of the 4K
; character sets with their particular national character set
; and utilize the CAPS_LOCK key to manually switch sets.
.page
.subttl RELEASE NOTES: BETA-8 04/15/85
; THE FOLLOWING MODIFICATIONS HAVE BEEN MADE TO THE BETA-7 CODE TO CREATE THE
; BETA-8 VERSION RELEASED ON 04/15/85. THE BETA-8 RELEASE IS A PRE-PRODUCTION
; VERSION INTENDED FOR SYSTEM TEST AND EVALUATION AND PRELIMINARY APPLICATION
; SOFTWARE DEVELOPMENT ONLY.
;
; **************************************************************
; * PENDING SYSTEM TEST, THIS SHALL BE THE FINAL BETA RELEASE. *
; * ANY PROBLEMS OR NEEDS *MUST* BE REPORTED TO SYSTEM *
; * ENGINEERING BEFORE 04/19/85 FOR RESOLUTION AND INCLUSION *
; * INTO THE PRODUCTION ROM RELEASE! *
; **************************************************************
;
;
;
;
; The following changes have been made to the MONITOR:
;
; 1/ The Monitor DOS interface now uses the reserved logical
; channel number 0, and no longer transmits a 'close' to the
; disk. Previously it used channel 1 (which was often in use by
; the user) and performed a full 'close' (which caused the disk
; to close ALL open files).
;
; 2/ The Monitor DOS interface no longer allows access to unit
; numbers 3 and 31. They are illegal serial bus devices.
;
; 3/ The Monitor MEMORY DUMP facility correctly displays the full
; CBM ASCII character set. Previously the ASCII was masked to
; 7 bits.
;
; The following changes have been made to the KERNAL:
;
; 1/ The Kernal BOOT routine no longer transmits a 'close' to the
; disk. The disk status will now reflect the last I/O operation
; status similar to a 'load' operation. A reduntant attempt to
; transmit the disk warm start (UI) command was removed.
;
; 2/ The Kernal GO64 routine now insures that the 6510 port /HIRAM
; and /LORAM lines are set HIGH before entering C64 mode.
; Previously entering C64 mode (where /HIRAM and /LORAM select
; RAM and ROM memory configurations) from a C128 graphics mode
; (where /HIRAM and /LORAM select VIC and processor color
; nybble banks) would crash the C64 system because its system
; ROM was not in context and entry was not via hardware reset.
;
;
; The following changes have been made to the EDITOR:
;
; 1/ The IRQ screen handler has been modified to accommodate 2 MHz
; split screen operation. Previously the split screen operation
; in 2 MHz mode caused the IRQ keyscan to be skipped.
;
; 2/ A difference between the C64 and C128 screen editors has been
; noted but will NOT BE CHANGED because the same anomaly occurs
; with the windowing editor on other products. The effect is
; illustrated by the following BASIC operation:
;
; 10 OPEN 1,0 :REM OPEN CHANNEL TO KEYBOARD
; 20 INPUT#1,A$ :REM INPUT A LINE
; 30 PRINT A$ :REM DISPLAY LINE INPUT
;
; The PRINT A$ will overwrite the last character of the string
; entered in response to the 'INPUT'. The C/64 editor does not
; overwrite; in fact there are extra spaces found between the
; input and output strings. Any requests to change this should
; be sent as soon as possible!
;
.page
.subttl RELEASE NOTES: BETA-8 04/15/85
; THE FOLLOWING MODIFICATIONS HAVE BEEN MADE TO THE BETA-8 CODE TO CREATE THE
; BETA-9 VERSION RELEASED ON 04/19/85. THE BETA-8 RELEASE IS A PRE-PRODUCTION
; VERSION INTENDED FOR SYSTEM TEST AND EVALUATION AND PRELIMINARY APPLICATION
; SOFTWARE DEVELOPMENT ONLY.
;
; **************************************************************
; * PENDING SYSTEM TEST, THIS SHALL BE THE FINAL BETA RELEASE. *
; **************************************************************
;
;
; The following changes have been made to the KERNAL:
;
; 1/ The Kernal TAPE handler previously returned the wrong error
; code upon encountering the EOT. This has been fixed to report
; 'file not found'.
;
; The following changes have been made to the EDITOR:
;
; 1/ DOCUMENTATION ONLY: Please note that the Editor does not
; factor in 'VM1' when utilizing 'LDTBL1'. This means that the
; IRQ screen handler WILL move the screen per VM1 but that all
; printing will continue to update the screen at $400. Because
; LDTBL1 is in ROM it cannot be modified as in the C/64. Any
; requests to change this mechanism must be made NOW.
;
; 2/ The Editor now includes the National keyboard lookup tables
; and a National-to-ASCII conversion table. While there is no
; National keyboard driver code in ROM, it is expected that the
; inclusion of these tables will provide sufficient support for
; RAM or Function Cartridge based drivers. AN APPLICATION NOTE
; WILL BE FORTHCOMING TO DETAIL THE IMPLEMENTATION OF A DRIVER.
;
; The following changes reference ALL sections of code:
;
; 1/ The three (3) C/128 ROMs now contain a revision byte and a
; byte reserved for 'rounding' the checksum. The locations are
; given below. Please note that the 'revision' byte described
; here refers to the individual ROM contents, NOT to the
; software (e.g.: the KERNAL software revision byte is $FF80).
;
; LOW (U33): $7FFE - REVISION BYTE
; $7FFF - CHECKSUM ADJUST
;
; MID (U34): $BFFE - REVISION BYTE
; $BFFF - CHECKSUM ADJUST
;
; HIGH (U35): $CFFE - REVISION BYTE
; $CFFF - CHECKSUM ADJUST
;
; The 8-bit checksum is calculated over the ROM's contents by
; adding the sequential bytes for each 16KB ROM, discarding any
; carry between additions. Thus the sum of each ROM should be
; equal to the MSB of its starting address (e.g.: LO=$40, MID=
; $80, HI=$C0). Please note the checksum of the HI (U35) ROM
; does NOT include the CP/M portion (address range $D000-$DFFF)
; as this section of ROM cannot be read by the host processor.
.page
.subttl RELEASE NOTES: 318020-03 05/08/85
; THE FOLLOWING MODIFICATIONS HAVE BEEN MADE TO THE 318020-02 CODE TO CREATE
; THE 318020-03 VERSION RELEASED ON 05/08/85. THIS RELEASE IS MADE TO CREATE
; MASKED ROMS FOR PRODUCTION.
;
;
;
; The following changes have been made to the KERNAL:
;
; 1/ Previously the IOINIT routine improperly initialized PAL and
; 'R8' versions of the 8563 80-column display device. This has
; been corrected. Testing of these modes has been very limited.
;
; 2/ Previously the fast SERIAL routine SPINP forced the 50/60 Hz
; flag on D1CRA low (60Hz). This has been corrected to preserve
; the status of this line.
;
; 3/ A new jump table entry has been created for the fast SERIAL
; routines SPINP and SPOUT at $FF47. Users must enter with the
; carry flag clear to select SPINP and carry flag set for SPOUT
;
; 4/ Previously the SERIAL routine DISK_CLI enabled IRQ's before
; restoring the sprite enable register. This caused the BASIC
; IRQ sprite handler, under stress, to lose sprites. This has
; been corrected. The fix required a change as well to the TAPE
; routine TNIF which shared portions of the DISK_CLI routine.
; The shared code has been eliminated by copying the necessary
; portions to TNIF.
;
; 5/ Previously the Kernal RAM code for JMPFAR called the GETCFG
; ROM code directly. To preserve code modularity, the direct
; address was replaced by the Kernal jump table address.
;
; The following changes have been made to the EDITOR:
;
; 1/ Due to remaining problems with the 8563 block fill function,
; the so-called KLUDGE code has again been added to the CLRLIN
; routine. This patch will clear up the occasional characters
; seen on the 80-column text screen after a SCNCLR, and will be
; valid even after the 8563 bug is fixed. Two (2) absolute RAM
; variables were added to DECLARE without disturbing anything.
;
; 2/ Previously it was not possible to move the VIC 40-column text
; screen and still utilize the screen editor because LDTB1 is
; is ROM based (unlke the C64 which is RAM based). To provide
; this capability a new variable, LDTB1_SA has been created and
; may be used in conjunction with the variable VM1 to move the
; VIC text screen. VM1 should be written instead of VIC reg #24
; (default value $14) and LDTB1_SA loaded with the high byte of
; the new screen location (default value $04). Please note that
; the placement of VIC video matrices is limited by the image
; of the character ROM VIC sees at $1000-$1FFF and the presence
; of ROM beginning at $4000 in the system's memory map. This
; change affected Editor routines SCRSET and MOVLIN which used
; LDTB1 directly, and CINT which now initializes LDTB1_SA.
;
; 3/ There was a problem with windows one (1) character wide in 80
; column mode which affected areas outside the window. It was
; been corrected by testing for this special case in CLRL80.
;
; 4/ The NATIONAL keyboard lookup tables and the National-to-ASCII
; conversion table have been removed. They were found to be
; unnecessary for Foreign-language systems and insufficent for
; other applications. AN APPLICATION NOTE IS FORTHCOMING.
;
; 5/ The handling of 8563s special attributes (ALT, RVS, UNDERLINE
; and FLASH) has been made more consistant throughout. The
; BLANK and CLRLN routines now strip all attributes except ALT.
; (this will affect, for example, INSERT and DELETE). Various
; other routines now preserve the RVS bit (not to be confused
; with reverse-field mode; this hardware bit is unused by the
; system but can be set by the user).
;
; 6/ A single <ESCAPE> no longer cancels all editor modes (e.g.
; quote, insert, underline, flash & reverse). A double <ESCAPE>
; or <ESCAPE>-O is now required.
;

640
KERNAL_C128_03/routines.src

@ -0,0 +1,640 @@
.page
.subttl C/128 KERNAL SUBROUTINES (04/29/85)
;////////////////// J U M P T A B L E R O U T I N E S \\\\\\\\\\\\\\\\\
setnam sta fnlen ;set up a filename
stx fnadr
sty fnadr+1
rts
setlfs sta la ;set up la, fa & sa variables
stx fa
sty sa
rts
setbnk sta ba ;set up ba variable & filename bank
stx fnbank
rts
readss lda fa ;read status byte for latest i/o operation
cmp #2
bne readst ;...branch if serial or cassette
lda rsstat ;read rs232 status
pha
lda #0 ;simulate acia: clear status when read
sta rsstat
pla
rts
readst lda status ;read serial bus or cassette status
udst ora status ;update serial or cassette status byte
sta status
rts
setmsg sta msgflg ;enable/disable kernal messages
rts
settmo sta timout ;??????????? left over from ieee days ??????????????
rts
.page
memtop bcc settop ;/////jump entry to read/set top of user ram
gettop ldx memsiz ;read top of memory (.c=1)
ldy memsiz+1
settop stx memsiz ;set top of memory (.c=0)
sty memsiz+1
rts
membot bcc setbot ;///// jump entry to read/set bottom of user ram
getbot ldx memstr ;read bottom of memory (.c=1)
ldy memstr+1
setbot stx memstr ;set bottom of memory (.c=0)
sty memstr+1
rts
iobase ldx #$00 ;return base address of i/o block in x & y
ldy #$d0
rts
.page
; look up secondary address:
;
; enter with sa sought in y. routine looks for match in tables.
; exits with .c=1 if not found, else .c=0 & .a=la, .x=fa, .y=sa
lkupsa
tya
ldx ldtnd ;get lat, fat, sat table index
1$ dex
bmi lkupng ;...branch if end of table (not found)
cmp sat,x
bne 1$ ;...keep looking
lkupok jsr getlfs ;set up la, fa, sa (** lkupla enters here **)
tax
lda la
ldy sa
clc ;flag 'we found it'
rts
lkupng sec ;flag 'not found'
rts
; look up logical file address:
;
; enter with la sought in a. routine looks for match in tables.
; exits with .c=1 if not found, else .c=0 & .a=la, .x=fa, .y=sa
lkupla
tax
jsr lookup ;search lat table
beq lkupok ;...branch if found
bne lkupng ;else return with .c=1
.page
dma_call
lda config,x ;lookup internal bank
and #$fe ;MUST enable I/O to access DMA controller!
tax
jmp do_dma ;go do it from common area (ram)
fnadry
stx fnadrx ;must save .x
ldx fnbank ; LDA (FNADR),Y from bank FNBANK
lda #fnadr
jsr indfet
ldx fnadrx ;restore .x
rts
salsy
ldx #sal ; STA (SAL),Y from bank BA
.byte $2c
ealsy
ldx #eal ; STA (EAL),Y from bank BA
stx stavec
ldx ba
jmp indsta
eally
lda #eal ; LDA (EAL),Y from bank BA
.byte $2c
sally
lda #sal
ldx ba ; LDA (SAL),Y from bank BA
;fall into 'indfet'
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
indfet
sta fetvec ; LDA (fetvec),Y utility
lda config,x
tax
jmp fetch
indsta
pha ; STA (stavec),Y utility
lda config,x
tax
pla ; (*note* user must setup 'stavec')
jmp stash
indcmp
pha ; CMP (cmpvec),Y utility
lda config,x
tax
pla ; (*note* user must setup 'cmpvec')
jmp cmpare
getcfg
lda config,x ;convert bank (0-15) in .x to mmu configuration in .a
rts
config
.byte %00111111 ;ram0 only
.byte %01111111 ;ram1 only
.byte %10111111 ;ram2 only
.byte %11111111 ;ram3 only
.byte %00010110 ;int rom, ram0, i/o
.byte %01010110 ;int rom, ram1, i/o
.byte %10010110 ;int rom, ram2, i/o
.byte %11010110 ;int rom, ram3, i/o
.byte %00101010 ;ext rom, ram0, i/o
.byte %01101010 ;ext rom, ram1, i/o
.byte %10101010 ;ext rom, ram2, i/o
.byte %11101010 ;ext rom, ram3, i/o
.byte %00000110 ;kernal & int_lo, ram0, i/o
.byte %00001010 ;kernal & ext_lo, ram0, i/o
.byte %00000001 ;kernal & basic, ram0, charrom
.byte %00000000 ;kernal & basic, ram0, i/o
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;///////////////////// K E R N A L R A M C O D E \\\\\\\\\\\\\\\\\\\\\\\
; FETCH ram code ( LDA (fetch_vector),Y from any bank )
;
; enter with 'fetvec' pointing to indirect adr & .y= index
; .x= memory configuration
;
; exits with .a= data byte & status flags valid
; .x altered
dl_beg lda mmucr ;save current memory configuration
stx mmucr ;configure memory this way
tax
lda ($ff),y ;get the byte ($ff here is a dummy address, 'FETVEC')
stx mmucr ;restore previous memory configuration
rts
; STASH ram code ( STA (stash_vector),Y to any bank )
;
; enter with 'stavec' pointing to indirect adr & .y= index
; .a= data byte to store
; .x= memory configuration (writes to rom bleed thru to ram)
;
; exits with .x & status altered
pha
lda mmucr ;save current memory configuration
stx mmucr ;configure memory this way
tax
pla
sta ($ff),y ;put the byte ($ff here is a dummy address, 'STAVEC')
stx mmucr ;restore previous memory configuration
rts
; CMPARE ram code ( CMP (cmpare_vector),Y to any bank )
;
; enter with 'cmpvec' pointing to indirect adr & .y= index
; .a= data byte to compare to memory
; .x= memory configuration
;
; exits with .a= data byte & status flags valid, .x is altered
pha
lda mmucr ;save current memory configuration
stx mmucr ;configure memory this way
tax
pla
cmp ($ff),y ;compare bytes ($ff here is a dummy address, 'CMPVEC')
stx mmucr ;restore previous memory configuration
rts
.page
; LONG CALL utility
;
jsr jmpfar ;execute jmp_long routine as a subroutine
sta a_reg
stx x_reg
sty y_reg
php
pla
sta s_reg
tsx
stx stkptr
lda #sysbnk
sta mmucr
rts
; LONG JUMP utility
;
ldx #0
1$
lda pc_hi,x ;put address & status on stack
pha
inx
cpx #3
bcc 1$
ldx bank
jsr get_cfg ;convert 'bank' to mmu data ??????????? rom routine ??????????
sta mmucr ;set up memory configuration
lda a_reg
ldx x_reg ;set up registers
ldy y_reg
rti ;goto it
dl_end
; DMA REQUEST utility for external ram access
;
; enter with .a= desired internal memory configuration during dma
; .y= dma command
ldx mmucr ;save current configuration
sty dma_cmd ;tell dma controller what to do (arm it)
sta mmucr ;setup (internal) bank for dma controller (trigger it)
stx mmucr ;all done! (like magic, huh?) restore user config & return
rts
dl_dma
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; *** phoenix ***
;
; > call every logged cartridge's cold start routine.
; > check serial disk unit #8 for 'boot' disk.
;
; order: external low/high, internal low/high, boot disk.
;
phoenix
sei
ldx #3
stx curbnk
1$ ldx curbnk
2$ lda pat,x
beq 3$ ;...branch if this slot empty
ldy #0
lda fkaddr,x
sta pc_hi ;cold start address hi
sty pc_lo ;cold start address lo ($00 always)
lda fkbank,x
sta bank ;card slot
jsr jsrfar ;call its cold start routine
3$ dec curbnk
bpl 1$ ;...loop until all function cards called
cli
;
; fall into BOOT and attempt an auto-load/run from disk
;
.page
; *** auto boot disk program ***
;
; 1/ read disk block at track 1 sector 0 into ram at $0b00 ('tbuffr').
; 2/ check for auto-boot signature. RTS if not. the relative format is:
;
; $00 $01 $02 $03 $04 $05 $06 ---------- A ---------- B -----> $FF
; | | | | | | | (optional) | (optional) |
; C B M adrl adrh bank #blk diskname 0 filename 0 6502 code
;
; 3/ IF #blk > 0 THEN block_read sequential sectors into ram at
; given adrl, adrh, bank location.
; 4/ IF filename THEN load filename into ram bank0 (normal load).
; 5/ JSR to user code following filename (system map).
boot
ldx #8 ;default device #
lda #'0' ;default drive #
boot_call ;//////user entry: enter with .x=device, .a=drive (ascii)
sta drive
stx fa
txa ;device #
jsr close_all ;close all current channels to boot device
ldx #0
stx ptr2 ;init filename length to 0
stx sector ;init to sector 0
inx
stx track ;init to track 1
1$ iny ;provide adequate delay for 1541 init to complete
bne 1$
inx
bne 1$
ldx #disk_init-block_data-1
10$ lda block_data,x
sta bad,x ;setup for disk block read: download cmd string
dex
bpl 10$
lda drive
sta bad+6 ;setup drive number
lda #ram0 ;********** open command channel & init drive **********
ldx #romram0
jsr setbnk ;setup bank parameters
lda #1
ldx #<disk_init
ldy #>disk_init
jsr setnam ;set up address & length of command string
lda #0 ;la: use reserved
ldy #15 ;sa: use command channel
ldx fa ;fa: use given device
jsr setlfs
jsr open ;open command channel & send command string: 'I'
bcs 15$ ;...branch if any problem
lda #1 ;********** open data channel to a disk buffer **********
ldx #<disk_bufr
ldy #>disk_bufr
jsr setnam ;set up address & length of command string
lda #13
tay
ldx fa
jsr setlfs ;setup device #, data channel
jsr open ;open data channel & send command string: '#'
bcc 16$ ;...branch if no problems
15$ jmp boot_close ;error exit: close all channels & rts
16$ lda #<tbuffr ;********** read disk track 1 sector 0 into ram **********
ldy #>tbuffr
sta sal ;setup destination address of 1st block read (bank setup earlier)
sty sal+1
jsr block_read ;read track 1 sector 0 into ram at 'tbuffr'
ldx #0
20$ lda tbuffr,x ;see if it is a 'boot' disk: look for 'CBM' key
cmp cbmkey,x
bne 15$ ;...branch & quit if not
inx
cpx #3
bcc 20$
jsr primm
.byte cr,'BOOTING ',0
.page
30$ lda tbuffr,x ;got a boot disk: setup load parameters for remaining boot code
sta sal-3,x
inx
cpx #7
bcc 30$ ;starting at sal we have: adrl, adrh, bank, #blocks to load
40$ lda tbuffr,x ;print optional disk name
beq 45$
jsr bsout
inx
bne 40$
45$ stx ptr1 ;save index into buffer
jsr primm
.byte '...',cr,0
lda sal+2 ;********** load sequential disk blocks into memory **********
sta ba ;destination bank
50$ lda sal+3 ;# of blocks remaining to load
beq 60$ ;...branch if no more
dec sal+3 ;one less disk block
jsr block_next ;increment track & sector and perform block_read
inc sal+1 ;increment address
bne 50$ ;bra
60$ jsr boot_close ;done block loads: close all files
ldx ptr1 ;********** bload given filename from disk **********
.byte $2c ;skip 1st increment
70$ inc ptr2
inx
lda tbuffr,x ;find end of filename to load
bne 70$
inx
stx pc_lo ;*** save *** this is the address to call when done!
ldx ptr1
lda #':' ;install drive #
sta tbuffr,x
dex
lda drive
sta tbuffr,x
stx ptr1
ldx ptr2
beq 99$ ;...branch if null filename: nothing else to load
inx
inx
txa ;pad fnlen to accomodate drive #
ldx ptr1
ldy #>tbuffr
jsr setnam
lda #ram0
tax
jsr setbnk
; lda fa
; tax
; tay ;specify disk default load (load adr comes from disk)
; jsr setlfs
lda #0
jsr load ;bload disk file to ram bank 0 at his address (sa<>0)
99$ lda #>tbuffr
sta pc_hi
lda #romram0
sta bank
jsr jsrfar ;call his routine loaded with 1st block read
clc ;in case he returns, clear error flag
rts
boot_close
php ;save error flag (.c)
pha ;save error code (if any)
jsr clrch ;in case this is an error exit
lda #13
clc
jsr close
ldx #0 ;send 'UI' to clear things up
jsr ckout
bcs 10$ ;...unless channels never established
lda #'U'
jsr bsout
lda #'I'
jsr bsout
10$ jsr clrch
lda #0
sec ;don't xmit close, just update tables
jsr close
pla ;restore error code (if any)
plp ;restore error flag (.c)
rts
.page
block_next
ldx sector ;********** increment track & sector **********
inx
cpx #21 ;1541: tracks 1-17 have 21 sectors (0-20)
bcc 1$
ldx #0 ;start a new track
inc track
1$ stx sector
txa
jsr dec_asc ;convert sector # to decimal ascii
sta bad+0
stx bad+1
lda track
jsr dec_asc ;convert track # likewise
sta bad+3
stx bad+4 ;fall into 'block_read'
block_read
ldx #0 ;********** command disk to read a block **********
jsr ckout
ldx #disk_init-block_data-1
1$ lda bad,x
jsr bsout ;send command string: 'U1:13 0 tt ss' via cmd channel
dex
bpl 1$
jsr clrch
ldx #13
jsr chkin ;********** move block from disk to ram **********
ldy #0
2$ jsr basin ;read bytes via data channel
jsr salsy ; sta (SAL),y to bank BA
iny
bne 2$
jmp clrch
dec_asc
ldx #'0' ;convert hex byte to 2-digit ascii decimal
sec
1$ sbc #10
bcc 2$
inx
bcs 1$
2$ adc #'9'+1
rts
block_data .byte '00 10 0 31:1U' ;block read cmd (reversed!)
disk_init .byte 'I' ;initialize cmd
disk_bufr .byte '#' ;get buffer cmd
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; *** print immediate ***
; a jsr to this routine is followed by an immediate ascii string,
; terminated by a $00. the immediate string must not be longer
; than 255 characters including the terminator.
primm
pha ;save registers
txa
pha
tya
pha
ldy #0
1$ tsx ;increment return address on stack
inc $104,x ;and make imparm = return address
bne 2$
inc $105,x
2$ lda $104,x
sta imparm
lda $105,x
sta imparm+1
lda (imparm),y ;fetch character to print (*** always system bank ***)
beq 3$ ;null= eol
jsr bsout ;print the character
bcc 1$
3$ pla ;restore registers
tay
pla
tax
pla
rts ;return
;.end

190
KERNAL_C128_03/rs232io.src

@ -0,0 +1,190 @@
.page
.subttl rs232 I/O (09/17/84): c/128
; output a file over usr port using rs232
cko232
sta dflto ;set default out
lda m51cdr ;check for 3/x line
lsr a
bcc cko100 ;3 line...no turn around
; turn around logic: check for dsr and rts
lda #$02 ;bit rts is on
bit d2prb
bpl ckdsrx ;no dsr...error
bne cko100 ;rts...outputing or full duplex
; check for active input: rts will be low if currently inputting
1$ lda enabl
and #$02 ;look at ier for t2
bne 1$ ;hang until input done
; wait for cts to be off as spec requires
2$ bit d2prb
bvs 2$
; turn on rts
lda d2prb
ora #$02
sta d2prb
; wait for cts to go on
3$ bit d2prb
bvs cko100 ;done...
bmi 3$ ;we still have dsr
ckdsrx
lda #$40 ;'data set ready' error
sta rsstat ;major error....will require reopen
cko100
clc ;no error
rts
.page
; bso232 - output a char via rs232: data passed in t1 from bsout
;
; hang loop for buffer full
bsobad
jsr bso100 ;keep trying to start system...
; buffer handler
bso232
ldy rodbe
iny
cpy rodbs ;check for buffer full
beq bsobad ;hang if so...trying to restart
sty rodbe ;indicate new start
dey
lda t1 ;get data...
sta (robuf),y ;store data
; set up if necessary to output
bso100
lda enabl ;check for a t1 nmi enable
lsr a ;bit 0
bcs 1$ ;running....so exit
; set up t1 nmi's
lda #$10 ;turn off timer to prevent false start...
sta d2cra
lda baudof ;set up timer1
sta d2t1l
lda baudof+1
sta d2t1h
lda #$81
jsr oenabl
jsr rstbgn ;set up to send (will stop on cts or dsr error)
lda #$11 ;turn on timer
sta d2cra
1$ rts
.page
; input a file over user port via rs232
cki232
sta dfltn ;set default input
lda m51cdr ;check for 3/x line
lsr a
bcc cki100 ;3 line...no handshake
and #$08 ;full/half check (byte shifted above)
beq cki100 ;full...no handshake
; turn around logic: check if dsr and not rts
lda #$02 ;bit rts is on
bit d2prb
bpl ckdsrx ;no dsr...error
beq cki110 ;rts low...in correct mode
; wait for active output to be done
1$ lda enabl
lsr a ;check t1 (bit 0)
bcs 1$
; turn off rts
lda d2prb
and #$ff-02
sta d2prb
; wait for dcd to go high (in spec)
2$ lda d2prb
and #$04
beq 2$
; enable flag for rs232 input
cki080
lda #$90
clc ;no error
jmp oenabl ;flag in enabl
; if not 3 line half then see if we need to turn on flag
cki100
lda enabl ;check for flag or t2 active
and #$12
beq cki080 ;no need to turn on
cki110
clc ;no error
rts
.page
; bsi232 - input a char via rs232
;
; buffer handler
bsi232
lda rsstat ;get status up to change...
ldy ridbs ;get last byte address
cpy ridbe ;see if buffer empty
beq 1$ ;return a null if no char
and #$ff-$08 ;clear buffer empty status
sta rsstat
lda (ribuf),y ;get last char
inc ridbs ;inc to next pos
rts ;receiver always runs
1$ ora #$08 ;set buffer empty status
sta rsstat
lda #0 ;return a null
rts
; protect serial & cassette from rs232 nmi's
rsp232
pha ;save .a
lda enabl ;does rs232 have any enables?
beq 2$ ;no...
1$ lda enabl ;wait until done
and #%00000011 ;with t1 & t2
bne 1$
lda #%00010000 ;disable flag (need to renable in user code)
sta d2icr ;turn of enabl
lda #0
sta enabl ;clear all enabls
2$ pla ;all done
rts
;.end

154
KERNAL_C128_03/rs232nmi.src

@ -0,0 +1,154 @@
.page
.subttl rs-232 nmi handler (02/12/85)
nmi232
tya ;y has icr contents
and enabl ;show only enables
tax ;preserve for later
and #$01 ;t1 nmi check - transmit a bit
beq 3$ ;...branch if not t1 (transmitter)
lda d2pra
and #$ff-$04 ;fix for current i/o
ora nxtbit ;load data and...
sta d2pra ;...send it
lda enabl ;restore nmi's
sta d2icr ;ready for next...
; because of 6526 icr structure...
; handle another nmi as a subroutine
txa ;test for another nmi
and #$12 ;test for t2 or flag
beq 2$
and #$02 ;check for t2
beq 1$ ;must be a flag
jsr t2nmi ;handle a normal bit in...
jmp 2$ ;...then continue output
1$ jsr flnmi ;handle a start bit...
2$ jsr rstrab ;go calc info (code could be in line)
jmp nmirti
3$ txa ;t2 nmi check - recieve a bit
and #$02 ;mask to t2
beq 4$ ;...branch if not t2 (receiver)
jsr t2nmi ;handle interrupt
jmp nmirti
; flag nmi handler - recieve a start bit
4$ txa ;check for edge
and #$10 ;on flag...
beq nmirti ;no...
jsr flnmi ;start bit routine
nmirti lda enabl ;restore nmi's
sta d2icr
rts ;rti via 'prend'
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; baudo - baud rate table for NTSC
;
; calc: 14.31818e6 / 14 / baud_rate / 2
;
baudo .word 10277-cbit ; 50 baud
.word 6818-cbit ; 75 baud
.word 4649-cbit ; 110 baud
.word 3800-cbit ; 134.6 baud
.word 3409-cbit ; 150 baud
.word 1705-cbit ; 300 baud
.word 852-cbit ; 600 baud
.word 426-cbit ; 1200 baud
.word 284-cbit ; 1800 baud
.word 213-cbit ; 2400 baud
; baudop - baud rate table for PAL
;
; calc: .985248e6 / baud_rate / 2
;
baudop .word 9853-cbit ; 50 baud
.word 6568-cbit ; 75 baud
.word 4478-cbit ; 110 baud
.word 3660-cbit ; 134.6 baud
.word 3284-cbit ; 150 baud
.word 1642-cbit ; 300 baud
.word 821-cbit ; 600 baud
.word 411-cbit ; 1200 baud
.word 274-cbit ; 1800 baud
.word 205-cbit ; 2400 baud
; cbit - an adjustment to make next t2 hit near center
; of the next bit. (aprox. the time to service a cb1 nmi)
cbit =100 ;cycles
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; t2nmi - subroutine to handle an rs232 bit input.
t2nmi lda d2prb ;get data in
and #$01 ;mask off...
sta inbit ;...save for later
; update t2 for mid bit check
; (worst case <213 cycles to here: calc 125 cycles+43-66 dead)
lda d2t2l ;calc new time & clr nmi
sbc #22+18
adc baudof
sta d2t2l
lda d2t2h
adc baudof+1
sta d2t2h
lda #$11 ;enable timer
sta d2crb
lda enabl ;restore nmi's early...
sta d2icr
lda #$ff ;enable count from $ffff
sta d2t2l
sta d2t2h
jmp rsrcvr ;go shift in...
; flnmi - subroutine to handle the start bit timing..
flnmi
lda m51ajb ;get half bit rate value
sta d2t2l
lda m51ajb+1
sta d2t2h
lda #$11 ;enable timer
sta d2crb
lda #$12 ;disable flag, enable t2
eor enabl
sta enabl
lda #$ff ;preset for count down
sta d2t2l
sta d2t2h
ldx bitnum ;get #of bits in
stx bitci ;put in rcvrcnt
rts
;.end

145
KERNAL_C128_03/rs232rcvr.src

@ -0,0 +1,145 @@
.page
.subttl rs-232 receiver (09/17/84): c/128
; rsrcvr - nmi routine to collect data into bytes
;
; variables used:
; inbit - input bit value
; bitci - bit count in
; rinone - flag for start bit check <>0 start bit
; ridata - byte input buffer
; riprty - holds byte input parity
; ribuf - indirect pointer to data buffer
; ridbs - input buffer pointer to start
; ridbe - input buffer index to end (if ridbe=ridbs then input buffer empty)
rsrcvr
ldx rinone ;check for start bit
bne rsrtrt ;was start bit
dec bitci ;check where we are in input...
beq rsr030 ;have a full byte
bmi rsr020 ;getting stop bits
; calculate parity
lda inbit ;get data up
eor riprty ;calc new parity
sta riprty
; shift data bit in
lsr inbit ;in bit pos 0
ror ridata ;c into data
; exit
rsrext
rts
.page
; have stop bit, so store in buffer
rsr018
dec bitci ;no parity, dec so check works
rsr020
lda inbit ;get data...
beq rsr060 ;...zero, an error?
lda m51ctr ;check for correct # of stop bits
asl a ;carry tell how may stop bits
lda #1
adc bitci
bne rsrext ;no..exit
; enable to recieve a byte
rsrabl
lda #$90 ;enable flag for next byte
sta d2icr ;toss bad/old nmi
ora enabl ;mark in enable register
sta enabl ; (re-enabled by 'jmp oenabl')
sta rinone ;flag for start bit
lda #$02 ;disable t2
jmp oenabl ;flip-off enabl
; reciever start bit check
rsrtrt
lda inbit ;check if space
bne rsrabl ;bad...try again
sta rinone ;good...disable flag
lda #1 ;set parity to one always
sta riprty
rts ;and exit
; put data in buffer (at parity time)
rsr030
ldy ridbe ;get end
iny
cpy ridbs ;have we passed start?
beq recerr ;yes...error
sty ridbe ;move ridbe foward
dey
lda ridata ;get byte buffer up
ldx bitnum ;shift untill full byte
1$
cpx #9 ;always 8 bits
beq 2$
lsr a ;fill with zeros
inx
bne 1$
2$ sta (ribuf),y ;data to page buffer
; parity checking
lda #$20 ;check 6551 command register
bit m51cdr
beq rsr018 ;no parity bit so stop bit
bmi rsrext ;no parity check
; check calc parity
lda inbit
eor riprty ;put in with parity
beq 3$ ;even parity
bvs rsrext ;odd...okay so exit
.byte $2c ;skip two
3$ bvc rsrext ;even...okay so exit
; errors reported
lda #1 ;parity error
.byte $2c
recerr
lda #$4 ;reciever overrun
.byte $2c
breake
lda #$80 ;break detected
.byte $2c
framee
lda #$02 ;frame error
ora rsstat
sta rsstat
jmp rsrabl ;bad exit so hang (!?)
; check for errors
rsr060
lda ridata ;expecting stop...
bne framee ;frame error
beq breake ;could be a break
;.end

164
KERNAL_C128_03/rs232xmit.src

@ -0,0 +1,164 @@
.page
.subttl rs-232 transmit (09/17/84): c/128
; rstrab - entry for nmi continue routine
; rstbgn - entry for start transmitter
;
; variables used:
; bitts - # of bits to be sent (<>0 not done)
; nxtbit - byte contains next bit to be sent
; roprty - byte contains parity bit calculated
; rodata - stores data byte currently being transmitted
; rodbs - output buffer index start
; rodbe - output buffer index end (if rodbs=rodbe then buffer empty)
; robuf - indirect pointer to data buffer
; rsstat - rs-232 status byte
;
; xxx us - normal bit path
; xxx us - worst case parity bit path
; xxx us - stop bit path
; xxx us - start bit path
rstrab
lda bitts ;check for place in byte...
beq rstbgn ;...done, =0 start next
bmi rst050 ;...doing stop bits
lsr rodata ;shift data into carry
ldx #0 ;prepare for a zero
bcc 1$ ;yes...a zero
dex ;no...make an $ff
1$
txa ;ready to send
eor roprty ;calc into parity
sta roprty
dec bitts ;bit count down
beq rst010 ;want a parity instead
rstext
txa ;calc bit whole to send
and #$04 ;goes out d2pa2
sta nxtbit
rts
.page
; calculate parity
; nxtbit =0 upon entry
rst010
lda #$20 ;check 6551 reg bits
bit m51cdr
beq rspno ;...no parity, send a stop
bmi rst040 ;...not real parity
bvs rst030 ;...even parity
lda roprty ;calc odd parity
bne rspext ;correct guess
rswext
dex ;wrong guess...its a one
rspext
dec bitts ;one stop bit always
lda m51ctr ;check # of stop bits
bpl rstext ;...one
dec bitts ;...two
bne rstext ;jump
rspno ;line to send cannot be pb0
inc bitts ;counts as one stop bit
bne rswext ;jump to flip to one
rst030
lda roprty ;even parity
beq rspext ;correct guess...exit
bne rswext ;wrong...flip and exit
rst040
bvs rspext ;wanted space
bvc rswext ;wanted mark
; stop bits
rst050
inc bitts ;stop bit count towards zero
ldx #$ff ;send stop bit
bne rstext ;jump to exit
.page
; rstbgn - entry to start byte trans
rstbgn
lda m51cdr ;check for 3/x line
lsr a
bcc 1$ ;3 line...no check
bit d2prb ;check for...
bpl dsrerr ;...dsr error
bvc ctserr ;...cts error
; set up to send next byte
1$ lda #0
sta roprty ;zero parity
sta nxtbit ;send start bit
ldx bitnum ;get # of bits
stx bitts ;bitts= # of bitts+1
ldy rodbs ;check buffer pointers
cpy rodbe
beq rsodne ;all done...
lda (robuf),y ;get data...
sta rodata ;...into byte buffer
inc rodbs ;move pointer to next
rts
; set errors
dsrerr
lda #$40 ;dsr gone error
.byte $2c
ctserr
lda #$10 ;cts gone error
ora rsstat
sta rsstat
; errors turn off t1
rsodne
lda #$01 ;kill t1 nmi
oenabl ;////// entry to turn off an enabled nmi...
sta d2icr ;toss bad/old nmi
eor enabl ;flip enable
ora #$80 ;enable good nmi's
sta enabl
sta d2icr
rts
; bitcnt - cal # of bits to be sent
; returns #of bits+1
bitcnt
ldx #9 ;calc word length
lda #$20
bit m51ctr
beq 1$
dex ;bit 5 high is a 7 or 5
1$ bvc 2$
dex ;bit 6 high is a 6 or 5
dex
2$ rts
;.end

154
KERNAL_C128_03/save.src

@ -0,0 +1,154 @@
.page
.subttl save (10/17/84): c/128
; **********************************************
; * save memory to mass storage *
; * *
; * fa: 0= keyboard <invalid> *
; * 1= cassette *
; * 2= rs-232 <invalid> *
; * 3= screen <invalid> *
; * 4-31= serial device *
; * *
; * sa: (cassette save only) *
; * bit0- 0= basic (blf) *
; * 1= absolute (plf) *
; * bit1- 0= nop *
; * 1= write eot *
; * *
; * ba: bank source *
; * *
; * > .a points to start address *
; * > x & y point to end address *
; **********************************************
savesp ;////// jump table entry
stx eal
sty eah ;setup ending address (in x & y)
tax
lda $00,x ;setup starting address (.a points to indirect)
sta stal
lda $01,x
sta stah
save ;////// old monitor entry (not c/128 monitor)
jmp (isave)
nsave
lda fa ;dispatch per device number
cmp #1
beq svtape ;load from cassette tape
cmp #4
bcs svdisk ;load from serial device
err9s jmp error9 ;illegal device
err8s jmp error8 ;missing filename
err4s jmp error4 ;file not found
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; save memory to serial device
svdisk
ldy fnlen ;must have filename
beq err8s ;...branch if missing filename
lda #$61 ;pass 'save' command to disk in sa
sta sa
jsr openi ;open the file
jsr saving ;'saving...'
lda fa
jsr listn ;establish the channel
lda sa
jsr secnd ;send 'save' command
ldy #0
jsr rd300 ; (copy 'stal,h' to 'sal,h')
jsr ciout ;send starting address lo
lda sah
jsr ciout ;send starting address hi
1$ jsr cmpste ;compare start to end
bcs 3$ ;...branch if at end
jsr sally ;lda (sal),y
jsr ciout ;send a byte
jsr stop
beq break ;...branch if aborted by <stop> key
2$ jsr incsal ;increment address for next byte
bne 1$ ;always
3$ jsr unlsn ;close channel, fall into file close routine: save done
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
clsei ;////// entry from other kernal routines
bit sa
bmi clsrts ;...branch if file not properly opened
lda fa
jsr listn ;get the channel
lda sa
and #$ef ;make sa a 'close' command
ora #$e0
jsr secnd ;send 'close' command
cunlsn ;////// entry from 'openi'
jsr unlsn ;close channel
clsrts clc ;signal good return
rts
break
jsr clsei ;close the file
lda #0 ;return =
sec ;signal error return
rts
; subroutine to output 'saving [<filename>]'
saving
lda msgflg
bpl svrts ;...branch if display disabled
ldy #ms11-ms1
jsr msg ;print 'saving '
jmp outfn ;print filename & rts
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; save memory to cassette tape
svtape
jsr tapadr ;setup pointers to cassette buffer
bcc err9s ;...branch if deallocated (error)
jsr cste2 ;prompt user 'press play & record...'
bcs svrts ;...branch if aborted by <stop> key
jsr saving ;'saving...'
ldx #plf
lda sa ;sa has type of tape file: 1=plf 0=blf
and #$01
bne 1$ ;...branch if 'plf' type
ldx #blf
1$ txa
jsr tapeh ;write tape header
bcs svrts ;...branch if aborted by <stop> key
jsr twrt ;write file to tape
bcs svrts ;...branch if aborted by <stop> key
lda sa
and #$02 ;sa has (optional) end_of_tape flag
beq 2$ ;...branch if not eot
lda #eot
jsr tapeh ;write eot mark to tape
.byte $24 ;preserve status in .c from tape handler
2$ clc ;signal good save
svrts rts ;done save
;.end

503
KERNAL_C128_03/serial.src

@ -0,0 +1,503 @@
.page
.subttl serial routines (04/29/85)
; command serial bus device to talk
talk ora #$40 ;make a talk address
.byte $2c ;skip two bytes
; command serial bus device to listen
listn ora #$20 ;make a listen address
jsr rsp232 ;protect from rs232 nmi's
list1 pha
bit c3p0 ;character left in buffer?
bpl 10$ ;no...
; send buffered character
sec ;init eoi flag
ror r2d2
jsr isour ;send last character
lsr c3p0 ;buffer clear flag
lsr r2d2 ;clear eoi flag
10$ pla ;talk/listen address
sta bsour
jsr disk_sei
jsr datahi
; jsr clklo ;PLUS-4 DMA kludge
lda d2pra (*fs*)
and #$08 (*fs*)
bne 30$ ;...branch if already under atn (*fs*)
jsr spout ;serial port output (*fs*)
lda #$ff (*fs*)
sta d1sdr ;send $ff (*fs*)
jsr slowb ;wait transmission time & go input (*fs*)
txa (*fs*)
ldx #20 ;delay for 1571 (*fs*)
20$ dex (*fs*)
bne 20$ (*fs*)
tax (*fs*)
30$ lda d2pra ;assert attention
ora #$08
sta d2pra
.page
isoura
jsr disk_sei
jsr clklo ;set clock line low
jsr datahi
txa ;save .x
ldx #200-16
10$ dex ;...wait for 1ms (approx- allow for VIC DMA's)
bne 10$
tax ;restore .x
isour jsr disk_sei ;no irq's allowed
jsr datahi ;make sure data is released
jsr debpia ;data should be low
bcc 1$
jmp nodev
1$ bit d1icr ;clear pending (*fs*)
jsr clkhi ;clock line high
bit r2d2 ;eoi flag test
bpl 10$ ;...branch if no eoi
; do the eoi
2$ jsr debpia ;wait for data to go high
bcc 2$
3$ jsr debpia ;wait for data to go low
bcs 3$
10$ lda d2pra ;wait for data to go high (*fs*)
cmp d2pra ;debounce (*fs*)
bne 10$ (*fs*)
pha (*fs*)
lda d1icr ;byte ready? (*fs*)
and #$08 (*fs*)
beq 20$ ;...no (*fs*)
lda #$c0 ;set fast serial flag (int & ext) (*fs*)
sta serial (*fs*)
20$ pla (*fs*)
bpl 10$ ;wait for data high (*fs*)
ora #$10 ;set clock low (*fs*)
sta d2pra (*fs*)
and #$08 ;under atn? (*fs*)
bne 30$ (*fs*)
bit serial ;fast? (*fs*)
bpl 30$ (*fs*)
jsr spout ;go output (*fs*)
lda bsour ;get data (*fs*)
sta d1sdr ;send it (*fs*)
jsr slowb ;wait for transmission & go input (*fs*)
jmp 70$ (*fs*)
; set to send data
30$ lda #$08 ;count 8 bits
sta count
; jsr clklo ;TED DMA kludge
40$ lda d2pra ;debounce the bus
cmp d2pra
bne 40$
asl a ;set the flags
bcc frmerr ;...frame error: data must be hi
ror bsour ;next bit into carry
bcs 50$ ;...branch isrhi
jsr datalo
bne 60$ ;...branch isrclk
50$ jsr datahi
60$ jsr clkhi ;clock hi
nop
nop
nop
nop
lda d2pra
and #%11011111 ;data high
ora #%00010000 ;clock low
sta d2pra
dec count
bne 40$ ;...loop until 8 bits sent
70$ txa ;save .x (*fs*)
pha (*fs*)
ldx #34 ;wait 1 ms (*fs*)
80$ jsr debpia ;debounce (*fs*)
bcs 90$ (*fs*)
pla (*fs*)
tax (*fs*)
jmp disk_cli ;leave with .c=0 (*fs*)
90$ dex (*fs*)
bne 80$ (*fs*)
pla (*fs*)
tax ;restore .x & fall into 'frmerr' (*fs*)
.page
; serial bus error handler: update I/O status byte
;
frmerr lda #$03 ;framing error
.byte $2c
nodev lda #$80 ;device not present error
csberr pha (*fs*)
lda serial ;reset fast serial flag (*fs*)
and #$7f (*fs*)
sta serial (*fs*)
pla (*fs*)
jsr udst ;commodore serial bus error entry
jsr disk_cli ;irq's were off...turn on
clc ;make sure no kernal error returned
jmp dlabye ;turn atn off & release all lines
.page
; input a byte from serial bus
acptr
jsr disk_sei ;disable irq's, sprites, & select 1MHz mode
lda #0
sta count ;clear eoi error flag
bit d1icr ;clear pending (*fs*)
txa (*fs*)
pha ;save .x (*fs*)
jsr clkhi ;release clock line
10$ jsr debpia ;wait for clock high
bpl 10$
20$ ldx #13 ;delay for 256 us (*fs*)
lda d2pra ;'datahi' in line
and #%11011111
sta d2pra ;makes timing more like vic-20 (*fs*)
30$ lda d2pra ;wait for clock low or timeout (*fs*)
cmp d2pra (*fs*)
bne 30$ ;debounce (*fs*)
asl a (*fs*)
bpl 50$ ;...exit timeout loop when clock low (*fs*)
dex (*fs*)
bne 30$ ;...loop until timeout (*fs*)
lda count
bne 40$ ;...branch if error (twice thru timeouts)
; timer ran out- do an eoi thing.
jsr datalo ;data line low
jsr clkhi ;delay and then set datahi (fix for 40us c64)
lda #$40
jsr udst ;or an eoi bit into status byte
inc count ;go around again for error check on eoi
bne 20$ ;always- go around again for eoi error check
40$ pla ;restore .x (*fs*)
tax (*fs*)
lda #2 ;error status = 2 for read timeout
jmp csberr
; do the byte transfer.
50$ ldx #8 ;set up bit counter
60$ lda d1icr ;was there fast byte to read? (*fs*)
and #$08 (*fs*)
bne 75$ ;...branch if fast byte to read (*fs*)
65$ lda d2pra ;wait for clock high then get bit
cmp d2pra
bne 65$ ;debounce
asl a ;shove bit into carry
bpl 60$ ;...branch until clock high & data valid
69$ ror bsour1 ;rotate bit in from carry
70$ lda d2pra ;got bit, now wait for clock low
cmp d2pra
bne 70$ ;debounce
asl a
bmi 70$ ;...branch until clock low
dex
beq 80$ ;...exit loop if all bits in
71$ lda d2pra ;got a bit, so we can exclude test for fast byte
cmp d2pra
bne 71$ ;debounce
asl a ;shove bit into carry
bpl 71$ ;...branch until clock high & data valid
bmi 69$ ;always
75$ lda d1sdr ;get a byte (*fs*)
sta bsour1 ;got a byte (*fs*)
lda #$c0 (*fs*)
sta serial ;flag fast device & exit (*fs*)
; ...exit...
80$ pla ;restore .x (*fs*)
tax (*fs*)
jsr datalo ;data low
bit status ;check for eoi
bvc 90$ ;...branch if none
jsr dladlh ;delay then set data high
90$ jsr disk_cli ;unleash irq's, sprites, 2MHz mode
lda bsour1 ;don't forget what we came for!
clc ;good exit
rts
.page
; send secondary address after listen
secnd sta bsour ;buffer character
jsr isoura ;send it
; release attention after listen
scatn lda d2pra
and #%11110111
sta d2pra ;release attention
rts
; talk second address
tksa sta bsour ;buffer character
jsr isoura ;send second addr
bit status
bmi dlabye ;...branch if error sending sa
tkatn ;shift over to listener
jsr disk_sei ;no irq's here
jsr datalo ;data line low
jsr scatn
jsr clkhi ;clock line high jsr/rts
10$ lda d2pra ;'debpia' in-line for faster turn-around
cmp d2pra
bne 10$ ;debounce
asl a ;data bit in .c (unused)
bmi 10$ ;...until clock low
jmp disk_cli ;enable irq's & rts
; buffered output to serial bus
ciout bit c3p0 ;buffered character?
bmi 10$ ;yes...send last
sec ;no...
ror c3p0 ;set buffered char flag
bne 20$ ;...branch always
10$ pha ;save current char
jsr isour ;send last char
pla ;restore current char
20$ sta bsour ;buffer current char
clc ;carry-good exit
rts
.page
; send untalk command on serial bus
untlk jsr disk_sei
jsr clklo
lda d2pra ;pull atn
ora #$08
sta d2pra
lda #$5f ;untalk command
.byte $2c ;skip two bytes
; send unlisten command on serial bus
unlsn lda #$3f ;unlisten command
pha
lda serial (*fs*)
and #$7f (*fs*)
sta serial ;reset fast serial flag (*fs*)
pla
jsr list1 ;send it & then release all lines
; release all lines
dlabye jsr scatn ;always release atn
dladlh txa ;delay and then release clock & data
ldx #10 ;delay approx 60 us
10$ dex
bne 10$
tax
jsr clkhi
jmp datahi
.page
clkhi ;set clock line high (inverted)
lda d2pra
and #%11101111
sta d2pra
rts
clklo ;set clock line low (inverted)
lda d2pra
ora #%00010000
sta d2pra
rts
datahi ;set data line high (inverted)
lda d2pra
and #%11011111
sta d2pra
rts
datalo ;set data line low (inverted)
lda d2pra
ora #%00100000
sta d2pra
rts
debpia
lda d2pra ;debounce the pia
cmp d2pra
bne debpia
asl a ;shift the data bit into the carry...
rts ;...and the clock into neg flag
.page
disk_sei
sei ;disable irq's, turn sprites off, insure 1MHz mode
get_sp ;///// entry from TAPECTLR
bit hold_off
bmi 10$ ;...branch if user wants full control of vic
bit speed
bmi 10$ ;...branch if already done!
lda vicreg+48
sta speed ;save current speed
lda vicreg+21
sta sprites ;save current sprite enables
lda #0
sta vicreg+21 ;disable all sprites
sta vicreg+48 ;insure 1MHz mode for time-sensitive operations
lda sprites
beq 10$ ;...avoid delay if sprites were off
txa
ldx #0
1$ dex ;allow vic sprite dma's to cease before time-sensitive stuff begins
bne 1$
tax
10$ rts
disk_cli ;restore irq's, sprites, & system speed
bit hold_off
bmi 10$ ;...branch if user wants full control of vic
bit speed
bpl 10$ ;...branch if nothing to restore
lda sprites
sta vicreg+21
lda speed
sta vicreg+48
lda #0
sta speed ;flag restoration
10$ cli
rts
.page
;(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)(*fs*)
slowb
lda d1icr ;wait sdr flag
and #$08
beq slowb
spinp
lda d1cra
and #$80 ;keep 50/60Hz tod flag
ora #$08 ;kill output on 6526
sta d1cra
lda mmumcr
and #%11110111 ;fast serial in
sta mmumcr
rts
spout
lda mmumcr
ora #%00001000 ;fast serial out
sta mmumcr
lda #$7f
sta d1icr ;no irq's
lda #$00
sta d1t1h ;output rate 4us*2 per bit
lda #$04
sta d1t1l
lda d1cra
and #$80 ;keep 50/60hz tod
ora #$55 ;set tod,spout,phi,frc,cont,tgl,pb6=off,start
sta d1cra
bit d1icr ;clear pending
rts
spin_spout
bcc spinp ;user wants spinp...
bcs spout ;user wants spout...
;.end

537
KERNAL_C128_03/sysdoc.src

@ -0,0 +1,537 @@
.subttl C/128 SYSTEM MEMORY MAPS (05/15/85)
.page
; COMPOSITE SYSTEM MEMORY MAP
;
; C64 Cartridges C64 C128 ROMs RAM Banks (0-3)
; $FFFF> _______________ _______________ _______________ _______________
; | | | | | | | |
; | Game | | KERNAL | | | | |
; | | | & | | KERNAL | | |
; | Card | | EDITOR | | | | |
; | | | | | | | |
; $E000>|_______________|-------|_______________|-------|_______________| | |
; | | | I/O | | |
; | I/O and CHARs | | CHARs & CP/M | | |
; $D000>------------------------|_______________|-------|_______________| | |
; | | | |
; _______________ _______________ | EDITOR | | |
; $C000>| |-------| |-------|_______________|-------| |
; | | | | | | | |
; | Application | | | | MONITOR | | |
; $B000>| |-------| BASIC |-------|_______________| | |
; | Card - HI | | | | | | |
; | | | | | | | _ |
; $A000>|_______________|-------|_______________| | | | | SYSTEM |
; | | | BASIC | | RAM0-| & BASIC|
; | Application | | | | |_ TEXT |
; | | | HI | | _ |
; | Card - LO | | | | | BASIC |
; | | | | | RAM1-| VARs |
; $8000>|_______________|-------------------------------|_______________|-------| |_ |
; | | | |
; | | | _ |
; | | | RAM2-| FUTURE |
; | BASIC | | RAM3-|_EXPAND |
; | | | |
; | LO | | |
; | | | |
; | | | |
; | | | |
; | | | |
; | | | |
; $4000>------------------------------------------------|_______________|-------| |
; | |
; | |
; | |
; | |
; | |
; | |
; | |
; | |
; | |
; $0400>------------------------------------------------------------------------|_______________|
; | COMMON |
; $0000>------------------------------------------------------------------------|_______________|
.page
; $0A00>|---------------| $1300>|---------------| $1C00>|---------------| $FFFF>|---------------|
; | | | | | | $FFFA>| NMI RST IRQ |
; | | | Basic | | | $FFD0>| CP/M RAM Code |
; | | | Absolute | | | | Krnl RAM Code |
; | Basic | | Variables | | | $FF05>|---------------|
; | | | | | | |MMU Config Regs|
; $0900>| Run-Time | $1200>|---------------| $1B00>| | $FF00>|---------------|
; | | | Basic | | | | |
; | Stack | | DOS / VSP | | Reserved | | |
; | | | Variables | | | | |
; | | $1108>|---------------| | For | | |
; | | |CP/M Reset Code| | | | |
; $0800>|---------------| $1100>|---------------| $1A00>| Function | | |
; | | | | | | | |
; | | | Function | | Key | | |
; | | | Key | | | | |
; | | | Buffer | | Software | | |
; | VIC | | | | | | |
; | | $1000>|---------------| $1900>| | | |
; | Text | | | | | | |
; ~ ~ | | | | | Basic |
; | Screen | | | | | | |
; | | | Sprite | | | | |
; | (VM#1) | | | | | | |
; | | $0F00>| Definition | $1800>|---------------| ~ Text ~
; | | | | | | | |
; | | | Area | | | | |
; | | | | | | | |
; | | | | | | | Area |
; | | | | | | | |
; $0400>|---------------| $0E00>|---------------| | | | |
; | Basic RAM Code| | | | | | (Basic Text |
; $0380>| - - - - - - - | | RS-232 | | Reserved | | begins at |
; | Kernal Tables | | Output | | | | $1C00 |
; $033C>| - - - - - - - | | Buffer | | for | | if Bit-Map |
; | Indirects | | | | | | unallocated) |
; $02FC>|---------------| $0D00>|---------------| | Foreign | $4000>|---------------|
; |Kernal RAM Code| | | | | | |
; $02A2>| - - - - - - - | | RS-232 | | Language | | |
; |Basic & Monitor| | Input | | | | |
; | Input | | Buffer | | Systems | | VIC |
; | Buffer | | | | | | |
; $0200>|---------------| $0C00>|---------------| | | ~ Bit-Map ~
; | System Stack | | (Disk Boot | | | | |
; $0149>| - - - - - - - | | Page) | | | | Screen |
; |Basic DOS,USING| $0BC0>| - - - - - - - | | | | |
; $0110>| - - - - - - - | | Cassette | | | | |
; | FBUFFER | | Buffer | | | | |
; $0100>|---------------| $0B00>|---------------| $1400>|---------------| $2000>| - - - - - - - |
; | | | Monitor & | | | | |
; | Kernal Z.P. | | Kernal | | | | VIC |
; $0090>| - - - - - - - | | Absolute | | ????????? | ~ Bit-Map ~
; | Basic Z.P. | | Variables | | | | Color |
; $0002>| _ _ _ _ _ _ _ | | | | | | (VM#2) |
; $0000>|_______________| $0A00>|---------------| $1300>|---------------| $1C00>|---------------|
; C/128 SYSTEM ROM LAYOUT
;
; $FFFF _ _______________
; $FF4D _ |_______________|__________ Kernal Jump Table & Hardware Vectors --------
; | | |
; $FF05 _ |_______________|__________ Kernal Interrupt Dispatch Code |
; $FF00 _ |///////////////|__________ MMU Configuration Registers |
; | | |
; | | |
; $FC80 _ |_______________|__________ ROM Reserved for Foreign Language Versions |
; | | |
; | | |
; $FA80 _ |_______________|__________ Editor Tables |
; | | |
; | | |
; / / -\ HIGH
; | | -/ ROM
; $E000 _ |_______________|__________ Kernal ROM Code |
; |///////////////| |
; |///////////////| |
; ///////////////// |
; |///////////////| |
; $D000 _ |///////////////|__________ I/O Space |
; | | |
; | | |
; / / |
; | | |
; $C000 _ |_______________|__________ Editor ROM Code -----------------------------
; | | |
; | | |
; / / |
; | | |
; $B000 _ |_______________|__________ Monitor ROM Code -\ MID
; | | -/ ROM
; | | |
; | | |
; | | |
; | | |
; $8000 - / / ------------------------------------------------------|
; | | |
; | | -\ LOW
; | | -/ ROM
; | | |
; $4000 _ |_______________|---------- BASIC ROM Code -----------------------------|
.page
; I/O BLOCK MAP 6526 CIA REGISTER MAP (typical)
;
; $DFFF _ _______________ REG# FUNCTION
; | | ________
; | I/O - 2 | / F .... CRB (control register B)
; $DF00 _ |_______________| / E .... CRA (control register A)
; | | / D .... ICR (interrupt control register)
; | I/O - 1 | / C .... SDR (serial data register)
; $DE00 _ |_______________|_/ B .... TOD (hours)
; | | A .... TOD (minutes)
; | CIA - 2 | 9 .... TOD (seconds)
; $DD00 _ |_______________| 8 .... TOD (tenths)
; | | 7 .... TB-HI (timer B)
; | CIA - 1 | 6 .... TB-LO
; $DC00 _ |_______________|_ 5 .... TA-HI (timer A)
; | | \ 4 .... TA-LO
; | VIC | \ 3 .... DDRB (data direction port B)
; / COLOR / \ 2 .... DDRA (data direction port A)
; | RAM | \ 1 .... PRB (port B)
; $D800 _ |_______________| \________ 0 .... PRA (port A)
; | |
; | (RESERVED) |
; $D700 _ |_______________|
; | |
; | 8563 VDC | ..... (register map on following pages)
; $D600 _ |_______________|
; | |
; | MMU | ..... (register map on following pages)
; $D500 _ |_______________|
; | |
; | SID | ..... (register map on following pages)
; $D400 _ |_______________|
; | |
; | |
; / VIC / ..... (register map on following pages)
; | |
; $D000 _ |_______________|
.page
;/////////////// T H E C / 1 2 8 K E Y B O A R D \\\\\\\\\\\\\\\
; ------------------------------------------------------------------- -------
; | C0 | C1 | C2 | C3 | C4 | C5 | C6 | C7 | K0 | K1 | K2 | | GND |
; |PIN13|PIN19|PIN18|PIN17|PIN16|PIN15|PIN14|PIN20|PIN21|PIN22|PIN23| |PIN-1|
; ---|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|--- ---|---
; \|/ \|/ \|/ \|/ \|/ \|/ \|/ \|/ \|/ \|/ \|/ |
; ------- ------------------------------------------------------------------- |
; | R0 |/__| INS | # | % | ' | ) | + | lb | ! | HELP| ESC | ALT | |
; |PIN12|\ | DEL | 3 | 5 | 7 | 9 | | | 1 | | | | |
; ------- ------------------------------------------------------------------- |
; | R1 |/__| RET | W | R | Y | I | P | * | <-- | 8 | + | 0 | |
; |PIN11|\ | | | | | | | | | | | | |
; ------- ------------------------------------------------------------------- |
; | R2 |/__| /_\ | A | D | G | J | L | ] | CTRL| 5 | - | . | |
; |PIN10|\ | \ / | | | | | | ; | | | | | |
; ------- ------------------------------------------------------------------- |
; | R3 |/__| F8 | $ | & | ( | 0 | - | CLR | " | TAB | LINE| /|\ | |
; |PIN-5|\ | F7 | 4 | 6 | 8 | | | HOM | 2 | | FEED| | | |
; ------- ------------------------------------------------------------------- |
; | R4 |/__| F2 | Z | C | B | M | > |RIGHT|SPACE| 2 |ENTER| | | |
; |PIN-8|\ | F1 | | | | | . |SHIFT| BAR | | | \|/ | |
; ------- ------------------------------------------------------------------- |
; | R5 |/__| F4 | S | F | H | K | [ | = | C= | 4 | 6 | /__ | |
; |PIN-7|\ | F3 | | | | | : | | | | | \ | |
; ------- ------------------------------------------------------------------- |
; | R6 |/__| F6 | E | T | U | O | @ | pi | Q | 7 | 9 | __\ | |
; |PIN-6|\ | F5 | | | | | | ^ | | | | / | |
; ------- ------------------------------------------------------------------- |
; | R7 |/__| /|\ |LEFT | X | V | N | < | ? | RUN | 1 | 3 | NO |_____ |
; |PIN-9|\ | \|/ |SHIFT| | | | , | / | STOP| | | SCRL| | |
; ------- ------------------------------------------------------------------- | |
; | | |
; ------- / (LOCKING) | |
; |SHIFT|__o o____________________________________________________| |
; | LOCK| |
; ------- |
; ------- ------- / |
; | NMI |/________|RESTR|__o o________________________________________________________o
; |PIN-3|\ | | |
; ------- ------- |
; ------- ------- / (LOCKING) |
; |40/80|/________|40/80|__o o________________________________________________________o
; |PIN24|\ |DSPLY| |
; ------- ------- |
; ------- ------- / (LOCKING) |
; |P6510|/________|CAPS |__o o________________________________________________________o
; |PIN25|\ |LOCK |
; ------- -------
;NOTES: 1/ THE 64 KEYS UNDER C0 THRU C7 ABOVE OCCUPY THE SAME MATRIX POSITION AS IN THE C/64,
; AS DOES THE 'RESTORE' KEY. INCLUDING THE 'SHIFT LOCK' KEY, THERE ARE 66 SUCH KEYS.
; 2/ THE 24 KEYS UNDER THE K0, K1 AND K2 OUTPUTS ARE PART OF THE EXTENDED KEYBOARD,
; AS ARE THE '40/80 DSPLY' AND 'CAPS LOCK' KEYS. THERE ARE 26 NEW KEYS. THEY WILL
; NOT BE SCANNED IN C/64 MODE, ALTHO THE USER MAY WRITE CODE TO SCAN THEM HIMSELF.
.page
; 8722 MMU REGISTER MAP
;
; REGISTER DESCRIPTION
; _______
; 11 (VR) ............. | 7 - 4 | ..... BANK Version
; Version Register | 3 - 0 | ..... MMU Version
; |-------|
; _______ __
; 10 (PAGE-1 HI) ...... | 7 - 4 | ..... ??? |
; 8 (PAGE-0 HI) | 3 | ......... A19 Swaps PAGE 0 and/or PAGE 1
; | 2 | ......... A18 with any other page in the
; | 1 | ......... A17 256K address space.
; | 0 | ......... A16 |
; |---| |
; ___ |
; 9 (PAGE-1 LO) ...... | 7 | ......... A15 |
; 7 (PAGE-0 LO) | 6 | ......... A14 |
; | 5 | ......... A13 |
; | 4 | ......... A12 |
; | 3 | ......... A11 |
; | 2 | ......... A10 |
; | 1 | ......... A9 |
; | 0 | ......... A8 __|
; |---|
; ___
; 6 (RCR) | 7 | ......... VA17 \ VIC RAM Bank
; | 6 | ......... VA16 /
; RAM Configuration | 5 | ......... \ RAM Block (for future expansion)
; Register | 4 | ......... /
; | 3 | ......... \ SHARE Status (none,bot,top,both)
; | 2 | ......... /
; | 1 | ......... \ SHARE Amount (1k,4k,8k,16k)
; | 0 | ......... /
; |---|
; ___
; 5 (MCR) | 7 | ......... 40/80 Key Sense
; | 6 | ......... OS Mode 0 = 128, 1 = 64
; Mode Configuration | 5 | ......... /EXROM line sense
; Register | 4 | ......... /GAME line sense
; | 3 | ......... FSDIR 0 = IN, 1 = OUT
; | 2 | ......... ???
; | 1 | ......... ???
; | 0 | ......... Processor: 0 = Z80, 1 = 85xx
; |---|
; ___
; 4 (PCR-D) | 7 | ......... A17 \ RAM BANK (0-3)
; 3 (PCR-C) | 6 | ......... A16 /
; 2 (PCR-B) | 5 | ......... \ ROM-HI (system,int,ext,RAM)
; 1 (PCR-A) | 4 | ......... /
; 0 (CR) | 3 | ......... \ ROM-MID (system,int,ext,RAM)
; | 2 | ......... /
; Pre-configuration | 1 | ................. ROM-LO (system,RAM)
; & Configuration | 0 | ................. I/O (I/O, else see ROM-HI)
; Registers |---|
.page
; (preliminary) DMA CONTROLLER REGISTER MAP
;
;
; REG # _______________________________________________________
; 0_ | BUSY | FAULT| -- | -- | -- | -- | -- | -- |______ Status Register
; 1_ | EXEC | SUM | -- | -- | IRQ | INC | MODE |______ Command Register
; 2_ | A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 |______ Host Address lo
; 3_ | A15 | A14 | A13 | A12 | A11 | A10 | A9 | A8 |______ Host Address hi
; 4_ | EX7 | EX6 | EX5 | EX4 | EX3 | EX2 | EX1 | EX0 |______ Expansion Address lo
; 5_ | EX15 | EX14 | EX13 | EX12 | EX11 | EX10 | EX9 | EX8 |______ Expansion Address hi
; 6_ | -- | -- | -- | -- | -- | BA2 | BA1 | BA0 |______ Expansion Bank pointer
; 7_ | L7 | L6 | L5 | L4 | L3 | L2 | L1 | L0 |______ Transfer Length lo
; 8_ | L15 | L14 | L13 | L12 | L11 | L10 | L9 | L8 |______ Transfer Length hi
; 9_ | S7 | S6 | S5 | S4 | S3 | S2 | S1 | S0 |______ Checksum
; 10_ |______|______|______|______|______|______|______|______|______ Version & Max-Memory
; MODE => 00: Transfer FROM internal TO external
; 01: Transfer TO internal FROM external
; 10: Swap
; 11: Verify
; The DMA CONTROLLER appears in the C/128 I/O memory map at IO2 ($DF00).
.page
; 8564 VIC REGISTER MAP
;
; REG # _______________________________________________________
; 0_ | S0x7 | S0x6 | S0x5 | S0x4 | S0x3 | S0x2 | S0x1 | S0x0 |______ Sprite 0 X location
; 1_ |______|______|______|______|______|______|______|______|______ Sprite 0 Y location
; 2_ | | | | | | | | |______ Sprite 1 X location
; 3_ |______|______|______|______|______|______|______|______|______ Sprite 1 Y location
; 4_ | | | | | | | | |______ Sprite 2 X location
; 5_ |______|______|______|______|______|______|______|______|______ Sprite 2 Y location
; 6_ | | | | | | | | |______ Sprite 3 X location
; 7_ |______|______|______|______|______|______|______|______|______ Sprite 3 Y location
; 8_ | | | | | | | | |______ Sprite 4 X location
; 9_ |______|______|______|______|______|______|______|______|______ Sprite 4 Y location
; 10_ | | | | | | | | |______ Sprite 5 X location
; 11_ |______|______|______|______|______|______|______|______|______ Sprite 5 Y location
; 12_ | | | | | | | | |______ Sprite 6 X location
; 13_ |______|______|______|______|______|______|______|______|______ Sprite 6 Y location
; 14_ | | | | | | | | |______ Sprite 7 X location
; 15_ |______|______|______|______|______|______|______|______|______ Sprite 7 Y location
; 16_ | S7x8 | S6x8 | S5x8 | S4x8 | S3x8 | S2x8 | S1x8 | S0x8 |______ MSB of Sprite X loctn
; 17_ | RC8 | ECM | BMM | Blank| ROWS | Y2 | Y1 | Y0 |______ mode, #row, y-scroll
; 18_ | RC7 | RC6 | RC5 | RC4 | RC3 | RC2 | RC1 | RC0 |______ Raster latch
; 19_ | LPx8 | LPx7 | LPx6 | LPx5 | LPx4 | LPx3 | LPx2 | LPx1 |______ Lightpen X latch
; 20_ | LPy7 | LPy6 | LPy5 | LPy4 | LPy3 | LPy2 | LPy1 | LPy0 |______ Lightpen Y latch
; 21_ | SD7 | SD6 | SD5 | SD4 | SD3 | SD2 | SD1 | SD0 |______ Sprite Disable
; 22_ | -- | -- | Reset| MCM | COLS | X2 | X1 | X0 |______ mode, #col, x-scroll
; 23_ | S7Ey | S6Ey | S5Ey | S4Ey | S3Ey | S2Ey | S1Ey | S0Ey |______ Sprite Y expand
; 24_ | VM13 | VM12 | VM11 | VM10 | CB13 | CB12 | CB11 | -- |______ VM Base, CHR Base
; 25_ | IRQ | -- | -- | -- | LP | S/S | S/B | RIRQ |______ IRQ source (wrt to clr)
; 26_ | -- | -- | -- | -- | _LP | _S/S | _S/B | _IRQ |______ IRQ enable (0=disable)
; 27_ | BSP7 | BSP6 | BSP5 | BSP4 | BSP3 | BSP2 | BSP1 | BSP0 |______ Sprite/Bgnd Priority
; 28_ | MCS7 | MCS6 | MCS5 | MCS4 | MCS3 | MCS2 | MCS1 | MCS0 |______ Multicolor Sprite Sel
; 29_ | S7Ex | S6Ex | S5Ex | S4Ex | S3Ex | S2Ex | S1Ex | S0Ex |______ Sprite X expand
; 30_ | SS7 | SS6 | SS5 | SS4 | SS3 | SS2 | SS1 | SS0 |______ S/S Collision latch
; 31_ | SB7 | SB6 | SB5 | SB4 | SB3 | SB2 | SB1 | SB0 |______ S/B Collision latch
; 32_ | -- | -- | -- | -- | | | | |______ Border Color
; 33_ | -- | -- | -- | -- | | | | |______ Background Color #0
; 34_ | -- | -- | -- | -- | | | | |______ Background Color #1
; 35_ | -- | -- | -- | -- | | | | |______ Background Color #2
; 36_ | -- | -- | -- | -- | | | | |______ Background Color #3
; 37_ | -- | -- | -- | -- | | | | |______ Sprite Multicolor #0
; 38_ | -- | -- | -- | -- | | | | |______ Sprite Multicolor #1
; 39_ | -- | -- | -- | -- | | | | |______ Sprite 0 Color
; 40_ | -- | -- | -- | -- | | | | |______ Sprite 1 Color
; 41_ | -- | -- | -- | -- | | | | |______ Sprite 2 Color
; 42_ | -- | -- | -- | -- | | | | |______ Sprite 3 Color
; 43_ | -- | -- | -- | -- | | | | |______ Sprite 4 Color
; 44_ | -- | -- | -- | -- | | | | |______ Sprite 5 Color
; 45_ | -- | -- | -- | -- | | | | |______ Sprite 6 Color
; 46_ | -- | -- | -- | -- | | | | |______ Sprite 7 Color
; 47_ | -- | -- | -- | -- | -- | K2 | K1 | K0 |______ Keyboard lines (new)
; 48_ | -- | -- | -- | -- | -- | -- | TEST | 2MHz |______ Clock speed
; |-------------------------------------------------------|
.page
; 6581 SID REGISTER MAP
;
; REG # _______________________________________________________
; 0_ | F7 | F6 | F5 | F4 | F3 | F2 | F1 | F0 |______ Frequency lo Voice-1
; 1_ | F15 | F14 | F13 | F12 | F11 | F10 | F9 | F8 |______ Frequency hi
; 2_ | PW7 | PW6 | PW5 | PW4 | PW3 | PW2 | PW1 | PW0 |______ Pulse Width lo
; 3_ | -- | -- | -- | -- | PW11 | PW10 | PW9 | PW8 |______ Pulse Width hi
; 4_ | NOISE| PULSE| SAW | TRI | TEST | RING | SYNC | GATE |______ Control Register
; 5_ | ATK3 | ATK2 | ATK1 | ATK0 | DCY3 | DCY2 | DCY1 | DCY0 |______ Attack/Decay
; 6_ | STN3 | STN2 | STN1 | STN0 | RLS3 | RLS2 | RLS1 | RLS0 |______ Sustain/Release
; |------|------|------|------|------|------|------|------|
; 7_ | F7 | F6 | F5 | F4 | F3 | F2 | F1 | F0 |______ Frequency lo Voice-2
; 8_ | F15 | F14 | F13 | F12 | F11 | F10 | F9 | F8 |______ Frequency hi
; 9_ | PW7 | PW6 | PW5 | PW4 | PW3 | PW2 | PW1 | PW0 |______ Pulse Width lo
; 10_ | -- | -- | -- | -- | PW11 | PW10 | PW9 | PW8 |______ Pulse Width hi
; 11_ | NOISE| PULSE| SAW | TRI | TEST | RING | SYNC | GATE |______ Control Register
; 12_ | ATK3 | ATK2 | ATK1 | ATK0 | DCY3 | DCY2 | DCY1 | DCY0 |______ Attack/Decay
; 13_ | STN3 | STN2 | STN1 | STN0 | RLS3 | RLS2 | RLS1 | RLS0 |______ Sustain/Release
; |------|------|------|------|------|------|------|------|
; 14_ | F7 | F6 | F5 | F4 | F3 | F2 | F1 | F0 |______ Frequency lo Voice-3
; 15_ | F15 | F14 | F13 | F12 | F11 | F10 | F9 | F8 |______ Frequency hi
; 16_ | PW7 | PW6 | PW5 | PW4 | PW3 | PW2 | PW1 | PW0 |______ Pulse Width lo
; 17_ | -- | -- | -- | -- | PW11 | PW10 | PW9 | PW8 |______ Pulse Width hi
; 18_ | NOISE| PULSE| SAW | TRI | TEST | RING | SYNC | GATE |______ Control Register
; 19_ | ATK3 | ATK2 | ATK1 | ATK0 | DCY3 | DCY2 | DCY1 | DCY0 |______ Attack/Decay
; 20_ | STN3 | STN2 | STN1 | STN0 | RLS3 | RLS2 | RLS1 | RLS0 |______ Sustain/Release
; |------|------|------|------|------|------|------|------|
; 21_ | -- | -- | -- | -- | -- | FC2 | FC1 | FC0 |______ Frequency lo Filter
; 22_ | FC10 | FC9 | FC8 | FC7 | FC6 | FC5 | FC4 | FC3 |______ Frequency hi
; 23_ | RES3 | RES2 | RES1 | RES0 |FILTEX| FILT3| FILT2| FILT0|______ Resonance/Filter
; 24_ | 3 OFF| HP | BP | LP | VOL3 | VOL2 | VOL1 | VOL0 |______ Mode/Volume
; |------|------|------|------|------|------|------|------|
; 25_ | PX7 | PX6 | PX5 | PX4 | PX3 | PX2 | PX1 | PX0 |______ Pot X Misc.
; 26_ | PY7 | PY6 | PY5 | PY4 | PY3 | PY2 | PY1 | PY0 |______ Pot Y
; 27_ | O7 | O6 | O5 | O4 | O3 | O2 | O1 | O0 |______ Oscillator 3
; 28_ | E7 | E6 | E5 | E4 | E3 | E2 | E1 | E0 |______ Envelope 3
; |-------------------------------------------------------|
.page
; 8563 VDC REGISTER MAP
;
; REG # _______________________________________________________
; 0_ | HT7 | HT6 | HT5 | HT4 | HT3 | HT2 | HT1 | HT0 |______ Horizontal Total
; 1_ | HD7 | HD6 | HD5 | HD4 | HD3 | HD2 | HD1 | HD0 |______ Horizontal Displayed
; 2_ | HP7 | HP6 | HP5 | HP4 | HP3 | HP2 | HP1 | HP0 |______ Horizontal Sync Position
; 3_ | VW3 | VW2 | VW1 | VW0 | HW3 | HW2 | HW1 | HW0 |______ Vert/Horz Sync Width
; 4_ | VT7 | VT6 | VT5 | VT4 | VT3 | VT2 | VT1 | VT0 |______ Vertical Total
; 5_ | -- | -- | -- | VA4 | VA3 | VA2 | VA1 | VA0 |______ Vertical Total Adjust
; 6_ | VD7 | VD6 | VD5 | VD4 | VD3 | VD2 | VD1 | VD0 |______ Vertical Displayed
; 7_ | VP7 | VP6 | VP5 | VP4 | VP3 | VP2 | VP1 | VP0 |______ Vertical Sync Position
; 8_ | -- | -- | -- | -- | -- | -- | IM1 | IM0 |______ Interlace Mode
; 9_ | -- | -- | -- | CTV4 | CTV3 | CTV2 | CTV1 | CTV0 |______ Character Total Vertical
; 10_ | -- | CM1 | CM0 | CS4 | CS3 | CS2 | CS1 | CS0 |______ Cursor Mode, Start Scan
; 11_ | -- | -- | -- | CE4 | CE3 | CE2 | CE1 | CE0 |______ Cursor End Scan Line
; 12_ | DS15 | DS14 | DS13 | DS12 | DS11 | DS10 | DS9 | DS8 |______ Display Start Address hi
; 13_ | DS7 | DS6 | DS5 | DS4 | DS3 | DS2 | DS1 | DS0 |______ Display Start Address lo
; 14_ | CP15 | CP14 | CP13 | CP12 | CP11 | CP10 | CP9 | CP8 |______ Cursor Position hi
; 15_ | CP7 | CP6 | CP5 | CP4 | CP3 | CP2 | CP1 | CP0 |______ Cursor Position lo
; 16_ | LPV7 | LPV6 | LPV5 | LPV4 | LPV3 | LPV2 | LPV1 | LPV0 |______ Light Pen Vertical
; 17_ | LPH7 | LPH6 | LPH5 | LPH4 | LPH3 | LPH2 | LPH1 | LPH0 |______ Light Pen Horizontal
; 18_ | UA15 | UA14 | UA13 | UA12 | UA11 | UA10 | UA9 | UA8 |______ Update Address hi
; 19_ | UA7 | UA6 | UA5 | UA4 | UA3 | UA2 | UA1 | UA0 |______ Update Address lo
; 20_ | AA15 | AA14 | AA13 | AA12 | AA11 | AA10 | AA9 | AA8 |______ Attribute Start Adr hi
; 21_ | AA7 | AA6 | AA5 | AA4 | AA3 | AA2 | AA1 | AA0 |______ Attribute Start Adr lo
; 22_ | CTH3 | CTH2 | CTH1 | CTH0 | CDH3 | CDH2 | CDH1 | CDH0 |______ Character Tot(h), Dsp(v)
; 23_ | -- | -- | -- | CDV4 | CDV3 | CDV2 | CDV1 | CDV0 |______ Character Dsp(v)
; 24_ | COPY | RVS |CBRATE| VSS4 | VSS3 | VSS2 | VSS1 | VSS0 |______ Vertical smooth scroll
; 25_ | TEXT | ATR | SEMI | DBL | HSS3 | HSS2 | HSS1 | HSS0 |______ Horizontal smooth scroll
; 26_ | FG3 | FG2 | FG1 | FG0 | BG3 | BG2 | BG1 | BG0 |______ Foregnd/Bgnd Color
; 27_ | AI7 | AI6 | AI5 | AI4 | AI3 | AI2 | AI1 | AI0 |______ Address Increment / Row
; 28_ | CB15 | CB14 | CB13 | RAM | -- | -- | -- | -- |______ Character Base Address
; 29_ | -- | -- | -- | UL4 | UL3 | UL2 | UL1 | UL0 |______ Underline scan line
; 30_ | WC7 | WC6 | WC5 | WC4 | WC3 | WC2 | WC1 | WC0 |______ Word Count
; 31_ | DA7 | DA6 | DA5 | DA4 | DA3 | DA2 | DA1 | DA0 |______ Data
; 32_ | BA15 | BA14 | BA13 | BA12 | BA11 | BA10 | BA9 | BA8 |______ Block Start Address hi
; 33_ | BA7 | BA6 | BA5 | BA4 | BA3 | BA2 | BA1 | BA0 |______ Block Start Address lo
; 34_ | DEB7 | DEB6 | DEB5 | DEB4 | DEB3 | DEB2 | DEB1 | DEB0 |______ Display Enable Begin
; 35_ | DEE7 | DEE6 | DEE5 | DEE4 | DEE3 | DEE2 | DEE1 | DEE0 |______ Display Enable End
; 36_ | -- | -- | -- | -- | DRR3 | DRR2 | DRR1 | DRR0 |______ DRAM Refresh rate
; |-------------------------------------------------------|
;
;
; Description of MAPPED registers:
; _______________________________________________________
; $D600 -> address (write): | -- | -- | R5 | R4 | R3 | R2 | R1 | R0 |
; status (read) : |STATUS| LP |VBLANK| -- | -- | VER2 | VER1 | VER0 |
; | | | | | | | | |
; $D601 -> data (r/w) : | D7 | D6 | D5 | D4 | D3 | D3 | D2 | D0 |
; |-------------------------------------------------------|
; _______________________________________________________
; ATTRIBUTE byte layout | ALT | RVS | UL | FLASH| R | G | B | I |
; |-------------------------------------------------------|
.page
; EXPLANATION OF VARIOUS KERNAL/EDITOR FLAG BYTES, ETC.
;
; Symbol Description
; 7 6 5 4 3 2 1 0
; _________________________________________________________
; D6510 | -- | (in) | (out)| (in) | (out)| (out)| (out)| (out)|
; | | | | | | | | |
; R6510 | -- |CAPKEY|CASMTR|CASSEN|CASWRT|CHAREN| HIRAM| LORAM|
; | | | | | | | | |
; LOCKS | CASE | CTL-S| -- | -- | -- | -- | -- | -- |
; | | | | | | | | |
; SCROLL | OFF |LINKER| | | | | | |
; | | | | | | | | |
; SHFLAG | -- | -- | -- | ALT | ALPHA| CTRL | C= | SHIFT|
; | | | | | | | | |
; RPTFLG | ALL | NONE | -- | -- | -- | -- | -- | -- |
; | | | | | | | | |
; BLNON | ON | BLNK | -- | -- | -- | -- | -- | -- |
; | | | | | | | | |
; BEEPER | ON | -- | -- | -- | -- | -- | -- | -- |
; | | | | | | | | |
; GRAPHM | MCM | SPLIT| BMM | -- | -- | -- | -- | -- |
; | | | | | | | | |
; MODE | 40/80| -- | -- | -- | -- | -- | -- | -- |
; | | | | | | | | |
; INIT_ |CHRSET| CINT | -- | -- | -- | -- | -- | BASIC|
; STATUS |-------------------------------------------------------|
; The following SYMBOLS are used by the c/128 EDITOR. Note that the
; EDITOR irq VIC screen handler depends upon them. In most cases the
; contents of these locations will be placed directly into the appropriate
; register and should be used by the user instead of the actual register.
; GRAPHM ....... See above. If = $FF then editor leaves VIC alone.
; CHAREN ....... Mask for R6510 /charen bit.
; VM1 .......... VIC text mode Video Matrix & Character Base pointer.
; VM2 .......... VIC graphic mode Video Matrix & Bit Map pointer.
; VM3 .......... 8563 text display base address.
; VM4 .......... 8563 attribute base address.
; SPLIT ........ If split screen mode, contains value for 'middle' raster IRQ.
; CURMOD ....... 8563 cursor mode.
; PAUSE ........ Control-S in effect flag. Is = $13 if so.
; Some insight into KERNAL symbols:
; INIT_STATUS .. See also above. Lets system know what has been initialized
; and what hasn't. Set to $00 by a reset but untouched by NMI.
; SYSTEM_VECTOR. Where the kernal goes when it has to go somewhere. It's set
; to BASIC COLD at reset. BASIC itself sets it to BASIC WARM
; after it has inited. The MONITOR respects it too.
; SYSTEM ....... Vector in RAM1 at $FFF8. Set at powerup to C128MODE, user may
; redirect it to his code. Taken at RESET always, providing
; user with control (protection) from reset.

211
KERNAL_C128_03/tapectlr.src

@ -0,0 +1,211 @@
.page
.subttl tape controller (03/18/85)
jtp20
jsr tapadr ;check for buffer pointer wrap
inc bufpt
ldy bufpt
cpy #bufsz ;returns = if wrap
rts
; wait for cassette <play> switch or keyboard <stop> key
;
cste1
jsr cs10 ;skip ahead if <play> already down
beq cs25
ldy #ms7-ms1 ;prompt: 'press play...'
cs30
jsr msg
1$ jsr tstop ;watch for stop key
jsr cs10 ;watch cassette switches
bne 1$
ldy #ms18-ms1 ;prompt: 'ok'
jmp msg
; check cassette switches: return = if switch down
cs10
lda #$10 ;check port
bit r6510 ;closed?
bne cs25 ;no
bit r6510 ;check again to debounce
cs25
clc ;good return
rts
; wait for cassette play & record switches
cste2
jsr cs10
beq cs25
ldy #ms8-ms1 ;prompt '...record'
bne cs30 ;always
.page
rblk ;read header block entry
lda #0
sta status
sta verck
jsr ldad1
trd ;read load block entry
jsr cste1 ;say 'press play'
bcs twrt3 ;stop key pressed
sei
lda #0 ;clear flags...
sta rdflg
sta snsw1
sta cmp0
sta ptr1
sta ptr2
sta dpsw
lda #$90 ;enable for ca1 irq...read line
ldx #14 ;redirect irq vector to read
bne tape ;always
wblk ;write header block entry
jsr ldad1
twrt ;write load block entry
lda #20 ;between block shorts
sta shcnh
twrt2
jsr cste2 ;say 'press play & record'
twrt3
bcs stop3 ;stop key pressed
sei
lda #$82 ;enable t2 irqs...write time
ldx #8 ;redirect irq vector to 'wrtz', fall into 'tape'
.page
; start tape operation entry point
tape
ldy #0
sty vicreg+26 ;kill unwanted vic irq's
dey
sty vicreg+25 ;clear any pending vic irq's
sta d1icr ;turn on wanted irq's
lda d1cra ;calculate timer enables
ora #$19
sta d1crb ;turn on t2 irq's for cassette write (one shot)
and #$91 ;save tod 50/60 indication
sta caston ;place in auto mode for t1
jsr rsp232 ;wait for any rs-232 operations to finish
lda vicreg+17 ;blank vic
tay
and #$10 ; (save blank bit status for restoration later)
sta blanking
tya
and #$6f ; (leave RC8 clear- it's the irq trigger!)
sta vicreg+17
jsr get_sp ;save system speed & sprites
lda iirq ;move irq to irqtemp during cassette operations
sta irqtmp
lda iirq+1
sta irqtmp+1
jsr bsiv ;go change irq vector
lda #2 ;fsblk starts at 2
sta fsblk
jsr newch ;prep local counters and flags
lda r6510 ;turn motor on
and #%00011111 ;low turns on
sta r6510
sta cas1 ;flag internal control of cassette motor
ldx #$ff ;delay between blocks
1$ ldy #$ff
2$ dey
bne 2$
dex
bne 1$
cli
3$ lda irqtmp+1 ;check for interrupt vector...
cmp iirq+1 ;...pointing at key routine
clc
beq stop3 ;...branch if so- & return
jsr tstop ;check for stop key (& never return if down)
jsr ud60 ;scan stop key (60Hz keyscan is off)
jmp 3$ ;loop until tape operations are done
.page
tstop
jsr stop ;stop key down?
clc ;assume no stop
bne stop4 ;we were right
; stop key down...
jsr tnif ;turn off cassette
sec ;failure flag
pla ;back one square...
pla
stop3
lda #0 ;deallocate irqtmp
sta irqtmp+1 ;if c-set then stop key
stop4
rts
.page
; stt1 - set up timeout watch for next dipole
stt1
stx temp ;.x has constant for timeout
lda cmp0 ;calculate: cmp0*5
asl a
asl a
clc
adc cmp0
clc
adc temp ;adjust long byte count
sta temp
lda #0
bit cmp0 ;check cmp0 ...
bmi 1$ ;...minus, no adjust
rol a ;...plus so adjust pos
1$ asl temp ;multiply corrected value by 4
rol a
asl temp
rol a
tax
2$ lda d1t2l ;watch out for d1t2h rollover...
cmp #22 ;...time for routine...!!!...
bcc 2$ ;...too close so wait until past
adc temp ;calculate and...
sta d1t1l ;...store adjusted time count
txa
adc d1t2h ;adjust for high time count
sta d1t1h
lda caston ;enable timers
sta d1cra
sta stupid ;non-zero means an t1 irq has not occured yet
lda d1icr ;clear old t1 interrupt
and #$10 ;check for old-flag irq
beq stt4 ;no...normal exit
lda #>stt4 ;push simulated return address on stack
pha
lda #<stt4
pha
jmp simirq
stt4 cli ;allow for re-entry code
rts
;.end

198
KERNAL_C128_03/tapefile.src

@ -0,0 +1,198 @@
.page
.subttl tape files (04/19/85)
;//////////// C A S S E T T E T A P E H A N D L E R \\\\\\\\\\\\
; fah -- find any header
;
; reads tape device until one of following block types found:
;
; bdfh - basic data file header
; blf - basic load file
;
; exits with: .c=0 if successful, .c=1 if failure
; .a=0 if <stop> key pressed
fah
lda verck ;save old verify
pha
jsr rblk ;read tape block
pla
sta verck ;restore verify flag
bcs 7$ ;read terminated, rts
ldy #0
lda (tape1),y ;get header type
cmp #eot ;check end of tape?
beq 6$ ;yes...failure (rts, .c=1 and <> )
cmp #blf ;basic load file?
beq 1$ ;yes...success
cmp #plf ;fixed load file?
beq 1$ ;yes...success
cmp #bdfh ;basic data file?
bne fah ;no...keep trying
1$ tax ;return file type in .x
bit msgflg ;printing messages?
bpl 5$ ;no...
ldy #ms17-ms1 ;print "found"
jsr msg
ldy #5
2$ lda (tape1),y ;print filename
jsr bsout
iny
cpy #21
bne 2$
lda time+1 ;set up for time out...
adc #2 ; (delay for 8 to 13 sec of display time)
3$ ldy stkey ;check for key down in last row
iny
bne 4$ ;...branch if key down (exit loop)
cmp time+1
bne 3$ ;...loop until enough delay
4$ cpy #$f0
beq fah ;...user hit 'space'- skip this one
5$ clc ;success flag
6$ dey ;make non-zero for good return
7$ rts
.page
; tapeh - write tape header
;
; exit: .c=1 if failure (eg: tape buffer de-allocated)
; .c=0 if good
tapeh
sta t1 ;save block type
jsr tapadr ;get address of tape buffer
bcc 4$ ;buffer was de-allocated
lda stah ;preserve start & end load adr in case of load file
pha
lda stal
pha
lda eah
pha
lda eal
pha
ldy #bufsz-1
lda #space
1$ sta (tape1),y ;put blanks into tape buffer
dey
bne 1$
lda t1
sta (tape1),y ;put block type into header
iny
lda stal
sta (tape1),y ;put load address into header
iny
lda stah
sta (tape1),y
iny
lda eal
sta (tape1),y ;put end address into header
iny
lda eah
sta (tape1),y
iny
sty t2
ldy #0
sty t1
2$ ldy t1
cpy fnlen
beq 3$
jsr fnadry ; <lda (fnadr),y>: put filename into header
ldy t2
sta (tape1),y
inc t1
inc t2
bne 2$
3$ jsr ldad1 ;set up start and end address of header
lda #$69 ;set up time for leader
sta shcnh
jsr twrt2 ;write header on tape
tay ;save error code in .y
pla
sta eal ;restore start & end adr of load file
pla
sta eah
pla
sta stal
pla
sta stah
tya ;restore error code for return
4$ rts
.page
; routine returns tape buffer address in tape1
;
; buffer is deallocated if 'tape1+1' < 2
; returns .c=0 if deallocated
tapadr ldx tape1 ;assume tape1
ldy tape1+1
cpy #>buf ;check for allocation...
rts
ldad1
jsr tapadr ;get ptr to cassette buffer
txa
sta stal ;save start low
clc
adc #bufsz ;compute pointer to end
sta eal ;save end low
tya
sta stah ;save start high
adc #0
sta eah ;save end high
rts
faf
jsr fah ;find any header
bcs 3$ ;failed
; success...see if right name
ldy #5 ;offset into tape header
sty t2
ldy #0 ;offset into file name
sty t1
1$ cpy fnlen ;compare this many
beq 2$ ;done
jsr fnadry ; <lda (fnadr),y>
ldy t2
cmp (tape1),y
bne faf ;mismatch--try next header
inc t1
inc t2
ldy t1
bne 1$ ;branch always
2$ clc ;success flag
3$ rts
;.end

37
KERNAL_C128_03/tapeirq.src

@ -0,0 +1,37 @@
.page
.subttl tape interrupt handler (12/26/84)
;///////////// T A P E I R Q I N T E R R U P T C O D E \\\\\\\\\\\\
; simirq - simulate an irq (for cassette read)
; (enter by a 'jsr simirq')
simirq
php
pla ;fix the break flag
and #$ef
pha
jmp irq ;make like an irq occurred
tapeirq
lda r6510 ;cassette switch handler
and #$10
beq 1$ ;...branch if cassette switch down
ldy #0
sty cas1 ;reset cassette 'off' switch
lda r6510
ora #$20
bne 2$ ;...branch always & turn motor off
1$ lda cas1
bne 3$ ;...branch if already 'on'
lda r6510
and #$df ;turn motor on
2$ sta r6510 ;make motor perform per switches
3$ rts
;.end

504
KERNAL_C128_03/taperead.src

@ -0,0 +1,504 @@
.page
.subttl tape read (11/28/84)
; variables used in cassette read routines:
;
; rez - counts zeros (if z then correct # of dipoles)
; rer - flags errors (if z then no error)
; diff - used to preserve syno (outside of bit routines)
; syno - flags if we have block sync (16 zero dipoles)
; snsw1 - flags if we have byte sync (a longlong)
; data - holds most recent dipole bit value
; mych - holds input byte being built
; firt - used to indicate which half of dipole we're in
; svxt - temp used to adjust software servo
; temp - used to hold dipole time during type calculations
; prty - holds current calculated parity bit
; prp - has combined error values from bit routines
; fsblk - indicate which block we're looking at (0 to exit)
; shcnl - holds fsblk, used to direct routines, because of exit case
; rdflg - holds function mode:
; mi - waiting for block sync
; vs - in data block reading data
; ne - waiting for byte sync
; sal - indirect to data storage area
; shcnh - left over from debugging
; bad - storage space for bad read locations (bottom of stack)
; ptr1 - count of read locations in error (pointer into bad, max 61)
; ptr2 - count of re-read locations (pointer into bad, during re-read)
; verchk- verify or load flag (z - loading)
; cmp0 - software servo (+/- adjust to time calcs)
; dpsw - if nz then expecting ll/l combination that ends a byte
; pcntr - counts down from 8-0 for data then to ff for parity
; stupid- hold indicator (nz - no t1irq yet) for t1irq
; kika26- holds old d1icr after clear on read
read
ldx d1t2h ;get time since last interrupt
ldy #$ff ;compute counter difference
tya
sbc d1t2l
cpx d1t2h ;check for timer high rollover...
bne read ;...yes then recompute
stx temp
tax
sty d1t2l ;reload timer2 (count down from $ffff)
sty d1t2h
lda #$19 ;enable timer
sta d1crb
lda d1icr ;clear read interrupt
sta kika26 ;save for later
tya
sbc temp ;calculate high
stx temp
lsr a ;move two bits from high to temp
ror temp
lsr a
ror temp
lda cmp0 ;calc min pulse value
clc
adc #60
cmp temp ;if pulse less than min...
bcs rdbk ;...then ignore as noise
ldx dpsw ;check if last bit...
beq 1$ ;...no then continue
jmp radj ;...yes then go finish byte
1$ ldx pcntr ;if 9 bits read...
bmi jrad2 ;... then goto ending
ldx #0 ;set bit value to zero
adc #48 ;add up to half way between...
adc cmp0 ;...short pulse and sync pulse
cmp temp ;check for short...
bcs radx2 ;...yes it's a short
inx ;set bit value to one
adc #38 ;move to middle of high
adc cmp0
cmp temp ;check for one...
bcs radl ;...yes it's a one
adc #44 ;move to longlong
adc cmp0
cmp temp ;check for longlong...
bcc srer ;...greater than is error
jrad2 jmp rad2 ;...it's a longlong
srer
lda snsw1 ;if not syncronized...
beq rdbk ;...then no error
sta rer ;...else flag rer
bne rdbk ;always
radx2
inc rez ;count rez up on zeros
bcs rad5 ;always
radl
dec rez ;count rez down on ones
rad5
sec ;calc actual value for compare store
sbc #19
sbc temp ;subtract input value from constant...
adc svxt ;...add difference to temp storage...
sta svxt ;...used later to adjust soft servo
lda firt ;flip dipole flag
eor #1
sta firt
beq rad3 ;second half of dipole
stx data ;first half so store its value
rdbk
lda snsw1 ;if no byte start...
beq radbk ;...then return
lda kika26 ;check to see if timer1 irqd us...
and #$01
bne radkx ;...yes
lda stupid ;check for old t1irq
bne radbk ;no...so exit
radkx
lda #0 ;...yes, set dipole flag for first half
sta firt
sta stupid ;set t1irq flag
lda pcntr ;check where we are in byte...
bpl rad4 ;...doing data
bmi jrad2 ;...process parity
radp
ldx #166 ;set up for longlong timeout
jsr stt1
lda prty ;if parity not even...
bne srer ;...then go set error
radbk
jmp prend ;go restore regs and rti
rad3
lda svxt ;adjust the software servo (cmp0)
beq 2$ ;no adjust
bmi 1$ ;adjust for more base time
dec cmp0 ;adjust for less base time
.byte $2c ;skip two bytes
1$ inc cmp0
2$ lda #0 ;clear difference value
sta svxt
; check for consecutive like values in dipole...
cpx data
bne rad4 ;...no, go process info
txa ;...yes so check the values...
bne srer ;if they were ones then error
; consecutive zeros
lda rez ;...check how many zeros have happened
bmi rdbk ;...if many don't check
cmp #16 ;... do we have 16 yet?...
bcc rdbk ;....no so continue
sta syno ;....yes so flag syno (between blocks)
bcs rdbk ;always
rad4
txa ;move read data to .a
eor prty ;calculate parity
sta prty
lda snsw1 ;real data?...
beq radbk ;...no so forget by exiting
dec pcntr ;dec bit count
bmi radp ;if minus then time for parity
lsr data ;shift bit from data...
ror mych ;...into byte storage (mych) buffer
ldx #218 ;set up for next dipole
jsr stt1
jmp prend ;restore regs and rti
; rad2 - longlong handler (could be a long one)
rad2
lda syno ;have we gotten block sync...
beq 1$ ;...no
lda snsw1 ;check if we've had a real byte start...
beq 2$ ;...no
1$ lda pcntr ;are we at end of byte...
bmi 2$ ;yes...go adjust for longlong
jmp radl ;...no so treat it as a long one read
2$ lsr temp ;adjust timeout for...
lda #147 ;...longlong pulse value
sec
sbc temp
adc cmp0
asl a
tax ;and set timeout for last bit
jsr stt1
inc dpsw ;set bit throw away flag
lda snsw1 ;if byte syncronized....
bne 3$ ;...then skip to pass char
lda syno ;throws out data until block sync...
beq 5$ ;...no block sync
sta rer ;flag data as error
lda #0 ;kill 16 sync flag
sta syno
lda #$81 ;set up for timer1 interrupts
sta d1icr
sta snsw1 ;flag that we have byte syncronized
3$ lda syno ;save syno status
sta diff
beq 4$ ;no block sync, no byte looking
lda #0 ;turn off byte sync switch
sta snsw1
lda #$01 ;disable timer1 interrupts
sta d1icr
4$ lda mych ;pass character to byte routine
sta ochar
lda rer ;combine error values with zero count...
ora rez
sta prp ;...and save in prp
5$ jmp prend ;go back and get last byte
radj
jsr newch ;finish byte, clr flags
sta dpsw ;clear bit throw away flag
ldx #218 ;initilize for next dipole
jsr stt1
lda fsblk ;check for last value
beq rd15
sta shcnl ;fall into byte handler
.page
; cassette read byte handler
;
; this portion of in line code is passed the
; byte assembled from reading tape in ochar.
;
; rer is set if the byte read is in error.
; rez is set if the interrupt program is reading zeros.
;
; rdflg tells us what we are doing:
; bit 7 says to ignore bytes until rez is set
; bit 6 says to load the byte. otherwise rdflg is a countdown after sync.
;
; if verck is set we do a compare instead of a store and set status.
; fsblk counts the two blocks.
; ptr1 is index to error table for pass1.
; ptr2 is index to correction table for pass2.
sperr = 16
ckerr = 32
sberr = 4
lberr = 8
rd15
lda #$f
bit rdflg ;test function mode
bpl rd20 ;not waiting for zeros
lda diff ;zeros yet?
bne rd12 ;yes...wait for sync
ldx fsblk ;is pass over?
dex ;...if fsblk zero then no error (first good)
bne rd10 ;no...
lda #lberr
jsr udst ;yes...long block error
bne rd10 ;branch always
rd12
lda #0
sta rdflg ;new mode is wait for sync
rd10 jmp prend ;exit...done
rd20
bvs rd60 ;we are loading
bne rd200 ;we are syncing
lda diff ;do we have block sync...
bne rd10 ;...yes, exit
lda prp ;if first byte has error...
bne rd10 ;...then skip (exit)
lda shcnl ;move fsblk to carry...
lsr a
lda ochar ; should be a header count char
bmi rd22 ;if neg then firstblock data
bcc rd40 ;...expecting firstblock data...yes
clc
rd22
bcs rd40 ;expecting second block?...yes
and #$0f ;mask off high store header count...
sta rdflg ;...in mode flag (have correct block)
rd200
dec rdflg ;wait until we get real data...
bne rd10 ;...9876543210 real
lda #$40 ;next up is real data...
sta rdflg ;...set data mode
jsr rd300 ;go setup address pointers
lda #0 ;debug code##################################################
sta shcnh
beq rd10 ;jmp to continue
rd40
lda #$80 ;we want to...
sta rdflg ;ignore bytes mode
bne rd10 ;jmp
rd60
lda diff ;check for end of block...
beq rd70 ;...okay
lda #sberr ;short block error
jsr udst
lda #0 ;force rdflg for an end
jmp rd161
rd70
jsr cmpste ;check for end of storage area
bcc 1$ ;not done yet
jmp rd160
1$ ldx shcnl ;check which pass...
dex
beq rd58 ;...second pass
lda verck ;check if load or verify...
beq rd80 ;...loading
ldy #0 ;...just verifying
jsr sally ; <lda (sal),y>
cmp ochar ;compare with data in memory
beq rd80 ;...good so continue
lda #1 ;...bad so flag...
sta prp ;...as an error
; store bad locations for second pass re-try
rd80
lda prp ;chk for errors...
beq rd59 ;...no errors
ldx #61 ;max allowed is 30
cpx ptr1 ;are we at max?...
bcc rd55 ;...yes, flag as second pass error
ldx ptr1 ;get index into bad...
lda sah ;...and store the bad location
sta bad+1,x ;...in bad table
lda sal
sta bad,x
inx ;advance pointer to next
inx
stx ptr1
jmp rd59 ;go store character
; check bad table for re-try (second pass)
rd58
ldx ptr2 ;have we done all in the table?...
cpx ptr1
beq rd90 ;...yes
lda sal ;see if this is next in the table...
cmp bad,x
bne rd90 ;...no
lda sah
cmp bad+1,x
bne rd90 ;...no
inc ptr2 ;we found next one, so advance pointer
inc ptr2
lda verck ;doing a load or verify?...
beq rd52 ;...loading
ldy #0 ;...just verifying
jsr sally ; <lda (sal),y>
cmp ochar ;compare with data in memory
beq rd90 ;...okay
iny ;make .y= 1
sty prp ;flag it as an error
rd52
lda prp ;a second pass error?...
beq rd59 ;...no
rd55 ;second pass error
lda #sperr
jsr udst
bne rd90 ;always
rd59
lda verck ;load or verify?...
bne rd90 ;...verify, don't store
tay ;make y zero
lda ochar
jsr salsy ; <sta (sal),y>: store character
rd90 jsr incsal ;increment addr.
bne rd180 ;branch always
rd160
lda #$80 ;set mode skip next data
rd161 sta rdflg
sei ;protect clearing of t1 information
ldx #$01
stx d1icr ;clear t1 enable...
ldx d1icr ;clear the interrupt
ldx fsblk ;dec fsblk for next pass...
dex
bmi rd167 ;we are done...fsblk=0
stx fsblk ;...else fsblk=next
rd167
dec shcnl ;dec pass calc...
beq rd175 ;...all done
lda ptr1 ;check for first pass errors...
bne rd180 ;...yes so continue
sta fsblk ;clear fsblk if no errors...
beq rd180 ;jmp to exit
rd175
jsr tnif ;read it all...exit
jsr rd300 ;restore sal & sah
ldy #0 ;set shcnh to zero...
sty shcnh ;...used to calc parity byte
; compute parity over load
vprty
jsr sally ; <lda (sal),y>: calc block bcc
eor shcnh
sta shcnh
jsr incsal ;increment address
jsr cmpste ;test against end
bcc vprty ;not done yet...
lda shcnh ;check for bcc char match...
eor ochar
beq rd180 ;...yes, exit
lda #ckerr ;chksum error
jsr udst
rd180 jmp prend
rd300
lda stah ; restore starting address...
sta sah ;...pointers (sah & sal)
lda stal
sta sal
rts
newch
lda #8 ;set up for 8 bits+parity
sta pcntr
lda #0 ;initilize...
sta firt ;..dipole counter
sta rer ;..error flag
sta prty ;..parity bit
sta rez ;..zero count
rts ;.a=0 on return
;.end

248
KERNAL_C128_03/tapewrite.src

@ -0,0 +1,248 @@
.page
.subttl tape write (04/29/85)
; cassette info - fsblk is block counter for record
;
; fsblk = 2 -first header
; = 1 -first data
; = 0 -second data
;
; write - toggle write bit according to lsb in ochar
write
lda ochar ;shift bit to write into carry
lsr a
lda #96 ;...c clr write short
bcc wrt1
wrtw
lda #176 ;...c set write long
wrt1
ldx #0 ;set and store time
wrtx
sta d1t2l
stx d1t2h
lda d1icr ;clear irq
lda #$19 ;enable timer (one-shot)
sta d1crb
lda r6510 ;toggle write bit
eor #$08
sta r6510
and #$08 ;leave only write bit
rts
wrtl3
sec ;flag prp for end of block
ror prp
bmi wrt3 ;always
; wrtn - called at the end of each byte to write a long rer rez
; hhhhhhllllllhhhlll...
wrtn
lda rer ;check for one long
bne wrtn1
lda #16 ;write a long bit
ldx #1
jsr wrtx
bne wrt3
inc rer
lda prp ;if end of block(bit set by wrtl3)...
bpl wrt3 ;...no end continue
jmp wrnc ;...end ...finish off
wrtn1
lda rez ;check for a one bit
bne wrtn2
jsr wrtw
bne wrt3
inc rez
bne wrt3
wrtn2
jsr write
bne wrt3 ;on bit low exit
lda firt ;check for first of dipole
eor #1
sta firt
beq wrt2 ;dipole done
lda ochar ;flips bit for complementary right
eor #1
sta ochar
and #1 ;toggle parity
eor prty
sta prty
wrt3 jmp prend ;restore regs and rti exit
wrt2
lsr ochar ;move to next bit
dec pcntr ;dec counter for # of bits
lda pcntr ;check for 8 bits sent...
beq wrt4 ;...if yes move in parity
bpl wrt3 ;...else send rest
wrts
jsr newch ;clean up counters
cli ;allow for interrupts to nest
lda cntdn ;are we writing header counters?...
beq wrt6 ;...no
; write header counters (9876543210 to help with read)
ldx #0 ;clear bcc
stx data
dec cntdn
ldx fsblk ;check for first block header
cpx #2
bne wrt61 ;...no
ora #$80 ;...yes mark first block header
wrt61
sta ochar ;write characters in header
bne wrt3
wrt6
jsr cmpste ;compare start:end
bcc wrt7 ;not done
bne wrtl3 ;go mark end
inc sah
lda data ;write out bcc
sta ochar
bcs wrt3 ;jmp
wrt7
ldy #0 ;get next character
jsr sally ;lda (sal),y
sta ochar ;store in output character
eor data ;update bcc
sta data
jsr incsal ;increment fetch address
bne wrt3 ;branch always
wrt4
lda prty ;move parity into ochar...
eor #1
sta ochar ;...to be written as next bit
wrtbk jmp prend ;restore regs and rti exit
wrnc
dec fsblk ;check for end
bne wrend ;...block only
jsr tnof ;...write, so turn off motor
wrend
lda #80 ;put 80 cassette syncs at end
sta shcnl
ldx #8
sei
jsr bsiv ;set vector to write zeros
bne wrtbk ;jmp
wrtz
lda #120 ;write leading zeros for sync
jsr wrt1
bne wrtbk
dec shcnl ;check if done with low sync...
bne wrtbk ;...no
jsr newch ;...yes clear up counters
dec shcnh ;check if done with sync...
bpl wrtbk ;...no
ldx #10 ;...yes so set vector for data
jsr bsiv
cli
inc shcnh ;zero shcnh
lda fsblk ;if done then...
beq stky ;...goto system restore
jsr rd300
ldx #9 ;set up for header count
stx cntdn
stx prp ;clear endof block flag
bne wrts ;jmp
.page
tnif
php ;return system to normal
sei
lda vicreg+17 ;unblank vic (maybe)
ora blanking
and #$7f ; (leave RC8 clear- it's the irq trigger!)
sta vicreg+17
bit hold_off
bmi 10$ ;...branch if user wants full control of vic
bit speed
bpl 10$ ;...branch if nothing to restore
lda sprites
sta vicreg+21
lda speed
sta vicreg+48
lda #0
sta speed ;flag restoration
10$ jsr tnof ;turn off cassette motor
jsr iokeys ;restore i/o devices for system
lda irqtmp+1 ;restore indirect interrupt vector
beq tniq ; (unless already done)
sta iirq+1
lda irqtmp
sta iirq
tniq
plp
rts
stky
jsr tnif ;go restore system interrupts
jmp prend ;came for cassette irq so rti
.page
; bsiv - subroutine to change irq vectors
; entrys - .x = 8 write zeros to tape
; .x = 10 write data to tape
; .x = 12 restore to keyscan
; .x = 14 read data from tape
bsiv
lda bsit-8,x ;move irq vectors, table to indirect
sta iirq
lda bsit-7,x
sta iirq+1
rts
bsit .word wrtz, wrtn, nirq, read ;indirects for cassette irq's
tnof
lda r6510 ;turn off cassette motor
ora #$20
sta r6510
rts
; compare start and end load/save addresses.
; subroutine called by: tape read, save, tape write
cmpste
sec
lda sal
sbc eal
lda sah
sbc eah
rts
; increment address pointer sal
incsal
inc sal
bne 1$
inc sah
1$ rts
;.end

91
KERNAL_C128_03/time.src

@ -0,0 +1,91 @@
.page
.subttl time functions (01/28/85)
; ***************************************************************
; * time consists of three functions: *
; * *
; * (1) udtim - update time registers as time-of-day clock and *
; * decrement timer registers. this routine should *
; * be called by irq handler for correct time. *
; * (2) settim- set time. .y=msd, .x=next significant, .a=lsd *
; * (3) rdtim - read time. .y=msd, .x=next significant, .a=lsd *
; * *
; ***************************************************************
udtim
inc time+2 ;proceed with an increment of the time registers
bne 1$
inc time+1
bne 1$
inc time
1$ sec ;check for roll-over 23:59:59
lda time+2
sbc #$01
lda time+1
sbc #$1a
lda time
sbc #$4f
bcc 2$
ldx #0 ;time has rolled- reset (zero) time registers
stx time
stx time+1
stx time+2
2$ lda timer ;decrement timer registers
bne 4$
lda timer+1
bne 3$
dec timer+2
3$ dec timer+1
4$ dec timer
bit palnts
bpl ud60 ;...branch if not PAL mode
dec palcnt
bpl ud60 ;...branch if no correction needed at this time
lda #5
sta palcnt
bne udtim ;always...give one extra tick to 50Hz systems
.page \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
ud60 ;set stop key flag here
lda rows ;wait for it to settle
cmp rows
bne ud60 ;still bouncing
tax ;set flags...
bmi 2$ ;no stop key...exit stop key=$7f
ldx #$ff-$42 ;check for a shift key
stx colm
1$ ldx rows ;wait to settle...
cpx rows
bne 1$
sta colm ;watch out...stop key .a=$7f...same as colms was...
inx ;any key down aborts
bne 3$ ;leave same as before...
2$ sta stkey ;save for other routines
3$ rts
rdtim ;read tod registers
sei ;keep time from changing
lda time+2 ;get lsd
ldx time+1 ;get next most sig.
ldy time ;get msd
settim ;set tod registers
sei ;keep time from changing
sta time+2 ;store lsd
stx time+1 ;next most significant
sty time ;store msd
cli
rts
;.end

85
KERNAL_C128_03/vectors.src

@ -0,0 +1,85 @@
.page
.subttl c/128 KERNAL JUMP TABLE (04/29/85)
;/////////////////// K E R N A L J U M P T A B L E \\\\\\\\\\\\\\\\\\\\
* = $ff80-57 ;new 'jmps' for c/128
.kernal_jmp_check
jmp spin_spout ;setup fast serial port for input or output
jmp close_all ;close all logical files for a given device
jmp c64mode ;reconfigure system as a c/64 (no return!)
jmp dma_call ;initiate dma request to external ram expansion
jmp boot_call ;boot load program from disk
jmp phoenix ;call all function card's cold start routines
jmp lkupla ;search tables for given la
jmp lkupsa ;search tables for given sa
jmp swapper ;swap to alternate display device (editor)
jmp dlchr ;init 80-col character ram (editor)
jmp pfkey ;program function key (editor)
jmp setbnk ;set bank for load/save/verify
get_cfg jmp getcfg ;convert bank to mmu configuration
jmp jsrfar ;JSR to any bank, RTS to calling bank
jmp jmpfar ;JMP to any bank
jmp indfet ;LDA (fetvec),Y from any bank
jmp indsta ;STA (stavec),Y to any bank
jmp indcmp ;CMP (cmpvec),Y to any bank
jmp primm ;print immediate (always JSR to this routine!)
.page
* = $ff80 ;conforms to c/64 jump table
.byte 0 ;release number of kernal
jmp cint ;init screen editor & display chips (editor)
jmp ioinit ;init i/o devices (ports, timers, etc.)
jmp ramtas ;initialize ram for system
jmp restor ;restore vectors to initial system
jmp vector ;change vectors for user
jmp setmsg ;control o.s. messages
jmp secnd ;send sa after listen
jmp tksa ;send sa after talk
jmp memtop ;set/read top of memory
jmp membot ;set/read bottom of memory
jmp key ;scan keyboard (editor)
jmp settmo ;set timeout in ieee ?????????????????? unused ???????????
jmp acptr ;handshake serial byte in
jmp ciout ;handshake serial byte out
jmp untlk ;send untalk out serial
jmp unlsn ;send unlisten out serial
jmp listn ;send listen out serial
jmp talk ;send talk out serial
jmp readss ;return i/o status byte
jmp setlfs ;set la, fa, sa
jmp setnam ;set length and fn adr
open jmp (iopen) ;open logical file
close jmp (iclose) ;close logical file
chkin jmp (ichkin) ;open channel in
ckout jmp (ickout) ;open channel out
clrch jmp (iclrch) ;close i/o channel
basin jmp (ibasin) ;input from channel
bsout jmp (ibsout) ;output to channel
jmp loadsp ;load from file
jmp savesp ;save to file
jmp settim ;set internal clock
jmp rdtim ;read internal clock
stop jmp (istop) ;scan stop key
getin jmp (igetin) ;get char from queue
clall jmp (iclall) ;clear all logical files (see close_all)
clock jmp udtim ;increment clock
jmp scrorg ;return current screen window size (editor)
jmp plot ;read/set x,y coord (editor)
jmp iobase ;return i/o base
* = $fff8
system .word c128mode
.word nmi ;processor hardware vectors
.word reset
.word irq

8
README.md

@ -40,14 +40,14 @@ It does not contain the version byte at $FF80 (which is $AA in the binary) or th
The Commodore Plus/4, C16 and C116 BASIC 3.5 and KERNAL source (1984). Source: [ted_kernal_basic_src.tar.gz](http://www.zimmers.net/anonftp/pub/cbm/src/plus4/index.html)
## BASIC_C128, KERNAL_C128_0{5|6}, EDITOR_C128[_DIN], MONITOR_C128
## BASIC_C128, KERNAL_C128_0{3|5|6}, EDITOR_C128[_DIN], MONITOR_C128
The Commodore 128 BASIC 7.0, KERNAL, EDITOR and MONITOR sources (1985/1986). Source: [c128_dev_pack.tar.gz](http://www.zimmers.net/anonftp/pub/cbm/src/c128/index.html)
* EDITOR_C128 is the US version (318020-05), EDITOR_C128_DIN the German version (315078-03).
* KERNAL_C128_03 is 318020-03, $FF80 = 0. (It was reconstructed from listings/first_release/kernal.lis in the dump.)
* KERNAL_C128_05 is 318020-05, $FF80 = 1.
* KERNAL_C128_06 is 318020-06, $FF80 = 2 - this version seems to have been unreleased.
* Version 318020-03, $FF80 = 0 was only included as an .lst file in the dump.
* KERNAL_C128_06 is 318020-06, $FF80 = 2. This version seems to have been unreleased.
* EDITOR_C128 is the US version (318020-05), EDITOR_C128_DIN the German version (315078-03).
## BASIC_PET2001

Loading…
Cancel
Save