5.3 KiB
Ghidra project analysis — Orion-MSXBASIC / MZBAS$.BRU
Program: MZBAS$ — MSX BASIC for the Orion-128 (Z80), tape image loaded at 0x0000.
Banner in the image: MSX system / version 1.2/M / MSX BASIC / Copyright 1983,1993 by Microsoft,OBERON Inc
i.e. the MSX BASIC 2.1 codebase ported to Orion-128 (64K RAM, Z80).
Source file format (MZBAS$.BRU)
Cassette-style image, 33664 (0x8380) bytes:
| Offset | Size | Content |
|---|---|---|
| 0x0000 | 8 | name MZBAS$·· |
| 0x0008 | 2 | load address 0x0000 (LE) |
| 0x000A | 2 | length field 0x8300 (LE; payload is actually 0x8370) |
| 0x000C | 4 | unknown/reserved (00 49 53 D4) |
| 0x0010 | 0x8370 | program image → ram:0x0000–0x836F |
Mapping verified: file offset 0x10 = ram:0000, banner at file 0x8251 = ram:08241.
The tape image contains only the BASIC program (0x0000–0x836F); high memory in the
Ghidra project was modeled separately.
Memory map (as modeled in Ghidra)
| Block | Range | Size | Notes |
|---|---|---|---|
| MB | 0000–BFFF | 48K | BASIC program image (real data ends at 0x836F) |
| SCREEN | C000–EFFF | 12K | MSX screen RAM (uninitialized in image) |
| MON_RAM | F000–F2FF | 768B | character generator (MON_CHARGEN) |
| ORI_F300_CODE | F300–F3FF | 256B | Orion I/O patch code — duplicated in the project from its in-image home at 0x0C22 (bytes identical) |
| IOPORTS | F400–F7FF | 1K | PORT_F400_KBD (keyboard, 10 xrefs), USR1 F500, USR2 F600, EXT F700, FDC regs F701–F708 |
| MONITOR | F800–FFFF | 2K | zeroed in the image; real monitor lives in Orion ROM. SYSINIT does CALL 0xF830 into it |
| PORTS (io space) | 0000–00FE | 255B | e.g. P_SW_MEM io:00F9 (14 xrefs), P_SW_SCR io:00FA |
Entry point and startup
- Entry:
SYSINITat0x0000=JP 0x24A2. 0x24A2:CALL 0xF830(Orion monitor), setsSP, saves it to0x8D01, then initializes the keyboard port (LD A,0xAA / LD HL,0xF400 ...), calls0x0C0A, does a wait-loop on BC/DE counters, and hands control onward.
Major structures found
1. Vector table, 0x0000–~0x00EC
~78 entries of JP nn. The first ~15 slots are 3-byte-aligned with NOP padding
(0x0000 JP 24A2, 0x0008 JP 24C6, 0x0010 JP 24C9, 0x0018 JP 2111,
0x0020 JP 1B55, 0x0028 JP 24CC, …), then densely packed JPs from 0x0038
(JP 03AB, 1AA1, 0228, 022E, 028D, 01EB, 0207, 0241, 1B5B, 04AC, 04F6, 0CE8, …).
This is the built-in command/statement dispatch table; real code starts at ~0x00ED.
2. Command-prefix table, 0x1AAD–~0x1B50
Fixed 16-byte records: 8-byte text + 8 zero bytes:
LOAD", AUTO , GOTO , LIST , RUN␍, SAVE", CLOAD", CONT␍, LIST.␍, …
Used to recognize whole-line commands. Table is pointed to from code at 0x1AA1
(LD HL,0x1AAD / CALL 0x0FF0).
3. Keyword/function lookup table, ~0x3AF5–0x3DA8
Variable-length entries: a short distinguishing fragment of the keyword (1–5 chars)
followed by a 2-byte handler address. Fragments include:
NKEY(INKEY$), PRIN(PRINT), ETUR(RETURN), ESTOR(RESTORE), ESUM(RESUME),
IGHT(RIGHT$), CREE(DECLARE), TRING(STRING), PACE(SPACE$), ARPT(VARPTR),
EFST/EFIN/EFSN/EFDB, ELET, OCAT, FILE, RESE, …
4. Error table, 0x3DAB–~0x4070 (MB_ERRTAB)
Zero-terminated messages, indexed by error code — matches errors.inc:
1 NEXT without FOR, 2 Syntax error, … 19 Line buffer overflow,
0x32 FIELD overflow, 0x33 Internal error, 0x34–0x3B file errors,
plus Orion-specific additions. Followed by " in ", "Ok␍␊", "Break".
5. Character tables, 0x07E2–0x089A
Digit/upper/lower case conversion tables (;1234567890-:, -@abcdefghijklmn, …).
6. Banner & workspace, ~0x8200–0x836F
Code for memory allocation/stack setup (refs to 0x8CC2/0x8CC4, 0x8EAF/0x8EB0/0x8EB2)
immediately followed by the banner strings at 0x8241 and end-of-image code at 0x836F.
7. Orion patch code, image copy at 0x0C22 (= project block F300)
Small I/O routines writing port 0xF9 (LD A,1 / OUT (F9),A) with HL-based loops —
the Orion-128 hardware glue that replaces MSX I/O calls.
Project state / gaps
- 2006 symbols (original Microsoft label names) are present, but:
- 0 functions defined, and no instruction listing outside the few ranges
disassembled in this session (
0x0000–0x005F,0x1A80–0x1B47,0x24A2–0x2501,0xF830–0xF86F). - Auto-analysis is marked complete (nothing left to run); scripts are disabled
(
GHIDRA_MCP_ALLOW_SCRIPTSnot set), so bulk work must go through individual tools.
- 0 functions defined, and no instruction listing outside the few ranges
disassembled in this session (
- High memory (SCREEN/MON_RAM/MONITOR) is placeholder; only F300 patch code and port labels carry real content.
Suggested next steps (for the reconstruction in mzbas.asm)
- Run
reanalyzeor create functions at the vector-table targets to get call graphs. - Walk the dispatch table at
0x0038+— each JP target is a statement handler; naming them from the MSX BASIC 2.1 source (MB_*labels) will anchor the rest. - Reconstruct the global variable block around
0x8C00–0x8F60(pointers seen:0x8CC2/0x8CC4,0x8D01,0x8EAF/0x8EB0/0x8EB2) — these are the BASIC workspace (MB_BASLIM, program pointer, stack, etc. in the original). - The 16-byte command records at
0x1AADand the fragment table at0x3AF5translate directly into assembler tables for sjasmplus.