Stack usage in the Apple 1 monitor

An interesting “feature” of the Apple 1 monitor is that it does not initialize the stack pointer. In the MOS Technology MCS6502 microprocessor, the most significant eight bits of the stack pointer are hardwired to $01. That means that the stack is constrained to a maximum of 256 bytes, in the address range $0100 to $01FF (page $01). If the stack pointer has the value $0100, and a byte is pushed onto the stack, the stack pointer will wrap to $01FF.  Similarly, if the stack pointer is $01FF, and a byte is popped from the stack, the stack pointer will wrap to $0100.

It is normal practice to initialize the stack pointer very early in system initialization.  However, if you do not plan to use any of the memory in page $01 for anything other than the stack, in principle it does not matter what the starting value of the stack pointer is, and thus it is not necessary to initialize it. The Apple 1 monitor saves a few bytes of ROM space by omitting the stack pointer initialization. Since there are only 256 bytes of ROM, this is a non-trivial savings.

For my port of the Apple 1 monitor to the Motorola MC6800 microprocessor, I will have to explicitly initialize the stack pointer. Since the MC6800 has a full 16-bit stack pointer, leaving it uninitialized could result in attempting to use ROM or nonexistent memory for the stack, neither of which would actually work. It is also possible that the stack would be in RAM, but pointing to locations that are being used for other purposes.

The most obvious way to initialize the stack pointer of the MC6800 is to use the LDS instruction (“LoaD Stack pointer”) with the immediate addressing mode. This is a three byte instruction, of which the second and third bytes are the value to be loaded.

It would be nice to come up with a way to initialize the stack pointer without using three bytes of code. It is my intention to have the MC6800 version of the monitor use a memory map nearly identical to the original MCS6502 version, where $0100 to $01FF is the stack, and $0200 to $027F is the line input buffer. Intuitively it seems like there should be some way to take advantage of the fact that the stack and line input buffer addresses are immediately adjacent, and initialize both the stack pointer and the line input buffer pointer at the same time, using the one-byte TXS instruction to copy the value into the stack pointer. Unfortunately I have yet to find a practical way to do this that actually reduces the overall byte count.

This entry was posted in RetroChallenge. Bookmark the permalink.

Leave a Reply