mirror of
https://github.com/alfishe/amiga-bootcamp.git
synced 2026-06-13 00:26:28 +00:00
docs(amiga): complete AmigaOS 3.1/3.2 developer reference — 172 files across 17 sections
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.
This commit is contained in:
parent
f07a368bf1
commit
21751c0025
172 changed files with 19701 additions and 0 deletions
18
10_devices/README.md
Normal file
18
10_devices/README.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
[← Home](../README.md)
|
||||
|
||||
# Devices — Overview
|
||||
|
||||
## Section Index
|
||||
|
||||
| File | Description |
|
||||
|---|---|
|
||||
| [trackdisk.md](trackdisk.md) | trackdisk.device — floppy I/O |
|
||||
| [scsi.md](scsi.md) | scsi.device / 2nd.scsi.device — hard disk I/O |
|
||||
| [serial.md](serial.md) | serial.device — RS-232 |
|
||||
| [parallel.md](parallel.md) | parallel.device — Centronics |
|
||||
| [timer.md](timer.md) | timer.device — timing and delays |
|
||||
| [audio.md](audio.md) | audio.device — DMA audio channels |
|
||||
| [keyboard.md](keyboard.md) | keyboard.device — keyboard events |
|
||||
| [gameport.md](gameport.md) | gameport.device — joystick/mouse |
|
||||
| [input.md](input.md) | input.device — event merging |
|
||||
| [console.md](console.md) | console.device — text terminal I/O |
|
||||
72
10_devices/audio.md
Normal file
72
10_devices/audio.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
[← Home](../README.md) · [Devices](README.md)
|
||||
|
||||
# audio.device — DMA Audio Channels
|
||||
|
||||
## Overview
|
||||
|
||||
`audio.device` provides access to the Amiga's 4 DMA audio channels. Each channel plays 8-bit PCM samples from Chip RAM at programmable rates.
|
||||
|
||||
---
|
||||
|
||||
## Channel Allocation
|
||||
|
||||
```c
|
||||
UBYTE allocationMap[] = { 1, 2, 4, 8 }; /* channel masks */
|
||||
struct IOAudio *aio = (struct IOAudio *)
|
||||
CreateIORequest(port, sizeof(struct IOAudio));
|
||||
aio->ioa_Request.io_Message.mn_Node.ln_Pri = 0;
|
||||
aio->ioa_Data = allocationMap;
|
||||
aio->ioa_Length = sizeof(allocationMap);
|
||||
OpenDevice("audio.device", 0, (struct IORequest *)aio, 0);
|
||||
/* aio->ioa_AllocKey = allocation key for this channel */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Playing a Sample
|
||||
|
||||
```c
|
||||
aio->ioa_Request.io_Command = CMD_WRITE;
|
||||
aio->ioa_Request.io_Flags = ADIOF_PERVOL;
|
||||
aio->ioa_Data = sampleData; /* MUST be in Chip RAM */
|
||||
aio->ioa_Length = sampleLength; /* in bytes */
|
||||
aio->ioa_Period = 428; /* ~8287 Hz (PAL) */
|
||||
aio->ioa_Volume = 64; /* 0–64 */
|
||||
aio->ioa_Cycles = 1; /* 0 = loop forever */
|
||||
BeginIO((struct IORequest *)aio);
|
||||
```
|
||||
|
||||
### Period Calculation
|
||||
|
||||
```
|
||||
Period = clock_constant / desired_frequency
|
||||
PAL: clock = 3546895 Hz → Period = 3546895 / freq
|
||||
NTSC: clock = 3579545 Hz → Period = 3579545 / freq
|
||||
```
|
||||
|
||||
| Frequency | Period (PAL) |
|
||||
|---|---|
|
||||
| 8287 Hz | 428 |
|
||||
| 11025 Hz | 322 |
|
||||
| 22050 Hz | 161 |
|
||||
| 28867 Hz | 124 (minimum safe) |
|
||||
|
||||
---
|
||||
|
||||
## Channel Registers
|
||||
|
||||
| Channel | Address | Description |
|
||||
|---|---|---|
|
||||
| 0 | `$DFF0A0` | AUD0 (left) |
|
||||
| 1 | `$DFF0B0` | AUD1 (right) |
|
||||
| 2 | `$DFF0C0` | AUD2 (right) |
|
||||
| 3 | `$DFF0D0` | AUD3 (left) |
|
||||
|
||||
Each channel: pointer (PTH/PTL), length (LEN), period (PER), volume (VOL).
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `devices/audio.h`
|
||||
- HRM: audio DMA chapter
|
||||
47
10_devices/console.md
Normal file
47
10_devices/console.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
[← Home](../README.md) · [Devices](README.md)
|
||||
|
||||
# console.device — Text Terminal I/O
|
||||
|
||||
## Overview
|
||||
|
||||
`console.device` provides ANSI-compatible text rendering into Intuition windows. It translates raw keycodes to ASCII and supports a rich set of escape sequences for cursor positioning, colour, and text formatting.
|
||||
|
||||
---
|
||||
|
||||
## Opening
|
||||
|
||||
```c
|
||||
struct IOStdReq *con = CreateStdIO(port);
|
||||
con->io_Data = (APTR)win; /* the Intuition Window */
|
||||
con->io_Length = sizeof(struct Window);
|
||||
OpenDevice("console.device", 0, (struct IORequest *)con, 0);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Escape Sequences
|
||||
|
||||
| Sequence | Description |
|
||||
|---|---|
|
||||
| `\033[H` | Home cursor |
|
||||
| `\033[nA` | Cursor up n lines |
|
||||
| `\033[nB` | Cursor down n lines |
|
||||
| `\033[nC` | Cursor right n columns |
|
||||
| `\033[nD` | Cursor left n columns |
|
||||
| `\033[y;xH` | Move to row y, column x |
|
||||
| `\033[J` | Clear to end of screen |
|
||||
| `\033[K` | Clear to end of line |
|
||||
| `\033[nm` | Set graphics rendition (colour/style) |
|
||||
| `\033[0m` | Reset attributes |
|
||||
| `\033[1m` | Bold |
|
||||
| `\033[3m` | Italic |
|
||||
| `\033[4m` | Underline |
|
||||
| `\033[30–37m` | Foreground colour |
|
||||
| `\033[40–47m` | Background colour |
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `devices/conunit.h`
|
||||
- ADCD 2.1: console.device autodocs
|
||||
64
10_devices/gameport.md
Normal file
64
10_devices/gameport.md
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
[← Home](../README.md) · [Devices](README.md)
|
||||
|
||||
# gameport.device — Joystick and Mouse
|
||||
|
||||
## Overview
|
||||
|
||||
`gameport.device` reads joystick and mouse ports (active on port 1 for joystick, port 0 for mouse). Uses CIA and custom chip registers.
|
||||
|
||||
---
|
||||
|
||||
## Controller Types
|
||||
|
||||
```c
|
||||
/* devices/gameport.h */
|
||||
#define GPCT_ALLOCATED -1 /* port is allocated */
|
||||
#define GPCT_NOCONTROLLER 0 /* nothing connected */
|
||||
#define GPCT_MOUSE 1 /* mouse */
|
||||
#define GPCT_RELJOYSTICK 2 /* relative joystick (proportional) */
|
||||
#define GPCT_ABSJOYSTICK 3 /* absolute joystick */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reading a Joystick
|
||||
|
||||
```c
|
||||
struct IOStdReq *gp = CreateStdIO(port);
|
||||
OpenDevice("gameport.device", 1, (struct IORequest *)gp, 0);
|
||||
|
||||
/* Set controller type: */
|
||||
UBYTE type = GPCT_ABSJOYSTICK;
|
||||
gp->io_Command = GPD_SETCTYPE;
|
||||
gp->io_Data = &type;
|
||||
gp->io_Length = 1;
|
||||
DoIO((struct IORequest *)gp);
|
||||
|
||||
/* Set trigger conditions: */
|
||||
struct GamePortTrigger trigger = {
|
||||
GPTF_UPKEYS | GPTF_DOWNKEYS, /* report buttons */
|
||||
10000, /* X delta timeout */
|
||||
10000, /* Y delta timeout */
|
||||
1, 1 /* X/Y delta threshold */
|
||||
};
|
||||
gp->io_Command = GPD_SETTRIGGER;
|
||||
gp->io_Data = &trigger;
|
||||
gp->io_Length = sizeof(trigger);
|
||||
DoIO((struct IORequest *)gp);
|
||||
|
||||
/* Read events: */
|
||||
struct InputEvent ie;
|
||||
gp->io_Command = GPD_READEVENT;
|
||||
gp->io_Data = &ie;
|
||||
gp->io_Length = sizeof(ie);
|
||||
DoIO((struct IORequest *)gp);
|
||||
/* ie.ie_Code, ie.ie_position.ie_xy give button/direction */
|
||||
|
||||
CloseDevice((struct IORequest *)gp);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `devices/gameport.h`
|
||||
41
10_devices/input.md
Normal file
41
10_devices/input.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
[← Home](../README.md) · [Devices](README.md)
|
||||
|
||||
# input.device — Event Stream Merging
|
||||
|
||||
## Overview
|
||||
|
||||
`input.device` merges events from keyboard, mouse, gameport, and timer into a single input stream that feeds Intuition. Input handlers can be installed at various priorities to filter, modify, or consume events.
|
||||
|
||||
---
|
||||
|
||||
## Handler Priority Levels
|
||||
|
||||
| Priority | Consumer |
|
||||
|---|---|
|
||||
| 100 | System reserved |
|
||||
| 51+ | Custom high-priority handlers |
|
||||
| 50 | Intuition |
|
||||
| 20 | Console.device |
|
||||
| 0 | Default |
|
||||
|
||||
---
|
||||
|
||||
## Commands
|
||||
|
||||
| Code | Constant | Description |
|
||||
|---|---|---|
|
||||
| 9 | `IND_ADDHANDLER` | Add input handler |
|
||||
| 10 | `IND_REMHANDLER` | Remove input handler |
|
||||
| 11 | `IND_WRITEEVENT` | Inject an InputEvent into the stream |
|
||||
| 12 | `IND_SETTHRESH` | Set double-click threshold |
|
||||
| 13 | `IND_SETPERIOD` | Set key repeat period |
|
||||
| 14 | `IND_SETMPORT` | Set mouse port type |
|
||||
| 15 | `IND_SETMTRIG` | Set mouse trigger |
|
||||
| 16 | `IND_SETMTYPE` | Set mouse type |
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `devices/input.h`
|
||||
- `09_intuition/input_events.md` — handler installation example
|
||||
48
10_devices/keyboard.md
Normal file
48
10_devices/keyboard.md
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
[← Home](../README.md) · [Devices](README.md)
|
||||
|
||||
# keyboard.device — Keyboard Input
|
||||
|
||||
## Overview
|
||||
|
||||
`keyboard.device` provides raw keycode events from the keyboard controller (8520 CIA-A). Normally used indirectly via `input.device`, but can be accessed directly for keymap-independent scanning.
|
||||
|
||||
---
|
||||
|
||||
## Keycodes
|
||||
|
||||
Amiga keycodes are 7-bit values (0–127). Bit 7 indicates key-up:
|
||||
|
||||
| Code | Key | Code | Key |
|
||||
|---|---|---|---|
|
||||
| `$00` | \` (backtick) | `$40` | Space |
|
||||
| `$01`–`$0A` | 1–0 | `$41` | Backspace |
|
||||
| `$10`–`$19` | Q–P | `$42` | Tab |
|
||||
| `$20`–`$28` | A–L | `$43` | Enter (keypad) |
|
||||
| `$31`–`$39` | Z–/ | `$44` | Return |
|
||||
| `$45` | Escape | `$46` | Delete |
|
||||
| `$4C` | Cursor Up | `$4D` | Cursor Down |
|
||||
| `$4E` | Cursor Right | `$4F` | Cursor Left |
|
||||
| `$50`–`$59` | F1–F10 | `$5F` | Help |
|
||||
| `$60` | Left Shift | `$61` | Right Shift |
|
||||
| `$62` | Caps Lock | `$63` | Control |
|
||||
| `$64` | Left Alt | `$65` | Right Alt |
|
||||
| `$66` | Left Amiga | `$67` | Right Amiga |
|
||||
|
||||
---
|
||||
|
||||
## Commands
|
||||
|
||||
| Code | Constant | Description |
|
||||
|---|---|---|
|
||||
| 2 | `CMD_READ` | Read raw keycodes |
|
||||
| 5 | `CMD_CLEAR` | Clear keyboard buffer |
|
||||
| 9 | `KBD_READMATRIX` | Read full key matrix state |
|
||||
| 10 | `KBD_ADDRESETHANDLER` | Add Ctrl-Amiga-Amiga handler |
|
||||
| 11 | `KBD_REMRESETHANDLER` | Remove reset handler |
|
||||
| 12 | `KBD_RESETHANDLERDONE` | Acknowledge reset handler completion |
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `devices/keyboard.h`
|
||||
36
10_devices/parallel.md
Normal file
36
10_devices/parallel.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
[← Home](../README.md) · [Devices](README.md)
|
||||
|
||||
# parallel.device — Centronics Parallel Port
|
||||
|
||||
## Overview
|
||||
|
||||
`parallel.device` provides I/O for the Amiga's Centronics-compatible parallel port, used primarily for printers.
|
||||
|
||||
---
|
||||
|
||||
## Opening
|
||||
|
||||
```c
|
||||
struct IOExtPar *par = (struct IOExtPar *)
|
||||
CreateIORequest(port, sizeof(struct IOExtPar));
|
||||
OpenDevice("parallel.device", 0, (struct IORequest *)par, 0);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Commands
|
||||
|
||||
| Code | Constant | Description |
|
||||
|---|---|---|
|
||||
| 2 | `CMD_READ` | Read bytes (if bidirectional) |
|
||||
| 3 | `CMD_WRITE` | Write bytes |
|
||||
| 5 | `CMD_CLEAR` | Clear buffers |
|
||||
| 8 | `CMD_FLUSH` | Abort pending |
|
||||
| 9 | `PDCMD_QUERY` | Get status |
|
||||
| 10 | `PDCMD_SETPARAMS` | Set parameters |
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `devices/parallel.h`
|
||||
66
10_devices/scsi.md
Normal file
66
10_devices/scsi.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
[← Home](../README.md) · [Devices](README.md)
|
||||
|
||||
# scsi.device — Hard Disk I/O
|
||||
|
||||
## Overview
|
||||
|
||||
SCSI and IDE hard disks are accessed via `scsi.device` (A3000/A4000 built-in) or `2nd.scsi.device` / `ide.device` (A1200/A600). The API is the same as trackdisk for basic read/write, with additional SCSI direct commands.
|
||||
|
||||
---
|
||||
|
||||
## Opening
|
||||
|
||||
```c
|
||||
struct IOStdReq *scsi = CreateStdIO(port);
|
||||
OpenDevice("scsi.device", 0, (struct IORequest *)scsi, 0);
|
||||
/* unit 0 = first SCSI/IDE device */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Standard Commands
|
||||
|
||||
Same as trackdisk: `CMD_READ`, `CMD_WRITE`, `CMD_UPDATE`, `TD_CHANGENUM`, etc.
|
||||
|
||||
---
|
||||
|
||||
## Direct SCSI Commands (HD_SCSICMD)
|
||||
|
||||
```c
|
||||
struct SCSICmd scsicmd;
|
||||
UBYTE cdb[10]; /* SCSI CDB */
|
||||
UBYTE sense[20]; /* sense data buffer */
|
||||
UBYTE data[512]; /* data buffer */
|
||||
|
||||
/* Read 1 sector at LBA 0: */
|
||||
cdb[0] = 0x28; /* READ(10) */
|
||||
cdb[1] = 0;
|
||||
cdb[2] = 0; cdb[3] = 0; cdb[4] = 0; cdb[5] = 0; /* LBA = 0 */
|
||||
cdb[6] = 0;
|
||||
cdb[7] = 0; cdb[8] = 1; /* transfer length = 1 sector */
|
||||
cdb[9] = 0;
|
||||
|
||||
scsicmd.scsi_Data = (UWORD *)data;
|
||||
scsicmd.scsi_Length = 512;
|
||||
scsicmd.scsi_Command = cdb;
|
||||
scsicmd.scsi_CmdLength = 10;
|
||||
scsicmd.scsi_Flags = SCSIF_READ;
|
||||
scsicmd.scsi_SenseData = sense;
|
||||
scsicmd.scsi_SenseLength = sizeof(sense);
|
||||
|
||||
scsi->io_Command = HD_SCSICMD;
|
||||
scsi->io_Data = &scsicmd;
|
||||
scsi->io_Length = sizeof(scsicmd);
|
||||
DoIO((struct IORequest *)scsi);
|
||||
|
||||
if (scsicmd.scsi_Status != 0) {
|
||||
/* SCSI error — check sense data */
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `devices/scsidisk.h`
|
||||
- ADCD 2.1: scsi.device autodocs
|
||||
54
10_devices/serial.md
Normal file
54
10_devices/serial.md
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
[← Home](../README.md) · [Devices](README.md)
|
||||
|
||||
# serial.device — RS-232 Communication
|
||||
|
||||
## Overview
|
||||
|
||||
`serial.device` provides buffered RS-232 serial I/O through the Amiga's built-in 8520 CIA UART (active-high active sense).
|
||||
|
||||
---
|
||||
|
||||
## Opening
|
||||
|
||||
```c
|
||||
struct IOExtSer *ser = (struct IOExtSer *)
|
||||
CreateIORequest(port, sizeof(struct IOExtSer));
|
||||
OpenDevice("serial.device", 0, (struct IORequest *)ser, 0);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Setting Parameters
|
||||
|
||||
```c
|
||||
ser->io_CtlChar = SER_DEFAULT_CTLCHAR;
|
||||
ser->io_RBufLen = 4096; /* read buffer size */
|
||||
ser->io_Baud = 9600;
|
||||
ser->io_ReadLen = 8; /* data bits */
|
||||
ser->io_WriteLen = 8;
|
||||
ser->io_StopBits = 1;
|
||||
ser->io_SerFlags = SERF_XDISABLED; /* no XON/XOFF */
|
||||
ser->IOSer.io_Command = SDCMD_SETPARAMS;
|
||||
DoIO((struct IORequest *)ser);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Commands
|
||||
|
||||
| Code | Constant | Description |
|
||||
|---|---|---|
|
||||
| 2 | `CMD_READ` | Read bytes |
|
||||
| 3 | `CMD_WRITE` | Write bytes |
|
||||
| 5 | `CMD_CLEAR` | Clear buffers |
|
||||
| 8 | `CMD_FLUSH` | Abort pending requests |
|
||||
| 9 | `SDCMD_QUERY` | Get status (bytes in buffer, errors) |
|
||||
| 10 | `SDCMD_BREAK` | Send break signal |
|
||||
| 11 | `SDCMD_SETPARAMS` | Set baud/bits/parity/stop |
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `devices/serial.h`
|
||||
- ADCD 2.1: serial.device autodocs
|
||||
79
10_devices/timer.md
Normal file
79
10_devices/timer.md
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
[← Home](../README.md) · [Devices](README.md)
|
||||
|
||||
# timer.device — Timing and Delays
|
||||
|
||||
## Overview
|
||||
|
||||
`timer.device` provides precise timing services: delays, time-of-day, and high-resolution timestamps. It has two units:
|
||||
|
||||
| Unit | Constant | Resolution | Use |
|
||||
|---|---|---|---|
|
||||
| 0 | `UNIT_MICROHZ` | ~2µs (E-clock) | Short, precise delays |
|
||||
| 1 | `UNIT_VBLANK` | ~20ms (VBlank) | Long delays, lower overhead |
|
||||
| 2 | `UNIT_ECLOCK` | CIA E-clock ticks | Highest resolution timing (OS 2.0+) |
|
||||
| 3 | `UNIT_WAITUNTIL` | absolute time | Wait until specific time (OS 2.0+) |
|
||||
| 4 | `UNIT_WAITECLOCK` | E-clock absolute | (OS 2.0+) |
|
||||
|
||||
---
|
||||
|
||||
## struct timeval / timerequest
|
||||
|
||||
```c
|
||||
/* devices/timer.h — NDK39 */
|
||||
struct timeval {
|
||||
ULONG tv_secs; /* seconds */
|
||||
ULONG tv_micro; /* microseconds */
|
||||
};
|
||||
|
||||
struct timerequest {
|
||||
struct IORequest tr_node;
|
||||
struct timeval tr_time;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Simple Delay
|
||||
|
||||
```c
|
||||
struct timerequest *tr = (struct timerequest *)
|
||||
CreateIORequest(port, sizeof(struct timerequest));
|
||||
OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)tr, 0);
|
||||
|
||||
tr->tr_node.io_Command = TR_ADDREQUEST;
|
||||
tr->tr_time.tv_secs = 2;
|
||||
tr->tr_time.tv_micro = 0;
|
||||
DoIO((struct IORequest *)tr); /* blocks for 2 seconds */
|
||||
|
||||
CloseDevice((struct IORequest *)tr);
|
||||
DeleteIORequest((struct IORequest *)tr);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Current Time
|
||||
|
||||
```c
|
||||
tr->tr_node.io_Command = TR_GETSYSTIME;
|
||||
DoIO((struct IORequest *)tr);
|
||||
Printf("Time: %lu.%06lu\n", tr->tr_time.tv_secs, tr->tr_time.tv_micro);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## High-Resolution Timing
|
||||
|
||||
```c
|
||||
/* Read E-clock (OS 2.0+): */
|
||||
struct EClockVal eclock;
|
||||
ULONG freq = ReadEClock(&eclock); /* returns ticks/second */
|
||||
/* eclock.ev_hi, eclock.ev_lo = 64-bit tick count */
|
||||
/* Typical freq: 709379 Hz (PAL) or 715909 Hz (NTSC) */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `devices/timer.h`
|
||||
- ADCD 2.1: timer.device autodocs
|
||||
74
10_devices/trackdisk.md
Normal file
74
10_devices/trackdisk.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
[← Home](../README.md) · [Devices](README.md)
|
||||
|
||||
# trackdisk.device — Floppy Disk I/O
|
||||
|
||||
## Overview
|
||||
|
||||
`trackdisk.device` provides raw sector I/O for Amiga floppy drives. Each drive is a unit (0–3). The device operates on 512-byte sectors, 11 sectors per track (880 KB DD disks) or 22 per track (1760 KB HD).
|
||||
|
||||
---
|
||||
|
||||
## Opening
|
||||
|
||||
```c
|
||||
struct IOExtTD *tdreq = (struct IOExtTD *)
|
||||
CreateIORequest(port, sizeof(struct IOExtTD));
|
||||
OpenDevice("trackdisk.device", 0, (struct IORequest *)tdreq, 0);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Commands
|
||||
|
||||
| Code | Constant | Description |
|
||||
|---|---|---|
|
||||
| 2 | `CMD_READ` | Read sectors |
|
||||
| 3 | `CMD_WRITE` | Write sectors |
|
||||
| 4 | `CMD_UPDATE` | Flush write buffer to disk |
|
||||
| 9 | `TD_MOTOR` | Turn motor on/off |
|
||||
| 10 | `TD_FORMAT` | Low-level format track |
|
||||
| 11 | `TD_SEEK` | Move head to track |
|
||||
| 12 | `TD_REMOVE` | Notify on disk change |
|
||||
| 13 | `TD_CHANGENUM` | Get disk change count |
|
||||
| 14 | `TD_CHANGESTATE` | Check if disk present |
|
||||
| 15 | `TD_PROTSTATUS` | Check write-protect |
|
||||
| 16 | `TD_RAWREAD` | Read raw MFM data |
|
||||
| 17 | `TD_RAWWRITE` | Write raw MFM data |
|
||||
| 18 | `TD_GETDRIVETYPE` | Get drive type |
|
||||
| 19 | `TD_GETNUMTRACKS` | Get total tracks |
|
||||
| 20 | `TD_ADDCHANGEINT` | Add disk change interrupt |
|
||||
| 21 | `TD_REMCHANGEINT` | Remove disk change interrupt |
|
||||
|
||||
---
|
||||
|
||||
## Reading a Sector
|
||||
|
||||
```c
|
||||
UBYTE buf[512];
|
||||
tdreq->iotd_Req.io_Command = CMD_READ;
|
||||
tdreq->iotd_Req.io_Data = buf;
|
||||
tdreq->iotd_Req.io_Length = 512;
|
||||
tdreq->iotd_Req.io_Offset = 0; /* byte offset = sector * 512 */
|
||||
DoIO((struct IORequest *)tdreq);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Disk Geometry
|
||||
|
||||
| Parameter | DD (880 KB) | HD (1760 KB) |
|
||||
|---|---|---|
|
||||
| Heads | 2 | 2 |
|
||||
| Cylinders | 80 | 80 |
|
||||
| Sectors/track | 11 | 22 |
|
||||
| Bytes/sector | 512 | 512 |
|
||||
| Total sectors | 1760 | 3520 |
|
||||
|
||||
Byte offset = `(cylinder * 2 + head) * sectors_per_track * 512 + sector * 512`
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `devices/trackdisk.h`
|
||||
- ADCD 2.1: trackdisk.device autodocs
|
||||
Loading…
Add table
Add a link
Reference in a new issue