# comodore-iec-emu — IEC listener PoC A proof-of-concept Commodore **IEC listener** device on a Raspberry Pi Zero 2 W. It behaves like a printer (default device address **4**): it never talks back, it only **listens**, and it debug-prints in real time everything the C64 sends. The timing-critical IEC handshake (ATN ack, per-bit sampling, EOI) runs in a **Linux kernel module**; a **Python** userspace program decodes and pretty-prints. See [`_plans/poc-listener-printer-PLAN.md`](_plans/poc-listener-printer-PLAN.md) for the full design and [`_research/`](_research/) for the grounding research. ## Layout ``` kernel/ # the kernel module (real-time half) — builds on the Pi iec_listener.c ISR, IRQ-off bit loop, listener state machine, /dev/iec0 iec_listener.h shared struct iec_record + ioctls (mirrors device.py) iec_lines.h logical line layer, direct BCM register access (hot path) iec_timing.h handshake timing constants Makefile out-of-tree build + load/unload/overlay targets dts/ device-tree overlay (pin reservation / pulls) iecpoc/ # Python userspace (everything else) — host-testable device.py /dev/iec0 record stream (wire format, replay) decode.py command-byte + event decoder petscii.py PETSCII -> display glyphs log.py the annotated trace formatter (PLAN §8) main.py CLI (--address, --raw, --logfile, --replay) tests/ # host-runnable, no Pi/kernel needed docs/ # wiring.md, kernel-notes.md ``` ## Userspace (Phase 0 — works on any host) ```bash python3 -m venv .venv && .venv/bin/pip install -e '.[dev]' .venv/bin/pytest # run the tests .venv/bin/python -m tests.fixtures # (re)generate the capture .venv/bin/python -m iecpoc.main --replay tests/data/hello_world_session.bin ``` On the Pi, point it at the live device instead: ```bash .venv/bin/python -m iecpoc.main --address 4 # reads /dev/iec0 ``` Example trace (the `OPEN 1,4 / PRINT# / CLOSE` session, abbreviated): ``` [IDLE] waiting for ATN [ATN] asserted -> DATA low (ack) [CMD] $24 LISTEN 4 (addressed: ME) [CMD] $60 DATA SA=0 [ATN] released -> LISTENER [DATA] $48 'H' ... [DATA] $0D [ATN] released -> not addressed -> IDLE ``` ## Kernel module (on the Pi) ```bash sudo apt install raspberrypi-kernel-headers cd kernel && make sudo insmod iec_listener.ko address=4 # creates /dev/iec0 sudo rmmod iec_listener # releases DATA on unload ``` See [`docs/wiring.md`](docs/wiring.md) for the level-shifter circuit and the pre-C64 bring-up checklist, and [`docs/kernel-notes.md`](docs/kernel-notes.md) for the resolved kernel real-time decisions. ## Status - **Phase 0 (userspace + tests):** complete, runs on any host. - **Phase 1 (kernel command phase):** skeleton present; needs Pi bring-up. - **Phase 2 (data-phase reception):** the real experiment; tune timing on real hardware. See PLAN.md §9 for the phased milestones.