Skip to content

A4091 Zorro III SCSI controller: board, 53C710 register model, minimal SCRIPTS engine#123

Open
codewiz wants to merge 10 commits into
LinuxJedi:mainfrom
codewiz:feat/a4091-board
Open

A4091 Zorro III SCSI controller: board, 53C710 register model, minimal SCRIPTS engine#123
codewiz wants to merge 10 commits into
LinuxJedi:mainfrom
codewiz:feat/a4091-board

Conversation

@codewiz

@codewiz codewiz commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Adds the Commodore A4091 as a Zorro III device board, staged bring-up guided by the open-source A4091 boot ROM and its ncr7xx hardware validation tool (https://github.com/A4091/a4091-software).

What's done

  • Board scaffolding ([a4091] config section: rom + unit0..6): Z3 autoconfig identity (mfg 514 / product 84 / 16M window / DiagArea vector $0200), nibble-wide autoboot ROM serving with 32K-image mirroring, DIP-switch byte at $8C0003, debugger peeks for the ROM region. First Z3 device board on the Zorro chain -- the existing routing handled it with no changes.
  • 53C710 register file: 64-byte register file mirrored across the whole $800000+ IO window (the board decodes only the low address bits; the driver's +$40 TEMP/SCRATCH write shadows depend on this), QEMU-matched reset values, CTEST8 chip revision, CTEST5 ADCK/BBCK strobes.
  • DMA FIFO (4 lanes x 16 deep, 9-bit entries via CTEST6/CTEST4.FBL2, parity through CTEST7/CTEST2, live CTEST1 and DSTAT.DFE) and SCSI FIFO (8 deep via SODL/CTEST4.SFWR and CTEST3, generated odd/even parity per SCNTL1.AESP, count in SSTAT2).
  • Interrupt plumbing: ISTAT.ABRT/RST strobes, computed DIP/SIP, read-to-clear DSTAT/SSTAT0, DIEN/SIEN gating, level-sensitive INT2 (semantics from Amiberry's qemuvga lsi53c710 core).
  • Minimal SCRIPTS engine: DSP-triggered execution, instruction fetch by bus-master DMA (works for chip/slow/Z2/Z3 RAM -- the existing decode is address-width agnostic), MOVE-immediate-to-register (native register numbering), Memory Move (including moves targeting the board's own register window, via a new DeviceHost::for_slot self-window lookup), RETURN, INT; undecodable fetches raise DSTAT.IID like real silicon on a garbage fetch. COPPERLINE_DIAG_A4091=1 logs fetches and moves.
  • Serial TCP sink (also split out as serial: bidirectional TCP sink (mode = "tcp") #121; this branch carries the same commit and will lose it on rebase once serial: bidirectional TCP sink (mode = "tcp") #121 merges): bridges Paula's serial port to a host TCP listener so an AUX: shell gives a scriptable remote console -- that is how this branch was tested.

How it was tested

  • 20 unit tests covering the ROM nibble encoding, register file, shadows, strobes, both FIFOs, interrupts, and the SCRIPTS engine (including the self-window Memory Move).
  • The ncr7xx validation tool from a4091-software, run on the emulated machine over the serial console after every increment. Current score, in suite order: Device access PASS, Register test PASS, DMA FIFO PASS, SCSI FIFO PASS, Bus access (interrupts + SCRIPTS fetch address-pin walk, incl. Z3 addresses) PASS, DMA test PASS, DMA copy PASS, DMA copy perf PASS. Only the SCSI pin test still fails (see below).
  • The ROM's DiagArea boots end to end: expansion.library reassembles it from the nibble-wide window, a4091.device loads, passes its walking-bits hardware self-test, and starts issuing SCSI SELECT scripts (which the engine currently answers with an illegal-instruction stop, so the driver times out cleanly and the machine boots normally).

Still missing

  • SCSI bus model / pin test: SBDL/SBCL must reflect the driven SODL/SOCL values (the 53C710 maps several read and write registers to different addresses; today they alias one storage cell), plus SCSI bus reset behavior.
  • The SCSI phase engine: block moves, SELECT/WAIT DISCONNECT/table-indirect addressing, bridging to the existing scsi.rs target layer so a4091.device can actually scan the bus and mount [a4091] drive images (currently parsed but ignored, with a warning).
  • Timing: SCRIPTS run synchronously inside the triggering register write; no bus arbitration is modelled (same simplification as the A2091's DMA).

Not caused by this branch, but found with it: ncr7xx's DMA test fails when MuForce+MuGuardianAngel trap the buffer writes (the AllocMem/FreeMem/AllocAbs alignment trick makes MuGA treat the buffer as free memory) -- the first trapped write loses its data somewhere in the 68040 access-error writeback path. Real hardware and Amiberry survive the same sequence. Will be reproduced and fixed separately.

🤖 Generated with Claude Code

codewiz and others added 10 commits July 6, 2026 01:07
The board autoconfigs (Commodore product 84, 16M Z3, DiagArea at $0200),
serves the boot ROM nibble-wide, and models the 53C710 register file with
the +$40 write shadows, mirrored across the register window. Passes the
driver's walking-bits hardware test; the SCRIPTS processor is still a stub.
Configured via a new [a4091] section (rom + unit0..6, drives ignored for
now).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Increment DNAD / decrement DBC by the bus width and self-clear, as
validated by the ncr7xx tool's register test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bridges Paula's serial port to a host TCP listener, like UAE's TCP:
serial device (same default port 1234; override with [serial] listen).
With an AUX: shell on the Amiga side this gives a remote AmigaDOS
console.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
FMT nibble = $F (all DMA FIFO byte lanes empty), per the ncr7xx DMA
FIFO test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Four 16-deep byte lanes with parity behind CTEST6/CTEST4.FBL2;
CTEST1 and DSTAT.DFE computed from fill state; parity via CTEST7.3
in, CTEST2.3 out. ISTAT.RST restores reset state, as a4091_reset()
in the driver does. Passes the ncr7xx DMA FIFO test sequence.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8-deep FIFO behind SODL/CTEST4.SFWR pushes and CTEST3 pops; odd
parity generated, even under SCNTL1.AESP; count in SSTAT2, parity
out via CTEST2.SFP. Passes the ncr7xx SCSI FIFO test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ISTAT.ABRT latches DSTAT.ABRT; DIP/SIP computed from pending causes;
DSTAT/SSTAT0 clear on read; INT2 asserted for DIEN/SIEN-enabled
causes, QEMU lsi53c710 semantics.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DSP writes start execution: instructions fetched by DMA from host
memory (incl. Z3 space), MOVE-immediate-to-register with native
register numbering, RETURN via TEMP, INT loads DSPS and raises
DSTAT.SIR; undecodable fetches stop with DSTAT.IID. Enough for the
ncr7xx bus access test's address-pin probes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DeviceHost learns which slot it serves so a bus master can recognize
DMA addresses inside its own configured window; the A4091 self-test
Memory Moves the chip's own SCRATCH to TEMP through board space.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codewiz

codewiz commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

@reinauer , wanna review?

@LinuxJedi

Copy link
Copy Markdown
Owner

Oh wow! That kills one todo list item that has been in the back of my head. I won’t be able to review this one until I’m at a computer in a couple of days.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds initial emulation support for the Commodore A4091 Zorro III SCSI-2 controller (board identity + nibble-wide ROM + NCR 53C710 register model and a minimal SCRIPTS subset) and introduces a new bidirectional TCP-backed serial sink for remote console workflows.

Changes:

  • Add new A4091 Zorro III device board, config surface ([a4091]), and machine wiring to place it on the Zorro chain.
  • Implement an initial 53C710 register window model (mirroring, reset values, FIFOs, interrupt plumbing) plus a minimal SCRIPTS engine sufficient for ROM self-tests.
  • Add SerialMode::Tcp and a TcpSerialSink implementation (plus launcher UI integration when built with midi feature).

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/zorro.rs Adds BoardSpec::a4091() identity/config for the new Zorro III device board.
src/zorro_device.rs Adds DeviceHost::for_slot() + self-window lookup, and wires BoardDevice::A4091.
src/video/launcher.rs Extends launcher serial mode cycling to include TCP (in midi builds).
src/serial.rs Implements TcpSerialSink and adds a unit test for basic round-trip behavior.
src/lib.rs Exposes the new a4091 module.
src/emulator.rs Wires SerialMode::Tcp and adds A4091 board creation/config validation at runtime.
src/cpu.rs Constructs DeviceHost with slot awareness for Zorro device accesses.
src/config.rs Adds [a4091] config parsing and introduces SerialMode::Tcp + [serial] listen.
src/bus.rs Passes slot-aware DeviceHost into per-device ticking.
src/a4091.rs New A4091 implementation: ROM nibble serving, 53C710 register/FIFO/IRQ behavior, minimal SCRIPTS engine, and unit tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/serial.rs
Comment on lines +133 to +138
for &b in &buf[..n] {
if tx.send(b).is_err() {
return;
}
reader_buffered.fetch_add(1, std::sync::atomic::Ordering::Release);
}
Comment thread src/emulator.rs
Comment on lines +1791 to +1794
log::warn!(
"a4091: the 53C710 SCSI core is not implemented yet; \
[a4091] drive images are ignored"
);
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.

3 participants