Introduction
An Amiga program is relocatable except for a few places that are the same on every Amiga. The disassembly of a hunk puts a note on an instruction that uses one of them, so
movea.l $4.w,a6 reads as “AbsExecBase” and move.w d0,$dff180 as “COLOR00”. The names come from the Amiga Hardware Reference Manual’s register summary
and the NetBSD header that retypes the CIA register map (read through page summaries); the library function names come from the NDK’s .fd files as the amitools project keeps them.
AbsExecBase
The long at address 4 is the base address of exec.library. It is the only absolute address an Amiga program is expected to use: it loads it
(movea.l 4.w,a6) and finds every other library through exec. The viewer names a reference to address 4 AbsExecBase (not a branch or a PC-relative reference, where 4 is only an
offset in the hunk).
Custom chip registers
The custom chips (Agnus, Denise, Paula) are registers at $DFF000 plus an offset; $DFF000 to $DFF1FF. Names and offsets follow the Hardware Reference Manual’s register
summary in address order. The viewer also names an odd address inside a register (a byte access) with “odd byte”.
| Offset | Name | Access | Offset | Name | Access | Offset | Name | Access |
|---|---|---|---|---|---|---|---|---|
$000 | BLTDDAT | early read | $002 | DMACONR | read | $004 | VPOSR | read |
$006 | VHPOSR | read | $008 | DSKDATR | early read | $00A | JOY0DAT | read |
$00C | JOY1DAT | read | $00E | CLXDAT | read | $010 | ADKCONR | read |
$012 | POT0DAT | read | $014 | POT1DAT | read | $016 | POTGOR | read |
$018 | SERDATR | read | $01A | DSKBYTR | read | $01C | INTENAR | read |
$01E | INTREQR | read | $020 | DSKPTH | write | $022 | DSKPTL | write |
$024 | DSKLEN | write | $026 | DSKDAT | write | $028 | REFPTR | write |
$02A | VPOSW | write | $02C | VHPOSW | write | $02E | COPCON | write |
$030 | SERDAT | write | $032 | SERPER | write | $034 | POTGO | write |
$036 | JOYTEST | write | $038 | STREQU | strobe | $03A | STRVBL | strobe |
$03C | STRHOR | strobe | $03E | STRLONG | strobe | $040 | BLTCON0 | write |
$042 | BLTCON1 | write | $044 | BLTAFWM | write | $046 | BLTALWM | write |
$048 | BLTCPTH | write | $04A | BLTCPTL | write | $04C | BLTBPTH | write |
$04E | BLTBPTL | write | $050 | BLTAPTH | write | $052 | BLTAPTL | write |
$054 | BLTDPTH | write | $056 | BLTDPTL | write | $058 | BLTSIZE | write |
$05A | BLTCON0L | write | $05C | BLTSIZV | write | $05E | BLTSIZH | write |
$060 | BLTCMOD | write | $062 | BLTBMOD | write | $064 | BLTAMOD | write |
$066 | BLTDMOD | write | $070 | BLTCDAT | write | $072 | BLTBDAT | write |
$074 | BLTADAT | write | $078 | SPRHDAT | write | $07C | DENISEID | read |
$07E | DSKSYNC | write | $080 | COP1LCH | write | $082 | COP1LCL | write |
$084 | COP2LCH | write | $086 | COP2LCL | write | $088 | COPJMP1 | strobe |
$08A | COPJMP2 | strobe | $08C | COPINS | write | $08E | DIWSTRT | write |
$090 | DIWSTOP | write | $092 | DDFSTRT | write | $094 | DDFSTOP | write |
$096 | DMACON | write | $098 | CLXCON | write | $09A | INTENA | write |
$09C | INTREQ | write | $09E | ADKCON | write | $100 | BPLCON0 | write |
$102 | BPLCON1 | write | $104 | BPLCON2 | write | $106 | BPLCON3 | write |
$108 | BPL1MOD | write | $10A | BPL2MOD | write | $1C0 | HTOTAL | write |
$1C2 | HSSTOP | write | $1C4 | HBSTRT | write | $1C6 | HBSTOP | write |
$1C8 | VTOTAL | write | $1CA | VSSTOP | write | $1CC | VBSTRT | write |
$1CE | VBSTOP | write | $1DC | BEAMCON0 | write | $1DE | HSSTRT | write |
$1E0 | VSSTRT | write | $1E2 | HCENTER | write | $1E4 | DIWHIGH | write |
The registers that come in runs:
| Registers | Offsets |
|---|---|
| AUD0LCH to AUD3DAT: for channel n = 0 to 3, LCH, LCL, LEN, PER, VOL, DAT | $0A0 + n × $10, then 2 bytes each (AUD3DAT is $0DA) |
| BPL1PTH to BPL6PTL: the bitplane pointers, high then low half | $0E0 + 4 × (plane − 1), and +2 for the low half (BPL6PTL is $0F6) |
| BPL1DAT to BPL6DAT: the bitplane data | $110 + 2 × (plane − 1) |
| SPR0PTH to SPR7PTL: the sprite pointers | $120 + 4 × n, and +2 for the low half (SPR7PTH is $13C) |
| SPR0POS to SPR7DATB: for sprite n = 0 to 7, POS, CTL, DATA, DATB | $140 + 8 × n, then 2 bytes each (SPR7DATB is $17E) |
| COLOR00 to COLOR31: the palette | $180 + 2 × n (COLOR31 is $1BE) |
Offsets the manual lists as reserved or unused, such as $068, are not named. The manual warns against writing to undocumented registers. Some registers exist only in the later chip sets (ECS: BEAMCON0, DIWHIGH and the
display-timing registers); the viewer names them whatever chip set the program targets.
CIA registers
Two 8520 CIA chips hold the timers, the keyboard, the serial and parallel ports, the disk-drive control lines and more. CIA A answers at odd addresses from $BFE001, CIA B at
even addresses from $BFD000; the sixteen registers are $100 bytes apart. The register order is that of the NetBSD cia.h.
| Register number | Name | CIA A address | CIA B address |
|---|---|---|---|
| 0 | PRA | $BFE001 | $BFD000 |
| 1 | PRB | $BFE101 | $BFD100 |
| 2 | DDRA | $BFE201 | $BFD200 |
| 3 | DDRB | $BFE301 | $BFD300 |
| 4, 5 | TALO, TAHI | $BFE401, $BFE501 | $BFD400, $BFD500 |
| 6, 7 | TBLO, TBHI | $BFE601, $BFE701 | $BFD600, $BFD700 |
| 8, 9, 10 | TODLO, TODMID, TODHI | $BFE801, $BFE901, $BFEA01 | $BFD800, $BFD900, $BFDA00 |
| 11 | (unused) | $BFEB01 | $BFDB00 |
| 12 | SDR | $BFEC01 | $BFDC00 |
| 13 | ICR | $BFED01 | $BFDD00 |
| 14, 15 | CRA, CRB | $BFEE01, $BFEF01 | $BFDE00, $BFDF00 |
The viewer’s names are CIAAPRA, CIAAPRB and so on. The port bits NetBSD names are: CIA A port A: OVL, LED, CHNG, WPRO, TK0, RDY, FIR0, FIR1 (bits 0 to 7); CIA B port A: BUSY, POUT, SEL, DSR, CTS, CD, RTS, DTR; CIA B port B: STEP, DIR, SIDE, SEL0, SEL1, SEL2, SEL3, MTR. The viewer lists them here only; it does not decode the bits of an operand.
Library calls
A call to a library function is jsr -offset(a6), with a6 holding the library’s base. Which library a6 holds is not in the instruction: it depends on the register’s value at that point, which the viewer
does not track. So the viewer names the call only for the library you choose in the options, and says so in the note (exec.library _LVOOpenLibrary (-552) if a6 = ExecBase). The default is exec.library, whose base is
the long at address 4. A library’s first function is at −30 and each slot is 6 bytes.
| Library | Base name | Names in the viewer |
|---|---|---|
| exec.library | ExecBase | 120 public functions from −30 to −828 |
| dos.library | DOSBase | 164 functions from −30 to −1158 |
| intuition.library | IntuitionBase | 127 functions from −30 to −1212 |
| graphics.library | GfxBase | 163 functions from −30 to −1056 |
The tables are from the .fd files kept in the amitools project (exec_lib.fd, dos_lib.fd, intuition_lib.fd, graphics_lib.fd), read through a page
summary. A slot those files mark private has no name here; for exec these are −36 to −66, −504 to −516, −792 to
−804 and −816 to −822. The viewer only says “not a public function” for such an offset. The exec table in full:
| Offset | Function | Offset | Function | Offset | Function | Offset | Function |
|---|---|---|---|---|---|---|---|
| −30 | Supervisor | −72 | InitCode | −78 | InitStruct | −84 | MakeLibrary |
| −90 | MakeFunctions | −96 | FindResident | −102 | InitResident | −108 | Alert |
| −114 | Debug | −120 | Disable | −126 | Enable | −132 | Forbid |
| −138 | Permit | −144 | SetSR | −150 | SuperState | −156 | UserState |
| −162 | SetIntVector | −168 | AddIntServer | −174 | RemIntServer | −180 | Cause |
| −186 | Allocate | −192 | Deallocate | −198 | AllocMem | −204 | AllocAbs |
| −210 | FreeMem | −216 | AvailMem | −222 | AllocEntry | −228 | FreeEntry |
| −234 | Insert | −240 | AddHead | −246 | AddTail | −252 | Remove |
| −258 | RemHead | −264 | RemTail | −270 | Enqueue | −276 | FindName |
| −282 | AddTask | −288 | RemTask | −294 | FindTask | −300 | SetTaskPri |
| −306 | SetSignal | −312 | SetExcept | −318 | Wait | −324 | Signal |
| −330 | AllocSignal | −336 | FreeSignal | −342 | AllocTrap | −348 | FreeTrap |
| −354 | AddPort | −360 | RemPort | −366 | PutMsg | −372 | GetMsg |
| −378 | ReplyMsg | −384 | WaitPort | −390 | FindPort | −396 | AddLibrary |
| −402 | RemLibrary | −408 | OldOpenLibrary | −414 | CloseLibrary | −420 | SetFunction |
| −426 | SumLibrary | −432 | AddDevice | −438 | RemDevice | −444 | OpenDevice |
| −450 | CloseDevice | −456 | DoIO | −462 | SendIO | −468 | CheckIO |
| −474 | WaitIO | −480 | AbortIO | −486 | AddResource | −492 | RemResource |
| −498 | OpenResource | −522 | RawDoFmt | −528 | GetCC | −534 | TypeOfMem |
| −540 | Procure | −546 | Vacate | −552 | OpenLibrary | −558 | InitSemaphore |
| −564 | ObtainSemaphore | −570 | ReleaseSemaphore | −576 | AttemptSemaphore | −582 | ObtainSemaphoreList |
| −588 | ReleaseSemaphoreList | −594 | FindSemaphore | −600 | AddSemaphore | −606 | RemSemaphore |
| −612 | SumKickData | −618 | AddMemList | −624 | CopyMem | −630 | CopyMemQuick |
| −636 | CacheClearU | −642 | CacheClearE | −648 | CacheControl | −654 | CreateIORequest |
| −660 | DeleteIORequest | −666 | CreateMsgPort | −672 | DeleteMsgPort | −678 | ObtainSemaphoreShared |
| −684 | AllocVec | −690 | FreeVec | −696 | CreatePool | −702 | DeletePool |
| −708 | AllocPooled | −714 | FreePooled | −720 | AttemptSemaphoreShared | −726 | ColdReboot |
| −732 | StackSwap | −738 | ChildFree | −744 | ChildOrphan | −750 | ChildStatus |
| −756 | ChildWait | −762 | CachePreDMA | −768 | CachePostDMA | −774 | AddMemHandler |
| −780 | RemMemHandler | −786 | ObtainQuickVector | −810 | TaggedOpenLibrary | −828 | NewMinList |
The dos, intuition and graphics tables are in the viewer’s option and not repeated here.
Not described
Known, not yet covered
- Reference: the bits of each custom and CIA register, the dos, intuition and graphics tables on this page, the other libraries (a program may call any library, including ones not in the NDK’s main set), and the library structure that precedes each library’s base (the jump table’s layout in memory). The ECS and AGA chip sets add registers the summary used here may not list in full.
- Viewer: only the instruction’s own operand is looked at: a register-relative access such as
move.w d0,$180(a5)with a5 set to$DFF000is not recognised, because that needs the register’s value. Library calls are named for one chosen library; there is no tracking of what a6 holds. Zorro and Kickstart-internal addresses are not named.
Links
Reference
- Amiga Hardware Reference Manual: register summary, address order – the Developer CD HTML copy
- NetBSD amiga cia.h – the CIA register map and the port bit names
- amitools data/fd – the NDK .fd files with the library vector offsets