|
|
@@ -5,6 +5,11 @@ Turbo Modula-2 Z80 interpreter as a **64-bit MC64** machine, driven by `mc64-spe
|
|
|
Constraints honored so far: no analysis/disassembly of `.MCD` binaries — work from
|
|
|
`.mod`/`.def` sources and the spec; module library compiled separately with `-c`.
|
|
|
|
|
|
+Companion effort: `m2c/` — a single-pass Modula-2 compiler (Coco/R `M2c.atg`
|
|
|
++ hand-written `SymTab`, `MGen`) targeting MC64 `.MC4` images runnable
|
|
|
+under `mcint`. Currently at **step 11** (separate compilation units),
|
|
|
+157/157 tests green (see `summary_step1.md` … `summary_step11.md`).
|
|
|
+
|
|
|
## Project layout
|
|
|
- `M2compiler/mc64/` — all VM code:
|
|
|
`Memory, Local, Stack, Console, FileIO, Global, Instruction, Extended, Interpreter,
|
|
|
@@ -12,15 +17,32 @@ Constraints honored so far: no analysis/disassembly of `.MCD` binaries — work
|
|
|
programs `MC64.mod` (REPL harness), `mkdemo.mod` (`boot.MC4`), `mcint.mod`
|
|
|
(`mcint file.MC4` launcher), `mkdtest.mod` (`example.MC4` generator);
|
|
|
built: `mkdemo`, `mc64`, `mcint`, `mkdtest`, `boot.MC4`, `example.MC4`.
|
|
|
+- `M2compiler/m2c/` — the compiler: `M2c.atg` (grammar + attributes),
|
|
|
+ `compiler.frm` (**true source** of generated `M2c.mod`: driver loop +
|
|
|
+ `Msg` table via `-->Errors`), `SymTab` (checking), `MGen` (MC64
|
|
|
+ emitter), `M2cS`/`M2cP` (CR-generated scanner/parser — never edit),
|
|
|
+ `M2c` (binary), `run_tests.sh`, `tests/` (`.mod` + `.def` + `.LST`),
|
|
|
+ per-test `.MC4` in `m2c/` root, `Showcase*.mod` tours.
|
|
|
- `M2compiler/mc64-spec.md` — normative spec (§5.2 frames, §7.1 descriptor layout,
|
|
|
§8.3 checksum rule, §9.3 SYSTEM ABI, §10 0x12/0x40 sub-dispatches, §11 opcode table,
|
|
|
§12 switch/strings, §16 GNU-M2 ISO implementation notes).
|
|
|
- `M2compiler/m-code-summary-64.md`, `m-code-summary.md` — opcode summaries.
|
|
|
+- `M2compiler/summary_stepN.md` — per-compiler-step log (commit + tag per step).
|
|
|
- `M2compiler/Resources/Turbo-reloaded/Reversing-Turbo-Modula2-main/MCode_specification/`
|
|
|
— reference Turbo M2 sources (used only as Modula-2 sources, never binary analysis).
|
|
|
- gm2 ISO libs at `.../gcc/x86_64-pc-linux-gnu/16.0.1/m2/m2iso/`; `FIO` at `m2/m2pim/`.
|
|
|
|
|
|
## Build recipes
|
|
|
+Compiler (`m2c/`, via `./build.sh`, needs `CR` at `../../CocoGm2/CR`):
|
|
|
+regenerates `M2cS`/`M2cP`/`M2c.mod` from `M2c.atg` (+ `Msg` from `M2c.err`
|
|
|
+via `compiler.frm`), recompiles, relinks `./M2c`. NEVER edit `M2c.mod`
|
|
|
+(directly: it is overwritten), `M2cS.*`, `M2cP.*` — edit `M2c.atg`,
|
|
|
+`compiler.frm`, `SymTab.*`, `MGen.*` instead.
|
|
|
+Single-file: `./M2c tests/foo.mod` (writes `tests/foo.LST`, `FOO.MC4`).
|
|
|
+Multi-file session (step 11): `./M2c lib.def impl.mod prog.mod`
|
|
|
+(definitions, then implementations, then exactly one program;
|
|
|
+one `<Prog>.MC4`, one `.LST` per input, fail-fast).
|
|
|
+Test: `bash run_tests.sh` (needs `../mc64/mcint`).
|
|
|
Libraries are pre-compiled and linked as `.o` (only the program `.mod` is passed to the
|
|
|
link step — multiple `.mod` files would collide on `main`):
|
|
|
```
|
|
|
@@ -37,6 +59,14 @@ gm2 -fiso -o mkdtest mkdtest.mod FileIO.o Console.o
|
|
|
- `./mkdemo` -> `boot.MC4` ; `./mc64` -> `Hello MC64!` + `[vm end]` (0) ;
|
|
|
`./mcint boot.MC4` -> `Hello MC64!` (0) ; `./mcint` -> usage (0) ;
|
|
|
`./mcint nope.MC4` -> Fatal (1).
|
|
|
+- `m2c`: 157/157 (`bash run_tests.sh`): steps 1–10 incl. step-10.1
|
|
|
+ init/proc-slot fix (regression `b_mix` -> 110, Showcase3 -> 168);
|
|
|
+ step 11 adds 7 multi-file run tests (`d_basic` 25, `d_from` 12,
|
|
|
+ `d_multi` 82, `d_init` 510, `d_func` 55, `d_type` 1122, `d_case` 25)
|
|
|
+ + 6 single-error rejections (201/231/200). Tags `step1` … `step11`
|
|
|
+ (+ `step2.1`, `step10.1` fixes) all point at their commits.
|
|
|
+- Showcases (hand-computed tours): 157, 83, 168, 225 — all print
|
|
|
+ their value under `mcint`.
|
|
|
- `./mkdtest` -> `example.MC4` (1350 B, MC64 format) ; `./mcint example.MC4` — 24/24
|
|
|
opcode-checks pass (exit 0):
|
|
|
loop g:=2g+1 x10 = 2047; add/sub/mul/div/mod; bit_and/or/xor & power2;
|
|
|
@@ -90,8 +120,20 @@ gm2 -fiso -o mkdtest mkdtest.mod FileIO.o Console.o
|
|
|
`IOChan.Look/Skip` char loop (avoids `TextRead`'s "current line" blocking);
|
|
|
stores chars up to (not incl.) line mark or EOF, NUL-terminates, pushes byte count.
|
|
|
Documented in spec §9.3; readtest.MC4 exercises it.
|
|
|
+- m2c gotchas: `M2c.mod`/`M2cS`/`M2cP` are REGENERATED by CR every build —
|
|
|
+ edit `M2c.atg`, `compiler.frm`, `SymTab`, `MGen` only. Coco/R numbers
|
|
|
+ tokens by first occurrence: new keywords go in end-of-file productions
|
|
|
+ and `M2c.mod`'s `Msg` re-mirrors `M2c.err` automatically (verify names
|
|
|
+ after grammar edits). gm2 `HALT` aborts (SIGABRT) — use loop `EXIT`
|
|
|
+ for clean failures. Proc/init table slots share one pool
|
|
|
+ (`SymTab.AllocInitNum`; step-10.1 fixed init stealing a later proc's
|
|
|
+ slot). Never compare against a negative literal inside an `&` chain
|
|
|
+ in `.atg` actions (gm2 16.0.1 ICE in generated `M2cP.mod`; nest IFs).
|
|
|
|
|
|
## Current task state
|
|
|
+- m2c step 11 — separate compilation units: **DONE** (`d3856a1`,
|
|
|
+ tag `step11`) — `DEFINITION`/`IMPLEMENTATION`/`IMPORT` across files
|
|
|
+ into one `.MC4` (157/157 tests, Showcase4 -> 225).
|
|
|
- Writing an **MC4 example file** to exercise the interpreter: **DONE** —
|
|
|
`mkdtest.mod` -> `example.MC4`, 24 opcode-checks pass under `./mcint`.
|
|
|
- **stdin support for SYSTEM service 2**: **DONE** — implemented in `Interpreter.mod`
|
|
|
@@ -99,6 +141,10 @@ gm2 -fiso -o mkdtest mkdtest.mod FileIO.o Console.o
|
|
|
line reads + line-mark consumption under piped input.
|
|
|
|
|
|
## Next steps / open ideas
|
|
|
+- m2c hardening (deferred): `M.x` as `VAR` actual (still 233),
|
|
|
+ `WITH`-field/`CHAR` tails as `VAR` actuals, open-to-open,
|
|
|
+ multi-`.MC4` images with `depCount` loading, circular imports,
|
|
|
+ opaque types, `LONGINT`/`LONGREAL` quads, procedure types, `cones`.
|
|
|
- 16→64 translation pass so classic 16-bit Z80 `.MCD` binaries can run on `mcint`
|
|
|
(widening MCode operands 2→8 bytes and descriptor fields); currently unimplemented.
|
|
|
- Hardware traps 0x45 (button/joystick/audio — currently no-ops), `0x08` output with
|