Files
vt1200/reference/memory-space-map.md
T

90 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# VT1200 firmware — address-space map (spike, 2026-10-16)
What external memory/register space the v2.2 firmware actually touches, derived by
sweeping every scalar operand in the disassembled image plus the raw ROM images, and
cross-checked against the MAME harness.
## Conventions (read this first)
* The TMS34010 is **bit-addressed**. The firmware stores **bit addresses**.
A physical **byte** address is `bit >> 3`; **Ghidra** byte address = `0x07E40000 + file_offset`.
* This document gives **bit addresses** (the value the firmware actually stores) and,
in parentheses, the **byte** address (`bit>>3`).
* "harness unit" (the MAME driver's `BOARD_BASE` and the access-log address) = `bit >> 4`
= 2 bytes per unit. The four known windows are written `0x5800000` (bit) here, which is
the driver's `0x5800000` too (leading-zero identical) — but the **log** prints them as
`0x0580000D` style (`bit>>4`). Do not mix the two.
* Evidence codes: **CONST** = scalar-operand count from the Ghidra sweep (96,801
instructions / 1,177 distinct `@`-targets); **XREF** = string/reference cross-check;
**LOG** = `harness/mame/board-4w.log` / `board-access.log`; **SG** = service guide.
* "Driver?" = does `harness/mame/vt1200.cpp` currently map it.
## Region table
| # | bit range | byte range | what | evidence | driver? | conf. |
|---|---|---|---|---|---|---|
| 1 | `0x0000000`–`0x2000000` | `0x000000`–`0x400000` | **Main RAM** 4 MiB | mem-test at `0x07EDFF22` walks SIMM regions at bit `0x800000`/`0x1000000`… (byte 1 MiB/2 MiB); ~5 000 absolute globals; POST clears RAM; SG: 1 MiB onboard + 3×1 MiB SIMM | yes (bit `0`–`0x1FFFFFF`) | **HIGH** |
| 2 | `0xC0000000`–`0xC00001FF` | (on-chip) | **CPU on-chip registers** (DPYCTL/DPYSTRT/DPYADR/CONTROL/…) | datasheet + `MEMORY_MAP.md`; 72 absolute operands | internal | **HIGH** |
| 3 | `0x5000000` | `0xA00000` | **Memory-config / SIMM-presence input port.** bits 0,1,2 = "SIMM 1/2/3 installed" | CONST 3 `@` reads; XREF: `0x07E58FB2`/`0x07E58FCE`/`0x07E58FEA` read bits 0/1/2 then print `Not Present`/`SIMM n installed` (strings @ file `0x0199BD`…); also read at `0x07EDFF22` | **no** | **HIGH** |
| 4 | `0x5600000` | `0xAC0000` | **Unidentified board register block** — most-touched unmodelled region. Offsets `+0x00 +0x10 +0x20 +0x30 +0x80 +0x100 +0x200 +0x380` | CONST **110** `@` accesses (2nd only to RAM/the known windows); writer at `0x07E6CB62`, adjacent to X-server strings (`no screens found`) | **no** | **HIGH** region / **LOW** identity |
| 5 | `0x5800000` | `0xB00000` | **DMA/board data port** | CONST 10 `@`; LOG; paired with #6; firmware `>>3`s a bit address into it (byte-addressed device) | yes | **HIGH** |
| 6 | `0x5900000` | `0xB20000` | **DMA/board command port** | CONST 6 `@`; LOG (commands 0,1,2,4,0x42) | yes | **HIGH** |
| 7 | `0x6000000` | `0xC00000` | **Candidate NVRAM.** ~2 KiB user-settings copy writes here; sits in a 256 KiB device slot between #6 and #8 | CONST 2 (`0x07E957F4`, `0x07E95974` push it as the destination of a settings copy/metadata routine `0x07E966D0`); XREF: adjacent `Old user settings layout.` / `User settings invalid.` | **no** | **MEDIUM-LOW** |
| 8 | `0x6200000` | `0xC40000` | **Board window** (STATUS `+0x10`, CMD `+0x20`, config `+0xD0`) | CONST 26 `@`; LOG; `BRINGUP_LOG.md` | yes | **HIGH** |
| 9 | `0x6400000` | `0xC80000` | **Board window** incl. monitor-selection switch (bits 4–6 of `+0xD0`) | CONST 24 `@`; LOG; `BRINGUP_LOG.md` | yes | **HIGH** |
| 10 | `0x6800000` | `0xD00000` | **Ethernet MAC-address ROM** | CONST 2 (`0x07E46112`); the 6-iteration byte-read loop `0x07E4611E`–`0x07E4613A` copies 6 bytes (a MAC) from this base; SG level-1 "Ethernet address ROM test" | **no** | **HIGH** |
| 11 | `0x4000000` | `0x800000` | **VRAM / framebuffer — candidate only** | `MOVI 0x4000000,B4` at `0x07E40AB0` in the reset-bank video init (`video_regs_init`); the `B` file holds bitmap bases | **no** | **LOW** |
### Notes on rows 3–7 (the peripheral map is regular)
The byte addresses `0xA00000`, `0xAC0000`, `0xB00000`, `0xB20000`, `0xC00000`,
`0xC40000`, `0xC80000`, `0xD00000` look like a decoded device map with a ~256 KiB
slot at the top end (`0xC00000`, `0xC40000`, `0xC80000`, `0xD00000` are exactly
`0x40000` apart). That regularity is *circumstantial* evidence for rows 7 and 10.
## What was ruled out (candidates that are NOT regions)
These appear constantly as large 32-bit constants but are **not** addresses:
| value (bit) | file offsets | why it is not an address |
|---|---|---|
| `0x112A880`, `0x2DC6C0`, `0x5B8D80`, `0x927C0`, `0x281F90`, `0x3600400`, `0x4000500` | reset/POST bank | `DSJS` delay-loop counters (gate 2 in `BRINGUP_LOG.md`) and per-monitor display-format constants selected by the monitor switch (`0x07E4089E`–`0x07E4090A`) |
| `0x800000`, `0x1000000` | `0x07EDFF2C`… | **RAM region boundaries** used by the SIMM memory test (byte 1 MiB / 2 MiB), not devices |
| `0x4000000` (all but one) | 49 aligned hits | bit-26 mask OR/AND, not an address |
| byte `0x600000`–`0x7E40000` "buckets" | whole image | code bytes / data tables. A naive raw scan of every 32-bit word is ~25 % false positives. The `0x5000000`/`0x6000000` "cluster" in bank 6 is **unaligned byte noise** inside sparse tables — re-scanning 16-bit-aligned collapses it. |
## What remains unknown (stated plainly)
1. **Exact VRAM base and size.** The framebuffer is *not* accessed by any absolute operand
(the `@`-sweep finds it nowhere), so it is addressed indirectly — via the `B`-register
file and/or the `DPYADR` (`0xC00001E0`) register, both set at runtime from a RAM screen
descriptor. Row 11 is the only static hint and is **weak**. It is also possible the
video DRAM sits *behind* the `0x5800000`/`0x5900000` DMA pair rather than being CPU-visible.
2. **Identity of row 4 (`0x5600000`).** Heavy, display-adjacent, but I could not name the device.
3. **NVRAM extent / exact base** (row 7), and whether the MAC ROM (row 10) is 16-bit-wide
(the read loop advances 2 bytes per MAC byte).
4. **Extent of each I/O block** — only point accesses are observed, so sizes are guessed from slot spacing.
## How to reproduce
```
# operand sweep (Ghidra, session required):
# iterate listing.getInstructions(True); for each Scalar operand >= 0x10000 and < 0x40000000,
# bucket by (value>>3)>>16. Filter to "@0x<value>" operands for true memory accesses.
python3 tools/ptr_constants.py vt1200_v22.bin # ROM-pointer subset
# raw aligned scan: 32-bit LE words whose (value>>3) lands in the region of interest
```
## Durable Ghidra annotations added (project `ghidra/vt1200`, program `vt1200_v22.bin`)
* Memory blocks (with comments) created at each region byte base:
`VRAM_800000_CAND`, `IO_50_SIMM_MEMCFG`, `IO_56_BOARD_REG`, `IO_58_DMA_DATA`,
`IO_59_DMA_CMD`, `IO_60_NVRAM_CAND`, `IO_62_WIN2`, `IO_64_WIN3`, `IO_68_MACROM`.
* Functions created/named: `video_regs_init`, `io5600000_screen_init`,
`nvr_user_settings_validate`, `io_settings_copy_expand`, `io_settings_copy_linear`,
`io_settings_restore`, `io5800_5900_init`, `io5800_status_read`,
`keyboard_mouse_irq_handler`, `led_control_1/2`.
* PRE comments at the key access sites (MAC read, SIMM read, `0x5600000` write,
settings copy, SIMM mem-test, video init, `B4=0x4000000`).
* Program saved. Function count 8 → 19; memory blocks 1 → 10.