[← Home](../README.md) · [Devices](README.md) # scsi.device — Hard Disk, CD-ROM, and Mass Storage I/O ## Overview SCSI and IDE hard disks on the Amiga are accessed through `scsi.device` or compatible device drivers. The API is consistent across implementations — the same IORequest structure and commands work regardless of whether the underlying hardware is Commodore's native Gayle IDE, a Zorro SCSI card, or an accelerator-integrated controller. --- ## Disk Interfaces by Amiga Model | Model | Interface | Controller | Device Name | Bandwidth Limit | |---|---|---|---|---| | A500 | None (stock) | — | — | Requires external SCSI card | | A500+ | None (stock) | — | — | Requires external SCSI card | | A600 | IDE (44-pin) | **Gayle** | `scsi.device` | ~1.5 MB/s (PIO, 16-bit CIA) | | A1000 | None (stock) | — | — | Requires SCSI sidecar | | A1200 | IDE (44-pin) | **Gayle** | `scsi.device` | ~1.5 MB/s (PIO) | | A2000 | None (stock) | — | — | Zorro II SCSI cards | | A3000 | SCSI (50-pin) | **WD33C93** | `scsi.device` | ~3 MB/s (DMA) | | A4000 | IDE (40-pin) | **A4000 IDE** | `scsi.device` | ~2 MB/s (PIO) | | A4000T | SCSI (50-pin) + IDE | **NCR 53C710** + IDE | `2nd.scsi.device` / `scsi.device` | ~10 MB/s (SCSI DMA) | | CD32 | IDE (internal CD) | **Akiko** | `scsi.device` | ~1.5 MB/s | | CDTV | SCSI (internal CD) | **DMAC + WD33C93** | `scsi.device` | ~150 KB/s (1× CD) | ### Why Native Bandwidth Is Limited The A600/A1200 **Gayle** IDE interface is the most common and the most constrained: ```mermaid flowchart LR CPU["68020/68030
(fast bus)"] -->|"PIO transfer
WORD at a time"| GAYLE["Gayle IDE
(no DMA!)"] GAYLE -->|"16-bit ATA"| DRIVE["IDE Drive"] style GAYLE fill:#ffcdd2,stroke:#c62828,color:#333 ``` | Bottleneck | Explanation | |---|---| | **No DMA** | Gayle has no DMA engine — every word must be moved by the CPU (`MOVE.W` loop) | | **16-bit bus** | Gayle connects via 16-bit data path even on 32-bit CPUs | | **PIO mode 0** | Stock Gayle supports only PIO mode 0 (~3.3 MB/s theoretical, ~1.5 MB/s actual) | | **CIA timing** | CIA chip access introduces wait states | | **CPU overhead** | 100% CPU utilization during transfers — no multitasking during disk I/O | ### Community Solutions — Fast IDE | Solution | Method | Improvement | |---|---|---| | **FastATA** (E-Matrix/Elbox) | Zorro SCSI/IDE card with DMA | Up to ~10 MB/s, frees CPU | | **Buddha/Catweasel** | Clock port / Zorro IDE with optimized driver | ~2–3 MB/s, multiple IDE channels | | **Blizzard SCSI** | Accelerator-integrated SCSI | Up to ~5 MB/s with DMA | | **GVP Series II** | Zorro II SCSI with custom DMA ASIC | ~3 MB/s, DMA frees CPU | | **A4091** | Zorro III SCSI (NCR 53C710) | **~10 MB/s** — fastest stock Amiga SCSI | | **CF adapters** | CompactFlash in IDE socket | Same speed, but no mechanical seek latency | | **SD/microSD** | Adapter on clock port | Varies, typically slow but no noise | --- ## Native vs. Vendor Drivers — Software Differences All drivers expose the same `CMD_READ`/`CMD_WRITE`/`HD_SCSICMD` API, but internal differences matter: | Aspect | Commodore `scsi.device` | Vendor Drivers (GVP, A4091, etc.) | |---|---|---| | **Source** | Commodore ROM or Devs: | Third-party (ships with hardware) | | **DMA support** | None (Gayle PIO) | Often DMA-capable | | **Interrupt handling** | Level 2 interrupt (CIA) | Card-specific interrupt level | | **TD64 / NSD** | Added via patches | Often built-in from factory | | **Multi-LUN** | Usually ignored | Proper LUN scanning on SCSI | | **Disconnect/reselect** | Not supported (Gayle) | SCSI disconnect on good controllers | | **Tagged queuing** | No | Some advanced SCSI controllers | | **CD-ROM support** | Basic (atapi.device) | Full ATAPI/SCSI CD support | | **Removable media** | Basic change detection | Proper unit attention handling | > [!IMPORTANT] > When writing software that accesses disks, **always use the device name from the mountlist** — don't hardcode `scsi.device`. Different systems use different device names for the same physical drive. --- ## Opening ```c struct MsgPort *diskPort = CreateMsgPort(); struct IOStdReq *diskReq = (struct IOStdReq *) CreateIORequest(diskPort, sizeof(struct IOStdReq)); /* Unit 0 = first device on the bus (master/ID 0): */ if (OpenDevice("scsi.device", 0, (struct IORequest *)diskReq, 0)) { Printf("Cannot open scsi.device unit 0\n"); } ``` ### Units | Unit | SCSI Meaning | IDE Meaning | |---|---|---| | 0 | SCSI ID 0 | Master | | 1 | SCSI ID 1 | Slave | | 2–6 | SCSI ID 2–6 | N/A | | 7 | Host adapter (reserved) | N/A | --- ## Standard Commands ```c /* Read 512 bytes from byte offset on disk: */ diskReq->io_Command = CMD_READ; diskReq->io_Data = buffer; diskReq->io_Length = 512; diskReq->io_Offset = 0; /* byte offset */ DoIO((struct IORequest *)diskReq); /* Write: */ diskReq->io_Command = CMD_WRITE; diskReq->io_Data = buffer; diskReq->io_Length = 512; diskReq->io_Offset = 512; DoIO((struct IORequest *)diskReq); /* Flush write cache: */ diskReq->io_Command = CMD_UPDATE; DoIO((struct IORequest *)diskReq); ``` > [!IMPORTANT] > The `io_Offset` field is a `ULONG` (32-bit), limiting addressable space to **4 GB**. For larger drives, use TD64/NSD 64-bit commands. --- ## Direct SCSI Commands (HD_SCSICMD) For operations beyond read/write — device identification, mode pages, CD-ROM commands: ```c #include struct SCSICmd scsicmd; UBYTE cdb[10], sense[20], data[512]; /* READ(10) — read 1 sector at LBA 0: */ memset(cdb, 0, sizeof(cdb)); cdb[0] = 0x28; /* READ(10) opcode */ cdb[7] = 0; cdb[8] = 1; /* transfer length = 1 sector */ scsicmd.scsi_Data = (UWORD *)data; scsicmd.scsi_Length = 512; scsicmd.scsi_Command = cdb; scsicmd.scsi_CmdLength = 10; scsicmd.scsi_Flags = SCSIF_READ | SCSIF_AUTOSENSE; scsicmd.scsi_SenseData = sense; scsicmd.scsi_SenseLength = sizeof(sense); diskReq->io_Command = HD_SCSICMD; diskReq->io_Data = &scsicmd; diskReq->io_Length = sizeof(scsicmd); DoIO((struct IORequest *)diskReq); if (scsicmd.scsi_Status != 0) Printf("SCSI error: status=%ld, sense key=%ld\n", scsicmd.scsi_Status, sense[2] & 0x0F); ``` ### Common SCSI Commands | Opcode | Name | CDB | Description | |---|---|---|---| | `0x00` | TEST UNIT READY | 6 | Check device readiness | | `0x03` | REQUEST SENSE | 6 | Get error details | | `0x12` | INQUIRY | 6 | Device identification | | `0x1A` | MODE SENSE(6) | 6 | Read device parameters | | `0x25` | READ CAPACITY | 10 | Get total sectors and sector size | | `0x28` | READ(10) | 10 | Read sectors (32-bit LBA) | | `0x2A` | WRITE(10) | 10 | Write sectors | | `0x35` | SYNCHRONIZE CACHE | 10 | Flush write cache | | `0x43` | READ TOC | 10 | Read CD table of contents | | `0xBE` | READ CD | 12 | Read CD sector (any format) | --- ## CD-ROM Specifics CD-ROM drives require special handling — they use ATAPI (IDE) or SCSI commands but with CD-specific extensions: ### Opening a CD-ROM ```c /* CD-ROM is typically on a different device or unit: */ /* A1200 + ATAPI CD: */ OpenDevice("scsi.device", 2, req, 0); /* unit 2 = slave on second channel */ /* External SCSI CD: */ OpenDevice("2nd.scsi.device", 3, req, 0); /* SCSI ID 3 */ /* AmiCDFS or CacheCDFS handles mounting automatically via: DEVS:DOSDrivers/CD0 mountlist entry */ ``` ### Reading the Table of Contents ```c UBYTE tocData[804]; /* max TOC size */ memset(cdb, 0, 10); cdb[0] = 0x43; /* READ TOC */ cdb[6] = 1; /* starting track */ cdb[7] = (sizeof(tocData) >> 8) & 0xFF; cdb[8] = sizeof(tocData) & 0xFF; scsicmd.scsi_Data = (UWORD *)tocData; scsicmd.scsi_Length = sizeof(tocData); scsicmd.scsi_Command = cdb; scsicmd.scsi_CmdLength = 10; scsicmd.scsi_Flags = SCSIF_READ | SCSIF_AUTOSENSE; DoIO((struct IORequest *)diskReq); ``` ### Audio CD Playback ```c /* PLAY AUDIO MSF — play from start to end: */ memset(cdb, 0, 10); cdb[0] = 0x47; /* PLAY AUDIO MSF */ cdb[3] = 0; /* start minute */ cdb[4] = 2; /* start second */ cdb[5] = 0; /* start frame */ cdb[6] = 60; /* end minute */ cdb[7] = 0; /* end second */ cdb[8] = 0; /* end frame */ scsicmd.scsi_Flags = SCSIF_READ; DoIO((struct IORequest *)diskReq); ``` ### CD Filesystem Drivers | Driver | Type | Features | |---|---|---| | **AmiCDFS** | Free (Aminet) | ISO 9660, Rock Ridge, HFS, circular cache | | **CacheCDFS** | OS 3.5+ / IDE-fix | ISO 9660, Rock Ridge, Joliet, HFS, LRU cache — de facto standard | | **AsimCDFS** | Commercial | ISO 9660, High Sierra, Rock Ridge, HFS, CD-DA ripping, CDTV/CD32 emulation | | **AllegroCDFS** | Elbox-bundled | ISO 9660 L1–3, Rock Ridge, Joliet, UDF, fastest benchmarks | | **ODFileSystem** | Open source | ISO 9660, Rock Ridge, Joliet, UDF, HFS, HFS+ — modern replacement | See [CD-ROM Filesystems](../07_dos/cdfs.md) for the full deep-dive: format coverage matrix, handler architecture, mount configuration, and decision guide. --- ## 64-Bit Addressing (TD64 / NSD) For drives larger than 4 GB: ```c /* TD64 — uses io_Actual for high 32 bits: */ diskReq->io_Command = NSCMD_TD_READ64; diskReq->io_Data = buffer; diskReq->io_Length = 512; diskReq->io_Offset = lowOffset; /* low 32 bits */ diskReq->io_Actual = highOffset; /* high 32 bits */ DoIO((struct IORequest *)diskReq); ``` > [!TIP] > **New Style Device (NSD)** provides a standard way to query 64-bit support: send `NSCMD_DEVICEQUERY` and check the returned command list. --- ## MiSTer / FPGA Notes | Aspect | Implementation | |---|---| | IDE emulation | MiSTer emulates Gayle IDE — presents virtual ATA backed by SD card `.hdf` | | SCSI emulation | A2091/A3000 SCSI cores map targets to `.hdf` files | | Sector size | Must be 512 bytes — all Amiga drivers assume this | | RDB | Rigid Disk Block at sectors 0–15 — must be present for HDToolBox | | Performance | Virtual IDE is faster than real Gayle (no PIO bottleneck) | --- ## References - NDK39: `devices/scsidisk.h`, `devices/trackdisk.h` - ADCD 2.1: scsi.device autodocs - SCSI-2 standard: ANSI X3.131-1994 - See also: [trackdisk.md](trackdisk.md) — floppy I/O (shares the same API model) - See also: [CDTV Hardware](../01_hardware/ocs_a500/cdtv_hardware.md) — DMAC/WD33C93 SCSI CD-ROM controller - See also: [Akiko — CD32](../01_hardware/aga_a1200_a4000/akiko_cd32.md) — CD32 CD-ROM controller (Akiko PIO, not SCSI) - See also: [Gayle IDE & PCMCIA](../01_hardware/common/gayle_ide_pcmcia.md) — A600/A1200 IDE controller - See also: [Gary — A3000](../01_hardware/ecs_a600_a3000/gary_system_controller.md) — A3000 SDMAC/WD33C93 SCSI integration - See also: [CD-ROM Filesystems](../07_dos/cdfs.md) — CDFS handler deep-dive: ISO 9660, Rock Ridge, Joliet, UDF, handler comparison - See also: [ATA/ATAPI Protocol](atapi.md) — ATA task file registers, ATAPI packet commands, driver ecosystem (IDE-fix, Buddha, FastATA), CompactFlash, removable media