amiga-bootcamp/10_devices/scsi.md
2026-04-26 14:46:18 -04:00

10 KiB
Raw Blame History

← Home · Devices

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:

flowchart LR
    CPU["68020/68030<br/>(fast bus)"] -->|"PIO transfer<br/>WORD at a time"| GAYLE["Gayle IDE<br/>(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 ~23 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

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
26 SCSI ID 26 N/A
7 Host adapter (reserved) N/A

Standard Commands

/* 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:

#include <devices/scsidisk.h>

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

/* 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

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

/* 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 Commodore (stock) Basic ISO 9660, slow
CacheCDFS Third-party (popular) ISO 9660 + Joliet + RockRidge, caching, fast
AsimCDFS Third-party Similar to CacheCDFS, commercial

64-Bit Addressing (TD64 / NSD)

For drives larger than 4 GB:

/* 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 015 — 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 — floppy I/O (shares the same API model)
  • See also: CDTV Hardware — DMAC/WD33C93 SCSI CD-ROM controller
  • See also: Akiko — CD32 — CD32 CD-ROM controller (Akiko PIO, not SCSI)
  • See also: Gayle IDE & PCMCIA — A600/A1200 IDE controller
  • See also: Gary — A3000 — A3000 SDMAC/WD33C93 SCSI integration