The Z80 system we have built to date only has the ability to run code from read-only memory. Read-only memory, as the name implies, is only readable and not writable which creates a problem for us. For instance, to use a stack we need memory that is both readable and writable so that we can use the CALL instruction. We need RAM.
RAM, or random access memory, is both readable and writable memory. The module I am using is made by Cypress Semiconductor and has the device name CY62256. This module is a 32KB static RAM and works very similarly to the ROM chip CAT28C256 we have been using in our design. The plan is to implement the same code we have used in our previous test for the console interface except this time we will initialize the Z80’s stack pointer so that we can make use a memory stack to make calls and issue returns. What is a stack? A stack is a programming term that is used to represent a section of memory that is used in a special way. The way this section of memory is used can be compared very similarly to a stack of plates in a plate dispenser. You can either push a plate into the dispenser or pop one off. The plates in the dispenser are always last in, first out. In our stack we either push in data to the memory’s stack location, or pop data off. This technique is useful for when we need to keep track of the instructions that the Z80 is processing. For example, when a CALL instruction is issued the Z80 pushes the memory address it is currently processing onto the stack, and jumps to the memory address referenced by the label that is “called.” Later when a RET is issued the Z80 pops the memory address from the top of the stack that was pushed on earlier to resume the normal execution path. This is very useful when it comes to structuring test programs. No longer is there a need to structure your program linearly because we can use the stack to take care of resolving the path the program needs to take. How to you get this stack up and running?
To get started we need to initialize the Z80’s stack pointer. The stack pointer (SP) is a 16-bit register that initially hold the address of the “top” of the stack. In my design I wanted to place the stack at the top address in that available RAM I was accessing. The RAM addresses were from 8000H → 87FFH. So to initialize the stack pointer I used the following assembly instructions,
RAMTOP: .EQU 87FFH ; TOP ADDRESS OF RAM LD SP, RAMTOP
Now that the stack pointer is initialized we can use four new instructions PUSH, POP, CALL, and RET in our programs. As we pointed out above CALL and RET allow us to change the flow of the program. This is done by manipulating the program counter register (PC). When a CALL is issued effectively a PUSH PC occurs and then a JMP to the location pointed to by the label referenced happens. The PUSH instruction places the operand used onto the top location of the stack. Later when a RET is issued a POP PC occurs and the Z80 “jumps” to the old address that was being held in the stack. The POP instruction takes the data held in the top location of the stack off and makes the next piece of data in line the new “top” of the stack which is what the stack pointer is used for. Instead moving the data around in the stack when it is pushed on or popped off the stack pointer just keeps track of the current top of the stack and moves to accommodate the stack’s function.
The schematic is a bit more robust now sporting some memory decoding logic and I/O enabling. I think I may start either moving the design to a proper PCB or programming up a bit more monitor software. I am leaning toward monitor software since it will probably help me understand more about where I want this computer design to end up before I start soldering. I am going to produce a loader program first for my monitor so that I can load hex files directly from my desktop computer into the system’s RAM without having to take out the ROM chip and flash its contents. This will definitely be a step in the right direction toward a fully featured monitor program.
All Files from this project can be downloaded from my GitHub Repository,