Technical Info:

What follows is technical information for users who want to know more about the emulator or want to develop support programs for the emulator or new software for the Color Computer running on the emulator. Nothing contained here is required to use the emulator.

Return to contents:

Technical info - DMK type virtual disks:

This information on what has become known as the DMK virtual disk format is provided for users wanting to better understand the operation of the emulator and for programmers writing their own emulators wanting to add support for this format and/or the creation of PC utilities to work with the DMK virtual disk format.

This virtual disk format is as close to the way data on a real disk is stored as possible. There is very little added overhead and the data is easily examined and edited using PC based hex editors. The actual design is really quite simple and enables support of ALL the WD-1771 and WD-19xx controller functions and formats. While the design is simple however the programming requirements for this format are much more extensive then for the JV1/JV3 formats.

Disk header:

Virtual disks have a 16 byte disk header which is initialized when the user creates a new virtual disk. This header may be modified before or after a virtual disk has been formatted to change some of its characteristics.

Byte 0 | If this byte is set to FFH the disk is `write protected', 00H allows writing.

Byte 1

Number of tracks on virtual disk. Since tracks start at 0 this value will be one greater than the highest track written to the disk. So a disk with 35 tracks will have a value of 35 (23H) in this field after formatting while the highest track written would be 34. This field is updated after a track is formatted if the track formatted is greater than or equal to the current number of tracks. Re-formatting a disk with fewer tracks will NOT reduce the number of tracks on the virtual disk. Once a virtual disk has allocated space for a track it will NEVER release it. Formatting a virtual disk with 80 tracks then re-formatting it with 35 tracks would waste space just like formatting only 35 tracks on an 80 track drive. The emulator and COCO operating systems don't care. To re-format a virtual disk with fewer tracks use the re-create the virtual disk first, then re-format to save space.

Note: This field should NEVER be modified. Changing this number will cause COCO operating system disk errors. (Like reading an 80 track disk in a 35 track drive)

Byte 2 & 3

This is the track length for the virtual disk. By default the value is 1900H, 80H bytes more than the actual track length, this gives a track length of 6272 bytes. A real double density track length is aprox. 6250 bytes. This is the default value when a virtual disk is created. Values for other disk and format types are 0CC0H for single density 5.25" floppies, 14E0H for single density 8" floppies and 2940H for double density 8" floppies. The max value is 2940H. For normal formatting of disks the values of 1900H and 2940H for 5.25" and 8" are used. The emulator will write two bytes and read every second byte when in single density to maintain proper sector spacing, allowing mixed density disks. Setting the track length must be done before a virtual disk is formatted or the disk will have to be re-formatted and since the space for the disk has already been allocated no space will be saved.

WARNING: Bytes are entered in reverse order (ex. 2940H would be entered, byte 2=40, byte 3=29).
Note: No modification of the track length is necessary, doing so only saves space and is not necessary to normal operation. The values for all normal 5.25" and 8" disks are set when the virtual disk is created. DON'T modify the track length unless you understand these instructions completely. Nothing in the PC world can be messed up by improper modification but any other virtual disk mounted in the emulator with an improperly modified disk could have their data scrambled.

Byte 4

Virtual disk option flags.

Bit 4 of this byte, if set, means this is a single sided ONLY disk. This bit is set if the user selects single sided during disk creation and should not require modification. This flag is used only to save PC hard disk space and is never required.

Bit 6 of this byte, if set, means this disk is to be single density size and the emulator will access one byte instead of two when doing I/O in single density. Double density can still be written to a single density disk but with half the track length only 10 256 byte sectors can be written in either density. Mixed density is also possible but sector timing may be off so protected disks may not work, a maximum of 10 256 byte sectors of mixed density can be written to a single density disk. A program like "Spook House" which has a mixed density track 0 with 1 SD sector and 1 DD sector and the rest of the disk consisting of 10 SD sectors/track will work with this flag set and save half the PC hard disk space. The protected disk "Super Utility + 3.0" however has 6 SD and 6 DD sectors/track for a total of 12 256 byte sectors/track. This disk cannot be single density.

This bit is set if the user selects single density during disk creation and should not require modification. This flag is used only to save PC hard disk space and is never required.

Bit 7 of this byte, if set, means density is to be ignored when accessing this disk. The disk MUST be formatted in double density but the emulator will then read and write the sectors in either density. The emulator will access one byte instead of two when doing I/O in single density.

This flag was an early way to support mixed density disks it is no longer needed for this purpose. It is now used for compatibility with old virtual disks created without the double byte now used when in single density. This bit can be set manually in a hex editor to access old virtual disks written in single density.

Byte 5-B | reserved for future options
Byte C-F | Must be zero if virtual disk is in emulator's native format. Must be 12345678h if virtual disk is a REAL disk specification file used to access REAL COCO floppies in compatible PC drives.

Track Header

Each track has a 128 (80H) byte header which contains an offset to each IDAM in the track. This is created during format and should NEVER require modification. The actual track data follows this header and can be viewed with a hex editor showing the raw data on the track. Modification should not be done as each IDAM and sector has a CRC, this is just like a real disk, and modifying the sector data without updating the CRC value will cause CRC errors when accessing the virtual disk within the emulator.

Note: Modification within MSDOS could however be done to emulate a protected disk in the TRS-80 & COCO emulators.

Track header:

Each side of each track has a 128 (80H) byte header which contains an offset pointer to each IDAM in the track. This allows a maximum of 64 sector IDAMs/track. This is more than twice what an 8 inch disk would require and 3.5 times that of a normal TRS-80/COCO 5 inch DD disk. This should more than enough for any protected disk also.

These IDAM pointers MUST adhere to the following rules.

- Each pointer is a 2 byte offset to the FEh byte of the IDAM. In double byte single density the pointer is to the first FEh.
- The offset includes the 128 byte header. For example, an IDAM 10h bytes into the track would have a pointer of 90h, 10h+80h=90h.
- The IDAM offsets MUST be in ascending order with no unused or bad pointers.
- If all the entries are not used the header is terminated with a 0000h entry. Unused entries must also be zero filled..
- Any IDAMs overwritten during a sector write command should have their entry removed from the header and all other pointer entries shifted to fill in.
- The IDAM pointers are created during the track write command (format). A completed track write MUST remove all previous IDAM pointers. A partial track write (aborted with the forced interrupt command) MUST have it's previous pointers that were not overwritten added to the new IDAM pointers.
- The pointer bytes are stored in reverse order (LSB/MSB).

Each IDAM pointer has two flags. Bit 15 is set if the sector is double density. Bit 14 is currently undefined. These bits must be masked to get the actual sector offset. For example, an offset to an IDAM at byte 90h would be 0090h if single density and 8090h if double density.

Track data:

The actual track data follows the header and can be viewed with a hex editor showing the raw data on the track. If the virtual disk doesn't have bits 6 or 7 set of byte 4 of the disk header then each single density data byte is written twice, this includes IDAMs and CRCs (the CRCs are calculated as if only 1 byte was written however). The IDAM and sector data each have CRCs, this is just like on a real disk.

Modification should not be done since doing so without updating the CRCs would cause data errors. Modification could be done however to create protected tracks for importing protected disks to virtual disk format. Examples of disks created using this technique are the TRS-80 programs "Super Utility+ 3.0" and "Forbidden City".

Return to contents:

Technical info - JV1/JV3 type virtual disks:

This emulator is capable of reading and writing to JV1/JV3 type virtual disks. Support for this type of virtual disk is limited by both the limits of the format type and this emulators support of it.

The emulator supports read sector, read address and write sector commands to the JV1 type virtual disk. JV1 disks are single density (Model 1) and double density (COCO), only. They can be up to 254 tracks long and always have a protected directory track at track 17. Read track and write track commands are not supported for this disk type. This disk type can be write protected from the "virtual floppy disk selection screen" but the write protect status will always default to off when ever a JV1 disk is opened.

The emulator supports read sector, read address and write sector commands to the JV3 type virtual disk. JV3 disks are single/double density and can be up to 96 tracks long. Read track and write track commands are not supported for this disk type. This disk type can be write protected from the "virtual floppy disk selection screen" but the write protect status will always default to what ever status is in the the JV3 virtual disk file (byte 21FFh) when the disk is opened, the write protect status is not updated. The density and CRC error flags are also supported but not updated. DAM types FB/F9 report FB and F8/FA report F8. Sector writes that change the DAM type from what is in the virtual disk file are not supported. This will not cause problems unless you try to change the protection status of a directory track. Standard IBM sector sizes are supported of 128, 256, 512 & 1024 bytes. A second sector header block is not supported.

Return to contents:

Technical info - REAL COCO floppy disks:

This emulator is capable of reading, writing and formatting REAL COCO floppy disks in compatible PC floppy drives. Support for this is limited by both the limits of the NEC type floppy disk controller and this emulators support of it.

Depending on compatibility of your PC you should be able to read/write single density & double density 5.25" and 3.5" disks in 360k and 720k PC floppy drives (commonly known as low/double density drives, DD). You should be able to read/write double density 5.25" and 3.5" disks in 1.2meg and 1.44meg PC floppy drives (commonly known as high density drives, HD).

Eight fixed sector length REAL floppy specification virtual disks are supplied to read/write 256 byte/sector floppies in a PC's A: and B: drives.

FDD0_360.DSK | Reads 35/40 track disks on a PC A: 360k (DD) drive.
FDD1_360.DSK | Reads 35/40 track disks on a PC B: 360k (DD) drive
FHD0_360.DSK | Reads 35/40 track disks on a PC A: 1.2meg (HD) drive. (double steps head)
FHD1_360.DSK | Reads 35/40 track disks on a PC B: 1.2meg (HD) drive. (double steps head)
FHD0_720.DSK | Reads 80 track disks on a PC A: 1.2meg (HD) drive.
FHD1_720.DSK | Reads 80 track disks on a PC B: 1.2meg (HD) drive.
F350_720.DSK | Reads 80 track 3.5" disks on a PC A: 1.44meg (HD) drive.
F351_720.DSK | Reads 80 track 3.5" disks on a PC B: 1.44meg (HD) drive.

Eight variable sector length REAL floppy specification virtual disks are supplied to read/write 128-1024 byte/sector floppies in a PC's A: and B: drives. These specification disks are slower than the fixed length ones and should only be used on disks un-readable with the fixed length specification disks.

VDD0_360.DSK | Reads 35/40 track disks on a PC A: 360k (DD) drive.
VDD1_360.DSK | Reads 35/40 track disks on a PC B: 360k (DD) drive
VHD0_360.DSK | Reads 35/40 track disks on a PC A: 1.2meg (HD) drive. (double steps head)
VHD1_360.DSK | Reads 35/40 track disks on a PC B: 1.2meg (HD) drive. (double steps head)
VHD0_720.DSK | Reads 80 track disks on a PC A: 1.2meg (HD) drive.
VHD1_720.DSK | Reads 80 track disks on a PC B: 1.2meg (HD) drive.
V350_720.DSK | Reads 80 track 3.5" disks on a PC A: 1.44meg (HD) drive.
V351_720.DSK | Reads 80 track 3.5" disks on a PC B: 1.44meg (HD) drive.

Because of the limitations of the PC's NEC type floppy disk controller the PC cannot read most protected disks. The emulator does not support the track read commands with REAL floppies. Because of limitations of the PC's controller most disk zap utilities (like Hyperzap and Super Utility) cannot work with REAL floppies. Also the write track command has to translate format data to the PC's controller form and is therefore unable to format anything but standard sectors. Because of the translation for PC disk I/O, access to real TRS-80 disks is apt to be slow, formatting in some cases can take as long as 8 seconds/track. This is unavoidable and should not present problems since REAL disk support is mainly for importing your existing COCO disks and transferring data and programs to the COCO. If your PC has a hard time reading your COCO disks then use the emulator to format a disk on the PC and then copy the disk on the COCO to the PC formatted disk, this should correct most problems.

Some PC's cannot read any COCO disks without errors. This is a compatibility problem with different PC controllers and not a problem with the emulator. Try using a different brand of PC or an older model PC. If you are still unable to read your disks and really need the data converted, e-mail me and maybe I can convert the disk for you (my PC has been able to read every disk I've tried so far).

Return to contents:

Technical info - Virtual hard disks:

This information on what are known as the HDV virtual hard disks is provided for users wanting to better understand the operation of the emulator and for programmers writing their own emulators wanting to add support for this format and/or the creation of PC utilities to work with the HDV virtual disk format.

Currently the COCO emulator does not support hard disks. This is the current HDV format that is used by other TRS-80 emulators and is provided so a compatible hard disk driver can be written for the COCO.

The existing HDV format has been extended to support 1024 cylinder hard drives using the WD1010 hard drive controller emulation.

Disk header:

Virtual hard disks have a 256 byte disk header which is initialized when the user creates a new virtual disk. This header may be modified before or after a virtual disk has been formatted to change some of its characteristics.

Byte 0 & 1 | Identifier 56h & CBh
Byte 2 | Version: set to 11h when file created (version 1.1)
Byte 3 | Checksum of bytes 0-31 (excepting byte 3) XORed with 4Ch
Byte 4 | Number of 256 byte blocks in header: should be 1 (anything other than 1 is not supported by this emulator)
Byte 5 | -unused- Currently set to 4 for compatibility
Byte 6 | Media type: 0 for hard disk
Byte 7 | Bit 7 set if hard disk is write protected, all other bits -unused-
Byte 8 & 9 | -unused-
Byte 10 | FFh = created with this emulator
Byte 11 | -unused- (DOS type)
Byte 12 | Creation month
Byte 13 | Creation day
Byte 14 | Creation year (offset from 1900)
Byte 15-26 | -unused-
Byte 27 | If 'byte 10' = FFh then bits 0-1 contains high bits of cylinder count (max value 1024) else -unused-
Byte 28 | If 'byte 10' = FFh then contains low byte of cylinder count else contains total number of cylinders on disk
Byte 29 | Number of sectors per cylinder This value must be divisible by 32. A value of 00h = 256 sectors
Byte 30 | -unused- but is set to 'byte 29' divided by 16 when file created (granules per cylinder)
Byte 31 | -unused- but is set to 1 when file created (directory cylinder)
Byte 32-63 | Volume label, set to TRS80 or COCO when file is created (31 bytes terminated by 00h)
Byte 64-71 | -unused- (Creation filename)
Byte 72-255 | -unused-

WARNING: Once hard disk support is added to the COCO emulator this file layout may have minor changes.

Return to contents:

Technical Info - Enhanced MC6809 instructions

The emulator has a set of enhanced MC6809 instructions. These instructions allow COCO programs to interface with the PC's disk drives, ports, memory and other hardware. These instructions also add high level math functions to the MC6809 instruction set.

NOTE: These instructions are only available in the emulators.

The following links contain a list of the enhanced instructions and documentation for each instruction.

Enhanced Instruction Documentation (on-line)

Enhanced Instruction Documentation (Microsoft Word 96k)

Return to contents:

Technical Info - Memory mapped PC I/O commands

In addition to the enhanced MC6809 instructions described above the emulator can also interface with the PC using memory mapped commands. These commands provide an easier to use interface when writing programs in BASIC or other high level language eliminating the need for machine language calls.

The memory mapped I/O commands allow access to the I/O functions between $10 and $1F as defined in the Enhanced Instruction Documentation. Access to the other enhanced instructions 00-$0F are also possible but are less useful in BASIC programs.

These memory mapped I/O commands also allow access to the PC's hardware clock, PC's I/O ports & PC mouse.

These memory mapped functions use the MC6809 memory address $FFE0-FFEF:

Memory addresses $FFE0-$FFE7 allow access to up to 16 different sets of I/O data. These data sets can be either 8bit or 16bit values. The set of data available is determined by memory address $FFEF. When a value between 0 and 15 is written to $FFEF the desired set of data is mapped into memory $FFE0-FFE7. When the data set is 16bit, each memory address must be read/written twice to load/store the 16 bit value.

When accessing 16bit values, each read/write of memory $FFE0-FFE7 toggles which 8bits are available. Therefore when accessing 16bit data knowing which 8bits are currently available is very important. To make this possible, anytime $FFEF is written to, the high 8bits of the 16bit word is always selected. Then by accessing each memory address twice the programmer will always know which 8bits of the 16bit value are available.

For example to write the 16bit value of $1234 to $FFE0 do the following:

POKE &HFFEF, 3: REM TO INSURE THE HIGH 8BITS OF DATA SET 3 ARE SELECTED
POKE &HFFE0,&H12
POKE &HFFE0,&H34

After writing &H34 to the low 8bits of &HFFE0, $FFE0-$FFE7 are again pointing to the high 8bits. To read the data back, writing to $FFEF is not necessary since we know which 8bits are selected. A read or write to any address $FFE0-$FFE7 controls which 8bits all the memory addresses $FFE0-$FFE7 point to.

For example executing the following:

POKE &HFFEF, 3: REM TO INSURE THE HIGH 8BITS OF DATA SET 3 ARE SELECTED
PRINT PEEK(HFFE0)
POKE &HFFE1,0

would print the high 8bit value of the 16bit value stored in $FFE0 and then write a zero to the low 8bits of the 16bit value stored at $FFE1. This is more than likely not what the programmer wanted.

Writing to memory address $FFEE is used to execute enhanced MC6809 instructions. Valid values are $00-$1F. Each value corresponds to the second byte of an enhanced instruction. A write to $FFEE of a valid command executes the corresponding enhanced instruction. The instruction uses the values stored in memory addresses $FFE0-$FFE7 instead of the work area defined by register U and memory addresses $FFE8-$FFE9 instead of registers A & B that the instruction would have used when executed using assembler language. Memory addresses $FFE0-FFE9 must be initialized before execution of an enhanced instruction.

Reading from memory address $FFEE will return the status of the last enhanced instruction executed.

Memory addresses $FFE0-$FFE7 must be initilized to data set 0 by writing zero to $FFEF. Then, the up to 8 bytes of data used by the enhanced instruction is loaded into memory addresses $FFE0-$FFE7. Memory address $FFE8-$FFE9 always point to the last values sent to or returned by the last enhanced instruction executed, regardless of the setting of $FFEF.

The values stored in memory address $FFE8-$FFE9 are loaded into register A & B when executing enhanced MC6809 instructions. After an enhanced instruction's execution $FFE8 contains the register A value and $FFE9 contains register CC (condition codes) returned by the enhanced instruction.

Some program listings of BASIC programs are available as examples of using the memory mapped I/O commands:

BASIC Examples

Return to contents:

Technical info - Memory mapped PC mouse functions:

The PC's mouse can be accessed from BASIC, assembler and other COCO languages through memory mapped I/O (see previous topic). Through simple reads and writes to COCO memory a COCO program can read the PC's mouse buttons and get its X & Y coordinates.

Writing a value of 4 to $FFEF will make the mouse I/O values available for access. The mouse values are 16bit and require two reads or writes to access all the values except for the buttons and sensitivity. These two 8bit values are also 16bit but the 8bit value is mirrored so a single read or write will access these values.

To read the PC mouse the program needs to read memory address $FFE0. This will load the X & Y coordinate values and return the current button status.

The button status shows which buttons have been pushed and which are currently pushed. Once a particular button has been pushed that flag will remain set until it is cleared by writing a zero to its bit at memory address $FFE0.

To get the current X & Y coordinates the program must read $FFE1 (X coordinate) and $FFE2 (Y coordinate) twice. For example the X coordinate is, the first value read at $FFE1 multiplied by 256 plus the second value read at $FFE1. The same is true for the Y coordinate.

Note: This assumes that the high byte of the 16bit value is available first. A read from memory address $FFEF will insure this condition. From that point on as long as the program always reads or writes each mouse I/O address twice the program will always be sure of the value available at each address.

The X & Y coordinate value returned is based on the PC's mouse movement and the minimum, maximum and sensitivity values loaded for the X & Y coordinates. The coordinate returned will always be in the range of the minimum and maximum values. The min/max values are 16bit values and are read and written the same way the actual coordinates are. The sensitivity is an 8bit value. The low 4bits the X axis sensitivity, the high 4bits the Y axis sensitivity. The larger the value the more sensitive that axis is.

Once the minimum, maximum and sensitivity values are loaded a program only need read $FFE0 to read the PC mouse buttons and update the X & Y coordinates then read $FFE1 & $FFE2 to read the X & Y coordinates. The emulator will insure the returned X & Y coordinates are always within the defined range. A program can also move the mouse to a new position by writing that new position to the X & Y coordinates. Note: no check is done to insure the new position is within the defined range, this must be done by the program.

See the BASIC programming examples, PGM4 for an example of how to use the PC mouse I/O function.

BASIC Examples

Return to contents:

Technical info - Keyboard maps:

The COCO emulator support two keyboard maps. These files determine the relationship between the PC keyboard and the COCO keyboard. Each key on the PC keyboard can be mapped to a key on the COCO keyboard. More than one PC key can be mapped to the same COCO key (ex. Backspace & left arrow are both mapped to left arrow on the COCO keyboard).

Each keyboard map file contains 512 bytes which are organized in pairs. The first 128 byte pairs are unshifted keys the last 128 are the same keys shifted. The PC communicates with its keyboard using scancodes. Each PC key has a scancode and each scancode has a matching 2 byte value in the keyboard map. For example the 'ENTER' key has a scancode of 28, therefore the 2 keyboard map values at 2 times 28 plus 1 (57), contains the COCO keyboard value for an unshifted 'ENTER' key. The map values 2 times 28 plus 257 (313), contains the COCO keyboard value for a shifted 'ENTER' key.

Below is a graphic of a standard PC keyboard layout showing the scancodes for each key. All the scancodes shown correspond to a keyboard map entry. The PC key's table entry can be found by multiplying the scancode by 2 and adding 1 for unshifted values or adding 257 for shifted values.

Note: The scancodes for the cursor keys are not the actual scancodes but the scancode plus 32 because the actual scancodes are the same as for the number pad. The PC prefixes these keys with a special code. The emulator adds 32 to these prefixed scancodes so they can have their own keyboard map entries.

As said before each scancode points to a two byte pair. The second byte is the entry type, it has the following values:

bit 0 | If clear then this is an unshifted COCO key When this key is pushed a value corresponding to the first byte of this map entry will be stored in the COCO keyboard memory matrix.
bit 0 | If set then this is a shifted COCO key When this key is pushed a value corresponding to the first byte of this map entry will be stored in the COCO keyboard memory matrix. A shift will also be stored in the matrix.
bit 1 | -reserved-
bit 2 | If bit 2 is set then this key is also used as a joystick emulator key. Bits 4-6 is the joystick value that the key will change. Values for bits 4-6 are: 000 - joystick up 001 - joystick down 010 - joystick left 011 - joystick right 100 - right joystick button 101 - left joystick button 110 - extra button 111 - extra button
The above bits are valid only if bit 7 is clear
128 | No function Pushing this key does nothing in the emulator
129 | Command function These keys execute emulator command functions like rebooting the emulator (F10). These map entries should not be modified. Incorrect entries to this type of entry can result in emulator functions not working, emulator lockups and system crashes.
130 | Shift Key Whenever this key is pushed and held the emulator will use the second half of the keyboard map. The first byte of this type of entry contains the type of shift key. For the COCO this value should always be 1.

The following table is to be used to find the first byte of the keyboard map value for entry type 0. The values in this table are in hex.

For example. If you look at the PC scancode graphic you will see that the 'ESC' key has a scan code of 1. If you look at the 3rd byte of the PCCOCO keyboard map file you will see a value of 38 (26 hex). Looking at the able above shows a value of 26H represents the COCO 'BREAK' key. The 'BREAK' key is in row 6 column 2 for the COCO keyboard matrix.

The 4th byte of the keyboard map file is a zero. This means the key is unshifted. If this value was 1 then anytime 'BREAK' was pushed the emulator would also push the COCO's shift key. This features allows keys that are not shifted on a PC keyboard to be shifted on the COCO keyboard (like '=') or shifted keys to be unshifted (like "@").

The following table is to be used to find the first byte of the keyboard map value for entry type 1. The values in this table are in hex.

For example. If you look at the PC scancode graphic you will see that the '= +' key has a scan code of 13. If you look at the 27th byte of the PCCOCO keyboard map file you will see a value of 85 (55 hex). Looking at the able above shows a value of 55H represents the COCO '- =' key. The '- =' key is in row 5 column 5 for the COCO keyboard matrix.

The 4th byte of the keyboard map file is a one. This means the key is shifted. When this key is pushed the COCO will be sent the '- =' key along with a shift key.

Most of the PC keys mapped to the COCO layout in the first half of the keyboard map will have an entry type of 0 since this section is used when neither of the PC shift keys are pushed. Most of the PC keys mapped to the COCO layout in the second half of the keyboard map will have an entry type of 1 since this section is used when either of the PC shift keys are pushed. Also, in most cases the first byte of a key entry in the first half of the map will be the same as the one in the second part of the map since it is just the shifted value of the other. Some of the PC keys however will have very different values in each half of the map (like' = +') for example because of the differences between the PC and COCO keyboard layouts.

I hope this documentation will give users the information needed to create custom keyboard layouts.

Return to contents:

Technical info - Cartridge .CAR files

The emulator supports cartridge ROM images. These images are raw dumps of an actual cartridge ROM. The load address is assumed to be $C000 and the length is assumed to be the actual file length with a maximum length of $3F00.

Because PC-DOS filenames are not very descriptive and a cartridge may contain hardware in addition to the ROM there needed to be a way to maintain this information easily and without having to modify the actual ROM image. To do this the emulator creates and maintains .CAR files. These files contain important information about a cartridge. This file is created when a cartridge ROM is first loaded and most of its information can be changed by the user.

Below is the actual file structure. Most of the items can be changed within the emulator on the Multi-Pak screen. The rest should never need to be changed but can be by using a hex file editor the file layout below .

Byte 0-3 | Identifier 'CART'
Byte 4 | Write protect: If this byte is zero, the emulator automatically updates any changes to the .CAR file when a cartridge is removed or upon exiting the emulator. If this byte is non-zero changes made to a loaded cartridge's options are not saved.

Byte 5 & 6

Length of ROM image:
This value is created when a cartridge ROM image is loaded for the first time. It contains the actual length of the image to a maximum of $3F00.
If this value is modified and is smaller then the actual ROM image length only the number of bytes in this field will be loaded.
If the value is modified to a value larger than the actual ROM image length this field will be changed to the actual ROM image length the next time the cartridge is loaded.

WARNING: Bytes are entered in reverse order (ex. $2000 would be entered, byte 5=00, byte 6=20).

Byte 7 | Cartridge label color: Contains a value between 0 & 15.
Byte 8 | Cartridge label text color: Contains a value between 0 & 15.
Byte 9 | Hardware options addressed using SCS* (spare select signal) Bit 0: Floppy Disk Controller Bit 1-7: reserved for additional hardware
Byte 10 | Hardware options addresses using CTS* (cartridge select signal) Bit 0-6: reserved for addition hardware Bit 7: cartridge interrupt signal (enabled if set) By default the cartridge interrupt signal is set enabled when the .CAR file is initalized for a new ROM image.
Byte 11 | Hardware options addressed whenever cartridge is inserted in Multi-Pak Interface: Bit 0: Orchestra-90 Music Synthesizer Bit 1-7: reserved for additional hardware
Byte 12 | reserved
Byte 14-37 | Cartridge description #1 (zero terminated)
byte 38-61 | Cartridge description #2 (zero terminated)

All the fields in the .CAR file are user modifiable within the emulator except bytes 4-6.
The proper hardware option field is automatically updated when the user enables a hardware option.

Return to contents:

Technical Info - Emulator memory map:

The Color Computer emulator memory map is as follows:

Memory range | Read | Write
FF00 | PIA #0 data port A | PIA #0 data port A
FF01 | PIA #0 control port A | PIA #0 control port A
FF02 | PIA #0 data port B | PIA #0 data port B
FF03 | PIA #0 control port B | PIA #0 control port B
FF04-FF1F | mirrors of FF00-FF03 | mirrors of FF00-FF03
FF20 | PIA #1 data port A | PIA #1 data port A
FF21 | PIA #1 control port A | PIA #1 control port A
FF22 | PIA #1 data port B | PIA #1 data port B
FF23 | PIA #1 control port B | PIA #1 control port B
FF24-FF3F | mirrors of FF20-FF23 | mirrors of FF20-FF23
FF40-FF47 | Disk select register | -unused-
FF48 | FDC status register | FDC command register
FF49 | FDC track register | FDC track register
FF4A | FDC sector register | FDC sector register
FF4B | FDC data register | FDC data register
FF40-FF5F | SCS - spare select signal | SCS - spare select signal Used by bank switched ROM cartridges Bit 0 = A14 Bit 1 = A15 Bit 2 = A16 Bit 3 = A17
FF68 & FF6C | Receiver data register | Transmit data register
FF69 & FF6D | Soft reset | Status register
FF6A & FF6E | Command register | Command register
FF6B & FF6F | Control register | Control register
Deluxe RS-232 Program Pak $FF68-$FF6B Direct Connect Modem Pak $FF6C-$FF6F
FF7A | -unused- | Orcherstra-90 (left channel)
FF7B | -unused- | Orchestra-90 (right channel)
FF7F | Multi-Pak programming register Get active slots bits 0-1: number of active SCS slot (FDC) bits 4-5: number of active CTS slot (ROM) bits 2,3,6,7: all set means value given is select switch setting | Multi-Pak programming register Set active slots bits 0-1: number of active SCS slot (FDC) bits 4-5: number of active CTS slot (ROM)
FFC0-FFC5 | -unused- | Graphics mode V0-V2
FFC6-FFD3 | -unused- | Video page offset
FFD8-FFD9 | -unused- | CPU speed (.895mhz / 1.78mhz)
FFDE-FFDF | -unused- | ROM enable/disable
FFF0-FFF1 | reserved | -unused-
FFF2-FFF3 | SWI3 vector | -unused-
FFF4-FFF5 | SWI2 vector | -unused-
FFF6-FFF7 | FIRQ vector | -unused-
FFF8-FFF9 | IRQ vector | -unused-
FFFA-FFFB | SWI vector | -unused-
FFFC-FFFD | NMI vector | -unused-
FFFE-FFFF | Reset vector | -unused-
All vectors are mapped to Color BASIC ROM address $BBF2-$BBFF

The Color Computer emulator support an enhanced memory map as follows:

Memory range | Read | Write
FFE0-FFE7 | up to 16 sets of 8bit or 16bit I/O data | up to 16 sets of 8bit or 16bit I/O data
FFE8 | CPU register A used by enhanced instructions | CPU register A used by enhanced instructions
FFE9 | CPU register B used by enhanced instructions -or- CPU register CC returned by enhanced instructions | CPU register B used by enhanced instructions
FFEA-FFED | -unused- | -unused-
FFEE | Enhanced instruction status register | Enhanced instruction command register Valid command are $00-$1F
FFEF | Bits 0-3: equal current data set for $FFE0-$FFE7 Bit 4: if set means $FFE0-$FFE7 are 16bit values Bit 5-7: -unused- | Bits 0-3: set the current data set for $FFE0-FFE7 Bit 4-7: -unused-
Anytime $FFEF is accessed the high/low 8bit toggle for 16bit values is set to the high 8 bits.
Memory address $FFEF equal $00
FFE0-FFE7 | Work area used by enhanced instructions | Work area used by enhanced instructions
Memory address $FFEF equal $01
FFE0 | seconds in BCD format | -unused-
Reading this address loads $FFE0-$FFE6 with the PC's system date and time.
FFE1 | minutes in BCD format | -unused-
FFE2 | hours in BCD format | -unused-
FFE3 | year in BCD format | -unused-
FFE4 | day in BCD format | -unused-
FFE5 | month in BCD format | -unused-
FFE6 | century in BCD format (19 or 20) | -unused-
Memory address $FFEF equal $02
FFE0-FFE7 | Read PC port | Write PC port
The PC port read or written is defined by the 16bit values stored in $FFE0-$FFE7 when $FFEF equal $03
Memory address $FFEF equal $03
FFE0-FFE7 | 16bit PC port address | 16bit PC port address
Memory address $FFEF equal $04
FFE0 | read PC mouse and load buttons and current X & Y coordinates bit 0: left button was pushed bit 1: right button was pushed bit 2: middle button was pushed bit 4: left button is pushed bit 5: right button is pushed bit 6: middle button is pushed | set mouse buttons bit 0: set/clear left button was pushed bit 1: set/clear right button was pushed bit 2: set/clear middle button was pushed
Reading this address load $FFE1 & FFE2 with the current mouse X & Y coordinates. These coordinates will always be greater than or equal to the minimum and less than or equal to the maximum.
FFE1 | get mouse current X coordinate | set mouse current X coordinate
FFE2 | get mouse current Y coordinate | set mouse current Y coordinate
FFE3 | get mouse min X coordinate | set mouse min X coordinate
FFE4 | get mouse min Y coordinate | set mouse min Y coordinate
FFE5 | get mouse max X coordinate | set mouse max X coordinate
FFE6 | get mouse max Y coordinate | set mouse max Y coordinate
Make sure that the minimum value is less than the maximum value or the X & Y coordinates will be unknown.
FFE7 | get mouse sensitivity bits 0-3: X axis (0-15) bits 4-7: Y axis (0-15) | set mouse sensitivity bits 0-3: X axis (0-15) bits 4-7: Y axis (0-15)
All X & Y coordinate values are 16bit. The mouse buttons and sensitivity are 8bit values mirrored into 16 bits. WARNING Memory mapped mouse functions are disabled when COCO joystick emulation is set to PC mouse.
Memory address $FFEF equal $05 - $0F -undefined-

Return to contents: