mirror of
https://github.com/alfishe/amiga-bootcamp.git
synced 2026-06-13 00:26:28 +00:00
Comprehensive technical documentation covering: - Hardware: OCS/ECS/AGA custom chip registers, Copper & Blitter deep dives - Boot sequence: cold boot through startup-sequence - Binary format: HUNK executable spec, relocation, debug info - Linking & ABI: .fd files, LVO tables, register calling conventions - Exec kernel: tasks, interrupts, memory, signals, semaphores - AmigaDOS: file I/O, FFS/OFS layout, CLI/Shell scripting - Graphics: planar bitmaps, Copper programming, HAM/EHB modes - Intuition: screens, windows, IDCMP, BOOPSI - Devices: trackdisk, SCSI, serial, timer, audio, keyboard - Libraries: utility, expansion, IFFParse, locale, ARexx - Networking: bsdsocket API, SANA-II, TCP/IP stack comparison - Toolchain: GCC, vasm/vlink, SAS/C, NDK, debugging - Reverse engineering: IDA/Ghidra setup, compiler fingerprints, case studies - CPU & MMU: 68040/060 emulation libs, PMMU, cache management - Driver development: SANA-II, Picasso96/RTG, AHI audio All files include breadcrumb navigation. No local paths or proprietary content.
4.5 KiB
4.5 KiB
IO Requests — IORequest, DoIO, SendIO, CheckIO, AbortIO
Overview
AmigaOS device I/O uses a message-based asynchronous protocol. Every device operation is described by an IORequest structure sent to a device's command port. The device processes it (synchronously or in the background) and replies when done.
Structures
/* exec/io.h — NDK39 */
struct IORequest {
struct Message io_Message; /* embedded Message (has MsgPort reply port) */
struct Device *io_Device; /* filled by OpenDevice */
struct Unit *io_Unit; /* filled by OpenDevice */
UWORD io_Command; /* CMD_READ, CMD_WRITE, TD_FORMAT, ... */
UBYTE io_Flags; /* IOF_QUICK = attempt synchronous fast path */
BYTE io_Error; /* result: 0 = success, negative = error code */
};
struct IOStdReq { /* extended version with data fields */
struct IORequest io_Request;
ULONG io_Actual; /* actual bytes transferred */
ULONG io_Length; /* requested byte count */
APTR io_Data; /* data buffer pointer */
ULONG io_Offset; /* byte offset (for random-access devices) */
};
Standard Command Codes
/* exec/io.h */
#define CMD_INVALID 0 /* not a valid command */
#define CMD_RESET 1 /* reset the device/unit to initial state */
#define CMD_READ 2 /* read io_Length bytes into io_Data from io_Offset */
#define CMD_WRITE 3 /* write io_Length bytes from io_Data at io_Offset */
#define CMD_UPDATE 4 /* flush write cache to media */
#define CMD_CLEAR 5 /* discard device read buffers */
#define CMD_STOP 6 /* suspend device operation */
#define CMD_START 7 /* resume device operation */
#define CMD_FLUSH 8 /* abort all pending requests */
#define CMD_NONSTD 9 /* first device-specific command number */
Device-specific commands start at CMD_NONSTD (9). Example: trackdisk uses TD_FORMAT (10), TD_MOTOR (11), TD_SEEK (12).
Error Codes (io_Error)
/* exec/errors.h — NDK39 */
#define IOERR_OPENFAIL -1 /* device/unit could not be opened */
#define IOERR_ABORTED -2 /* request was aborted via AbortIO */
#define IOERR_NOCMD -3 /* unknown command */
#define IOERR_BADLENGTH -4 /* io_Length invalid for this command */
#define IOERR_BADADDRESS -5 /* io_Data not aligned or accessible */
#define IOERR_UNITBUSY -6 /* unit in use, cannot complete */
#define IOERR_SELFTEST -7 /* hardware self-test failed */
Opening a Device
struct IOStdReq *ior = CreateStdIO(reply_port); /* alloc + fill reply port */
if (OpenDevice("trackdisk.device", unit, (struct IORequest *)ior, 0) != 0) {
/* open failed — ior->io_Error set */
}
Or manually:
struct IOStdReq *ior = AllocMem(sizeof(struct IOStdReq), MEMF_PUBLIC|MEMF_CLEAR);
ior->io_Message.mn_ReplyPort = my_reply_port;
ior->io_Message.mn_Length = sizeof(struct IOStdReq);
OpenDevice("audio.device", 0, (struct IORequest *)ior, 0);
Synchronous I/O: DoIO
Blocks the calling task until the device completes the request:
ior->io_Command = CMD_READ;
ior->io_Data = buffer;
ior->io_Length = 512;
ior->io_Offset = 0;
LONG err = DoIO((struct IORequest *)ior);
/* io_Actual = bytes actually read; io_Error = error code */
Asynchronous I/O: SendIO + WaitIO
/* Queue the request — returns immediately: */
SendIO((struct IORequest *)ior);
/* Do other work while device operates... */
/* Block until this specific request completes: */
WaitIO((struct IORequest *)ior);
err = ior->io_Error;
Poll without blocking: CheckIO
/* Returns non-NULL if request is done (removed from device queue): */
if (CheckIO((struct IORequest *)ior)) {
WaitIO((struct IORequest *)ior); /* must still call WaitIO to dequeue reply */
}
Aborting a Request: AbortIO
AbortIO((struct IORequest *)ior); /* ask device to cancel */
WaitIO((struct IORequest *)ior); /* wait for confirmation */
/* io_Error will be IOERR_ABORTED (-2) */
Closing a Device
CloseDevice((struct IORequest *)ior);
DeleteStdIO(ior); /* or FreeMem */
References
- NDK39:
exec/io.h,exec/errors.h - ADCD 2.1:
OpenDevice,CloseDevice,DoIO,SendIO,WaitIO,CheckIO,AbortIO 10_devices/— per-device command codes and structures- Amiga ROM Kernel Reference Manual: Exec — I/O requests chapter