Writing a Color Computer 3 Emulator - ROM/RAM Modes

By Craig Thomas, Sat 01 September 2018, in category Emulation

emulation, trs-80

Last time I wrote about the Chip 8 interpreter, and how the first 512 bytes of RAM were used for the built in font set. Now that I have a little more experience writing simple emulators, I figured it was time to revisit the original reason why I started down this path: to write a Color Computer 3 emulator.

The emulator that I wrote is now mostly functional. It includes the ability to read and write from virtual cassette tapes and virtual disk drives. If you are interested in checking it out, it is available from my Github repository: Color Computer 3 Java Emulator. Note that I cannot distribute the Super Extended Color Basic ROM files, or Disk Basic ROM files, as they are copyright their respective owners.

More Complex

The Chip 8 served as a good introduction to emulation basics and taught me about the main emulation loop, basic bit operations, and how to draw items to a screen. The Color Computer 3 however, is much more complex. For example, there are 7 different addressing modes that can combine with the 59 basic instructions to give rise to over 1,400 combinations of how instructions may operate on data.

All of the addressing modes and instructions are covered in great detail, both from Motorola's technical documentation, and from various other sources around the web. So rather than going into detail about those already well documented aspects, I wanted to start touching on elements of the emulator that are more unique to the Color Computer 3 itself.

With that said, let's delve into the Color Computer 3's different combinations of ROM and RAM modes! Let's start with the various operating system ROMs that were available.

BASIC Operating System ROMs

In the 8-bit era, computers typically had some form of operating system built directly into the machine. Usually, this consisted of some flavor of BASIC (Beginner's All-purpose Symbolic Instruction Code) that was loaded immediately when the device was powered on. BASIC was a good choice for a simple operating system, as it was easy to understand, and had a very gentle learning curve. BASIC is essentially an interpreter that is capable of interpreting a series of keywords, and performing operations based on those keywords (for example, GOTO, FOR, PRINT, etc).

Each different version of BASIC was recorded in a Read Only Memory (ROM) chip that was subsequently embedded on the motherboard. With the Color Computer family, there were several different versions of BASIC that were released, each one adding different functionality.

Color Basic

The first BASIC version, Color Basic was included on the original Color Computer 1. Interestingly, this version of BASIC was written by Microsoft and adapted specifically to run with a total of 4K of RAM. Color Basic is 8K in size.

Extended Color Basic

The second BASIC version called Extended Color Basic was introduced as an improvement to the original Color Basic. It does not completely replace Color Basic, but instead extends Color Basic's command interpreter with a new set of commands (mostly to support graphics functions such as PCLEAR, PMODE, DRAW, etc). Extended Color Basic is 8K in size.

Disk Basic

As computer technology evolved, disk systems became available (and more affordable) for the home computing marketplace. As the name suggests, Disk Basic is a flavor of BASIC that supported commands to interface with a disk system. The Disk Basic operating system is usually contained within a floppy controller, and overrides the computer's built in version of BASIC when the controller is plugged into the cartridge slot. It is important to note however, that Disk Basic does not have any of the graphics commands or extensions that Extended Color Basic provides. Disk Basic is 8K in size.

Super Extended Color Basic

The final BASIC version released specifically for the Color Computer 3 was Super Extended Color Basic. This version of BASIC was needed in order to support the Color Computer 3's new architecture. Many of the chips on the Color Computer 3 were folded into a single controller known as the GIME chip (Graphics, Interrupt, Memory Enhancement). The GIME chip was technically known as the ACVC (Advanced Color Video Chip). The GIME provided new graphics modes, as well as introduced a new Memory Management Unit that allowed access to 512K of RAM. The Super Extended Color Basic ROM was 16K in size.

ROM and RAM

As mentioned above, BASIC was fully contained within a set of memory chips that were Read Only Memory (ROM). ROMs essentially function the same as RAM does, meaning that each cell in a ROM stores a byte value that can be read by the CPU. The main difference is that when power to the computer is removed, the contents of ROM are not cleared. Plus, as the name suggests, you cannot change anything on a ROM chip even if you tried - you can only read whatever value is stored in it.

In order to read from ROM or RAM however, the chip must somehow be mapped into the address space of the computer, otherwise the CPU has no way of accessing it!

Address Space

All of the Color Computer models had a 16-bit program counter, meaning that the computer was capable of accessing addresses between 0 ($0000) and 65535 ($FFFF). These memory addresses can come from both a mixture of ROM or RAM chips.

For example, given that Color Basic is 8K in size, you could map addresses 40960 ($A000) - 49151 ($BFFF) to the Color Basic ROM chip. The space of $A000 to $BFFF is exactly 8K in size. If you were to do this, when you read address $A010 from memory, instead of reading from RAM, it would read address $0010 from the ROM chip instead.

Memory Map

This example above is exactly what the Color Computers 1 and 2 actually do (and 3 as well, although this map would look a little different - keep reading!). If you look at a memory map, then you would see something that looks like this:

+------------------------+---------+
| Function               | Address |
+------------------------+---------+
| RAM                    | $0000   |
| (32K)                  |   to    |
|                        | $7FFF   |
+------------------------+---------+
| Extended Color Basic   | $8000   |
| ROM                    |   to    |
| (8K)                   | $9FFF   |
+------------------------+---------+
| Color Basic ROM        | $A000   |
| (8K)                   |   to    |
|                        | $BFFF   |
+------------------------+---------+
| External Cartridge ROM | $C000   |
| (16K)                  |   to    |
|                        | $FFFF   |
+------------------------+---------+

As you can see, 32K of RAM is mapped to the bottom half of the address space. The top half of the address space is reserved for the Basic ROMs and cartridge ROM.

But wait - the Color Computer 1 and 2 were able to have 64K of RAM, yet half of that mapping above is dedicated to reading ROM addresses! How do we access all 64K of RAM?

ROM / RAM Mapping Modes

The Color Computers 1, 2 and 3 had a set of memory mapping modes. These modes controlled what ROM chips were loaded into which address space. The modes are controlled by the SAM TY bit:

+----------------------------------+------------------------------+
| SAM TY Bit Clear                 | SAM TY Bit Set               |
+----------------------------------+------------------------------+
| RAM                      $0000   | RAM                   $0000  |
| (32K)                      to    | (64K)                   to   |
|                          $7FFF   |                       $FFFF  |
+----------------------------------+                              |
| Extended Color Basic     $8000   |                              |
| ROM                        to    |                              |
| (8K)                     $9FFF   |                              |
+----------------------------------+                              |
| Color Basic ROM          $A000   |                              |
| (8K)                       to    |                              |
|                          $BFFF   |                              |
+----------------------------------+                              |
| External Cartridge ROM   $C000   |                              |
| (16K)                      to    |                              |
|                          $FFFF   |                              |
+----------------------------------+------------------------------+

You can see here that when the SAM TY bit is set, all 64K of RAM is available. Well, almost all of it - addresses $FF00 to $FFFF are dedicated for I/O functions. When a byte is read from or written to any one of those dedicated addresses, they pass to specific hardware devices instead. More on that below.

The Color Computer 3 takes things one step further. The configuration of the ROM mode is configurable through two bits in the INIT 0 $FF90 IO address. The above configuration when the SAM TY bit is clear is accessible by writing 0 into bit 1 of $FF90 and any other value into bit 0 of $FF90.

Two additional configurations are available when the SAM TY bit is clear:

+------------------------+---------------------+-----------------------+
| $FF90 bits xxxxxx0x    | $FF90 bits xxxxxx10 | $FF90 bits xxxxxx11   |
+------------------------+---------------------+-----------------------+
| RAM            $0000   | RAM          $0000  | RAM            $0000  |
| (32K)            to    | (32K)          to   | (32K)            to   |
|                $7FFF   |              $7FFF  |                $7FFF  |
+------------------------+---------------------+-----------------------+
| Extended       $8000   | Extended     $8000  | External       $8000  |
| Color Basic      to    | Color Basic    to   | Cartridge ROM    to   |
| (8K)           $9FFF   | (8K)         $9FFF  | (32K)          $FFFF  |
+------------------------+---------------------+                       |
| Color          $A000   | Color        $A000  |                       |
| Basic ROM        to    | Basic ROM      to   |                       | 
| (8K)           $BFFF   | (8K)         $BFFF  |                       |
+------------------------+---------------------+                       | 
| External       $C000   | Super Ext    $C000  |                       |
| Cartridge ROM    to    | Color Basic    to   |                       |
| (16K)          $FFFF   | (16K         $FFFF  |                       |
+------------------------+---------------------+-----------------------+

Note that this memory map isn't entirely accurate to how the Color Computer 3 actually maps the ROM and RAM. The memory management unit distinguishes between physical and virtual memory, and maps ROMs into a specific 8K page. However, that's a discussion for the next article.

Now it becomes obvious why when the computer starts up it only has approximately 32K of RAM free for BASIC - the ROMs are mapped to one half of the memory space the CPU has access to! In order to gain access to it all, you would need to set the SAM TY bit. Doing so however, has the side-effect of removing the BASIC ROM from the CPU's address space. This means that you would not have access to any of the BASIC subroutines.

Challenges for an Emulator

As you can see above, it now becomes more complicated to access memory. In emulators like the Chip 8, the memory footprint is simply a 4K block in a single array. Memory could be written to or read from by directly accessing an array of bytes such as:

byte [] memory = new byte [4096];

memory[0x03CD] = someByte;

Conceptually, this meant that the CPU had a direct relationship with the memory array. Hierarhically, this would look like this:

Chip 8 CPU and Memory Relationship

With the CoCo, memory locations may come from one of three places: RAM, ROM, or cartridge ROM. Instead of using an array to represent memory, it pays to have a slightly more complicated structure to control reads and writes.

An IO Controller

In my Color Computer 3 Java Emulator, I created a new class called an IOController. Given that there are multiple hardware devices that can be attached to the computer, it made sense to create a single class that would control access to and from these devices. Here is a simple representation of the new hierarchy.

Color Computer 3 IO Hierarchy

Memory and the IOController

One of those IO devices is system memory. When the CPU attempts to read or write a byte into memory, it performs the read or write on the IOController, which in turn does any necessary interpretation of the value being written, and then passes it on to a second class called Memory, which contains 3 different byte arrays:

When a byte is read from memory using readByte, or written to memory using writeByte, the functions will check to see what memory mapping mode is in effect, and route the read or write to the appropriate array.

Here is a more complete picture of the hierarchy with classes.

Color Computer 3 IO Hierarchy

Controlling the ROM / RAM Mapping

The Memory class contains functions that sets what type of ROM / RAM mapping is currently in effect. In turn, the IOController class sets the ROM / RAM mapping modes when specific bytes are written to specific addresses.

For example, as mentioned above, addresses $FF00 through $FFFF are reserved for interacting with IO devices. These addresses always route to IO devices regardless of the ROM / RAM mapping that is set. The IOController interprets values sent to these addresses, and performs functions based upon the values written. In the case of address $FF90, it does the following:

    public void writeIOByte(UnsignedWord address, UnsignedByte value) {
        int intAddress = address.getInt() - 0xFF00;
        ioMemory[intAddress] = value.getShort();

        switch (address.getInt()) {

            /* INIT 0 */
            case 0xFF90:
                /* ROM memory mapping - two lowest bits */
                memory.setROMMode(new UnsignedByte(value.getShort() & 0x3));
                break;

            default:
                memory.writeByte(address, value);
                break;
        }
    }

As you can see, when a value is written to address $FF90, the bottom two bits are sent to the Memory class, to a method called setROMMode, which will interpret the two bits and instruct subsequent read / write accesses to store or pull values from the correct array.

Wrapping Up

As we can see, memory accesses have become more complicated, with memory either coming from RAM, a BASIC ROM, or a cartridge ROM. Within the Color Computer 3, there are several different mapping modes that control how ROM is intermixed with RAM in the address space available to the CPU.

To make accessing memory easier, a Memory class controls reads and writes to one of three different memory arrays - RAM, BASIC ROM, or external cartridge ROM. In turn, an IOController controls access to dedicated IO addresses, and also controls interaction with other hardware devices.

Tune in next time when I discuss the Color Computer 3's memory management unit, and how the computer can address 512K of RAM while the CPU is bound to a 64K address space.