Case Study: A4091 / 53C710 SCSI driver¶
This is the deep end of the drivers pillar: writing a brand-new SCSI host adapter driver for Amix, for a board the OS was never meant to support, and getting Amix to boot with root, swap and filesystem entirely on it. It pulls together the device-driver model, Zorro AUTOCONFIG, the kernel build and the boot process — all the other driver pages applied at once to a real board.
The work is first-party and reproduced locally in Amiberry on the real Amix 2.1c distribution.
Claims tagged ✅ below were reproduced on the running system; 🟡 claims are emulation-only and need
real-hardware confirmation; 🔴 marks a belief we held and disproved. The source is the
A4091-on-Amix project — src/a4091-wr.c, the src/kernel-patches/, driver.conf,
and its CHANGELOG.md and docs/.
What the A4091 is¶
The A4091 is Commodore's Zorro III SCSI-2 host adapter, built on the NCR/Symbios 53C710 SCSI I/O processor ✅. It is the high-end successor to the Zorro II A2091 (WD33C93), intended for the A3000T/A4000T class.
Its AUTOCONFIG identity and memory window ✅ (src/a4091-wr.c, docs/a4091-53c710-reference.md §0):
| Property | Value | Source |
|---|---|---|
| AutoConfig manufacturer | 0x0202 (Commodore) |
a4091-wr.c A4091_PROD |
| AutoConfig product | 0x54 |
a4091-wr.c A4091_PROD |
| Combined product id | 0x02020054 |
a4091-wr.c #define A4091_PROD 0x02020054 |
er_Type |
0x90 (Zorro III) |
reference §0 |
| Physical board base | 0x40000000 |
a4091-wr.c a4091map() fallback |
| Board window | 0x01000000 (16 MB), sparse |
reference §1 |
| 53C710 register block | board + 0x00800000 → 0x40800000 |
a4091-wr.c SIOP_OFF |
Amix (Commodore's SVR4.0 port to 68030 Amigas, the "2.1c" distribution ✅) shipped with no 53C710 driver and is widely described as Zorro II only ✅ — see Zorro AUTOCONFIG for drivers and Supported hardware. The stock kernel only knows the A2090/A2091 (WD33C93) and the A3000 on-board SCSI. This project wrote a native 53C710 block driver and made the A4091 a first-class, auto-detected SCSI controller alongside them.
The Zorro III obstacle and the sptalloc() solution¶
The board is in Zorro III space, and that is exactly where the stock drivers' trick breaks down.
🔴 "Zorro III is unaddressable" — was thought absolute, is actually an unmapped address range with
a work-around. Amix identity-maps only the low 1 GB of physical address space,
0x00000000–0x3FFFFFFF ✅. That leaves 0x40000000–0x7FFFFFFF unmapped — and the A4091 sits
in it ✅. Zorro II boards are ≤ 24-bit (e.g. the A3000 SCSI at 0xDD0000), so they fall inside the
identity map; that is why the stock WD33C93 drivers can simply dereference the address autocon()
returns. Extending the identity map upward to cover the gap is unsafe — amiga/ml/syms.s places
the page-mapped u-area at 0x40000000 ✅.
Correction (2026-08-14). This section previously attributed that identity map to the 68030's Transparent-Translation registers (
tt0 = 0x003F0143/tt1 = 0x807F0143, fromamiga/ml/ttrap.s). AMIX does not use the TT registers — they read E = 0 on a running kernel, the boot path zeroes them, and the identity map is a section-0 early-termination page descriptor in the MMU root table ✅. Nothing below changes; see how the low 1 GB is really mapped.
The fix is the kernel primitive sptalloc(npages, prot, pfn, flag), which page-table-maps
physical pages into kernel virtual address space ✅. The driver maps the board's AutoConfig page and
the 53C710 register block (src/a4091-wr.c, a4091map()):
#define SIOP_OFF 0x00800000 /* 53C710 register block within the board window */
...
acfg = (volatile uchar *)sptalloc( 1, PG_V, phystopfn( (paddr_t)base), 0); /* board base */
siop = (volatile uchar *)sptalloc( 1, PG_V, phystopfn( (paddr_t)base + SIOP_OFF), 0); /* 53C710 regs */
Post-boot these return working kernel VAs (observed siop = 0x401CA000) and the 53C710 is fully
addressable ✅. DMA is unaffected: the 53C710 bus-masters to Amix RAM at phys 0x07800000+,
which is inside the identity-mapped low 1 GB, so DMA targets are reachable no matter where the
board's registers land in kernel VA ✅. (See Zorro AUTOCONFIG for autocon() and the Zorro III
detection that complements this mapping.)
sptalloc() is the 68030 build's mapping. The 68040/68060 arm of the same driver
(-DA4091_KVA) cannot use it, because there sptalloc() gives a cacheable page: it maps both
register pages non-cacheable with dev_kvmap() and sends every transfer through a DMA-coherence
service (the project's docs/D42-CALL-SHAPE.md) ✅. "DMA is unaffected" is the 68030 line's rule
only; the 030 build does no cache maintenance, which is justified in emulation (data cache off)
only 🟡.
The 53C710 driver model — how it plugs into the Amix SCSI stack¶
✅ The Amix SCSI stack (amiga/alien/) layers like this:
The command unit handed down the stack is struct sdcom (sd.h): cdb[12], the data addr/nbyte,
unit/card, the reading flag, status/okay, and an intr() completion callback ✅. See
the device-driver model for the general switch-table mechanism this sits on top of.
The card registry in sd.c¶
sd.c carries a registry table scsicard[] mapping AutoConfig product ids to queue functions. The
project ships no sd.c: its driver.conf lists one row per board the driver binds, and
amix-kerntools' amix-build generates the sd.c additions from it (gen_sd_patch) ✅:
static struct {
uint pn; /* product number */
bool (*f)( ); /* queuing function */
char *hardwarename;
} scsicard[] = {
0x0202F003, &a3091queue, "A3000 Internal SCSI",
0x02020001, &a2090queue, "A2090 SCSI",
0x02020003, &a2091queue, "A2091 SCSI",
0x02020054, &a4091queue, "A4091 SCSI", /* <- generated from driver.conf */
0xc0de0001, &a4091queue, "A4092 SCSI",
0xc0de0002, &a4091queue, "A4770 SCSI",
};
At the first root open, sd.c init() calls autocon(productid, …) for each row and insert()s the
cards it finds, sorted ascending by board base address ✅:
static void
init( )
{
if (not queue->f)
for (i=0; i<nel( scsicard); ++i) {
int c = 0;
while (autocon( scsicard[i].pn, c, &a, &o))
insert( scsicard[i].f, c++, a, scsicard[i].hardwarename);
}
}
So on a machine with both controllers, the A3000 SCSI (0xDD0000) becomes queue[0] (card 0)
and the A4091 (0x40000000) becomes queue[1] (card 1) — the lower base sorts first ✅. This
ordering is the entire story behind booting root from the A4091 — see
the boot process: root on an A4091 and the phantom-A3000 fix in
Zorro AUTOCONFIG.
Why the stock ordering cannot be trusted at all. Stock
autocon()decides whether the A3000 internal SCSI exists from where the kernel was loaded (end > 0x07000000insupport.c,endbeing the kernel's own end address), never from the hardware ✅ — so it fabricates a card 0 where no controller exists and, on a machine where the kernel loads lower, silently drops the real one (root disk included) while every remaining card renumbers ✅. Both directions produce a machine that cannot find its disk and says nothing. Probe, don't guess — see quirks §41 and the chipset-gated WD33C93 probe that replaces the special case.
amix-build also generates the matching amiga/alien Makefile edit, which adds a4091.o to the
OBJ list (gen_makefile_patch); the project does not ship it.
The driver itself: a4091-wr.c¶
The production driver is src/a4091-wr.c (the READ+WRITE driver) ✅. Its key pieces:
a4091map()—sptalloc-maps the board base and the register block (above;dev_kvmapon the 040/060 arm), and caches the mapping per card so it only happens once. The 68030 build falls back to the known base0x40000000if no base was recorded for the card; the 040/060 arm has no fallback and treats that as "no board" ✅.a4091init()— a 53C710 soft reset followed by minimal polled-mode register init. Reset is via ISTAT bit 6 (not DCNTL — that is the older 53C700) and is not self-clearing, so it is set then explicitly cleared. The init writesSCNTL0=0xCC,SCNTL1=0x20,DCNTL=0x00,DMODE=0xE0(burst-8 | FC2, the A4091 value), the one-hot host idSCID = 1 << 7 = 0x80, and the A4091 bus-arbitration errata bitCTEST8 |= 0x01(SM). No SCSI/DMA interrupts are enabled ✅. On an A4092 with card CPLD 1.4.21 the SM bit is mandatory: the CPLD grants the bus only with it set, so a 53C710 driver that leaves it clear never gets a DMA cycle ✅ (real hardware and the CPLD's logic) — see below. All register writes go toreg + 0x40(the A4091 write-shadowWRSHADOW), reads atreg + 0; accesses are 8- or 32-bit only, never 16-bit ✅.a4091queue(c, cp)— drives any CDB from the caller'ssdcomthrough a table-indirect 53C710 SCRIPTS program (inq_script[], a staticulong[]that lives in kernel.data, so its bus address equals&inq_script[0]under the low-1 GB identity mapping). CDB length is derived from the SCSI group code (top 3 bits of the opcode → 6 / 10 / 12 bytes). The DSA (struct siop_ds) binds IDENTIFY / CDB / status / message / data buffers; the DATA phase dispatches on the live bus phase, so one SCRIPTS program performs both READ(10) and WRITE(10). Data DMAs straight intocp->addr— the caller's buffer, already a physical address viadd.c'svtop()✅.
The SCRIPTS program's data-phase dispatch (from inq_script[] in src/a4091-wr.c) is what makes one
program serve reads and writes:
0x808b0000, 0x00000018, /* JUMP dataout, WHEN DATA_OUT (write) */
0x818b0000, 0x00000020, /* JUMP datain, WHEN DATA_IN (read) */
0x838b0000, 0x00000020, /* JUMP status, WHEN STATUS (no data) */
The DSA table binds the caller's buffer for the data move ✅:
Completion: a bounded ISTAT poll¶
After launching SCRIPTS (a write to R_DSP), the driver spins on ISTAT until SIP or DIP is
set or a bound of 8 000 000 reads runs out ✅:
WR32( R_DSP, (ulong)inq_script);
/* bounded-poll completion -- spin on ISTAT until SIP|DIP or the bound */
while (poll < limit) {
istat = RD8(R_ISTAT);
if (istat & (ISTAT_SIP | ISTAT_DIP)) break;
poll = poll + 1;
}
...
if (!(istat & (ISTAT_SIP | ISTAT_DIP))) rc = -2; /* bound ran out */
else if (sstat0 & SSTAT0_STO) rc = -1; /* selection timeout */
else if ((dstat & DSTAT_SIR) && dsps == 0xff00) rc = 0; /* SCRIPTS "done" INT */
The bound exists because the same path runs the boot-time SCSI bus scan, which must not hang on an
empty id ✅. After a short-read resume the driver re-polls the same way, and it keeps
a4091_maxpoll (the high-water poll count) and the a4091_slow_poll console threshold so the cost
on a physical disk can be read back ✅. This completion ran on metal in the 68040/68060 build — the
A4092 results below
came through it 🟡 (one machine). Interrupt-driven completion is not implemented: the driver enables
no SCSI/DMA interrupts. The early prototypes (a4091-nopoll.c, a4091-blk.c) used a single
ISTAT read, which works only because the emulated target answers synchronously ✅.
For the full 53C710 register map, SCRIPTS encoding, one-hot SELECT-ID encoding, the soft-reset
sequence, the write-shadow at reg+0x40, and the emulator's full-window SIGSEGV hazard, see the
project's docs/a4091-53c710-reference.md (the verified chip reference behind this driver).
The A4091 disk's /dev numbering¶
✅ With both an A3000 and an A4091 present, the A4091 (card 1) target 0 slice 0 is reached at:
The cN in the name is computed, not stored — see the SCSI minor-number scheme on the
device list. From
amiga/alien/sd.h:
sdunit(dev) = (dev>>0) & 7 /* SCSI target id 0-7 */
sdcard(dev) = (dev>>3) & 1 /* card index (queue[] slot) -- only 0 or 1; SDCARDS = 2 */
sdpart(dev) = (dev>>4) & 7 /* slice/partition */
So cN = sdcard*8 + sdunit: c8d0s0 = card 1, target 0, slice 0 = makedevice(18, 8); the stock
A3000-root device c6d0s1 = card 0, target 6, slice 1 = makedevice(18, 22) ✅. A dev_t is
(major << 18) | minor ✅.
The READ/WRITE path was validated end to end ✅:
- Raw SCSI passthrough via the
gsioctluserspace path (src/gsio.c,/dev/scsimajor 11) — INQUIRY, READ(10), WRITE(10) all returning correct data. mkfs ufs+mounton the A4091 disk, with files written and surviving a reboot (genuine persistence to the disk behind the A4091, not a RAM artefact).
Driver variants — the evolution¶
Only a4091-wr.c is the production driver; the earlier variants are kept under src/ to show the
incremental bring-up path ✅:
| File | Stage |
|---|---|
a4091.c |
detection-only (proves sptalloc + register read) |
a4091-nopoll.c |
INQUIRY only |
a4091-blk.c |
READ-only block device |
a4091-wr.c |
READ + WRITE — production |
a4091-wr-dbg.c |
same as production + A4: printf diagnostics (used to trace the early-boot path) |
Build & install¶
The driver is a standard kernel-relink job (kernel build & install), with the A4091-specific steps:
- Drop the driver
src/a4091-wr.cinto the kernel tree as/usr/sys/amiga/alien/a4091.c. - Register it in the Makefile — add
a4091.oto theamiga/alienOBJlist (generated fromdriver.confby amix-kerntools'amix-build). - Add the SCSI-stack rows — the
scsicard[]rows insd.c, also generated fromdriver.confbyamix-build. - Apply the auto-detect patch — the chipset-gated
autocon()insupport.c(src/kernel-patches/support.c.patch); this is what lets one kernel boot both an A3000 and an A4000+A4091. The why is on Zorro AUTOCONFIG and the boot process. - Build with the clean-gate. The Amix
ldintermittently corrupts the linked kernel (the "D245 boot-breaker"); relink until the checksum recurs rather than trusting a singlemake. Usetools/build-clean-kernel.shand verify withtools/relsim.py/checkunix.c— full detail on kernel build & install. Nevermake installan unverified kernel onto your working disk — it rewrites the boot partition and bricks it if the kernel is corrupt. - Install carefully onto a throwaway / clone disk — see adding drivers to a custom boot disk and the "boot root on the A4091" install recipe on the boot process.
Tip — cross-develop on a modern host. As of 2026-06 you can build the driver object on Linux with the
gcc-cross-amixcross-toolchain (m68k-cbm-sysv4-gcc) instead of editing on the box — it cross-compiles a real Amix driver.cto a relocatable m68k ELF; you then do only the final relink on Amix. See Toolchain → cross-compiling. ✅
The SCRIPTS source (reference/scripts/inq-wr.ss) is assembled with the NetBSD ncr53cxxx
assembler from the open-source a4091.device project, which
also provides the A4091 autoboot ROM used by the emulator
(Amix on Amiberry).
Zorro III DMA into a Z3660's CPU RAM — the first metal data point (2026-10-02)¶
Can a Zorro III bus master reach the RAM on a Z3660 accelerator? For one setup the answer is
yes ✅: on an A4000D (Buster -11) with a Z3660 in real-68LC060 mode, an autoconfigured
A4092 (53C710, card CPLD 1.4.21, at 0x40000000) DMAs into the Z3660's CPU-local RAM at
0x08000000, the memory the Amix kernel runs from. The kernel was a 68060 Amix kernel with this
driver and a DMA cache-coherence service; with copyback caching on, LBA 0 reads back as a valid RDB,
4 MB and 32 MB raw reads give the same checksum on every read and across power-cycled boots, and the
coherence service's invariants held over about 72 MB of device-to-memory transfers ✅. The data is
also right, not merely repeatable ✅: a host copy of the disk image (104 857 600 bytes, pulled without
the Amiga's network, every 8 MiB piece CRC-checked against the device) has the same sum -r at
4 MiB (49574, matching the Amix reads on both boots) and at 32 MiB (09482, matching both reads on
the first boot) and the same block 0. So the read direction — device to Z3660 RAM — is coherent ✅.
The write direction (memory to device) and root on the A4092 followed on the same A4000D + Z3660
with the same driver arm 🟡 (one machine): on 2026-10-03 the A4092 carried the root filesystem
through two full boots, and on 2026-10-11 the hardware acceptance of the 1.0 install media installed
the 30-package set onto a 512 MB disk behind the A4092 (c9d0) in 1 h 45 min, with a clean final
fsck and a booting system.
Why the read direction can be coherent in hardware 🟡. The Z3660's CPLD drives the 68060's
SNOOP input low on every cycle of its own DMA engine and whenever the ARM holds the bus
(z3660.vhd line 459 in the flashed DMA_WIP design; the firmware's CHANGES for v1.03 beta 2 note
the SNOOP change) ✅ (read from the source). Per the MC68060 bus-snooping rules as commonly
described, a snooped write by another master invalidates a matching data-cache line, while a
snooped read is not supplied from a dirty cache line (the 68040's snoop-sourcing was dropped
on the 68060) — the manual is not in this project's sources, so this half is 🟡. If that holds,
DMA into Z3660 RAM is coherent without software help, and DMA out of it is not: a driver must
push dirty cache lines to memory before a device reads them. Earlier cautions that Zorro DMA cannot
reach a Z3660's memory concerned RAM autoconfigured into Zorro space; they do not describe this
CPU-local aperture 🟡. Registering the A4092 at all needed the stock-kernel fix in
quirks §65.
What the Zynq side sees ✅ (real hardware, A4000D + Z3660). The Z3660's CPU RAM is cache-coherent on the ARM side through the Zynq's ACP port: writes by the 68060 or by a Zorro master sit as dirty lines in the ARM's L2. Firmware that reads memory a bus master has written must clean and invalidate, never plain-invalidate (that discards the DMA'd data), and must clean anything it wrote before a master reads it. The card's bus arbiter ranks an external master above the ARM above the 68060, so the ARM can take the bus from a running 060 (grant in under 1 µs) and must not issue a bus cycle while the 53C710 may own it.
A second card, and root as a module (2026-10-18 to 2026-10-27) ✅¶
On the same A4000D + Z3660 a second A4092 card passed a 22 MB read whose CRC matched with the DMA buffer in motherboard RAM and in Z3660 RAM, plus a 4 MiB write/verify; under the 1.1 module kernel (68060 line) reads through it were byte-equal to the host copy, and it carried the root filesystem alone and beside the Z3660's own disk ✅ (first-party record). The "one machine" caveat in the table below still applies: one A4000D, now two A4092 cards.
A4092 CPLD and 53C710 behaviour ✅¶
Measured on real hardware with the 53C710 driven from the Z3660's ARM, and read from the CPLD logic:
- CPLD 1.4.21 gates the bus grant on
CTEST8.SM(the grant follows the chip's SC0 line, which SM drives). Every A4092 with that CPLD needs SM set by the driver. A diagnostic that never sets SM on a 53C710 — thencr7xxtool's DMA tests 4–7 — therefore fails on every such card without a fault. - The CPLD version is readable from the board's AutoConfig serial number (
01040015= 1.4.21); the card's ROM header carries manufacturer0xD0CE, a nibble swap of the0xC0DEAutoConfig id. - Never read the 53C710's longword at +
0x14while it is connected to a target: the read pops the SCSI FIFO and raises a gross error. - The 53C710 can raise a selection timeout while connected and halt SCRIPTS even with
SIENclear; re-running the phase switch recovers. SCRIPTS should be phase-adaptive (the reference driver's switch shape); straight-line scripts halt at the end of MSG OUT. - Byte writes of
CTEST8.SMandCTEST7.CDISmisbehave about one boot in four: write, read back, retry. - Rates through the A4092 to a ZuluSCSI target with an asynchronous transfer: 6.4 MB/s on the bus with no OS running, 3.85 MB/s with one; the asynchronous handshake ceiling is about 5.6 MB/s, and DMA is 35–48× faster than programmed I/O (9–12 µs per byte). Synchronous transfers were not measured.
The A4000T's onboard 53C710 ✅¶
The A4000T's onboard SCSI is a 53C710 with no AutoConfig ✅ (the reference AmigaOS driver's source and real hardware):
| A4091 / A4092 | A4000T onboard | |
|---|---|---|
| Discovery | AutoConfig | none: fixed base $DD0000 |
| Registers | base + 0x800000 |
base + 0x40, written directly |
| DIP switches | base + 0x8c0003 (byte) |
base + 0x3000 (longword) |
DCNTL |
0x00 |
0x20 (EA: connect _SLACK/_STERM) |
| Bus master | Zorro III, through Buster | a motherboard master, the class of the A3000's SDMAC |
- Its register window hangs any read until the A4000T ROM's own NCR driver has initialised the chip
✅ (real hardware: the first read at
$DD0000or$DD0040hangs under a Kickstart without that driver, and 21 of 21 reads answer once it has run). An A4000D, which has no chip there, froze on a read at or near$DD0000too (quirk 66). So a probe must be gated: AGA first (quirk 61), and then only when the A4000T ROM is known to have initialised the chip. - Amix boots with its root on the onboard 53C710 — on the 1.1 module kernel (68060 line), through
Kickstart's NCR
scsi.device, 3 of 3 cold boots ✅ (one A4000T). - Its DMA into Z3660 memory was clean (496 MiB, no miscompare, under AmigaOS) ✅; DMA into chip RAM with a Z3660 fitted hung or corrupted at random on the one A4000T tested, worse with larger transfers 🟡 (a reproduction board with open build items — possibly that board). A loader that keeps its DMA buffer in fast RAM booted cleanly there.
Not with the Z3660 in 68030 mode ✅: in its Amix 68030-emulation mode the Z3660 firmware hides the
motherboard memory (so no memory a bus master can reach remains) and maps $DD0000 to its emulated A3000
SCSI, so neither the onboard 53C710 nor any other bus master can be used on that boot. The same mode makes
Zorro III DMA impossible for the A4091/A4092 as well.
The first command's SCSI bus reset ✅¶
The driver's first command in a boot runs a SCSI bus reset that waits for 4000 changes of the beam
counter. On metal (A4000D, A4092) that took about 0.25 s: the first INQUIRY to an empty id came
back in under a second, with one reset and no reset timeout ✅. Under Amiberry at cpu_speed=max
the first INQUIRY to the A4091 took 53 s on the 68060 kernel and 72 s on the 68030 kernel, and
every later command under a second ✅. The likely reason 🟡: the wait counts changes of VHPOSR's
high byte, which Amiberry at that speed shows only once or twice a frame, so any busy wait on the
beam counter runs slow there. A fix that counts lines passed is pending.
Status¶
| Claim | Status |
|---|---|
| A4091/53C710 driver detects, reads and writes; root + swap + filesystem on the A4091; multi-user, networking | ✅ emulation-proven (Amiberry, real Amix 2.1c) |
| One universal kernel boots both A3000(ECS) and A4000(AGA) + A4091 | ✅ emulation-proven, one binary |
| Bounded ISTAT-poll completion (real disks are not instant) | ✅ shipped; run on metal in the 68040/68060 build (A4092) 🟡 one machine; no interrupt-driven completion |
| Real-hardware validation of the 68030 line on a physical A3000 and A4000 + A4091 | 🟡 pending (emulation only) |
| An A4092 on real hardware (A4000D + Z3660, 68060 kernel): registered, raw reads match a host copy of the disk, DMA into the Z3660's RAM | ✅ 2026-10-02 |
| The same A4092: writes, root (two boots, 2026-10-03), a full install onto a disk behind it (2026-10-11) | 🟡 one machine |
| A second A4092 card on the same machine; root on an A4092 under the 1.1 module kernel (68060 line) | ✅ 2026-10-27, one machine |
| The A4000T onboard 53C710 as root (1.1 module kernel, 68060 line) | ✅ 2026-10-28, one machine |
| Any bus-master DMA with the Z3660 in its 68030-emulation mode | ✅ not possible (firmware hides the reachable memory) |
See also¶
- Zorro AUTOCONFIG for drivers —
autocon(), the Zorro III /sptallocquestion, and the chipset-gated auto-detection that registers the A3000 SCSI only when present. - Building & installing a kernel — the
make→relocunix→make bootpartflow and the D245 clean-gate that this driver's build depends on. - The boot process — booting Amix with root on the A4091, and the rootdev ↔ card-index device numbering.
- Device list — the SCSI block/char major numbers and the card/target/slice minor scheme.
- Z3660 piscsi SCSI driver and Z3660 ethernet driver — the other modern Zorro III drivers; the piscsi "SCSI" is a deliberately contrasting ~5-poke firmware mailbox (no 53C710, no SCRIPTS) that boots Amix from real hardware.
- Supported hardware & requirements — the Zorro II / Zorro III rules the A4091 work pushes against.
- Amix on Amiberry — the A4091-in-Amiberry config and the A3000(ECS) vs A4000(AGA) Kickstart finding.
- The Amix device-driver model — the switch-table mechanism underneath the SCSI stack.
Sources¶
- The first-command bus reset (first-party record, 2026-11-02) ✅/🟡 —
kbootset inquirytimings under Amiberry on both kernel lines and on an A4000D with an A4092 (the driver's reset counters read withmodadmin -p); the per-card bus reset inamigaux/amixkernel/drivers/a4091/CHANGELOG.md(2026-10-03). TheVHPOSRexplanation is the driver project's 🟡. -
Stock sources, public ✅ — the stock SCSI layer in
amigaux/amix-system(7cba961):usr/sys/amiga/alien/sd.c,usr/include/sys/sd.h,usr/sys/amiga/alien/dd.c,usr/sys/amiga/kernel/support.c. -
The Z3660 CPLD's
SNOOPdrive —z3660-firmware/CPLD/DMA _WIP/z3660.vhdline 459 (nSNOOPlow whenDMA_BUSYor on an ARM bus grant;DMA_BUSYset whenever the CPLD's DMA state machine is not idle, line 424) and the firmwareCHANGES.md, v1.03 beta 2 ✅. The 68060 snoop semantics are 🟡: the MC68060 User's Manual is not among this project's sources. - The first Zorro III DMA metal run into a Z3660's RAM ✅ — first-party record, 2026-10-02 (A4000D, Z3660 68LC060, an A4092 with CPLD 1.4.21 at
0x40000000; valid RDB at LBA 0, repeatablesum -rover 4 MB and 32 MB raw reads across power-cycled boots with copyback on, coherence invariants over ~72 MB), and the host-truth compare that closed the read side (the disk image pulled to the host, sha256ec8d8d24…, every 8 MiB piece CRC-matched to the device,sum -r49574 / 09482 and block 0 equal to the Amix reads). - The signed manufacturer compare in stock
autocon()✅ —amix-a4091commit06a7d96(2026-10-02,support.c.patch: the unsigned shift, codegenswap/ext.l→clr.w/swap), the matching one-byteasr.l→lsr.lpatch in the 68040/68060 relink tooling the same day, and the A4000D metal run that proved it (the A4092's0xC0DE0001handed over inbootinfo.autocon[]but unregistered without the fix, registered as card 1 with it; first-party record, 2026-10-02). - The 2026-09-29 stock-kernel RAM-layout measurement ✅ — on the emulated bench the same 64 MB A3000 motherboard bank boots a kernel that probes for the A3000 SCSI and stops the pinned stock kernel at
s5mountroot VOP_OPEN error 6(no card 0), symbolised against the stockautocon()load-address guess (first-party record, 2026-09-29; quirks §57). - The A4091-on-Amix project, https://github.com/jusii/amix-a4091 — README (incl. its Status
table),
CHANGELOG.md(dated entries, 2026-06 to 2026-10),docs/A4000T-ONBOARD-710.md,docs/D42-CALL-SHAPE.md(the 040/060 arm'sdev_kvmapmapping and DMA-coherence service), andsrc//tools/; the emulation bring-up itself is first-party record, 2026-06-04/05 (reproduced locally ✅). src/a4091-wr.c— the 53C710 READ+WRITE driver (A4091_PROD 0x02020054,SIOP_OFF 0x00800000,sptalloc()mapping,inq_script[],a4091queue()with its bounded ISTAT poll,a4091_maxpoll/a4091_slow_poll); SCRIPTS from the a4091-software repo'sncr53cxxxsource.src/kernel-patches/support.c.patch— the chipset-gatedautocon()diff;driver.conf— the A4091, A4092 and A4770 identities from which amix-kerntools'amix-build(https://github.com/jusii/amix-kerntools,gen_sd_patch,gen_makefile_patch) generates thescsicard[]rows,sdcardbase()and thea4091.oOBJentry.- The A4092 writes and root on metal 🟡 (one machine) — the amix-a4091 README (root filesystem
through two full boots on an A4000D + Z3660, 2026-10-03) and Installer-NG
docs/releases/1.0.md, Hardware acceptance (not public; the 30-package install ontoc9d0behind the A4092, 2026-10-11). docs/a4091-53c710-reference.mdin the project repo — the verified 53C710 register/SCRIPTS detail behind this driver.- The 2026-08-12/14 RAM-ceiling investigation (first-party record, 2026-08-12/14) — the identity map's real mechanism (the TT
registers are disabled; a section-0 early-termination root-table descriptor maps the low 1 GB) and
the two-sided failure of the stock load-address SCSI inference in
support.c:305(described then as a RAM-size test; corrected 2026-09-29), with real A3000s above 16 MB inside the affected envelope ✅. - a4091.device open-source project: https://github.com/A4091/a4091-software (A4091 ROM +
ncr53cxxxSCRIPTS assembler). - The Zorro III write-path and DMA work on an A4000D + Z3660 (first-party record, 2026-10-17 to 2026-10-19) ✅: the ACP coherence rule, the CPLD arbiter priority, the A4092 CPLD 1.4.21
SMgate (with the CPLD's logic), the 53C710 behaviours, the menu-route and OS-route rates. - The second A4092 card and the module-kernel rows (first-party record, 2026-10-26 to 2026-10-27) ✅;
amix-kerntoolsCHANGELOG 2026-10-27/28 (the A4000D and A4000T metal blocks). amix-a4091docs/A4000T-ONBOARD-710.md§1 (the onboard chip versus the A4091, from the reference driver'sa4091.h,attach.c,siop.c,ncr7xx.c), §2 "T0 result" (the read hangs and the 21 answered reads), §10.10 (the Z3660 68030 mode) ✅.