CBM 5/6/700 - Basic 4+ ROM Chart

CBM 5/6/700 - Basic 4+ ROM Chart

The ROM chart gives the addresses for the three ROM sets that I had in my possession in the 1980s. They were for the 500 and the 128K and 256K versions of the 6/700 - my 600 possessed the 128K version ROMs and I was later sent a dump of the 256K version. There were various other early versions of the 6/700 128/256K set which contained the coding for cassette operation plus countless bugs.

It is also possible that 64K and even 192K versions could have existed as the original source code could be compiled for these memory sizes (the 500 was originally specified as having only 64K). Of the three listed here, the 500 is the oldest and has several bugs - of the 6/700 ROMs the 256K appears slightly older as it has a couple of patches missing that appear in the 128K version. Note that all were in EPROM though the early versions for the 700 that allowed cassette operation were, I believe, made as mask-programmed ROMs.

Nowadays a quick search of the Internet will provide links to various other ROM sets. A good selection can be obtained from funet.fi.

500128K256KDescription
800080008000Cold Start entry point
800380038003Warm Start entry point
800680068006CBM8 in ASCII
POINTERS AND KEYWORDS
500128K256KDescription
800A800A----SPACE and then pointers to various ROM routines such as EVAL, New statement etc. (128K systems only)
80278027800AAddresses (-1) of END to NEW
806D806D8050Addresses (-1) of GO to PUDEF
80A380A38086Addresses of SGN to MID$
80D180D180B4Addresses (-1) and hierarchy of operators
80EF80EF80D2Table of keywords with last byte of each + 128
828F828F8272Pointers (addresses) of error messages at $82E7 onwards
82E782E782CCTable of error (and other) messages. 256K version has extra message OUT OF ARRAY SPACE
LINE INPUT AND BASIC PROCESSING
500128K256KDescription
855085508548?OUT OF MEMORY error
85558555854DIf TRAP is on then jump to TRAP routine else print error message (indicated by .X register) and then...
85AB85AB85A3Print IN plus line number and then...
85C085C085B8Print READY. and then...
85CA85CA85C2Await next entry (via RAM vector at $0282)
85F385F385EBProcess new BASIC line
869B869B8693Rechain BASIC and await next entry
86A486A4869CRechain BASIC subroutine
86E386E386DBInput line into BASIC buffer (160 characters maximum)
871F871F8717Find a line number (compare with $1B/C)
875187518749Process next BASIC statement (with STOP key check)
87638763875BMove to next BASIC line (with check for end of program)
877B877B8773Do end of line/statement checks
87A887A887A0Process BASIC keyword - if no keyword then assume LET
87D187D187C9Check for end of statement
87DB87DB87D3Check the stack for a FOR entry
88158815880DOpen up a space in memory (enter with carry clear for bank 1 else bank 2 (500 is bank 0 and bank 1 respectively)
88668866885CCheck space available on the stack
88778877886DCheck for overlap in variable memory
88A688A6887CGet the bank and pointer to a variable and then...
88A988A9887F...store in FOR/NEXT pointer area
88B088B08886Check memory in program bank (?OUT OF TEXT error if none left)
--------8895Check memory in array bank (256K only) and give OUT OF ARRAY SPACE error if none left
88BF88BF88A6Tokenise a BASIC line
893F893F8926Shift down contents of BASIC buffer by .Y bytes after each keyword has been tokenised
89578957893ETokenise a keyword into a single byte
PROCESS KEYWORDS
500128K256KDescription
898D898D8974LIST
89F189F189D8LIST vector jump via $0286
8A298A298A10NEW and then...
8A458A458A2CCLR and then...
8A728A728A5DReset RESTORE pointer and stack
8A908A908A7BTable of PUDEF default values (Space, comma, dot, dollar)
8A948A948A7FFOR
8AE78AE78AD2Check for STEP value
8B068B068AF1NEXT
8B798B798B64RESTORE
8B978B978B82Reset RESTORE pointer to the start of the program
8BA88BA88B93STOP entry
8BAA8BAA8B95END entry
8BAF8BAF8B9ABREAK entry
8BE98BE98BD4CONT
8C078C078BF2RUN
8C258C258C10GOSUB
8C428C428C2DIF
8C4F8C4F8C3ACheck for GOTO and THEN
8C688C688C53Check for ELSE
8C778C778C62Code for REM and ELSE to ignore the rest of the line
8C7C8C7C8C6AGO (checks for TO following) and then does...
8C848C848C6FGOTO
8CB88CB88CA3RETURN
8CDF8CDF8CCADATA when come across during normal execution (not via READ) and so ignores all characters up to either the next statement or line. This routine is also used as the final part of RETURN so that after the GOSUB pointers have been restored from the stack the TXTPTR is incremented past the actual GOSUB itself ready for the next statement or line
8CED8CED8CD8Search for next BASIC statement
8CF08CF08CDBSearch for next BASIC line
8D168D168D01TRAP
8D2B8D2B8D16ON
8D4E8D4E8D39Get line number from BASIC in $1B/C
8D888D888D73LET (default entry to $8D8A/8D8A/8D75 if no keyword found from process BASIC keyword routine)
8DC48DC48DAFRESUME
8DFF8DFF8DEARestore current line number and TXTPTR
8E248E248E0FDISPOSE
8E7A8E7A8E65PRINT# (does CMD and then PRINT)
8E808E808E6BCMD
8E978E978E82PRINT
8E9D8E9D8E88PRINT initial entry point
8EC88EC88EB3Print CRLF (part of PRINT)
8F158F158F00GET and GET#
8F4B8F4B8F36INPUT#
8F598F598F44Restore normal I/O
8F668F668F51INPUT
8FA88FA88F93Routine to get a line (from any device) into the input buffer
8FB58FB58FA0Move to next line during READ
8FEA8FEA8FD5READ (parts also used by GET and INPUT)
8FF18FF18FDCINPUT entry into READ routine
8FF38FF38FDEGET entry into READ routine
906B906B9056Get TXTPTR (then add carry flag) into .A/Y and bank number into .X
907790779062READ continued
90E790E790D2SYS (allows jumps to any bank 600/700 - bank 15 only on the 500 as this has a small routine missing compared to the 6/700 - it is a coincidence that the addresses for the 500 correspond to those of the 256K version from this point onwards until the BLOAD command)
90F4910990F4DIM
910191169101DEF
913191469131POKE
913D9152913DWAIT
916091759160Set bank for POKE, WAIT etc.
916A917F916AKEY (checks for following parameter and does assignment if it exists else prints all current definitions)
91A191B691A1Input a string expression from BASIC (such as KEY definition)
I/O AND DISK HANDLING KEYWORDS
500128K256KDescription
91A791BC91A7VERIFY
91B391C891B3LOAD
91B891CD91B8Does rechain BASIC and CLR after LOAD else flags errors into ST
91E491F991E4Common LOAD/VERIFY coding
9206921B9206SAVE
922E9243922EOPEN
9266927B9266Get filename parameters and then...
9269927E9269Clear channels and do OPEN
927292879272Get the current character (via CHRGOT) and check for end of line and, if not, then...
927C9291927CGet the next parameter as an integer into .X
928292979282CLOSE
928C92A1928CCATALOG and DIRECTORY
933B9350933BClear channels and then set output device
9346935B9346Open channel 14 to device 8 for disk commands
9358936D9358DOPEN (Note that all the disk commands use general parameter handling routines that start at B514/B540/B4A2)
9369937E9369APPEND
9379938E9379Check entered line and then look for an unused secondary address to use to send the command to the disk
939493A99394DCLOSE
93A893BD93A8Get device number in .A and close all open files on that device (via $FFE7 close all files call)
93AE93C393AEDSAVE
93B993CE93B9DLOAD
93C993DE93C9BANK
93D793EC93D7BSAVE
93F9940E93F9BLOAD. The coding for the 500 differs and appears to be of an older (possibly bugged) format - take care with this command!
941D94279412HEADER
945A9464944FSCRATCH
9494949E9489RECORD
9500950A94F5DCLEAR (this command is not mentioned in some manuals and is the equivalent to OPEN15,8,15,'I0' to initialise, not format, the disk in drive 0. Use DCLEAR D1 for drive 1)
9509951394FECOLLECT
9520952A9515COPY
953C95469531CONCAT
95489552953DRENAME
95569560954BBACKUP
95679578955CSet up DOS buffer and send DOS command
957B95859570Checksum byte ($19, $22 and $C0)
----95869571Clear DS and ST and then set output device (patch)
----958C9577Clear DS and ST and then set input device (patch)
----9592----Close files on device held in .A (patch)
957C9596957DUnused ROM area
MATHS HANDLING ROUTINES
500128K256KDescription
95AD95C195ACEvaluate expression (via vector at $028C)
963296469631Recursive entry for evaluate expression
964596599644Save the rounded value of FAC#1 on the stack
966E9682966DPull FAC#1 from stack
969A96AE9699Get number or variable from BASIC (also check for PI)
96A996BD96A8Check for PI (tokenised as $FF)
96B796CB96B6PI in floating point format
96DC96F096DBCheck for NOT
96F3970796F2Check for FN
96FA970E96F9Check for a valid function token
97109724970FEvaluate expression in brackets
9716972A9715Check for right bracket ')' else SYNTAX ERROR
9719972D9718Check for left bracket '(' else SYNTAX ERROR
971C9730971BCheck for comma else SYNTAX ERROR
971E9732971DCheck for character in .A else SYNTAX ERROR
973B974F973AError message SYNTAX ERROR
97409754973FGet the value of a variable
975A976E9759Check for TI$ and then DS$
9786979A9785Get DS$ from disk (if not already found)
978D97A1978CGet integer/floating point variable value
97A597B997A4Get floating point variable value
97B397C797B2Check for ST, ER, EL and DS variables
980D9821980CExecute functions via jump (JSR) to $0061
9857986B9856OR
985A986E9859AND
989498A89893Do comparisons (<, >, =, <=, >=, <>)
9918992C9917Get the name and pointer to a variable
99AB99BF99AACheck that .A holds 'A' to 'Z'
99B599C999B4Variable not found so if called from $9740/$9754/$973F then use dummy value of zero else...
99CA99DE99C9Set up variable (with checks for TI$, ST, ER, EL, DS and DS$). The coding for the 256K version is a lot smaller as there is no need for checks on the other variable boundaries as they are in the other banks
9AE19AF59A3BCalculate the pointer to an array body
9AF29B069A4CConvert a string to an integer value
9AFF9B139A59Convert a floating point value to an integer
9B149B289A6EGet the pointer to an array variable
9B909BA49AEABAD SUBSCRIPT error
9B939BA79AEDILLEGAL QTY error
9BB29BC69B0CSet .X to length of array element (length depends on array type)
9BBC9BD09B16Allocate array
9CB09CC49C0ACalculate the length for an array with a check for enough memory
9CE19CF59C3BFRE (return 0 for all except program or variable banks)
9CF49D089C4ECalculate free memory in bank 1 (500 bank 0)
--------9C5FCalculate free memory in bank 3
9D059D199C72Calculate free memory in bank 2 (500 bank 1)
--------9C85Calculate free memory in bank 4
9D1A9D299C95Set value to 0 (for all other banks for FRE)
9D1D9D2C9C98Print .A/Y as a value of 0 to 65535
9D249D339C9FPOS
9D289D379CA3Print value in .Y
9D2A9D399CA5Print .A/Y as value -32768 to 32767
9D309D3F9CABPut .A/Y into FAC#1 (ready for printing as a value)
9D3B9D4A9CB6Check for direct mode and, if so, do ILLEGAL DIRECT error
9D439D529CBEUNDEF'D FUNCTION error
9D489D579CC3Check for direct mode
9D4D9D5C9CC8Do FN functions
9D629D719CDDExpand FN call
9DF89E079D73PEEK
9E189E279D93Load .A/Y with the address of the floating point to integer conversion number
9E1E9E2D9D99Move memory to FAC#2 and then...
9E219E309D9CChange FAC#1 sign and do addition
9E2D9E3C9DA8Set .X/Y to the top of the program bank (-1) as a pointer to the BASIC input buffer
9E369E459DB1Do addition
9ECB9EDA9E46Zero FAC#1 exponent and sign
9ED29EE19E4DAdd FAC#2 to FAC#1 (result in FAC#1)
9EF19F199E6CShift FAC#1 right one bit
9F1B9F2A9E96Twos complement FAC#1
9F409F4F9EBBIncrement FAC#1 by one bit
9F4F9F5E9ECAOVERFLOW error
9F549F639ECFMultiply
9F8D9F9C9F08Table of floating point values (1 and LOG constants)
9FBB9FCA9F36LOG
9FF9A0089F74Continue multiplication
A04DA05C9FC8Move memory (pointer is $22/3) to FAC#2
A07FA08E9FFAMultiply exponents overflow check
A09CA0ABA017Handle under/overflow
A0AAA0B9A025Multiply FAC#1 by 10
A0C1A0D0A03CValue 10 in floating point format
A0C6A0D5A041Divide FAC#1 by 10
A0CFA0DEA04ADivide FAC#2 by memory (pointer is $22/3)
A0D7A0E6A052Division
A139A148A0B4DIVISION BY ZERO error
A14BA15AA0C6Move $28-B (multiply area) into FAC#1
A157A166A0D2Move memory (pointer $22/3) to FAC#1
A182A191A0FDMove FAC#1 to memory (variable bank)
A1C4A1D3A13FMove FAC#2 to FAC#1
A1D4A1E3A14FRound FAC#1 and then move it to FAC#2
A1E3A1F2A15ERound FAC#1
A1F3A202A16EFind sign of FAC#1
A201A210A17CSGN
A220A22FA19BABS
A223A232A19ECompare FAC#1 to memory (bank 15 - pointer is $25/6)
A269A278A1E4Get a byte from bank 15 (pointer is $25/6)
A271A280A1ECConvert FAC#1 to integer
A2A2A2B1A21DINT
A2C9A2D8A244Convert an ASCII string to a number in FAC#1
A340A34FA2BBAdd the next ASCII numeral to FAC#1 mantissa
A354A363A2CFAdd .A to FAC#1
A396A3A5A311Table of string conversion constants
A3A5A3B4A320Print .A/X as a number (0 - 65535) - usually a line number
A3B4A3C3A32FPrint error message (.X is index to error type)
A3D3A3E2A34EConvert FAC#1 to an ASCII string at $0200
A4FEA50DA479Second table of string constants
A528A537A4A3SQR
A532A541A4ADDo power '^'
A576A585A4F1LOG Constants table
A5A4A5B3A51FEXP
A5F6A605A571SIN/ATN function evaluation
A60CA61BA587SIN/COS/LOG function evaluation
A642A651A5BDRND constants table
A64AA659A5C5RND
A697A6A6A612COS
A69EA6ADA619SIN
A6E9A6F8A664TAN
A713A722A68EDo Cosine of FAC#1
A717A726A692SIN/COS/TAN constants table
A745A754A6C0ATN constants table
A782A791A6FDATN
STRING HANDLING ROUTINES
500128K256KDescription
A7B1A7C0A72CPUDEF
A7CCA7DBA747STR$
A7F6A805A771Allocate area for string
A810A81FA78BGet the descriptor of a string into FAC#1 and set up string in memory
A85DA86CA7D8Save string descriptor to descriptor stack
A89CA8ABA817Store string in high RAM in string Bank
A8D7A8E6A852De-allocate temporary string if possible from the given descriptor
A921A930A89CSet up descriptor values from string pointed to by $22/3
A940A94FA8BBIf descriptor pointer is at the top of the descriptor stack then remove it.
A964A973A8DFAssign string to a variable (with check for Bank 15 in which case we are trying to assign TI$)
A96DA97CA8E8Assign normal string to a variable (coding is simpler in 256K version)
A9AEA9BDA91FCopy a string (from the program into the string Bank)
A9EDA9FCA95ESet the pointer at the end of the actual string back to the descriptor area
AA03AA12A974Check if there is an old value of the string and mark it as garbage if so
AA24AA33A998Return the descriptor values of a string (if DS$ or string has a length of zero then do nothing)
AA5DAA6CA9CESet up the index for a descriptor (get pointer and bank no. into $22-4)
AA6BAA7AA9DCConcatenate two strings
AAB9AAC8AA2ADe-allocate temp string
AAC2AAD1AA33CHR$
AADCAAEBAA4DLEFT$
AB09AB18AA7AAdd .A to text pointer
AB13AB22AA84RIGHT$
AB33AB42AAA4MID$
AB7FAB8EAAF0LEN
AB85AB94AAF6Get 8-bit value for LEN
AB8EAB9DAAFFASC. This routine has an annoying feature in that it returns an ILLEGAL QTY error instead of 0 for a null string. This was fixed on the later C128 OS as Commodore Guru Jim Butterfield complained several times about it! The fix is easy for those with EPROM programmers - change the branch in the second instruction of the routine from F0 09 to F0 06 (a BEQ to the previous JMP)
AB9FABAEAB10VAL
ABE4ABF3AB55Restore TXTPTR (values saved in $82-4)
ABF1AC00AB62ERR$
AC4DAC5CABBEPut 6526 clock value into TI$
ACC7ACD6AC38Put TI$ into 6526 clock registers (500 code differs)
AD20AD3DAC9FPacking subroutine for TI$ to 6526 regs.
GARBAGE COLLECTION ROUTINES
500128K256KDescription
AD36AD53ACB5Allocate .A bytes for a string (and may force a Garbage collection if space is low)
AD8EADA5AD07Do Garbage collection or OUT OF MEMORY error depending on space available
AD9BADB5AD17Do Garbage collection (again the 500 code differs significantly from that of the later 128K/256K 6/700 - there is a complete piece of code added in the 6/700 which includes setting the correct bank and suggests that the 500 could get into difficulties when it runs out of string space)
AE08AE43ADA5Skip over a string
AE1BAE56ADB8Check for top of strings else set up pointers for a string movement (i.e. move valid strings over old defunct strings in order to clear out old strings)
----AE85ADE7Mark temporary strings as garbage
----AEAFAE11Set pointer to string back pointer (the back pointer is located at the end of each string in high RAM which points back to the variable name in low RAM)
AE4A--------The 500 combines the two previous routines into one with completely different coding
AE9CAEC8AE2AAdd .A to garbage pointer at $5B
AEABAED7AE39Add .A to garbage pointer at $6D
INSTR & DELETE
500128K256KDescription
AEBDAEE9AE4BINSTR
AF71AF9DAEFFDELETE (There is a small bug at the end of DELETE which returns the system to the wrong point afterwards without giving the READY message - it doesn't affect the DELETE operation itself)
AFC8AFF4AF56Get parameters for LIST/DELETE
PRINT USING + ASSOCIATED ROUTINES
500128K256KDescription
AFFAB026AF88USING
B082B0AEB010Check for comma and semicolon (exit USING routines if semicolon)
B0BBB0E7B049Output a number to format
B0F3B11FB081Handle 'E' exponent
B155B181B0E3If no exponent then adjust decimal point. Also check if room for output and if not then print asterisks instead
B1ADB1D9B13BAdd extra 0 before decimal point if less than 1
B1BDB1E9B14BShift decimal point and adjust exponent
B1E2B20EB170Add leading zeroes if necessary
B202B22EB190Adjust exponent subroutine
B20EB23AB19CCheck for overflow
B229B255B1B7Check for underflow
B240B26CB1CEReverse the sign of the exponent
B253B27FB1E1Get a digit from the exponent and set carry flag if overflow (checks for a '9')
B279B2A5B207Initialise the counters and flags
B294B2C0B222Round a number (checks digit to be chopped off for whether it is '5'. If lower then rounds down)
B2C4B2F0B252Add 1 for rounding
B2D6B302B264Delete leading zeroes
B2F7B323B285Check for end of number reached
B30CB338B29ACheck for dollar and comma flags and make room if dollar flag set, add a comma if comma flag set.
B333B35FB2C1Check if decimal point required
B33DB369B2CBPrint leading zeroes and dollar (or whatever has been set by PUDEF)
B352B37EB2E0Check for USING symbols +, - and ^, and output sign if needed
B38CB3B8B31APrint '-' if negative else print blank (or '*' if number will not fit)
B397B3C3B325Print blanks (or '*') plus a sign if needed
B3B7B3E3B345Output a character and decrement the count of available character spaces left
B3BEB3EAB34CGet next format character and print next printable character
B41CB448B3AAIf dollar found in format then set dollar flag
B42FB45BB3BDIf 4 up arrows (^) found then set exponent flag
B449B475B3D7If '+' found then set sign flag
B466B492B3F4If '-' found then set sign flag
B472B49EB400Compare .A with USINGs special characters (+, -, ., =, > and #)
GENERAL BASIC ROUTINES
500128K256KDescription
B48CB4B8B41AReset TXTPTR to start of BASIC and set Bank to 1 (0 in 500)
B49EB4CAB42CGet a positive integer
B4A7B4D3B435Get integer from BASIC into .X
B4B9B4E5B447Get 16-bit value from BASIC into .A/Y and $1B/C
B4D2B4FEB460ILLEGAL QTY Error (USR vector is set up by transferring this JMP into location 2, bank 15)
B4D5B501B463Get and evaluate expression from BASIC
B4E4B510B472TYPE MISMATCH error
B4E9B515B477Print string ($22/3 points to it - Bank in $24)
B4FFB52BB48DSet to Bank 1 (500 = Bank 0)
B502B52EB490Print CRSR Right or SPACE if keyboard is input file
B506B532B494Print a SPACE
B509B535B497Print cursor right
B50CB538B49APrint a '?'
GENERAL DISK ROUTINES
500128K256KDescription
B514B540B4A2DOS table containing 4 bytes set to $FF and then the default disk channel, device and secondary address ($0E $08 and $6F - 500 has first two bytes set to 02 and 00)
B51BB547B4A9Set up DOS area
B546B572B4D4Check disk syntax bytes
B554B580B4E2Get disk primary parameters (#, W, L or R)
B56AB596B4F8Process ON in disk command
B570B59CB4FEProcess U device parameter
B575B5A1B503Process B Bank parameter
B57AB5A6B508Check for D, ON, B, U, P and I parameters
B594B5C0B522Get file number after #
B5AAB5D65538DOPEN parameters L and W
B5D6B602B564Check D drive parameter
B5EFB61BB57DCheck for ID already got
B5F6B622B584Process P address parameters
B61EB64AB5ACGet ID
B635B661B5C3Process first file name or parameter in brackets
B66EB69AB5FCProcess secondary parameters
B6A5B6D1B633Get second D drive number
B6BEB6EAB64CGet U device (via $B6FF/B72B/B68D)
B6C3B6EFB651Process second file name or parameter in brackets
B6E1B70DB66FMore secondary parameters check
B6F2B71EB680Handle U or B after ON
B6FFB72BB68DMain routine to get U device number
B710B73CB69EMain routine to get B Bank number
B72BB757B6B9Main routine to get file name with check for @ (Save-with-replace flag)
B759B785B6E7STRING TOO LONG error
B75EB78AB6ECGet integer value into .X (possibly inside brackets)
B771B79DB6FFGet address into .A/Y (possibly inside brackets)
B789B7B5B717Check first disk syntax byte - if error then SYNTAX ERROR
B78EB7BAB71CCheck second disk syntax byte - if error then SYNTAX ERROR
B793B7BFB721DISK command parameter checking table
B7DFB80BB76DPut parameters in DOS buffer
B83EB86AB7CCSet pointer to DOS buffer at $0226, Bank 15
B851B87DB7DFPut RECORD number in DOS buffer
B856B882B7E4Check if @ (Save-with-replace) wanted
B860B88CB7EEPut ID in DOS buffer
B86CB898B7FADefault to SEQuEntial if L record parameter not present
B875B8A1B803Set SEQuential and W write flags in buffer
B87EB8AAB80CPut address in buffer
B888B8B4B816Put first filename in DOS buffer
B89CB8C8B82APut second filename in buffer
B8C7B8F3B855Check parameters set up correctly for HEADER, DLOAD and SCRATCH
B8CEB8FAB85CCheck for filename set up for DSAVE
B8D9B905B867Check COLLECT parameters set up
B8DEB90AB86ECheck parameters set up for COPY, CONCAT and
B8E4B910B872....RENAME
B8EDB919B87BCheck DOPEN, APPEND parameters
B8F6B922B884Send command in buffer to disk and check returned disk error channel
B92FB95BB8BDARE YOU SURE? checks for YES or just Y
B968B994B8F6Clear DS and ST
B970B99CB8FEGet filename pointer and Bank for LOAD, SAVE etc.
B986B9B2B914Check parameters for LOAD, SAVE and VERIFY
B9CDB9F9B95BGet filename
CHRGET AND BANK ROUTINES
500128K256KDescription
B9D5BA01B963Check for comma and then get next character
B9E0BA0CB96ECheck if variable is in BASIC (exits with carry set if variable is from Bank 15)
B9F2BA1EB980Convert floating point to integer (result in .A/Y)
B9FABA26B988CHRGET routine entry - get next character from BASIC. This is via a RAM vector at $0290.
B9FDBA29B98BCHRGOT routine entry - reget current character from BASIC - via RAM vector at $028E.
BA00BA2CB98EActual CHRGOT routine.
BA06BA32B997Actual CHRGET routine. Unlike earlier machines, CHRGxT is all in ROM apart from the actual pointer into the BASIC program. The PET/Vic/64 transferred the entire routine from ROM into RAM (zero page).
BA24BA50B9B2Routine used by CHRGET to set Z and C flags depending on character input. Z is set if character is either a colon ($3A) or end of line ($00). C is clear when the character is numeric (0-9)
BA2EBA5AB9BCSet text Bank (1 in 6/700, 0 in 500)
BA38BA64B9C6ORA with byte in set bank (using pointer in $22/3)
BA3DBA69B9CBSet to bank ($73)
BA42BA6EB9D0Set to bank ($60)
BA47BA73B9D5Set to bank ($24)
BA4CBA78B9DASet to bank 15
BA51BA7DB9DFSet to string bank
BA56BA82B9E4Set to array bank
BA5BBA87B9E9Set to variable bank
BA60BA8CB9EESet to text bank
BA67BA93B9F5Set up buffer areas in various banks (for RND, Input, DS etc.) when BASIC is initialised
BAF5BB21BA83Table of RNDs initial seed
BAFBBB27BA89BASIC Cold Start routine. Set up vectors, call buffer set up routine, print power up message and reset start up vector so that when reset button pressed it now points to warm start instead.
BB55BB81BAEEPower up message in ASCII
BB7ABBA6BB13Table of vectors for $0280 onwards
BB90BBBCBB29Set up vectors at $0280
BB9CBBC8BB35LDA $FFFF/RTS routine. This is transferred to $025A on power up and used by various routines. The $FFFF address is changed to suit the routine
BBA0BBCCBB39BASIC Warm start. Resets I/O, clears screen and then jumps to READY.
BBB1BBDDBB4ASet ST error with contents of .A
BBB5BBE1BB4EDo OPEN (via $FFC0) and check for error
BBBCBBE8BB55Do GETCHR (via $FFE4) and check for error
BBC2BBEEBB5BDo I/P CHR (via $FFCF) and check for error
BBC8BBF4BB61Do O/P CHR (via $FFD2) and check for error
BBCEBBFABB67Set input device (via $FFC6) and check for error
BBD4BC00BB6DSet output device (via $FFC9) and check for error
BBDABC06BB73Do LOAD (via $FFD5) and check for error
BBE0BC0CBB79Do SAVE (via $FFD8) and check for error
BBE6BC12BB7FDo CLOSE (via $FFC3)
BBEABC16BB83Do CLOSE ALL FILES (via $FFE7)
BBEEBC1ABB87Error handling routine for above calls - closes the open file and then prints the error message indicated in .A
----BC28BB95Checksum byte ($B5 in 128K, $CE in 256K)
BBFCBC29BB96Empty space (values of $FF) from here to the end of the BASIC ROM ($BFFF) in 128K/256K - to $BFFE in the 500
BFFF--------500 checksum byte (value $6B)
RESET MONITOR ENTRY
500128K256KDescription
E000E000E000Reset entry points here when BASIC ROM not installed (jumps into monitor instead)
SCREEN EDITOR JUMP TABLE
500128K256KDescription
E004E004E004Initialise screen and keyboard
E007E007E007Get a character from the keyboard (or function key definition if f-key has been pressed)
E00AE00AE00AInput from screen
E00DE00DE00DPrint a character to the screen
E010E010E010Return screen size into .X (columns) and .Y (rows)
E013E013E013IRQ entry to flash the cursor (500 only) and then scan the keyboard
E016E016E016Set the cursor position in the video chip (6/700 only - 500 points to RTS)
E019E019E019Read/Set screen x/y co-ordinates
E01CE01CE01CSet .X/Y to start of I/O area ($DC00)
E01FE01FE01FDo ESC function (on entry .A should hold 'A' to 'Z' in ASCII)
E022E022E022Print/set function keys
SCREEN EDITOR
500128K256KDescription
E025E025E025Read/Set screen x/y co-ordinates (Carry clear upon entry to set co-ords)
E03AE03AE03ASet .X/Y to start of I/O area ($DC00)
E03FE03FE03FSet .X/Y to screen size (.X = columns, .Y = rows)
E044E044E044Initialise the screen and keyboard
E0C5E0B3E0B3Clear the screen and then...
E0D3E0C1E0C1Home the cursor and then...
E0DFE0CDE0CDSet the screen line address
----E0DAE0DASet the cursor position in the VDC chip
E0F4E0FEE0FEGet a character from either the keyboard buffer or a function key definition
E0F8E102E102Get a character from a function key definition
E10AE114E114Get a character from the keyboard buffer
E11FE129E129Await screen entry. Echoes each character typed into the keyboard onto the screen until RETURN is pressed
E174E179E179Input from screen main routine
E1B9E1BEE1BECheck if character entered is PI and convert it from $DE to $FF
E1C8E1CDE1CDCheck for quotes character and swap quote flag if so (unless there are inserts outstanding - 6/700 only)
E1D5E1DEE1DESet bit 7 of character if RVS flag on
E1E2E1EBE1EBCheck for Auto-Insert flag on (ESC A) and if so then insert a space first and then...
E1F0E1F9E1F9Output the character to the screen and then...
----E1FCE1FCCheck if on the 70th column of the screen and ring the bell if so (and the bell flag has not been turned off) and then...
E1F6E206E206Exit from screen print routine
E207E21AE21ALoad .A with a space and then...
E207E21CE21CPOKE .A onto the screen at the current position - 500 also sets the corresponding colour memory byte
E224E227E227Clear a screen line
E23FE242E242Read the character at the current position into .A - 500 also reads the colour at the current position
E251E24DE24DSet text/graphic mode (enter with carry clear for text mode)
----E260E260Set up the 6845 VDC chip. There are three possible set ups, a 700 with a built in monitor screen and 14 by 9 pixel character ROM, and either a 50Hz or 60Hz setting for the 6/700 using an external monitor. Bit 7 of $DF02 is set for an internal screen and bit 6 is set when the system is on 60Hz. Each set up has its own table of values to be sent to the VDC
----E27DE27DSet to bank 15 for text screen
E267E282E282Set to new bank saving the original bank setting and preserving .A
E26E--------Set to text screen bank (this is usually bank 15 but can be altered to use bank 0)
E27CE291E291Restore original bank
E284E299E299Print a character to the screen (main routine)
E2C5E2B4E2B4Check if last character was an ESC and jump to ESC routine if so
E2D2E2C1E2C1Convert ASCII to screen value
E2E0E2CFE2CFCheck for control codes (RETURN, INSERT etc.)
E317E306E306Jump to control code function (pushes address-1 onto the stack and then does a RTS to get to it)
E322E311E311Vector for extra control code functions (via $0322)
E325E314E314Handle cursor up/down
E327E316E316Cursor down
E334E323E323Cursor up
E342E331E331Handle cursor left/right
E344E333E333Cursor right
E34AE339E339Cursor left
E355E344E344Swap the RVS flag (does EOR #$80 so there could be a possibility that it may accidently swap it the wrong way - the C128 sets or clears it as two separate options)
E35BE34AE34AHandle CLR/HOME
E360E34FE34FCheck for two HOME keys and, if so, then resets the screen window to full size
E36BE35AE35AHandle the TAB key
E36FE35EE35EMove to next TAB position or to end of screen line if no more positions set
E381E370E370Set or clear a TAB at the current cursor position
E38BE37AE37ACheck if a screen scroll is needed and scroll if so (unless scrolling has been turned off in which case move cursor to the top line in the current window)
E3A5E394E394Handle RETURN and then...
E772E3A2E3A2Cancel quotes, inserts and RVS flags (ESC O comes here) - the 500 has this routine out of sequence compared to the 6/700
E3B6E3B4E3B4Move a screen line
E3DFE3CDE3CDRoutine used by reverse scrolling and insert a blank line (ESC I) to move part or all of the current window down a line
E408E3F6E3F6Scroll the current window
E43FE42DE42DScreen scroll subroutine and then...
E459E447E447Check if CTRL key held down and do a short delay (slows screen scroll) and then...
E479E45FE45FCheck if CBM key held down (halts screen scroll)
E49AE480E480Check if key pressed subroutine
E675E48DE48DRing the bell (CTRL-G) - 500 is out of sequence here
E6A3E4BAE4BAHandle the CE key. Delete either one alpha character or all numeric (including +,-,E and .) characters until a non numeric character is found - 500 is out of sequence here
E4A6E4F5E4F5Get a bit from the screen wrap table (if zero then carry is cleared)
E4B2E501E501Set a bit in the screen wrap table according to carry flag
E4CFE51EE51EGet bit position subroutine
E4E3E532E532Move to the start of the line (ESC J). If this is a wrapped line (i.e. the second screen line of a BASIC line that starts on the previous screen line) then move back until the start of a non-wrapped line
E4F7E544E544Move to the last non-space character on the line (ESC K). Note that ESC K was changed slightly on the C128 in that the cursor is positioned one character past the last character on the line (the C16 & Plus/4 are the same as the 5/6/700)
E521E574E574Cursor right subroutine - move to the next character (on the next line if at the end of the current screen line)
E534E587E587Cursor left subroutine - move back to the previous character (on the previous line if at the start of a screen line)
E552E5A5E5A5Save current screen row and column into temporary store
E55BE5AEE5AEHandle INST/DEL
E55DE5B0E5B0Delete a character
E591E5E4E5E4Insert a space
E5C9E61CE61CHandle CHR$(131) (Shift RUN/STOP). Put 'dL"* + run' into the keyboard buffer
E5DBE62EE62EMove to next character position. Insert a blank line if the end of the line has been reached and the next line isn't part of the current wrap
E602--------Set the current text colour
E612--------Store a value in the VIC chip. Some values are checked or ANDed with $0F
E632--------Table of masks for values sent to Vic chip
E641--------Subroutine to store a value onto the screen. It can handle the screen in either bank 0 or bank 15. This loops until it is sure that the value is stable on the screen and is one reason for the very slow screen update - the following routine has similar coding
E650--------Subroutine to store a value in the colour memory in bank 15
E669--------Vector jump (via $03BB). This is used to intercept normal print characters on their way to the screen - normally points to a RTS so that no action is taken
E66C--------Vector jump (via $03BD). This used to intercept the screen/keyboard IRQ routine and normally points to a RTS
E675--------Ring the bell (see E48D in the 128K sequence)
E6A3--------Handle the CE key (see E4BA in the 128K sequence)
E6DEE655E655Vector for function keys (via $0320)
E6E1E658E658Insert a blank line (ESC I points here)
E6F6E66DE66DDelete a line (ESC D)
E71F--------Handle erase to start/end of line (common entry point 500 only)
E727E694E694Erase characters up to the end of the current screen wrap (ESC Q)
E739E6A9E6A9Erase characters from current cursor position back to the start of the current screen wrap (ESC P)
E74A--------Handle scroll up/down (common entry point - 500 only)
E752E6BDE6BDScroll up (ESC V)
E75DE6CBE6CBScroll down (ESC W)
E772--------ESC O turn off various flags (see E3A2 in the 128K sequence)
E77FE6E3E6E3Enable scrolling (ESC L)
E782E6E5E6E5Disable scrolling (ESC M)
E78A--------Turn off Auto Insert mode (never called)
E78D--------Turn on Auto Insert mode (never called). These two routines are not used at all, the ones that are used are located at EAA8/EAAB
E795E6EDE6EDDisable logical scrolling
E798E6F0E6F0Enable logical scrolling. This and the above routine are never actually called via any CTRL or ESC key presses and the flag really has to be POKEd to change the setting. When bit 7 is set then a complete set of wrapped screen lines will disappear off the top of the screen when the first is scrolled off. When cleared then the wrapped bits are ignored and a set of wrapped lines will disappear one by one with a scroll needed for each one. The flag is temporarily set by the ESC D routine so that it always deletes a complete set of screen wrapped lines
E7A0--------Routine called by CTRL-F. Purpose unknown at the time of writing
E7A9E6F8E6F8Either print the current function key definitions (if .Y is either 0 or >126) else set up a new definition for function key .Y
E7AFE6FFE6FFPrint function key definitions (there are several bugs in this routine - all of which were removed for the Plus/4 and C128 - where strange things happen if the first character is a quote plus the ESC character is never printed if it is part of the definition. The 500 version doesn't recognise the shifted return CHR$(141) either
E83CE781E781Subroutine to print either 'KEY' or '+CHR$(' and a number
E856E7A6E7A6KEY and various CHR$ values for printing the function definitions (held as ASCII but all in reverse)
E86CE7BEE7BESet up a new function key definition
E90C--------IRQ entry (500). Flash the cursor and then...
E933E865E865IRQ entry (6/700). Set up the keyboard ready to be scanned and, if a key is pressed then...
E949E87EE87ESet .Y to an index into the keyboard tables depending on the key pressed and then...
E974E8A9E8A9Store the .Y index and, depending on the state of the CTRL and Shift keys (and whether the machine is in graphic or text mode AND the shift key is pressed) then get the final actual key value from one of four keyboard tables
E995E8C9E8C9Check for a function key (any value >=$E0) and set up a pointer to its definition
E9B1E8E5E8E5Check for the '00' key and store '0' twice in the keyboard buffer
E9CEE902E902Handle key repeats
E9EAE91EE91ESubroutine to get a debounced key value
E9F3E927E927Function key IRQ routine vector (via $03B5) to set the pointer to the specified function key definition and set its length in $D6
EA15E949E949Set .A/X to the start of the specified function key definition
EA26E95AE95AGet a TAB bit position subroutine
EA3CE970E970Do an ESC function (.A must be set to 'A' to 'Z' else the routine exits)
EA51E985E985Table of ESC addresses (-1)
EA85E9B9E9B9Do ESC T - set window top
EA87E9BBE9BBDo ESC B - set window bottom
EA93E9C7E9C7Set the window to full screen size (used by 2 x HOME as well as initialisation)
EAA2E9D6E9D6Bell on (ESC G)
EAA4E9D8E9D8Bell off (ESC H) provided .A holds a non-zero value upon entry
----E9DCE9DCSet underline cursor mode (ESC U)
----E9E6E9E6Set flashing cursor mode (ESC F)
----E9ECE9ECSet solid block cursor mode (ESC S)
----E9EFE9EFSet non-flashing cursor mode (ESC E)
----E9F6E9F6Reverse screen on (ESC R)
----E9F9E9F9Set to alternative character set (ESC Z)
----EA05EA05Set to normal (un-reversed) screen (ESC N)
----EA08EA08Set to normal character set (ESC Y)
EAA8EA20EA20Auto insert mode off (ESC C)
EAABEA23EA23Auto insert mode on (ESC A)
EAB1EA29EA29Normal keyboard table (no Shift or CTRL keys pressed)
EB11EA89EA89Shifted keyboard table (text mode only)
EB71EAE9EAE9Shifted keyboard table (graphic mode only)
EBD1EB49EB49CTRL keyboard table
EC31EBA9EBA9'dL"* + run' in ASCII
EC3AEBB2EBB2Screen line address table (lo)
EC53EBCBEBCBScreen line address table (hi)
EC6CEBE4EBE4Addresses (-1) of CTRL and cursor functions
ECACEC24EC24Function key lengths for...
ECB6EC2EEC2EInitial function key definitions
ECEFEC67EC67Bit table
----EC6FEC6FVDC table for 700 with built in monitor
----EC81EC81VDC table for 60Hz system
----EC93EC93VDC table for 50Hz system
ECF7--------Table of VIC chip initial values
ED08--------Table of vectors for $03B5 to $03BE
ED12--------Table of ASCII colour keyboard codes
ED22ECA5ECA5Screen editor checksum byte
ED23ECA6ECA6Unused ROM area
----ED00ED00Patch to pull return address if the window bottom and top lines are the same
MONITOR
500128K256KDescription
EE00EE00EE00Monitor startup entry point (resets all I/O)
EE09EE09EE09Monitor entry point when BASIC not installed
EE21EE21EE21Break monitor entry point
EE29EE29EE29Pull registers from stack and store in zero page. Also save a copy of IRQ vector, bank number and stack pointer for register display
EE4CEE4CEE4CLoad .A with 'R' in order to register display command
EE50EE50EE50Print ? for monitor errors and then...
EE55EE55EE55Normal return point after each command and then...
EE69EE69EE69Await next command. The 500 only checks for a space to see if a command has been entered as it doesn't print a '.' on each line
EE70EE74EE74Do entered command (via RAM vector at $031E)
EE7FEE83EE83Check command against table and, when found, jump to it
EE94EE98EE98Loop for next command in table. If not found then store command in buffer and assume its a filename and try loading it from the specified device (default 8)
EED1EED5EED5Table of monitor commands and addresses. Each single byte command is followed by the appropriate two byte address
EEF5EEF9EEF9Do the X command and jump back to (normally) BASIC via RAM vector at $03F8
EEFBEEFFEEFFSave address bytes in reversed format in PC address area
EF04EF08EF08Set up to print registers from $B0 onwards
EF13EF17EF17Print CR and '.', then character in .A finally a space (500 misses the '.')
----EF27EF27Subroutine to print CR and '.'
EF26EF31EF31Headings for register display
EF41EF4CEF4CR command - print registers
EF67EF72EF72Common routine to print .Y bytes starting at ($B9) used by the R and M commands
EF84EF8FEF8FM command to display a memory dump
EFC5EFCBEFCB; command to read new register values. The 500 has an extra error check at the start of this and the next few routines which accounts for the slightly longer length of each - the 6/700 handle these checks at $F03A/F040
EFDFEFE1EFE1V command to View a different bank
EFEBEFEBEFEBU command alters the default device number
EFF7EFF5EFF5: command to read new values for memory dump
EFFEEFFAEFFACommon routine reads .A bytes for M and R commands
F014F010F010G command jumps to machine code routine (bank 15 only)
----F03AF03AGet a two character hex byte into .A with an error check to see if it is valid
----F040F040Get a four character hex address into $B9/A
F043F04AF04ADo L and S commands. Sets up default I/O (device set to tape!), gets filename, device number, optional load address/start save address and end address. Again the 500 version is slightly longer as it does its own error checking on the addresses instead of using $F03A/F040
F0F9F0F6F0F6Print .X/Y as hex address
F116F113F113Swap $B9/A and $BB/C. Used when two addresses entered for M command to store one safely while the other is entered
F126F123F123Get a hex address into $B9/A
F133F130F130Get two hex characters into .A
F157F154F154Convert ASCII hex character to $0-$F
F162F15FF15FGet a character and check if its a CR
F168F165F165Do @ command to send a disk command to the current device (set by the U command)
F18BF188F188Send disk command
F19DF19AF19AReturn disk status
KERNAL MESSAGES
500128K256KDescription
F1CAF1C3F1C3Table of (error) messages
F223F21CF21CPrint message from above table - .Y must be pointing to the first character of the wanted message
IEEE HANDLING
500128K256KDescription
F237F230F230Send IEEE Talk
F23BF234F234Send IEEE Listen
F23EF236F236Send byte in .A to IEEE
F27BF274F274Send secondary address after Listen
F287F280F280Send secondary address after Talk
F29EF297F297Send deferred byte to IEEE
F2B2F2ABF2ABSend IEEE Untalk (from $FFAB Kernal call)
F2B6F2AFF2AFSend IEEE Unlisten
F2C0F2B9F2B9Subroutine to send byte on IEEE and check for device not present (timeout check)
F311F30AF30AInput a byte on IEEE with timeout checks
F376F36FF36FSet timer for 65mS (values differ between 1MHz 500 and the 2MHz 6/700)
RS232 HANDLING
500128K256KDescription
F388F381F381Open an RS232 channel. Sets 6551 from the first two control characters (the 3rd and 4th, if they exist, are ignored). Also sets up RS232 input buffer if this is the first time it has been accessed
F3CEF3C7F3C7Converts proper ASCII to Commodore ASCII (sometimes called PETSCII as the first implementation of Commodore ASCII was on the PET)
F3E3F3DCF3DCPETSCII to ASCII
F3F8F3F1F3F1Turn on transmitter (but no interrupts)
F403F3FCF3FCSet up registers for creating the RS232 input buffer and then...
F407F400F400Allocate a buffer. The size of the allocation is held in the .X/Y registers (.Y is the high byte). This routine has not been completely implemented as .A should indicate the type of set wanted (in high memory, low memory etc) but it is ignored and discarded
F435F42EF42EReset the RS232 DCD and DSR status
GENERAL I/O
500128K256KDescription
F444F43DF43DGet a byte (from $FFE4 Kernal call). If not keyboard or RS232 then does Input Byte (via $FFCF)
F45BF454F454Get a byte from RS232
F4A3F49CF49CInput a byte (from $FFCF Kernal call)
F4D7F4D0F4D0Input a byte from RS232
F4F5F4EEF4EEOutput a byte (from $FFD2 Kernal call)
F518F511F511Output a byte to RS232
F550F549F549Set the current Input device (from $FFC6 Kernal call)
F569F562F562Set RS232 as the Input device
F591F58AF58ASet the IEEE Input device (send Talk and secondary address, and then check ST)
F5AAF5A3F5A3Set the current Output device (from $FFC9 Kernal call)
F5C6F5BFF5BFSet RS232 as the Output device
F5DCF5D5F5D5Set the IEEE Input device (send Listen and secondary address, and then check ST)
F5F4F5EDF5EDClose a file (from $FFC3 Kernal call). Check that it is actually open first
F621F61AF61ASend Close on IEEE and then...
F624F61DF61DRemove file entry from tables
F645F63EF63ECheck for file open
F657F650F650Get file parameters from file tables and set up as current file (.X must be set up as the index into the file tables upon entry)
F667F660F660Find the file parameters (put into .A/X/Y). .Y must be set to the required secondary address upon entry
F67FF678F678Check if file (in .A) is open and, if it is, then set up file parameters
F686F67FF67FClose all files. This routine was improved over the PET which used to abort the files - e.g. would leave the disk unit thinking a file was still open while the PET considered it closed)
F6C6F6BFF6BFOpen a file (from $FFC0 Kernal call). If carry set then jump to Transmit (see below) else checks to see if file is already open and gives an error if so, otherwise...
F6D5F6CEF6CECheck if 10 files already open and, if less, then...
F6DFF6D8F6D8Store new file parameters in the file table (adds file number, device number and secondary address)
F70EF707F707Do IEEE Open (send Listen plus secondary address and then checks ST for any errors)
F72BF724F724Send the filename to the IEEE (if there is one)
F741F73AF73ATransmit command (Open jumps here if carry is set). This routine only appears on the 5/6/700, neither the earlier or later machines have it. All it does is send a listen and a secondary address. It assumes that all relevant file parameters have already been set up.
F74DF746F746LOAD entry from $FFD5 Kernal call (this also handles verify)
F764F75DF75DTrap LOADs from tape and RS232 (give DEVICE NOT PRESENT) and screen/keyboard give ILLEGAL DEVICE NUMBER
F76DF766F766Do IEEE load. First check file name is present (if not then give an error)
F7C1F7BAF7BAMain loop to input characters for IEEE load/verify. There is a check to make sure that locations 0 and 1 of any bank are NOT loaded with anything so that loading goes from $FFFF on one bank to $0002 on the next - SAVE is handled in a similar fashion. Depending on the load/verify flag each byte is either stored or compared. There appears to be a strange instruction that reads LDA $9691 (or AD 91 96) which is really the store instruction when entered at the second byte in (91 96 = STA ($96),Y)
F81AF813F813Exit from load with the .A holding the bank and .X/Y holding the final address of the load so that, if required, the end address may be set (for BASIC)
F822F81BF81BPrint 'SEARCHING' and optionally 'FOR' and the filename
F847F840F840Print either 'LOADING' or 'VERIFYING' depending on the Load/Verify flag
F853F84CF84CSAVE entry (from $FFD8 Kernal call). This must be entered with .X as an index to the first of three zero page bytes holding the address and bank of the start address and .Y as a similar index to the end address
F87AF873F873Do IEEE save (checks for filename, writes start address and loops to send each character)
F8E0F8D9F8D9Print 'SAVING' plus filename
F8EDF8E6F8E6Routine to read the TOD (Time Of Day) clock from the 6526 into the .A/X/Y registers
F915F90EF90ESet the TOD clock from the .A/X/Y registers
F940F939F939Do I/O ERROR #1 or TOO MANY FILES
F943F93CF93CDo I/O ERROR #2 or FILE OPEN
F946F93FF93FDo I/O ERROR #3 or FILE NOT OPEN
F949F942F942Do I/O ERROR #4 or FILE NOT FOUND
F94CF945F945Do I/O ERROR #5 or DEVICE NOT PRESENT
F94FF948F948Do I/O ERROR #6 or NOT INPUT FILE
F952F94BF94BDo I/O ERROR #7 or NOT OUTPUT FILE
F955F94EF94EDo I/O ERROR #8 or MISSING FILE NAME
F958F951F951Do I/O ERROR #9 or BAD DEVICE NUMBER
F95AF953F953Save error number, restore default I/O, check error message type and print 'I/O ERROR #n' if in Monitor
F972F96BF96BCheck for STOP key pressed (from $FFE1 Kernal call)
F980F979F979IRQ code for setting STOP key pressed flag
RESET CODE
500128K256KDescription
F99CF995F995'BM' in ASCII. This is used to check against either BASIC or a cartridge at $x009 (where x is any valid cartridge startup point in bank 15 - i.e. 1 to 8). If found then a jump is made to $x000
F99EF997F997Reset entry (from reset vector at $FFFC/D). First check for cartridges or BASIC present
F9D8F9D5F9D5Set reset RAM vector to use $E000 as startup point (monitor) as no BASIC or cartridges were found
F9DBF9D8F9D8Set reset RAM vector use $x000 as startup point
F9E3F9E0F9E0Set up system (unless cartridge found)
F9FBF9F8F9F8Jump to BASIC/Cartridge/Monitor via vector ($03F8)
F9FEF9FBF9FBSet up I/O chips. Checks 50/60 Hz and sets TOD clock accordingly. Sets up Co-processor workspace whether its there or not
FA94FA88FA88Clear zero page, page 2 and 3 in Bank 15. Then check the RAM bank memory from bank 1 (bank 0 on 500). Each byte is non-destructively tested by saving the value, writing $55 and then checking $55 is read back, doing the same with $AA and finally re-writing the original value back. This is mainly what the system is doing after power up and before the power up message is displayed
FAE3FAD7FAD7Once a bank has been discovered to contain no RAM (or Bank 15 has been reached) then this routine sets the top bank and the top of memory (always set to $FDFF so that $FE00-FFFF remain free for bank switching routines if they need to be installed)
FB09FAFDFAFDTable of vectors for $0300 onwards
FB3DFB31FB31NMI vector jump via RAM vector at $0304. This normally points to the RTI (ReTurn from Interrupt) instruction at the end of the IRQ routine
MISC. KERNAL ROUTINES
500128K256KDescription
FB40FB34FB34Set the filename parameters (from $FFBD Kernal call)
FB4FFB43FB43Set the file parameters (from $FFBA Kernal call)
FB56FB4AFB4ARead or Set ST error status (from $FFB7 Kernal call). Carry must be set to store else read is performed. RS232 errors are also stored by this routine
FB6EFB5FFB5FORA bits in .A with ST and store in ST
FB83FB74FB74Set IEEE timeout byte (from $FFA2 Kernal call)
FB87FB78FB78Read/set top of memory including bank (from $FF99 Kernal call). Carry must be clear to perform read
FB9CFB8DFB8DRead/set bottom of memory (from $FF9C Kernal call)
FBB1FBA2FBA2From $FF87 Kernal call. Point .X/Y to table of vectors for $0300 (.A holds bank number), clear carry and then...
FBB8FBA9FBA9Read/set up vectors at $0300-0333 from .A/X/Y (from $FF84 Kernal call). Carry must be set to read from $0300
FBD9FBCAFBCASet reset vector from .X/Y and set the 'Initialisation complete' flag
IRQ HANDLING
500128K256KDescription
FBE5FBD6FBD6IRQ routine. Push registers onto the stack and check for normal interrupt or BRK and jump (via vectors at $0300 and $0302) to either normal IRQ handling or the monitor
FBF8FBE9FBE9Normal IRQ handling entry from $0300 vector. Save indirection bank (location $01) and then check for what has initiated the IRQ
FC0BFBFCFBFCHandle RS232 IRQs and add byte to input buffer if byte has been received
FC69FC5BFC5BCheck for internal disk IRQ
FC77FC69FC69Check for timer IRQ and store a copy of the 6526 IRQs in case they are needed later
FC88FC7AFC7ACheck for IEEE SRQ line IRQs (but don't do anything about them!)
FC8FFC81FC81If we've got this far then it must be a normal 50/60 Hz interrupt so scan the keyboard and then check if the STOP key has been pressed. Finally check the cassette keys and turn the cassette motor on or off as required (this is the only thing that these versions of the operating systems have to do with actually handling the cassette!)
FCADFC9FFC9FReturn from IRQ routine (NMI vector points at the RTI instruction at the end of this routine)
SECOND PROCESSOR CODE
500128K256KDescription
FCB9FCABFCABSend a request to the IPC (Inter Process Communicator) for the second processor (2P)
FD56FD48FD48Service a 2P request
FDA7FD99FD99Send bytes back to 2P
FDD1FDC3FDC3Push return address and get back bus control if 2P finished with it and then jump (via vector at $0801) to next process
FDDDFDCFFDCFGive up bus and then send request to 2P
FDF4FDE6FDE6Wait until 2P flag is low (flag is in I/O at $DB01 bit 2)
FDFCFDEEFDEEWait until 2P flag is high
FE04FDF6FDF66509 acknowledge to 2P by putting 6509 flag high ($DB01 bit 3)
FE0DFDFFFDFFPut 6509 flag low
FE16FE08FE08Free bus so 2P can have it
FE1FFE11FE11Await bus free and then claim it for 6509
FE2FFE21FE21Get number of i/o bytes from table at $0910 (indexed by .Y)
FE41FE33FE33Relinquish control to 2P. Loop while awaiting requests from 2P
VARIOUS BANK HANDLING AND MISC.
500128K256KDescription
FE68FE5AFE5AAll tape routines come here which is a jump to a RAM vector ($036A) which normally points to the next small piece of code. To implement tape cassette routines the user would have to pull the address off the stack to determine which routine was being used and then handle the tape with new code in RAM
FE6BFE5DFE5DPull return address and throw it away and then do DEVICE NOT PRESENT for all tape routines
FE70FE62FE62Put SAVE start address in temp and set the start address bank in the 6509 bank indirection register ($01)
FE7FFE71FE7FCheck if end address reached for SAVE
FE8DFE7FFE7FIncrement SAVE address and, if it was $FFFF, then move to next bank jumping over locations $00 and $01
FEA0FE92FE92Get byte pointed at by ($90) + .Y, bank in $92. This is used to get the filename from any bank
FEABFE9DFE9DMove to any bank. This routine allows a jump to any bank while preserving all registers (which are all passed via each banks stack). The 500 has part of this routine missing which accounts for its inability to use the SYS command to jump to another bank
FEFDFF04FF04Return to calling bank
FF11FF19FF19Initialise pointer to $0100 for bank move and get stack pointer stored at $01FF
FF1CFF24FF24Store .A/X in another stack ready for move
FF26FF2EFF2ERestore registers after move to next bank
FF2DFF35FF35Push the processor status and do an NMI (via $FFFA)
FF31FF39FF39Do BRK, NOP and RTS
FF34FF3CFF3CDo CLI and RTS
FF36FF3EFF3EUnused area
KERNAL TABLE
500128K256KDescription
----FF6CFF6CSYS to any bank
FF6FFF6FFF6FSet power on reset vector
FF72FF72FF72Jump to second processor (also monitors Z command)
FF75FF75FF75Set/Print Function keys
FF78FF78FF78Send second processor request
FF7BFF7BFF7BSet up I/O chips
FF7EFF7EFF7EScreen/keyboard initialisation
FF81FF81FF81Set up buffer in high memory
FF84FF84FF84Read/Set I/O vectors at $0300
FF87FF87FF87Restore I/O vectors to standard settings
FF8AFF8AFF8ASet up device and file number from given secondary address in .A
FF8DFF8DFF8DSet up device an sec address given file number
FF90FF90FF90Control operating system messages mode
FF93FF93FF93Send secondary address after listen
FF96FF96FF96Send secondary address after talk
FF99FF99FF99Read/Set top of memory
FF9CFF9CFF9CRead/Set bottom of memory
FF9FFF9FFF9FScan keyboard
FFA2FFA2FFA2Set IEEE timeout byte with .A
FFA5FFA5FFA5Input byte on IEEE
FFA8FFA8FFA8Output byte on IEEE
FFABFFABFFABSend Untalk on IEEE
FFAEFFAEFFAESend Unlisten on IEEE
FFB1FFB1FFB1Send Listen on IEEE
FFB4FFB4FFB4Send Untalk on IEEE
FFB7FFB7FFB7Read/Set ST error
FFBAFFBAFFBASet file parameters
FFBDFFBDFFBDSet filename parameters
FFC0FFC0FFC0Open a logical file
FFC3FFC3FFC3Close a logical file
FFC6FFC6FFC6Set the Input device
FFC9FFC9FFC9Set the Output device
FFCCFFCCFFCCRestore default I/O channels
FFCFFFCFFFCFInput a byte from current input channel
FFD2FFD2FFD2Output a byte to the current output channel
FFD5FFD5FFD5Load from device
FFD8FFD8FFD8Save to device
FFDBFFDBFFDBSet the clock
FFDEFFDEFFDERead the clock
FFE1FFE1FFE1Check for STOP key pressed
FFE4FFE4FFE4Get a character
FFE7FFE7FFE7Close all files
FFEAFFEAFFEAIRQ routine to check for STOP key pressed (in other machines this routine also updates the software clock which is handled by hardware in these machines)
FFF0FFF0FFF0Read/Set screen X/Y co-ordinates
FFF3FFF3FFF3Set .X/Y to start of I/O
FFF6FFF6FFF6Set (.A) as the current bank
FFF9FFF9FFF9Kernal checksum byte
FFFAFFFAFFFANMI hardware vector
FFFCFFFCFFFCReset hardware vector
FFFEFFFEFFFEIRQ hardware vector