CPU: Motorola 68000
Rotate, Line, and Sound CPU's also
68k feeds data to the Rotate CPU which converts 3D coordinates (I assume) to 2D lines. Line CPU takes 2D line coordinates and converts to horizontal line segments which are passed to the fill hardware.
Format of data sent from Rotate CPU to line CPU
Data is split into 16-bit words. The high nibble of each word (AND with 0xF000 to isolate) is used to determine which address to jump to in the line CPU's program. The address that does the jump is at 0x10. So if the high nibble is 0x07, then the instruction at 0x10 will jump to 0x07.
|1||This means to increment the data index by 1, and ANDing with 0x0fff may give you the index of the end of the data to be parsed. For parsing purposes, this value may be able to be considered a NOP.|
|2||Set Z-order value. See instruction at 2.|
|3||Set Color Index value. See instruction at 3.|
|4||Special case. This points to a memory offset that describes a polygon with at least three vertices, but it is conditional upon the data that it points to. The 'high' portion of the line CPU's ROM decides whether this nibble gets turned into a 5 or into a 1. (see notes about high section of program)|
|5||Memory offset to a Line or Polygon. (AND with 0x0FFF)
At the memory offset will be (N*2)+1 16-bit words, where N is the number of vertices. If N is 2, then this object will be a line. If N > 2 then this object will be a polygon. The first word will be an X coordinate OR'd with 0x8000. The second word will be a Y coordinate. This pattern continues (X word, followed by Y word) until the object has been fully described. The object is terminated by a 0x9xxx value. The polygon described must be wound counter-clockwise or it won't be rendered correctly (I tested this).
|7||Jump (or pause). I think this says to jump to the value you get by AND'ing with 0x0FFF. Therefore, seeing a 0x7000 means to jump back to the beginning of the program. It's entire operation can be found in instructions 0x7, 0x11, and 0x12.
UPDATE: further examination may be needed as this also may just indicate to pause until this value changes. (the rotate CPU does its work in chunks and puts temporary 0x7000's in memory which it later overwrites once more work has been done) When the high section of the program sees this value, it waits until this value changes (see 0x87, 0x91, and 0x92).
|8||Horizontal coordinate (AND with 0x0FFF to get pixel offset)|
|9||Terminates list of vertices. The lower 12 bits seem to be ignored.|
|A||Sometimes vertical coordinates have an 'A' in front of them. This may have been due to historical reasons, as the most significant nibble seems to be always ignored.|
Line CPU's program description
The line CPU's program is relatively small. It is split into two sections, the low section (0-0x7F) and the high section (0x80-0xFF). Each instruction can do a lot more than typical CPU instructions. For example, one instruction can load memory, perform a math operation, store the memory again, and do a conditional or absolute jump.
The Low Section
The low section of the program is dedicated to decoding almost all the data sent from the rotate CPU, and drawing the lines. It does most of the work. The only 'instruction' it doesn't decode is one that begins with a high nibble of 4.
The High Section
The high section of the program seems to only exist to handle the special case of receiving an 'instruction' with a high nibble of 4. When an 'instruction' with a high nibble of 4 is encountered, the geometry that it points to is examined, and based on the findings, the 4 is replaced with either a 5 (draw it) or a 1 (ignore it).
The algorithm is this:
iX1 = vertex1 & 0x0FFF; iY1 = vertex2 & 0x0FFF; iX2 = vertex3 & 0x0FFF; iY2 = vertex4 & 0x0FFF; iX3 = vertex5 & 0x0FFF; iY3 = vertex6 & 0x0FFF; int iP1 = (iX2 - iX1) * (iY2 - iY3); int iP2 = (iY1 - iY2) * (iX2 - iX3); if ((iP1 >= 0) || (iP2 >= 0)) return 5; else return 1;