amiga-bootcamp/16_driver_development/ahi_driver.md
Ilia Sharin 21751c0025 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.
2026-04-23 12:17:35 -04:00

185 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[← Home](../README.md) · [Driver Development](README.md)
# Writing AHI Audio Drivers
## Overview
**AHI** (Audio Hardware Interface) is the standard retargetable audio system for AmigaOS. It abstracts audio hardware behind a uniform API, similar to how RTG abstracts graphics cards. AHI drivers are shared libraries that implement the AHI driver protocol.
---
## Architecture
```
Application
↓ ahi.device (OpenDevice, CMD_WRITE, etc.)
AHI System
↓ Calls driver functions via function table
AHI Audio Driver (.audio file)
↓ Programs hardware / DMA / codec
Audio Hardware (Paula, sound card, FPGA audio, codec)
```
---
## Driver File Location
```
DEVS:AHI/myaudio.audio ; the driver library
DEVS:AudioModes/myaudio ; mode file (preferences)
```
---
## Required Driver Functions
| Function | LVO | Description |
|---|---|---|
| `AHIsub_AllocAudio` | 30 | Allocate hardware resources |
| `AHIsub_FreeAudio` | 36 | Free hardware resources |
| `AHIsub_Disable` | 42 | Disable audio interrupts |
| `AHIsub_Enable` | 48 | Enable audio interrupts |
| `AHIsub_Start` | 54 | Start playback/recording |
| `AHIsub_Update` | 60 | Update playback parameters |
| `AHIsub_Stop` | 66 | Stop playback/recording |
| `AHIsub_SetVol` | 72 | Set channel volume/panning |
| `AHIsub_SetFreq` | 78 | Set channel frequency |
| `AHIsub_SetSound` | 84 | Set channel sound data |
| `AHIsub_SetEffect` | 90 | Set audio effects |
| `AHIsub_LoadSound` | 96 | Load a sound into hardware |
| `AHIsub_UnloadSound` | 102 | Unload a sound |
| `AHIsub_GetAttr` | 108 | Query driver capabilities |
| `AHIsub_HardwareControl` | 114 | Hardware-specific control |
---
## AHIsub_AllocAudio
```c
ULONG AHIsub_AllocAudio(struct AHIAudioCtrlDrv *audioctrl,
struct TagItem *tags)
{
/* Allocate hardware resources */
struct MyDriverData *dd = AllocMem(sizeof(*dd), MEMF_PUBLIC|MEMF_CLEAR);
audioctrl->ahiac_DriverData = dd;
/* Set up interrupt for mixing: */
dd->dd_Interrupt.is_Node.ln_Type = NT_INTERRUPT;
dd->dd_Interrupt.is_Node.ln_Pri = 0;
dd->dd_Interrupt.is_Node.ln_Name = "myaudio";
dd->dd_Interrupt.is_Code = (APTR)PlaybackInterrupt;
dd->dd_Interrupt.is_Data = audioctrl;
/* Report capabilities: */
return AHISF_CANRECORD | /* can record */
AHISF_KNOWSTEREO | /* knows stereo */
AHISF_MIXING; /* uses AHI's software mixing */
}
```
---
## AHIsub_Start — Begin Playback
```c
ULONG AHIsub_Start(ULONG flags, struct AHIAudioCtrlDrv *audioctrl)
{
struct MyDriverData *dd = audioctrl->ahiac_DriverData;
if (flags & AHISF_PLAY) {
/* Allocate DMA buffer: */
dd->dd_MixBuffer = AllocMem(audioctrl->ahiac_BuffSamples * 4,
MEMF_CHIP | MEMF_CLEAR);
/* Set up timer interrupt for mixing callback: */
/* Timer fires at: audioctrl->ahiac_PlayerFreq */
dd->dd_TimerReq->tr_time.tv_micro =
1000000 / audioctrl->ahiac_PlayerFreq;
/* Start the interrupt-driven playback loop: */
AddIntServer(INTB_VERTB, &dd->dd_Interrupt);
}
return AHIE_OK;
}
```
---
## Playback Interrupt — The Mixing Callback
```c
LONG __saveds PlaybackInterrupt(struct AHIAudioCtrlDrv *audioctrl __asm("a1"))
{
struct MyDriverData *dd = audioctrl->ahiac_DriverData;
/* Call AHI's software mixer to fill our buffer: */
CallHookPkt(audioctrl->ahiac_PlayerFunc, audioctrl, NULL);
CallHookPkt(audioctrl->ahiac_MixerFunc, audioctrl, dd->dd_MixBuffer);
/* dd->dd_MixBuffer now contains mixed PCM data */
/* Feed it to hardware DMA / codec / FPGA: */
HW_SetDMAPointer(dd->dd_HWBase, dd->dd_MixBuffer);
HW_SetDMALength(dd->dd_HWBase, audioctrl->ahiac_BuffSamples);
return 0;
}
```
---
## AHIsub_GetAttr — Report Capabilities
```c
LONG AHIsub_GetAttr(ULONG attribute, LONG argument, LONG default_val,
struct TagItem *tags, struct AHIBase *AHIBase)
{
switch (attribute) {
case AHIDB_Bits: return 16; /* 16-bit audio */
case AHIDB_MaxChannels: return 2; /* stereo */
case AHIDB_Frequencies: return 4; /* number of supported rates */
case AHIDB_Frequency:
switch (argument) {
case 0: return 22050;
case 1: return 44100;
case 2: return 48000;
case 3: return 96000;
}
break;
case AHIDB_Author: return (LONG)"My Name";
case AHIDB_Copyright: return (LONG)"(C) 2026";
case AHIDB_Version: return (LONG)"myaudio 1.0";
case AHIDB_Annotation: return (LONG)"FPGA audio driver";
case AHIDB_Record: return TRUE;
case AHIDB_FullDuplex: return TRUE;
case AHIDB_MinMixFreq: return 8000;
case AHIDB_MaxMixFreq: return 96000;
}
return default_val;
}
```
---
## Audio Mode Registration
Create `DEVS:AudioModes/myaudio`:
```
;; AHI audio mode file
BEGIN
Name "MyAudio:HiFi 16 bit stereo++"
Driver "DEVS:AHI/myaudio.audio"
Flags 0
Frequency 44100 48000 96000
END
```
---
## References
- AHI Developer's Guide (Martin Blom)
- AHI SDK: Aminet `dev/misc/ahidev.lha`
- Example: `paula.audio` driver source (AHI distribution)