Every address and name on this page comes from the RACE emulator’s source (main.c, race-memory.c, tlcs900h.c, its comments and constants) and the register list of the emulators.org debugger, which names the video registers;
nothing is read from a real SNK BIOS or from SNK’s technical reference. The CPU’s address space is 24 bits (TLCS-900/H).
The map
| Range | What |
|---|---|
0x000000–0x0000FF | CPU I/O registers (below) |
0x004000–0x006FFF | Work RAM; the BIOS’s own variables are at 0x6F80 and up (BIOS) |
0x007000–0x007FFF | The sound CPU’s 4 KiB RAM, shared (Z80) |
0x008000–0x0087FF | K1GE / K2GE video registers and palettes (below) |
0x008C00 | Sprite palette numbers |
0x009000, 0x009800 | The front and the back scroll plane’s tile maps |
0x200000–0x3FFFFF | Cartridge ROM, the first 16 Mbit (2 MiB): the file from offset 0 |
0x800000–0x9FFFFF | Cartridge ROM, the second 16 Mbit: file offset 0x200000 and up (RACE reads 0x800000 as the second half of its 4 MiB ROM buffer) |
0xFF0000–0xFFFFFF | The BIOS, with the interrupt vector table at 0xFFFF00 |
RACE’s own comment gives the preliminary map as “0x00000000–0x000000ff cpuram, 0x00004000–0x0000ffff ram, 0x00200000–0x003fffff rom (lower 16 Mbit), 0x00800000–0x009fffff rom (higher 16 Mbit), 0x00fffe00–0x00ffffff other ram/rom”.
RACE’s memory reader treats 0x004000–0x017FFF as RAM, which is why the RAM above is not given an upper end here. Reads of unmapped ranges return 0xFF in RACE.
CPU I/O registers
| Address | Name | Meaning |
|---|---|---|
0x20 | T8RUN | 8-bit timer run control (RACE’s name) |
0x22, 0x23 | TREG0, TREG1 | 8-bit timer 0 and 1 registers |
0x24 | T01MOD | 8-bit timers 0 and 1 mode |
0x26, 0x27 | TREG2, TREG3 | 8-bit timer 2 and 3 registers |
0x28 | T23MOD | 8-bit timers 2 and 3 mode |
0x70 | INTLV_RTC_AL | Interrupt level: low nibble the RTC alarm |
0x71 | INTLV_Z80 | High nibble: the interrupt from the Z80 |
0x73 | INTLV_T01 | Low nibble timer 0, high nibble timer 1 |
0x74 | INTLV_T23 | Low nibble timer 2, high nibble timer 3 |
0x79 | INTLV_DMA01 | Low nibble end of DMA 0, high nibble DMA 1 |
0x7A | INTLV_DMA23 | Low nibble end of DMA 2, high nibble DMA 3 |
0xA0 | SND_L | Left channel sound source control: a write reaches the tone chip once the sound CPU is enabled |
0xA1 | SND_R | Right channel sound source control |
0xA2, 0xA3 | DAC_L, DAC_R | Left and right DAC control (written while 0xB8 is 0xAA) |
0xB8 | Z80_RESET | Z80 reset: 0x55 starts the sound CPU, 0xAA stops it |
0xB9 | SND_RESET | Sound source reset control (0x55 and 0xAA) |
0xBA | Z80_NMI | A write raises a non-maskable interrupt in the Z80 |
0xBC | Z80_COMM | A byte shared with the Z80 (its address 0x8000) |
The DMA control registers (DMAS0–DMAS3 at control-register codes 0x00–0x0C, DMAD0–3 at 0x10–0x1C, DMAC0–3 at 0x20, 0x24, 0x28, 0x2C, DMAM0–3 at 0x22, 0x26, 0x2A, 0x2E)
are reached with LDC, not through memory (registers page); RACE keeps the DMA vector bytes at 0x7C–0x7F.
Only the registers named in RACE’s source are listed; the TMP95C061 has many more (ports, the serial channel, the A/D converter).
Video registers
| Address | Name | Meaning |
|---|---|---|
0x8000 | CTRL | Frame 0 priority and interrupt enables: bit 7 enables the V-blank interrupt, bit 6 the H-blank (timer 0) interrupt |
0x8002, 0x8003 | WBA_H, WBA_V | Window origin X, Y |
0x8004, 0x8005 | WSI_H, WSI_V | Window width, height |
0x8008, 0x8009 | RAS_H, RAS_V | Raster position; the visible lines are 0 to 151 and RACE counts to 198 |
0x8012 | OOW_COL | Out-of-window colour select |
0x8020, 0x8021 | SPR_X, SPR_Y | Sprite plane scroll |
0x8030 | MODE | Frame 1 priority: bit 7 swaps the order of the two scroll planes |
0x8032, 0x8033 | PF1_X, PF1_Y | Scroll plane 1 (front) |
0x8034, 0x8035 | PF2_X, PF2_Y | Scroll plane 2 (back) |
0x8100 | BW_PAL | Monochrome palette table |
0x8118 | BG_COL | Background colour select |
0x8200 | COL_PAL | Colour palette table (Pocket Color) |
0x83E0, 0x83F0 | BG_PAL, OOW_PAL | Background and out-of-window colour tables |
0x87E2 | K2GE_MODE | K1GE / K2GE mode: 0x10 is colour |
0x87F0 | GE_LOCK | RACE writes 0x55 here after setting the mode, so the mode registers can no longer be written |
0x8C00 | SPR_PAL | Sprite palette numbers |
0x9000, 0x9800 | TILEMAP_FRONT, TILEMAP_BACK | Scroll plane 1 and 2 tile maps |
The names are those of the emulators.org debugger’s video device, which says they match MAME’s and FBNeo’s K1GE descriptions; the addresses are the ones RACE’s main.c uses. The register bits are not described beyond what is in the table, and the tiles, sprites and palettes are not decoded by the viewer.
The sound CPU (Z80)
A Zilog Z80 plays the sound. RACE maps the Z80’s RAM at its 0x0000 and lets the main CPU see it at 0x7000–0x7FFF; the Z80 sees the sound chip at 0x4000 (noise) and 0x4001 (tone), the byte shared with the main CPU at 0x8000 (the main CPU’s 0xBC),
and a write to 0xC000 raises an interrupt in the main CPU. In RACE a write of 0x55 to 0xB8 or 0xB9 starts the sound CPU and 0xAA stops it; the main CPU’s writes to 0xA0 and 0xA1 reach the tone chip while 0xB8 holds 0x55 and 0xB9 holds 0xAA. A game copies a sound driver to 0x7000 first (that the driver is copied there is the usual arrangement, not something the sources read state). The header does not say where the driver lies in the ROM, so the viewer
disassembles a Z80 program only where you point it (options: file offset and size), with the Z80 decoder.
Not described
- SNK’s own register documentation (the technical reference): the video register bits, the sprite and tile formats, the full list of CPU I/O registers and the exact RAM sizes were not read.
- The exact upper end of RAM and what lies between
0x0100and0x3FFFbeyond the video block.