Py6502v REPL + Dual Execution

CSA-102 §11.9 (Weeks 1-4). Write Py6502v on the left; the same source runs unchanged on host CPython AND on an emulated 6502 side-by-side. The dual-execution match indicator IS the pedagogy. CSA-102 catalog.

The dual-execution property

Py6502v is Python-syntax-compatible. The exact same source runs in two places: under host CPython using academy-supplied shim modules (py6502v.std.io, py6502v.std.types) which interpret the typed-int + print contract directly; AND through the academy compiler to 6502 assembly which runs on an emulated 6502 (real py65 core) in your browser. When you click Run both, the two outputs are compared. They match. That match is the contract.

Pyodide loads on first run (about 15 seconds the first time; cached after). The compiler is the real py6502v Round 5 package; the emulator is the same py65 the compiler's run subcommand uses on the host. No translation layer; no "close enough." If a divergence ever shows up here, it is a real compiler bug.

Py6502v source sourcePython-syntax-compatible subset

Generated 6502 asm asmcodegen.generate(module)

Click Compile to see the generated 6502 assembly.

Emulator state py65post-run

A$00
X$00
Y$00
PC$0000
SP$FF
P$00
No run yet.

Host CPython output hostpython3 src.py

Click Run host to execute under CPython.

Emulated 6502 output 6502UART capture via $D000

Click Run emulated to compile + execute on py65.
· Dual-execution match: not yet run. Click Run both to compare.
How this works. Pyodide hosts a real CPython 3.12 + the academy's py6502v Round 5 package + py65 in your browser. Host run: writes the source to the in-browser filesystem and exec()s it with the academy shim modules on the path. Emulated run: the same compiler the CLI uses (load_projectgenerateload_runtime_sourceassemblePy65Runner.run) runs end-to-end, captures the UART output at $D000, and the halt status at $D0FF. The two captured strings are compared character-by-character. Identical = the contract holds.