Complete doesn't mean finished though! This was not like a modern iterative development process with small incremental changes as features were added and enhanced. The entire system had to be coded before all the dependancies were resolved. This took an entire year and there are still several weeks of testing ahead (and some inevitable updates).
So what has been coded? Essentially the only program that will ever be written to run on this hardware. This is the firmware that forms the hardware abstract layer that all other programs will use to access the functions of the machine.
There are two reasons for this approach. The first (and least significant) is the limited implementation of the Harvard Architecture: The system uses only one ROM and one RAM chip and there are two data data paths, one for program and other for data. It makes most sense to put the program in the ROM, so this means a new machine code program can not be loaded without reprograming the ROM.
It is easy to add another RAM chip to the system and configure this as an additional bank of program memory. This solves the issue of not being able to load new machine code at run time, but there is a far more significant issue to consider: The main reason for not allowing a user to add their own machine code is to prevent a user's program from taking control of the CPU execution.
If the system yields to a user's program then that program needs to be aware and responsible for all the critical real-time activities required to make the hardware work. The hardware provides the bare minimum to support the electrical interfaces for things like audio, video, and serial communications. The software is responsible for all the timing and state for these interfaces. An interrupt mechanism could be employed, but this is impractical with horizontal video timings running as fast as 48kHz.
The way to keep the system simple is to use a byte code interpreter to execute the user's program. This does have a significant performance impact but there is plenty of room to extend the interpreter with fast native functions for common activities. A big advantage of the interpreter is the ability to provide binary compatibility with an existing processor like the 8080. This makes it easy to port things like CP/M to the platform.
A lot of the firmware features have been discussed in previous logs during their development. A few things have changed as the final pieces came together, so these will be expanded on in later logs. For now this is a quick summary of the final firmware: The base system consists of 120 pages containing over 5,000 assembly instructions (not including 900 NOP instructions to pad timing). This code operates 10 non-blocking threads to control: horizontal video timing, vertical video timing, PS/2 keyboard scan, realtime clock, serial I/O sampling, RS232 transmit, RS232 receive, wavetable synthesizer, maskable interrupts, and byte-code interpreter.