It has been a few days since I last wrote about FAP, it’s not that I have given up on it, although I did cool off a bit and spent more time on other stuff. I’ve been developing a video card for FAP, but it’s not finished yet so I’ll leave it to another post. This time, it’s all about writing programs for FAP to execute.
With 16KB of RAM and 16KB of ROM, FAP is ready to function like any other proper computers! Although without any means of input or output, it’s not entirely useful at this stage, but I’m not going to let that stop me from at least making it execute a simple program to see if it actually works.
However, before doing that, some more housekeeping to do. I need a streamlined way to write an assembly program, have it assembled and uploaded to FAP and have it executed. I began by adding a “programming mode”, which is entered by default upon powering up. In this mode the STM32 controller kicks the CPU off the bus, takes control of the memory and listens on the serial input, I can then issue read or write commands via bluetooth serial and have it program the EEPROM. When I actually want FAP to start executing the program, I reset the STM32 controller while holding down the second button, and it will enter execute mode and start running the program, easy. While I was at it, I also added another button as well as labeling them. From left to right are reset, single clock, single instruction, and full speed start/stop.
Here is a code snippet of the program mode function, in the loop it checks if there is a command in the UART receive buffer, and execute it if there is. The command could be read, write, or zeroing the EEPROM.
With that done, time to focus on the PC side. I need a Z80 cross assembler, debugger, and some way to upload my program. The assembler I picked is zmac, a long lived and feature rich cross assembler, and open source too. It comes with a windows executable but you can compile it from source yourself. The debugger is z80sim, I downloaded it but haven’t got a chance to use it because all my programs are really simple right now. Anyway, that only leaves the matter of uploading the program. I wrote a simple and rather crappy python script for it:
It basically go through each byte in a binary file and send write commands for each, while making sure it has been written properly. It’s pretty ugly but it works.
Now we have everything set up, time to write a proper program, and what a program it is!
The program starts at address 0x0, and just jump to itself endlessly. The assembled program is 3 bytes: C3 00 00, C3 is JMP instruction, and 00 is the address its supposed to jump to. If everything goes well, we should see the address bus go in a loop forever.
Here you can see me uploading the program wirelessly to FAP via bluetooth, reset the STM32 controller while holding the second button to enter execute mode, and then a few single clock steps. You can see the address went from 0x0 to 0x1, then 0x2, and then back to 0x0 again, also notice the C3 and 00 on the data bus as Z80 fetches instructions. After that I let it run at full speed and you can see the address looping. Success!
Now that FAP is going, I wrote a slightly more complicated program for it to test writing to SRAM:
After clearing A and setting up stack pointer, it adds 0x10 to A, then push the content of AF to stack every loop. If everything goes well I can let it run for a while, reset the STM32 controller to go into program mode, and read back values in SRAM, and it should be 0, 10, 20, 30 etc. This program is also a whooping 10 bytes, so it must be at least 3 times better than the last one, right?
I upload the program, let it run for a while, and read back the beginning of the stack. You can see the address bus looping, and the SRAM address flashing by in each loop. Now let’s examine the content:
At first glance it might look like I cocked it up, since it’s not strictly increasing as the code suggests. However, push instruction pushes both A and F to stack, F first then A, so the value of A is at even addresses, i.e. 0x7ffe, 0x7ffc, 0x7ffa etc. And if you look at the numbers you can see they are indeed increasing. The odd addresses are contents of flag register, it should be 0 for the first few loops, but some of them are 0x20. 0x20 is flag bit 5 set, which is actually a undocumented flag that is “a copy of bit 5”, which is exactly what happened here, so after all, everything is alright.
And there you have it! FAP, built from a 8 ancient chips and spaghetti of wires, actually running proper programs that I wrote for it. It’s a big milestone in this build, and as you expect I’m thrilled by it. However, I’m going to put the F in FAP as I develop a VGA graphics card for the Z80 computer in the next post, stay tuned!