Thursday, February 7, 2013

Phoenix says "Hello, world."


Now that Phoenix has a CPU, memory, display and a keyboard, it's time to actually make it do something. The first "real" program I wrote was loosely inspired by the Apple 1's Woz Monitor: a simple text-based program that can be used to inspect and modify memory contents, useful for debugging during the development of more advanced programs.

Since Phoenix display hardware is graphics based, the first thing I needed was a way to display characters on the screen. Using 8x8-pixel characters on the 256x192-pixel screen gives 24 lines of 32 characters each. Not spectacular, but the same as used in the ZX Spectrum, for example.

It's fairly straightforward to display 8x8-pixel characters: the framebuffer is organized as bytes of 8 pixels each. A line of pixels is 32 bytes, and so a line of text is 8 * 32 = 256 bytes. This makes cursor addressing especially easy: converting from (row,column) in a register pair to the location in memory just requires adding the start address of the framebuffer.

In addition to just drawing the characters, we need to keep track of the current position and increment  it after each character, handle newlines and scroll the screen when the bottom is reached. The latter can be done easily using the Z80 "LDIR" (Load, Increment, Repeat) instruction.

Since the monitor deals with memory addresses and contents, I also wrote some functions to print and parse hexadecimal values.

The monitor program (as before, available on GitHub) consists of a main loop reading a character from the keyboard using the routine described in the previous post, and interpreting it as one of the commands listed below. There's a separate function implementing each of these commands, reading additional arguments as needed and then executing it, followed by jumping back to the start of the loop.

The commands supported are:

  • e value -- enable/disable keyboard [e]cho: whether keyboard input is shown on the screen.
  • d address size -- [d]ump the contents of size number of bytes at address.
  • l address size byte... -- [l]oad size number of bytes into memory starting at address.
  • j address -- [j]ump to address.
And here is a demonstration of the monitor being used to enter a simple Z80 machine code program, verify its contents, and run it:


No comments:

Post a Comment