One useful feature of the 8080 was the ability to call a handful of addresses in low memory with a single-byte instuction, as opposed to the usual three bytes needed for CALL and other branch instructions. These addresses were known as the "Restart" addresses, and memory-conscious programmers would always put their most-commonly called functions here, thus saving two bytes on every call elsewhere in the program. There are 7 restart addresses, spaced at 8 byte intervals from 0000 to 0030 inclusive. (NB: There is support for an eighth restart function, RST 7, but Basic makes no use of it).
Once the loader had finished loading Basic into memory from paper tape it would jump to address 0000, the very start of the program. Not much needs to be done here - just disable interrupts and jump up to the Init section in upper memory. Notice that the jump address here is coloured red, indicating the code is modified by code elsewhere. In this case, the jump address is changed to point to Ready once Init has run successfully. (fixme: not yet it isnt).
0000 | F3 | Start | DI | |
0001 | C3210D | JMP Init |
Fixme: What are these two addresses for?
0004 | 9004 | DW 0490 | ||
0006 | F907 | DW 07F9 |
Here is a truly beautiful piece of code, it's Golden Weasel richly deserved. It's used at run-time to check syntax in a very cool way : the byte immediately following an RST 1 instruction is not the following instruction, but the keyword or operator ID that's expected to appear in the program at that point. If the keyword or operator is not present, then it Syntax Errors out, but if it is present then the return address is fixed-up - ie advanced one byte - and the function falls into NextChar so the caller has even less work to do. I honestly doubt syntax checks could be done more efficiently than this. Sheer bloody genius.
|
Return next character of input from the buffer at HL, skipping over space characters. The Carry flag is set if the returned character is not alphanumeric, also the zero flag is set if a null character has been reached.
0010 | 23 | NextChar | INX H | |
0011 | 7E | MOV A,M | ||
0012 | FE3A | CPI 3A | ||
0014 | D0 | RNC | ||
0015 | C35E04 | JMP NextChar_tail |
Prints a character to the terminal.
0018 | F5 | OutChar | PUSH PSW | |
0019 | 3A2700 | LDA TERMINAL_X | ||
001C | C36E03 | JMP OutChar_tail | ||
001F | 00 | NOP |
Compares HL and DE with same logical results (C and Z flags) as for standard eight-bit compares.
0020 | 7C | CompareHLDE | MOV A,H | |
0021 | 92 | SUB D | ||
0022 | C0 | RNZ | ||
0023 | 7D | MOV A,L | ||
0024 | 93 | SUB E | ||
0025 | C9 | RET |
Variables controlling the current X and Y positions of terminal output.
0026 | 01 | TERMINAL_Y | DB 01 | |
0027 | 00 | TERMINAL_X | DB 00 |
Tests the state of FACCUM. This part returns with A=0 and zero set if FACCUM==0, the tail of the function sets the sign flag and A accordingly (0xFF is negative, 0x01 if positive) before returning.
0028 | 3A7201 | FTestSign | LDA FACCUM+3 | |
002B | B7 | ORA A | ||
002C | C2DA09 | JNZ FTestSign_tail | ||
002F | C9 | RET |
Effectively PUSH (HL). First we write the return address to the JMP instruction at the end of the function; then we read the word at (HL) into BC and push it onto the stack; lastly jumping to the return address.
0030 | E3 | PushNextWord | XTHL | |
0031 | 223B00 | SHLD 003B | ||
0034 | E1 | POP H | ||
0035 | 4E | MOV C,M | ||
0036 | 23 | INX H | ||
0037 | 46 | MOV B,M | ||
0038 | 23 | INX H | ||
0039 | C5 | PUSH B | ||
003A | C33A00 | JMP 003A |