From C64-Wiki
Jump to navigationJump to search

The address range 115–138 (or $73–$8A in hexadecimal) holds a machine language subroutine that plays a central role for the BASIC interpreter built into the C-64: It reads either the current or the next character or token in the BASIC program, skips any excess spaces, and sets or clears the carry flag depending on whether the character read is a numerical digit ("0" thru "9") or not. It also sets or clears the zero flag depending on whether the end of statement (either a colon or the end of line) has been reached:

Address Machine
Assembler Comments
Dec Hex Labels Code
115 73 E6 7A CHRGET INC TXTPTR Increase the two-byte pointer at label TXTPTR (122–123/$7A–$7B) by one.
117 75 D0 02 BNE CHRGOT
119 77 E6 7B INC TXTPTR+1
121 79 AD ... CHRGOT LDA ... LDA in absolute mode, with the argument given below
122 7A 60 EA TXTPTR .WORD 60000 Pointer to current character in the BASIC text
124 7C C9 3A CMP #":" Leave the routine through label QUIT with the carry set, if the PETSCII code read equals or exceeds 58 (the code for "colon", following the codes for "9")
126 7E B0 0A BCS QUIT
128 80 C9 20 CMP #" " If the character read was a space then skip it and go back and read the next character
130 82 B0 0A BEQ CHRGET
132 84 38 SEC Together these two subtractions leave the character held in the accumulator unchanged, while the last of them sets the carry if the character's PETSCII code is less than that of the digit "0"
133 85 E9 30 SBC #"0"
135 87 38 SEC
136 88 E9 D0 SBC #256-"0"
138 8A 60 QUIT RTS Return from this subroutine

Being a fundamental example of self-modifying code, this routine needs to be in RAM which can be modified, as opposed to ROM: Inside this routine is a pointer (at 122–123/$7A–$7B) which is made part of the LDA absolute instruction which reads a character from the BASIC text – in effect implementing the non-existant "LDA indirect".

ROM details[edit | edit source]

During cold start, i.e. after power-up or a reset, the system runs through a short loop at 58336–58345/$E3E0–$E3E9, which copies the routine above (along with the initial "seed" value for the RND BASIC function) from a ROM image held at 58274–58297/$E3A2–$E3BE. In this ROM image, the two bytes that end up in the pointer at 122–123 point to the "arbitrary" address of 60000/$EA60, although this address will always refer to the KERNAL in any situation where the BASIC is banked in.