Skip to content

Full suite of Kaypro machine support: Kaypro II, 4/83, 4-84, TurboROM 3.4, TOML-configurable machines at boot time#2

Open
eneilson-zz wants to merge 119 commits intoivanizag:mainfrom
eneilson-zz:main
Open

Full suite of Kaypro machine support: Kaypro II, 4/83, 4-84, TurboROM 3.4, TOML-configurable machines at boot time#2
eneilson-zz wants to merge 119 commits intoivanizag:mainfrom
eneilson-zz:main

Conversation

@eneilson-zz
Copy link

New Features

TOML Configuration System

  • New izkaypro.toml config file for runtime model selection
  • No recompilation needed to switch between Kaypro models
  • Supported presets: kaypro_ii, kaypro4_83, kaypro4_84, turbo_rom, custom
  • ROM and disk images loaded from external files with embedded fallbacks
  • Command-line disk arguments override config file settings

Machine Name Display

  • Top border line now shows centered machine name (e.g., //===Kaypro 4-84===\\)

Kaypro 4-84 Support with SY6545 CRTC

  • New SY6545 CRTC emulation (src/sy6545.rs) for Kaypro 2X/4/84
  • Port-based VRAM access via transparent addressing protocol
  • Attribute RAM support (reverse, dim, blink, underline)
  • Hardware scrolling via R12:R13 start address

DSDD Disk Drive Support

  • Support added for DSDD Kaypro disk formats

TurboROM 3.4 Support

  • ROM shadowing to RAM for ROMs that switch bank modes
  • Index pulse simulation (FDC status bit 1)
  • Fixed NMI timing for HALT instruction handling

Bug Fixes

ROM Banking Fix

  • Fixed critical bug where .COM programs crashed after loading
  • ROM reads now correctly return ROM data (not overwritten RAM) when in ROM bank mode

CRTC Cursor Artifact Fix

  • VRAM writes via port 0x1F only accepted when R31 (strobe) is selected
  • Prevents stray writes after cursor register updates

Memory Mapping Fix

  • 0x3000-0x3FFF treated as regular RAM in CRTC mode (not memory-mapped VRAM)
  • Fixes display issues in programs like Zork that use this memory region

FDC (WD1793) Enhancements

  • Added STEP, STEP IN, STEP OUT commands with direction tracking
  • READ ADDRESS returns physical head position (not software track register)
  • Index pulse simulation for TurboROM format detection

New Files

File Purpose
src/config.rs TOML configuration parsing and model presets
src/sy6545.rs SY6545 CRTC emulation
src/diagnostics.rs ROM/RAM/VRAM diagnostic tests
izkaypro.toml Default configuration file
AGENTS.md Technical documentation for AI assistants

eneilson-zz and others added 10 commits February 3, 2026 16:00
Key changes:
- SY6545 CRTC emulation for Kaypro 2X/4/84 (81-292a ROM)
  - Transparent addressing via R18/R19 registers
  - Port 0x1F dual-purpose: strobe control and character data
  - Hardware scrolling with 2KB VRAM circular buffer
  - Auto-increment of addr_latch after character writes

- Port 0x14 system PIO for Kaypro 4-84
  - Bank switching, drive select, motor, density, side select
  - Different bit layout from port 0x1C (Kaypro II)

- Memory-mapped VRAM to CRTC VRAM translation
  - Converts 128-byte stride to 80-byte linear layout

- Built-in diagnostics (cargo run -- -d)
  - ROM checksum test
  - RAM sliding-data and address-data tests

- CP/M diagnostic program (EMUTEST.COM on drive B)
  - ROM test with code relocation to 0x8000
  - RAM tests matching diag4.mac methodology

- CRTC trace option (-v, --crtc-trace)

- Documentation in AGENTS.md with protocol details

Amp-Thread-ID: https://ampcode.com/threads/T-019c21ba-b84b-750e-861e-202e464c5a85
Co-authored-by: Amp <amp@ampcode.com>
- Implement diag4-compatible VRAM read/write protocol in emutest.asm
- Fix port 0x1F to detect diag4 mode (reg_index == 0x1F) for data writes
- Remove strobe-based R18/R19 split - always update addr_latch
- Add test_vram_via_ports() diagnostic that tests port I/O protocol
- Update AGENTS.md with dual-protocol documentation
- VRAM test passes: tests 2KB range 0x000-0x7FF

Amp-Thread-ID: https://ampcode.com/threads/T-019c2589-141e-70cb-be42-f3dfcc476f31
Co-authored-by: Amp <amp@ampcode.com>
The issue was stray writes to port 0x1F (VIDMEM) being accepted when
R31 (strobe register) was not selected. After the ROM wrote cursor
registers R14/R15 via port 0x1D, subsequent writes to port 0x1F would
corrupt attribute RAM because addr_latch still pointed to 0x800.

Fix: Only accept VRAM writes via port 0x1F when reg_index == 0x1F (R31).
This enforces the proper SY6545 transparent addressing protocol where
R31 must be selected before VRAM access.

Amp-Thread-ID: https://ampcode.com/threads/T-019c26e1-4a85-71bd-9d04-558d5e578ca6
Co-authored-by: Amp <amp@ampcode.com>
- New izkaypro.toml config file to select Kaypro model at runtime
- Supported models: kaypro_ii, kaypro4_83, kaypro4_84, turbo_rom, custom
- ROM and disk images loaded from files with embedded fallbacks
- Fixed ROM banking bug where .COM programs would crash
- Updated default boot disk to cpm22g-rom292a.img for Kaypro 4/84
- Command-line disk arguments override config file settings

Amp-Thread-ID: https://ampcode.com/threads/T-019c2aa9-6855-71cf-9b84-63a529e992eb
Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019c2b9c-d62a-76eb-926d-2aecacab808e
Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019c2b9c-d62a-76eb-926d-2aecacab808e
Co-authored-by: Amp <amp@ampcode.com>
@ivanizag
Copy link
Owner

ivanizag commented Feb 5, 2026

Wow. Nice work. It will take me a while to review it, but I will.

eneilson-zz and others added 19 commits February 5, 2026 20:15
Amp-Thread-ID: https://ampcode.com/threads/T-019c2b9c-d62a-76eb-926d-2aecacab808e
Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019c2b9c-d62a-76eb-926d-2aecacab808e
Co-authored-by: Amp <amp@ampcode.com>
- WRITE TRACK (format) with WD1793 data stream parsing
- Multi-sector read/write with auto-increment
- Write-protect status for read-only disk images
- DRQ status bit, STEP/STEP IN/STEP OUT commands
- Force Interrupt improvements
- Disk writes persist to image files

Amp-Thread-ID: https://ampcode.com/threads/T-019c349c-2843-7373-8e35-c2802af5faa1
Co-authored-by: Amp <amp@ampcode.com>
New features:
- Basic KayPLUS 84 ROM support (kplus84.rom) with SIO interrupt-driven
  keyboard (IM2 vectoring) and configurable side1_sector_base for
  KayPLUS-formatted disks (sector IDs 0-9 on both sides)
- Headless boot test suite (--boot-test) that verifies 81-292a,
  TurboROM, and KayPLUS 84 all boot to the A> prompt
- nmi_vector_is_safe() utility that inspects mapped memory at 0x0066

Bug fixes:
- NMI delivery reworked: replaced 10M-instruction delay with HALT-only
  pending latch, correctly handling both HALT-based ROMs (81-292a,
  TurboROM) and polling-based ROMs (KayPLUS)
- FDC READ ADDRESS: BUSY persists for a status-read countdown, sector
  register updated per WD1793 datasheet, sector ID base respects
  side1_sector_base
- FDC get_status(): removed spurious get_data() call, DRQ/index pulse
  reporting corrected for Type I vs Type II/III status
- Sector mapping fix for KayPLUS disks in sector_index()

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019c3873-546a-72d4-b66d-a333d27dfd0f
- SY6545 CRTC: auto-increment addr_latch on port 0x1F read/write.
  Fixes KayPLUS clear screen (Ctrl-Z) which relies on auto-increment
  for consecutive VRAM writes. The 81-292a ROM is unaffected as it
  re-programs R18:R19 before each access.

- NMI delivery: add deadline-based fallback for non-HALTing programs.
  After 10M instructions, deliver NMI if nmi_vector_is_safe() confirms
  a proper handler at 0x0066. Fixes DIAG4 and similar polling programs.

- Add kayplus_84 as a first-class model preset in config.

- Remove ~150 lines of debug trace instrumentation from diagnostics.rs
  and last_command from floppy_controller.rs.

- Remove stale disks/kayplus1.img, restore izkaypro.toml defaults.

Amp-Thread-ID: https://ampcode.com/threads/T-019c3981-834b-76bb-ab0d-899c23b58523
Co-authored-by: Amp <amp@ampcode.com>
Add overflow/underflow handling in get_data() and put_data() for formats
with sector sizes != 512 bytes (256-byte Osborne, 1024-byte Advent).
BUSY is no longer cleared immediately on sector completion; instead
get_status() clears it when the program polls without data access.

Add status_polls_without_data abandonment detection: if the program
polls status 10 times without reading/writing data, the transfer is
considered abandoned and BUSY clears.

Add diagnostic accessors for crash tracing.

Amp-Thread-ID: https://ampcode.com/threads/T-019c39f8-09fb-75c8-bd7f-8c5fd02113a6
Co-authored-by: Amp <amp@ampcode.com>
…ndex layout

- Add write_protected field to Media, decoupled from file handle
- Split sector_index into per-track geometry path and flat layout fallback
- Simplify track_stride_per_side to sectors_per_side * sector_size
- All 10 format tests and 3 boot tests pass

Amp-Thread-ID: https://ampcode.com/threads/T-019c3ef3-4a3b-72da-880e-962873336117
Co-authored-by: Amp <amp@ampcode.com>
On the real WD1793, READ/WRITE SECTOR stays BUSY while scanning
for the sector ID. After ~5 revolutions, BUSY clears and RNF is set.
Previously we set only RNF without BUSY, which caused KayPLUS to
miss the completion NMI and hang at HALT.

Amp-Thread-ID: https://ampcode.com/threads/T-019c3ef3-4a3b-72da-880e-962873336117
Co-authored-by: Amp <amp@ampcode.com>
- get_status() preserves RNF/error bits when clearing BUSY
- READ/WRITE SECTOR set BUSY|RNF on sector-not-found (real WD1793 behavior)
- Remove DSDD-on-SSSD test (format.com writes N=0 but expects N=1 sectors)
- Osborne SSSD format.com verify failure is a known limitation:
  format.com writes 10 sectors with N=0 (128 bytes) but verifies 20,
  expecting sectors 11-20 which don't exist on the formatted track

Amp-Thread-ID: https://ampcode.com/threads/T-019c3ef3-4a3b-72da-880e-962873336117
Co-authored-by: Amp <amp@ampcode.com>
After the last byte of a READ SECTOR, the dummy-byte path was
overwriting self.data with 0x00. Programs using HALT+INI loops
read one extra byte beyond the sector data (for the completion
NMI), and the 0x00 corrupted the verify buffer. Fix: retain
the last real data byte instead of overwriting with 0x00.

Also update Xerox 820-II DSDD test to use the real mixed-density
format (Track 0 SD, rest DD) and add a mixed-density test with
unique per-sector fill data to catch offset/data corruption.

Amp-Thread-ID: https://ampcode.com/threads/T-019c3f40-9922-701d-bc66-c8213c5e2c7a
Co-authored-by: Amp <amp@ampcode.com>
Remove z80dasm disassembly dumps (0, 0x0100, 0x0359), debug log files,
unused disk images (kayplus2, kayplus_install, osborne-blank,
test-cpm22-dsdd-blank), and update izkaypro.toml and blank disk images.

Amp-Thread-ID: https://ampcode.com/threads/T-019c3f7c-3f08-755d-bda4-89f05c1de5d1
Co-authored-by: Amp <amp@ampcode.com>
READ ADDRESS on a non-existent side (e.g., side 1 of an SSDD disk)
returned RNF without BUSY, causing the BIOS to HALT waiting for an
NMI that never came. Fix: set BUSY|RNF with a countdown (matching
real WD1793 behavior where the chip stays BUSY scanning for sector
headers before timing out). Also fix get_status() to preserve error
bits when clearing BUSY, instead of resetting to NoError.

Add test_ssdd_disk_in_dsdd_machine unit test to verify the fix.

Amp-Thread-ID: https://ampcode.com/threads/T-019c3f7c-3f08-755d-bda4-89f05c1de5d1
Co-authored-by: Amp <amp@ampcode.com>
- Add src/renderer.rs: character ROM loader, VRAM→pixel buffer rendering
- Support 2KB (81-146a, 8-row) and 4KB (81-235/81-187, 16-row) chargen ROMs
- Handle inverted pixel polarity for Kaypro II ROM
- Scanline doubling for 8-row ROMs (CRT-like 4:3 aspect ratio)
- Add --gui flag gated by 'gui' feature (minifb crate)
- Add run_gui() with instruction batching, NMI, SIO, clock throttling
- Disable keyboard idle_sleep_enabled in GUI mode (prevents hang)
- ESC key checked after update_with_buffer for clean macOS exit
- Add chargen ROM files: 81-146a.rom, 81-187.rom, 81-235.rom
- All 7 boot tests pass

Amp-Thread-ID: https://ampcode.com/threads/T-019cb4f4-055c-70cf-ab7e-fca8bc7a610d
- Add gui_mode, gui_key_queue, gui_command_queue to Keyboard struct
- consume_input() drains GUI queues when gui_mode=true, skips stdin
- is_key_pressed() skips idle sleep in gui_mode (prevents hang)
- Map minifb::Key to ASCII via minifb_key_letter/minifb_key_digit helpers
- Support Shift (uppercase/symbols) and Ctrl (control codes) modifiers
- Map F1-F9 to Command enum (Help, Quit, SelectDisk, TraceCPU, etc.)
- Arrow keys map to 0xF1-0xF4 (same codes as terminal ANSI parsing)
- All 7 boot tests pass

Amp-Thread-ID: https://ampcode.com/threads/T-019cb4f4-055c-70cf-ab7e-fca8bc7a610d
… support

- GUI rendering via minifb using actual Kaypro chargen ROMs (--chargen flag)
- Supports all models: 2KB (81-146a) and 4KB (81-235, 81-187) chargen ROMs
- Scanline doubling for 8-row models (Kaypro II) for CRT-like aspect ratio
- Video attributes: reverse, dim, blink, underline, cursor via SY6545 CRTC
- Full keyboard input: letters, digits, punctuation, arrows, Ctrl/Shift
- All function keys: help overlay, status overlay, disk dialogs (rfd),
  speed input, save BIOS, CPU trace toggle
- Fix GUI F5 handler: set disk_in_drive/motor_on and patch Kaypro 10 ROM
  drive type table after loading floppy (matches terminal behavior)
- Rename --gui flag to --chargen
- Update README with chargen feature, ultimate model, and new CLI options

Amp-Thread-ID: https://ampcode.com/threads/T-019cb53e-ea9b-75c9-9937-59481ee5a89b
- Add --phosphor flag with presets: green (default), amber, white, blue
- Add --phosphor-fg, --phosphor-bg, --phosphor-dim for custom hex colors
- Rename --gui to --chargen; gui feature now compiled by default
- Add kpgraphic.txt documentation and Harry.bas test program to mbasic.img
- Update README with chargen feature, phosphor options, and CLI reference
- All 5 phases complete: rendering, keyboard, attributes, function keys,
  multi-model support

Amp-Thread-ID: https://ampcode.com/threads/T-019cb53e-ea9b-75c9-9937-59481ee5a89b
- ESC key sends 0x1B to emulated machine instead of exiting (CP/M programs use ESC)
- ESC still dismisses overlays (speed input, help, status) when active
- macOS: patch NSWindowStyleMaskMiniaturizable via objc_msgSend for minimize button
- ARM64-safe objc_msgSend using typed function pointer transmute (not variadic)
- Window resize enabled (resize: true in WindowOptions)
- Force X11 backend on Linux (minifb Wayland lacks window decorations)
- Remove GUI debug logging (eprintln counter/PC dump)
- Add Linux build dependencies to README
- Document Rust 1.87+ requirement

Amp-Thread-ID: https://ampcode.com/threads/T-019cb673-a912-759c-8e88-b20afc067b10
…tion

Add graphical rendering backend using character generator ROMs (--chargen flag):
- Renders emulated VRAM through actual Kaypro chargen ROMs (81-146a, 81-235, 81-187)
- Phosphor color presets: green (default), amber, white, blue
- Custom phosphor colors via --phosphor-fg/bg/dim hex overrides
- Full keyboard input via minifb window with Shift/Ctrl modifiers
- GUI overlays for help (F1), status (F2), speed input (F9), disk select (F5/F6)
- Supports all models: 2KB 8-row ROMs (Kaypro II) with scanline doubling,
  4KB 16-row ROMs (4/84, Kaypro 10, TurboROM, KayPLUS)
- Character attributes: reverse, dim, blink, underline, cursor rendering
- Cross-platform: macOS (Cocoa), Windows (WinAPI), Linux (X11)
- Updated Utilities disk image
- Updated README with chargen screenshot

Amp-Thread-ID: https://ampcode.com/threads/T-019cb6eb-1e5a-7388-88e6-76b06cb8f016
Linux musl target cannot dynamically link X11/GTK libraries needed by
minifb and rfd. Build Linux with --no-default-features (terminal-only).
macOS and Windows build with default features (GUI included).

Amp-Thread-ID: https://ampcode.com/threads/T-019cb6eb-1e5a-7388-88e6-76b06cb8f016
…ing for Kaypro 10

- F5/F6 now trigger on key release instead of key press in GUI mode,
  preventing the rfd dialog from swallowing the key-up event on macOS
  and causing every other press to be missed.
- Kaypro 10 floppy drive label changed from A to C (matching hardware).
- F6 disabled in GUI mode for Kaypro 10 (single floppy drive only).

Amp-Thread-ID: https://ampcode.com/threads/T-019cbb1a-4335-7722-b3ea-25c1045edff2
…tory

resolve_path() tries the executable's directory first (for installed/release
layouts where roms/ and disks/ sit next to the binary), then falls back to
the current working directory (for cargo run during development).

Amp-Thread-ID: https://ampcode.com/threads/T-019cbb1a-4335-7722-b3ea-25c1045edff2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants