From dd3e4176b99566620723fca341154fb14993f8f2 Mon Sep 17 00:00:00 2001 From: Willem Drijver Date: Wed, 4 Nov 2026 14:02:05 +0300 Subject: [PATCH 01/12] SAGA register intake: SAGA-specific registers into core/saga-registers/ Add the SAGA register documentation (HTML, 93 pages) verbatim to sources/official/saga-registers/ and the converter tools/intake/sagaregs.py, which generates 12 files in core/saga-registers/: the SAGA-specific rows of index.htm (OCS, ECS and AGA empty, plus the SAGA addresses the original also marks as classic), without the Atari section. The converter applies a listed set of corrections (typos in addresses and descriptions, $DFF3EC is writable) and adds, with source tags, what the original lacks: PIP 2 and the 32x32 pointer sprite from ApolloLib, the Arne volume range, channels 0-3 = Paula, and the board IDs. Open questions are listed in core/saga-registers/index.md. Point AGENTS.md, CONTRIBUTING.md and the chip folders to the new folder. Co-Authored-By: Claude Opus 5.5 --- .github/CODEOWNERS | 12 + AGENTS.md | 7 +- CONTRIBUTING.md | 3 + core/saga-3d-maggie/index.md | 8 +- core/saga-3d-maggie/registers.md | 1 + core/saga-audio-arne/index.md | 14 +- core/saga-audio-arne/registers.md | 8 +- core/saga-registers/arne-channels.md | 92 + .../saga-registers/arne-dma-and-interrupts.md | 100 + core/saga-registers/chunky-plane.md | 113 + core/saga-registers/colour-ports.md | 75 + core/saga-registers/display-control.md | 91 + core/saga-registers/index.md | 185 + core/saga-registers/input.md | 97 + core/saga-registers/maggie-3d.md | 82 + core/saga-registers/pip.md | 94 + core/saga-registers/pointer.md | 76 + core/saga-registers/sprite-collision.md | 71 + core/saga-registers/system.md | 74 + core/saga-video-isabelle/index.md | 15 +- sources/official/saga-registers/adkcon.html | 54 + sources/official/saga-registers/adkcon2.htm | 32 + sources/official/saga-registers/adkconr.htm | 51 + sources/official/saga-registers/audnvol.htm | 21 + sources/official/saga-registers/audxctrl.htm | 26 + sources/official/saga-registers/audxdat.htm | 24 + sources/official/saga-registers/audxl.htm | 11 + sources/official/saga-registers/audxlch.htm | 22 + sources/official/saga-registers/audxlen.htm | 12 + sources/official/saga-registers/audxper.htm | 19 + sources/official/saga-registers/audxvol.htm | 24 + sources/official/saga-registers/audxvol2.htm | 25 + sources/official/saga-registers/beamcon0.htm | 13 + sources/official/saga-registers/bltafwm.htm | 20 + sources/official/saga-registers/bltcon0.htm | 114 + sources/official/saga-registers/bltddat.htm | 18 + sources/official/saga-registers/bltsize.htm | 39 + sources/official/saga-registers/bltsizh.htm | 40 + sources/official/saga-registers/bltsizv.htm | 40 + sources/official/saga-registers/bltxdat.htm | 22 + sources/official/saga-registers/bltxmod.htm | 34 + sources/official/saga-registers/bltxpth.htm | 30 + sources/official/saga-registers/bplcon0.htm | 65 + sources/official/saga-registers/bplcon1.htm | 65 + sources/official/saga-registers/bplcon2.htm | 65 + sources/official/saga-registers/bplcon3.htm | 65 + sources/official/saga-registers/bplhmod.htm | 13 + sources/official/saga-registers/bplhpth.htm | 12 + sources/official/saga-registers/bplxdat.htm | 28 + sources/official/saga-registers/bplxmod.htm | 24 + sources/official/saga-registers/bplxpth.htm | 20 + sources/official/saga-registers/chunkycol.htm | 29 + sources/official/saga-registers/clxcon.htm | 51 + sources/official/saga-registers/clxdat.htm | 39 + sources/official/saga-registers/clxdatx.htm | 32 + sources/official/saga-registers/colorx.htm | 28 + sources/official/saga-registers/cop1lch.htm | 22 + sources/official/saga-registers/cop2lch.htm | 24 + sources/official/saga-registers/copcon.htm | 22 + sources/official/saga-registers/copins.htm | 100 + sources/official/saga-registers/copjmp.htm | 21 + sources/official/saga-registers/ddfstrt.htm | 48 + sources/official/saga-registers/deniseid.htm | 14 + sources/official/saga-registers/diwhigh.htm | 36 + sources/official/saga-registers/diwstrt.htm | 34 + sources/official/saga-registers/dmacon2.htm | 32 + sources/official/saga-registers/dmaconr.htm | 45 + sources/official/saga-registers/dskbytr.htm | 30 + sources/official/saga-registers/dskdatr.htm | 24 + sources/official/saga-registers/dsklen.htm | 24 + sources/official/saga-registers/dskpth.htm | 18 + sources/official/saga-registers/dsksync.htm | 15 + sources/official/saga-registers/fmode.htm | 27 + sources/official/saga-registers/gfxmode.htm | 54 + sources/official/saga-registers/hbstrt.htm | 21 + sources/official/saga-registers/hcenter.htm | 23 + sources/official/saga-registers/hsstop.htm | 21 + sources/official/saga-registers/hsstrt.htm | 19 + sources/official/saga-registers/htotal.htm | 20 + sources/official/saga-registers/index.htm | 3386 +++++++++++++++++ sources/official/saga-registers/intena2.htm | 39 + sources/official/saga-registers/intenar.htm | 41 + sources/official/saga-registers/intreq2.htm | 41 + sources/official/saga-registers/intreqr.htm | 24 + sources/official/saga-registers/joy0dat.htm | 68 + .../official/saga-registers/joybuttons.htm | 32 + sources/official/saga-registers/joytest.htm | 20 + .../official/saga-registers/mousewheel.htm | 25 + sources/official/saga-registers/pipcol.htm | 28 + sources/official/saga-registers/planarcol.htm | 29 + sources/official/saga-registers/pot0dat.htm | 34 + sources/official/saga-registers/potgo.htm | 38 + sources/official/saga-registers/potinp.htm | 33 + sources/official/saga-registers/refptr.htm | 18 + sources/official/saga-registers/saga.htm | 2139 +++++++++++ .../official/saga-registers/sagacontrol.htm | 31 + .../official/saga-registers/screenadjust.htm | 29 + sources/official/saga-registers/serdat.htm | 64 + sources/official/saga-registers/serdatr.htm | 66 + sources/official/saga-registers/serper.htm | 22 + sources/official/saga-registers/shiftdown.htm | 19 + sources/official/saga-registers/spritecol.htm | 29 + sources/official/saga-registers/sprxctl.htm | 40 + sources/official/saga-registers/sprxdata.htm | 27 + sources/official/saga-registers/sprxpos.htm | 41 + sources/official/saga-registers/sprxpth.htm | 24 + sources/official/saga-registers/strequ.htm | 28 + .../official/saga-registers/vampversion.htm | 19 + sources/official/saga-registers/vbstrt.htm | 17 + sources/official/saga-registers/vhposr.htm | 22 + sources/official/saga-registers/vposr.htm | 22 + sources/official/saga-registers/vsstrt.htm | 16 + sources/official/saga-registers/vtotal.htm | 21 + tools/intake/sagaregs.py | 937 +++++ 114 files changed, 10588 insertions(+), 20 deletions(-) create mode 100644 core/saga-registers/arne-channels.md create mode 100644 core/saga-registers/arne-dma-and-interrupts.md create mode 100644 core/saga-registers/chunky-plane.md create mode 100644 core/saga-registers/colour-ports.md create mode 100644 core/saga-registers/display-control.md create mode 100644 core/saga-registers/index.md create mode 100644 core/saga-registers/input.md create mode 100644 core/saga-registers/maggie-3d.md create mode 100644 core/saga-registers/pip.md create mode 100644 core/saga-registers/pointer.md create mode 100644 core/saga-registers/sprite-collision.md create mode 100644 core/saga-registers/system.md create mode 100755 sources/official/saga-registers/adkcon.html create mode 100755 sources/official/saga-registers/adkcon2.htm create mode 100755 sources/official/saga-registers/adkconr.htm create mode 100755 sources/official/saga-registers/audnvol.htm create mode 100755 sources/official/saga-registers/audxctrl.htm create mode 100755 sources/official/saga-registers/audxdat.htm create mode 100755 sources/official/saga-registers/audxl.htm create mode 100755 sources/official/saga-registers/audxlch.htm create mode 100755 sources/official/saga-registers/audxlen.htm create mode 100755 sources/official/saga-registers/audxper.htm create mode 100755 sources/official/saga-registers/audxvol.htm create mode 100755 sources/official/saga-registers/audxvol2.htm create mode 100755 sources/official/saga-registers/beamcon0.htm create mode 100755 sources/official/saga-registers/bltafwm.htm create mode 100755 sources/official/saga-registers/bltcon0.htm create mode 100755 sources/official/saga-registers/bltddat.htm create mode 100755 sources/official/saga-registers/bltsize.htm create mode 100755 sources/official/saga-registers/bltsizh.htm create mode 100755 sources/official/saga-registers/bltsizv.htm create mode 100755 sources/official/saga-registers/bltxdat.htm create mode 100755 sources/official/saga-registers/bltxmod.htm create mode 100755 sources/official/saga-registers/bltxpth.htm create mode 100755 sources/official/saga-registers/bplcon0.htm create mode 100755 sources/official/saga-registers/bplcon1.htm create mode 100755 sources/official/saga-registers/bplcon2.htm create mode 100755 sources/official/saga-registers/bplcon3.htm create mode 100755 sources/official/saga-registers/bplhmod.htm create mode 100755 sources/official/saga-registers/bplhpth.htm create mode 100755 sources/official/saga-registers/bplxdat.htm create mode 100755 sources/official/saga-registers/bplxmod.htm create mode 100755 sources/official/saga-registers/bplxpth.htm create mode 100755 sources/official/saga-registers/chunkycol.htm create mode 100755 sources/official/saga-registers/clxcon.htm create mode 100755 sources/official/saga-registers/clxdat.htm create mode 100755 sources/official/saga-registers/clxdatx.htm create mode 100755 sources/official/saga-registers/colorx.htm create mode 100755 sources/official/saga-registers/cop1lch.htm create mode 100755 sources/official/saga-registers/cop2lch.htm create mode 100755 sources/official/saga-registers/copcon.htm create mode 100755 sources/official/saga-registers/copins.htm create mode 100755 sources/official/saga-registers/copjmp.htm create mode 100755 sources/official/saga-registers/ddfstrt.htm create mode 100755 sources/official/saga-registers/deniseid.htm create mode 100755 sources/official/saga-registers/diwhigh.htm create mode 100755 sources/official/saga-registers/diwstrt.htm create mode 100755 sources/official/saga-registers/dmacon2.htm create mode 100755 sources/official/saga-registers/dmaconr.htm create mode 100755 sources/official/saga-registers/dskbytr.htm create mode 100755 sources/official/saga-registers/dskdatr.htm create mode 100755 sources/official/saga-registers/dsklen.htm create mode 100755 sources/official/saga-registers/dskpth.htm create mode 100755 sources/official/saga-registers/dsksync.htm create mode 100755 sources/official/saga-registers/fmode.htm create mode 100755 sources/official/saga-registers/gfxmode.htm create mode 100755 sources/official/saga-registers/hbstrt.htm create mode 100755 sources/official/saga-registers/hcenter.htm create mode 100755 sources/official/saga-registers/hsstop.htm create mode 100755 sources/official/saga-registers/hsstrt.htm create mode 100755 sources/official/saga-registers/htotal.htm create mode 100755 sources/official/saga-registers/index.htm create mode 100755 sources/official/saga-registers/intena2.htm create mode 100755 sources/official/saga-registers/intenar.htm create mode 100755 sources/official/saga-registers/intreq2.htm create mode 100755 sources/official/saga-registers/intreqr.htm create mode 100755 sources/official/saga-registers/joy0dat.htm create mode 100755 sources/official/saga-registers/joybuttons.htm create mode 100755 sources/official/saga-registers/joytest.htm create mode 100755 sources/official/saga-registers/mousewheel.htm create mode 100755 sources/official/saga-registers/pipcol.htm create mode 100755 sources/official/saga-registers/planarcol.htm create mode 100755 sources/official/saga-registers/pot0dat.htm create mode 100755 sources/official/saga-registers/potgo.htm create mode 100755 sources/official/saga-registers/potinp.htm create mode 100755 sources/official/saga-registers/refptr.htm create mode 100755 sources/official/saga-registers/saga.htm create mode 100755 sources/official/saga-registers/sagacontrol.htm create mode 100755 sources/official/saga-registers/screenadjust.htm create mode 100755 sources/official/saga-registers/serdat.htm create mode 100755 sources/official/saga-registers/serdatr.htm create mode 100755 sources/official/saga-registers/serper.htm create mode 100755 sources/official/saga-registers/shiftdown.htm create mode 100755 sources/official/saga-registers/spritecol.htm create mode 100755 sources/official/saga-registers/sprxctl.htm create mode 100755 sources/official/saga-registers/sprxdata.htm create mode 100755 sources/official/saga-registers/sprxpos.htm create mode 100755 sources/official/saga-registers/sprxpth.htm create mode 100755 sources/official/saga-registers/strequ.htm create mode 100755 sources/official/saga-registers/vampversion.htm create mode 100755 sources/official/saga-registers/vbstrt.htm create mode 100755 sources/official/saga-registers/vhposr.htm create mode 100755 sources/official/saga-registers/vposr.htm create mode 100755 sources/official/saga-registers/vsstrt.htm create mode 100755 sources/official/saga-registers/vtotal.htm create mode 100644 tools/intake/sagaregs.py diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e891121..25c51f6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -155,6 +155,18 @@ /core/saga-audio-arne/index.md @WDrijver /core/saga-audio-arne/registers.md @TuKo1982 /core/saga-dma-anni/index.md @WDrijver +/core/saga-registers/arne-channels.md @WDrijver +/core/saga-registers/arne-dma-and-interrupts.md @WDrijver +/core/saga-registers/chunky-plane.md @WDrijver +/core/saga-registers/colour-ports.md @WDrijver +/core/saga-registers/display-control.md @WDrijver +/core/saga-registers/index.md @WDrijver +/core/saga-registers/input.md @WDrijver +/core/saga-registers/maggie-3d.md @WDrijver +/core/saga-registers/pip.md @WDrijver +/core/saga-registers/pointer.md @WDrijver +/core/saga-registers/sprite-collision.md @WDrijver +/core/saga-registers/system.md @WDrijver /core/saga-video-isabelle/index.md @WDrijver /hardware/index.md @WDrijver /os/apolloos-and-amigaos-on-v4.md @WDrijver diff --git a/AGENTS.md b/AGENTS.md index 7d619ec..10e0939 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -85,10 +85,11 @@ you read. | Execution mode is `os-takeover` (games, demos) | `os/os-takeover.md`, `core/` | | Writing code at all | `conventions/`, `toolchain/` | | CPU-heavy or assembly code | `core/cpu-68080/`, `core/best-practices/`, `core/pitfalls/` | -| Graphics, screens, video modes | `core/saga-video-isabelle/` | -| Sound | `core/saga-audio-arne/` | +| Graphics, screens, video modes | `core/saga-video-isabelle/`, `core/saga-registers/` | +| Sound | `core/saga-audio-arne/`, `core/saga-registers/` | | Memory transfers, DMA | `core/saga-dma-anni/` | -| 3D | `core/saga-3d-maggie/` | +| SAGA input, board ID, other SAGA registers | `core/saga-registers/` | +| 3D | `core/saga-3d-maggie/`, `core/saga-registers/` | | Board connectors, headers, memory, model differences | `hardware/v4-generic/`, the model's folder in `hardware/` | | Using or changing an ApolloOS library | `os/libraries/` | | Device drivers | `os/devs/`, plus the `core/` or `hardware/` folder of the hardware involved | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 12130c7..9886028 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -78,6 +78,9 @@ Not content: `templates/` (file, repo and seed templates), `sources/` skills, step 2), `evals/` (AI benchmarks, step 5), `tools/` (CI scripts). Each chip folder keeps its register map in `registers.md` inside that folder. +The official SAGA register documentation is generated into +`core/saga-registers/` (document intake, section 11); the chip folders link +to it. `core/` is the FPGA core, the same on every V4 model. `hardware/` is the board: connectors, headers, memory and what differs per model. Knowledge that diff --git a/core/saga-3d-maggie/index.md b/core/saga-3d-maggie/index.md index 4f463fb..7357ed1 100644 --- a/core/saga-3d-maggie/index.md +++ b/core/saga-3d-maggie/index.md @@ -16,8 +16,9 @@ sources: Maggie, the SAGA 3D chip. -**This folder is only partly covered.** It has the span registers as -maggie.library uses them (`registers.md`) and the pitfalls in +**This folder is only partly covered.** It has the official register names +([core/saga-registers/maggie-3d.md](../saga-registers/maggie-3d.md)), the +span registers as maggie.library uses them (`registers.md`) and the pitfalls in `core/pitfalls/maggie-*.md`. For anything else, tell the user that the knowledge base does not cover it yet. Do not fill the gap with classic Amiga or 68060 knowledge. @@ -27,7 +28,8 @@ or 68060 knowledge. ### Planned files - `registers.md`: the span unit registers as maggie.library uses them, with - measured behaviour (exists; no official register documentation yet) + measured behaviour (exists; the official names are in + `core/saga-registers/maggie-3d.md`) - One file per feature, for example texture mapping - Using maggie.library: [os/libraries/maggie-library.md](../../os/libraries/maggie-library.md) diff --git a/core/saga-3d-maggie/registers.md b/core/saga-3d-maggie/registers.md index 3ec83e7..6ba3734 100644 --- a/core/saga-3d-maggie/registers.md +++ b/core/saga-3d-maggie/registers.md @@ -15,6 +15,7 @@ related: - core/pitfalls/maggie-depth-test-colour-write.md - core/pitfalls/maggie-span-tail.md - core/pitfalls/maggie-span-usage.md + - core/saga-registers/maggie-3d.md sources: - "TuKo1982, 68080 compilation and optimisation guide (2026-10-30), section 15.7" - "maggie.library source, github.com/RMortenB/MaggieLibrary, commit 64c78ef (2026-08-17)" diff --git a/core/saga-audio-arne/index.md b/core/saga-audio-arne/index.md index 1aa9555..7e4974e 100644 --- a/core/saga-audio-arne/index.md +++ b/core/saga-audio-arne/index.md @@ -16,17 +16,19 @@ sources: Arne, the SAGA audio chip. -**This folder is only partly covered.** `registers.md` has the registers and -values used in V4 audio driver work. For anything else, tell the user that -the knowledge base does not cover it yet. Do not fill the gap with classic -Amiga (Paula) or 68060 knowledge. +**This folder is only partly covered.** The official register map is in +[core/saga-registers/arne-channels.md](../saga-registers/arne-channels.md) +and [arne-dma-and-interrupts.md](../saga-registers/arne-dma-and-interrupts.md). +`registers.md` has the values measured in V4 audio driver work. For anything +else, tell the user that the knowledge base does not cover it yet. Do not +fill the gap with classic Amiga (Paula) or 68060 knowledge. ## Details ### Planned files -- `registers.md`: partial register reference (exists; the full map is still - missing) +- `registers.md`: values measured in driver work (exists); the official map + is in `core/saga-registers/` - One file per feature, for example channels or sample formats ### For contributors diff --git a/core/saga-audio-arne/registers.md b/core/saga-audio-arne/registers.md index ee83715..82e38a1 100644 --- a/core/saga-audio-arne/registers.md +++ b/core/saga-audio-arne/registers.md @@ -13,6 +13,7 @@ tags: [arne, audio, saga, registers, dma, interrupts] related: - core/saga-audio-arne/index.md - core/cpu-68080/core-at-a-glance.md + - core/saga-registers/arne-channels.md sources: - "TuKo1982, 68080 compilation and optimisation guide (2026-10-30), sections 1 and 13" --- @@ -33,7 +34,8 @@ is not documented here yet. | LEN | 32-bit count of **sample pairs** | | VOL | Left volume in bits 15–8, right volume in bits 7–0 | -The base addresses of the channel registers are not given in the source. +The channel base addresses are in the official register map: +[core/saga-registers/arne-channels.md](../saga-registers/arne-channels.md). ### Control and interrupt registers @@ -63,5 +65,5 @@ The base addresses of the channel registers are not given in the source. - DO keep the period at 65 or higher. - DO give LEN in sample pairs, not words. -- DON'T guess the remaining ARNE registers: the knowledge base does not - cover them yet. +- DON'T guess ARNE registers: use the official map in + `core/saga-registers/`. diff --git a/core/saga-registers/arne-channels.md b/core/saga-registers/arne-channels.md new file mode 100644 index 0000000..a7d102d --- /dev/null +++ b/core/saga-registers/arne-channels.md @@ -0,0 +1,92 @@ +--- +title: "SAGA Arne audio channel registers" +type: reference +owner: WDrijver +status: draft +origin: official +basis: [official, source-code] +components: [saga-audio-arne] +applies_to: + core: "Core 12000+" + os: [any] +tags: [saga, arne, audio, registers] +related: + - core/saga-registers/index.md + - core/saga-audio-arne/registers.md + - core/saga-registers/arne-dma-and-interrupts.md +sources: + - "SAGA register documentation, sources/official/saga-registers/ (HTML)" + - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)" + - "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04" +generated_from: sources/official/saga-registers/index.htm +--- + + + +## Summary + +Arne, the SAGA audio unit, has 16 channels of 8- or 16-bit mono or 16-bit stereo samples from any RAM, each with a 32-bit pointer and length at `$DFF400 + n × $10`. Channels 0–3 are the Paula channels. + +## Details + +### Channel layout + +16 channels, channel n at `$DFF400 + n × $10` (n = 0–15). The converter checks every row of the original against this layout. + +| Offset | Register | Size | Access | Meaning | +|---|---|---|---|---| +| +0 | AUDxL | L | W | Pointer to the sample data (32-bit, any RAM) | +| +4 | AUDxLEN | L | W | Length in sample pairs (32-bit) | +| +8 | AUDxVOL | W | W | Volume: bits 15–8 left, 7–0 right | +| +A | AUDxCTRL | W | W | Control (see below) | +| +C | AUDxPER | W | W | Period (16-bit) | + +- `$DFF430`: corrected: typo in the original: this is channel 3. +- `$DFF4A0`: corrected: typo in the original: the AUD10 block is at $DFF4A0, as the channel layout requires. +- `$DFF4CC`: corrected: typo in the original: AUD12PER is at $DFF4CC, as the channel layout requires. + +### Channels 0–3 and Paula + +Arne channels 0–3 are the four Paula channels: the same voices, with the classic registers at `$DFF0A0`–`$DFF0DF` and the Arne registers at `$DFF400`–`$DFF43F` (WDrijver, 2026-11-04). ApolloLib starts and stops channels 0–3 with DMACON bits 0–3 (`$DFF096`) and checks them in DMACONR (`$DFF002`); channels 4–15 use DMACON2 (SRC, see [arne-dma-and-interrupts.md](arne-dma-and-interrupts.md)). + +### AUDxCTRL + +| Bits | Function | Description | +|---|---|---| +| 2 | Stereo | 16bit/16bit interleaved mode - 64bit align | +| 1 | OneShot | Channel will turn itself off at sample end | +| 0 | 16bit | 0=8bit, 1=16bit samples | + +Sample formats (original): + +- 8bit signed mono. Data stored in pairs, data aligment 16bit +- 16bit signed mono, Data stored in pairs, data alignment 32bit +- Left/Rigth signed 16bit stereo, Data in memory in pairs, memory alignment 64bit + +ApolloLib writes `$0005` (16-bit stereo, looping) and `$0007` (16-bit stereo, one-shot) (SRC). The other bits are not described. + +### AUDxLEN + +The count is in pairs of samples (original). For 16-bit stereo, ApolloLib writes the size in bytes / 8: one count is two stereo frames of 2 × 16 bits (SRC). + +### AUDxVOL + +Bits 15–8 left volume, bits 7–0 right volume (original). Each side ranges from `$00` to `$FF` (ApolloLib, SRC). + +### AUDxPER + +16bit PERIOD COUNT This register contains the period (rate) of audio channel x DMA data transfer. The minimum period is 65 color clocks. This means that the smallest number that should be placed in this register is 65 decimal. This corresponds to a maximum sample frequency of 56 khz. + +With the PAL clock of 3546895 Hz (ApolloLib), period 65 gives 3546895 / 65 = 54.6 kHz, not the 56 kHz in the original. + +## Differences from AmigaOS / AROS / 68060 + +- Paula has 4 channels, 8-bit samples, 6-bit volume and Chip RAM only. Arne channels 0–3 are those same channels, with the extra registers at `$DFF400`. +- Classic AUDxLEN counts words; Arne AUDxLEN counts sample pairs and is 32 bits. + +## Do / Don't + +- DO keep the period at 65 or higher. +- DO give AUDxLEN in sample pairs. +- DO start channels 0–3 with DMACON and channels 4–15 with DMACON2. +- DON'T program channel 0–3 through both register sets at the same time. diff --git a/core/saga-registers/arne-dma-and-interrupts.md b/core/saga-registers/arne-dma-and-interrupts.md new file mode 100644 index 0000000..023c930 --- /dev/null +++ b/core/saga-registers/arne-dma-and-interrupts.md @@ -0,0 +1,100 @@ +--- +title: "SAGA DMACON2, INTENA2 and INTREQ2" +type: reference +owner: WDrijver +status: draft +origin: official +basis: [official] +components: [saga-audio-arne] +applies_to: + core: "Core 12000+" + os: [any] +tags: [saga, arne, audio, dma, interrupts, ethernet, registers] +related: + - core/saga-registers/index.md + - core/saga-registers/arne-channels.md +sources: + - "SAGA register documentation, sources/official/saga-registers/ (HTML)" +generated_from: sources/official/saga-registers/index.htm +--- + + + +## Summary + +DMACON2, INTENA2 and INTREQ2 control DMA and interrupts of Arne audio channels 4–15 and of the Ethernet. Bit n is channel n + 4; bit 13 is Ethernet. + +## Details + +### Registers + +| Address | Name | Access | Description (original) | +|---|---|---|---| +| `$DFF202` | DMACON2 Read | R | – | +| `$DFF21C` | INTENA2 Read | R | – | +| `$DFF21E` | INTREQ2 Read | R | – | +| `$DFF296` | DMACON2 | W | DMACON2 | +| `$DFF29A` | INTENA2 | W | INTENA2 | +| `$DFF29C` | INTREQ2 | W | INTREQ2 | + +- `$DFF21C`: corrected: upper case, as everywhere else. + +### DMACON2 + +| Bits | Function | Description | +|---|---|---| +| 15 | | SET/CLR | +| 14 | | | +| 13 | ETH | Ethernet | +| 12 | | | +| 11 | AUD15 | Audio channel 15 | +| 10 | AUD14 | Audio channel 14 | +| 9 | AUD13 | Audio channel 13 | +| 8 | AUD12 | Audio channel 12 | +| 7 | AUD11 | Audio channel 11 | +| 6 | AUD10 | Audio channel 10 | +| 5 | AUD9 | Audio channel 9 | +| 4 | AUD8 | Audio channel 8 | +| 3 | AUD7 | Audio channel 7 | +| 2 | AUD6 | Audio channel 6 | +| 1 | AUD5 | Audio channel 5 | +| 0 | AUD4 | Audio channel 4 | + +### INTENA2 and INTREQ2 + +Both use the same bits. INTREQ2 needs a set and a clear write to load arbitrary data, as INTREQ (original). + +| Bits | Function | Description | +|---|---|---| +| 15 | | SET/CLR | +| 14 | | | +| 13 | ETH | Ethernet | +| 12 | | | +| 11 | AUD15 | Audio channel 15 block finished | +| 10 | AUD14 | Audio channel 14 block finished | +| 9 | AUD13 | Audio channel 13 block finished | +| 8 | AUD12 | Audio channel 12 block finished | +| 7 | AUD11 | Audio channel 11 block finished | +| 6 | AUD10 | Audio channel 10 block finished | +| 5 | AUD9 | Audio channel 9 block finished | +| 4 | AUD8 | Audio channel 8 block finished | +| 3 | AUD7 | Audio channel 7 block finished | +| 2 | AUD6 | Audio channel 6 block finished | +| 1 | AUD5 | Audio channel 5 block finished | +| 0 | AUD4 | Audio channel 4 block finished | + +The original adds: + +- "Ethernet will throw IRQ $48" +- "The new Audio channels will throw IRQ $50" + +Whether `$48` and `$50` are vector offsets or vector numbers, and at which interrupt level they arrive, is an open question (see [index.md](index.md)). + +## Differences from AmigaOS / AROS / 68060 + +- Classic DMACON/INTENA/INTREQ cover audio channels 0–3 only. Channels 0–3 stay there on SAGA; the second set adds 4–15 and Ethernet. + +## Do / Don't + +- DO use bit 15 as SET/CLR, as in the classic registers. +- DO map channel n (4–15) to bit n − 4. diff --git a/core/saga-registers/chunky-plane.md b/core/saga-registers/chunky-plane.md new file mode 100644 index 0000000..df02851 --- /dev/null +++ b/core/saga-registers/chunky-plane.md @@ -0,0 +1,113 @@ +--- +title: "SAGA chunky plane: GFXMODE, pointer and modulo" +type: reference +owner: WDrijver +status: draft +origin: official +basis: [official, source-code] +components: [saga-video-isabelle] +applies_to: + core: "Core 12000+" + os: [any] +tags: [saga, isabelle, gfxmode, chunky, registers] +related: + - core/saga-registers/index.md +sources: + - "SAGA register documentation, sources/official/saga-registers/ (HTML)" + - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)" + - "maggie.library samples, see os/libraries/maggie-library.md" +generated_from: sources/official/saga-registers/index.htm +--- + + + +## Summary + +The SAGA chunky plane is a linear framebuffer in any RAM. GFXMODE (`$DFF1F4`) selects resolution and pixel format, BPLHPT (`$DFF1EC`) points to the pixels and BPLHMOD (`$DFF1E6`) sets the row modulo. + +## Details + +### Registers + +| Address | Name | Access | Description (original) | +|---|---|---|---| +| `$DFF1E6` | BPLHMOD | W | Chunky plane modulo | +| `$DFF1EC` | BPLHPTH | W | Chunky plane pointer (hi 16 bits) | +| `$DFF1EE` | BPLHPTL | W | Chunky plane pointer (lo 16 bits) | +| `$DFF1F4` | GFXMODE | W | Set Resolution and Pixformat | + +- `$DFF1EC`: corrected: the high word of a 32-bit pointer has 16 bits. +- `$DFF1EE`: corrected: the low word of a 32-bit pointer has 16 bits. + +### GFXMODE (`$DFF1F4`) + +16bit register selecting the screen size and the pixelformat for the Chunky plane. + +Bits 15–8 select the resolution, bits 7–0 the pixel format. Write it as one word: `(resolution << 8) | format`. + +#### Resolution (bits 15–8) + +| Value | Resolution | Refresh | Pixel clock | Pixel doubling | +|---|---|---|---|---| +| `$01` | 320x200 | 60Hz | 28MHz | 2x2 | +| `$02` | 320x240 | 60Hz | 28MHz | 2x2 | +| `$03` | 320x256 | 60Hz | 28MHz | 2x2 | +| `$04` | 640x400 | 60Hz | 28MHz | – | +| `$05` | 640x480 | 60Hz | 28MHz | – | +| `$06` | 640x512 | 50Hz | 28MHz | – | +| `$07` | 960x540 | 60Hz | 42MHz | – | +| `$08` | 480x270 | 60Hz | 42MHz | 2x2 | +| `$09` | 304x224 | 60Hz | 28MHz | 2x2 | +| `$0A` | 1280x720 | 50Hz | 85MHz | – | +| `$0B` | 640x360 | 50Hz | 85MHz | 2x2 | +| `$0C` | 800x600 | 60Hz | 42MHz | – | +| `$0D` | 1024x768 | 60Hz | 85MHz | – | +| `$0E` | 720x576 | 50Hz | 28MHz | – | +| `$0F` | 848x480 | 60Hz | 42MHz | – | +| `$10` | 640x200 | 60Hz | 28MHz | – | +| `$11` | 1920x1080 | 24Hz | 85MHz | – | +| `$12` | 1280x1024 | 50Hz | 85MHz | – | +| `$13` | 1280x800 | 60Hz | 84MHz | – | +| `$14` | 1440x900 | 50Hz | 85MHz | – | +| `$15` | 720x405 | 50Hz | 28MHz | – | + +`$00` has no description in the original. The original writes 84 MHz for `$13` and 85 MHz for the other high-resolution modes. + +#### Pixel format (bits 7–0) + +| Value | Format | +|---|---| +| `$01` | 8bit CHUNKY (indexed) | +| `$02` | 16bit R5G6B5 | +| `$03` | 15bit 1R5G5B5 | +| `$04` | 24bit R8G8B8 | +| `$05` | 32bit A8R8G8B8 | +| `$06` | YUV888 | +| `$0E` | YUV444 | +| `$07` | (empty in the original) | +| `$08` | PLANAR 1BIT ATARI | +| `$09` | PLANAR 2BIT ATARI | +| `$0A` | PLANAR 4BIT ATARI | +| `$0B` | PLANAR 8BIT ATARI | + +Values `$08`–`$0B` are Atari planar formats (ApolloLib names them APOLLO_ATARI_1BIT to _8BIT) (SRC). + +### Chunky plane pointer and modulo + +- BPLHPTH/BPLHPTL (`$DFF1EC`): 32bit pointer to Chunky plane. The Chunky plane can show 8bit/16Bit/15bit/24bit/32bit screens. +- BPLHMOD (`$DFF1E6`): This is the number (sign extended) that is added to the UHRES bitplane pointer (BPLHPTL,H) every line, just like the other modulos. The original's text says "UHRES bitplane pointer"; on SAGA it is the chunky plane: the number of bytes skipped after each row (ApolloLib, SRC). + +### Reading the current mode back + +The original gives no read address. maggie.library's samples save the current mode and frame pointer from `$DFE1F4` and `$DFE1EC` (SRC, see [maggie-library.md](../../os/libraries/maggie-library.md)). Whether every SAGA register reads back at `$DFExxx` is an open question (see [index.md](index.md)). + +## Differences from AmigaOS / AROS / 68060 + +- Classic Amiga chipsets have only planar bitplanes in Chip RAM. The chunky plane has 8- to 32-bit pixels and can be in Fast RAM. +- On ECS, `$DFF1E6`/`$DFF1EC` were BPLHMOD/BPLHPT for UHRES bitplanes; SAGA reuses the names for the chunky plane. + +## Do / Don't + +- DO write GFXMODE as one word, resolution in the high byte. +- DO set the pointer and modulo before you switch the mode. +- DON'T rely on GFXMODE `$00` or pixel format `$07`: the original describes neither. diff --git a/core/saga-registers/colour-ports.md b/core/saga-registers/colour-ports.md new file mode 100644 index 0000000..fe4e324 --- /dev/null +++ b/core/saga-registers/colour-ports.md @@ -0,0 +1,75 @@ +--- +title: "SAGA colour ports (24-bit palettes)" +type: reference +owner: WDrijver +status: draft +origin: official +basis: [official, source-code] +components: [saga-video-isabelle] +applies_to: + core: "Core 12000+" + os: [any] +tags: [saga, isabelle, palette, colour, registers] +related: + - core/saga-registers/index.md +sources: + - "SAGA register documentation, sources/official/saga-registers/ (HTML)" + - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)" +generated_from: sources/official/saga-registers/index.htm +--- + + + +## Summary + +SAGA sets 24-bit palette entries through 32-bit colour ports: one write gives the entry number and its red, green and blue. There is one port each for the planar, sprite, chunky and PIP palettes. + +## Details + +### Registers + +| Address | Name | Access | Description (original) | +|---|---|---|---| +| `$DFF380` | PlanarCOLH | W | 32bit Planar COLOR Port register | +| `$DFF382` | PlanarCOLL | W | 256 Color Register, Format [ID,RR,GG,BB] | +| `$DFF384` | SpriteCOLH | W | 32bit Sprite COLOR Port register | +| `$DFF386` | SpriteCOLL | W | 256 Color Register, Format [ID,RR,GG,BB] | +| `$DFF388` | ChunkyCOLH | W | 32bit Chunky COLOR Port register | +| `$DFF38A` | ChunkyCOLL | W | 256 Color Register, Format [ID,RR,GG,BB] | +| `$DFF38C` | PIPCOLH | W | 32bit PIP COLOR Port register | +| `$DFF38E` | PIPCOLL | W | 256 Color Register, Format [ID,RR,GG,BB] | + +Each port is one 32-bit register (the original lists its high and low word, H and L). A 32-bit write sets one entry of a 256-colour table: + +| Bits | Function | Description | +|---|---|---| +| 31–24 | Number | 8bit Colornumber | +| 23–16 | RED | 8bit Red | +| 15–8 | GREEN | 8bit Green | +| 7–0 | BLUE | 8bit Blue | + +| Port | Address | Table | +|---|---|---| +| Planar | `$DFF380` | Bitplane colours (256) | +| Sprite | `$DFF384` | Sprite colours (256) | +| Chunky | `$DFF388` | Chunky plane in 8-bit mode (256) | +| PIP 1 | `$DFF38C` | PIP 1 in 8-bit mode (256) | +| PIP 2 | `$DFF37C` | PIP 2 in 8-bit mode (256) (SRC, not in the original) | + +### Example (original) + +```asm + move.l #$00FF0000,$DFF380 ; colour 0 = red + move.l #$01FFFF00,$DFF380 ; colour 1 = yellow +``` + +The original also shows a Copper form, `dc.w $8380,$00FF,$0000` ("set color0 = RED"). This is three words, while a classic Copper MOVE has two. How the SAGA Copper encodes a 32-bit MOVE is an open question (see [index.md](index.md)); don't use the form until it is documented. + +## Differences from AmigaOS / AROS / 68060 + +- Classic COLORxx registers (`$DFF180`–`$DFF1BE`) hold 32 entries; AGA reaches 256 through banks and BPLCON3. A SAGA port writes any of 256 entries in one 32-bit write. + +## Do / Don't + +- DO write the port with one `move.l`. +- DON'T use the three-word Copper form from the original yet. diff --git a/core/saga-registers/display-control.md b/core/saga-registers/display-control.md new file mode 100644 index 0000000..a60f5c9 --- /dev/null +++ b/core/saga-registers/display-control.md @@ -0,0 +1,91 @@ +--- +title: "SAGA display control, screen shift and screen mode adjust" +type: reference +owner: WDrijver +status: draft +origin: official +basis: [official] +components: [saga-video-isabelle] +applies_to: + core: "Core 12000+" + os: [any] +tags: [saga, isabelle, scanlines, zoom, registers] +related: + - core/saga-registers/index.md +sources: + - "SAGA register documentation, sources/official/saga-registers/ (HTML)" +generated_from: sources/official/saga-registers/index.htm +--- + + + +## Summary + +SAGA CONTROL (`$DFF3EC`) switches scanlines, zoom and a forced OCS mode; SCREEN SHIFT (`$DFF3EE`) and SCREENMODE ADJUST (`$DFF390`) move and enlarge the SAGA screen modes. + +## Details + +### Registers + +| Address | Name | Access | Description (original) | +|---|---|---|---| +| `$DFF390`, `$DFF392` | SCREENMODE ADJUST | W | Adjust Y/X for Screenmodes | +| `$DFF3EC` | SAGA CONTROL REG | W | Reserved | +| `$DFF3EE` | SCREEN SHIFT | R | Reserved | + +- `$DFF3EC`: corrected: $DFF3EC is writable (WDrijver, 2026-11-04). + +### SAGA CONTROL (`$DFF3EC`, write) + +Bit 15 is SET/CLR, as in DMACON: bits written as 1 are set when bit 15 is 1, and cleared when it is 0. + +| Bits | Function | Description | +|---|---|---| +| 15 | SET/CLR | | +| 6 | FORCE OCS MODE | | +| 5 | Enable PAL ZOOM | | +| 4 | -- | | +| 3 | -- | | +| 2 | Enable Zoom | | +| 1 | Scanline Mode | | +| 0 | Scanlines On/Off | | + +Examples from the original (`apoke address size value`): + +```text +No Zoom = apoke $DFF3EC 2 $0024 +ZOOM1 (NTSC) = apoke $DFF3EC 2 $8004 +ZOOM2 (NTSC+) = apoke $DFF3EC 2 $8020 +ZOOM3 (PAL) = apoke $DFF3EC 2 $8024 +``` + +### SCREEN SHIFT (`$DFF3EE`) + +The original's page has the title "SAGA CONTROL Register"; its content is the screen shift: + +| Bits | Function | Description | +|---|---|---| +| 15–8 | Y shift | | +| 7–0 | X shift | | + +The original marks it R. Whether it is also writable is an open question. + +### SCREENMODE ADJUST (`$DFF390`) + +| Bits | Function | Description | +|---|---|---| +| 31–24 | Number | 8bit Screenmode-ID | +| 23–16 | -- | 8bit 00 reserved | +| 15–8 | -Y | 8bit 0Y more rows | +| 7–0 | -X | 8bit 0X more widthX | + +The original's example on this page is the one of the planar colour port (it sets colour 0 to red) and is left out. + +## Differences from AmigaOS / AROS / 68060 + +- Classic Amiga chipsets have none of these registers: scanlines and zoom are features of the SAGA video output. + +## Do / Don't + +- DO set bit 15 to set bits and clear it to clear them. +- DON'T treat `$DFF3EC` as read-only: the original's Access column is wrong there. diff --git a/core/saga-registers/index.md b/core/saga-registers/index.md new file mode 100644 index 0000000..c06048a --- /dev/null +++ b/core/saga-registers/index.md @@ -0,0 +1,185 @@ +--- +title: "SAGA registers (SAGA-specific)" +type: reference +owner: WDrijver +status: draft +origin: official +basis: [official, source-code] +components: [saga-video-isabelle, saga-audio-arne, saga-3d-maggie, general] +applies_to: + core: "Core 12000+" + os: [any] +tags: [saga, registers, index] +sources: + - "SAGA register documentation, sources/official/saga-registers/ (HTML)" + - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)" + - "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04" +generated_from: sources/official/saga-registers/index.htm +--- + + + +## Summary + +The SAGA-specific chipset registers of the Apollo V4, converted from the official SAGA register documentation: video (chunky plane, colour ports, PIP, pointer), Arne audio, Maggie 3D, input and system registers. Classic OCS/ECS/AGA registers are not repeated here. + +## Details + +### About the original + +- Original: [`sources/official/saga-registers/`](../../sources/official/saga-registers/), an HTML register table (`index.htm`) with one page per register. It is leading; these files are generated from it by `tools/intake/sagaregs.py`. +- Valid for Core 12000+ (WDrijver, 2026-11-04). +- `index.htm` is the current table. `saga.htm` is an older table with another audio and sprite layout; it is not used. +- The Atari section of `index.htm` is skipped. + +### Scope: SAGA-specific registers only + +Every one of the 419 rows of the original is marked SAGA, because SAGA contains the classic chipset. These files cover the 188 SAGA-specific rows: the rows where OCS, ECS and AGA are empty, plus the SAGA addresses that the original also marks as classic. + +For every other register, the Amiga Hardware Reference Manual applies, with one difference: **on SAGA, all classic pointer registers (BPLxPT, SPRxPT, COPxLC, BLTxPT, AUDxLC, DSKPT) are 32 bits wide and reach all RAM** (WDrijver, 2026-11-04). Their pages in the original still say 18 bits. FMODE (`$DFF1FC`) bit 4 "SAGA" enables the SAGA features (original). + +### Access codes (original) + +| Code | Meaning | +|---|---| +| R | read | +| W | write | +| S | strobe (a write of any value triggers the action) | +| ER | early read | + +### Files + +| Topic | File | +|---|---| +| Chunky plane: GFXMODE, pointer, modulo | [chunky-plane.md](chunky-plane.md) | +| 24-bit colour ports | [colour-ports.md](colour-ports.md) | +| Picture in picture (PIP 1 and 2) | [pip.md](pip.md) | +| Hardware sprite pointer | [pointer.md](pointer.md) | +| SAGA control, screen shift, screen mode adjust | [display-control.md](display-control.md) | +| Detailed sprite collision | [sprite-collision.md](sprite-collision.md) | +| Arne audio channels | [arne-channels.md](arne-channels.md) | +| DMACON2, INTENA2, INTREQ2 | [arne-dma-and-interrupts.md](arne-dma-and-interrupts.md) | +| Maggie 3D registers | [maggie-3d.md](maggie-3d.md) | +| USB joypads, mouse wheel, DB9 | [input.md](input.md) | +| Board ID, core revision, chip ID, SPI | [system.md](system.md) | + +### Register map + +| Address | Name | Access | File | +|---|---|---|---| +| `$DFF1E6` | BPLHMOD | W | [chunky-plane.md](chunky-plane.md) | +| `$DFF1EC` | BPLHPTH | W | [chunky-plane.md](chunky-plane.md) | +| `$DFF1EE` | BPLHPTL | W | [chunky-plane.md](chunky-plane.md) | +| `$DFF1F4` | GFXMODE | W | [chunky-plane.md](chunky-plane.md) | +| `$DFF380` | PlanarCOLH | W | [colour-ports.md](colour-ports.md) | +| `$DFF382` | PlanarCOLL | W | [colour-ports.md](colour-ports.md) | +| `$DFF384` | SpriteCOLH | W | [colour-ports.md](colour-ports.md) | +| `$DFF386` | SpriteCOLL | W | [colour-ports.md](colour-ports.md) | +| `$DFF388` | ChunkyCOLH | W | [colour-ports.md](colour-ports.md) | +| `$DFF38A` | ChunkyCOLL | W | [colour-ports.md](colour-ports.md) | +| `$DFF38C` | PIPCOLH | W | [colour-ports.md](colour-ports.md) | +| `$DFF38E` | PIPCOLL | W | [colour-ports.md](colour-ports.md) | +| `$DFF3D0` | PipXStrt | W | [pip.md](pip.md) | +| `$DFF3D2` | PipYStrt | W | [pip.md](pip.md) | +| `$DFF3D4` | PipXStop | W | [pip.md](pip.md) | +| `$DFF3D6` | PipYStop | W | [pip.md](pip.md) | +| `$DFF3D8` | PipPtr | W | [pip.md](pip.md) | +| `$DFF3DC` | PipFormat | W | [pip.md](pip.md) | +| `$DFF3DE` | PipModulo | W | [pip.md](pip.md) | +| `$DFF3E0` | PipColorKey | W | [pip.md](pip.md) | +| `$DFF3E2` | PipDMARowLen | W | [pip.md](pip.md) | +| `$DFF1D0` | SPRHSTRT | W | [pointer.md](pointer.md) | +| `$DFF1D2` | SPRHSTOP | W | [pointer.md](pointer.md) | +| `$DFF3A2` | Sprite Col1 | W | [pointer.md](pointer.md) | +| `$DFF3A4` | Sprite Col2 | W | [pointer.md](pointer.md) | +| `$DFF3A6` | Sprite Col3 | W | [pointer.md](pointer.md) | +| `$DFF390/92` | SCREENMODE ADJUST | W | [display-control.md](display-control.md) | +| `$DFF3EC` | SAGA CONTROL REG | W | [display-control.md](display-control.md) | +| `$DFF3EE` | SCREEN SHIFT | R | [display-control.md](display-control.md) | +| `$DFF230` | clxdat0 | R | [sprite-collision.md](sprite-collision.md) | +| `$DFF232` | clxdat1 | R | [sprite-collision.md](sprite-collision.md) | +| `$DFF234` | clxdat2 | R | [sprite-collision.md](sprite-collision.md) | +| `$DFF236` | clxdat3 | R | [sprite-collision.md](sprite-collision.md) | +| `$DFF238` | clxdat4 | R | [sprite-collision.md](sprite-collision.md) | +| `$DFF23A` | clxdat5 | R | [sprite-collision.md](sprite-collision.md) | +| `$DFF23C` | clxdat6 | R | [sprite-collision.md](sprite-collision.md) | +| `$DFF23E` | clxdat7 | R | [sprite-collision.md](sprite-collision.md) | +| `$DFF400`–`$DFF4FF` | AUD0–AUD15: L, LEN, VOL, CTRL, PER (112 rows) | W | [arne-channels.md](arne-channels.md) | +| `$DFF202` | DMACON2 Read | R | [arne-dma-and-interrupts.md](arne-dma-and-interrupts.md) | +| `$DFF21C` | INTENA2 Read | R | [arne-dma-and-interrupts.md](arne-dma-and-interrupts.md) | +| `$DFF21E` | INTREQ2 Read | R | [arne-dma-and-interrupts.md](arne-dma-and-interrupts.md) | +| `$DFF296` | DMACON2 | W | [arne-dma-and-interrupts.md](arne-dma-and-interrupts.md) | +| `$DFF29A` | INTENA2 | W | [arne-dma-and-interrupts.md](arne-dma-and-interrupts.md) | +| `$DFF29C` | INTREQ2 | W | [arne-dma-and-interrupts.md](arne-dma-and-interrupts.md) | +| `$DFF250` | TEXTPT | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF254` | TEXDPT | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF258` | TEXZPT | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF25E` | TEXSTRT | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF260` | TEXMIP | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF262` | TEXMODE | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF266` | TEXDMOD | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF268` | TEXddUUuuuu | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF26C` | TEXddVVvvvv | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF270` | TEXUUuuuu | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF274` | TEXVVvvvv | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF278` | TEXdUUuuuu | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF27C` | TEXdVVvvvv | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF280` | TEXLight | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF282` | TEXdLight | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF284` | TEXLightcolor | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF288` | TEXZZzz | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF28C` | TEXdZZzz | W | [maggie-3d.md](maggie-3d.md) | +| `$DFF20A` | JOY0DAT | R | [input.md](input.md) | +| `$DFF20C` | JOY1DAT | R | [input.md](input.md) | +| `$DFF212` | Mouse Wheel | R | [input.md](input.md) | +| `$DFF220` | joy0buttons | R | [input.md](input.md) | +| `$DFF222` | joy1buttons | R | [input.md](input.md) | +| `$DFF224` | joy2buttons | R | [input.md](input.md) | +| `$DFF226` | joy3buttons | R | [input.md](input.md) | +| `$DFF3EA` | CORE REVISION | R | [system.md](system.md) | +| `$DFF3F0` | CHIP ID | R | [system.md](system.md) | +| `$DFF3F2` | CHIP ID | R | [system.md](system.md) | +| `$DFF3F4` | CHIP ID | R | [system.md](system.md) | +| `$DFF3F6` | CHIP ID | R | [system.md](system.md) | +| `$DFF3F8` | SPI WRITE | R | [system.md](system.md) | +| `$DFF3FA` | SPI read | R | [system.md](system.md) | +| `$DFF3FC` | VAMPIRE VERSION | R | [system.md](system.md) | + +Not in the original, added from ApolloLib (SRC): PIP 2 at `$DFF3B0`–`$DFF3C2` and its colour port `$DFF37C` ([pip.md](pip.md)); the pointer sprite at `$DFD000`, `$DFF3A8` and `$DFF3AA` ([pointer.md](pointer.md)). + +### Corrections to the original + +Applied by the converter; the original should be fixed the same way. + +| Address | Field | Original | Corrected | Why | +|---|---|---|---|---| +| `$DFFAA0` | addr | DFFAA0 | DFF4A0 | typo in the original: the AUD10 block is at $DFF4A0, as the channel layout requires | +| `$DFF4C4C` | addr | DFF4C4C | DFF4CC | typo in the original: AUD12PER is at $DFF4CC, as the channel layout requires | +| `$DFF21c` | addr | DFF21c | DFF21C | upper case, as everywhere else | +| `$DFF430` | desc | Audio channel 1 location (32bit PTR) | Audio channel 3 location (32bit PTR) | typo in the original: this is channel 3 | +| `$DFF1EC` | desc | Chunky plane pointer (hi 15 bits) | Chunky plane pointer (hi 16 bits) | the high word of a 32-bit pointer has 16 bits | +| `$DFF3EC` | access | R | W | $DFF3EC is writable (WDrijver, 2026-11-04) | +| `$DFF1EE` | desc | Chunky plane pointer (lo 15 bits) | Chunky plane pointer (lo 16 bits) | the low word of a 32-bit pointer has 16 bits | +| `$DFF20C` | desc | Vaniall DB9 Joystick-mouse 1 data (vert, horiz) | Vanilla DB9 Joystick-mouse 1 data (vert, horiz) | typo in the original | + +Wrong or missing page links in the original: the 32-bit Arne rows link to the classic Paula pages (`audxlch.htm`, `audxvol.htm`, `audxdat.htm`), the PIP rows to a page that doesn't exist. The converter uses `audxl.htm`, `audxlen.htm`, `audnvol.htm`, `audxctrl.htm` and `audxper.htm` for Arne. + +### Open questions + +1. The Copper form `dc.w $8380,$00FF,$0000` in the colour port pages: how the SAGA Copper encodes a 32-bit MOVE and which SAGA registers it reaches. +2. "IRQ $48" (Ethernet) and "IRQ $50" (Arne channels 4–15): vector offsets or vector numbers, and at which interrupt level. +3. Read-back at `$DFExxx`: known for `$DFE1D0`/`$DFE1D2` (pointer) and `$DFE1F4`/`$DFE1EC` (mode, frame pointer). Does every write register read back there? +4. SCREEN SHIFT (`$DFF3EE`): read only, as the original says, or also writable? +5. Pointer: which cores have the 16x16 planar pointer (`$DFF800`, colours `$DFF3A0`–`$DFF3A6`) next to, or instead of, the 32x32 sprite at `$DFD000`? +6. PIP format: the original lists YUV, ApolloLib supports only `$01`–`$03`. +7. Sprites 8–15: the collision bits name them; the original documents 8 sprites. + +## Differences from AmigaOS / AROS / 68060 + +- SAGA contains the classic chipset at its classic addresses. The registers here are added on top of it, mostly at `$DFF1E6`–`$DFF1F4`, `$DFF200`–`$DFF29F` and `$DFF380`–`$DFF4FF`. +- Classic pointers are 18 (OCS) or 21 (ECS/AGA) bits; on SAGA they are 32 bits. + +## Do / Don't + +- DO look up a classic register in the HRM, and its SAGA-specific registers here. +- DON'T use a register listed under the open questions without checking it on real hardware. diff --git a/core/saga-registers/input.md b/core/saga-registers/input.md new file mode 100644 index 0000000..81abf56 --- /dev/null +++ b/core/saga-registers/input.md @@ -0,0 +1,97 @@ +--- +title: "SAGA input registers: USB joypads, mouse wheel, DB9" +type: reference +owner: WDrijver +status: draft +origin: official +basis: [official, source-code] +components: [general] +applies_to: + core: "Core 12000+" + os: [any] +tags: [saga, input, joypad, usb, mouse, registers] +related: + - core/saga-registers/index.md +sources: + - "SAGA register documentation, sources/official/saga-registers/ (HTML)" + - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)" +generated_from: sources/official/saga-registers/index.htm +--- + + + +## Summary + +SAGA reads USB joypads (`$DFF220`–`$DFF226`) and the USB mouse wheel (`$DFF212`) through registers, and adds the DB9 ports at `$DFF20A`/`$DFF20C`. + +## Details + +### Registers + +| Address | Name | Access | Description (original) | +|---|---|---|---| +| `$DFF20A` | JOY0DAT | R | Vanilla DB9 Joystick-mouse 0 data (vert, horiz) | +| `$DFF20C` | JOY1DAT | R | Vanilla DB9 Joystick-mouse 1 data (vert, horiz) | +| `$DFF212` | Mouse Wheel | R | Mouse Wheel read register | +| `$DFF220` | joy0buttons | R | 16bit USB Joy Buttons (0)=active | +| `$DFF222` | joy1buttons | R | 16bit USB Joy Buttons (0)=active | +| `$DFF224` | joy2buttons | R | 16bit USB Joy Buttons (0)=active | +| `$DFF226` | joy3buttons | R | 16bit USB Joy Buttons (0)=active | + +- `$DFF20A`: a SAGA address; the original also marks OCS, ECS and AGA. +- `$DFF20C`: corrected: typo in the original. +- `$DFF20C`: a SAGA address; the original also marks OCS, ECS and AGA. + +### USB joypads (`$DFF220`–`$DFF226`) + +One register per joypad. The index describes them as "16bit USB Joy Buttons (0)=active"; ApolloLib reads a set bit as pressed and bit 0 as connected (SRC). ApolloLib's names are in the last column. + +| Bits | Function | Description | ApolloLib | +|---|---|---|---| +| 15 | Right | Move RIGHT | | +| 14 | Left | Move Left | | +| 13 | Down | Move Down | | +| 12 | Up | Move Up | | +| 11 | Reserved | | | +| 10 | Start | Start | | +| 09 | Back | Back | | +| 08 | FIRE8 | Firebutton 8 | TR | +| 07 | FIRE7 | Firebutton 7 | TL | +| 06 | FIRE6 | Firebutton 6 | BR | +| 05 | FIRE5 | Firebutton 5 | BL | +| 04 | FIRE4 | Firebutton 4 | Y | +| 03 | FIRE3 | Firebutton 3 | X | +| 02 | FIRE2 | Firebutton 2 | B | +| 01 | FIRE1 | Firebutton 1 | A | +| 00 | PLUG | Joypad connected | Connected | + +ApolloLib also reads bits 2/3 as right stick X and bits 1/4 as right stick Y (SRC). + +### Mouse wheel (`$DFF212`) + +| Bits | Use | +|---|---| +| 15–10 | unused | +| 9 | Mouse Button 5 | +| 8 | Mouse Button 4 | +| 7–0 | signed 8 bit counter counts USB mouse Wheel events | + +### DB9 joysticks (`$DFF20A`, `$DFF20C`) + +The "vanilla" DB9 ports, with the layout of JOY0DAT/JOY1DAT. The original's index marks them OCS, ECS and AGA too, but these addresses are SAGA's. + +### Extra fire buttons in POTGO (classic register) + +- Bit 14 = Firebutton 2 Joy2 +- Bit 12 = Firebutton 3 Joy2 +- Bit 10 = Firebutton 2 +- Bit 8 = Firebutton 3 + +## Differences from AmigaOS / AROS / 68060 + +- Classic Amiga input is JOYxDAT, POTGO/POTINP and CIA bits, without USB, wheel or more than 3 buttons. + +## Do / Don't + +- DO test bit 0 (connected) before you trust a joypad register. +- DO treat the wheel counter as signed and use the difference between two reads. diff --git a/core/saga-registers/maggie-3d.md b/core/saga-registers/maggie-3d.md new file mode 100644 index 0000000..fd47afa --- /dev/null +++ b/core/saga-registers/maggie-3d.md @@ -0,0 +1,82 @@ +--- +title: "SAGA Maggie 3D registers (official names)" +type: reference +owner: WDrijver +status: draft +origin: official +basis: [official] +components: [saga-3d-maggie] +applies_to: + core: "Core 12000+" + os: [any] +tags: [saga, maggie, 3d, texture, registers] +related: + - core/saga-registers/index.md + - core/saga-3d-maggie/registers.md +sources: + - "SAGA register documentation, sources/official/saga-registers/ (HTML)" +generated_from: sources/official/saga-registers/index.htm +--- + + + +## Summary + +Maggie, the SAGA texture-mapping unit, is programmed through registers at `$DFF250`–`$DFF28F`. This file gives the official names; the measured behaviour is in core/saga-3d-maggie/registers.md. + +## Details + +### Registers + +| Address | Name | Access | Description (original) | +|---|---|---|---| +| `$DFF250` | TEXTPT | W | 3D 32bit texture source | +| `$DFF254` | TEXDPT | W | 3D 32bit Destination Screen Addr | +| `$DFF258` | TEXZPT | W | 3D ZBuffer Addr | +| `$DFF25E` | TEXSTRT | W | 3D 16bit LEN and START Bit15=0 = Start new job Bit15=1 = Continue previous job Bit10..0 = length in pixel | +| `$DFF260` | TEXMIP | W | 3D 16bit MIP texture size bit(3..0) ($A=1024/9=512/8=256/7=128/6=64/5=32) Bit4='1' = AutoMipMapMode with Bit3-0 define max mip | +| `$DFF262` | TEXMODE | W | 3D 16bit MODE (Bit0=use Bilienar) (Bit1=use Zbuffer) (Bit2=select 16bit output) (Bit3=inhibit Zbuffer write) (Bit4=select 24bit output) (Bit5=quadratic-mode) (Bit7-6= BLENDMode "00" =COPY) (Bit7-6= BLENDMode "01" =ADD) (Bit7-6= BLENDMode "10" =MUL) | +| `$DFF266` | TEXDMOD | W | 3D 16bit signed Destination Step | +| `$DFF268` | TEXddUUuuuu | W | 3D 24bit ddUUuuuu (quadratic) | +| `$DFF26C` | TEXddVVvvvv | W | 3D 24bit ddVVvvvv (quadratic) | +| `$DFF270` | TEXUUuuuu | W | 3D 24bit UUuuuu | +| `$DFF274` | TEXVVvvvv | W | 3D 24bit VVvvvv | +| `$DFF278` | TEXdUUuuuu | W | 3D 24bit dUUuuuu | +| `$DFF27C` | TEXdVVvvvv | W | 3D 24bit dVVvvvv | +| `$DFF280` | TEXLight | W | 3D 16bit Light Ll | +| `$DFF282` | TEXdLight | W | 3D 16bit Light dLl | +| `$DFF284` | TEXLightcolor | W | 3D 32bit Light color | +| `$DFF288` | TEXZZzz | W | 3D 32bit ZZZZzzzz | +| `$DFF28C` | TEXdZZzz | W | 3D 32bit Delta ZZZZzzzz | + +Offsets from `$DFF250`, for comparison with the measured layout in [registers.md](../saga-3d-maggie/registers.md): + +| Offset | Name (original) | +|---|---| +| 0 | TEXTPT | +| 4 | TEXDPT | +| 8 | TEXZPT | +| 14 | TEXSTRT | +| 16 | TEXMIP | +| 18 | TEXMODE | +| 22 | TEXDMOD | +| 24 | TEXddUUuuuu | +| 28 | TEXddVVvvvv | +| 32 | TEXUUuuuu | +| 36 | TEXVVvvvv | +| 40 | TEXdUUuuuu | +| 44 | TEXdVVvvvv | +| 48 | TEXLight | +| 50 | TEXdLight | +| 52 | TEXLightcolor | +| 56 | TEXZZzz | +| 60 | TEXdZZzz | + +## Differences from AmigaOS / AROS / 68060 + +- Classic Amiga chipsets have no texture-mapping unit. + +## Do / Don't + +- DO write TEXSTRT (`$DFF25E`) last: it starts the span. +- DO check core/saga-3d-maggie/registers.md and its pitfalls for the measured behaviour. diff --git a/core/saga-registers/pip.md b/core/saga-registers/pip.md new file mode 100644 index 0000000..6e12c1c --- /dev/null +++ b/core/saga-registers/pip.md @@ -0,0 +1,94 @@ +--- +title: "SAGA picture in picture (PIP 1 and PIP 2)" +type: reference +owner: WDrijver +status: draft +origin: official +basis: [official, source-code] +components: [saga-video-isabelle] +applies_to: + core: "Core 12000+" + os: [any] +tags: [saga, isabelle, pip, overlay, registers] +related: + - core/saga-registers/index.md + - core/saga-registers/colour-ports.md + - core/saga-registers/chunky-plane.md +sources: + - "SAGA register documentation, sources/official/saga-registers/ (HTML)" + - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)" + - "Example SAGAPiP.c, github.com/WDrijver/ApolloCrossDev Projects/SAGAPiP, commit 2dfaa5c (2026-09-02)" +generated_from: sources/official/saga-registers/index.htm +--- + + + +## Summary + +SAGA overlays up to two picture-in-picture windows (PIP) on the main screen, each with its own bitmap, format, position and colour key. The original documents PIP 1 only; PIP 2 and the register meanings come from ApolloLib. + +## Details + +### PIP 1 registers (original) + +| Address | Name | Access | Description (original) | +|---|---|---|---| +| `$DFF3D0` | PipXStrt | W | X start | +| `$DFF3D2` | PipYStrt | W | Y start | +| `$DFF3D4` | PipXStop | W | X stop | +| `$DFF3D6` | PipYStop | W | Y stop | +| `$DFF3D8` | PipPtr | W | 32 bit Ptr | +| `$DFF3DC` | PipFormat | W | Colorformat (8bit/16bit/15bit/YUV) | +| `$DFF3DE` | PipModulo | W | Modulo | +| `$DFF3E0` | PipColorKey | W | ColorKey 1000,RRRR,GGGG,BBBB | +| `$DFF3E2` | PipDMARowLen | W | PipDMARowLen | + +The original links these rows to a page that doesn't exist; the facts below come from ApolloLib and the SAGAPiP example (SRC). + +### PIP 2 registers (SRC, not in the original) + +PIP 2 has the same layout as PIP 1, `$20` lower (ApolloLib): + +| Address | Register | Same as PIP 1 | +|---|---|---| +| `$DFF3B0` | PIP2 X start | `$DFF3D0` | +| `$DFF3B2` | PIP2 Y start | `$DFF3D2` | +| `$DFF3B4` | PIP2 X stop | `$DFF3D4` | +| `$DFF3B6` | PIP2 Y stop | `$DFF3D6` | +| `$DFF3B8` | PIP2 pointer (32-bit) | `$DFF3D8` | +| `$DFF3BC` | PIP2 format | `$DFF3DC` | +| `$DFF3BE` | PIP2 modulo | `$DFF3DE` | +| `$DFF3C0` | PIP2 colour key | `$DFF3E0` | +| `$DFF3C2` | PIP2 DMA row length | `$DFF3E2` | + +Its colour port is `$DFF37C` (see [colour-ports.md](colour-ports.md)). The SAGAPiP example says two PIPs exist from Core 11900 (SRC). + +### Register meanings (SRC) + +| Register | Meaning | +|---|---| +| X/Y start, X/Y stop | Window position in screen pixels. The example writes X + 16 and Y − 1 to place the PIP exactly over a window. | +| Pointer | 32-bit address of the PIP bitmap | +| Format | Bits 7–0: pixel format as in GFXMODE, only `$01` (8-bit), `$02` (R5G6B5) and `$03` (1R5G5B5). Bit 8: transparency on, key colour `$F81F` in 16-bit mode. | +| Modulo | Bytes skipped after each row | +| Colour key | Bit 15 = enable, bits 11–8 red, 7–4 green, 3–0 blue | +| DMA row length | Bytes fetched per row = width × bytes per pixel. **0 switches the PIP off.** | + +### Two modes (SAGAPiP example, SRC) + +- **Overlay:** colour key 0. The PIP is in front of the main screen; with format bit 8 set, pixels with `$F81F` are transparent. +- **Chroma key:** colour key with bit 15 set, for example `$8F0F` (purple). The PIP is behind the main screen and shows only where the main screen has the key colour. + +### Conflict with the original + +The original describes PipFormat as "Colorformat (8bit/16bit/15bit/YUV)". ApolloLib marks YUV and the 24- and 32-bit formats as not supported on PIP. Until this is settled, use only `$01`–`$03`. + +## Differences from AmigaOS / AROS / 68060 + +- Classic Amiga chipsets have no PIP. Dual playfield is the nearest classic feature, and it is limited to planar bitmaps in Chip RAM. + +## Do / Don't + +- DO set the DMA row length last: it switches the PIP on. +- DO write 0 to the DMA row length to switch a PIP off. +- DON'T use YUV, 24- or 32-bit formats for a PIP. diff --git a/core/saga-registers/pointer.md b/core/saga-registers/pointer.md new file mode 100644 index 0000000..2d8fd5b --- /dev/null +++ b/core/saga-registers/pointer.md @@ -0,0 +1,76 @@ +--- +title: "SAGA hardware sprite pointer" +type: reference +owner: WDrijver +status: draft +origin: official +basis: [official, source-code] +components: [saga-video-isabelle] +applies_to: + core: "Core 12000+" + os: [any] +tags: [saga, isabelle, pointer, sprite, registers] +related: + - core/saga-registers/index.md +sources: + - "SAGA register documentation, sources/official/saga-registers/ (HTML)" + - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)" + - "ApolloLib, older copy in ApolloClaude docs/toolchain/_ApolloLib (ApolloCrossDev_Defines.h), 2026-11-04" + - "Example ApolloPointer.c, github.com/WDrijver/ApolloCrossDev Projects/ApolloPointer, commit 2dfaa5c (2026-09-02)" +generated_from: sources/official/saga-registers/index.htm +--- + + + +## Summary + +SAGA has a hardware mouse pointer: a 32x32 sprite with a 256-colour palette and alpha, positioned through `$DFF1D0`/`$DFF1D2`. The original documents only the position and three 12-bit colours; the sprite image and palette come from ApolloLib. + +## Details + +### Position (original and SRC) + +| Address | Name | Access | Description (original) | +|---|---|---|---| +| `$DFF1D0` | SPRHSTRT | W | CHUNKY SPRITE X Pos | +| `$DFF1D2` | SPRHSTOP | W | CHUNKY SPRITE Y POS | + +- `$DFF1D0`: on SAGA this is the pointer X position; the original also marks ECS and AGA. +- `$DFF1D2`: on SAGA this is the pointer Y position; the original also marks ECS and AGA. + +- Write X to `$DFF1D0` and Y to `$DFF1D2`; read them back at `$DFE1D0` and `$DFE1D2` (ApolloLib, SRC). +- ApolloLib writes the mouse position + 16 (X) and + 8 (Y) (SRC). + +### 32x32 pointer sprite (SRC, not in the original) + +From the current ApolloLib and the ApolloPointer example: + +| Address | Use | +|---|---| +| `$DFD000` | Image: 32 x 32 pixels, 2 bytes per pixel (colour index, alpha), 2048 bytes, row by row | +| `$DFF3A8` | Palette index (word): write the entry number first | +| `$DFF3AA` | Palette colour (long, R8G8B8) for the entry selected at `$DFF3A8` | + +- Index 0 is transparent. ApolloLib writes alpha `$FF` for opaque pixels and `$00` for semi-transparent ones; the example's usage text says colour 1 is semi-transparent. +- To set the palette, write the index to `$DFF3A8`, then the colour to `$DFF3AA`, for each of the 256 entries. + +### 12-bit pointer colours (original) + +| Address | Name | Access | Description (original) | +|---|---|---|---| +| `$DFF3A2` | Sprite Col1 | W | Word register RGB (11..0) | +| `$DFF3A4` | Sprite Col2 | W | Word register RGB (11..0) | +| `$DFF3A6` | Sprite Col3 | W | Word register RGB (11..0) | + +These rows have no page in the original. An older ApolloLib copy adds colour 0 at `$DFF3A0` and a 16x16 planar pointer image at `$DFF800` (SRC). Which cores have this 16x16 pointer next to, or instead of, the 32x32 sprite is an open question (see [index.md](index.md)). + +## Differences from AmigaOS / AROS / 68060 + +- On ECS, `$DFF1D0`/`$DFF1D2` are SPRHSTRT/SPRHSTOP (UHRES sprite vertical start and stop). On SAGA they position the pointer. +- Classic sprites are 16 pixels wide with 3 colours, fetched by DMA from Chip RAM. The SAGA pointer sprite is written directly to `$DFD000`. + +## Do / Don't + +- DO write the palette through `$DFF3A8` (index) and `$DFF3AA` (colour). +- DO keep colour index 0 for transparent pixels. +- DON'T use `$DFF800` or `$DFF3A0`–`$DFF3A6` until the open question is settled. diff --git a/core/saga-registers/sprite-collision.md b/core/saga-registers/sprite-collision.md new file mode 100644 index 0000000..c566405 --- /dev/null +++ b/core/saga-registers/sprite-collision.md @@ -0,0 +1,71 @@ +--- +title: "SAGA detailed sprite collision" +type: reference +owner: WDrijver +status: draft +origin: official +basis: [official] +components: [saga-video-isabelle] +applies_to: + core: "Core 12000+" + os: [any] +tags: [saga, isabelle, sprites, collision, registers] +related: + - core/saga-registers/index.md +sources: + - "SAGA register documentation, sources/official/saga-registers/ (HTML)" +generated_from: sources/official/saga-registers/index.htm +--- + + + +## Summary + +SAGA reports, per sprite, which other sprites it touches, in one register per sprite at `$DFF230`–`$DFF23E`. + +## Details + +### Registers + +| Address | Name | Access | Description (original) | +|---|---|---|---| +| `$DFF230` | clxdat0 | R | Sprite0 Detailed Collision | +| `$DFF232` | clxdat1 | R | Sprite1 Detailed Collision | +| `$DFF234` | clxdat2 | R | Sprite2 Detailed Collision | +| `$DFF236` | clxdat3 | R | Sprite3 Detailed Collision | +| `$DFF238` | clxdat4 | R | Sprite4 Detailed Collision | +| `$DFF23A` | clxdat5 | R | Sprite5 Detailed Collision | +| `$DFF23C` | clxdat6 | R | Sprite6 Detailed Collision | +| `$DFF23E` | clxdat7 | R | Sprite7 Detailed Collision | + +Bit layout (one register per sprite): + +| Bits | Function | Description | +|---|---|---| +| 15 | HIT15 | Sprite to SpriteF | +| 14 | HIT14 | Sprite to SpriteE | +| 13 | HIT13 | Sprite to SpriteD | +| 12 | HIT12 | Sprite to SpriteC | +| 11 | HIT11 | Sprite to SpriteB | +| 10 | HIT10 | Sprite to SpriteA | +| 9 | HIT9 | Sprite to Sprite9 | +| 8 | HIT8 | Sprite to Sprite8 | +| 7 | HIT7 | Sprite to Sprite7 | +| 6 | HIT6 | Sprite to Sprite6 | +| 5 | HIT5 | Sprite to Sprite5 | +| 4 | HIT4 | Sprite to Sprite4 | +| 3 | HIT3 | Sprite to Sprite3 | +| 2 | HIT2 | Sprite to Sprite2 | +| 1 | HIT1 | Sprite to Sprite1 | +| 0 | HIT0 | Sprite to Sprite0 | + +The bits name sprites 0 to F (16 sprites), but the original lists registers for sprites 0–7 only. Whether sprites 8–15 exist is not documented. + +## Differences from AmigaOS / AROS / 68060 + +- Classic CLXDAT (`$DFF00E`) reports collisions only between sprite pairs and playfields, and clears on read. + +## Do / Don't + +- DO read the register of the sprite you are interested in. +- DON'T assume sprites 8–15 exist. diff --git a/core/saga-registers/system.md b/core/saga-registers/system.md new file mode 100644 index 0000000..f972343 --- /dev/null +++ b/core/saga-registers/system.md @@ -0,0 +1,74 @@ +--- +title: "SAGA system registers: board ID, core revision, chip ID, SPI" +type: reference +owner: WDrijver +status: draft +origin: official +basis: [official, source-code] +components: [general] +applies_to: + core: "Core 12000+" + os: [any] +tags: [saga, board-id, version, registers] +related: + - core/saga-registers/index.md + - hardware/index.md +sources: + - "SAGA register documentation, sources/official/saga-registers/ (HTML)" + - "ApolloOS source, github.com/ApolloTeam-dev/ApolloOS.R10 arch/m68k-amiga/hidd/sagagfx/sagagfx_hw.h, commit ca5ef46 (2025-06-10)" + - "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04" +generated_from: sources/official/saga-registers/index.htm +--- + + + +## Summary + +`$DFF3FC` gives the V4 board ID and the CPU clock multiplier. Core revision, chip ID and SPI registers sit at `$DFF3EA`–`$DFF3FA`. + +## Details + +### Registers + +| Address | Name | Access | Description (original) | +|---|---|---|---| +| `$DFF3EA` | CORE REVISION | R | Reserved | +| `$DFF3F0` | CHIP ID | R | – | +| `$DFF3F2` | CHIP ID | R | – | +| `$DFF3F4` | CHIP ID | R | – | +| `$DFF3F6` | CHIP ID | R | – | +| `$DFF3F8` | SPI WRITE | R | Reserved | +| `$DFF3FA` | SPI read | R | Reserved | +| `$DFF3FC` | VAMPIRE VERSION | R | 8bit Card Version / 8bit clock multiplier | + +### VAMPIRE VERSION / board ID (`$DFF3FC`) + +Bits 15–8: board (card) ID. Bits 7–0: CPU clock multiplier. + +| ID | Board | Source | +|---|---|---| +| $01 | V2-V600 (legacy) | ApolloOS | +| $02 | V2-V500 (legacy) | ApolloOS | +| $03 | V4 Firebird (A500); also Salamander (Firebird on an A2000 adapter) and Phoenix (Firebird on an A1000 adapter) | WDrijver, original | +| $04 | V4 IceDrake (A1200) | WDrijver, original | +| $05 | V4 Standalone | WDrijver, original | +| $06 | V2-V1200 (legacy) | ApolloOS | +| $07 | V4 Manticore (A600) | WDrijver, original | +| $08 | V4 UniCorn (A6000) | WDrijver, ApolloOS | + +The original's list says 1 = V600, 2 = V500, 6 = V1200 without "V2", and lacks `$08`. ApolloOS marks `$09` as future. + +All V4 boards run the same core: the board ID tells the board, not different SAGA features (see [hardware/index.md](../../hardware/index.md)). + +### Other registers + +CORE REVISION, CHIP ID and the SPI registers have no description in the original. SPI WRITE (`$DFF3F8`) is marked R there, which is unlikely for a write register. + +## Differences from AmigaOS / AROS / 68060 + +- Classic Amiga chipsets have DENISEID (`$DFF07C`) for the video chip only; there is no board or clock register. + +## Do / Don't + +- DO read the board ID with `move.w $DFF3FC` and use the high byte. +- DON'T use the board ID to decide which SAGA features exist: they are the same on every V4 board with the same core. diff --git a/core/saga-video-isabelle/index.md b/core/saga-video-isabelle/index.md index 34129ee..63bda13 100644 --- a/core/saga-video-isabelle/index.md +++ b/core/saga-video-isabelle/index.md @@ -16,16 +16,21 @@ sources: Isabelle, the SAGA video chip: screen modes and video features. -**This folder has no content yet.** If your task depends on it, tell the -user that the knowledge base does not cover the SAGA video (Isabelle) yet. Do not fill the -gap with classic Amiga or 68060 knowledge. +**This folder has no content of its own yet.** The official register map +is in `core/saga-registers/`: [chunky-plane.md](../saga-registers/chunky-plane.md) +(GFXMODE, screen modes), [colour-ports.md](../saga-registers/colour-ports.md), +[pip.md](../saga-registers/pip.md), [pointer.md](../saga-registers/pointer.md), +[display-control.md](../saga-registers/display-control.md) and +[sprite-collision.md](../saga-registers/sprite-collision.md). For anything +else, tell the user that the knowledge base does not cover it yet. Do not +fill the gap with classic Amiga or 68060 knowledge. ## Details ### Planned files -- `registers.md`: register map with offsets, bits and access rules -- One file per feature, for example screen modes or sprites +- One file per feature, for example screen modes or sprites, built on the + register map in `core/saga-registers/` ### For contributors diff --git a/sources/official/saga-registers/adkcon.html b/sources/official/saga-registers/adkcon.html new file mode 100755 index 0000000..0a0e8c8 --- /dev/null +++ b/sources/official/saga-registers/adkcon.html @@ -0,0 +1,54 @@ + + +
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+ADKCON     09E      W       P      Audio, disk, control write
+ADKCONR    010      R       P      Audio, disk, control read
+
+            BIT#   USE
+            ----   ------------------------------------
+            15     SET/CLR    Set/clear control bit. Determines if bits
+                              written with a 1 get set or cleared. Bits
+                              written with a zero are always unchanged.
+            14-13  PRECOMP 1-0
+
+                       CODE  PRECOMP VALUE
+                       ----  -------------
+                        00   none
+                        01   140 ns
+                        10   280 ns
+                        11   560 ns
+
+            12     MFMPREC       ( 1=MFM precomp 0=GCR precomp)
+            11     UARTBRK        Forces a UART break (clears TXD) if true.
+            10     WORDSYNC       Enables disk read synchronizing on a word
+                              equal to DISK SYNC CODE, located in
+                              address (3F)*2.
+            09 MSBSYNC        Enables disk read synchronizing on the MSB
+                              (most significant bit). Appl type GCR.
+            08 FAST   Disk data clock rate control 1=fast(2us) 0=slow(4us).
+                      (fast for MFM, slow for MFM or GCR)
+
+            07 USE3PN Use audio channel 3 to modulate nothing.
+            06 USE2P3 Use audio channel 2 to modulate period of channel 3.
+            05 USE1P2 Use audio channel 1 to modulate period of channel 2.
+            04 USE0P1 Use audio channel 0 to modulate period of channel 1.
+
+            03 USE3VN Use audio channel 3 to modulate nothing.
+            02 USE2V3 Use audio channel 2 to modulate volume of channel 3.
+            01 USE1V2 Use audio channel 1 to modulate volume of channel 2.
+            00 USE0V1 Use audio channel 0 to modulate volume of channel 1.
+
+                NOTE:  If both period and volume are modulated on the
+                same channel, the period and volume will be alternated.
+                First word xxxxxxxx V6-V0 , Second word P15-P0 (etc)
+
+
+
+ + diff --git a/sources/official/saga-registers/adkcon2.htm b/sources/official/saga-registers/adkcon2.htm new file mode 100755 index 0000000..44d7230 --- /dev/null +++ b/sources/official/saga-registers/adkcon2.htm @@ -0,0 +1,32 @@ + + +
+
+INTREQ2
+
+         This register contains detailed Sprite collision detection
+
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 15    |         | SET/CLR                                    |
+         | 14    |         |                                            |
+         | 13    | ETH     | Ethernet                                   |
+         | 12    |         |                                            |
+         | 11    | AUD15   | Audio channel 15 block finished            |
+         | 10    | AUD14   | Audio channel 14 block finished            |
+         | 09    | AUD13   | Audio channel 13 block finished            |
+         | 08    | AUD12   | Audio channel 12 block finished            |
+         | 07    | AUD11   | Audio channel 11 block finished            |
+         | 06    | AUD10   | Audio channel 10 block finished            |
+         | 05    | AUD9    | Audio channel 9 block finished             |
+         | 04    | AUD8    | Audio channel 8 block finished             |
+         | 03    | AUD7    | Audio channel 7 block finished             |
+         | 02    | AUD6    | Audio channel 6 block finished             |
+         | 01    | AUD5    | Audio channel 5 block finished             |
+         | 00    | AUD4    | Audio channel 4 block finished             |
+         +-------+----------+-------------------------------------------+
+
+ + diff --git a/sources/official/saga-registers/adkconr.htm b/sources/official/saga-registers/adkconr.htm new file mode 100755 index 0000000..de1ccf2 --- /dev/null +++ b/sources/official/saga-registers/adkconr.htm @@ -0,0 +1,51 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+ADKCON     09E      W       P      Audio, disk, control write
+ADKCONR    010      R       P      Audio, disk, control read
+
+            BIT#   USE
+            ----   ------------------------------------
+            15     SET/CLR    Set/clear control bit. Determines if bits
+                              written with a 1 get set or cleared. Bits
+                              written with a zero are always unchanged.
+            14-13  PRECOMP 1-0
+
+                       CODE  PRECOMP VALUE
+                       ----  -------------
+                        00   none
+                        01   140 ns
+                        10   280 ns
+                        11   560 ns
+
+            12     MFMPREC       ( 1=MFM precomp 0=GCR precomp)
+            11     UARTBRK        Forces a UART break (clears TXD) if true.
+            10     WORDSYNC       Enables disk read synchronizing on a word
+                              equal to DISK SYNC CODE, located in
+                              address (3F)*2.
+            09 MSBSYNC        Enables disk read synchronizing on the MSB
+                              (most significant bit). Appl type GCR.
+            08 FAST   Disk data clock rate control 1=fast(2us) 0=slow(4us).
+                      (fast for MFM, slow for MFM or GCR)
+
+            07 USE3PN Use audio channel 3 to modulate nothing.
+            06 USE2P3 Use audio channel 2 to modulate period of channel 3.
+            05 USE1P2 Use audio channel 1 to modulate period of channel 2.
+            04 USE0P1 Use audio channel 0 to modulate period of channel 1.
+
+            03 USE3VN Use audio channel 3 to modulate nothing.
+            02 USE2V3 Use audio channel 2 to modulate volume of channel 3.
+            01 USE1V2 Use audio channel 1 to modulate volume of channel 2.
+            00 USE0V1 Use audio channel 0 to modulate volume of channel 1.
+
+                NOTE:  If both period and volume are modulated on the
+                same channel, the period and volume will be alternated.
+                First word xxxxxxxx V6-V0 , Second word P15-P0 (etc)
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/audnvol.htm b/sources/official/saga-registers/audnvol.htm new file mode 100755 index 0000000..0919748 --- /dev/null +++ b/sources/official/saga-registers/audnvol.htm @@ -0,0 +1,21 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+AUDnVOL   DFF4n8      W       P      Audio channel x stereo volume
+
+                 This register contains the stereo volume setting for
+                 audio channel x. 
+
+                 Bit#    Use
+                 ----    --------------------------
+                  15-08  Left Volume
+                  07-00  Right Volume
+
+
+ + diff --git a/sources/official/saga-registers/audxctrl.htm b/sources/official/saga-registers/audxctrl.htm new file mode 100755 index 0000000..2c50f88 --- /dev/null +++ b/sources/official/saga-registers/audxctrl.htm @@ -0,0 +1,26 @@ + + +
+
+AUDCTRL
+
+         16bit Audio CONTROL Register
+
+         +-------+----------+-------------------------------------------+
+         | BIT# | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 2    | Stereo   | 16bit/16bit interleaved mode - 64bit align |
+         | 1    | OneShot  | Channel will turn itself off at sample end |
+         | 0    | 16bit    | 0=8bit, 1=16bit samples                    |
+         +-------+----------+-------------------------------------------+
+
+Supported format:
+
+8bit signed mono. Data stored in pairs, data aligment 16bit
+16bit signed mono, Data stored in pairs, data alignment 32bit
+Left/Rigth signed 16bit stereo, Data in memory in pairs, memory alignment 64bit 
+
+
+
+ + diff --git a/sources/official/saga-registers/audxdat.htm b/sources/official/saga-registers/audxdat.htm new file mode 100755 index 0000000..c621588 --- /dev/null +++ b/sources/official/saga-registers/audxdat.htm @@ -0,0 +1,24 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+AUDxDAT    0AA      W       P      Audio channel x data
+
+                 This register is the audio channel x (x=0,1,2,3)
+                 DMA data buffer.  It contains 2 bytes of data that
+                 are each 2's complement and are outputted
+                 sequentially (with digital-to-analog conversion)
+                 to the audio output pins.  (LSB = 3 MV)  The DMA
+                 controller automatically transfers data to this
+                 register from RAM.  The processor can also write
+                 directly to this register.  When the DMA data is
+                 finished (words outputted=length) and the data in
+                 this register has been used, an audio channel
+                 interrupt request is set.
+
+ + diff --git a/sources/official/saga-registers/audxl.htm b/sources/official/saga-registers/audxl.htm new file mode 100755 index 0000000..8f678e0 --- /dev/null +++ b/sources/official/saga-registers/audxl.htm @@ -0,0 +1,11 @@ + + +
+
+AUD_PTR
+
+         32bit pointer to Audio data.
+
+
+ + diff --git a/sources/official/saga-registers/audxlch.htm b/sources/official/saga-registers/audxlch.htm new file mode 100755 index 0000000..7f0f75d --- /dev/null +++ b/sources/official/saga-registers/audxlch.htm @@ -0,0 +1,22 @@ + + +
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+AUDxLCH    0A0      W      A( E )  Audio channel x location (high 3 bits,
+                                       5 bits if ECS)
+AUDxLCL    0A2      W       A      Audio channel x location (low 15 bits)
+
+                 This pair of registers contains the 18 bit starting
+                 address (location) of audio channel x (x=0,1,2,3) DMA
+                 data. This is not a pointer register and therefore needs
+                 to be reloaded only if a different memory location is to
+                 be outputted.
+
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/audxlen.htm b/sources/official/saga-registers/audxlen.htm new file mode 100755 index 0000000..a86a4e7 --- /dev/null +++ b/sources/official/saga-registers/audxlen.htm @@ -0,0 +1,12 @@ + + +
+
+AUDLEN
+
+         32bit length of audio data.
+         Count is in pair of samples!
+
+
+ + diff --git a/sources/official/saga-registers/audxper.htm b/sources/official/saga-registers/audxper.htm new file mode 100755 index 0000000..29db542 --- /dev/null +++ b/sources/official/saga-registers/audxper.htm @@ -0,0 +1,19 @@ + + +
+
+AUDPER
+
+         16bit PERIOD COUNT
+
+ This register contains the period (rate) of
+ audio channel x DMA data transfer.
+ The minimum period is 65 color clocks. This means
+ that the smallest number that should be placed in
+ this register is 65 decimal.  This corresponds to
+ a maximum sample frequency of 56 khz.
+
+
+
+ + diff --git a/sources/official/saga-registers/audxvol.htm b/sources/official/saga-registers/audxvol.htm new file mode 100755 index 0000000..b29109d --- /dev/null +++ b/sources/official/saga-registers/audxvol.htm @@ -0,0 +1,24 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+AUDxVOL    0A8      W       P      Audio channel x volume
+
+                 This register contains the volume setting for
+                 audio channel x.  Bits 6,5,4,3,2,1,0 specify 65
+                 linear volume levels as shown below.
+
+                 Bit#    Use
+                 ----    --------------------------
+                  15-07  Not used
+                  06     Forces volume to max (64 ones, no zeros)
+                  05-00  Sets one of 64 levels (000000=no output
+                         (111111=63 1s, one 0)
+
+
+ + diff --git a/sources/official/saga-registers/audxvol2.htm b/sources/official/saga-registers/audxvol2.htm new file mode 100755 index 0000000..0c8182d --- /dev/null +++ b/sources/official/saga-registers/audxvol2.htm @@ -0,0 +1,25 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+AUDxVOL    0A8      W       P      Audio channel x volume
+
+                 This register contains the volume setting for
+                 audio channel x.  Bits 6,5,4,3,2,1,0 specify 65
+                 linear volume levels as shown below.
+
+                 Bit#    Use
+                 ----    --------------------------
+                  15-07  Not used
+                  06     Forces volume to max (64 ones, no zeros)
+                  05-00  Sets one of 64 levels (000000=no output
+                         (111111=63 1s, one 0)
+
+
+
+ + diff --git a/sources/official/saga-registers/beamcon0.htm b/sources/official/saga-registers/beamcon0.htm new file mode 100755 index 0000000..41030d1 --- /dev/null +++ b/sources/official/saga-registers/beamcon0.htm @@ -0,0 +1,13 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BEAMCON0   1DC      W      A( E ) Beam counter control register (SHRES,PAL)
+
+
+ + diff --git a/sources/official/saga-registers/bltafwm.htm b/sources/official/saga-registers/bltafwm.htm new file mode 100755 index 0000000..abee88c --- /dev/null +++ b/sources/official/saga-registers/bltafwm.htm @@ -0,0 +1,20 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BLTAFWM    044      W       A      Blitter first-word mask for source A
+BLTALWM    046      W       A      Blitter last-word mask for source A
+
+                 The patterns in these two registers are ANDed with
+                 the first and last words of each line of data from
+                 source A into the blitter. A zero in any bit
+                 overrides data from source A.  These registers
+                 should be set to all 1s for fill mode or for
+                 line-drawing mode.
+
+ + diff --git a/sources/official/saga-registers/bltcon0.htm b/sources/official/saga-registers/bltcon0.htm new file mode 100755 index 0000000..7f5ad58 --- /dev/null +++ b/sources/official/saga-registers/bltcon0.htm @@ -0,0 +1,114 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BLTCON0    040      W       A      Blitter control register 0
+BLTCON1    042      W      A( E )  Blitter control register 1
+
+                 These two control registers are used together to
+                 control blitter operations.  There are two basic
+                 modes, area and line, which are selected by bit
+                 0 of BLTCON1, as shown below.
+
+                    AREA MODE ("normal")
+                 -------------------------
+                 BIT# BLTCON0     BLTCON1
+                 ---- -------     -------
+                 15   ASH3        BSH3
+                 14   ASH2        BSH2
+                 13   ASH1        BSH1
+                 12   ASA0        BSH0
+                 11   USEA         X
+                 10   USEB         X
+                 09   USEC         X
+                 08   USED         X
+                 07   LF7          DOFF
+                 06   LF6          X
+                 05   LF5          X
+                 04   LF4         EFE
+                 03   LF3         IFE
+                 02   LF2         FCI
+                 01   LF1         DESC
+                 00   LF0         LINE(=0)
+
+                 ASH3-0  Shift value of A source
+                 BSH3-0  Shift value of B source
+                 USEA    Mode control bit to use source A
+                 USEB    Mode control bit to use source B
+                 USEC    Mode control bit to use source C
+                 USED    Mode control bit to use destination D
+                 LF7-0   Logic function minterm select lines
+                 EFE     Exclusive fill enable
+                 IFE     Inclusive fill enable
+                 FCI     Fill carry input
+                 DESC    Descending (decreasing address) control bit
+                 LINE    Line mode control bit (set to 0)
+
+                 LINE DRAW       LINE MODE (line draw)
+                 LINE DRAW     ------------------------------
+                 LINE DRAW     BIT# BLTCON0     BLTCON1
+                 LINE DRAW     ---- -------     -------
+                 LINE DRAW     15   START3      TEXTURE3
+                 LINE DRAW     14   START2      TEXTURE2
+                 LINE DRAW     13   START1      TEXTURE1
+                 LINE DRAW     12   START0      TEXTURE0
+                 LINE DRAW     11    1              0
+                 LINE DRAW     10    0              0
+                 LINE DRAW     09    1              0
+                 LINE DRAW     08    1              0
+                 LINE DRAW     07   LF7             0
+                 LINE DRAW     06   LF6            SIGN
+                 LINE DRAW     05   LF5             0 (Reserved)
+                 LINE DRAW     04   LF4            SUD
+                 LINE DRAW     03   LF3            SUL
+                 LINE DRAW     02   LF2            AUL
+                 LINE DRAW     01   LF1            SING
+                 LINE DRAW     00   LF0            LINE(=1)
+                 LINE DRAW
+                 LINE DRAW     START3-0  Starting point of line
+                 LINE DRAW               (0 thru 15 hex)
+
+                 LINE DRAW     LF7-0     Logic function minterm
+                 LINE DRAW     select lines should be preloaded
+                 LINE DRAW     with 4A to select the equation
+                 LINE DRAW     D=(AC+ABC).  Since A contains a
+                 LINE DRAW     single bit true (8000), most bits
+                 LINE DRAW     will pass the C field unchanged
+                 LINE DRAW     (not A and C), but one bit will
+                 LINE DRAW     invert the C field and combine it
+                 LINE DRAW     with texture (A and B and not C).
+                 LINE DRAW     The A bit is automatically moved
+                 LINE DRAW     across the word by the hardware.
+                 LINE DRAW
+                 LINE DRAW     LINE   Line mode control bit (set to 1)
+                 LINE DRAW     SIGN   Sign flag
+                 LINE DRAW     0      Reserved for new mode
+                 LINE DRAW     SING   Single bit per horizontal line for
+                 LINE DRAW            use with subsequent area fill
+                 LINE DRAW     SUD    Sometimes up or down (=AUD*)
+                 LINE DRAW     SUL    Sometimes up or left
+                 LINE DRAW     AUL    Always up or left
+
+                 LINE DRAW     The 3 bits above select the octant
+                 LINE DRAW     for line drawing:
+
+                 LINE DRAW            OCT     SUD  SUL  AUL
+                 LINE DRAW            ---     ---  ---  ---
+                 LINE DRAW             0       1    1    0
+                 LINE DRAW             1       0    0    1
+                 LINE DRAW             2       0    1    1
+                 LINE DRAW             3       1    1    1
+                 LINE DRAW             4       1    0    1
+                 LINE DRAW             5       0    1    0
+                 LINE DRAW             6       0    0    0
+                 LINE DRAW             7       1    0    0
+
+                 LINE DRAW     The "B" source is used for
+                 LINE DRAW     texturing the drawn lines.
+
+ + diff --git a/sources/official/saga-registers/bltddat.htm b/sources/official/saga-registers/bltddat.htm new file mode 100755 index 0000000..672acbe --- /dev/null +++ b/sources/official/saga-registers/bltddat.htm @@ -0,0 +1,18 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BLTDDAT    ---      -      ----  Blitter destination data register
+
+                 This register holds the data resulting from each
+                 word of blitter operation until it is sent to a
+                 RAM destination.  This is a dummy address and
+                 cannot be read by the micro.  The transfer is
+                 automatic during blitter operation.
+
+ + diff --git a/sources/official/saga-registers/bltsize.htm b/sources/official/saga-registers/bltsize.htm new file mode 100755 index 0000000..27d65e2 --- /dev/null +++ b/sources/official/saga-registers/bltsize.htm @@ -0,0 +1,39 @@ + + +
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BLTSIZE    058      W       A      Blitter start and size (window width,
+                                       height)
+
+                 This register contains the width and height of
+                 the blitter operation (in line mode, width must
+                 = 2, height = line length).  Writing to this
+                 register will start the blitter, and should be
+                 done last, after all pointers and control
+                 registers have been initialized.
+
+                 BIT#  15,14,13,12,11,10,09,08,07,06,05,04,03,02,01,00
+                       -----------------------------------------------
+                       h9 h8 h7 h6 h5 h4 h3 h2 h1 h0,w5 w4 w3 w2 w1 w0
+
+                 h=height=vertical lines (10 bits=1024 lines max)
+                 w=width =horizontal pixels (6 bits=64
+                                      words=1024 pixels max)
+
+                 LINE DRAW   BLTSIZE controls the line length and starts
+                 LINE DRAW   the line draw when written to.  The h field
+                 LINE DRAW   controls the line length (10 bits gives
+                 LINE DRAW   lines up to 1024 dots long).  The w field
+                 LINE DRAW   must be set to 02 for all line drawing.
+
+BLTSIZV    05C      W      A( E ) Blitter V size (for 15 bit vertical size)
+BLTSIZH    05E      W      A( E ) Blitter H size and start (for 11 bit
+                                      H size)
+
+ + diff --git a/sources/official/saga-registers/bltsizh.htm b/sources/official/saga-registers/bltsizh.htm new file mode 100755 index 0000000..560395a --- /dev/null +++ b/sources/official/saga-registers/bltsizh.htm @@ -0,0 +1,40 @@ + + +
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BLTSIZE    058      W       A      Blitter start and size (window width,
+                                       height)
+
+                 This register contains the width and height of
+                 the blitter operation (in line mode, width must
+                 = 2, height = line length).  Writing to this
+                 register will start the blitter, and should be
+                 done last, after all pointers and control
+                 registers have been initialized.
+
+                 BIT#  15,14,13,12,11,10,09,08,07,06,05,04,03,02,01,00
+                       -----------------------------------------------
+                       h9 h8 h7 h6 h5 h4 h3 h2 h1 h0,w5 w4 w3 w2 w1 w0
+
+                 h=height=vertical lines (10 bits=1024 lines max)
+                 w=width =horizontal pixels (6 bits=64
+                                      words=1024 pixels max)
+
+                 LINE DRAW   BLTSIZE controls the line length and starts
+                 LINE DRAW   the line draw when written to.  The h field
+                 LINE DRAW   controls the line length (10 bits gives
+                 LINE DRAW   lines up to 1024 dots long).  The w field
+                 LINE DRAW   must be set to 02 for all line drawing.
+
+BLTSIZV    05C      W      A( E ) Blitter V size (for 15 bit vertical size)
+BLTSIZH    05E      W      A( E ) Blitter H size and start (for 11 bit
+                                      H size)
+
+
+ + diff --git a/sources/official/saga-registers/bltsizv.htm b/sources/official/saga-registers/bltsizv.htm new file mode 100755 index 0000000..560395a --- /dev/null +++ b/sources/official/saga-registers/bltsizv.htm @@ -0,0 +1,40 @@ + + +
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BLTSIZE    058      W       A      Blitter start and size (window width,
+                                       height)
+
+                 This register contains the width and height of
+                 the blitter operation (in line mode, width must
+                 = 2, height = line length).  Writing to this
+                 register will start the blitter, and should be
+                 done last, after all pointers and control
+                 registers have been initialized.
+
+                 BIT#  15,14,13,12,11,10,09,08,07,06,05,04,03,02,01,00
+                       -----------------------------------------------
+                       h9 h8 h7 h6 h5 h4 h3 h2 h1 h0,w5 w4 w3 w2 w1 w0
+
+                 h=height=vertical lines (10 bits=1024 lines max)
+                 w=width =horizontal pixels (6 bits=64
+                                      words=1024 pixels max)
+
+                 LINE DRAW   BLTSIZE controls the line length and starts
+                 LINE DRAW   the line draw when written to.  The h field
+                 LINE DRAW   controls the line length (10 bits gives
+                 LINE DRAW   lines up to 1024 dots long).  The w field
+                 LINE DRAW   must be set to 02 for all line drawing.
+
+BLTSIZV    05C      W      A( E ) Blitter V size (for 15 bit vertical size)
+BLTSIZH    05E      W      A( E ) Blitter H size and start (for 11 bit
+                                      H size)
+
+
+ + diff --git a/sources/official/saga-registers/bltxdat.htm b/sources/official/saga-registers/bltxdat.htm new file mode 100755 index 0000000..06d8297 --- /dev/null +++ b/sources/official/saga-registers/bltxdat.htm @@ -0,0 +1,22 @@ + + +
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BLTxDAT    074      W       A     Blitter source x data register
+
+                 This register holds source x (x=A,B,C) data for
+                 use by the blitter. It is normally loaded by the
+                 blitter DMA channel; however, it may also be
+                 preloaded by the microprocessor.
+
+                 LINE DRAW   BLTADAT is used as an index register
+                 LINE DRAW   and must be preloaded with 8000.
+                 LINE DRAW   BLTBDAT is used for texture; it must
+                 LINE DRAW   be preloaded with FF if no texture
+                 LINE DRAW   (solid line) is desired.
+
+ + diff --git a/sources/official/saga-registers/bltxmod.htm b/sources/official/saga-registers/bltxmod.htm new file mode 100755 index 0000000..5482f02 --- /dev/null +++ b/sources/official/saga-registers/bltxmod.htm @@ -0,0 +1,34 @@ + + +
+
+
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BLTxMOD    064      W       A     Blitter modulo x
+
+                 This register contains the modulo for blitter
+                 source (x=A,B,C) or destination (x=D).  A modulo
+                 is a number that is automatically added to the
+                 address at the end of each line, to make the
+                 address point to the start of the next line.  Each
+                 source or destination has its own modulo, allowing
+                 each to be a different size, while an identical
+                 area of each is used in the blitter operation.
+
+                 LINE DRAW   BLTAMOD and BLTBMOD are used as slope
+                 LINE DRAW   storage registers and must be preloaded
+                 LINE DRAW   with the values (4Y-4X) and (4Y)
+                 LINE DRAW   respectively.  Y/X= line slope.
+                 LINE DRAW   BLTCMOD and BLTDMOD must both be
+                 LINE DRAW   preloaded with the width (in bytes)
+                 LINE DRAW   of the image into which the line is
+                 LINE DRAW   being drawn (normally two times the
+                 LINE DRAW   screen width in words).
+
+ + diff --git a/sources/official/saga-registers/bltxpth.htm b/sources/official/saga-registers/bltxpth.htm new file mode 100755 index 0000000..d12ed2f --- /dev/null +++ b/sources/official/saga-registers/bltxpth.htm @@ -0,0 +1,30 @@ + + +
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BLTxPTH    050      W      A( E ) Blitter pointer to x (high 3 bits,
+                                      5 bits if ECS)
+BLTxPTL    052      W       A     Blitter pointer to x (low 15 bits)
+
+                 This pair of registers contains the 18-bit address
+                 of blitter source (x=A,B,C) or destination (x=D)
+                 DMA data.  This pointer must be preloaded with the
+                 starting address of the data to be processed by
+                 the blitter. After the blitter is finished, it
+                 will contain the last data address (plus increment
+                 and modulo).
+
+                 LINE DRAW   BLTAPTL is used as an accumulator
+                 LINE DRAW   register and must be preloaded with
+                 LINE DRAW   the starting value of (2Y-X) where
+                 LINE DRAW   Y/X is the line slope.  BLTCPT and
+                 LINE DRAW   BLTDPT (both H and L) must be
+                 LINE DRAW   preloaded with the starting address
+                 LINE DRAW   of the line.
+
+
+ + diff --git a/sources/official/saga-registers/bplcon0.htm b/sources/official/saga-registers/bplcon0.htm new file mode 100755 index 0000000..4356560 --- /dev/null +++ b/sources/official/saga-registers/bplcon0.htm @@ -0,0 +1,65 @@ + + +
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BPLCON0    100      W     A D( E ) Bitplane control register (misc.
+                                       control bits)
+BPLCON1    102      W       D      Bitplane control register
+                                       (horizontal scroll control)
+BPLCON2    104      W       D( E ) Bitplane control register
+                                       (video priority control)
+
+                 These registers control the operation of the
+                 bitplanes and various aspects of the display.
+
+                 BIT#     BPLCON0    BPLCON1    BPLCON2
+                 ----     --------   --------   --------
+                 15       HIRES       X           X
+                 14       BPU2        X           X
+                 13       BPU1        X           X
+                 12       BPU0        X           X
+                 11       HOMOD       X           X
+                 10       DBLPF       X           X
+                 09       COLOR       X           X
+                 08       GAUD        X           X
+                 07        X         PF2H3        X
+                 06        X         PF2H2      PF2PRI
+                 05        X         PF2H1      PF2P2
+                 04        X         PF2H0      PF2P1
+                 03       LPEN       PF1H3      PF2P0
+                 02       LACE       PF1H2      PF1P2
+                 01       ERSY       PF1H1      PF1P1
+                 00        X         PF1H0      PF1P0
+
+               HIRES=High-resolution (70 ns pixels)
+               BPU  =Bitplane use code 000-110 (NONE through 6 inclusive)
+               HOMOD=Hold-and-modify mode (1 = Hold-and-modify mode (HAM);
+                       0 = Extra Half Brite (EHB) if HAM=0 and BPU=6
+                       and DBLPF=0 then bitplane 6 controls an intensity
+                       reduction in the other five bitplanes)
+               DBLPF=Double playfield (PF1=odd PF2=even bitplanes)
+               COLOR=Composite video COLOR enable
+               GAUD=Genlock audio enable (muxed on BKGND pin
+                       during vertical blanking
+               LPEN =Light pen enable (reset on power up)
+               LACE =Interlace enable (reset on power up)
+               ERSY =External resync (HSYNC, VSYNC pads become
+                       inputs) (reset on power up)
+               PF2PRI=Playfield 2 (even planes) has priority over
+                       (appears in front of) playfield 1
+                       (odd planes).
+               PF2P=Playfield 2 priority code (with respect
+                       to sprites)
+               PF1P=Playfield 1 priority code (with respect
+                       to sprites)
+               PF2H=Playfield 2 horizontal scroll code
+               PF1H=Playfield 1 horizontal scroll code
+
+BPLCON3    106      W      D( E ) Bitplane control (enhanced features)
+
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/bplcon1.htm b/sources/official/saga-registers/bplcon1.htm new file mode 100755 index 0000000..4356560 --- /dev/null +++ b/sources/official/saga-registers/bplcon1.htm @@ -0,0 +1,65 @@ + + +
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BPLCON0    100      W     A D( E ) Bitplane control register (misc.
+                                       control bits)
+BPLCON1    102      W       D      Bitplane control register
+                                       (horizontal scroll control)
+BPLCON2    104      W       D( E ) Bitplane control register
+                                       (video priority control)
+
+                 These registers control the operation of the
+                 bitplanes and various aspects of the display.
+
+                 BIT#     BPLCON0    BPLCON1    BPLCON2
+                 ----     --------   --------   --------
+                 15       HIRES       X           X
+                 14       BPU2        X           X
+                 13       BPU1        X           X
+                 12       BPU0        X           X
+                 11       HOMOD       X           X
+                 10       DBLPF       X           X
+                 09       COLOR       X           X
+                 08       GAUD        X           X
+                 07        X         PF2H3        X
+                 06        X         PF2H2      PF2PRI
+                 05        X         PF2H1      PF2P2
+                 04        X         PF2H0      PF2P1
+                 03       LPEN       PF1H3      PF2P0
+                 02       LACE       PF1H2      PF1P2
+                 01       ERSY       PF1H1      PF1P1
+                 00        X         PF1H0      PF1P0
+
+               HIRES=High-resolution (70 ns pixels)
+               BPU  =Bitplane use code 000-110 (NONE through 6 inclusive)
+               HOMOD=Hold-and-modify mode (1 = Hold-and-modify mode (HAM);
+                       0 = Extra Half Brite (EHB) if HAM=0 and BPU=6
+                       and DBLPF=0 then bitplane 6 controls an intensity
+                       reduction in the other five bitplanes)
+               DBLPF=Double playfield (PF1=odd PF2=even bitplanes)
+               COLOR=Composite video COLOR enable
+               GAUD=Genlock audio enable (muxed on BKGND pin
+                       during vertical blanking
+               LPEN =Light pen enable (reset on power up)
+               LACE =Interlace enable (reset on power up)
+               ERSY =External resync (HSYNC, VSYNC pads become
+                       inputs) (reset on power up)
+               PF2PRI=Playfield 2 (even planes) has priority over
+                       (appears in front of) playfield 1
+                       (odd planes).
+               PF2P=Playfield 2 priority code (with respect
+                       to sprites)
+               PF1P=Playfield 1 priority code (with respect
+                       to sprites)
+               PF2H=Playfield 2 horizontal scroll code
+               PF1H=Playfield 1 horizontal scroll code
+
+BPLCON3    106      W      D( E ) Bitplane control (enhanced features)
+
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/bplcon2.htm b/sources/official/saga-registers/bplcon2.htm new file mode 100755 index 0000000..4356560 --- /dev/null +++ b/sources/official/saga-registers/bplcon2.htm @@ -0,0 +1,65 @@ + + +
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BPLCON0    100      W     A D( E ) Bitplane control register (misc.
+                                       control bits)
+BPLCON1    102      W       D      Bitplane control register
+                                       (horizontal scroll control)
+BPLCON2    104      W       D( E ) Bitplane control register
+                                       (video priority control)
+
+                 These registers control the operation of the
+                 bitplanes and various aspects of the display.
+
+                 BIT#     BPLCON0    BPLCON1    BPLCON2
+                 ----     --------   --------   --------
+                 15       HIRES       X           X
+                 14       BPU2        X           X
+                 13       BPU1        X           X
+                 12       BPU0        X           X
+                 11       HOMOD       X           X
+                 10       DBLPF       X           X
+                 09       COLOR       X           X
+                 08       GAUD        X           X
+                 07        X         PF2H3        X
+                 06        X         PF2H2      PF2PRI
+                 05        X         PF2H1      PF2P2
+                 04        X         PF2H0      PF2P1
+                 03       LPEN       PF1H3      PF2P0
+                 02       LACE       PF1H2      PF1P2
+                 01       ERSY       PF1H1      PF1P1
+                 00        X         PF1H0      PF1P0
+
+               HIRES=High-resolution (70 ns pixels)
+               BPU  =Bitplane use code 000-110 (NONE through 6 inclusive)
+               HOMOD=Hold-and-modify mode (1 = Hold-and-modify mode (HAM);
+                       0 = Extra Half Brite (EHB) if HAM=0 and BPU=6
+                       and DBLPF=0 then bitplane 6 controls an intensity
+                       reduction in the other five bitplanes)
+               DBLPF=Double playfield (PF1=odd PF2=even bitplanes)
+               COLOR=Composite video COLOR enable
+               GAUD=Genlock audio enable (muxed on BKGND pin
+                       during vertical blanking
+               LPEN =Light pen enable (reset on power up)
+               LACE =Interlace enable (reset on power up)
+               ERSY =External resync (HSYNC, VSYNC pads become
+                       inputs) (reset on power up)
+               PF2PRI=Playfield 2 (even planes) has priority over
+                       (appears in front of) playfield 1
+                       (odd planes).
+               PF2P=Playfield 2 priority code (with respect
+                       to sprites)
+               PF1P=Playfield 1 priority code (with respect
+                       to sprites)
+               PF2H=Playfield 2 horizontal scroll code
+               PF1H=Playfield 1 horizontal scroll code
+
+BPLCON3    106      W      D( E ) Bitplane control (enhanced features)
+
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/bplcon3.htm b/sources/official/saga-registers/bplcon3.htm new file mode 100755 index 0000000..4356560 --- /dev/null +++ b/sources/official/saga-registers/bplcon3.htm @@ -0,0 +1,65 @@ + + +
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BPLCON0    100      W     A D( E ) Bitplane control register (misc.
+                                       control bits)
+BPLCON1    102      W       D      Bitplane control register
+                                       (horizontal scroll control)
+BPLCON2    104      W       D( E ) Bitplane control register
+                                       (video priority control)
+
+                 These registers control the operation of the
+                 bitplanes and various aspects of the display.
+
+                 BIT#     BPLCON0    BPLCON1    BPLCON2
+                 ----     --------   --------   --------
+                 15       HIRES       X           X
+                 14       BPU2        X           X
+                 13       BPU1        X           X
+                 12       BPU0        X           X
+                 11       HOMOD       X           X
+                 10       DBLPF       X           X
+                 09       COLOR       X           X
+                 08       GAUD        X           X
+                 07        X         PF2H3        X
+                 06        X         PF2H2      PF2PRI
+                 05        X         PF2H1      PF2P2
+                 04        X         PF2H0      PF2P1
+                 03       LPEN       PF1H3      PF2P0
+                 02       LACE       PF1H2      PF1P2
+                 01       ERSY       PF1H1      PF1P1
+                 00        X         PF1H0      PF1P0
+
+               HIRES=High-resolution (70 ns pixels)
+               BPU  =Bitplane use code 000-110 (NONE through 6 inclusive)
+               HOMOD=Hold-and-modify mode (1 = Hold-and-modify mode (HAM);
+                       0 = Extra Half Brite (EHB) if HAM=0 and BPU=6
+                       and DBLPF=0 then bitplane 6 controls an intensity
+                       reduction in the other five bitplanes)
+               DBLPF=Double playfield (PF1=odd PF2=even bitplanes)
+               COLOR=Composite video COLOR enable
+               GAUD=Genlock audio enable (muxed on BKGND pin
+                       during vertical blanking
+               LPEN =Light pen enable (reset on power up)
+               LACE =Interlace enable (reset on power up)
+               ERSY =External resync (HSYNC, VSYNC pads become
+                       inputs) (reset on power up)
+               PF2PRI=Playfield 2 (even planes) has priority over
+                       (appears in front of) playfield 1
+                       (odd planes).
+               PF2P=Playfield 2 priority code (with respect
+                       to sprites)
+               PF1P=Playfield 1 priority code (with respect
+                       to sprites)
+               PF2H=Playfield 2 horizontal scroll code
+               PF1H=Playfield 1 horizontal scroll code
+
+BPLCON3    106      W      D( E ) Bitplane control (enhanced features)
+
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/bplhmod.htm b/sources/official/saga-registers/bplhmod.htm new file mode 100755 index 0000000..5d981b1 --- /dev/null +++ b/sources/official/saga-registers/bplhmod.htm @@ -0,0 +1,13 @@ + + +
+
+BPLHMOD
+
+         This is the number (sign extended) that is added to the UHRES bitplane
+         pointer (BPLHPTL,H) every line, just like the other modulos.
+
+
+
+ + diff --git a/sources/official/saga-registers/bplhpth.htm b/sources/official/saga-registers/bplhpth.htm new file mode 100755 index 0000000..248a4dd --- /dev/null +++ b/sources/official/saga-registers/bplhpth.htm @@ -0,0 +1,12 @@ + + +
+
+BPLHPTR
+
+         32bit pointer to Chunky plane.
+         The Chunky plane can show 8bit/16Bit/15bit/24bit/32bit screens.
+
+
+ + diff --git a/sources/official/saga-registers/bplxdat.htm b/sources/official/saga-registers/bplxdat.htm new file mode 100755 index 0000000..4d9567a --- /dev/null +++ b/sources/official/saga-registers/bplxdat.htm @@ -0,0 +1,28 @@ + + +
+
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BPLxDAT    110      W       D     Bitplane x data (parallel-to-serial
+                                      convert)
+
+                 These registers receive the DMA data fetched from
+                 RAM by the bitplane address pointers described
+                 above.  They may also be written by either
+                 microprocessor.  They act as a six-word parallel-
+                 to-serial buffer for up to six memory bitplanes
+                 (x=1-6).  The parallel-to-serial conversion is
+                 triggered whenever bitplane #1 is written,
+                 indicating the completion of all bitplanes for
+                 that word (16 pixels).  The MSB is output first,
+                 and is, therefore, always on the left.
+
+
+
+ + diff --git a/sources/official/saga-registers/bplxmod.htm b/sources/official/saga-registers/bplxmod.htm new file mode 100755 index 0000000..986d97d --- /dev/null +++ b/sources/official/saga-registers/bplxmod.htm @@ -0,0 +1,24 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BPL1MOD    108      W       A     Bitplane modulo (odd planes)
+BPL2MOD    10A      W       A     Bitplane modulo (even planes)
+
+                 These registers contain the modulos for the odd
+                 and even bitplanes.  A modulo is a number that is
+                 automatically added to the address at the end of
+                 each line, so that the address then points to the
+                 start of the next line.
+                 Since they have separate modulos, the odd and even
+                 bitplanes may have sizes that are different from
+                 each other, as well as different from the display
+                 window size.
+
+
+ + diff --git a/sources/official/saga-registers/bplxpth.htm b/sources/official/saga-registers/bplxpth.htm new file mode 100755 index 0000000..6bc54b1 --- /dev/null +++ b/sources/official/saga-registers/bplxpth.htm @@ -0,0 +1,20 @@ + + +
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+BPLxPTH    0E0      W       A     Bitplane x pointer (high 3 bits)
+BPLxPTL    0E2      W       A     Bitplane x pointer (low 15 bits)
+
+                 This pair of registers contains the 18-bit pointer to
+                 the address of bitplane x (x=1,2,3,4,5,6) DMA data.
+                 This pointer must be reinitialized by the processor
+                 or copper to point to the beginning of bitplane data
+                 every vertical blank time.
+
+ + diff --git a/sources/official/saga-registers/chunkycol.htm b/sources/official/saga-registers/chunkycol.htm new file mode 100755 index 0000000..231376c --- /dev/null +++ b/sources/official/saga-registers/chunkycol.htm @@ -0,0 +1,29 @@ + + +
+
+CHUNKY COLOR PORT
+
+         This register allows direct setting of 256 Chunky colors registers
+
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 31-24 | index   | 8bit Colornumber                           |
+         | 23-16 | RED     | 8bit Red                                   |
+         | 15-08 | GREEN   | 8bit Green                                 |
+         | 07-00 | BLUE    | 8bit Blue                                  |
+         +-------+----------+-------------------------------------------+
+
+Example:
+
+ move.l #$00FF0000,$DFF388   -- set color0 = RED
+ move.l #$01FFFF00,$DFF388   -- set color1 = YELLOW
+
+Copper:
+ dc.w  $8388,$00FF,$0000     -- set color0 = RED
+
+
+ + diff --git a/sources/official/saga-registers/clxcon.htm b/sources/official/saga-registers/clxcon.htm new file mode 100755 index 0000000..00166e8 --- /dev/null +++ b/sources/official/saga-registers/clxcon.htm @@ -0,0 +1,51 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+CLXCON     098      W       D     Collision control
+
+                 This register controls which bitplanes are
+                 included (enabled) in collision detection and
+                 their required state if included.  It also controls
+                 the individual inclusion of odd-numbered sprites
+                 in the collision detection by logically OR-ing
+                 them with their corresponding even-numbered sprite.
+
+                 BIT#  FUNCTION  DESCRIPTION
+                 ----  --------  ------------------------------
+                 15    ENSP7     Enable sprite 7 (ORed with sprite 6)
+                 14    ENSP5     Enable sprite 5 (ORed with sprite 4)
+                 13    ENSP3     Enable sprite 3 (ORed with sprite 2)
+                 12    ENSP1     Enable sprite 1 (ORed with sprite 0)
+                 11    ENBP6     Enable bitplane 6 (match required
+                                 for collision)
+                 10    ENBP5     Enable bitplane 5 (match required
+                                 for collision)
+                 09    ENBP4     Enable bitplane 4 (match required
+                                 for collision)
+                 08    ENBP3     Enable bitplane 3 (match required
+                                 for collision)
+                 07    ENBP2     Enable bitplane 2 (match required
+                                 for collision)
+                 06    ENBP1     Enable bitplane 1 (match required
+                                 for collision)
+                 05    MVBP6     Match value for bitplane 6 collision
+                 04    MVBP5     Match value for bitplane 5 collision
+                 03    MVBP4     Match value for bitplane 4 collision
+                 02    MVBP3     Match value for bitplane 3 collision
+                 01    MVBP2     Match value for bitplane 2 collision
+                 00    MVBP1     Match value for bitplane 1 collision
+
+                       NOTE:  Disabled bitplanes cannot prevent
+                       collisions.  Therefore if all bitplanes are
+                       disabled, collisions will be continuous,
+                       regardless of the match values.
+
+
+
+ + diff --git a/sources/official/saga-registers/clxdat.htm b/sources/official/saga-registers/clxdat.htm new file mode 100755 index 0000000..e8642e6 --- /dev/null +++ b/sources/official/saga-registers/clxdat.htm @@ -0,0 +1,39 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+CLXDAT     00E      R       D     Collision data register (read and clear)
+
+                 This address reads (and clears) the collision
+                 detection register. The bit assignments are below.
+
+                 NOTE: Playfield 1 is all odd-numbered enabled
+                       bitplanes.  Playfield 2 is all even-numbered
+                       enabled bitplanes
+
+                 BIT#   COLLISIONS REGISTERED
+                 -----  --------------------------
+                 15     not used
+                 14     Sprite 4 (or 5) to sprite 6 (or 7)
+                 13     Sprite 2 (or 3) to sprite 6 (or 7)
+                 12     Sprite 2 (or 3) to sprite 4 (or 5)
+                 11     Sprite 0 (or 1) to sprite 6 (or 7)
+                 10     Sprite 0 (or 1) to sprite 4 (or 5)
+                 09     Sprite 0 (or 1) to sprite 2 (or 3)
+                 08     Playfield 2 to sprite 6 (or 7)
+                 07     Playfield 2 to sprite 4 (or 5)
+                 06     Playfield 2 to sprite 2 (or 3)
+                 05     Playfield 2 to sprite 0 (or 1)
+                 04     Playfield 1 to sprite 6 (or 7)
+                 03     Playfield 1 to sprite 4 (or 5)
+                 02     Playfield 1 to sprite 2 (or 3)
+                 01     Playfield 1 to sprite 0 (or 1)
+                 00     Playfield 1 to playfield 2
+
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/clxdatx.htm b/sources/official/saga-registers/clxdatx.htm new file mode 100755 index 0000000..d67a142 --- /dev/null +++ b/sources/official/saga-registers/clxdatx.htm @@ -0,0 +1,32 @@ + + +
+
+CLXDAT
+
+         This register contains detailed Sprite collision detection
+
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 15    | HIT15   | Sprite to SpriteF                          |
+         | 14    | HIT14   | Sprite to SpriteE                          |
+         | 13    | HIT13   | Sprite to SpriteD                          |
+         | 12    | HIT12   | Sprite to SpriteC                          |
+         | 11    | HIT11   | Sprite to SpriteB                          |
+         | 10    | HIT10   | Sprite to SpriteA                          |
+         | 09    | HIT9    | Sprite to Sprite9                          |
+         | 08    | HIT8    | Sprite to Sprite8                          |
+         | 07    | HIT7    | Sprite to Sprite7                          |
+         | 06    | HIT6    | Sprite to Sprite6                          |
+         | 05    | HIT5    | Sprite to Sprite5                          |
+         | 04    | HIT4    | Sprite to Sprite4                          |
+         | 03    | HIT3    | Sprite to Sprite3                          |
+         | 02    | HIT2    | Sprite to Sprite2                          |
+         | 01    | HIT1    | Sprite to Sprite1                          |
+         | 00    | HIT0    | Sprite to Sprite0                          |
+         +-------+----------+-------------------------------------------+
+
+ + diff --git a/sources/official/saga-registers/colorx.htm b/sources/official/saga-registers/colorx.htm new file mode 100755 index 0000000..82155e5 --- /dev/null +++ b/sources/official/saga-registers/colorx.htm @@ -0,0 +1,28 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+COLORxx    180      W       D     Color table xx
+
+                 There are 32 of these registers (xx=00-31) and they
+                 are sometimes collectively called the "color
+                 palette."  They contain 12-bit codes representing
+                 red, green, and blue colors for RGB systems.
+                 One of these registers at a time is selected
+                 (by the BPLxDAT serialized video code)
+                 for presentation at the RGB video output pins.
+                 The table below shows the color register bit usage.
+
+                 BIT# 15,14,13,12,11,10,09,08,07,06,05,04,03,02,01,00
+                      ----------- ----------- ----------- -----------
+                 RGB  X  X  X  X  R3 R2 R1 R0 G3 G2 G1 G0 B3 B2 B1 B0
+
+                 B=blue, G=green, R=red,
+
+
+ + diff --git a/sources/official/saga-registers/cop1lch.htm b/sources/official/saga-registers/cop1lch.htm new file mode 100755 index 0000000..32cd463 --- /dev/null +++ b/sources/official/saga-registers/cop1lch.htm @@ -0,0 +1,22 @@ + + +
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+COP1LCH    080      W      A( E ) Copper first location register
+                                      (high 3 bits, high 5 bits if ECS)
+COP1LCL    082      W       A     Copper first location register
+                                      (low 15 bits)
+COP2LCH    084      W      A( E ) Copper second location register
+                                      (high 3 bits, high 5 bits if ECS)
+COP2LCL    086      W       A     Copper second location register
+                                      (low 15 bits)
+
+                 These registers contain the jump addresses
+                 described above.
+
+
+ + diff --git a/sources/official/saga-registers/cop2lch.htm b/sources/official/saga-registers/cop2lch.htm new file mode 100755 index 0000000..8476265 --- /dev/null +++ b/sources/official/saga-registers/cop2lch.htm @@ -0,0 +1,24 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+COP1LCH    080      W      A( E ) Copper first location register
+                                      (high 3 bits, high 5 bits if ECS)
+COP1LCL    082      W       A     Copper first location register
+                                      (low 15 bits)
+COP2LCH    084      W      A( E ) Copper second location register
+                                      (high 3 bits, high 5 bits if ECS)
+COP2LCL    086      W       A     Copper second location register
+                                      (low 15 bits)
+
+                 These registers contain the jump addresses
+                 described above.
+
+
+
+ + diff --git a/sources/official/saga-registers/copcon.htm b/sources/official/saga-registers/copcon.htm new file mode 100755 index 0000000..86b9a17 --- /dev/null +++ b/sources/official/saga-registers/copcon.htm @@ -0,0 +1,22 @@ + + +
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+COPCON     02E      W      A( E ) Copper control register
+
+                 This is a 1-bit register that when set true, allows
+                 the Copper to access the blitter hardware. This
+                 bit is cleared by power-on reset, so that the Copper
+                 cannot access the blitter hardware. See Appendix C
+                 for ECS operation.
+
+                 BIT#    NAME      FUNCTION
+                 ----    -------   ------------------
+                  01     CDANG     Copper danger mode. Allows Copper
+                                   access to blitter if true.
+
+ + diff --git a/sources/official/saga-registers/copins.htm b/sources/official/saga-registers/copins.htm new file mode 100755 index 0000000..49bcba4 --- /dev/null +++ b/sources/official/saga-registers/copins.htm @@ -0,0 +1,100 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+COPINS     08C      W       A     Copper instruction fetch identify
+
+                 This is a dummy address that is generated by the
+                 Copper whenever it is loading instructions into
+                 its own instruction register. This actually occurs
+                 every Copper cycle except for the second (IR2)
+                 cycle of the MOVE instruction. The three types
+                 of instructions are shown below.
+
+                 MOVE    Move immediate to destination.
+                 WAIT    Wait until beam counter is equal to, or
+                         greater than.  (keeps Copper off of bus
+                         until beam position has been reached).
+                 SKIP    Skip if beam counter is equal to or greater
+                         than (skips following MOVE instruction unless
+                         beam position has been reached).
+
+                           MOVE         WAIT UNTIL      SKIP IF
+                         --------       -----------    ------------
+                 BIT#    IR1   IR2      IR1    IR2     IR1     IR2
+                 ----    ----  ----     ----   ----    ----    ----
+                 15       X    RD15     VP7    BFD *   VP7    BFD *
+                 14       X    RD14     VP6    VE6     VP6    VE6
+                 13       X    RD13     VP5    VE5     VP5    VE5
+                 12       X    RD12     VP4    VE4     VP4    VE4
+                 11       X    RD11     VP3    VE3     VP3    VE3
+                 10       X    RD10     VP2    VE2     VP2    VE2
+                 09       X    RD09     VP1    VE1     VP1    VE1
+                 08      DA8   RD08     VP0    VE0     VP0    VE0
+                 07      DA7   RD07     HP8    HE8     HP8    HE8
+                 06      DA6   RD06     HP7    HE7     HP7    HE7
+                 05      DA5   RD05     HP6    HE6     HP6    HE6
+                 04      DA4   RD04     HP5    HE5     HP5    HE5
+                 03      DA3   RD03     HP4    HE4     HP4    HE4
+                 02      DA2   RD02     HP3    HE3     HP3    HE3
+                 01      DA1   RD01     HP2    HE2     HP2    HE2
+                 00       0    RD00      1      0       1      1
+
+                 IR1=First instruction register
+                 IR2=Second instruction register
+                 DA =Destination address for MOVE instruction.  Fetched
+                     during IR1 time, used during IR2 time on RGA bus.
+                 RD =RAM data moved by MOVE instruction at IR2 time
+                     directly from RAM to the address given by the
+                     DA field.
+                 VP =Vertical beam position comparison bit.
+                 HP =Horizontal beam position comparison bit.
+                 VE =Enable comparison (mask bit).
+                 HE =Enable comparison (mask bit).
+
+                * NOTE BFD=Blitter finished disable. When this bit
+                           is true, the Blitter Finished flag will
+                           have no effect on the Copper. When this
+                           bit is zero, the Blitter Finished flag
+                           must be true (in addition to the rest of
+                           the bit comparisons) before the Copper
+                           can exit from its wait state or skip
+                           over an instruction.  Note that the V7
+                           comparison cannot be masked.
+
+                 The Copper is basically a two-cycle machine that
+                 requests the bus only during odd memory cycles
+                 (4 memory cycles per instruction).  This prevents
+                 collisions with display, audio, disk, refresh, and
+                 sprites, all of which use only even cycles.  It
+                 therefore needs (and has) priority over only the
+                 blitter and microprocessor.
+
+                 There are only three types of instructions:
+                 MOVE immediate, WAIT until, and SKIP if.  All
+                 instructions (except for WAIT) require two bus
+                 cycles (and two instruction words).  Since only
+                 the odd bus cycles are requested, four memory
+                 cycle times are required per instruction
+                 (memory cycles are 280 ns.)
+
+                 There are two indirect jump registers,  COP1LC  and
+                  COP2LC .  These are 18-bit pointer registers whose
+                 contents are used to modify the program counter for
+                 initialization or jumps.  They are transferred to
+                 the program counter whenever strobe addresses
+                  COPJMP1  or  COPJMP2  are written.  In addition,
+                  COP1LC  is automatically used at the beginning of
+                 each vertical blank time.
+
+                 It is important that one of the jump registers be
+                 initialized and its jump strobe address hit after
+                 power-up but before Copper DMA is initialized.
+                 This insures a determined startup address and state.
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/copjmp.htm b/sources/official/saga-registers/copjmp.htm new file mode 100755 index 0000000..3fae975 --- /dev/null +++ b/sources/official/saga-registers/copjmp.htm @@ -0,0 +1,21 @@ + + +
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+COPJMP1    088      S       A     Copper restart at first location
+COPJMP2    08A      S       A     Copper restart at second location
+
+                 These addresses are strobe addresses.  When written
+                 to, they cause the Copper to jump indirect using
+                 the address contained in the first or second
+                 location registers described below. The Copper
+                 itself can write to these addresses, causing its
+                 own jump indirect.
+
+ + + + diff --git a/sources/official/saga-registers/ddfstrt.htm b/sources/official/saga-registers/ddfstrt.htm new file mode 100755 index 0000000..707c22a --- /dev/null +++ b/sources/official/saga-registers/ddfstrt.htm @@ -0,0 +1,48 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+DDFSTOP    094      W       A    Display data fetch stop (horiz. position)
+DDFSTRT    092      W       A    Display data fetch start (horiz. position)
+
+                 These registers control the horizontal timing of the
+                 beginning and end of the bitplane DMA display data
+                 fetch.  The vertical bitplane DMA timing is identical
+                 to the display windows described above.
+                 The bitplane modulos are dependent on the bitplane
+                 horizontal size and on this data-fetch window size.
+
+                 Register bit assignment
+                 -------------------------
+                 BIT#  15,14,13,12,11,10,09,08,07,06,05,04,03,02,01,00
+                       -----------------------------------------------
+                 USE    X  X  X  X  X  X  X  X H8 H7 H6 H5 H4 H3  X  X
+
+                  (Always set X bits to 0 to maintain upward compatibility)
+
+                 The tables below show the start and stop timing for
+                 different register contents.
+
+                    DDFSTRT (left edge of display data fetch)
+                    ----------------------------------------
+                         PURPOSE        H8,H7,H6,H5,H4
+                     -----------------  --------------
+                     Extra wide (max) *  0  0  1  0  1
+                     Wide                0  0  1  1  0
+                     Normal              0  0  1  1  1
+                     Narrow              0  1  0  0  0
+
+                     DDFSTOP (right edge of display data fetch)
+                     ------------------------------------------
+                          PURPOSE        H8,H7,H6,H5,H4
+                     ------------------  --------------
+                     Narrow               1  1  0  0  1
+                     Normal               1  1  0  1  0
+                     Wide (max)           1  1  0  1  1
+
+ + diff --git a/sources/official/saga-registers/deniseid.htm b/sources/official/saga-registers/deniseid.htm new file mode 100755 index 0000000..2c3f3fc --- /dev/null +++ b/sources/official/saga-registers/deniseid.htm @@ -0,0 +1,14 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+DENISEID   07C      R      D( E ) Chip revision level for Denise
+                                      (video out chip)
+
+
+ + diff --git a/sources/official/saga-registers/diwhigh.htm b/sources/official/saga-registers/diwhigh.htm new file mode 100755 index 0000000..9a3a39d --- /dev/null +++ b/sources/official/saga-registers/diwhigh.htm @@ -0,0 +1,36 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+DIWHIGH    1E4      W     A,D( E ) Display window -  upper bits for
+                                       start, stop
+
+DIWSTOP    090      W       A      Display window stop (lower right
+                                       vertical-horizontal position)
+DIWSTRT    08E      W       A      Display window start (upper left
+                                       vertical-horizontal position)
+
+                 These registers control display window size and position
+                 by locating the upper left and lower right corners.
+
+                 BIT# 15,14,13,12,11,10,09,08,07,06,05,04,03,02,01,00
+                      -----------------------------------------------
+                 USE  V7 V6 V5 V4 V3 V2 V1 V0 H7 H6 H5 H4 H3 H2 H1 H0
+
+                 DIWSTRT is vertically restricted to the upper 2/3
+                 of the display (V8=0) and horizontally restricted to
+                 the left 3/4 of the display (H8=0).
+
+                 DIWSTOP is vertically restricted to the lower 1/2
+                 of the display (V8=/=V7) and horizontally restricted
+                 to the right 1/4 of the display (H8=1).
+
+
+
+
+ + diff --git a/sources/official/saga-registers/diwstrt.htm b/sources/official/saga-registers/diwstrt.htm new file mode 100755 index 0000000..5a7cfbe --- /dev/null +++ b/sources/official/saga-registers/diwstrt.htm @@ -0,0 +1,34 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+DIWHIGH    1E4      W     A,D( E ) Display window -  upper bits for
+                                       start, stop
+
+DIWSTOP    090      W       A      Display window stop (lower right
+                                       vertical-horizontal position)
+DIWSTRT    08E      W       A      Display window start (upper left
+                                       vertical-horizontal position)
+
+                 These registers control display window size and position
+                 by locating the upper left and lower right corners.
+
+                 BIT# 15,14,13,12,11,10,09,08,07,06,05,04,03,02,01,00
+                      -----------------------------------------------
+                 USE  V7 V6 V5 V4 V3 V2 V1 V0 H7 H6 H5 H4 H3 H2 H1 H0
+
+                 DIWSTRT is vertically restricted to the upper 2/3
+                 of the display (V8=0) and horizontally restricted to
+                 the left 3/4 of the display (H8=0).
+
+                 DIWSTOP is vertically restricted to the lower 1/2
+                 of the display (V8=/=V7) and horizontally restricted
+                 to the right 1/4 of the display (H8=1).
+
+
+ + diff --git a/sources/official/saga-registers/dmacon2.htm b/sources/official/saga-registers/dmacon2.htm new file mode 100755 index 0000000..72daf32 --- /dev/null +++ b/sources/official/saga-registers/dmacon2.htm @@ -0,0 +1,32 @@ + + +
+
+DMACON2
+
+         DMA Channel control 2  - For Audio channels and Ethernet
+
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 15    |         | SET/CLR                                    |
+         | 14    |         |                                            |
+         | 13    | ETH     | Ethernet                                   |
+         | 12    |         |                                            |
+         | 11    | AUD15   | Audio channel 15                           |
+         | 10    | AUD14   | Audio channel 14                           |
+         | 09    | AUD13   | Audio channel 13                           |
+         | 08    | AUD12   | Audio channel 12                           |
+         | 07    | AUD11   | Audio channel 11                           |
+         | 06    | AUD10   | Audio channel 10                           |
+         | 05    | AUD9    | Audio channel 9                            |
+         | 04    | AUD8    | Audio channel 8                            |
+         | 03    | AUD7    | Audio channel 7                            |
+         | 02    | AUD6    | Audio channel 6                            |
+         | 01    | AUD5    | Audio channel 5                            |
+         | 00    | AUD4    | Audio channel 4                            |
+         +-------+----------+-------------------------------------------+
+
+ + diff --git a/sources/official/saga-registers/dmaconr.htm b/sources/official/saga-registers/dmaconr.htm new file mode 100755 index 0000000..68fff4c --- /dev/null +++ b/sources/official/saga-registers/dmaconr.htm @@ -0,0 +1,45 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+DMACON     096      W     A D P   DMA control write (clear or set)
+DMACONR    002      R     A   P   DMA control (and blitter status) read
+
+                 This register controls all of the DMA channels and
+                 contains blitter DMA status bits.
+
+                 BIT#  FUNCTION    DESCRIPTION
+                 ----  ---------   -----------------------------------
+                 15    SET/CLR     Set/clear control bit. Determines
+                                   if bits written with a 1 get set or
+                                   cleared.  Bits written with a zero
+                                   are unchanged.
+                 14    BBUSY       Blitter busy status bit (read only)
+                 13    BZERO       Blitter logic  zero status bit
+                                   (read only).
+                 12    X
+                 11    X
+                 10    BLTPRI      Blitter DMA priority
+                                   (over CPU micro) (also called
+                                   "blitter nasty") (disables /BLS
+                                   pin, preventing micro from
+                                   stealing any bus cycles while
+                                   blitter DMA is running).
+                 09    DMAEN       Enable all DMA below
+                 08    BPLEN       Bitplane DMA enable
+                 07    COPEN       Copper DMA enable
+                 06    BLTEN       Blitter DMA enable
+                 05    SPREN       Sprite DMA enable
+                 04    DSKEN       Disk DMA enable
+                 03    AUD3EN      Audio channel 3 DMA enable
+                 02    AUD2EN      Audio channel 2 DMA enable
+                 01    AUD1EN      Audio channel 1 DMA enable
+                 00    AUD0EN      Audio channel 0 DMA enable
+
+
+ + diff --git a/sources/official/saga-registers/dskbytr.htm b/sources/official/saga-registers/dskbytr.htm new file mode 100755 index 0000000..b6e3578 --- /dev/null +++ b/sources/official/saga-registers/dskbytr.htm @@ -0,0 +1,30 @@ + + +
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+DSKBYTR    01A      R       P     Disk data byte and status read
+
+                 This register is the disk-microprocessor data
+                 buffer.  Data from the disk (in read mode) is
+                 loaded into this register one byte at a time, and
+                 bit 15 (DSKBYT) is set true.
+
+                 BIT#
+                 ----  ---------  --------------------------------
+                 15    DSKBYT     Disk byte ready (reset on read)
+                 14    DMAON      Mirror of bit 15 (DMAEN) in  DSKLEN ,
+                                  ANDed with Bit09 (DMAEN) in  DMACON 
+                 13    DISKWRITE  Mirror of bit 14 (WRITE) in  DSKLEN 
+                 12    WORDEQUAL  This bit true only while the
+                                   DSKSYNC  register equals the data
+                                  from disk.
+                 11-08  X         Not used
+                 07-00 DATA       Disk byte data
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/dskdatr.htm b/sources/official/saga-registers/dskdatr.htm new file mode 100755 index 0000000..b42e96c --- /dev/null +++ b/sources/official/saga-registers/dskdatr.htm @@ -0,0 +1,24 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+DSKDAT     026      W       P     Disk DMA data write
+DSKDATR    008      ER      P     Disk DMA data read (early read dummy
+                                      address)
+
+                 This register is the disk DMA data buffer. It
+                 contains two bytes of data that are either sent
+                 (written) to or received (read) from the disk.
+                 The write mode is enabled by bit 14 of the LENGTH
+                 register. The DMA controller automatically
+                 transfers data to or from this register and RAM,
+                 and when the DMA data is finished (length=0) it
+                 causes a disk block interrupt. See interrupts below.
+
+
+ + diff --git a/sources/official/saga-registers/dsklen.htm b/sources/official/saga-registers/dsklen.htm new file mode 100755 index 0000000..b740dbc --- /dev/null +++ b/sources/official/saga-registers/dsklen.htm @@ -0,0 +1,24 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+DSKLEN     024      W       P     Disk length
+
+                 This register contains the length (number of words)
+                 of disk DMA data. It also contains two control
+                 bits, a DMA enable bit, and a DMA direction
+                 (read/write) bit.
+
+                 BIT#  FUNCTION      DESCRIPTION
+                 ----  -----------   --------------------------------
+                 15    DMAEN         Disk DMA enable
+                 14    WRITE         Disk write (RAM to disk) if 1
+                 13-0  LENGTH        Length (# of words) of DMA data.
+
+ + + diff --git a/sources/official/saga-registers/dskpth.htm b/sources/official/saga-registers/dskpth.htm new file mode 100755 index 0000000..7e2ea37 --- /dev/null +++ b/sources/official/saga-registers/dskpth.htm @@ -0,0 +1,18 @@ + + +
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+DSKPTH     020      W      A( E ) Disk pointer (high 3 bits,
+                                      high 5 bits if ECS)
+DSKPTL     022      W       A     Disk pointer (low 15 bits)
+
+                 This pair of registers contains the 18-bit
+                 address of disk DMA data. These address registers
+                 must be initialized by the processor or Copper
+                 before disk DMA is enabled.
+
+ + diff --git a/sources/official/saga-registers/dsksync.htm b/sources/official/saga-registers/dsksync.htm new file mode 100755 index 0000000..81ea9a8 --- /dev/null +++ b/sources/official/saga-registers/dsksync.htm @@ -0,0 +1,15 @@ + + +
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+DSKSYNC    07E      W       P     Disk sync register
+
+                 holds the match code for disk read synchronization.
+                 See  ADKCON  bit 10.
+
+
+ + diff --git a/sources/official/saga-registers/fmode.htm b/sources/official/saga-registers/fmode.htm new file mode 100755 index 0000000..5bcb6b1 --- /dev/null +++ b/sources/official/saga-registers/fmode.htm @@ -0,0 +1,27 @@ + + +
+
+FMODE
+
+         This register controls the fetch mechanism for different
+         types of Chip RAM accesses:
+
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 15    | SSCAN2   | Global enable for sprite scan-doubling.   |
+         | 14    | BSCAN2   | Enables the use of 2nd P/F modulus on an  |
+         |       |          | alternate line basis to support bitplane  |
+         |       |          | scan-doubling.                            |
+         | 13-05 | Unused   |                                           |
+         | 04    | SAGA     | Enable SAGA New features                  |
+         | 03    | SPAGEM   | Sprite page mode (double CAS)             |
+         | 02    | SPR32    | Sprite 32 bit wide mode                   |
+         | 01    | BPAGEM   | Bitplane Page Mode (double CAS)           |
+         | 00    | BLP32    | Bitplane 32 bit wide mode                 |
+         +-------+----------+-------------------------------------------+
+
+ + diff --git a/sources/official/saga-registers/gfxmode.htm b/sources/official/saga-registers/gfxmode.htm new file mode 100755 index 0000000..f4272a0 --- /dev/null +++ b/sources/official/saga-registers/gfxmode.htm @@ -0,0 +1,54 @@ + + +
+
+GFXMODE
+         16bit register selecting the screen size and the pixelformat for the Chunky plane.
+         
+
+       +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                             |
+         +-------+----------+-----------------------------------------+
+         | 15.08 | Resolution  | $00                                  |
+         |       |               $01 = 320x200     60Hz  28Mhz x2 x2  |
+         |       |               $02 = 320x240     60Hz  28Mhz x2 x2  |
+         |       |               $03 = 320x256     60Hz  28Mhz x2 x2  |
+         |       |               $04 = 640x400     60Hz  28Mhz        |
+         |       |               $05 = 640x480     60Hz  28MHz        |
+         |       |               $06 = 640x512     50Hz  28MHz        |
+         |       |               $07 = 960x540     60Hz  42Mhz        |
+         |       |               $08 = 480x270     60Hz  42Mhz x2 x2  |
+         |       |               $09 = 304x224     60Hz  28Mhz x2 x2  |
+         |       |               $0A = 1280x720    50Hz  85Mhz        |
+         |       |               $0B = 640x360     50Hz  85Mhz x2 x2  |
+         |       |               $0C = 800x600     60Hz  42MHz        |
+         |       |               $0D = 1024x768    60Hz  85MHz        |
+         |       |               $0E = 720x576     50Hz  28Mhz        |
+         |       |               $0F = 848x480     60Hz  42MHz        |
+         |       |               $10 = 640x200     60Hz  28Mhz        |
+         |       |               $11 = 1920x1080   24Hz  85Mhz        |
+         |       |               $12 = 1280x1024   50Hz  85Mhz        |
+         |       |               $13 = 1280x800    60Hz  84Mhz        |
+         |       |               $14 = 1440x900    50Hz  85Mhz        |
+         |       |               $15 = 720x405     50Hz  28Mhz        |
+         +-------+----------+-----------------------------------------+ 
+         | 07.00 | Pixelformat | $00                                  |
+         |       |               $01 = 8bit CHUNKY (indexed)          |
+         |       |               $02 = 16bit R5G6B5                   |
+         |       |               $03 = 15bit 1R5G5B5                  |
+         |       |               $04 = 24bit R8G8B8                   |
+         |       |               $05 = 32bit A8R8G8B8                 |
+         |       |               $06 = YUV888                         |
+         |       |               $0E = YUV444                         |
+         |       |               $07 =                                |
+         |       |               $08 = PLANAR 1BIT ATARI              |
+         |       |               $09 = PLANAR 2BIT ATARI              |
+         |       |               $0A = PLANAR 4BIT ATARI              |
+         |       |               $0B = PLANAR 8BIT ATARI              |
+         +-------+----------+-----------------------------------------+ 
+
+	 
+
+ + + diff --git a/sources/official/saga-registers/hbstrt.htm b/sources/official/saga-registers/hbstrt.htm new file mode 100755 index 0000000..167deda --- /dev/null +++ b/sources/official/saga-registers/hbstrt.htm @@ -0,0 +1,21 @@ + + +
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+HBSTOP     1C6      W      A( E ) Horizontal line position for HBLANK stop
+HBSTRT     1C4      W      A( E ) Horizontal line position for HBLANK start
+HCENTER    1E2      W      A( E ) Horizontal position for Vsync on interlace
+HSSTOP     1C2      W      A( E ) Horizontal line position for HSYNC stop
+HSSTRT     1DE      W      A( E ) Horizontal sync start (VARHSY)
+HTOTAL     1C0      W      A( E ) Highest number count, horiz. line
+                                     (VARBEAMEN=1)
+
+
+
+ + diff --git a/sources/official/saga-registers/hcenter.htm b/sources/official/saga-registers/hcenter.htm new file mode 100755 index 0000000..64fc0cc --- /dev/null +++ b/sources/official/saga-registers/hcenter.htm @@ -0,0 +1,23 @@ + + +
+
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+HBSTOP     1C6      W      A( E ) Horizontal line position for HBLANK stop
+HBSTRT     1C4      W      A( E ) Horizontal line position for HBLANK start
+HCENTER    1E2      W      A( E ) Horizontal position for Vsync on interlace
+HSSTOP     1C2      W      A( E ) Horizontal line position for HSYNC stop
+HSSTRT     1DE      W      A( E ) Horizontal sync start (VARHSY)
+HTOTAL     1C0      W      A( E ) Highest number count, horiz. line
+                                     (VARBEAMEN=1)
+
+
+
+
+ + diff --git a/sources/official/saga-registers/hsstop.htm b/sources/official/saga-registers/hsstop.htm new file mode 100755 index 0000000..167deda --- /dev/null +++ b/sources/official/saga-registers/hsstop.htm @@ -0,0 +1,21 @@ + + +
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+HBSTOP     1C6      W      A( E ) Horizontal line position for HBLANK stop
+HBSTRT     1C4      W      A( E ) Horizontal line position for HBLANK start
+HCENTER    1E2      W      A( E ) Horizontal position for Vsync on interlace
+HSSTOP     1C2      W      A( E ) Horizontal line position for HSYNC stop
+HSSTRT     1DE      W      A( E ) Horizontal sync start (VARHSY)
+HTOTAL     1C0      W      A( E ) Highest number count, horiz. line
+                                     (VARBEAMEN=1)
+
+
+
+ + diff --git a/sources/official/saga-registers/hsstrt.htm b/sources/official/saga-registers/hsstrt.htm new file mode 100755 index 0000000..ca4aa3f --- /dev/null +++ b/sources/official/saga-registers/hsstrt.htm @@ -0,0 +1,19 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+HBSTOP     1C6      W      A( E ) Horizontal line position for HBLANK stop
+HBSTRT     1C4      W      A( E ) Horizontal line position for HBLANK start
+HCENTER    1E2      W      A( E ) Horizontal position for Vsync on interlace
+HSSTOP     1C2      W      A( E ) Horizontal line position for HSYNC stop
+HSSTRT     1DE      W      A( E ) Horizontal sync start (VARHSY)
+HTOTAL     1C0      W      A( E ) Highest number count, horiz. line
+                                     (VARBEAMEN=1)
+
+
+ + diff --git a/sources/official/saga-registers/htotal.htm b/sources/official/saga-registers/htotal.htm new file mode 100755 index 0000000..8e67ff7 --- /dev/null +++ b/sources/official/saga-registers/htotal.htm @@ -0,0 +1,20 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+HBSTOP     1C6      W      A( E ) Horizontal line position for HBLANK stop
+HBSTRT     1C4      W      A( E ) Horizontal line position for HBLANK start
+HCENTER    1E2      W      A( E ) Horizontal position for Vsync on interlace
+HSSTOP     1C2      W      A( E ) Horizontal line position for HSYNC stop
+HSSTRT     1DE      W      A( E ) Horizontal sync start (VARHSY)
+HTOTAL     1C0      W      A( E ) Highest number count, horiz. line
+                                     (VARBEAMEN=1)
+
+
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/index.htm b/sources/official/saga-registers/index.htm new file mode 100755 index 0000000..48ebcdf --- /dev/null +++ b/sources/official/saga-registers/index.htm @@ -0,0 +1,3386 @@ + + + Hardware SAGA Chipset Amiga Development + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AddressNameAccessOCS ECS AGA SAGADescription
DFF000BLTDDATER* * * *Blitter dest. early read (dummy address)
DFF002DMACONRR* * * *Dma control (and blitter status) read
DFF004VPOSRR* * * *Read vertical most sig. bits (and frame flop)
DFF006VHPOSRR* * * *Read vert and horiz position of beam
DFF008DSKDATRER* * * *Disk data early read (dummy address)
DFF00AJOY0DATR* * * *Joystick-mouse 0 data (vert, horiz)
DFF00CJOY1DATR* * * *Joystick-mouse 1 data (vert, horiz)
DFF00ECLXDATR* * * *Collision data reg. (read and clear)
DFF010ADKCONRR* * * *Audio,disk control register read
DFF012POT0DATR* * * *Pot counter data left pair (vert, horiz)
DFF014POT1DATR* * * *Pot counter data right pair (vert, horiz)
DFF016POTINPR* * * *Pot pin data read
DFF018SERDATRR* * * *Serial port data and status read
DFF01ADSKBYTRR* * * *Disk data byte and status read
DFF01CINTENARR* * * *Interrupt enable bits read
DFF01EINTREQRR* * * *Interrupt request bits read
DFF020DSKPTHW* * * *Disk pointer (high 5 bits, was 3 bits)
DFF022DSKPTLW* * * *Disk pointer (low 15 bits)
DFF024DSKLENW** * *Disk length
DFF026DSKDATW* * * *Disk DMA data write
DFF028REFPTRW* * * *Refresh pointer
DFF02AVPOSWW* * * *Write vert most sig. bits (and frame flop)
DFF02CVHPOSWW* * * *Write vert and horiz pos of beam
DFF02ECOPCONW* * * *Coprocessor control
DFF030SERDATW* * * *Serial port data and stop bits write
DFF032SERPERW* * * *Serial port period and control
DFF034POTGOW* * * *Pot count start,pot pin drive enable data
DFF036JOYTESTW* * * *Write to all 4 joystick-mouse counters at once
DFF038STREQUS* * * *Strobe for horiz sync with VB and EQU
DFF03ASTRVBLS* * * *Strobe for horiz sync with VB (vert blank)
DFF03CSTRHORS* * * *Strobe for horiz sync
DFF03ESTRLONGS* * * *Strobe for identification of long horiz line
DFF040BLTCON0W* * * *Blitter control register 0
DFF042BLTCON1W* * * *Blitter control register 1
DFF044BLTAFWMW* * * *Blitter first word mask for source A
DFF046BLTALWMW* * * *Blitter last word mask for source A
DFF048BLTCPTHW* * * *Blitter pointer to source C (high 5 bits, was 3 bits)
DFF04ABLTCPTLW* * * *Blitter pointer to source C (low 15 bits)
DFF04CBLTBPTHW* * * *Blitter pointer to source B (high 5 bits, was 3 bits)
DFF04EBLTBPTLW* * * *Blitter pointer to source B (low 15 bits)
DFF050BLTAPTHW* * * *Blitter pointer to source A (high 5 bits, was 3 bits)
DFF052BLTAPTLW* * * *Blitter pointer to source A (low 15 bits)
DFF054BLTDPTHW* * * *Blitter pointer to dest D (high 5 bits, was 3 bits)
DFF056BLTDPTLW* * * *Blitter pointer to dest D (low 15 bits)
DFF058BLTSIZEW* * * *Blitter start and size (win/width,height)
DFF05ABLTCON0LW * * *Blitter control 0, lower 8 bits (minterms)
DFF05CBLTSIZVW * * *Blitter V size (for 15 bit vertical size)
DFF05EBLTSIZHW * * *Blitter H size and start (for 11 bit H size)
DFF060BLTCMODW* * * *Blitter modulo for source C
DFF062BLTBMODW* * * *Blitter modulo for source B
DFF064BLTAMODW* * * *Blitter modulo for source A
DFF066BLTDMODW* * * *Blitter modulo for dest D
DFF070BLTCDATW* * * *Blitter source C data register
DFF072BLTBDATW* * * *Blitter source B data register
DFF074BLTADATW* * * *Blitter source A data register
DFF078SPRHDATW * * *Ext. logic UHRES sprite pointer and data identifier
DFF07ABPLHDATW * * *Ext. logic UHRES bit plane identifier
DFF07CDENISEIDR * * *Chip revision level for Denise/Lisa (video out chip)
DFF07EDSKSYNCW* * * *Disk sync pattern reg for disk read
DFF080COP1LCHW* * * *Coprocessor 1st location (high 5 bits,was 3 bits)
DFF082COP1LCLW* * * *Coprocessor 1st location (low 15 bits)
DFF084COP2LCHW* * * *Coprocessor 2nd location(high 5 bits,was 3 bits)
DFF086COP2LCLW* * * *Coprocessor 2nd location (low 15 bits)
DFF088COPJMP1S* * * *Coprocessor restart at 1st location
DFF08ACOPJMP2S* * * *Coprocessor restart at 2nd location
DFF08CCOPINSS* * * *Coprocessor inst fetch identify
DFF08EDIWSTRTW* * * *Display window start (upper left vert,horiz pos)
DFF090DIWSTOPW* * * *Display window stop (lower right vert,horiz pos)
DFF092DDFSTRTW* * * *Display bit plane data fetch start,horiz pos
DFF094DDFSTOPW* * * *Display bit plane data fetch stop,horiz pos
DFF096DMACONW* * * *DMA control write (clear or set)
DFF098CLXCONW* * * *Collision control
DFF09AINTENAW* * * *Interrupt enable bits (clear or set bits)
DFF09CINTREQW* * * *Interrupt request bits (clear or set bits)
DFF09EADKCONW* * * *Audio,disk,UART control
DFF0A0AUD0LCHW* * * *Audio channel 0 location (high 5 bits was 3 bits)
DFF0A2AUD0LCLW* * * *Audio channel 0 location (low 15 bits)
DFF0A4AUD0LENW* * * *Audio channel 0 length
DFF0A6AUD0PERW* * * *Audio channel 0 period
DFF0A8AUD0VOLW* * * *Audio channel 0 volume
DFF0AAAUD0DATW* * * *Audio channel 0 data
DFF0B0AUD1LCHW* * * *Audio channel 1 location (high 5 bits was 3 bits)
DFF0B2AUD1LCLW* * * *Audio channel 1 location (low 15 bits)
DFF0B4AUD1LENW* * * *Audio channel 1 length
DFF0B6AUD1PERW* * * *Audio channel 1 period
DFF0B8AUD1VOLW* * * *Audio channel 1 volume
DFF0BAAUD1DATW* * * *Audio channel 1 data
DFF0C0AUD2LCHW* * * *Audio channel 2 location (high 5 bits was 3 bits)
DFF0C2AUD2LCLW* * * *Audio channel 2 location (low 15 bits)
DFF0C4AUD2LENW* * * *Audio channel 2 length
DFF0C6AUD2PERW* * * *Audio channel 2 period
DFF0C8AUD2VOLW* * * *Audio channel 2 volume
DFF0CAAUD2DATW* * * *Audio channel 2 data
DFF0D0AUD3LCHW* * * *Audio channel 3 location (high 5 bits was 3 bits)
DFF0D2AUD3LCLW* * * *Audio channel 3 location (low 15 bits)
DFF0D4AUD3LENW* * * *Audio channel 3 length
DFF0D6AUD3PERW* * * *Audio channel 3 period
DFF0D8AUD3VOLW* * * *Audio channel 3 volume
DFF0DAAUD3DATW* * * *Audio channel 3 data
 
DFF0E0BPL1PTHW* * * *Bitplane pointer 1 (high 5 bits was 3 bits)
DFF0E2BPL1PTLW* * * *Bitplane pointer 1 (low 15 bits)
DFF0E4BPL2PTHW* * * *Bitplane pointer 2 (high 5 bits was 3 bits)
DFF0E6BPL2PTLW* * * *Bitplane pointer 2 (low 15 bits)
DFF0E8BPL3PTHW* * * *Bitplane pointer 3 (high 5 bits was 3 bits)
DFF0EABPL3PTLW* * * *Bitplane pointer 3 (low 15 bits)
DFF0ECBPL4PTHW* * * *Bitplane pointer 4 (high 5 bits was 3 bits)
DFF0EEBPL4PTLW* * * *Bitplane pointer 4 (low 15 bits)
DFF0F0BPL5PTHW* * * *Bitplane pointer 5 (high 5 bits was 3 bits)
DFF0F2BPL5PTLW* * * *Bitplane pointer 5 (low 15 bits)
DFF0F4BPL6PTHW* * * *Bitplane pointer 6 (high 5 bits was 3 bits)
DFF0F6BPL6PTLW* * * *Bitplane pointer 6 (low 15 bits)
DFF0F8BPL7PTHW * *Bitplane pointer 7 (high 5 bits was 3 bits)
DFF0FABPL7PTLW * *Bitplane pointer 7 (low 15 bits)
DFF0FCBPL8PTHW * *Bitplane pointer 8 (high 5 bits was 3 bits)
DFF0FEBPL8PTLW * *Bitplane pointer 8 (low 15 bits)
DFF100BPLCON0W* * * *Bitplane control (miscellaneous control bits)
DFF102BPLCON1W* * * *Bitplane control (scroll value)
DFF104BPLCON2W* * * *Bitplane control (video priority control)
DFF106BPLCON3W* * * *Bitplane control (enhanced features)
DFF108BPL1MODW* * * *Bitplane modulo (odd planes)
DFF10ABPL2MODW* * * *Bitplane modulo (even planes)
DFF10CBPLCON4W * *Bitplane control (bitplane and sprite-masks)
DFF10ECLXCON2W * *Extended collision control
DFF110BPL1DATW* * * *Bitplane 1 data (parallel to serial convert)
DFF112BPL2DATW* * * *Bitplane 2 data (parallel to serial convert)
DFF114BPL3DATW* * * *Bitplane 3 data (parallel to serial convert)
DFF116BPL4DATW* * * *Bitplane 4 data (parallel to serial convert)
DFF118BPL5DATW* * * *Bitplane 5 data (parallel to serial convert)
DFF11ABPL6DATW* * * *Bitplane 6 data (parallel to serial convert)
DFF11CBPL7DATW * *Bitplane 7 data (parallel to serial convert)
DFF11EBPL8DATW * *Bitplane 8 data (parallel to serial convert)
 
DFF120SPR0PTHW* * * *Sprite 0 pointer (high 5 bits was 3 bits)
DFF122SPR0PTLW* * * *Sprite 0 pointer (low 15 bits)
DFF124SPR1PTHW* * * *Sprite 1 pointer (high 5 bits was 3 bits)
DFF126SPR1PTLW* * * *Sprite 1 pointer (low 15 bits)
DFF128SPR2PTHW* * * *Sprite 2 pointer (high 5 bits was 3 bits)
DFF12ASPR2PTLW* * * *Sprite 2 pointer (low 15 bits)
DFF12CSPR3PTHW* * * *Sprite 3 pointer (high 5 bits was 3 bits)
DFF12ESPR3PTLW* * * *Sprite 3 pointer (low 15 bits)
DFF130SPR4PTHW* * * *Sprite 4 pointer (high 5 bits was 3 bits)
DFF132SPR4PTLW* * * *Sprite 4 pointer (low 15 bits)
DFF134SPR5PTHW* * * *Sprite 5 pointer (high 5 bits was 3 bits)
DFF136SPR5PTLW* * * *Sprite 5 pointer (low 15 bits)
DFF138SPR6PTHW* * * *Sprite 6 pointer (high 5 bits was 3 bits)
DFF13ASPR6PTLW* * * *Sprite 6 pointer (low 15 bits)
DFF13CSPR7PTHW* * * *Sprite 7 pointer (high 5 bits was 3 bits)
DFF13ESPR7PTLW* * * *Sprite 7 pointer (low 15 bits)
DFF140SPR0POSW* * * *Sprite 0 vert,horiz start pos data
DFF142SPR0CTLW* * * *Sprite 0 position and control data
DFF144SPR0DATAW* * * *Sprite 0 image data register A
DFF146SPR0DATBW* * * *Sprite 0 image data register B
DFF148SPR1POSW* * * *Sprite 1 vert,horiz start pos data
DFF14ASPR1CTLW* * * *Sprite 1 position and control data
DFF14CSPR1DATAW* * * *Sprite 1 image data register A
DFF14ESPR1DATBW* * * *Sprite 1 image data register B
DFF150SPR2POSW* * * *Sprite 2 vert,horiz start pos data
DFF152SPR2CTLW* * * *Sprite 2 position and control data
DFF154SPR2DATAW* * * *Sprite 2 image data register A
DFF156SPR2DATBW* * * *Sprite 2 image data register B
DFF158SPR3POSW* * * *Sprite 3 vert,horiz start pos data
DFF15ASPR3CTLW* * * *Sprite 3 position and control data
DFF15CSPR3DATAW* * * *Sprite 3 image data register A
DFF15ESPR3DATBW* * * *Sprite 3 image data register B
DFF160SPR4POSW* * * *Sprite 4 vert,horiz start pos data
DFF162SPR4CTLW* * * *Sprite 4 position and control data
DFF164SPR4DATAW* * * *Sprite 4 image data register A
DFF166SPR4DATBW* * * *Sprite 4 image data register B
DFF168SPR5POSW* * * *Sprite 5 vert,horiz start pos data
DFF16ASPR5CTLW* * * *Sprite 5 position and control data
DFF16CSPR5DATAW* * * *Sprite 5 image data register A
DFF16ESPR5DATBW* * * *Sprite 5 image data register B
DFF170SPR6POSW* * * *Sprite 6 vert,horiz start pos data
DFF172SPR6CTLW* * * *Sprite 6 position and control data
DFF174SPR6DATAW* * * *Sprite 6 image data register A
DFF176SPR6DATBW* * * *Sprite 6 image data register B
DFF178SPR7POSW* * * *Sprite 7 vert,horiz start pos data
DFF17ASPR7CTLW* * * *Sprite 7 position and control data
DFF17CSPR7DATAW* * * *Sprite 7 image data register A
DFF17ESPR7DATBW* * * *Sprite 7 image data register B
 
DFF180COLOR00W* * * *Color table 0
DFF182COLOR01W* * * *Color table 1
DFF184COLOR02W* * * *Color table 2
DFF186COLOR03W* * * *Color table 3
DFF188COLOR04W* * * *Color table 4
DFF18ACOLOR05W* * * *Color table 5
DFF18CCOLOR06W* * * *Color table 6
DFF18ECOLOR07W* * * *Color table 7
DFF190COLOR08W* * * *Color table 8
DFF192COLOR09W* * * *Color table 9
DFF194COLOR10W* * * *Color table 10
DFF196COLOR11W* * * *Color table 11
DFF198COLOR12W* * * *Color table 12
DFF19ACOLOR13W* * * *Color table 13
DFF19CCOLOR14W* * * *Color table 14
DFF19ECOLOR15W* * * *Color table 15
DFF1A0COLOR16W* * * *Color table 16
DFF1A2COLOR17W* * * *Color table 17
DFF1A4COLOR18W* * * *Color table 18
DFF1A6COLOR19W* * * *Color table 19
DFF1A8COLOR20W* * * *Color table 20
DFF1AACOLOR21W* * * *Color table 21
DFF1ACCOLOR22W* * * *Color table 22
DFF1AECOLOR23W* * * *Color table 23
DFF1B0COLOR24W* * * *Color table 24
DFF1B2COLOR25W* * * *Color table 25
DFF1B4COLOR26W* * * *Color table 26
DFF1B6COLOR27W* * * *Color table 27
DFF1B8COLOR28W* * * *Color table 28
DFF1BACOLOR29W* * * *Color table 29
DFF1BCCOLOR30W* * * *Color table 30
DFF1BECOLOR31W* * * *Color table 31
 
DFF1C0HTOTALW * * *Highest number count, horiz line (VARBEAMEN=1)
DFF1C2HSSTOPW * * *Horizontal line position for HSYNC stop
DFF1C4HBSTRTW * * *Horizontal line position for HBLANK start
DFF1C6HBSTOPW * * *Horizontal line position for HBLANK stop
DFF1C8VTOTALW * * *Highest numbered vertical line (VARBEAMEN=1)
DFF1CAVSSTOPW * * *Vertical line position for VSYNC stop
DFF1CCVBSTRTW * * *Vertical line for VBLANK start
DFF1CEVBSTOPW * * *Vertical line for VBLANK stop
DFF1D0SPRHSTRTW * * *CHUNKY SPRITE X Pos
DFF1D2SPRHSTOPW * * *CHUNKY SPRITE Y POS
DFF1D4BPLHSTRTW * * *UHRES bit plane vertical start
DFF1D6BPLHSTOPW * * *UHRES bit plane vertical stop
DFF1D8HHPOSWW * * *DUAL mode hires H beam counter write
DFF1DAHHPOSRR * * *DUAL mode hires H beam counter read
DFF1DCBEAMCON0W* * * *Beam counter control register (SHRES,UHRES,PAL)
DFF1DEHSSTRTW * * *Horizontal sync start (VARHSY)
DFF1E0VSSTRTW * * *Vertical sync start (VARVSY)
DFF1E2HCENTERW * * *Horizontal position for Vsync on interlace
DFF1E4DIWHIGHW * * *Display window - upper bits for start/stop
DFF1E6BPLHMODW *Chunky plane modulo
DFF1E8SPRHPTHW * * *UHRES sprite pointer (high 5 bits)
DFF1EASPRHPTLW * * *UHRES sprite pointer (low 15 bits)
DFF1ECBPLHPTHW *Chunky plane pointer (hi 15 bits)
DFF1EEBPLHPTLW *Chunky plane pointer (lo 15 bits)
DFF1F4GFXMODEW *Set Resolution and Pixformat
DFF1FCFMODEW * *Fetch mode register
 
AddressNameAccessOCS ECS AGA SAGADescription
DFF202DMACON2 ReadR *
DFF20AJOY0DATR* * * *Vanilla DB9 Joystick-mouse 0 data (vert, horiz)
DFF20CJOY1DATR* * * *Vaniall DB9 Joystick-mouse 1 data (vert, horiz)
DFF212Mouse WheelR *Mouse Wheel read register
DFF21cINTENA2 ReadR *
DFF21EINTREQ2 ReadR *
DFF220joy0buttonsR *16bit USB Joy Buttons (0)=active
DFF222joy1buttonsR *16bit USB Joy Buttons (0)=active
DFF224joy2buttonsR *16bit USB Joy Buttons (0)=active
DFF226joy3buttonsR *16bit USB Joy Buttons (0)=active
 
DFF230clxdat0R *Sprite0 Detailed Collision
DFF232clxdat1R *Sprite1 Detailed Collision
DFF234clxdat2R *Sprite2 Detailed Collision
DFF236clxdat3R *Sprite3 Detailed Collision
DFF238clxdat4R *Sprite4 Detailed Collision
DFF23Aclxdat5R *Sprite5 Detailed Collision
DFF23Cclxdat6R *Sprite6 Detailed Collision
DFF23Eclxdat7R *Sprite7 Detailed Collision
 
DFF250TEXTPTW *3D 32bit texture source
DFF254TEXDPTW *3D 32bit Destination Screen Addr
DFF258TEXZPTW *3D ZBuffer Addr
DFF25ETEXSTRTW *3D 16bit LEN and START
+Bit15=0 = Start new job
+Bit15=1 = Continue previous job
+Bit10..0 = length in pixel
+
DFF260TEXMIPW *3D 16bit MIP texture size bit(3..0) ($A=1024/9=512/8=256/7=128/6=64/5=32) +
Bit4='1' = AutoMipMapMode with Bit3-0 define max mip
DFF262TEXMODEW *3D 16bit MODE +
(Bit0=use Bilienar)
+(Bit1=use Zbuffer) +(Bit2=select 16bit output)
+(Bit3=inhibit Zbuffer write)
+(Bit4=select 24bit output)
+(Bit5=quadratic-mode)
+(Bit7-6= BLENDMode "00" =COPY) +(Bit7-6= BLENDMode "01" =ADD) +(Bit7-6= BLENDMode "10" =MUL) +
DFF266TEXDMODW *3D 16bit signed Destination Step
DFF268TEXddUUuuuuW *3D 24bit ddUUuuuu (quadratic)
DFF26CTEXddVVvvvvW *3D 24bit ddVVvvvv (quadratic)
DFF270TEXUUuuuuW *3D 24bit UUuuuu
DFF274TEXVVvvvvW *3D 24bit VVvvvv
DFF278TEXdUUuuuuW *3D 24bit dUUuuuu
DFF27CTEXdVVvvvvW *3D 24bit dVVvvvv
DFF280TEXLightW *3D 16bit Light Ll
DFF282TEXdLightW *3D 16bit Light dLl
DFF284TEXLightcolorW *3D 32bit Light color
DFF288TEXZZzzW *3D 32bit ZZZZzzzz
DFF28CTEXdZZzzW *3D 32bit Delta ZZZZzzzz
 
DFF296DMACON2W *DMACON2
DFF29AINTENA2W *INTENA2
DFF29CINTREQ2W *INTREQ2
DFF380PlanarCOLHW *32bit Planar COLOR Port register
DFF382PlanarCOLLW *256 Color Register, Format [ID,RR,GG,BB]
DFF384SpriteCOLHW *32bit Sprite COLOR Port register
DFF386SpriteCOLLW *256 Color Register, Format [ID,RR,GG,BB]
DFF388ChunkyCOLHW *32bit Chunky COLOR Port register
DFF38AChunkyCOLLW *256 Color Register, Format [ID,RR,GG,BB]
DFF38CPIPCOLHW *32bit PIP COLOR Port register
DFF38EPIPCOLLW *256 Color Register, Format [ID,RR,GG,BB]
DFF390/92SCREENMODE ADJUSTW *Adjust Y/X for Screenmodes
DFF3A2Sprite Col1W *Word register RGB (11..0)
DFF3A4Sprite Col2W *Word register RGB (11..0)
DFF3A6Sprite Col3W *Word register RGB (11..0)
DFF3D0PipXStrtW *X start
DFF3D2PipYStrtW *Y start
DFF3D4PipXStopW *X stop
DFF3D6PipYStopW *Y stop
DFF3D8PipPtrW *32 bit Ptr
DFF3DCPipFormatW *Colorformat (8bit/16bit/15bit/YUV)
DFF3DEPipModuloW *Modulo
DFF3E0PipColorKeyW *ColorKey 1000,RRRR,GGGG,BBBB
DFF3E2PipDMARowLenW *PipDMARowLen
DFF3EACORE REVISIONR *Reserved
DFF3ECSAGA CONTROL REGR *Reserved
DFF3EESCREEN SHIFTR *Reserved
DFF3F0CHIP IDR *
DFF3F2CHIP IDR *
DFF3F4CHIP IDR *
DFF3F6CHIP IDR *
DFF3F8SPI WRITER *Reserved
DFF3FASPI readR *Reserved
DFF3FCVAMPIRE VERSIONR *8bit Card Version / 8bit clock multiplier
 
AddressNameAccessOCS ECS AGA SAGADescription
DFF400AUD0L W *Audio channel 0 location (32bit PTR)
DFF402AUD0L W *
DFF404AUD0LENW *Audio channel 0 length (32bit)
DFF406AUD0LENW *
DFF408AUD0VOLW *2x8bit VOL (LEFT/RIGHT)
DFF40AAUD0CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF40CAUD0PERW *16bit PERIOD
DFF410AUD1L W *Audio channel 1 location (32bit PTR)
DFF412AUD1L W *
DFF414AUD1LENW *Audio channel 1 length (32bit)
DFF416AUD1LENW *
DFF418AUD1VOLW *2x8bit VOL (LEFT/RIGHT)
DFF41AAUD1CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF41CAUD1PERW *16bit PERIOD
DFF420AUD2L W *Audio channel 2 location (32bit PTR)
DFF422AUD2L W *
DFF424AUD2LENW *Audio channel 2 length (32bit)
DFF426AUD2LENW *
DFF428AUD2VOLW *2x8bit VOL (LEFT/RIGHT)
DFF42AAUD2CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF42CAUD2PERW *16bit PERIOD
DFF430AUD3L W *Audio channel 1 location (32bit PTR)
DFF432AUD3L W *
DFF434AUD3LENW *Audio channel 3 length (32bit)
DFF436AUD3LENW *
DFF438AUD3VOLW *2x8bit VOL (LEFT/RIGHT)
DFF43AAUD3CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF43CAUD3PERW *16bit PERIOD
DFF440AUD4L W *Audio channel 4 location (32bit PTR)
DFF442AUD4L W *
DFF444AUD4LENW *Audio channel 4 length (32bit)
DFF446AUD4LENW *
DFF448AUD4VOLW *2x8bit VOL (LEFT/RIGHT)
DFF44AAUD4CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF44CAUD4PERW *16bit PERIOD
DFF450AUD5L W *Audio channel 5 location (32bit PTR)
DFF452AUD5L W *
DFF454AUD5LENW *Audio channel 5 length (32bit)
DFF456AUD5LENW *
DFF458AUD5VOLW *2x8bit VOL (LEFT/RIGHT)
DFF45AAUD5CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF45CAUD5PERW *16bit PERIOD
DFF460AUD6L W *Audio channel 6 location (32bit PTR)
DFF462AUD6L W *
DFF464AUD6LENW *Audio channel 6 length (32bit)
DFF466AUD6LENW *
DFF468AUD6VOLW *2x8bit VOL (LEFT/RIGHT)
DFF46AAUD6CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF46CAUD6PERW *16bit PERIOD
DFF470AUD7L W *Audio channel 7 location (32bit PTR)
DFF472AUD7L W *
DFF474AUD7LENW *Audio channel 7 length (32bit)
DFF476AUD7LENW *
DFF478AUD7VOLW *2x8bit VOL (LEFT/RIGHT)
DFF47AAUD7CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF47CAUD7PERW *16bit PERIOD
DFF480AUD8L W *Audio channel 8 location (32bit PTR)
DFF482AUD8L W *
DFF484AUD8LENW *Audio channel 8 length (32bit)
DFF486AUD8LENW *
DFF488AUD8VOLW *2x8bit VOL (LEFT/RIGHT)
DFF48AAUD8CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF48CAUD8PERW *16bit PERIOD
DFF490AUD9L W *Audio channel 9 location (32bit PTR)
DFF492AUD9L W *
DFF494AUD9LENW *Audio channel 9 length (32bit)
DFF496AUD9LENW *
DFF498AUD9VOLW *2x8bit VOL (LEFT/RIGHT)
DFF49AAUD9CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF49CAUD9PERW *16bit PERIOD
DFFAA0AUD10L W *Audio channel 10 location (32bit PTR)
DFF4A2AUD10L W *
DFF4A4AUD10LENW *Audio channel 10 length (32bit)
DFF4A6AUD10LENW *
DFF4A8AUD10VOLW *2x8bit VOL (LEFT/RIGHT)
DFF4AAAUD10CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF4ACAUD10PERW *16bit PERIOD
DFF4B0AUD11L W *Audio channel 11 location (32bit PTR)
DFF4B2AUD11L W *
DFF4B4AUD11LENW *Audio channel 11 length (32bit)
DFF4B6AUD11LENW *
DFF4B8AUD11VOLW *2x8bit VOL (LEFT/RIGHT)
DFF4BAAUD11CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF4BCAUD11PERW *16bit PERIOD
DFF4C0AUD12L W *Audio channel 12 location (32bit PTR)
DFF4C2AUD12L W *
DFF4C4AUD12LENW *Audio channel 12 length (32bit)
DFF4C6AUD12LENW *
DFF4C8AUD12VOLW *2x8bit VOL (LEFT/RIGHT)
DFF4CAAUD12CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF4C4CAUD12PERW *16bit PERIOD
DFF4D0AUD13L W *Audio channel 13 location (32bit PTR)
DFF4D2AUD13L W *
DFF4D4AUD13LENW *Audio channel 13 length (32bit)
DFF4D6AUD13LENW *
DFF4D8AUD13VOLW *2x8bit VOL (LEFT/RIGHT)
DFF4DAAUD13CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF4DCAUD13PERW *16bit PERIOD
DFF4E0AUD14L W *Audio channel 14 location (32bit PTR)
DFF4E2AUD14L W *
DFF4E4AUD14LENW *Audio channel 14 length (32bit)
DFF4E6AUD14LENW *
DFF4E8AUD14VOLW *2x8bit VOL (LEFT/RIGHT)
DFF4EAAUD14CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF4ECAUD14PERW *16bit PERIOD
DFF4F0AUD15L W *Audio channel 15 location (32bit PTR)
DFF4F2AUD15L W *
DFF4F4AUD15LENW *Audio channel 15 length (32bit)
DFF4F6AUD15LENW *
DFF4F8AUD15VOLW *2x8bit VOL (LEFT/RIGHT)
DFF4FAAUD15CTRLW *16 Control bits +2= Stereo +1= Oneshot +0= (8bit/16bit)
DFF4FCAUD15PERW *16bit PERIOD
ATARI CHIPSET
DF8200 SHIFTER COLORSR/W * SHIFTER COLORS
DF8800 YAMAHA_RR/W * YAMAHA AUDIO
DF8802 YAMAHA_WR/W * YAMAHA AUDIO
DFFA07 MFP_IERAR/W * MFP Timer
DFFA09MFP_IERBR/W *MFP Timer
DFFA0BMFP_IPRAR/W *MFP Timer
DFFA0DMFP_IPRBR/W *MFP Timer
DFFA0FMFP_ISRAR/W *MFP Timer
DFFA11MFP_ISRBR/W *MFP Timer
DFFA13MFP_IMRAR/W *MFP Timer
DFFA15MFP_IMRBR/W *MFP Timer
DFFA17MFP_VECR/W *MFP Timer
DFFA19MFP_TACRR/W *MFP Timer
DFFA1BMFP_TBCRR/W *MFP Timer
DFFA1DMFP_TCDCRR/W *MFP Timer
DFFA1F MFP_TADRR/W * MFP Timer
DFFA21 MFP_TBDRR/W * MFP Timer
DFFA23 MFP_TCDRR/W * MFP Timer
DFFA25 MFP_TDDRR/W * MFP Timer
+ + + diff --git a/sources/official/saga-registers/intena2.htm b/sources/official/saga-registers/intena2.htm new file mode 100755 index 0000000..d6bbae0 --- /dev/null +++ b/sources/official/saga-registers/intena2.htm @@ -0,0 +1,39 @@ + + +
+
+INTENA2
+
+This register contains interrupt enable bits. The bit assignment for
+both the request, and enable registers is given below
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 15    |         | SET/CLR                                    |
+         | 14    |         |                                            |
+         | 13    | ETH     | Ethernet                                   |
+         | 12    |         |                                            |
+         | 11    | AUD15   | Audio channel 15 block finished            |
+         | 10    | AUD14   | Audio channel 14 block finished            |
+         | 09    | AUD13   | Audio channel 13 block finished            |
+         | 08    | AUD12   | Audio channel 12 block finished            |
+         | 07    | AUD11   | Audio channel 11 block finished            |
+         | 06    | AUD10   | Audio channel 10 block finished            |
+         | 05    | AUD9    | Audio channel 9 block finished             |
+         | 04    | AUD8    | Audio channel 8 block finished             |
+         | 03    | AUD7    | Audio channel 7 block finished             |
+         | 02    | AUD6    | Audio channel 6 block finished             |
+         | 01    | AUD5    | Audio channel 5 block finished             |
+         | 00    | AUD4    | Audio channel 4 block finished             |
+         +-------+----------+-------------------------------------------+
+
+
+Ethernet will throw IRQ $48
+The new Audio channels will throw IRQ $50
+
+
+
+
+ + diff --git a/sources/official/saga-registers/intenar.htm b/sources/official/saga-registers/intenar.htm new file mode 100755 index 0000000..57c3023 --- /dev/null +++ b/sources/official/saga-registers/intenar.htm @@ -0,0 +1,41 @@ + + +
+                Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+INTENA     09A      W       P    Interrupt enable bits (clear or set bits)
+INTENAR    01C      R       P    Interrupt enable bits (read)
+
+                 This register contains interrupt enable bits. The bit
+                 assignment for both the request and enable registers
+                 is given below.
+
+                 BIT#  FUNCT  LEVEL DESCRIPTION
+                 ----  ------ ----- ----------------------------------
+                 15    SET/CLR     Set/clear control bit. Determines if
+                                   bits written with a 1 get set or
+                                   cleared. Bits written with a zero
+                                   are always unchanged.
+                 14    INTEN       Master interrupt (enable only,
+                                     no request)
+                 13    EXTER   6   External interrupt
+                 12    DSKSYN  5   Disk sync register ( DSKSYNC )
+                                     matches disk data
+                 11    RBF     5   Serial port receive buffer full
+                 10    AUD3    4   Audio channel 3 block finished
+                 09    AUD2    4   Audio channel 2 block finished
+                 08    AUD1    4   Audio channel 1 block finished
+                 07    AUD0    4   Audio channel 0 block finished
+                 06    BLIT    3   Blitter finished
+                 05    VERTB   3   Start of vertical blank
+                 04    COPER   3   Copper
+                 03    PORTS   2   I/O ports and timers
+                 02    SOFT    1   Reserved for software-initiated
+                                     interrupt
+                 01    DSKBLK  1   Disk block finished
+                 00    TBE     1   Serial port transmit buffer empty
+
+ + diff --git a/sources/official/saga-registers/intreq2.htm b/sources/official/saga-registers/intreq2.htm new file mode 100755 index 0000000..125621e --- /dev/null +++ b/sources/official/saga-registers/intreq2.htm @@ -0,0 +1,41 @@ + + +
+
+INTREQ2
+
+This register contains interrupt request bits (or flags). These bits
+may be polled by the processor, and if enabled by the bits listed in
+the next register, they may cause processor interrupts. Both a set
+and clear operation are required to load arbitrary data into this register.
+
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 15    |         | SET/CLR                                    |
+         | 14    |         |                                            |
+         | 13    | ETH     | Ethernet                                   |
+         | 12    |         |                                            |
+         | 11    | AUD15   | Audio channel 15 block finished            |
+         | 10    | AUD14   | Audio channel 14 block finished            |
+         | 09    | AUD13   | Audio channel 13 block finished            |
+         | 08    | AUD12   | Audio channel 12 block finished            |
+         | 07    | AUD11   | Audio channel 11 block finished            |
+         | 06    | AUD10   | Audio channel 10 block finished            |
+         | 05    | AUD9    | Audio channel 9 block finished             |
+         | 04    | AUD8    | Audio channel 8 block finished             |
+         | 03    | AUD7    | Audio channel 7 block finished             |
+         | 02    | AUD6    | Audio channel 6 block finished             |
+         | 01    | AUD5    | Audio channel 5 block finished             |
+         | 00    | AUD4    | Audio channel 4 block finished             |
+         +-------+----------+-------------------------------------------+
+
+
+Ethernet will throw IRQ $48
+The new Audio channels will throw IRQ $50
+
+
+
+ + diff --git a/sources/official/saga-registers/intreqr.htm b/sources/official/saga-registers/intreqr.htm new file mode 100755 index 0000000..9543534 --- /dev/null +++ b/sources/official/saga-registers/intreqr.htm @@ -0,0 +1,24 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+INTREQ     09C      W       P   Interrupt request bits (clear or set)
+INTREQR    01E      R       P   Interrupt request bits (read)
+
+                 This register contains interrupt request bits (or
+                 flags).  These bits may be polled by the processor;
+                 if enabled by the bits listed in the above register,
+                 they may cause processor interrupts.  Both a set and
+                 clear operation are required to load arbitrary data
+                 into this register.  These status bits are not
+                 automatically reset when the interrupt is serviced,
+                 and must be reset when desired by writing to this
+                 address.  The bit assignments are identical to the
+                  enable register .
+
+ + diff --git a/sources/official/saga-registers/joy0dat.htm b/sources/official/saga-registers/joy0dat.htm new file mode 100755 index 0000000..bfbe6b1 --- /dev/null +++ b/sources/official/saga-registers/joy0dat.htm @@ -0,0 +1,68 @@ + + +
+
+ Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+JOY0DAT    00A      R       D     Joystick-mouse 0 data (left vertical,
+                                      horizontal)
+JOY1DAT    00C      R       D     Joystick-mouse 1 data (right vertical,
+                                      horizontal)
+
+                 These addresses each read a pair of 8-bit mouse
+                 counters.  0=left controller pair, 1=right
+                 controller pair (four counters total).  The bit
+                 usage for both left and right addresses is shown
+                 below.  Each counter is clocked by signals from
+                 two controller pins.  Bits 1 and 0 of each counter
+                 may be read to determine the state of these two
+                 clock pins.  This allows these pins to double as
+                 joystick switch inputs.
+
+                 Mouse counter usage:
+                 (pins 1,3=Yclock, pins 2,4=Xclock)
+
+                 BIT# 15,14,13,12,11,10,09,08  07,06,05,04,03,02,01,00
+                      -----------------------  -----------------------
+                 0DAT Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0  X7 X6 X5 X4 X3 X2 X1 X0
+                 1DAT Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0  X7 X6 X5 X4 X3 X2 X1 X0
+
+                 The following table shows the mouse/joystick
+                 connector pin usage.  The pins (and their functions)
+                 are sampled (multiplexed) into the DENISE chip
+                 during the clock times shown in the table.
+                 This table is for reference only and should
+                 not be needed by the programmer.  (Note that the
+                 joystick functions are all "active low" at the
+                 connector pins.)
+
+                                            Sampled by DENISE
+                 Conn   Joystick  Mouse     -----------------
+                 Pin    Function  Function  Pin  Name  Clock
+                 ----   --------  --------  ---  ----  -----
+                 L1     FORW*        Y      38   M0V at CCK
+                 L3     LEFT*        YQ     38   M0V at CCK*
+                 L2     BACK*        X       9   M0H at CCK
+                 L4     RIGH*        XQ      9   M0H at CCK*
+                 R1     FORW*        Y      39   M1V at CCK
+                 R3     LEFT*        YQ     39   M1V at CCK*
+                 R2     BACK*        X       8   M1H at CCK
+                 R4     RIGH*        XQ      8   M1H at CCK*
+
+                 After being sampled, these connector pin signals
+                 are used in quadrature to clock the mouse counters.
+                 The LEFT and RIGHT joystick functions (active high)
+                 are directly available on the Y1 and X1 bits of
+                 each counter.  In order to recreate the FORWARD
+                 and BACK joystick functions, however, it is
+                 necessary to logically combine (exclusive OR)
+                 the lower two bits of each counter.
+                 This is illustrated in the following table.
+
+                 To detect              Read these counter bits
+                 --------               ----------------
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/joybuttons.htm b/sources/official/saga-registers/joybuttons.htm new file mode 100755 index 0000000..1aca107 --- /dev/null +++ b/sources/official/saga-registers/joybuttons.htm @@ -0,0 +1,32 @@ + + +
+
+JOYBUTTONS
+
+         This register contains extra fire buttons (USB joyspads)
+
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 15    | Right   | Move RIGHT                                 |
+         | 14    | Left    | Move Left                                  |
+         | 13    | Down    | Move Down                                  |
+         | 12    | Up      | Move Up                                    |
+         | 11    | Reserved|                                            |
+         | 10    | Start   | Start                                      |
+         | 09    | Back    | Back                                       |
+         | 08    | FIRE8   | Firebutton 8                               |
+         | 07    | FIRE7   | Firebutton 7                               |
+         | 06    | FIRE6   | Firebutton 6                               |
+         | 05    | FIRE5   | Firebutton 5                               |
+         | 04    | FIRE4   | Firebutton 4                               |
+         | 03    | FIRE3   | Firebutton 3                               |
+         | 02    | FIRE2   | Firebutton 2                               |
+         | 01    | FIRE1   | Firebutton 1                               |
+         | 00    | PLUG    | Joypad connected                           |
+         +-------+----------+-------------------------------------------+
+
+ + diff --git a/sources/official/saga-registers/joytest.htm b/sources/official/saga-registers/joytest.htm new file mode 100755 index 0000000..4b7e4d7 --- /dev/null +++ b/sources/official/saga-registers/joytest.htm @@ -0,0 +1,20 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+JOYTEST    036      W       D     Write to all four joystick-mouse counters
+                                  at once.
+
+                 Mouse counter write test data:
+
+                 BIT#  15,14,13,12,11,10,09,08  07,06,05,04,03,02,01,00
+                       -----------------------  -----------------------
+                 0DAT  Y7 Y6 Y5 Y4 Y3 Y2 xx xx  X7 X6 X5 X4 X3 X2 xx xx
+                 1DAT  Y7 Y6 Y5 Y4 Y3 Y2 xx xx  X7 X6 X5 X4 X3 X2 xx xx
+
+ + diff --git a/sources/official/saga-registers/mousewheel.htm b/sources/official/saga-registers/mousewheel.htm new file mode 100755 index 0000000..6052875 --- /dev/null +++ b/sources/official/saga-registers/mousewheel.htm @@ -0,0 +1,25 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+Wheel      212      R      P( E )     Wheel events
+
+                 BIT  15-10 unused
+                 BIT  9     Mouse Button 5
+                 BIT  8     Mouse Button 4
+
+
+                 signed 8 bit counter counts USB mouse Wheel events
+
+                 BIT#  07,06,05,04,03,02,01,00
+                 ----- ------------------------ -----------------------
+                       X7 X6 X5 X4 X3 X2 X1 X0
+
+
+
+ + diff --git a/sources/official/saga-registers/pipcol.htm b/sources/official/saga-registers/pipcol.htm new file mode 100755 index 0000000..7d567ec --- /dev/null +++ b/sources/official/saga-registers/pipcol.htm @@ -0,0 +1,28 @@ + + +
+
+PIP COLOR PORT
+
+         This register allows direct setting of 256 PIP colors registers
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 31-24 | index   | 8bit Colornumber                           |
+         | 23-16 | RED     | 8bit Red                                   |
+         | 15-08 | GREEN   | 8bit Green                                 |
+         | 07-00 | BLUE    | 8bit Blue                                  |
+         +-------+----------+-------------------------------------------+
+
+Example:
+
+ move.l #$00FF0000,$DFF38C   -- set color0 = RED
+ move.l #$01FFFF00,$DFF38C   -- set color1 = YELLOW
+
+Copper:
+ dc.w  $838C,$00FF,$0000     -- set color0 = RED
+
+
+ + diff --git a/sources/official/saga-registers/planarcol.htm b/sources/official/saga-registers/planarcol.htm new file mode 100755 index 0000000..a05b84c --- /dev/null +++ b/sources/official/saga-registers/planarcol.htm @@ -0,0 +1,29 @@ + + +
+
+PLANAR COLOR PORT
+
+         This register allows direct setting of 256 Planar colors registers
+
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 31-24 | Number  | 8bit Colornumber                           |
+         | 23-16 | RED     | 8bit Red                                   |
+         | 15-08 | GREEN   | 8bit Green                                 |
+         | 07-00 | BLUE    | 8bit Blue                                  |
+         +-------+----------+-------------------------------------------+
+
+Example:
+
+ move.l #$00FF0000,$DFF380   -- set color0 = RED
+ move.l #$01FFFF00,$DFF380   -- set color1 = YELLOW
+
+Copper:
+ dc.w  $8380,$00FF,$0000     -- set color0 = RED
+
+
+ + diff --git a/sources/official/saga-registers/pot0dat.htm b/sources/official/saga-registers/pot0dat.htm new file mode 100755 index 0000000..881dffa --- /dev/null +++ b/sources/official/saga-registers/pot0dat.htm @@ -0,0 +1,34 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+POT0DAT    012      R      P( E ) Pot counter data left pair (vert,horiz.)
+POT1DAT    014      R      P( E ) Pot counter data right pair (vert,horiz.)
+
+                 These addresses each read a pair of 8-bit pot counters.
+                 (Four counters total.) The bit assignment for both
+                 addresses is shown below. The counters are stopped by
+                 signals from two controller connectors (left-right)
+                 with two pins each.
+
+                 BIT#  15,14,13,12,11,10,09,08  07,06,05,04,03,02,01,00
+                 ----- ------------------------ -----------------------
+                 RIGHT Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0  X7 X6 X5 X4 X3 X2 X1 X0
+                 LEFT  Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0  X7 X6 X5 X4 X3 X2 X1 X0
+
+                           CONNECTORS                PAULA
+                         --------------------    ----------------
+                         Loc. Dir. Sym   Pin     Pin#    Pin Name
+                         ----  --- ----  ----    ----    --------
+                         RIGHT  Y   RY    9      36      (POT1Y)
+                         RIGHT  X   RX    5      35      (POT1X)
+                         LEFT   Y   LY    9      33      (POT0Y)
+                         LEFT   X   LX    5      32      (POT0X)
+
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/potgo.htm b/sources/official/saga-registers/potgo.htm new file mode 100755 index 0000000..3b08e84 --- /dev/null +++ b/sources/official/saga-registers/potgo.htm @@ -0,0 +1,38 @@ + + +
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+POTGO      034      W       P     Pot port data write and start.
+
+POTGOR     016      R       P     Pot port data read
+                                      (formerly called POTINP).
+
+                 This register controls a 4-bit bi-directional I/O port
+                 that shares the same four pins as the four pot counters
+                 above.
+
+                 BIT#  FUNCT   DESCRIPTION
+                 ----  ---------------------------------------
+                 15    OUTRY   Output enable for Paula pin 36
+                 14    DATRY   I/O data Paula pin 36
+                 13    OUTRX   Output enable for Paula pin 35
+                 12    DATRX   I/O data Paula pin 35
+                 11    OUTLY   Output enable for Paula pin 33
+                 10    DATLY   I/O data Paula pin 33
+                 09    OUTLX   Output enable for Paula pin 32
+                 08    DATLX   I/O data Paula pin 32
+                 07-01   0     Reserved for chip ID code (presently 0)
+                 00    START   Start pots (dump capacitors, start
+                                 counters)
+
+Bit 14 = Firebutton 2 Joy2
+Bit 12 = Firebutton 3 Joy2
+Bit 10 = Firebutton 2
+Bit  8 = Firebutton 3
+
+
+ + diff --git a/sources/official/saga-registers/potinp.htm b/sources/official/saga-registers/potinp.htm new file mode 100755 index 0000000..3aa3167 --- /dev/null +++ b/sources/official/saga-registers/potinp.htm @@ -0,0 +1,33 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+POTGO      034      W       P     Pot port data write and start.
+
+POTGOR     016      R       P     Pot port data read
+                                      (formerly called POTINP).
+
+                 This register controls a 4-bit bi-directional I/O port
+                 that shares the same four pins as the four pot counters
+                 above.
+
+                 BIT#  FUNCT   DESCRIPTION
+                 ----  ---------------------------------------
+                 15    OUTRY   Output enable for Paula pin 36
+                 14    DATRY   I/O data Paula pin 36
+                 13    OUTRX   Output enable for Paula pin 35
+                 12    DATRX   I/O data Paula pin 35
+                 11    OUTLY   Output enable for Paula pin 33
+                 10    DATLY   I/O data Paula pin 33
+                 09    OUTLX   Output enable for Paula pin 32
+                 08    DATLX   I/O data Paula pin 32
+                 07-01   0     Reserved for chip ID code (PAULA=0/ARNE=1)
+                 00    START   Start pots (dump capacitors, start
+                                 counters)
+
+ + diff --git a/sources/official/saga-registers/refptr.htm b/sources/official/saga-registers/refptr.htm new file mode 100755 index 0000000..16c102a --- /dev/null +++ b/sources/official/saga-registers/refptr.htm @@ -0,0 +1,18 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+REFPTR     028      W       A      Refresh pointer
+
+                 This register is used as a dynamic RAM refresh
+                 address generator. It is writeable for test
+                 purposes only, and should never be written by
+                 the microprocessor.
+
+ + + diff --git a/sources/official/saga-registers/saga.htm b/sources/official/saga-registers/saga.htm new file mode 100755 index 0000000..490993e --- /dev/null +++ b/sources/official/saga-registers/saga.htm @@ -0,0 +1,2139 @@ + + + Hardware SAGA Chipset Amiga Development + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AddressNameAccessOCS ECS AGA SAGADescription
DFF000BLTDDATER* * * *Blitter dest. early read (dummy address)
DFF002DMACONRR* * * *Dma control (and blitter status) read
DFF004VPOSRR* * * *Read vertical most sig. bits (and frame flop)
DFF006VHPOSRR* * * *Read vert and horiz position of beam
DFF008DSKDATRER* * * *Disk data early read (dummy address)
DFF00AJOY0DATR* * * *Joystick-mouse 0 data (vert, horiz)
DFF00CJOY1DATR* * * *Joystick-mouse 1 data (vert, horiz)
DFF00ECLXDATR* * * *Collision data reg. (read and clear)
DFF010ADKCONRR* * * *Audio,disk control register read
DFF012POT0DATR* * * *Pot counter data left pair (vert, horiz)
DFF014POT1DATR* * * *Pot counter data right pair (vert, horiz)
DFF016POTINPR* * * *Pot pin data read
DFF018SERDATRR* * * *Serial port data and status read
DFF01ADSKBYTRR* * * *Disk data byte and status read
DFF01CINTENARR* * * *Interrupt enable bits read
DFF01EINTREQRR* * * *Interrupt request bits read
DFF020DSKPTHW* * * *Disk pointer (high 5 bits, was 3 bits)
DFF022DSKPTLW* * * *Disk pointer (low 15 bits)
DFF024DSKLENW** * *Disk length
DFF026DSKDATW* * * *Disk DMA data write
DFF028REFPTRW* * * *Refresh pointer
DFF02AVPOSWW* * * *Write vert most sig. bits (and frame flop)
DFF02CVHPOSWW* * * *Write vert and horiz pos of beam
DFF02ECOPCONW* * * *Coprocessor control
DFF030SERDATW* * * *Serial port data and stop bits write
DFF032SERPERW* * * *Serial port period and control
DFF034POTGOW* * * *Pot count start,pot pin drive enable data
DFF036JOYTESTW* * * *Write to all 4 joystick-mouse counters at once
DFF038STREQUS* * * *Strobe for horiz sync with VB and EQU
DFF03ASTRVBLS* * * *Strobe for horiz sync with VB (vert blank)
DFF03CSTRHORS* * * *Strobe for horiz sync
DFF03ESTRLONGS* * * *Strobe for identification of long horiz line
DFF040BLTCON0W* * * *Blitter control register 0
DFF042BLTCON1W* * * *Blitter control register 1
DFF044BLTAFWMW* * * *Blitter first word mask for source A
DFF046BLTALWMW* * * *Blitter last word mask for source A
DFF048BLTCPTHW* * * *Blitter pointer to source C (high 5 bits, was 3 bits)
DFF04ABLTCPTLW* * * *Blitter pointer to source C (low 15 bits)
DFF04CBLTBPTHW* * * *Blitter pointer to source B (high 5 bits, was 3 bits)
DFF04EBLTBPTLW* * * *Blitter pointer to source B (low 15 bits)
DFF050BLTAPTHW* * * *Blitter pointer to source A (high 5 bits, was 3 bits)
DFF052BLTAPTLW* * * *Blitter pointer to source A (low 15 bits)
DFF054BLTDPTHW* * * *Blitter pointer to dest D (high 5 bits, was 3 bits)
DFF056BLTDPTLW* * * *Blitter pointer to dest D (low 15 bits)
DFF058BLTSIZEW* * * *Blitter start and size (win/width,height)
DFF05ABLTCON0LW * * *Blitter control 0, lower 8 bits (minterms)
DFF05CBLTSIZVW * * *Blitter V size (for 15 bit vertical size)
DFF05EBLTSIZHW * * *Blitter H size and start (for 11 bit H size)
DFF060BLTCMODW* * * *Blitter modulo for source C
DFF062BLTBMODW* * * *Blitter modulo for source B
DFF064BLTAMODW* * * *Blitter modulo for source A
DFF066BLTDMODW* * * *Blitter modulo for dest D
DFF070BLTCDATW* * * *Blitter source C data register
DFF072BLTBDATW* * * *Blitter source B data register
DFF074BLTADATW* * * *Blitter source A data register
DFF078SPRHDATW * * *Ext. logic UHRES sprite pointer and data identifier
DFF07ABPLHDATW * * *Ext. logic UHRES bit plane identifier
DFF07CDENISEIDR * * *Chip revision level for Denise/Lisa (video out chip)
DFF07EDSKSYNCW* * * *Disk sync pattern reg for disk read
DFF080COP1LCHW* * * *Coprocessor 1st location (high 5 bits,was 3 bits)
DFF082COP1LCLW* * * *Coprocessor 1st location (low 15 bits)
DFF084COP2LCHW* * * *Coprocessor 2nd location(high 5 bits,was 3 bits)
DFF086COP2LCLW* * * *Coprocessor 2nd location (low 15 bits)
DFF088COPJMP1S* * * *Coprocessor restart at 1st location
DFF08ACOPJMP2S* * * *Coprocessor restart at 2nd location
DFF08CCOPINSS* * * *Coprocessor inst fetch identify
DFF08EDIWSTRTW* * * *Display window start (upper left vert,horiz pos)
DFF090DIWSTOPW* * * *Display window stop (lower right vert,horiz pos)
DFF092DDFSTRTW* * * *Display bit plane data fetch start,horiz pos
DFF094DDFSTOPW* * * *Display bit plane data fetch stop,horiz pos
DFF096DMACONW* * * *DMA control write (clear or set)
DFF098CLXCONW* * * *Collision control
DFF09AINTENAW* * * *Interrupt enable bits (clear or set bits)
DFF09CINTREQW* * * *Interrupt request bits (clear or set bits)
DFF09EADKCONW* * * *Audio,disk,UART control
DFF0A0AUD0LCHW* * * *Audio channel 0 location (high 5 bits was 3 bits)
DFF0A2AUD0LCLW* * * *Audio channel 0 location (low 15 bits)
DFF0A4AUD0LENW* * * *Audio channel 0 length
DFF0A6AUD0PERW* * * *Audio channel 0 period
DFF0A8AUD0VOLW* * * *Audio channel 0 volume
DFF0AAAUD0DATW* * * *Audio channel 0 data
DFF0ACAUD0VOL2W *Audio channel 0 volume far side
DFF0AEAUD0LENHIW *Audio channel 0 length high bits
DFF0B0AUD1LCHW* * * *Audio channel 1 location (high 5 bits was 3 bits)
DFF0B2AUD1LCLW* * * *Audio channel 1 location (low 15 bits)
DFF0B4AUD1LENW* * * *Audio channel 1 length
DFF0B6AUD1PERW* * * *Audio channel 1 period
DFF0B8AUD1VOLW* * * *Audio channel 1 volume
DFF0BAAUD1DATW* * * *Audio channel 1 data
DFF0BCAUD1VOL2W *Audio channel 1 volume far side
DFF0BEAUD1LENHIW *Audio channel 1 length high bits
DFF0C0AUD2LCHW* * * *Audio channel 2 location (high 5 bits was 3 bits)
DFF0C2AUD2LCLW* * * *Audio channel 2 location (low 15 bits)
DFF0C4AUD2LENW* * * *Audio channel 2 length
DFF0C6AUD2PERW* * * *Audio channel 2 period
DFF0C8AUD2VOLW* * * *Audio channel 2 volume
DFF0CAAUD2DATW* * * *Audio channel 2 data
DFF0CCAUD2VOL2W *Audio channel 2 volume far side
DFF0CEAUD2LENHIW *Audio channel 2 length high bits
DFF0D0AUD3LCHW* * * *Audio channel 3 location (high 5 bits was 3 bits)
DFF0D2AUD3LCLW* * * *Audio channel 3 location (low 15 bits)
DFF0D4AUD3LENW* * * *Audio channel 3 length
DFF0D6AUD3PERW* * * *Audio channel 3 period
DFF0D8AUD3VOLW* * * *Audio channel 3 volume
DFF0DAAUD3DATW* * * *Audio channel 3 data
DFF0DCAUD3VOL2W *Audio channel 3 volume far side
DFF0DEAUD3LENHIW *Audio channel 3 length high bits
 
DFF0E0BPL1PTHW* * * *Bitplane pointer 1 (high 5 bits was 3 bits)
DFF0E2BPL1PTLW* * * *Bitplane pointer 1 (low 15 bits)
DFF0E4BPL2PTHW* * * *Bitplane pointer 2 (high 5 bits was 3 bits)
DFF0E6BPL2PTLW* * * *Bitplane pointer 2 (low 15 bits)
DFF0E8BPL3PTHW* * * *Bitplane pointer 3 (high 5 bits was 3 bits)
DFF0EABPL3PTLW* * * *Bitplane pointer 3 (low 15 bits)
DFF0ECBPL4PTHW* * * *Bitplane pointer 4 (high 5 bits was 3 bits)
DFF0EEBPL4PTLW* * * *Bitplane pointer 4 (low 15 bits)
DFF0F0BPL5PTHW* * * *Bitplane pointer 5 (high 5 bits was 3 bits)
DFF0F2BPL5PTLW* * * *Bitplane pointer 5 (low 15 bits)
DFF0F4BPL6PTHW* * * *Bitplane pointer 6 (high 5 bits was 3 bits)
DFF0F6BPL6PTLW* * * *Bitplane pointer 6 (low 15 bits)
DFF0F8BPL7PTHW * *Bitplane pointer 7 (high 5 bits was 3 bits)
DFF0FABPL7PTLW * *Bitplane pointer 7 (low 15 bits)
DFF0FCBPL8PTHW * *Bitplane pointer 8 (high 5 bits was 3 bits)
DFF0FEBPL8PTLW * *Bitplane pointer 8 (low 15 bits)
DFF100BPLCON0W* * * *Bitplane control (miscellaneous control bits)
DFF102BPLCON1W* * * *Bitplane control (scroll value)
DFF104BPLCON2W* * * *Bitplane control (video priority control)
DFF106BPLCON3W* * * *Bitplane control (enhanced features)
DFF108BPL1MODW* * * *Bitplane modulo (odd planes)
DFF10ABPL2MODW* * * *Bitplane modulo (even planes)
DFF10CBPLCON4W * *Bitplane control (bitplane and sprite-masks)
DFF10ECLXCON2W * *Extended collision control
DFF110BPL1DATW* * * *Bitplane 1 data (parallel to serial convert)
DFF112BPL2DATW* * * *Bitplane 2 data (parallel to serial convert)
DFF114BPL3DATW* * * *Bitplane 3 data (parallel to serial convert)
DFF116BPL4DATW* * * *Bitplane 4 data (parallel to serial convert)
DFF118BPL5DATW* * * *Bitplane 5 data (parallel to serial convert)
DFF11ABPL6DATW* * * *Bitplane 6 data (parallel to serial convert)
DFF11CBPL7DATW * *Bitplane 7 data (parallel to serial convert)
DFF11EBPL8DATW * *Bitplane 8 data (parallel to serial convert)
 
DFF120SPR0PTHW* * * *Sprite 0 pointer (high 5 bits was 3 bits)
DFF122SPR0PTLW* * * *Sprite 0 pointer (low 15 bits)
DFF124SPR1PTHW* * * *Sprite 1 pointer (high 5 bits was 3 bits)
DFF126SPR1PTLW* * * *Sprite 1 pointer (low 15 bits)
DFF128SPR2PTHW* * * *Sprite 2 pointer (high 5 bits was 3 bits)
DFF12ASPR2PTLW* * * *Sprite 2 pointer (low 15 bits)
DFF12CSPR3PTHW* * * *Sprite 3 pointer (high 5 bits was 3 bits)
DFF12ESPR3PTLW* * * *Sprite 3 pointer (low 15 bits)
DFF130SPR4PTHW* * * *Sprite 4 pointer (high 5 bits was 3 bits)
DFF132SPR4PTLW* * * *Sprite 4 pointer (low 15 bits)
DFF134SPR5PTHW* * * *Sprite 5 pointer (high 5 bits was 3 bits)
DFF136SPR5PTLW* * * *Sprite 5 pointer (low 15 bits)
DFF138SPR6PTHW* * * *Sprite 6 pointer (high 5 bits was 3 bits)
DFF13ASPR6PTLW* * * *Sprite 6 pointer (low 15 bits)
DFF13CSPR7PTHW* * * *Sprite 7 pointer (high 5 bits was 3 bits)
DFF13ESPR7PTLW* * * *Sprite 7 pointer (low 15 bits)
DFF140SPR0POSW* * * *Sprite 0 vert,horiz start pos data
DFF142SPR0CTLW* * * *Sprite 0 position and control data
DFF144SPR0DATAW* * * *Sprite 0 image data register A
DFF146SPR0DATBW* * * *Sprite 0 image data register B
DFF148SPR1POSW* * * *Sprite 1 vert,horiz start pos data
DFF14ASPR1CTLW* * * *Sprite 1 position and control data
DFF14CSPR1DATAW* * * *Sprite 1 image data register A
DFF14ESPR1DATBW* * * *Sprite 1 image data register B
DFF150SPR2POSW* * * *Sprite 2 vert,horiz start pos data
DFF152SPR2CTLW* * * *Sprite 2 position and control data
DFF154SPR2DATAW* * * *Sprite 2 image data register A
DFF156SPR2DATBW* * * *Sprite 2 image data register B
DFF158SPR3POSW* * * *Sprite 3 vert,horiz start pos data
DFF15ASPR3CTLW* * * *Sprite 3 position and control data
DFF15CSPR3DATAW* * * *Sprite 3 image data register A
DFF15ESPR3DATBW* * * *Sprite 3 image data register B
DFF160SPR4POSW* * * *Sprite 4 vert,horiz start pos data
DFF162SPR4CTLW* * * *Sprite 4 position and control data
DFF164SPR4DATAW* * * *Sprite 4 image data register A
DFF166SPR4DATBW* * * *Sprite 4 image data register B
DFF168SPR5POSW* * * *Sprite 5 vert,horiz start pos data
DFF16ASPR5CTLW* * * *Sprite 5 position and control data
DFF16CSPR5DATAW* * * *Sprite 5 image data register A
DFF16ESPR5DATBW* * * *Sprite 5 image data register B
DFF170SPR6POSW* * * *Sprite 6 vert,horiz start pos data
DFF172SPR6CTLW* * * *Sprite 6 position and control data
DFF174SPR6DATAW* * * *Sprite 6 image data register A
DFF176SPR6DATBW* * * *Sprite 6 image data register B
DFF178SPR7POSW* * * *Sprite 7 vert,horiz start pos data
DFF17ASPR7CTLW* * * *Sprite 7 position and control data
DFF17CSPR7DATAW* * * *Sprite 7 image data register A
DFF17ESPR7DATBW* * * *Sprite 7 image data register B
 
DFF180COLOR00W* * * *Color table 0
DFF182COLOR01W* * * *Color table 1
DFF184COLOR02W* * * *Color table 2
DFF186COLOR03W* * * *Color table 3
DFF188COLOR04W* * * *Color table 4
DFF18ACOLOR05W* * * *Color table 5
DFF18CCOLOR06W* * * *Color table 6
DFF18ECOLOR07W* * * *Color table 7
DFF190COLOR08W* * * *Color table 8
DFF192COLOR09W* * * *Color table 9
DFF194COLOR10W* * * *Color table 10
DFF196COLOR11W* * * *Color table 11
DFF198COLOR12W* * * *Color table 12
DFF19ACOLOR13W* * * *Color table 13
DFF19CCOLOR14W* * * *Color table 14
DFF19ECOLOR15W* * * *Color table 15
DFF1A0COLOR16W* * * *Color table 16
DFF1A2COLOR17W* * * *Color table 17
DFF1A4COLOR18W* * * *Color table 18
DFF1A6COLOR19W* * * *Color table 19
DFF1A8COLOR20W* * * *Color table 20
DFF1AACOLOR21W* * * *Color table 21
DFF1ACCOLOR22W* * * *Color table 22
DFF1AECOLOR23W* * * *Color table 23
DFF1B0COLOR24W* * * *Color table 24
DFF1B2COLOR25W* * * *Color table 25
DFF1B4COLOR26W* * * *Color table 26
DFF1B6COLOR27W* * * *Color table 27
DFF1B8COLOR28W* * * *Color table 28
DFF1BACOLOR29W* * * *Color table 29
DFF1BCCOLOR30W* * * *Color table 30
DFF1BECOLOR31W* * * *Color table 31
 
DFF1C0HTOTALW * * *Highest number count, horiz line (VARBEAMEN=1)
DFF1C2HSSTOPW * * *Horizontal line position for HSYNC stop
DFF1C4HBSTRTW * * *Horizontal line position for HBLANK start
DFF1C6HBSTOPW * * *Horizontal line position for HBLANK stop
DFF1C8VTOTALW * * *Highest numbered vertical line (VARBEAMEN=1)
DFF1CAVSSTOPW * * *Vertical line position for VSYNC stop
DFF1CCVBSTRTW * * *Vertical line for VBLANK start
DFF1CEVBSTOPW * * *Vertical line for VBLANK stop
DFF1D0SPRHSTRTW * * *UHRES sprite vertical start
DFF1D2SPRHSTOPW * * *UHRES sprite vertical stop
DFF1D4BPLHSTRTW * * *UHRES bit plane vertical start
DFF1D6BPLHSTOPW * * *UHRES bit plane vertical stop
DFF1D8HHPOSWW * * *DUAL mode hires H beam counter write
DFF1DAHHPOSRR * * *DUAL mode hires H beam counter read
DFF1DCBEAMCON0W* * * *Beam counter control register (SHRES,UHRES,PAL)
DFF1DEHSSTRTW * * *Horizontal sync start (VARHSY)
DFF1E0VSSTRTW * * *Vertical sync start (VARVSY)
DFF1E2HCENTERW * * *Horizontal position for Vsync on interlace
DFF1E4DIWHIGHW * * *Display window - upper bits for start/stop
DFF1E6BPLHMODW *Chunky plane modulo
DFF1E8SPRHPTHW * * *UHRES sprite pointer (high 5 bits)
DFF1EASPRHPTLW * * *UHRES sprite pointer (low 15 bits)
DFF1ECBPLHPTHW *Chunky plane pointer (hi 15 bits)
DFF1EEBPLHPTLW *Chunky plane pointer (lo 15 bits)
DFF1FCFMODEW * *Fetch mode register
 
AddressNameAccessOCS ECS AGA SAGADescription
 
DFF230clxdat0R *Sprite0 Detailed Collision
DFF232clxdat1R *Sprite1 Detailed Collision
DFF234clxdat2R *Sprite2 Detailed Collision
DFF236clxdat3R *Sprite3 Detailed Collision
DFF29EADKCON2W* * * *Audio,disk,UART control
DFF2A0AUD4LCHW *Audio channel 4 location (high 5 bits was 3 bits)
DFF2A2AUD4LCLW *Audio channel 4 location (low 15 bits)
DFF2A4AUD4LENW *Audio channel 4 length
DFF2A6AUD4PERW *Audio channel 4 period
DFF2A8AUD4VOLW *Audio channel 4 volume
DFF2AAAUD4DATW *Audio channel 4 data
DFF2ACAUD4VOL2W *Audio channel 4 volume far side
DFF2AEAUD4LENHIW *Audio channel 4 length high bits
DFF2B0AUD5LCHW *Audio channel 5 location (high 5 bits was 3 bits)
DFF2B2AUD5LCLW *Audio channel 5 location (low 15 bits)
DFF2B4AUD5LENW *Audio channel 5 length
DFF2B6AUD5PERW *Audio channel 5 period
DFF2B8AUD5VOLW *Audio channel 5 volume
DFF2BAAUD5DATW *Audio channel 5 data
DFF2BCAUD5VOL2W *Audio channel 1 volume far side
DFF2BEAUD5LENHIW *Audio channel 5 length high bits
DFF2C0AUD6LCHW *Audio channel 6 location (high 5 bits was 3 bits)
DFF2C2AUD6LCLW *Audio channel 6 location (low 15 bits)
DFF2C4AUD6LENW *Audio channel 6 length
DFF2C6AUD6PERW *Audio channel 6 period
DFF2C8AUD6VOLW *Audio channel 6 volume
DFF2CAAUD6DATW *Audio channel 6 data
DFF2CCAUD6VOL2W *Audio channel 6 volume far side
DFF2CEAUD6LENHIW *Audio channel 6 length high bits
DFF2D0AUD7LCHW *Audio channel 7 location (high 5 bits was 3 bits)
DFF2D2AUD7LCLW *Audio channel 7 location (low 15 bits)
DFF2D4AUD7LENW *Audio channel 7 length
DFF2D6AUD7PERW *Audio channel 7 period
DFF2D8AUD7VOLW *Audio channel 7 volume
DFF2DAAUD7DATW *Audio channel 7 data
DFF2DCAUD7VOL2W *Audio channel 7 volume far side
DFF2DEAUD7LENHIW *Audio channel 7 length high bits
 
DFF320SPR8PTHW *Sprite 8 pointer (high 5 bits was 3 bits)
DFF322SPR8PTLW *Sprite 8 pointer (low 15 bits)
DFF324SPR9PTHW *Sprite 9 pointer (high 5 bits was 3 bits)
DFF326SPR9PTLW *Sprite 9 pointer (low 15 bits)
DFF328SPR10PTHW *Sprite 10 pointer (high 5 bits was 3 bits)
DFF32ASPR10PTLW *Sprite 10 pointer (low 15 bits)
DFF32CSPR11PTHW *Sprite 11 pointer (high 5 bits was 3 bits)
DFF32ESPR11PTLW *Sprite 11 pointer (low 15 bits)
DFF330SPR12PTHW *Sprite 12 pointer (high 5 bits was 3 bits)
DFF332SPR12PTLW *Sprite 12 pointer (low 15 bits)
DFF334SPR13PTHW *Sprite 13 pointer (high 5 bits was 3 bits)
DFF336SPR13PTLW *Sprite 13 pointer (low 15 bits)
DFF338SPR14PTHW *Sprite 14 pointer (high 5 bits was 3 bits)
DFF33ASPR14PTLW *Sprite 14 pointer (low 15 bits)
DFF33CSPR15PTHW *Sprite 15 pointer (high 5 bits was 3 bits)
DFF33ESPR15PTLW *Sprite 15 pointer (low 15 bits)
+ + + diff --git a/sources/official/saga-registers/sagacontrol.htm b/sources/official/saga-registers/sagacontrol.htm new file mode 100755 index 0000000..1d0dc98 --- /dev/null +++ b/sources/official/saga-registers/sagacontrol.htm @@ -0,0 +1,31 @@ + + +
+
+SAGA CONTROL Register
+
+
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 15    | SET/CLR            |                                |
+         | 6     | FORCE OCS MODE     |                                |
+         | 5     | Enable PAL ZOOM    |                                |
+         | 4     | --                 |                                |
+         | 3     | --                 |                                |
+         | 2     | Enable Zoom        |                                |
+         | 1     | Scanline Mode      |                                |
+         | 0     | Scanlines On/Off   |                                |
+         +-------+----------+-------------------------------------------+
+
+Examples: + +No Zoom = apoke $DFF3EC 2 $0024
+ZOOM1 (NTSC) = apoke $DFF3EC 2 $8004
+ZOOM2 (NTSC+) = apoke $DFF3EC 2 $8020
+ZOOM3 (PAL) = apoke $DFF3EC 2 $8024
+ + + + diff --git a/sources/official/saga-registers/screenadjust.htm b/sources/official/saga-registers/screenadjust.htm new file mode 100755 index 0000000..86602dc --- /dev/null +++ b/sources/official/saga-registers/screenadjust.htm @@ -0,0 +1,29 @@ + + +
+
+SCREEN ADJUST PORT
+
+         This register allows adjusting the SAGA screenmodes
+
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 31-24 | Number  | 8bit Screenmode-ID                         |
+         | 23-16 | --      | 8bit 00 reserved                           |
+         | 15-08 | -Y      | 8bit 0Y more rows                          |
+         | 07-00 | -X      | 8bit 0X more widthX                        |
+         +-------+----------+-------------------------------------------+
+
+Example:
+
+ move.l #$00FF0000,$DFF380   -- set color0 = RED
+ move.l #$01FFFF00,$DFF380   -- set color1 = YELLOW
+
+Copper:
+ dc.w  $8380,$00FF,$0000     -- set color0 = RED
+
+
+ + diff --git a/sources/official/saga-registers/serdat.htm b/sources/official/saga-registers/serdat.htm new file mode 100755 index 0000000..f8cba48 --- /dev/null +++ b/sources/official/saga-registers/serdat.htm @@ -0,0 +1,64 @@ + + +
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+SERDAT     030      W       P      Serial port data and stop bits write
+                                       (transmit data buffer)
+
+                 This address writes data to a transmit data buffer.
+                 Data from this buffer is moved into a serial shift
+                 register for output transmission whenever it is
+                 empty.  This sets the interrupt request TBE
+                 (transmit buffer empty). A stop bit must be
+                 provided as part of the data word. The length of
+                 the data word is set by the position of the stop
+                 bit.
+
+                 BIT# 15,14,13,12,11,10,09,08,07,06,05,04,03,02,01,00
+                      -----------------------------------------------
+                 USE   0  0  0  0  0  0  S D8 D7 D6 D5 D4 D3 D2 D1 D0
+
+                 Note:  S = stop bit = 1, D = data bits.
+
+SERDATR    018      R       P      Serial port data and status read
+                                       (receive data buffer)
+
+                 This address reads data from a receive data buffer.
+                 Data in this buffer is loaded from a receiving
+                 shift register whenever it is full.  Several
+                 interrupt request bits are also read at this
+                 address, along with the data, as shown below.
+
+                 BIT#  SYM          FUNCTION
+                 ----  ----         -----------------------
+                 15    OVRUN        Serial port receiver overrun.
+                                    Reset by resetting bit 11 of
+                                     INTREQ .
+                 14    RBF          Serial port receive buffer full
+                                    (mirror).
+                 13    TBE          Serial port transmit buffer
+                                    empty (mirror).
+                 12    TSRE         Serial port transmit shift
+                                    register empty.
+                                    Reset by loading into buffer.
+                 11    RXD          RXD pin receives UART serial
+                                    data for direct bit test by
+                                    the microprocessor.
+                 10     0           Not used
+                 09    STP          Stop bit
+                 08  STP-DB8        Stop bit if LONG, data bit if
+                                    not.
+                 07    DB7          Data bit
+                 06    DB6          Data bit
+                 05    DB5          Data bit
+                 04    DB4          Data bit
+                 03    DB3          Data bit
+                 02    DB2          Data bit
+                 01    DB1          Data bit
+                 00    DB0          Data bit
+
+ + diff --git a/sources/official/saga-registers/serdatr.htm b/sources/official/saga-registers/serdatr.htm new file mode 100755 index 0000000..94e404e --- /dev/null +++ b/sources/official/saga-registers/serdatr.htm @@ -0,0 +1,66 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+SERDAT     030      W       P      Serial port data and stop bits write
+                                       (transmit data buffer)
+
+                 This address writes data to a transmit data buffer.
+                 Data from this buffer is moved into a serial shift
+                 register for output transmission whenever it is
+                 empty.  This sets the interrupt request TBE
+                 (transmit buffer empty). A stop bit must be
+                 provided as part of the data word. The length of
+                 the data word is set by the position of the stop
+                 bit.
+
+                 BIT# 15,14,13,12,11,10,09,08,07,06,05,04,03,02,01,00
+                      -----------------------------------------------
+                 USE   0  0  0  0  0  0  S D8 D7 D6 D5 D4 D3 D2 D1 D0
+
+                 Note:  S = stop bit = 1, D = data bits.
+
+SERDATR    018      R       P      Serial port data and status read
+                                       (receive data buffer)
+
+                 This address reads data from a receive data buffer.
+                 Data in this buffer is loaded from a receiving
+                 shift register whenever it is full.  Several
+                 interrupt request bits are also read at this
+                 address, along with the data, as shown below.
+
+                 BIT#  SYM          FUNCTION
+                 ----  ----         -----------------------
+                 15    OVRUN        Serial port receiver overrun.
+                                    Reset by resetting bit 11 of
+                                     INTREQ .
+                 14    RBF          Serial port receive buffer full
+                                    (mirror).
+                 13    TBE          Serial port transmit buffer
+                                    empty (mirror).
+                 12    TSRE         Serial port transmit shift
+                                    register empty.
+                                    Reset by loading into buffer.
+                 11    RXD          RXD pin receives UART serial
+                                    data for direct bit test by
+                                    the microprocessor.
+                 10     0           Not used
+                 09    STP          Stop bit
+                 08  STP-DB8        Stop bit if LONG, data bit if
+                                    not.
+                 07    DB7          Data bit
+                 06    DB6          Data bit
+                 05    DB5          Data bit
+                 04    DB4          Data bit
+                 03    DB3          Data bit
+                 02    DB2          Data bit
+                 01    DB1          Data bit
+                 00    DB0          Data bit
+
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/serper.htm b/sources/official/saga-registers/serper.htm new file mode 100755 index 0000000..c8bb3e0 --- /dev/null +++ b/sources/official/saga-registers/serper.htm @@ -0,0 +1,22 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+SERPER     032      W       P      Serial port period and control
+
+                 This register contains the control bit LONG referred to
+                 above, and a 15-bit number defining the serial port
+                 baud rate. If this number is N, then the baud rate is
+                 1 bit every (N+1)*.2794  microseconds.
+
+                 BIT#   SYM     FUNCTION
+                 -----  ----    ---------------
+                 15     LONG    Defines serial receive as 9-bit word.
+                 14-00  RATE    Defines baud rate=1/((N+1)*.2794 microsec.)
+
+ + diff --git a/sources/official/saga-registers/shiftdown.htm b/sources/official/saga-registers/shiftdown.htm new file mode 100755 index 0000000..66cf1c7 --- /dev/null +++ b/sources/official/saga-registers/shiftdown.htm @@ -0,0 +1,19 @@ + + +
+
+SAGA CONTROL Register
+
+
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 15 ..8 | Y shift           |                                |
+         | 7..0   | X shift           |                                |
+         +-------+----------+-------------------------------------------+
+
+ + + + diff --git a/sources/official/saga-registers/spritecol.htm b/sources/official/saga-registers/spritecol.htm new file mode 100755 index 0000000..c978416 --- /dev/null +++ b/sources/official/saga-registers/spritecol.htm @@ -0,0 +1,29 @@ + + +
+
+SPRITE COLOR PORT
+
+         This register allows direct setting of 256 Sprite colors
+
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 31-24 | number  | 8bit Colornumber                           |
+         | 23-16 | RED     | 8bit Red                                   |
+         | 15-08 | GREEN   | 8bit Green                                 |
+         | 07-00 | BLUE    | 8bit Blue                                  |
+         +-------+----------+-------------------------------------------+
+
+Example:
+
+ move.l #$00FF0000,$DFF384   -- set color0 = RED
+ move.l #$01FFFF00,$DFF384   -- set color1 = YELLOW
+
+Copper:
+ dc.w  $8384,$00FF,$0000     -- set color0 = RED
+
+
+ + diff --git a/sources/official/saga-registers/sprxctl.htm b/sources/official/saga-registers/sprxctl.htm new file mode 100755 index 0000000..85c245c --- /dev/null +++ b/sources/official/saga-registers/sprxctl.htm @@ -0,0 +1,40 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+SPRxCTL    142      W     A D( E ) Sprite x vert stop position and
+                                       control data
+SPRxPOS    140      W      A D     Sprite x vert-horiz start position data
+
+                 These two registers work together as position, size and
+                 feature sprite-control registers.  They are usually loaded
+                 by the sprite DMA channel during horizontal blank;
+                 however, they may be loaded by either processor at any
+                 time.  SPRxPOS register:
+
+                 BIT#   SYM      FUNCTION
+                 ----   ----     -----------------------------
+                 15-08  SV7-SV0  Start vertical value. High bit(SV8) is
+                                 in SPRxCTL register below.
+                 07-00  SH8-SH1  Start horizontal value. Low bit(SH0) is
+                                 in SPRxCTL register below.
+
+                 SPRxCTL register (writing this address disables sprite
+                                   horizontal comparator circuit):
+
+                 BIT#    SYM       FUNCTION
+                 ----    --------  -----------------------------
+                 15-08   EV7-EV0   End (stop) vertical value low 8 bits
+                 07      ATT       Sprite attach control bit (odd sprites)
+                 06-04    X        Not used
+                 02      SV8       Start vertical value high bit
+                 01      EV8       End (stop) vertical value high bit
+                 00      SH0       Start horizontal value low bit
+
+
+ + diff --git a/sources/official/saga-registers/sprxdata.htm b/sources/official/saga-registers/sprxdata.htm new file mode 100755 index 0000000..0ea8a10 --- /dev/null +++ b/sources/official/saga-registers/sprxdata.htm @@ -0,0 +1,27 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+SPRxDATA   144      W       D     Sprite x image data register A
+SPRxDATB   146      W       D     Sprite x image data register B
+
+                 These registers buffer the sprite image data. They are
+                 usually loaded by the sprite DMA channel but may be
+                 loaded by either processor at any time.  When a
+                 horizontal comparison occurs, the buffers are dumped
+                 into shift registers and serially outputted to the
+                 display, MSB first on the left.
+
+                 NOTE: Writing to the A buffer enables (arms) the sprite.
+                 Writing to the SPRxCTL register disables the sprite.
+                 If enabled, data in the A and B buffers will be outputted
+                 whenever the beam counter equals the sprite horizontal
+                 position value in the  SPRxPOS  register.
+
+
+ + diff --git a/sources/official/saga-registers/sprxpos.htm b/sources/official/saga-registers/sprxpos.htm new file mode 100755 index 0000000..13b8bbb --- /dev/null +++ b/sources/official/saga-registers/sprxpos.htm @@ -0,0 +1,41 @@ + + +
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+SPRxCTL    142      W     A D( E ) Sprite x vert stop position and
+                                       control data
+SPRxPOS    140      W      A D     Sprite x vert-horiz start position data
+
+                 These two registers work together as position, size and
+                 feature sprite-control registers.  They are usually loaded
+                 by the sprite DMA channel during horizontal blank;
+                 however, they may be loaded by either processor at any
+                 time.  SPRxPOS register:
+
+                 BIT#   SYM      FUNCTION
+                 ----   ----     -----------------------------
+                 15-08  SV7-SV0  Start vertical value. High bit(SV8) is
+                                 in SPRxCTL register below.
+                 07-00  SH8-SH1  Start horizontal value. Low bit(SH0) is
+                                 in SPRxCTL register below.
+
+                 SPRxCTL register (writing this address disables sprite
+                                   horizontal comparator circuit):
+
+                 BIT#    SYM       FUNCTION
+                 ----    --------  -----------------------------
+                 15-08   EV7-EV0   End (stop) vertical value low 8 bits
+                 07      ATT       Sprite attach control bit (odd sprites)
+                 06-04    X        Not used
+                 02      SV8       Start vertical value high bit
+                 01      EV8       End (stop) vertical value high bit
+                 00      SH0       Start horizontal value low bit
+
+
+ + diff --git a/sources/official/saga-registers/sprxpth.htm b/sources/official/saga-registers/sprxpth.htm new file mode 100755 index 0000000..48df63b --- /dev/null +++ b/sources/official/saga-registers/sprxpth.htm @@ -0,0 +1,24 @@ + + +
+
+
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+SPRxPTH    120      W       A     Sprite x pointer (high 3 bits)
+SPRxPTL    122      W       A     Sprite x pointer (low 15 bits)
+
+                 This pair of registers contains the 18-bit address
+                 of sprite x (x=0,1,2,3,4,5,6,7) DMA data. These address
+                 registers must be initialized by the processor or Copper
+                 every vertical blank time.
+
+
+
+
+ + diff --git a/sources/official/saga-registers/strequ.htm b/sources/official/saga-registers/strequ.htm new file mode 100755 index 0000000..b4a5843 --- /dev/null +++ b/sources/official/saga-registers/strequ.htm @@ -0,0 +1,28 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+STREQU     038      S       D     Strobe for horizontal sync with VB
+                                      and EQU
+STRHOR     03C      S      D P    Strobe for horizontal sync
+STRLONG    03E      S      D( E ) Strobe for identification of long
+                                      horizontal line
+
+                 One of the first three strobe addresses above is
+                 placed on the destination address bus during the
+                 first refresh time slot.  The fourth strobe shown
+                 above is used during the second refresh time slot of
+                 every other line to identify lines with long counts
+                 (228).  There are four refresh time slots, and any
+                 not used for strobes will leave a null (FF) address
+                 on the destination address bus.
+
+STRVBL     03A      S       D     Strobe for horizontal sync with VB
+                                  (vertical blank)
+
+ + diff --git a/sources/official/saga-registers/vampversion.htm b/sources/official/saga-registers/vampversion.htm new file mode 100755 index 0000000..e76c529 --- /dev/null +++ b/sources/official/saga-registers/vampversion.htm @@ -0,0 +1,19 @@ + + +
+
+VAMP VERSION
+
+         This register card version and CPU Clockrate
+
+
+         +-------+----------+-------------------------------------------+
+         | BIT#  | FUNCTION | DESCRIPTION                               |
+         +-------+----------+-------------------------------------------+
+         | 15-08 | Card    | Card Version                               |
+         |       |         | 1=V600, 2=V500, 3=V4_500(Firebird=500/Salamander=2000/Phoenix=1000), 4=V4_1200(Icedrake), 5=V4SA, 6=V1200, 7=V4_600(Manticore)  |
+         | 07-00 | Clock   | Clock multiplier                           |
+         +-------+----------+-------------------------------------------+
+
+ + diff --git a/sources/official/saga-registers/vbstrt.htm b/sources/official/saga-registers/vbstrt.htm new file mode 100755 index 0000000..8dbbd7e --- /dev/null +++ b/sources/official/saga-registers/vbstrt.htm @@ -0,0 +1,17 @@ + + +
+
+
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+VBSTOP     1CE      W      A( E ) Vertical line for VBLANK stop
+VBSTRT     1CC      W      A( E ) Vertical line for VBLANK start
+
+
+ + diff --git a/sources/official/saga-registers/vhposr.htm b/sources/official/saga-registers/vhposr.htm new file mode 100755 index 0000000..637ca16 --- /dev/null +++ b/sources/official/saga-registers/vhposr.htm @@ -0,0 +1,22 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+VHPOSR     006      R       A     Read vertical and horizontal position of
+                                      beam or lightpen
+VHPOSW     02C      W       A     Write vertical and horizontal position
+                                      of beam or lightpen
+
+                 BIT# 15,14,13,12,11,10,09,08,07,06,05,04,03,02,01,00
+                      -----------------------------------------------
+                 USE  V7 V6 V5 V4 V3 V2 V1 V0,H8 H7 H6 H5 H4 H3 H2 H1
+
+                 RESOLUTION = 1/160 of screen width (280 ns)
+
+
+ + diff --git a/sources/official/saga-registers/vposr.htm b/sources/official/saga-registers/vposr.htm new file mode 100755 index 0000000..4b5f49a --- /dev/null +++ b/sources/official/saga-registers/vposr.htm @@ -0,0 +1,22 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+VPOSR      004      R      A( E ) Read vertical most significant bit
+                                      (and frame flop)
+VPOSW      02A      W       A     Write vertical most significant bit
+                                      (and frame flop)
+
+                 BIT# 15,14,13,12,11,10,09,08,07,06,05,04,03,02,01,00
+                      -----------------------------------------------
+                 USE  LOF-- -- -- -- -- -- --,-- -- -- -- -- -- -- V8
+
+                 LOF=Long frame (auto toggle control bit in  BPLCON0 )
+
+
+ + \ No newline at end of file diff --git a/sources/official/saga-registers/vsstrt.htm b/sources/official/saga-registers/vsstrt.htm new file mode 100755 index 0000000..5f82938 --- /dev/null +++ b/sources/official/saga-registers/vsstrt.htm @@ -0,0 +1,16 @@ + + +
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+VSSTOP     1CA      W      A( E ) Vertical line position for VSYNC stop
+VSSTRT     1E0      W      A( E ) Vertical sync start   (VARVSY)
+VTOTAL     1C8      W      A( E ) Highest numbered vertical line
+                                      (VARBEAMEN=1)
+
+
+ + diff --git a/sources/official/saga-registers/vtotal.htm b/sources/official/saga-registers/vtotal.htm new file mode 100755 index 0000000..167deda --- /dev/null +++ b/sources/official/saga-registers/vtotal.htm @@ -0,0 +1,21 @@ + + +
+
+
+                          Agnus/
+                  Read/   Denise/
+Register Address  Write   Paula         Function
+-------- -------  -----   -------       --------
+HBSTOP     1C6      W      A( E ) Horizontal line position for HBLANK stop
+HBSTRT     1C4      W      A( E ) Horizontal line position for HBLANK start
+HCENTER    1E2      W      A( E ) Horizontal position for Vsync on interlace
+HSSTOP     1C2      W      A( E ) Horizontal line position for HSYNC stop
+HSSTRT     1DE      W      A( E ) Horizontal sync start (VARHSY)
+HTOTAL     1C0      W      A( E ) Highest number count, horiz. line
+                                     (VARBEAMEN=1)
+
+
+
+ + diff --git a/tools/intake/sagaregs.py b/tools/intake/sagaregs.py new file mode 100644 index 0000000..8142d33 --- /dev/null +++ b/tools/intake/sagaregs.py @@ -0,0 +1,937 @@ +#!/usr/bin/env python3 +"""Document intake: convert the SAGA register documentation +(sources/official/saga-registers/, HTML) into core/saga-registers/. + + sagaregs.py regenerate core/saga-registers/ + sagaregs.py --check exit 1 if the generated files are out of date + +The HTML is leading (CONTRIBUTING.md section 11). Never edit the generated +files: change the original, or this script, and regenerate. Uses only the +Python standard library. + +The original is a register table (index.htm) with one page per register or +register group. This script takes only the SAGA-specific registers (the rows +where OCS, ECS and AGA are empty, plus the SAGA addresses listed in +EXTRA_ROWS), skips the Atari section, and applies the corrections in +CORRECTIONS. Facts that the original lacks come from ADDITIONS, each with +its source tag. Both lists are printed in core/saga-registers/index.md. +""" +import html +import os +import re +import sys + +ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) +SRCDIR = "sources/official/saga-registers" +SOURCE = f"{SRCDIR}/index.htm" +OUTDIR = "core/saga-registers" +OWNER = "WDrijver" +CORE = "Core 12000+" +SOURCE_NAME = "SAGA register documentation, sources/official/saga-registers/ (HTML)" +WD = "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04" +WDS = "WDrijver, 2026-11-04" +APOLLOLIB = ("ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib " + "(ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)") +APOLLOLIB_OLD = ("ApolloLib, older copy in ApolloClaude docs/toolchain/_ApolloLib " + "(ApolloCrossDev_Defines.h), 2026-11-04") +EX_PIP = ("Example SAGAPiP.c, github.com/WDrijver/ApolloCrossDev Projects/SAGAPiP, " + "commit 2dfaa5c (2026-09-02)") +EX_POINTER = ("Example ApolloPointer.c, github.com/WDrijver/ApolloCrossDev " + "Projects/ApolloPointer, commit 2dfaa5c (2026-09-02)") +APOLLOOS = ("ApolloOS source, github.com/ApolloTeam-dev/ApolloOS.R10 " + "arch/m68k-amiga/hidd/sagagfx/sagagfx_hw.h, commit ca5ef46 (2025-06-10)") +MAGGIE = "maggie.library samples, see os/libraries/maggie-library.md" + +ACCESS = {"R": "read", "W": "write", "S": "strobe (a write of any value " + "triggers the action)", "ER": "early read"} + + +# ------------------------------------------------------------ the original + +def read(name): + with open(os.path.join(ROOT, SRCDIR, name), encoding="latin-1") as f: + return f.read() + + +def index_rows(): + """The rows of index.htm: (address, name, page, access, flags, description). + flags is the set of chipsets marked with '*'. Stops at the Atari section.""" + rows = [] + for part in re.split(r"]*>", part) + body = re.split(r"|", part[m.end():])[0] + cells = re.findall(r"]*>(.*?)(?=|$)", body, re.S) + if not cells: + continue + def text(c): + c = re.sub(r"", "\n", c) + c = html.unescape(re.sub(r"<[^>]+>", "", c)) + return "\n".join(re.sub(r"\s+", " ", ln).strip() + for ln in c.split("\n")).strip() + first = text(cells[0]) + if "ATARI" in first.upper(): + break + if not re.match(r"^DF[0-9A-Fa-f]", first) or len(cells) < 8: + continue + link = re.search(r'href="([^"]+)"', cells[1]) + flags = {n for n, c in zip(("OCS", "ECS", "AGA", "SAGA"), cells[3:7]) + if text(c) == "*"} + rows.append(dict(addr=first, name=text(cells[1]), + page=link.group(1) if link else None, + access=text(cells[2]), flags=flags, + desc=text(cells[7]).replace("\n", " "), notes=[])) + return rows + + +def page(name): + """The text of a register page, including any text after its
 block,
+    without empty edge lines."""
+    if not name or not os.path.isfile(os.path.join(ROOT, SRCDIR, name)):
+        return None
+    t = re.sub(r"", "\n", read(name), flags=re.I)
+    t = html.unescape(re.sub(r"<[^>]+>", "", t))
+    lines = [ln.rstrip().expandtabs() for ln in t.split("\n")]
+    while lines and not lines[0].strip():
+        lines.pop(0)
+    while lines and not lines[-1].strip():
+        lines.pop()
+    return lines
+
+
+def box_table(lines):
+    """The bit table of a page drawn with +---+ and | characters, as rows of
+    (bits, function, description). A row with empty bits continues the row
+    above it."""
+    rows = []
+    for ln in lines:
+        s = ln.strip()
+        if not s.startswith("|"):
+            continue
+        cells = [c.strip() for c in s.strip("|").split("|")]
+        if cells[0].upper().startswith("BIT"):
+            continue
+        cells = (cells + ["", ""])[:3] if len(cells) < 3 else \
+            [cells[0], cells[1], " ".join(c for c in cells[2:] if c)]
+        if not cells[0] and rows:
+            extra = " ".join(c for c in cells[1:] if c)
+            rows[-1][2] = (rows[-1][2] + " " + extra).strip()
+            continue
+        rows.append(cells)
+    return rows
+
+
+def prose(lines, skip=0):
+    """Page text after the table header lines, joined into paragraphs."""
+    paras, cur = [], []
+    for ln in lines[skip:]:
+        s = ln.strip()
+        if not s or s.startswith("+-") or s.startswith("-----"):
+            if cur:
+                paras.append(" ".join(cur))
+                cur = []
+            continue
+        cur.append(re.sub(r"\s+", " ", s))
+    if cur:
+        paras.append(" ".join(cur))
+    return paras
+
+
+def md(s):
+    return s.replace("|", "\\|").replace("*", "\\*").replace("_", "\\_")
+
+
+def table(head, rows):
+    out = ["| " + " | ".join(head) + " |", "|" + "---|" * len(head)]
+    out += ["| " + " | ".join(md(str(c)) if not str(c).startswith("`") else str(c)
+                              for c in r) + " |" for r in rows]
+    return out
+
+
+def bits_md(rows):
+    return table(["Bits", "Function", "Description"],
+                 [[bitrange(b), f, d] for b, f, d in rows])
+
+
+def bitrange(b):
+    """'15.08', '15 ..8' and '31-24' all become '15–8' style ranges."""
+    parts = [p for p in re.split(r"[\s.\-]+", b.strip()) if p]
+    return "–".join(str(int(p)) if p.isdigit() else p for p in parts)
+
+
+# ------------------------------------------------------------ corrections
+
+# Each correction: (address, field, original value, corrected value, source).
+# They are printed in index.md, so the original can be fixed.
+CORRECTIONS = [
+    ("DFFAA0", "addr", "DFFAA0", "DFF4A0",
+     "typo in the original: the AUD10 block is at $DFF4A0, as the channel layout requires"),
+    ("DFF4C4C", "addr", "DFF4C4C", "DFF4CC",
+     "typo in the original: AUD12PER is at $DFF4CC, as the channel layout requires"),
+    ("DFF21c", "addr", "DFF21c", "DFF21C", "upper case, as everywhere else"),
+    ("DFF430", "desc", "Audio channel 1 location (32bit PTR)",
+     "Audio channel 3 location (32bit PTR)", "typo in the original: this is channel 3"),
+    ("DFF1EC", "desc", "Chunky plane pointer (hi 15 bits)",
+     "Chunky plane pointer (hi 16 bits)",
+     "the high word of a 32-bit pointer has 16 bits"),
+    ("DFF3EC", "access", "R", "W", f"$DFF3EC is writable ({WDS})"),
+    ("DFF1EE", "desc", "Chunky plane pointer (lo 15 bits)",
+     "Chunky plane pointer (lo 16 bits)",
+     "the low word of a 32-bit pointer has 16 bits"),
+    ("DFF20C", "desc", "Vaniall DB9 Joystick-mouse 1 data (vert, horiz)",
+     "Vanilla DB9 Joystick-mouse 1 data (vert, horiz)", "typo in the original"),
+]
+
+# SAGA-specific rows that the original marks as OCS/ECS/AGA too: new SAGA
+# addresses or a classic address with a SAGA meaning.
+EXTRA_ROWS = {
+    "DFF20A": "a SAGA address; the original also marks OCS, ECS and AGA",
+    "DFF20C": "a SAGA address; the original also marks OCS, ECS and AGA",
+    "DFF1D0": "on SAGA this is the pointer X position; "
+              "the original also marks ECS and AGA",
+    "DFF1D2": "on SAGA this is the pointer Y position; "
+              "the original also marks ECS and AGA",
+}
+
+# Pages the original links wrongly or not at all, by register name pattern.
+PAGE_FIX = [
+    (r"^AUD\d+L$", "audxl.htm"),
+    (r"^AUD\d+LEN$", "audxlen.htm"),
+    (r"^AUD\d+VOL$", "audnvol.htm"),
+    (r"^AUD\d+CTRL$", "audxctrl.htm"),
+    (r"^AUD\d+PER$", "audxper.htm"),
+]
+
+
+def apply_corrections(rows):
+    applied = []
+    for addr, field, old, new, why in CORRECTIONS:
+        hit = [r for r in rows if r["addr"] == addr and r[field] == old] if field != "addr" \
+            else [r for r in rows if r["addr"] == old]
+        if not hit:
+            raise SystemExit(f"correction does not match the original: {addr} {field}")
+        for r in hit:
+            r[field] = new
+            r["notes"].append(f"corrected: {why}")
+        applied.append((addr, field, old, new, why))
+    return applied
+
+
+def saga_rows():
+    rows = index_rows()
+    applied = apply_corrections(rows)
+    keep = [r for r in rows if "SAGA" in r["flags"] and
+            (not r["flags"] - {"SAGA"} or r["addr"] in EXTRA_ROWS)]
+    for r in keep:
+        if r["addr"] in EXTRA_ROWS:
+            r["notes"].append(EXTRA_ROWS[r["addr"]])
+    return rows, keep, applied
+
+
+def addr(a):
+    return int(a.split("/")[0], 16)
+
+
+def row_md(r, with_page=False):
+    a = r["addr"]
+    a = f"`${a}`" if "/" not in a else \
+        f"`${a.split('/')[0]}`, `${a.split('/')[0][:-2]}{a.split('/')[1]}`"
+    cells = [a, md(r["name"]), md(r["access"]), md(r["desc"]) or "–"]
+    return "| " + " | ".join(cells) + " |"
+
+
+def reg_table(rows):
+    out = ["| Address | Name | Access | Description (original) |", "|---|---|---|---|"]
+    out += [row_md(r) for r in rows]
+    notes = [(r["addr"], n) for r in rows for n in r["notes"]]
+    if notes:
+        out += [""] + [f"- `${a}`: {n}." for a, n in notes]
+    return out
+
+
+# ------------------------------------------------------------ output files
+
+def frontmatter(title, components, tags, related, sources, basis):
+    lines = ["---", f'title: "{title}"', "type: reference", f"owner: {OWNER}",
+             "status: draft", "origin: official", f"basis: [{', '.join(basis)}]",
+             f"components: [{', '.join(components)}]",
+             "applies_to:", f'  core: "{CORE}"', "  os: [any]",
+             f"tags: [{', '.join(tags)}]"]
+    if related:
+        lines.append("related:")
+        lines += [f"  - {r}" for r in related]
+    lines += ["sources:"] + [f'  - "{s}"' for s in [SOURCE_NAME] + sources]
+    lines += [f"generated_from: {SOURCE}", "---", "",
+              "", ""]
+    return lines
+
+
+def tidy(lines):
+    out = []
+    for ln in lines:
+        if ln == "" and out and out[-1] == "":
+            continue
+        out.append(ln.rstrip())
+    while out and out[-1] == "":
+        out.pop()
+    return "\n".join(out) + "\n"
+
+
+def doc(name, title, components, tags, summary, details, diff, rules,
+        sources=(), basis=("official",), related=()):
+    rel = ([] if name == "index.md" else [f"{OUTDIR}/index.md"]) + list(related)
+    lines = frontmatter(title, components, tags, rel, list(sources), basis)
+    lines += ["## Summary", "", summary, "", "## Details", ""] + details
+    lines += ["", "## Differences from AmigaOS / AROS / 68060", ""] + diff
+    lines += ["", "## Do / Don't", ""] + [f"- {r}" for r in rules]
+    return name, tidy(lines)
+
+
+def pick(rows, lo, hi):
+    return [r for r in rows if lo <= addr(r["addr"]) <= hi]
+
+
+def by_addr(rows, a):
+    return next(r for r in rows if r["addr"] == a)
+
+
+def chunky_plane(rows):
+    gm = page("gfxmode.htm")
+    modes, fmts, part = [], [], None
+    for ln in gm:
+        if "Resolution" in ln:
+            part = modes
+        elif "Pixelformat" in ln:
+            part = fmts
+        m = re.search(r"\$([0-9A-F]{2})\s*=\s*(.*?)\s*\|?\s*$", ln)
+        if m and part is not None:
+            part.append((m.group(1), m.group(2).rstrip("| ").strip()))
+    res = []
+    for code, rest in modes:
+        m = re.match(r"(\d+x\d+)\s+(\d+Hz)\s+(\d+M[Hh]z)\s*(x2 x2)?", rest)
+        res.append([f"`${code}`", m.group(1), m.group(2), m.group(3).replace("Mhz", "MHz"),
+                    "2x2" if m.group(4) else "–"])
+    fm = [[f"`${c}`", d or "(empty in the original)"] for c, d in fmts]
+    mod = page("bplhmod.htm")
+    ptr = page("bplhpth.htm")
+    details = ["### Registers", ""] + reg_table(pick(rows, 0xDFF1E6, 0xDFF1F4))
+    details += ["", "### GFXMODE (`$DFF1F4`)", "",
+                prose(gm, 1)[0] if prose(gm, 1) else "", "",
+                "Bits 15–8 select the resolution, bits 7–0 the pixel format. "
+                "Write it as one word: `(resolution << 8) | format`.", "",
+                "#### Resolution (bits 15–8)", ""]
+    details += table(["Value", "Resolution", "Refresh", "Pixel clock", "Pixel doubling"], res)
+    details += ["", "`$00` has no description in the original. The original writes "
+                "84 MHz for `$13` and 85 MHz for the other high-resolution modes.", "",
+                "#### Pixel format (bits 7–0)", ""]
+    details += table(["Value", "Format"], fm)
+    details += ["", "Values `$08`–`$0B` are Atari planar formats (ApolloLib names them "
+                "APOLLO_ATARI_1BIT to _8BIT) (SRC).", "",
+                "### Chunky plane pointer and modulo", "",
+                f"- BPLHPTH/BPLHPTL (`$DFF1EC`): {' '.join(prose(ptr, 1))}",
+                f"- BPLHMOD (`$DFF1E6`): {' '.join(prose(mod, 1))} The original's "
+                "text says \"UHRES bitplane pointer\"; on SAGA it is the chunky plane: "
+                "the number of bytes skipped after each row (ApolloLib, SRC).", "",
+                "### Reading the current mode back", "",
+                "The original gives no read address. maggie.library's samples save "
+                "the current mode and frame pointer from `$DFE1F4` and `$DFE1EC` "
+                "(SRC, see [maggie-library.md](../../os/libraries/maggie-library.md)). "
+                "Whether every SAGA register reads back at `$DFExxx` is an open "
+                "question (see [index.md](index.md))."]
+    return doc("chunky-plane.md", "SAGA chunky plane: GFXMODE, pointer and modulo",
+               ["saga-video-isabelle"], ["saga", "isabelle", "gfxmode", "chunky", "registers"],
+               "The SAGA chunky plane is a linear framebuffer in any RAM. GFXMODE "
+               "(`$DFF1F4`) selects resolution and pixel format, BPLHPT (`$DFF1EC`) "
+               "points to the pixels and BPLHMOD (`$DFF1E6`) sets the row modulo.",
+               details,
+               ["- Classic Amiga chipsets have only planar bitplanes in Chip RAM. "
+                "The chunky plane has 8- to 32-bit pixels and can be in Fast RAM.",
+                "- On ECS, `$DFF1E6`/`$DFF1EC` were BPLHMOD/BPLHPT for UHRES "
+                "bitplanes; SAGA reuses the names for the chunky plane."],
+               ["DO write GFXMODE as one word, resolution in the high byte.",
+                "DO set the pointer and modulo before you switch the mode.",
+                "DON'T rely on GFXMODE `$00` or pixel format `$07`: the original "
+                "describes neither."],
+               sources=[APOLLOLIB, MAGGIE], basis=["official", "source-code"])
+
+
+def colour_ports(rows):
+    ports = [("planarcol.htm", "DFF380"), ("spritecol.htm", "DFF384"),
+             ("chunkycol.htm", "DFF388"), ("pipcol.htm", "DFF38C")]
+    bits = box_table(page("planarcol.htm"))
+    details = ["### Registers", ""] + reg_table(pick(rows, 0xDFF380, 0xDFF38E))
+    details += ["", "Each port is one 32-bit register (the original lists its high "
+                "and low word, H and L). A 32-bit write sets one entry of a "
+                "256-colour table:", ""] + bits_md(bits)
+    details += ["", "| Port | Address | Table |", "|---|---|---|",
+                "| Planar | `$DFF380` | Bitplane colours (256) |",
+                "| Sprite | `$DFF384` | Sprite colours (256) |",
+                "| Chunky | `$DFF388` | Chunky plane in 8-bit mode (256) |",
+                "| PIP 1 | `$DFF38C` | PIP 1 in 8-bit mode (256) |",
+                "| PIP 2 | `$DFF37C` | PIP 2 in 8-bit mode (256) (SRC, not in the original) |",
+                "", "### Example (original)", "", "```asm",
+                "    move.l  #$00FF0000,$DFF380   ; colour 0 = red",
+                "    move.l  #$01FFFF00,$DFF380   ; colour 1 = yellow",
+                "```", "",
+                "The original also shows a Copper form, `dc.w $8380,$00FF,$0000` "
+                "(\"set color0 = RED\"). This is three words, while a classic Copper "
+                "MOVE has two. How the SAGA Copper encodes a 32-bit MOVE is an open "
+                "question (see [index.md](index.md)); don't use the form until it is "
+                "documented."]
+    return doc("colour-ports.md", "SAGA colour ports (24-bit palettes)",
+               ["saga-video-isabelle"], ["saga", "isabelle", "palette", "colour", "registers"],
+               "SAGA sets 24-bit palette entries through 32-bit colour ports: one "
+               "write gives the entry number and its red, green and blue. There is one "
+               "port each for the planar, sprite, chunky and PIP palettes.",
+               details,
+               ["- Classic COLORxx registers (`$DFF180`–`$DFF1BE`) hold 32 entries; AGA "
+                "reaches 256 through banks and BPLCON3. A SAGA port writes any of 256 "
+                "entries in one 32-bit write."],
+               ["DO write the port with one `move.l`.",
+                "DON'T use the three-word Copper form from the original yet."],
+               sources=[APOLLOLIB], basis=["official", "source-code"])
+
+
+PIP2 = [("DFF3B0", "PIP2 X start"), ("DFF3B2", "PIP2 Y start"),
+        ("DFF3B4", "PIP2 X stop"), ("DFF3B6", "PIP2 Y stop"),
+        ("DFF3B8", "PIP2 pointer (32-bit)"), ("DFF3BC", "PIP2 format"),
+        ("DFF3BE", "PIP2 modulo"), ("DFF3C0", "PIP2 colour key"),
+        ("DFF3C2", "PIP2 DMA row length")]
+
+
+def pip(rows):
+    p1 = pick(rows, 0xDFF3D0, 0xDFF3E2)
+    details = ["### PIP 1 registers (original)", ""] + reg_table(p1)
+    details += ["", "The original links these rows to a page that doesn't exist; the "
+                "facts below come from ApolloLib and the SAGAPiP example (SRC).", "",
+                "### PIP 2 registers (SRC, not in the original)", "",
+                "PIP 2 has the same layout as PIP 1, `$20` lower (ApolloLib):", "",
+                "| Address | Register | Same as PIP 1 |", "|---|---|---|"]
+    details += [f"| `${a}` | {n} | `${addr(a) + 0x20:06X}` |" for a, n in PIP2]
+    details += ["", "Its colour port is `$DFF37C` (see [colour-ports.md](colour-ports.md)). "
+                "The SAGAPiP example says two PIPs exist from Core 11900 (SRC).", "",
+                "### Register meanings (SRC)", "",
+                "| Register | Meaning |", "|---|---|",
+                "| X/Y start, X/Y stop | Window position in screen pixels. The example "
+                "writes X + 16 and Y − 1 to place the PIP exactly over a window. |",
+                "| Pointer | 32-bit address of the PIP bitmap |",
+                "| Format | Bits 7–0: pixel format as in GFXMODE, only `$01` (8-bit), "
+                "`$02` (R5G6B5) and `$03` (1R5G5B5). Bit 8: transparency on, key colour "
+                "`$F81F` in 16-bit mode. |",
+                "| Modulo | Bytes skipped after each row |",
+                "| Colour key | Bit 15 = enable, bits 11–8 red, 7–4 green, 3–0 blue |",
+                "| DMA row length | Bytes fetched per row = width × bytes per pixel. "
+                "**0 switches the PIP off.** |",
+                "", "### Two modes (SAGAPiP example, SRC)", "",
+                "- **Overlay:** colour key 0. The PIP is in front of the main screen; "
+                "with format bit 8 set, pixels with `$F81F` are transparent.",
+                "- **Chroma key:** colour key with bit 15 set, for example `$8F0F` "
+                "(purple). The PIP is behind the main screen and shows only where the "
+                "main screen has the key colour.", "",
+                "### Conflict with the original", "",
+                "The original describes PipFormat as \"Colorformat "
+                "(8bit/16bit/15bit/YUV)\". ApolloLib marks YUV and the 24- and 32-bit "
+                "formats as not supported on PIP. Until this is settled, use only "
+                "`$01`–`$03`."]
+    return doc("pip.md", "SAGA picture in picture (PIP 1 and PIP 2)",
+               ["saga-video-isabelle"], ["saga", "isabelle", "pip", "overlay", "registers"],
+               "SAGA overlays up to two picture-in-picture windows (PIP) on the main "
+               "screen, each with its own bitmap, format, position and colour key. The "
+               "original documents PIP 1 only; PIP 2 and the register meanings come "
+               "from ApolloLib.",
+               details,
+               ["- Classic Amiga chipsets have no PIP. Dual playfield is the nearest "
+                "classic feature, and it is limited to planar bitmaps in Chip RAM."],
+               ["DO set the DMA row length last: it switches the PIP on.",
+                "DO write 0 to the DMA row length to switch a PIP off.",
+                "DON'T use YUV, 24- or 32-bit formats for a PIP."],
+               sources=[APOLLOLIB, EX_PIP], basis=["official", "source-code"],
+               related=[f"{OUTDIR}/colour-ports.md", f"{OUTDIR}/chunky-plane.md"])
+
+
+def pointer(rows):
+    pos = [by_addr(rows, "DFF1D0"), by_addr(rows, "DFF1D2")]
+    cols = pick(rows, 0xDFF3A2, 0xDFF3A6)
+    details = ["### Position (original and SRC)", ""] + reg_table(pos)
+    details += ["", "- Write X to `$DFF1D0` and Y to `$DFF1D2`; read them back at "
+                "`$DFE1D0` and `$DFE1D2` (ApolloLib, SRC).",
+                "- ApolloLib writes the mouse position + 16 (X) and + 8 (Y) (SRC).", "",
+                "### 32x32 pointer sprite (SRC, not in the original)", "",
+                "From the current ApolloLib and the ApolloPointer example:", "",
+                "| Address | Use |", "|---|---|",
+                "| `$DFD000` | Image: 32 x 32 pixels, 2 bytes per pixel (colour index, "
+                "alpha), 2048 bytes, row by row |",
+                "| `$DFF3A8` | Palette index (word): write the entry number first |",
+                "| `$DFF3AA` | Palette colour (long, R8G8B8) for the entry selected at "
+                "`$DFF3A8` |", "",
+                "- Index 0 is transparent. ApolloLib writes alpha `$FF` for opaque "
+                "pixels and `$00` for semi-transparent ones; the example's usage text "
+                "says colour 1 is semi-transparent.",
+                "- To set the palette, write the index to `$DFF3A8`, then the colour to "
+                "`$DFF3AA`, for each of the 256 entries.", "",
+                "### 12-bit pointer colours (original)", ""] + reg_table(cols)
+    details += ["", "These rows have no page in the original. An older ApolloLib copy "
+                "adds colour 0 at `$DFF3A0` and a 16x16 planar pointer image at "
+                "`$DFF800` (SRC). Which cores have this 16x16 pointer next to, or "
+                "instead of, the 32x32 sprite is an open question (see "
+                "[index.md](index.md))."]
+    return doc("pointer.md", "SAGA hardware sprite pointer",
+               ["saga-video-isabelle"], ["saga", "isabelle", "pointer", "sprite", "registers"],
+               "SAGA has a hardware mouse pointer: a 32x32 sprite with a 256-colour "
+               "palette and alpha, positioned through `$DFF1D0`/`$DFF1D2`. The original "
+               "documents only the position and three 12-bit colours; the sprite "
+               "image and palette come from ApolloLib.",
+               details,
+               ["- On ECS, `$DFF1D0`/`$DFF1D2` are SPRHSTRT/SPRHSTOP (UHRES sprite "
+                "vertical start and stop). On SAGA they position the pointer.",
+                "- Classic sprites are 16 pixels wide with 3 colours, fetched by DMA "
+                "from Chip RAM. The SAGA pointer sprite is written directly to `$DFD000`."],
+               ["DO write the palette through `$DFF3A8` (index) and `$DFF3AA` (colour).",
+                "DO keep colour index 0 for transparent pixels.",
+                "DON'T use `$DFF800` or `$DFF3A0`–`$DFF3A6` until the open question "
+                "is settled."],
+               sources=[APOLLOLIB, APOLLOLIB_OLD, EX_POINTER], basis=["official", "source-code"])
+
+
+def display_control(rows):
+    sc = box_table(page("sagacontrol.htm"))
+    sh = box_table(page("shiftdown.htm"))
+    adj = box_table(page("screenadjust.htm"))
+    ex = [re.sub(r"\s+", " ", ln.replace("Examples:", "")).strip()
+          for ln in page("sagacontrol.htm") if "apoke" in ln]
+    details = ["### Registers", ""] + reg_table(pick(rows, 0xDFF390, 0xDFF392) +
+                                                pick(rows, 0xDFF3EC, 0xDFF3EE))
+    details += ["", "### SAGA CONTROL (`$DFF3EC`, write)", "",
+                "Bit 15 is SET/CLR, as in DMACON: bits written as 1 are set when bit "
+                "15 is 1, and cleared when it is 0.", ""] + bits_md(sc)
+    details += ["", "Examples from the original (`apoke address size value`):", "", "```text"]
+    details += ex + ["```", "",
+                "### SCREEN SHIFT (`$DFF3EE`)", "",
+                "The original's page has the title \"SAGA CONTROL Register\"; its "
+                "content is the screen shift:", ""] + bits_md(sh)
+    details += ["", "The original marks it R. Whether it is also writable is an open "
+                "question.", "",
+                "### SCREENMODE ADJUST (`$DFF390`)", ""] + bits_md(adj)
+    details += ["", "The original's example on this page is the one of the planar "
+                "colour port (it sets colour 0 to red) and is left out."]
+    return doc("display-control.md", "SAGA display control, screen shift and screen mode adjust",
+               ["saga-video-isabelle"], ["saga", "isabelle", "scanlines", "zoom", "registers"],
+               "SAGA CONTROL (`$DFF3EC`) switches scanlines, zoom and a forced OCS mode; "
+               "SCREEN SHIFT (`$DFF3EE`) and SCREENMODE ADJUST (`$DFF390`) move and "
+               "enlarge the SAGA screen modes.",
+               details,
+               ["- Classic Amiga chipsets have none of these registers: scanlines and "
+                "zoom are features of the SAGA video output."],
+               ["DO set bit 15 to set bits and clear it to clear them.",
+                "DON'T treat `$DFF3EC` as read-only: the original's Access column is "
+                "wrong there."])
+
+
+def collisions(rows):
+    c = pick(rows, 0xDFF230, 0xDFF23E)
+    details = ["### Registers", ""] + reg_table(c)
+    details += ["", "Bit layout (one register per sprite):", ""] + \
+        bits_md(box_table(page("clxdatx.htm")))
+    details += ["", "The bits name sprites 0 to F (16 sprites), but the original lists "
+                "registers for sprites 0–7 only. Whether sprites 8–15 exist is not "
+                "documented."]
+    return doc("sprite-collision.md", "SAGA detailed sprite collision",
+               ["saga-video-isabelle"], ["saga", "isabelle", "sprites", "collision", "registers"],
+               "SAGA reports, per sprite, which other sprites it touches, in one "
+               "register per sprite at `$DFF230`–`$DFF23E`.",
+               details,
+               ["- Classic CLXDAT (`$DFF00E`) reports collisions only between sprite "
+                "pairs and playfields, and clears on read."],
+               ["DO read the register of the sprite you are interested in.",
+                "DON'T assume sprites 8–15 exist."])
+
+
+ARNE_LAYOUT = [("+0", "AUDxL", "L", "W", "Pointer to the sample data (32-bit, any RAM)"),
+               ("+4", "AUDxLEN", "L", "W", "Length in sample pairs (32-bit)"),
+               ("+8", "AUDxVOL", "W", "W", "Volume: bits 15–8 left, 7–0 right"),
+               ("+A", "AUDxCTRL", "W", "W", "Control (see below)"),
+               ("+C", "AUDxPER", "W", "W", "Period (16-bit)")]
+
+
+def arne_channels(rows):
+    ch = pick(rows, 0xDFF400, 0xDFF4FF)
+    # Check the layout: channel n at $DFF400 + n*$10.
+    off = {"L": 0, "LEN": 4, "VOL": 8, "CTRL": 0xA, "PER": 0xC}
+    bad = []
+    for r in ch:
+        m = re.match(r"^AUD(\d+)(L|LEN|VOL|CTRL|PER)$", r["name"])
+        if not m:
+            bad.append(r["addr"])
+            continue
+        want = 0xDFF400 + int(m.group(1)) * 0x10 + off[m.group(2)]
+        if addr(r["addr"]) not in (want, want + 2):
+            bad.append(r["addr"])
+    if bad:
+        raise SystemExit(f"Arne layout does not match the original: {bad}")
+    ctrl = box_table(page("audxctrl.htm"))
+    fmt = [ln.strip() for ln in page("audxctrl.htm")
+           if "signed" in ln]
+    per = prose(page("audxper.htm"), 1)
+    notes = [(r["addr"], n) for r in ch for n in r["notes"]]
+    details = ["### Channel layout", "",
+               "16 channels, channel n at `$DFF400 + n × $10` (n = 0–15). The converter "
+               "checks every row of the original against this layout.", ""]
+    details += table(["Offset", "Register", "Size", "Access", "Meaning"], ARNE_LAYOUT)
+    if notes:
+        details += [""] + [f"- `${a}`: {n}." for a, n in notes]
+    details += ["", "### Channels 0–3 and Paula", "",
+                "Arne channels 0–3 are the four Paula channels: the same voices, with "
+                "the classic registers at `$DFF0A0`–`$DFF0DF` and the Arne registers "
+                f"at `$DFF400`–`$DFF43F` ({WDS}). ApolloLib "
+                "starts and stops channels 0–3 with DMACON bits 0–3 (`$DFF096`) and "
+                "checks them in DMACONR (`$DFF002`); channels 4–15 use DMACON2 (SRC, "
+                "see [arne-dma-and-interrupts.md](arne-dma-and-interrupts.md)).", "",
+                "### AUDxCTRL", ""] + bits_md(ctrl)
+    details += ["", "Sample formats (original):", ""] + [f"- {f}" for f in fmt]
+    details += ["", "ApolloLib writes `$0005` (16-bit stereo, looping) and `$0007` "
+                "(16-bit stereo, one-shot) (SRC). The other bits are not described.", "",
+                "### AUDxLEN", "",
+                "The count is in pairs of samples (original). For 16-bit stereo, "
+                "ApolloLib writes the size in bytes / 8: one count is two stereo frames "
+                "of 2 × 16 bits (SRC).", "",
+                "### AUDxVOL", "",
+                "Bits 15–8 left volume, bits 7–0 right volume (original). Each side "
+                "ranges from `$00` to `$FF` (ApolloLib, SRC).", "",
+                "### AUDxPER", ""] + [" ".join(per)]
+    details += ["", "With the PAL clock of 3546895 Hz (ApolloLib), period 65 gives "
+                "3546895 / 65 = 54.6 kHz, not the 56 kHz in the original."]
+    return doc("arne-channels.md", "SAGA Arne audio channel registers",
+               ["saga-audio-arne"], ["saga", "arne", "audio", "registers"],
+               "Arne, the SAGA audio unit, has 16 channels of 8- or 16-bit mono or "
+               "16-bit stereo samples from any RAM, each with a 32-bit pointer and "
+               "length at `$DFF400 + n × $10`. Channels 0–3 are the Paula channels.",
+               details,
+               ["- Paula has 4 channels, 8-bit samples, 6-bit volume and Chip RAM only. "
+                "Arne channels 0–3 are those same channels, with the extra registers at "
+                "`$DFF400`.",
+                "- Classic AUDxLEN counts words; Arne AUDxLEN counts sample pairs and "
+                "is 32 bits."],
+               ["DO keep the period at 65 or higher.",
+                "DO give AUDxLEN in sample pairs.",
+                "DO start channels 0–3 with DMACON and channels 4–15 with DMACON2.",
+                "DON'T program channel 0–3 through both register sets at the same time."],
+               sources=[APOLLOLIB, WD], basis=["official", "source-code"],
+               related=["core/saga-audio-arne/registers.md",
+                        f"{OUTDIR}/arne-dma-and-interrupts.md"])
+
+
+def arne_dma(rows):
+    regs = [r for r in rows if r["addr"] in ("DFF202", "DFF21C", "DFF21E",
+                                             "DFF296", "DFF29A", "DFF29C")]
+    d = box_table(page("dmacon2.htm"))
+    i = box_table(page("intena2.htm"))
+    irq = [ln.strip() for ln in page("intena2.htm") if "IRQ" in ln]
+    details = ["### Registers", ""] + reg_table(regs)
+    details += ["", "### DMACON2", ""] + bits_md(d)
+    details += ["", "### INTENA2 and INTREQ2", "",
+                "Both use the same bits. INTREQ2 needs a set and a clear write to load "
+                "arbitrary data, as INTREQ (original).", ""] + bits_md(i)
+    details += ["", "The original adds:", ""] + [f"- \"{x}\"" for x in irq]
+    details += ["", "Whether `$48` and `$50` are vector offsets or vector numbers, and "
+                "at which interrupt level they arrive, is an open question (see "
+                "[index.md](index.md))."]
+    return doc("arne-dma-and-interrupts.md", "SAGA DMACON2, INTENA2 and INTREQ2",
+               ["saga-audio-arne"], ["saga", "arne", "audio", "dma", "interrupts",
+                                     "ethernet", "registers"],
+               "DMACON2, INTENA2 and INTREQ2 control DMA and interrupts of Arne audio "
+               "channels 4–15 and of the Ethernet. Bit n is channel n + 4; bit 13 is "
+               "Ethernet.",
+               details,
+               ["- Classic DMACON/INTENA/INTREQ cover audio channels 0–3 only. "
+                "Channels 0–3 stay there on SAGA; the second set adds 4–15 and "
+                "Ethernet."],
+               ["DO use bit 15 as SET/CLR, as in the classic registers.",
+                "DO map channel n (4–15) to bit n − 4."],
+               related=[f"{OUTDIR}/arne-channels.md"])
+
+
+def maggie(rows):
+    t = pick(rows, 0xDFF250, 0xDFF28C)
+    details = ["### Registers", ""] + reg_table(t)
+    details += ["", "Offsets from `$DFF250`, for comparison with the measured layout "
+                "in [registers.md](../saga-3d-maggie/registers.md):", "",
+                "| Offset | Name (original) |", "|---|---|"]
+    details += [f"| {addr(r['addr']) - 0xDFF250} | {md(r['name'])} |" for r in t]
+    return doc("maggie-3d.md", "SAGA Maggie 3D registers (official names)",
+               ["saga-3d-maggie"], ["saga", "maggie", "3d", "texture", "registers"],
+               "Maggie, the SAGA texture-mapping unit, is programmed through registers at "
+               "`$DFF250`–`$DFF28F`. This file gives the official names; the measured "
+               "behaviour is in core/saga-3d-maggie/registers.md.",
+               details,
+               ["- Classic Amiga chipsets have no texture-mapping unit."],
+               ["DO write TEXSTRT (`$DFF25E`) last: it starts the span.",
+                "DO check core/saga-3d-maggie/registers.md and its pitfalls for the "
+                "measured behaviour."],
+               related=["core/saga-3d-maggie/registers.md"])
+
+
+def inputs(rows):
+    regs = [r for r in rows if r["addr"] in ("DFF20A", "DFF20C", "DFF212")] + \
+        pick(rows, 0xDFF220, 0xDFF226)
+    wheel = page("mousewheel.htm")
+    jb = box_table(page("joybuttons.htm"))
+    potgo = [ln.strip() for ln in page("potgo.htm") if ln.strip().startswith("Bit ")]
+    details = ["### Registers", ""] + reg_table(regs)
+    details += ["", "### USB joypads (`$DFF220`–`$DFF226`)", "",
+                "One register per joypad. The index describes them as \"16bit USB Joy "
+                "Buttons (0)=active\"; ApolloLib reads a set bit as pressed and bit 0 "
+                "as connected (SRC). ApolloLib's names are in the last column.", ""]
+    names = {"08": "TR", "07": "TL", "06": "BR", "05": "BL", "04": "Y", "03": "X",
+             "02": "B", "01": "A", "00": "Connected"}
+    details += table(["Bits", "Function", "Description", "ApolloLib"],
+                     [[b, f, d, names.get(b, "")] for b, f, d in jb])
+    details += ["", "ApolloLib also reads bits 2/3 as right stick X and bits 1/4 as "
+                "right stick Y (SRC).", "",
+                "### Mouse wheel (`$DFF212`)", "",
+                "| Bits | Use |", "|---|---|"]
+    for ln in wheel:
+        m = re.match(r"\s*BIT\s+(\d+(?:-\d+)?)\s+(.*\S)", ln)
+        if m:
+            details.append(f"| {bitrange(m.group(1))} | {md(m.group(2))} |")
+    counter = next(ln.strip() for ln in wheel if "counter" in ln)
+    details += [f"| 7–0 | {md(counter)} |", "",
+                "### DB9 joysticks (`$DFF20A`, `$DFF20C`)", "",
+                "The \"vanilla\" DB9 ports, with the layout of JOY0DAT/JOY1DAT. The "
+                "original's index marks them OCS, ECS and AGA too, but these addresses "
+                "are SAGA's.", "",
+                "### Extra fire buttons in POTGO (classic register)", ""]
+    details += [f"- {p}" for p in potgo]
+    return doc("input.md", "SAGA input registers: USB joypads, mouse wheel, DB9",
+               ["general"], ["saga", "input", "joypad", "usb", "mouse", "registers"],
+               "SAGA reads USB joypads (`$DFF220`–`$DFF226`) and the USB mouse wheel "
+               "(`$DFF212`) through registers, and adds the DB9 ports at `$DFF20A`/`$DFF20C`.",
+               details,
+               ["- Classic Amiga input is JOYxDAT, POTGO/POTINP and CIA bits, without "
+                "USB, wheel or more than 3 buttons."],
+               ["DO test bit 0 (connected) before you trust a joypad register.",
+                "DO treat the wheel counter as signed and use the difference between "
+                "two reads."],
+               sources=[APOLLOLIB], basis=["official", "source-code"])
+
+
+BOARDS = [("$01", "V2-V600 (legacy)", "ApolloOS"), ("$02", "V2-V500 (legacy)", "ApolloOS"),
+          ("$03", "V4 Firebird (A500); also Salamander (Firebird on an A2000 adapter) "
+           "and Phoenix (Firebird on an A1000 adapter)", "WDrijver, original"),
+          ("$04", "V4 IceDrake (A1200)", "WDrijver, original"),
+          ("$05", "V4 Standalone", "WDrijver, original"),
+          ("$06", "V2-V1200 (legacy)", "ApolloOS"),
+          ("$07", "V4 Manticore (A600)", "WDrijver, original"),
+          ("$08", "V4 UniCorn (A6000)", "WDrijver, ApolloOS")]
+
+
+def system(rows):
+    regs = pick(rows, 0xDFF3EA, 0xDFF3EA) + pick(rows, 0xDFF3F0, 0xDFF3FC)
+    details = ["### Registers", ""] + reg_table(regs)
+    details += ["", "### VAMPIRE VERSION / board ID (`$DFF3FC`)", "",
+                "Bits 15–8: board (card) ID. Bits 7–0: CPU clock multiplier.", ""]
+    details += table(["ID", "Board", "Source"], BOARDS)
+    details += ["", "The original's list says 1 = V600, 2 = V500, 6 = V1200 without "
+                "\"V2\", and lacks `$08`. ApolloOS marks `$09` as future.", "",
+                "All V4 boards run the same core: the board ID tells the board, not "
+                "different SAGA features (see [hardware/index.md](../../hardware/index.md)).",
+                "", "### Other registers", "",
+                "CORE REVISION, CHIP ID and the SPI registers have no description in "
+                "the original. SPI WRITE (`$DFF3F8`) is marked R there, which is "
+                "unlikely for a write register."]
+    return doc("system.md", "SAGA system registers: board ID, core revision, chip ID, SPI",
+               ["general"], ["saga", "board-id", "version", "registers"],
+               "`$DFF3FC` gives the V4 board ID and the CPU clock multiplier. Core "
+               "revision, chip ID and SPI registers sit at `$DFF3EA`–`$DFF3FA`.",
+               details,
+               ["- Classic Amiga chipsets have DENISEID (`$DFF07C`) for the video chip "
+                "only; there is no board or clock register."],
+               ["DO read the board ID with `move.w $DFF3FC` and use the high byte.",
+                "DON'T use the board ID to decide which SAGA features exist: they are "
+                "the same on every V4 board with the same core."],
+               sources=[APOLLOOS, WD], basis=["official", "source-code"],
+               related=["hardware/index.md"])
+
+
+FILES = [("chunky-plane.md", "Chunky plane: GFXMODE, pointer, modulo"),
+         ("colour-ports.md", "24-bit colour ports"),
+         ("pip.md", "Picture in picture (PIP 1 and 2)"),
+         ("pointer.md", "Hardware sprite pointer"),
+         ("display-control.md", "SAGA control, screen shift, screen mode adjust"),
+         ("sprite-collision.md", "Detailed sprite collision"),
+         ("arne-channels.md", "Arne audio channels"),
+         ("arne-dma-and-interrupts.md", "DMACON2, INTENA2, INTREQ2"),
+         ("maggie-3d.md", "Maggie 3D registers"),
+         ("input.md", "USB joypads, mouse wheel, DB9"),
+         ("system.md", "Board ID, core revision, chip ID, SPI")]
+
+OPEN = [
+    "The Copper form `dc.w $8380,$00FF,$0000` in the colour port pages: how the "
+    "SAGA Copper encodes a 32-bit MOVE and which SAGA registers it reaches.",
+    "\"IRQ $48\" (Ethernet) and \"IRQ $50\" (Arne channels 4–15): vector offsets or "
+    "vector numbers, and at which interrupt level.",
+    "Read-back at `$DFExxx`: known for `$DFE1D0`/`$DFE1D2` (pointer) and "
+    "`$DFE1F4`/`$DFE1EC` (mode, frame pointer). Does every write register read back "
+    "there?",
+    "SCREEN SHIFT (`$DFF3EE`): read only, as the original says, or also writable?",
+    "Pointer: which cores have the 16x16 planar pointer (`$DFF800`, colours "
+    "`$DFF3A0`–`$DFF3A6`) next to, or instead of, the 32x32 sprite at `$DFD000`?",
+    "PIP format: the original lists YUV, ApolloLib supports only `$01`–`$03`.",
+    "Sprites 8–15: the collision bits name them; the original documents 8 sprites.",
+]
+
+
+def index(rows, keep, applied):
+    where = {}
+    for name, lo, hi in [("chunky-plane.md", 0xDFF1E6, 0xDFF1F4),
+                         ("arne-dma-and-interrupts.md", 0xDFF202, 0xDFF202),
+                         ("input.md", 0xDFF20A, 0xDFF226),
+                         ("arne-dma-and-interrupts.md", 0xDFF21C, 0xDFF21E),
+                         ("sprite-collision.md", 0xDFF230, 0xDFF23E),
+                         ("maggie-3d.md", 0xDFF250, 0xDFF28C),
+                         ("arne-dma-and-interrupts.md", 0xDFF296, 0xDFF29C),
+                         ("colour-ports.md", 0xDFF380, 0xDFF38E),
+                         ("display-control.md", 0xDFF390, 0xDFF392),
+                         ("pointer.md", 0xDFF3A2, 0xDFF3A6),
+                         ("pip.md", 0xDFF3D0, 0xDFF3E2),
+                         ("system.md", 0xDFF3EA, 0xDFF3EA),
+                         ("display-control.md", 0xDFF3EC, 0xDFF3EE),
+                         ("system.md", 0xDFF3F0, 0xDFF3FC),
+                         ("arne-channels.md", 0xDFF400, 0xDFF4FF),
+                         ("pointer.md", 0xDFF1D0, 0xDFF1D2)]:
+        for r in keep:
+            if lo <= addr(r["addr"]) <= hi:
+                where[r["addr"]] = name
+    missing = [r["addr"] for r in keep if r["addr"] not in where]
+    if missing:
+        raise SystemExit(f"rows without a file: {missing}")
+    groups = {}
+    for r in sorted(keep, key=lambda r: addr(r["addr"])):
+        groups.setdefault(where[r["addr"]], []).append(r)
+    details = ["### About the original", "",
+               f"- Original: [`{SRCDIR}/`](../../{SRCDIR}/), an HTML register table "
+               "(`index.htm`) with one page per register. It is leading; these files "
+               "are generated from it by `tools/intake/sagaregs.py`.",
+               f"- Valid for {CORE} ({WDS}).",
+               "- `index.htm` is the current table. `saga.htm` is an older table with "
+               "another audio and sprite layout; it is not used.",
+               "- The Atari section of `index.htm` is skipped.", "",
+               "### Scope: SAGA-specific registers only", "",
+               f"Every one of the {len(rows)} rows of the original is marked SAGA, "
+               "because SAGA contains the classic chipset. These files cover the "
+               f"{len(keep)} SAGA-specific rows: the rows where OCS, ECS and AGA are "
+               "empty, plus the SAGA addresses that the original also marks as classic.",
+               "", "For every other register, the Amiga Hardware Reference Manual "
+               "applies, with one difference: **on SAGA, all classic pointer registers "
+               "(BPLxPT, SPRxPT, COPxLC, BLTxPT, AUDxLC, DSKPT) are 32 bits wide and "
+               f"reach all RAM** ({WDS}). Their pages in the "
+               "original still say 18 bits. FMODE (`$DFF1FC`) bit 4 \"SAGA\" enables "
+               "the SAGA features (original).", "",
+               "### Access codes (original)", "",
+               "| Code | Meaning |", "|---|---|"]
+    details += [f"| {k} | {v} |" for k, v in ACCESS.items()]
+    details += ["", "### Files", "", "| Topic | File |", "|---|---|"]
+    details += [f"| {t} | [{f}]({f}) |" for f, t in FILES]
+    details += ["", "### Register map", "",
+                "| Address | Name | Access | File |", "|---|---|---|---|"]
+    for f, _ in FILES:
+        if f == "arne-channels.md":
+            n = len(groups.get(f, []))
+            details.append(f"| `$DFF400`–`$DFF4FF` | AUD0–AUD15: L, LEN, VOL, CTRL, PER "
+                           f"({n} rows) | W | [{f}]({f}) |")
+            continue
+        for r in groups.get(f, []):
+            details.append(f"| `${r['addr']}` | {md(r['name'])} | {md(r['access'])} | "
+                           f"[{f}]({f}) |")
+    details += ["", "Not in the original, added from ApolloLib (SRC): PIP 2 at "
+                "`$DFF3B0`–`$DFF3C2` and its colour port `$DFF37C` ([pip.md](pip.md)); "
+                "the pointer sprite at `$DFD000`, `$DFF3A8` and `$DFF3AA` "
+                "([pointer.md](pointer.md)).", "",
+                "### Corrections to the original", "",
+                "Applied by the converter; the original should be fixed the same way.", "",
+                "| Address | Field | Original | Corrected | Why |", "|---|---|---|---|---|"]
+    details += [f"| `${a}` | {f} | {md(o)} | {md(n)} | {md(w)} |" for a, f, o, n, w in applied]
+    details += ["", "Wrong or missing page links in the original: the 32-bit Arne "
+                "rows link to the classic Paula pages (`audxlch.htm`, `audxvol.htm`, "
+                "`audxdat.htm`), the PIP rows to a page that doesn't exist. The "
+                "converter uses `audxl.htm`, `audxlen.htm`, `audnvol.htm`, "
+                "`audxctrl.htm` and `audxper.htm` for Arne.", "",
+                "### Open questions", ""]
+    details += [f"{n}. {q}" for n, q in enumerate(OPEN, 1)]
+    return doc("index.md", "SAGA registers (SAGA-specific)",
+               ["saga-video-isabelle", "saga-audio-arne", "saga-3d-maggie", "general"],
+               ["saga", "registers", "index"],
+               "The SAGA-specific chipset registers of the Apollo V4, converted from the "
+               "official SAGA register documentation: video (chunky plane, colour "
+               "ports, PIP, pointer), Arne audio, Maggie 3D, input and system "
+               "registers. Classic OCS/ECS/AGA registers are not repeated here.",
+               details,
+               ["- SAGA contains the classic chipset at its classic addresses. The "
+                "registers here are added on top of it, mostly at `$DFF1E6`–`$DFF1F4`, "
+                "`$DFF200`–`$DFF29F` and `$DFF380`–`$DFF4FF`.",
+                "- Classic pointers are 18 (OCS) or 21 (ECS/AGA) bits; on SAGA they "
+                "are 32 bits."],
+               ["DO look up a classic register in the HRM, and its SAGA-specific "
+                "registers here.",
+                "DON'T use a register listed under the open questions without checking "
+                "it on real hardware."],
+               sources=[APOLLOLIB, WD], basis=["official", "source-code"])
+
+
+def build():
+    rows, keep, applied = saga_rows()
+    parts = [index(rows, keep, applied), chunky_plane(keep), colour_ports(keep),
+             pip(keep), pointer(keep), display_control(keep), collisions(keep),
+             arne_channels(keep), arne_dma(keep), maggie(keep), inputs(keep),
+             system(keep)]
+    return dict(parts)
+
+
+# ------------------------------------------------------------ status, check
+
+STATUS_RE = re.compile(r"^(status|last_verified):.*\n", re.M)
+
+
+def body(text):
+    return text.split("\n---\n", 1)[-1]
+
+
+def keep_status(old, new):
+    """Keep the status a maintainer gave a file while its body is unchanged."""
+    if old is None or body(old) != body(new):
+        return new
+    fields = "".join(m.group(0) for m in STATUS_RE.finditer(old))
+    return STATUS_RE.sub("", new, count=1).replace(
+        "origin: ", fields + "origin: ", 1) if fields else new
+
+
+def main():
+    files = build()
+    out = os.path.join(ROOT, OUTDIR)
+    existing = set(os.listdir(out)) if os.path.isdir(out) else set()
+    stale = []
+    for rel, text in files.items():
+        p = os.path.join(out, rel)
+        old = open(p, encoding="utf-8").read() if os.path.isfile(p) else None
+        files[rel] = text = keep_status(old, text)
+        if old != text:
+            stale.append(rel)
+    extra = sorted(existing - set(files))
+    if "--check" in sys.argv:
+        if stale or extra:
+            for s in stale + extra:
+                print(f"out of date: {OUTDIR}/{s}", file=sys.stderr)
+            sys.exit(1)
+        print("OK")
+        return
+    os.makedirs(out, exist_ok=True)
+    for rel in stale:
+        with open(os.path.join(out, rel), "w", encoding="utf-8") as f:
+            f.write(files[rel])
+    for rel in extra:
+        print(f"not generated any more, remove by hand: {OUTDIR}/{rel}")
+    print(f"Wrote {len(stale)} of {len(files)} file(s) in {OUTDIR}/")
+
+
+if __name__ == "__main__":
+    main()

From 58030adae3534e221d71b67063f138aad04d7045 Mon Sep 17 00:00:00 2001
From: Willem Drijver 
Date: Wed, 4 Nov 2026 14:25:53 +0300
Subject: [PATCH 02/12] SAGA registers: $DFF3EC write-only, $DFF3EE read and
 write

WDrijver, 2026-11-04: $DFF3EC is SAGA Control 1 (OCS mode, PAL zoom, zoom
mode, scanlines), write-only. $DFF3EE is SAGA Control 2 (zoom shift X and
Y in pixels, positive integers), read and write. Add both as corrections
and drop the SCREEN SHIFT open question.

Co-Authored-By: Claude Opus 5.5 
---
 core/saga-registers/display-control.md | 23 ++++++++++------
 core/saga-registers/index.md           | 15 ++++++-----
 tools/intake/sagaregs.py               | 36 +++++++++++++++++---------
 3 files changed, 48 insertions(+), 26 deletions(-)

diff --git a/core/saga-registers/display-control.md b/core/saga-registers/display-control.md
index a60f5c9..1045599 100644
--- a/core/saga-registers/display-control.md
+++ b/core/saga-registers/display-control.md
@@ -14,6 +14,7 @@ related:
   - core/saga-registers/index.md
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
+  - "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04"
 generated_from: sources/official/saga-registers/index.htm
 ---
 
@@ -21,7 +22,7 @@ generated_from: sources/official/saga-registers/index.htm
 
 ## Summary
 
-SAGA CONTROL (`$DFF3EC`) switches scanlines, zoom and a forced OCS mode; SCREEN SHIFT (`$DFF3EE`) and SCREENMODE ADJUST (`$DFF390`) move and enlarge the SAGA screen modes.
+SAGA CONTROL (`$DFF3EC`, write-only) switches scanlines, zoom and a forced OCS mode; SCREEN SHIFT (`$DFF3EE`, read and write) shifts the zoomed screen in pixels; SCREENMODE ADJUST (`$DFF390`) enlarges the SAGA screen modes.
 
 ## Details
 
@@ -30,12 +31,17 @@ SAGA CONTROL (`$DFF3EC`) switches scanlines, zoom and a forced OCS mode; SCREEN
 | Address | Name | Access | Description (original) |
 |---|---|---|---|
 | `$DFF390`, `$DFF392` | SCREENMODE ADJUST | W | Adjust Y/X for Screenmodes |
-| `$DFF3EC` | SAGA CONTROL REG | W | Reserved |
-| `$DFF3EE` | SCREEN SHIFT | R | Reserved |
+| `$DFF3EC` | SAGA CONTROL REG | W | SAGA Control 1: OCS mode, PAL zoom, zoom mode, scanlines |
+| `$DFF3EE` | SCREEN SHIFT | R/W | SAGA Control 2: zoom shift X and Y in pixels |
 
-- `$DFF3EC`: corrected: $DFF3EC is writable (WDrijver, 2026-11-04).
+- `$DFF3EC`: corrected: $DFF3EC is write-only (WDrijver, 2026-11-04).
+- `$DFF3EC`: corrected: the register's function (WDrijver, 2026-11-04).
+- `$DFF3EE`: corrected: $DFF3EE is read and write (WDrijver, 2026-11-04).
+- `$DFF3EE`: corrected: the register's function (WDrijver, 2026-11-04).
 
-### SAGA CONTROL (`$DFF3EC`, write)
+### SAGA CONTROL (`$DFF3EC`, write-only)
+
+SAGA Control 1: OCS mode, PAL zoom, zoom mode and scanlines (WDrijver, 2026-11-04).
 
 Bit 15 is SET/CLR, as in DMACON: bits written as 1 are set when bit 15 is 1, and cleared when it is 0.
 
@@ -59,7 +65,7 @@ ZOOM2 (NTSC+) = apoke $DFF3EC 2 $8020
 ZOOM3 (PAL) = apoke $DFF3EC 2 $8024
 ```
 
-### SCREEN SHIFT (`$DFF3EE`)
+### SCREEN SHIFT (`$DFF3EE`, read and write)
 
 The original's page has the title "SAGA CONTROL Register"; its content is the screen shift:
 
@@ -68,7 +74,7 @@ The original's page has the title "SAGA CONTROL Register"; its content is the sc
 | 15–8 | Y shift |  |
 | 7–0 | X shift |  |
 
-The original marks it R. Whether it is also writable is an open question.
+SAGA Control 2: the zoom shift. Read and write; X and Y are in pixels, positive integers (WDrijver, 2026-11-04). The original marks it R.
 
 ### SCREENMODE ADJUST (`$DFF390`)
 
@@ -88,4 +94,5 @@ The original's example on this page is the one of the planar colour port (it set
 ## Do / Don't
 
 - DO set bit 15 to set bits and clear it to clear them.
-- DON'T treat `$DFF3EC` as read-only: the original's Access column is wrong there.
+- DON'T read `$DFF3EC`: it is write-only, although the original's Access column says R.
+- DO give the zoom shift in `$DFF3EE` as positive pixel counts.
diff --git a/core/saga-registers/index.md b/core/saga-registers/index.md
index c06048a..1331bc6 100644
--- a/core/saga-registers/index.md
+++ b/core/saga-registers/index.md
@@ -46,6 +46,7 @@ For every other register, the Amiga Hardware Reference Manual applies, with one
 | W | write |
 | S | strobe (a write of any value triggers the action) |
 | ER | early read |
+| R/W | read and write (used in the original's Atari section, and here for `$DFF3EE`) |
 
 ### Files
 
@@ -95,7 +96,7 @@ For every other register, the Amiga Hardware Reference Manual applies, with one
 | `$DFF3A6` | Sprite Col3 | W | [pointer.md](pointer.md) |
 | `$DFF390/92` | SCREENMODE ADJUST | W | [display-control.md](display-control.md) |
 | `$DFF3EC` | SAGA CONTROL REG | W | [display-control.md](display-control.md) |
-| `$DFF3EE` | SCREEN SHIFT | R | [display-control.md](display-control.md) |
+| `$DFF3EE` | SCREEN SHIFT | R/W | [display-control.md](display-control.md) |
 | `$DFF230` | clxdat0 | R | [sprite-collision.md](sprite-collision.md) |
 | `$DFF232` | clxdat1 | R | [sprite-collision.md](sprite-collision.md) |
 | `$DFF234` | clxdat2 | R | [sprite-collision.md](sprite-collision.md) |
@@ -158,7 +159,10 @@ Applied by the converter; the original should be fixed the same way.
 | `$DFF21c` | addr | DFF21c | DFF21C | upper case, as everywhere else |
 | `$DFF430` | desc | Audio channel 1 location (32bit PTR) | Audio channel 3 location (32bit PTR) | typo in the original: this is channel 3 |
 | `$DFF1EC` | desc | Chunky plane pointer (hi 15 bits) | Chunky plane pointer (hi 16 bits) | the high word of a 32-bit pointer has 16 bits |
-| `$DFF3EC` | access | R | W | $DFF3EC is writable (WDrijver, 2026-11-04) |
+| `$DFF3EC` | access | R | W | $DFF3EC is write-only (WDrijver, 2026-11-04) |
+| `$DFF3EC` | desc | Reserved | SAGA Control 1: OCS mode, PAL zoom, zoom mode, scanlines | the register's function (WDrijver, 2026-11-04) |
+| `$DFF3EE` | access | R | R/W | $DFF3EE is read and write (WDrijver, 2026-11-04) |
+| `$DFF3EE` | desc | Reserved | SAGA Control 2: zoom shift X and Y in pixels | the register's function (WDrijver, 2026-11-04) |
 | `$DFF1EE` | desc | Chunky plane pointer (lo 15 bits) | Chunky plane pointer (lo 16 bits) | the low word of a 32-bit pointer has 16 bits |
 | `$DFF20C` | desc | Vaniall DB9 Joystick-mouse 1 data (vert, horiz) | Vanilla DB9 Joystick-mouse 1 data (vert, horiz) | typo in the original |
 
@@ -169,10 +173,9 @@ Wrong or missing page links in the original: the 32-bit Arne rows link to the cl
 1. The Copper form `dc.w $8380,$00FF,$0000` in the colour port pages: how the SAGA Copper encodes a 32-bit MOVE and which SAGA registers it reaches.
 2. "IRQ $48" (Ethernet) and "IRQ $50" (Arne channels 4–15): vector offsets or vector numbers, and at which interrupt level.
 3. Read-back at `$DFExxx`: known for `$DFE1D0`/`$DFE1D2` (pointer) and `$DFE1F4`/`$DFE1EC` (mode, frame pointer). Does every write register read back there?
-4. SCREEN SHIFT (`$DFF3EE`): read only, as the original says, or also writable?
-5. Pointer: which cores have the 16x16 planar pointer (`$DFF800`, colours `$DFF3A0`–`$DFF3A6`) next to, or instead of, the 32x32 sprite at `$DFD000`?
-6. PIP format: the original lists YUV, ApolloLib supports only `$01`–`$03`.
-7. Sprites 8–15: the collision bits name them; the original documents 8 sprites.
+4. Pointer: which cores have the 16x16 planar pointer (`$DFF800`, colours `$DFF3A0`–`$DFF3A6`) next to, or instead of, the 32x32 sprite at `$DFD000`?
+5. PIP format: the original lists YUV, ApolloLib supports only `$01`–`$03`.
+6. Sprites 8–15: the collision bits name them; the original documents 8 sprites.
 
 ## Differences from AmigaOS / AROS / 68060
 
diff --git a/tools/intake/sagaregs.py b/tools/intake/sagaregs.py
index 8142d33..2dfb23a 100644
--- a/tools/intake/sagaregs.py
+++ b/tools/intake/sagaregs.py
@@ -43,7 +43,9 @@
 MAGGIE = "maggie.library samples, see os/libraries/maggie-library.md"
 
 ACCESS = {"R": "read", "W": "write", "S": "strobe (a write of any value "
-          "triggers the action)", "ER": "early read"}
+          "triggers the action)", "ER": "early read",
+          "R/W": "read and write (used in the original's Atari section, and here "
+          "for `$DFF3EE`)"}
 
 
 # ------------------------------------------------------------ the original
@@ -173,7 +175,14 @@ def bitrange(b):
     ("DFF1EC", "desc", "Chunky plane pointer (hi 15 bits)",
      "Chunky plane pointer (hi 16 bits)",
      "the high word of a 32-bit pointer has 16 bits"),
-    ("DFF3EC", "access", "R", "W", f"$DFF3EC is writable ({WDS})"),
+    ("DFF3EC", "access", "R", "W", f"$DFF3EC is write-only ({WDS})"),
+    ("DFF3EC", "desc", "Reserved",
+     "SAGA Control 1: OCS mode, PAL zoom, zoom mode, scanlines",
+     f"the register's function ({WDS})"),
+    ("DFF3EE", "access", "R", "R/W", f"$DFF3EE is read and write ({WDS})"),
+    ("DFF3EE", "desc", "Reserved",
+     "SAGA Control 2: zoom shift X and Y in pixels",
+     f"the register's function ({WDS})"),
     ("DFF1EE", "desc", "Chunky plane pointer (lo 15 bits)",
      "Chunky plane pointer (lo 16 bits)",
      "the low word of a 32-bit pointer has 16 bits"),
@@ -502,30 +511,34 @@ def display_control(rows):
           for ln in page("sagacontrol.htm") if "apoke" in ln]
     details = ["### Registers", ""] + reg_table(pick(rows, 0xDFF390, 0xDFF392) +
                                                 pick(rows, 0xDFF3EC, 0xDFF3EE))
-    details += ["", "### SAGA CONTROL (`$DFF3EC`, write)", "",
+    details += ["", "### SAGA CONTROL (`$DFF3EC`, write-only)", "",
+                f"SAGA Control 1: OCS mode, PAL zoom, zoom mode and scanlines ({WDS}).", "",
                 "Bit 15 is SET/CLR, as in DMACON: bits written as 1 are set when bit "
                 "15 is 1, and cleared when it is 0.", ""] + bits_md(sc)
     details += ["", "Examples from the original (`apoke address size value`):", "", "```text"]
     details += ex + ["```", "",
-                "### SCREEN SHIFT (`$DFF3EE`)", "",
+                "### SCREEN SHIFT (`$DFF3EE`, read and write)", "",
                 "The original's page has the title \"SAGA CONTROL Register\"; its "
                 "content is the screen shift:", ""] + bits_md(sh)
-    details += ["", "The original marks it R. Whether it is also writable is an open "
-                "question.", "",
+    details += ["", f"SAGA Control 2: the zoom shift. Read and write; X and Y are in "
+                f"pixels, positive integers ({WDS}). The original marks it R.", "",
                 "### SCREENMODE ADJUST (`$DFF390`)", ""] + bits_md(adj)
     details += ["", "The original's example on this page is the one of the planar "
                 "colour port (it sets colour 0 to red) and is left out."]
     return doc("display-control.md", "SAGA display control, screen shift and screen mode adjust",
                ["saga-video-isabelle"], ["saga", "isabelle", "scanlines", "zoom", "registers"],
-               "SAGA CONTROL (`$DFF3EC`) switches scanlines, zoom and a forced OCS mode; "
-               "SCREEN SHIFT (`$DFF3EE`) and SCREENMODE ADJUST (`$DFF390`) move and "
-               "enlarge the SAGA screen modes.",
+               "SAGA CONTROL (`$DFF3EC`, write-only) switches scanlines, zoom and a "
+               "forced OCS mode; SCREEN SHIFT (`$DFF3EE`, read and write) shifts the "
+               "zoomed screen in pixels; SCREENMODE ADJUST (`$DFF390`) enlarges the "
+               "SAGA screen modes.",
                details,
                ["- Classic Amiga chipsets have none of these registers: scanlines and "
                 "zoom are features of the SAGA video output."],
                ["DO set bit 15 to set bits and clear it to clear them.",
-                "DON'T treat `$DFF3EC` as read-only: the original's Access column is "
-                "wrong there."])
+                "DON'T read `$DFF3EC`: it is write-only, although the original's "
+                "Access column says R.",
+                "DO give the zoom shift in `$DFF3EE` as positive pixel counts."],
+               sources=[WD])
 
 
 def collisions(rows):
@@ -773,7 +786,6 @@ def system(rows):
     "Read-back at `$DFExxx`: known for `$DFE1D0`/`$DFE1D2` (pointer) and "
     "`$DFE1F4`/`$DFE1EC` (mode, frame pointer). Does every write register read back "
     "there?",
-    "SCREEN SHIFT (`$DFF3EE`): read only, as the original says, or also writable?",
     "Pointer: which cores have the 16x16 planar pointer (`$DFF800`, colours "
     "`$DFF3A0`–`$DFF3A6`) next to, or instead of, the 32x32 sprite at `$DFD000`?",
     "PIP format: the original lists YUV, ApolloLib supports only `$01`–`$03`.",

From 7c1e26039808c59fc43ea1bf6f08370b853f2533 Mon Sep 17 00:00:00 2001
From: Willem Drijver 
Date: Wed, 4 Nov 2026 14:41:14 +0300
Subject: [PATCH 03/12] SAGA registers: 32x32 pointer sprite from Core 12500

WDrijver, 2026-11-04: from Core 12500 the 32x32x8-bit hardware sprite
pointer replaces the old 16x16 pointer, and it has only 50 %
semi-transparency, no real alpha. Describe both generations with their
core ranges and drop the pointer open question.

Co-Authored-By: Claude Opus 5.5 
---
 core/saga-registers/index.md   |  5 ++--
 core/saga-registers/pointer.md | 28 +++++++++++++++-----
 tools/intake/sagaregs.py       | 48 ++++++++++++++++++++--------------
 3 files changed, 51 insertions(+), 30 deletions(-)

diff --git a/core/saga-registers/index.md b/core/saga-registers/index.md
index 1331bc6..9be5ffa 100644
--- a/core/saga-registers/index.md
+++ b/core/saga-registers/index.md
@@ -173,9 +173,8 @@ Wrong or missing page links in the original: the 32-bit Arne rows link to the cl
 1. The Copper form `dc.w $8380,$00FF,$0000` in the colour port pages: how the SAGA Copper encodes a 32-bit MOVE and which SAGA registers it reaches.
 2. "IRQ $48" (Ethernet) and "IRQ $50" (Arne channels 4–15): vector offsets or vector numbers, and at which interrupt level.
 3. Read-back at `$DFExxx`: known for `$DFE1D0`/`$DFE1D2` (pointer) and `$DFE1F4`/`$DFE1EC` (mode, frame pointer). Does every write register read back there?
-4. Pointer: which cores have the 16x16 planar pointer (`$DFF800`, colours `$DFF3A0`–`$DFF3A6`) next to, or instead of, the 32x32 sprite at `$DFD000`?
-5. PIP format: the original lists YUV, ApolloLib supports only `$01`–`$03`.
-6. Sprites 8–15: the collision bits name them; the original documents 8 sprites.
+4. PIP format: the original lists YUV, ApolloLib supports only `$01`–`$03`.
+5. Sprites 8–15: the collision bits name them; the original documents 8 sprites.
 
 ## Differences from AmigaOS / AROS / 68060
 
diff --git a/core/saga-registers/pointer.md b/core/saga-registers/pointer.md
index 2d8fd5b..9fc1113 100644
--- a/core/saga-registers/pointer.md
+++ b/core/saga-registers/pointer.md
@@ -17,6 +17,7 @@ sources:
   - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)"
   - "ApolloLib, older copy in ApolloClaude docs/toolchain/_ApolloLib (ApolloCrossDev_Defines.h), 2026-11-04"
   - "Example ApolloPointer.c, github.com/WDrijver/ApolloCrossDev Projects/ApolloPointer, commit 2dfaa5c (2026-09-02)"
+  - "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04"
 generated_from: sources/official/saga-registers/index.htm
 ---
 
@@ -24,10 +25,19 @@ generated_from: sources/official/saga-registers/index.htm
 
 ## Summary
 
-SAGA has a hardware mouse pointer: a 32x32 sprite with a 256-colour palette and alpha, positioned through `$DFF1D0`/`$DFF1D2`. The original documents only the position and three 12-bit colours; the sprite image and palette come from ApolloLib.
+SAGA has a hardware mouse pointer, positioned through `$DFF1D0`/`$DFF1D2`. From Core 12500 it is a 32x32 sprite with an 8-bit colour index, a 256-colour palette and 50 % semi-transparency; before that it was a 16x16 planar pointer. The original documents only the position and the old pointer's colours; the 32x32 sprite comes from ApolloLib.
 
 ## Details
 
+### Two pointer generations
+
+| Cores | Pointer |
+|---|---|
+| Core 12500 and later | 32x32, 8-bit colour index, 256-colour palette, 50 % semi-transparency |
+| Before Core 12500 | 16x16 planar, 12-bit colours |
+
+From Core 12500 the 32x32 sprite replaces the 16x16 pointer (WDrijver, 2026-11-04). The position registers are the same for both.
+
 ### Position (original and SRC)
 
 | Address | Name | Access | Description (original) |
@@ -41,20 +51,23 @@ SAGA has a hardware mouse pointer: a 32x32 sprite with a 256-colour palette and
 - Write X to `$DFF1D0` and Y to `$DFF1D2`; read them back at `$DFE1D0` and `$DFE1D2` (ApolloLib, SRC).
 - ApolloLib writes the mouse position + 16 (X) and + 8 (Y) (SRC).
 
-### 32x32 pointer sprite (SRC, not in the original)
+### 32x32 pointer sprite, Core 12500 and later (SRC, not in the original)
 
 From the current ApolloLib and the ApolloPointer example:
 
 | Address | Use |
 |---|---|
-| `$DFD000` | Image: 32 x 32 pixels, 2 bytes per pixel (colour index, alpha), 2048 bytes, row by row |
+| `$DFD000` | Image: 32 x 32 pixels, 2 bytes per pixel (colour index, transparency byte), 2048 bytes, row by row |
 | `$DFF3A8` | Palette index (word): write the entry number first |
 | `$DFF3AA` | Palette colour (long, R8G8B8) for the entry selected at `$DFF3A8` |
 
-- Index 0 is transparent. ApolloLib writes alpha `$FF` for opaque pixels and `$00` for semi-transparent ones; the example's usage text says colour 1 is semi-transparent.
+- Colour index 0 is fully transparent.
+- The second byte is not a real alpha: a pixel is either opaque or 50 % semi-transparent (WDrijver, 2026-11-04). ApolloLib writes `$FF` for opaque and `$00` for semi-transparent (SRC).
 - To set the palette, write the index to `$DFF3A8`, then the colour to `$DFF3AA`, for each of the 256 entries.
 
-### 12-bit pointer colours (original)
+### 16x16 pointer, before Core 12500
+
+The original lists three 12-bit colours of this pointer:
 
 | Address | Name | Access | Description (original) |
 |---|---|---|---|
@@ -62,7 +75,7 @@ From the current ApolloLib and the ApolloPointer example:
 | `$DFF3A4` | Sprite Col2 | W | Word register RGB (11..0) |
 | `$DFF3A6` | Sprite Col3 | W | Word register RGB (11..0) |
 
-These rows have no page in the original. An older ApolloLib copy adds colour 0 at `$DFF3A0` and a 16x16 planar pointer image at `$DFF800` (SRC). Which cores have this 16x16 pointer next to, or instead of, the 32x32 sprite is an open question (see [index.md](index.md)).
+These rows have no page in the original. An older ApolloLib copy adds colour 0 at `$DFF3A0` and the 16x16 planar image at `$DFF800` (SRC).
 
 ## Differences from AmigaOS / AROS / 68060
 
@@ -73,4 +86,5 @@ These rows have no page in the original. An older ApolloLib copy adds colour 0 a
 
 - DO write the palette through `$DFF3A8` (index) and `$DFF3AA` (colour).
 - DO keep colour index 0 for transparent pixels.
-- DON'T use `$DFF800` or `$DFF3A0`–`$DFF3A6` until the open question is settled.
+- DON'T expect real alpha blending: a pixel is opaque or 50 % semi-transparent.
+- DON'T use `$DFF800` or `$DFF3A0`–`$DFF3A6` on Core 12500 and later: they belong to the old 16x16 pointer.
diff --git a/tools/intake/sagaregs.py b/tools/intake/sagaregs.py
index 2dfb23a..33104bd 100644
--- a/tools/intake/sagaregs.py
+++ b/tools/intake/sagaregs.py
@@ -462,35 +462,42 @@ def pip(rows):
 def pointer(rows):
     pos = [by_addr(rows, "DFF1D0"), by_addr(rows, "DFF1D2")]
     cols = pick(rows, 0xDFF3A2, 0xDFF3A6)
-    details = ["### Position (original and SRC)", ""] + reg_table(pos)
+    details = ["### Two pointer generations", "",
+               "| Cores | Pointer |", "|---|---|",
+               "| Core 12500 and later | 32x32, 8-bit colour index, 256-colour palette, "
+               "50 % semi-transparency |",
+               "| Before Core 12500 | 16x16 planar, 12-bit colours |", "",
+               f"From Core 12500 the 32x32 sprite replaces the 16x16 pointer ({WDS}). The "
+               "position registers are the same for both.", "",
+               "### Position (original and SRC)", ""] + reg_table(pos)
     details += ["", "- Write X to `$DFF1D0` and Y to `$DFF1D2`; read them back at "
                 "`$DFE1D0` and `$DFE1D2` (ApolloLib, SRC).",
                 "- ApolloLib writes the mouse position + 16 (X) and + 8 (Y) (SRC).", "",
-                "### 32x32 pointer sprite (SRC, not in the original)", "",
+                "### 32x32 pointer sprite, Core 12500 and later (SRC, not in the original)", "",
                 "From the current ApolloLib and the ApolloPointer example:", "",
                 "| Address | Use |", "|---|---|",
                 "| `$DFD000` | Image: 32 x 32 pixels, 2 bytes per pixel (colour index, "
-                "alpha), 2048 bytes, row by row |",
+                "transparency byte), 2048 bytes, row by row |",
                 "| `$DFF3A8` | Palette index (word): write the entry number first |",
                 "| `$DFF3AA` | Palette colour (long, R8G8B8) for the entry selected at "
                 "`$DFF3A8` |", "",
-                "- Index 0 is transparent. ApolloLib writes alpha `$FF` for opaque "
-                "pixels and `$00` for semi-transparent ones; the example's usage text "
-                "says colour 1 is semi-transparent.",
+                "- Colour index 0 is fully transparent.",
+                f"- The second byte is not a real alpha: a pixel is either opaque or 50 % "
+                f"semi-transparent ({WDS}). ApolloLib writes `$FF` for opaque and `$00` for "
+                "semi-transparent (SRC).",
                 "- To set the palette, write the index to `$DFF3A8`, then the colour to "
                 "`$DFF3AA`, for each of the 256 entries.", "",
-                "### 12-bit pointer colours (original)", ""] + reg_table(cols)
+                "### 16x16 pointer, before Core 12500", "",
+                "The original lists three 12-bit colours of this pointer:", ""] + reg_table(cols)
     details += ["", "These rows have no page in the original. An older ApolloLib copy "
-                "adds colour 0 at `$DFF3A0` and a 16x16 planar pointer image at "
-                "`$DFF800` (SRC). Which cores have this 16x16 pointer next to, or "
-                "instead of, the 32x32 sprite is an open question (see "
-                "[index.md](index.md))."]
+                "adds colour 0 at `$DFF3A0` and the 16x16 planar image at `$DFF800` (SRC)."]
     return doc("pointer.md", "SAGA hardware sprite pointer",
                ["saga-video-isabelle"], ["saga", "isabelle", "pointer", "sprite", "registers"],
-               "SAGA has a hardware mouse pointer: a 32x32 sprite with a 256-colour "
-               "palette and alpha, positioned through `$DFF1D0`/`$DFF1D2`. The original "
-               "documents only the position and three 12-bit colours; the sprite "
-               "image and palette come from ApolloLib.",
+               "SAGA has a hardware mouse pointer, positioned through `$DFF1D0`/`$DFF1D2`. "
+               "From Core 12500 it is a 32x32 sprite with an 8-bit colour index, a "
+               "256-colour palette and 50 % semi-transparency; before that it was a "
+               "16x16 planar pointer. The original documents only the position and the "
+               "old pointer's colours; the 32x32 sprite comes from ApolloLib.",
                details,
                ["- On ECS, `$DFF1D0`/`$DFF1D2` are SPRHSTRT/SPRHSTOP (UHRES sprite "
                 "vertical start and stop). On SAGA they position the pointer.",
@@ -498,9 +505,12 @@ def pointer(rows):
                 "from Chip RAM. The SAGA pointer sprite is written directly to `$DFD000`."],
                ["DO write the palette through `$DFF3A8` (index) and `$DFF3AA` (colour).",
                 "DO keep colour index 0 for transparent pixels.",
-                "DON'T use `$DFF800` or `$DFF3A0`–`$DFF3A6` until the open question "
-                "is settled."],
-               sources=[APOLLOLIB, APOLLOLIB_OLD, EX_POINTER], basis=["official", "source-code"])
+                "DON'T expect real alpha blending: a pixel is opaque or 50 % "
+                "semi-transparent.",
+                "DON'T use `$DFF800` or `$DFF3A0`–`$DFF3A6` on Core 12500 and later: "
+                "they belong to the old 16x16 pointer."],
+               sources=[APOLLOLIB, APOLLOLIB_OLD, EX_POINTER, WD],
+               basis=["official", "source-code"])
 
 
 def display_control(rows):
@@ -786,8 +796,6 @@ def system(rows):
     "Read-back at `$DFExxx`: known for `$DFE1D0`/`$DFE1D2` (pointer) and "
     "`$DFE1F4`/`$DFE1EC` (mode, frame pointer). Does every write register read back "
     "there?",
-    "Pointer: which cores have the 16x16 planar pointer (`$DFF800`, colours "
-    "`$DFF3A0`–`$DFF3A6`) next to, or instead of, the 32x32 sprite at `$DFD000`?",
     "PIP format: the original lists YUV, ApolloLib supports only `$01`–`$03`.",
     "Sprites 8–15: the collision bits name them; the original documents 8 sprites.",
 ]

From ae923e5b257788508cff27aac7970d3dd6815863 Mon Sep 17 00:00:00 2001
From: Willem Drijver 
Date: Wed, 4 Nov 2026 15:05:11 +0300
Subject: [PATCH 04/12] SAGA registers: PIP formats and transparent colours

WDrijver, 2026-11-04: a PIP supports 8-bit indexed, R5G6B5, 1R5G5B5,
YUV888 and YUV444, not 24- or 32-bit. With format bit 8 set, the
transparent colour is fixed: index $FF in 8-bit, red and blue at maximum
(purple) in 15- and 16-bit. ApolloLib still marks YUV as unsupported; that
is an ApolloLib error. Drop the PIP format open question.

Co-Authored-By: Claude Opus 5.5 
---
 core/saga-registers/index.md |  3 +--
 core/saga-registers/pip.md   | 26 +++++++++++++++++-------
 tools/intake/sagaregs.py     | 38 +++++++++++++++++++++++-------------
 3 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/core/saga-registers/index.md b/core/saga-registers/index.md
index 9be5ffa..d2ce99c 100644
--- a/core/saga-registers/index.md
+++ b/core/saga-registers/index.md
@@ -173,8 +173,7 @@ Wrong or missing page links in the original: the 32-bit Arne rows link to the cl
 1. The Copper form `dc.w $8380,$00FF,$0000` in the colour port pages: how the SAGA Copper encodes a 32-bit MOVE and which SAGA registers it reaches.
 2. "IRQ $48" (Ethernet) and "IRQ $50" (Arne channels 4–15): vector offsets or vector numbers, and at which interrupt level.
 3. Read-back at `$DFExxx`: known for `$DFE1D0`/`$DFE1D2` (pointer) and `$DFE1F4`/`$DFE1EC` (mode, frame pointer). Does every write register read back there?
-4. PIP format: the original lists YUV, ApolloLib supports only `$01`–`$03`.
-5. Sprites 8–15: the collision bits name them; the original documents 8 sprites.
+4. Sprites 8–15: the collision bits name them; the original documents 8 sprites.
 
 ## Differences from AmigaOS / AROS / 68060
 
diff --git a/core/saga-registers/pip.md b/core/saga-registers/pip.md
index 6e12c1c..74e9d3f 100644
--- a/core/saga-registers/pip.md
+++ b/core/saga-registers/pip.md
@@ -18,6 +18,7 @@ sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)"
   - "Example SAGAPiP.c, github.com/WDrijver/ApolloCrossDev Projects/SAGAPiP, commit 2dfaa5c (2026-09-02)"
+  - "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04"
 generated_from: sources/official/saga-registers/index.htm
 ---
 
@@ -69,19 +70,29 @@ Its colour port is `$DFF37C` (see [colour-ports.md](colour-ports.md)). The SAGAP
 |---|---|
 | X/Y start, X/Y stop | Window position in screen pixels. The example writes X + 16 and Y − 1 to place the PIP exactly over a window. |
 | Pointer | 32-bit address of the PIP bitmap |
-| Format | Bits 7–0: pixel format as in GFXMODE, only `$01` (8-bit), `$02` (R5G6B5) and `$03` (1R5G5B5). Bit 8: transparency on, key colour `$F81F` in 16-bit mode. |
+| Format | Bits 7–0: pixel format; bit 8: transparency on. See the table below. |
 | Modulo | Bytes skipped after each row |
 | Colour key | Bit 15 = enable, bits 11–8 red, 7–4 green, 3–0 blue |
 | DMA row length | Bytes fetched per row = width × bytes per pixel. **0 switches the PIP off.** |
 
-### Two modes (SAGAPiP example, SRC)
+### Pixel formats and transparency
 
-- **Overlay:** colour key 0. The PIP is in front of the main screen; with format bit 8 set, pixels with `$F81F` are transparent.
-- **Chroma key:** colour key with bit 15 set, for example `$8F0F` (purple). The PIP is behind the main screen and shows only where the main screen has the key colour.
+| Format | Value | On PIP | Transparent colour (bit 8 set) |
+|---|---|---|---|
+| 8-bit indexed | `$01` | Yes | Index `$FF` |
+| 16-bit R5G6B5 | `$02` | Yes | `$F81F`: red and blue at maximum (purple) |
+| 15-bit 1R5G5B5 | `$03` | Yes | `$7C1F`: red and blue at maximum (purple) |
+| 24-bit R8G8B8 | `$04` | No | – |
+| 32-bit A8R8G8B8 | `$05` | No | – |
+| YUV888 | `$06` | Yes | Not documented |
+| YUV444 | `$0E` | Yes | Not documented |
 
-### Conflict with the original
+Formats and transparent colours: WDrijver, 2026-11-04. The transparent colour is fixed per format. ApolloLib still marks YUV as not supported on PIP; that is an error in ApolloLib, not in the hardware.
 
-The original describes PipFormat as "Colorformat (8bit/16bit/15bit/YUV)". ApolloLib marks YUV and the 24- and 32-bit formats as not supported on PIP. Until this is settled, use only `$01`–`$03`.
+### Two modes (SAGAPiP example, SRC)
+
+- **Overlay:** colour key 0. The PIP is in front of the main screen; with format bit 8 set, pixels in the transparent colour of the format are transparent.
+- **Chroma key:** colour key with bit 15 set, for example `$8F0F` (purple). The PIP is behind the main screen and shows only where the main screen has the key colour.
 
 ## Differences from AmigaOS / AROS / 68060
 
@@ -91,4 +102,5 @@ The original describes PipFormat as "Colorformat (8bit/16bit/15bit/YUV)". Apollo
 
 - DO set the DMA row length last: it switches the PIP on.
 - DO write 0 to the DMA row length to switch a PIP off.
-- DON'T use YUV, 24- or 32-bit formats for a PIP.
+- DON'T use the 24- or 32-bit formats (`$04`, `$05`) for a PIP.
+- DO keep the transparent colour (`$FF` in 8-bit, purple in 15- and 16-bit) out of the PIP image, except where it should be transparent.
diff --git a/tools/intake/sagaregs.py b/tools/intake/sagaregs.py
index 33104bd..afe6943 100644
--- a/tools/intake/sagaregs.py
+++ b/tools/intake/sagaregs.py
@@ -425,24 +425,33 @@ def pip(rows):
                 "| X/Y start, X/Y stop | Window position in screen pixels. The example "
                 "writes X + 16 and Y − 1 to place the PIP exactly over a window. |",
                 "| Pointer | 32-bit address of the PIP bitmap |",
-                "| Format | Bits 7–0: pixel format as in GFXMODE, only `$01` (8-bit), "
-                "`$02` (R5G6B5) and `$03` (1R5G5B5). Bit 8: transparency on, key colour "
-                "`$F81F` in 16-bit mode. |",
+                "| Format | Bits 7–0: pixel format; bit 8: transparency on. See the "
+                "table below. |",
                 "| Modulo | Bytes skipped after each row |",
                 "| Colour key | Bit 15 = enable, bits 11–8 red, 7–4 green, 3–0 blue |",
                 "| DMA row length | Bytes fetched per row = width × bytes per pixel. "
                 "**0 switches the PIP off.** |",
-                "", "### Two modes (SAGAPiP example, SRC)", "",
+                "", "### Pixel formats and transparency", "",
+                "| Format | Value | On PIP | Transparent colour (bit 8 set) |",
+                "|---|---|---|---|",
+                "| 8-bit indexed | `$01` | Yes | Index `$FF` |",
+                "| 16-bit R5G6B5 | `$02` | Yes | `$F81F`: red and blue at maximum (purple) |",
+                "| 15-bit 1R5G5B5 | `$03` | Yes | `$7C1F`: red and blue at maximum (purple) |",
+                "| 24-bit R8G8B8 | `$04` | No | – |",
+                "| 32-bit A8R8G8B8 | `$05` | No | – |",
+                "| YUV888 | `$06` | Yes | Not documented |",
+                "| YUV444 | `$0E` | Yes | Not documented |",
+                "",
+                f"Formats and transparent colours: {WDS}. The transparent colour is "
+                "fixed per format. ApolloLib still marks YUV as not supported on PIP; "
+                "that is an error in ApolloLib, not in the hardware.", "",
+                "### Two modes (SAGAPiP example, SRC)", "",
                 "- **Overlay:** colour key 0. The PIP is in front of the main screen; "
-                "with format bit 8 set, pixels with `$F81F` are transparent.",
+                "with format bit 8 set, pixels in the transparent colour of the "
+                "format are transparent.",
                 "- **Chroma key:** colour key with bit 15 set, for example `$8F0F` "
                 "(purple). The PIP is behind the main screen and shows only where the "
-                "main screen has the key colour.", "",
-                "### Conflict with the original", "",
-                "The original describes PipFormat as \"Colorformat "
-                "(8bit/16bit/15bit/YUV)\". ApolloLib marks YUV and the 24- and 32-bit "
-                "formats as not supported on PIP. Until this is settled, use only "
-                "`$01`–`$03`."]
+                "main screen has the key colour."]
     return doc("pip.md", "SAGA picture in picture (PIP 1 and PIP 2)",
                ["saga-video-isabelle"], ["saga", "isabelle", "pip", "overlay", "registers"],
                "SAGA overlays up to two picture-in-picture windows (PIP) on the main "
@@ -454,8 +463,10 @@ def pip(rows):
                 "classic feature, and it is limited to planar bitmaps in Chip RAM."],
                ["DO set the DMA row length last: it switches the PIP on.",
                 "DO write 0 to the DMA row length to switch a PIP off.",
-                "DON'T use YUV, 24- or 32-bit formats for a PIP."],
-               sources=[APOLLOLIB, EX_PIP], basis=["official", "source-code"],
+                "DON'T use the 24- or 32-bit formats (`$04`, `$05`) for a PIP.",
+                "DO keep the transparent colour (`$FF` in 8-bit, purple in 15- and "
+                "16-bit) out of the PIP image, except where it should be transparent."],
+               sources=[APOLLOLIB, EX_PIP, WD], basis=["official", "source-code"],
                related=[f"{OUTDIR}/colour-ports.md", f"{OUTDIR}/chunky-plane.md"])
 
 
@@ -796,7 +807,6 @@ def system(rows):
     "Read-back at `$DFExxx`: known for `$DFE1D0`/`$DFE1D2` (pointer) and "
     "`$DFE1F4`/`$DFE1EC` (mode, frame pointer). Does every write register read back "
     "there?",
-    "PIP format: the original lists YUV, ApolloLib supports only `$01`–`$03`.",
     "Sprites 8–15: the collision bits name them; the original documents 8 sprites.",
 ]
 

From 54545666553c34c87e3387777b20448028e7174d Mon Sep 17 00:00:00 2001
From: Willem Drijver 
Date: Wed, 4 Nov 2026 15:37:01 +0300
Subject: [PATCH 05/12] SAGA registers: SAGA has the 8 classic sprites

WDrijver, 2026-11-04: SAGA supports the 8 classic sprites, as on the
classic Amiga. Only bits 0-7 of clxdat0-7 refer to real sprites. Drop the
sprites 8-15 open question.

Co-Authored-By: Claude Opus 5.5 
---
 core/saga-registers/index.md            |  1 -
 core/saga-registers/sprite-collision.md |  5 +++--
 tools/intake/sagaregs.py                | 10 +++++-----
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/core/saga-registers/index.md b/core/saga-registers/index.md
index d2ce99c..b719271 100644
--- a/core/saga-registers/index.md
+++ b/core/saga-registers/index.md
@@ -173,7 +173,6 @@ Wrong or missing page links in the original: the 32-bit Arne rows link to the cl
 1. The Copper form `dc.w $8380,$00FF,$0000` in the colour port pages: how the SAGA Copper encodes a 32-bit MOVE and which SAGA registers it reaches.
 2. "IRQ $48" (Ethernet) and "IRQ $50" (Arne channels 4–15): vector offsets or vector numbers, and at which interrupt level.
 3. Read-back at `$DFExxx`: known for `$DFE1D0`/`$DFE1D2` (pointer) and `$DFE1F4`/`$DFE1EC` (mode, frame pointer). Does every write register read back there?
-4. Sprites 8–15: the collision bits name them; the original documents 8 sprites.
 
 ## Differences from AmigaOS / AROS / 68060
 
diff --git a/core/saga-registers/sprite-collision.md b/core/saga-registers/sprite-collision.md
index c566405..5b799ec 100644
--- a/core/saga-registers/sprite-collision.md
+++ b/core/saga-registers/sprite-collision.md
@@ -14,6 +14,7 @@ related:
   - core/saga-registers/index.md
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
+  - "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04"
 generated_from: sources/official/saga-registers/index.htm
 ---
 
@@ -59,7 +60,7 @@ Bit layout (one register per sprite):
 | 1 | HIT1 | Sprite to Sprite1 |
 | 0 | HIT0 | Sprite to Sprite0 |
 
-The bits name sprites 0 to F (16 sprites), but the original lists registers for sprites 0–7 only. Whether sprites 8–15 exist is not documented.
+SAGA has the 8 classic sprites, as on the classic Amiga (WDrijver, 2026-11-04). The original's bit table names sprites 0 to F; since sprites 8–F don't exist, only bits 0–7 refer to real sprites.
 
 ## Differences from AmigaOS / AROS / 68060
 
@@ -68,4 +69,4 @@ The bits name sprites 0 to F (16 sprites), but the original lists registers for
 ## Do / Don't
 
 - DO read the register of the sprite you are interested in.
-- DON'T assume sprites 8–15 exist.
+- DON'T use bits 8–15: SAGA has 8 sprites.
diff --git a/tools/intake/sagaregs.py b/tools/intake/sagaregs.py
index afe6943..9c03db4 100644
--- a/tools/intake/sagaregs.py
+++ b/tools/intake/sagaregs.py
@@ -567,9 +567,9 @@ def collisions(rows):
     details = ["### Registers", ""] + reg_table(c)
     details += ["", "Bit layout (one register per sprite):", ""] + \
         bits_md(box_table(page("clxdatx.htm")))
-    details += ["", "The bits name sprites 0 to F (16 sprites), but the original lists "
-                "registers for sprites 0–7 only. Whether sprites 8–15 exist is not "
-                "documented."]
+    details += ["", f"SAGA has the 8 classic sprites, as on the classic Amiga ({WDS}). "
+                "The original's bit table names sprites 0 to F; since sprites 8–F "
+                "don't exist, only bits 0–7 refer to real sprites."]
     return doc("sprite-collision.md", "SAGA detailed sprite collision",
                ["saga-video-isabelle"], ["saga", "isabelle", "sprites", "collision", "registers"],
                "SAGA reports, per sprite, which other sprites it touches, in one "
@@ -578,7 +578,8 @@ def collisions(rows):
                ["- Classic CLXDAT (`$DFF00E`) reports collisions only between sprite "
                 "pairs and playfields, and clears on read."],
                ["DO read the register of the sprite you are interested in.",
-                "DON'T assume sprites 8–15 exist."])
+                "DON'T use bits 8–15: SAGA has 8 sprites."],
+               sources=[WD])
 
 
 ARNE_LAYOUT = [("+0", "AUDxL", "L", "W", "Pointer to the sample data (32-bit, any RAM)"),
@@ -807,7 +808,6 @@ def system(rows):
     "Read-back at `$DFExxx`: known for `$DFE1D0`/`$DFE1D2` (pointer) and "
     "`$DFE1F4`/`$DFE1EC` (mode, frame pointer). Does every write register read back "
     "there?",
-    "Sprites 8–15: the collision bits name them; the original documents 8 sprites.",
 ]
 
 

From 4eaf9eb832b820bc3afd12d1ff59388b8f01e20d Mon Sep 17 00:00:00 2001
From: Willem Drijver 
Date: Wed, 4 Nov 2026 15:40:26 +0300
Subject: [PATCH 06/12] SAGA registers: write-only registers read back at
 $DFExxx

WDrijver, 2026-11-04: every write-only register at $DFF000-$DFF1FF reads
back at the same offset in $DFE000-$DFE1FF. State the rule in the index,
chunky-plane and pointer files, and narrow the open question to the
write-only registers from $DFF200 up.

Co-Authored-By: Claude Opus 5.5 
---
 core/saga-registers/chunky-plane.md |  2 +-
 core/saga-registers/index.md        |  6 +++++-
 core/saga-registers/pointer.md      |  2 +-
 tools/intake/sagaregs.py            | 25 ++++++++++++++++---------
 4 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/core/saga-registers/chunky-plane.md b/core/saga-registers/chunky-plane.md
index df02851..6fd5788 100644
--- a/core/saga-registers/chunky-plane.md
+++ b/core/saga-registers/chunky-plane.md
@@ -99,7 +99,7 @@ Values `$08`–`$0B` are Atari planar formats (ApolloLib names them APOLLO_ATARI
 
 ### Reading the current mode back
 
-The original gives no read address. maggie.library's samples save the current mode and frame pointer from `$DFE1F4` and `$DFE1EC` (SRC, see [maggie-library.md](../../os/libraries/maggie-library.md)). Whether every SAGA register reads back at `$DFExxx` is an open question (see [index.md](index.md)).
+Every write-only register at `$DFF000`–`$DFF1FF` reads back at the same offset in `$DFE000`–`$DFE1FF` (WDrijver, 2026-11-04): GFXMODE at `$DFE1F4`, the chunky pointer at `$DFE1EC`, the modulo at `$DFE1E6`. maggie.library's samples save the mode and frame pointer this way (SRC, see [maggie-library.md](../../os/libraries/maggie-library.md)).
 
 ## Differences from AmigaOS / AROS / 68060
 
diff --git a/core/saga-registers/index.md b/core/saga-registers/index.md
index b719271..d0c1f97 100644
--- a/core/saga-registers/index.md
+++ b/core/saga-registers/index.md
@@ -38,6 +38,10 @@ Every one of the 419 rows of the original is marked SAGA, because SAGA contains
 
 For every other register, the Amiga Hardware Reference Manual applies, with one difference: **on SAGA, all classic pointer registers (BPLxPT, SPRxPT, COPxLC, BLTxPT, AUDxLC, DSKPT) are 32 bits wide and reach all RAM** (WDrijver, 2026-11-04). Their pages in the original still say 18 bits. FMODE (`$DFF1FC`) bit 4 "SAGA" enables the SAGA features (original).
 
+### Reading back write-only registers
+
+Every write-only register at `$DFF000`–`$DFF1FF` reads back at the same offset in `$DFE000`–`$DFE1FF` (WDrijver, 2026-11-04). This holds for the classic and the SAGA registers in that range, for example DMACON `$DFF096` at `$DFE096`, GFXMODE `$DFF1F4` at `$DFE1F4` and the pointer position `$DFF1D0` at `$DFE1D0`. The original doesn't mention it.
+
 ### Access codes (original)
 
 | Code | Meaning |
@@ -172,7 +176,7 @@ Wrong or missing page links in the original: the 32-bit Arne rows link to the cl
 
 1. The Copper form `dc.w $8380,$00FF,$0000` in the colour port pages: how the SAGA Copper encodes a 32-bit MOVE and which SAGA registers it reaches.
 2. "IRQ $48" (Ethernet) and "IRQ $50" (Arne channels 4–15): vector offsets or vector numbers, and at which interrupt level.
-3. Read-back at `$DFExxx`: known for `$DFE1D0`/`$DFE1D2` (pointer) and `$DFE1F4`/`$DFE1EC` (mode, frame pointer). Does every write register read back there?
+3. Read-back above `$DFF1FF`: write-only registers at `$DFF000`–`$DFF1FF` read back at `$DFE000`–`$DFE1FF`. Is there a read-back for the write-only registers from `$DFF200` up (Maggie, DMACON2, colour ports, PIP, Arne)?
 
 ## Differences from AmigaOS / AROS / 68060
 
diff --git a/core/saga-registers/pointer.md b/core/saga-registers/pointer.md
index 9fc1113..121aba9 100644
--- a/core/saga-registers/pointer.md
+++ b/core/saga-registers/pointer.md
@@ -48,7 +48,7 @@ From Core 12500 the 32x32 sprite replaces the 16x16 pointer (WDrijver, 2026-11-0
 - `$DFF1D0`: on SAGA this is the pointer X position; the original also marks ECS and AGA.
 - `$DFF1D2`: on SAGA this is the pointer Y position; the original also marks ECS and AGA.
 
-- Write X to `$DFF1D0` and Y to `$DFF1D2`; read them back at `$DFE1D0` and `$DFE1D2` (ApolloLib, SRC).
+- Write X to `$DFF1D0` and Y to `$DFF1D2`; read them back at `$DFE1D0` and `$DFE1D2`, as every write-only register up to `$DFF1FF` (WDrijver, 2026-11-04; ApolloLib does this, SRC).
 - ApolloLib writes the mouse position + 16 (X) and + 8 (Y) (SRC).
 
 ### 32x32 pointer sprite, Core 12500 and later (SRC, not in the original)
diff --git a/tools/intake/sagaregs.py b/tools/intake/sagaregs.py
index 9c03db4..b0ae898 100644
--- a/tools/intake/sagaregs.py
+++ b/tools/intake/sagaregs.py
@@ -343,11 +343,11 @@ def chunky_plane(rows):
                 "text says \"UHRES bitplane pointer\"; on SAGA it is the chunky plane: "
                 "the number of bytes skipped after each row (ApolloLib, SRC).", "",
                 "### Reading the current mode back", "",
-                "The original gives no read address. maggie.library's samples save "
-                "the current mode and frame pointer from `$DFE1F4` and `$DFE1EC` "
-                "(SRC, see [maggie-library.md](../../os/libraries/maggie-library.md)). "
-                "Whether every SAGA register reads back at `$DFExxx` is an open "
-                "question (see [index.md](index.md))."]
+                "Every write-only register at `$DFF000`–`$DFF1FF` reads back at the "
+                f"same offset in `$DFE000`–`$DFE1FF` ({WDS}): GFXMODE at `$DFE1F4`, "
+                "the chunky pointer at `$DFE1EC`, the modulo at `$DFE1E6`. "
+                "maggie.library's samples save the mode and frame pointer this way "
+                "(SRC, see [maggie-library.md](../../os/libraries/maggie-library.md))."]
     return doc("chunky-plane.md", "SAGA chunky plane: GFXMODE, pointer and modulo",
                ["saga-video-isabelle"], ["saga", "isabelle", "gfxmode", "chunky", "registers"],
                "The SAGA chunky plane is a linear framebuffer in any RAM. GFXMODE "
@@ -482,7 +482,8 @@ def pointer(rows):
                "position registers are the same for both.", "",
                "### Position (original and SRC)", ""] + reg_table(pos)
     details += ["", "- Write X to `$DFF1D0` and Y to `$DFF1D2`; read them back at "
-                "`$DFE1D0` and `$DFE1D2` (ApolloLib, SRC).",
+                f"`$DFE1D0` and `$DFE1D2`, as every write-only register up to `$DFF1FF` "
+                f"({WDS}; ApolloLib does this, SRC).",
                 "- ApolloLib writes the mouse position + 16 (X) and + 8 (Y) (SRC).", "",
                 "### 32x32 pointer sprite, Core 12500 and later (SRC, not in the original)", "",
                 "From the current ApolloLib and the ApolloPointer example:", "",
@@ -805,9 +806,9 @@ def system(rows):
     "SAGA Copper encodes a 32-bit MOVE and which SAGA registers it reaches.",
     "\"IRQ $48\" (Ethernet) and \"IRQ $50\" (Arne channels 4–15): vector offsets or "
     "vector numbers, and at which interrupt level.",
-    "Read-back at `$DFExxx`: known for `$DFE1D0`/`$DFE1D2` (pointer) and "
-    "`$DFE1F4`/`$DFE1EC` (mode, frame pointer). Does every write register read back "
-    "there?",
+    "Read-back above `$DFF1FF`: write-only registers at `$DFF000`–`$DFF1FF` read "
+    "back at `$DFE000`–`$DFE1FF`. Is there a read-back for the write-only registers "
+    "from `$DFF200` up (Maggie, DMACON2, colour ports, PIP, Arne)?",
 ]
 
 
@@ -857,6 +858,12 @@ def index(rows, keep, applied):
                f"reach all RAM** ({WDS}). Their pages in the "
                "original still say 18 bits. FMODE (`$DFF1FC`) bit 4 \"SAGA\" enables "
                "the SAGA features (original).", "",
+               "### Reading back write-only registers", "",
+               "Every write-only register at `$DFF000`–`$DFF1FF` reads back at the "
+               f"same offset in `$DFE000`–`$DFE1FF` ({WDS}). This holds for the "
+               "classic and the SAGA registers in that range, for example DMACON "
+               "`$DFF096` at `$DFE096`, GFXMODE `$DFF1F4` at `$DFE1F4` and the pointer "
+               "position `$DFF1D0` at `$DFE1D0`. The original doesn't mention it.", "",
                "### Access codes (original)", "",
                "| Code | Meaning |", "|---|---|"]
     details += [f"| {k} | {v} |" for k, v in ACCESS.items()]

From f0d44e32f09f345469e370499b03d6383f88176d Mon Sep 17 00:00:00 2001
From: Willem Drijver 
Date: Wed, 4 Nov 2026 15:44:07 +0300
Subject: [PATCH 07/12] SAGA registers: 32-bit Copper MOVE in SAGA mode

BigGun (Apollo chat, 2026-11-04, relayed by WDrijver): the SAGA Copper can
do 32-bit moves; the first word has its high bit set; SAGA mode needs the
SAGA bit in FMODE; without it the Copper writes only $DFF0xx and $DFF1xx.
Describe the three-word form in colour-ports.md and the FMODE note in the
index, and narrow the Copper open question.

Co-Authored-By: Claude Opus 5.5 
---
 core/saga-registers/colour-ports.md | 19 +++++++++++++---
 core/saga-registers/index.md        |  4 ++--
 tools/intake/sagaregs.py            | 35 ++++++++++++++++++++---------
 3 files changed, 43 insertions(+), 15 deletions(-)

diff --git a/core/saga-registers/colour-ports.md b/core/saga-registers/colour-ports.md
index fe4e324..b9076c8 100644
--- a/core/saga-registers/colour-ports.md
+++ b/core/saga-registers/colour-ports.md
@@ -4,7 +4,7 @@ type: reference
 owner: WDrijver
 status: draft
 origin: official
-basis: [official, source-code]
+basis: [official, source-code, other]
 components: [saga-video-isabelle]
 applies_to:
   core: "Core 12000+"
@@ -15,6 +15,7 @@ related:
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)"
+  - "BigGun, Apollo chat, 2026-11-04 (relayed by WDrijver)"
 generated_from: sources/official/saga-registers/index.htm
 ---
 
@@ -63,7 +64,18 @@ Each port is one 32-bit register (the original lists its high and low word, H an
     move.l  #$01FFFF00,$DFF380   ; colour 1 = yellow
 ```
 
-The original also shows a Copper form, `dc.w $8380,$00FF,$0000` ("set color0 = RED"). This is three words, while a classic Copper MOVE has two. How the SAGA Copper encodes a 32-bit MOVE is an open question (see [index.md](index.md)); don't use the form until it is documented.
+### Copper: 32-bit MOVE
+
+```asm
+    dc.w    $8380,$00FF,$0000    ; colour 0 = red (original)
+```
+
+- The SAGA Copper can do 32-bit moves (BigGun, 2026-11-04).
+- A 32-bit MOVE has the high bit of its first word set (BigGun, 2026-11-04): `$8380` = bit 15 + register `$380`. The two words after it are the 32-bit value, high word first, as in the original's example.
+- It needs SAGA mode: set the SAGA bit in FMODE (`$DFF1FC` bit 4) first (BigGun, 2026-11-04).
+- Without the SAGA bit, the Copper can write only `$DFF0xx` and `$DFF1xx` (BigGun, 2026-11-04), so it can't reach the colour ports at `$DFF3xx`.
+
+A classic Copper MOVE is two words (register, 16-bit value). Read the classic way, `$8380` would be COLOR00 (`$180`), and the third word the start of the next instruction.
 
 ## Differences from AmigaOS / AROS / 68060
 
@@ -72,4 +84,5 @@ The original also shows a Copper form, `dc.w $8380,$00FF,$0000` ("set color0 = R
 ## Do / Don't
 
 - DO write the port with one `move.l`.
-- DON'T use the three-word Copper form from the original yet.
+- DO set FMODE bit 4 (SAGA) before a Copper list writes a colour port.
+- DO set bit 15 in the first word of a 32-bit Copper MOVE.
diff --git a/core/saga-registers/index.md b/core/saga-registers/index.md
index d0c1f97..e26b45f 100644
--- a/core/saga-registers/index.md
+++ b/core/saga-registers/index.md
@@ -36,7 +36,7 @@ The SAGA-specific chipset registers of the Apollo V4, converted from the officia
 
 Every one of the 419 rows of the original is marked SAGA, because SAGA contains the classic chipset. These files cover the 188 SAGA-specific rows: the rows where OCS, ECS and AGA are empty, plus the SAGA addresses that the original also marks as classic.
 
-For every other register, the Amiga Hardware Reference Manual applies, with one difference: **on SAGA, all classic pointer registers (BPLxPT, SPRxPT, COPxLC, BLTxPT, AUDxLC, DSKPT) are 32 bits wide and reach all RAM** (WDrijver, 2026-11-04). Their pages in the original still say 18 bits. FMODE (`$DFF1FC`) bit 4 "SAGA" enables the SAGA features (original).
+For every other register, the Amiga Hardware Reference Manual applies, with one difference: **on SAGA, all classic pointer registers (BPLxPT, SPRxPT, COPxLC, BLTxPT, AUDxLC, DSKPT) are 32 bits wide and reach all RAM** (WDrijver, 2026-11-04). Their pages in the original still say 18 bits. FMODE (`$DFF1FC`) bit 4 "SAGA" enables the SAGA features (original); among them, it lets the Copper write above `$DFF1FF` and do 32-bit moves (BigGun, 2026-11-04, see [colour-ports.md](colour-ports.md)).
 
 ### Reading back write-only registers
 
@@ -174,7 +174,7 @@ Wrong or missing page links in the original: the 32-bit Arne rows link to the cl
 
 ### Open questions
 
-1. The Copper form `dc.w $8380,$00FF,$0000` in the colour port pages: how the SAGA Copper encodes a 32-bit MOVE and which SAGA registers it reaches.
+1. Copper in SAGA mode: does it reach every SAGA register, including Arne at `$DFF400`–`$DFF4FF` (that needs register bit 10)? Can it also do 16-bit moves above `$DFF1FF`, and does COPCON's danger bit still apply?
 2. "IRQ $48" (Ethernet) and "IRQ $50" (Arne channels 4–15): vector offsets or vector numbers, and at which interrupt level.
 3. Read-back above `$DFF1FF`: write-only registers at `$DFF000`–`$DFF1FF` read back at `$DFE000`–`$DFE1FF`. Is there a read-back for the write-only registers from `$DFF200` up (Maggie, DMACON2, colour ports, PIP, Arne)?
 
diff --git a/tools/intake/sagaregs.py b/tools/intake/sagaregs.py
index b0ae898..5c46362 100644
--- a/tools/intake/sagaregs.py
+++ b/tools/intake/sagaregs.py
@@ -30,6 +30,8 @@
 SOURCE_NAME = "SAGA register documentation, sources/official/saga-registers/ (HTML)"
 WD = "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04"
 WDS = "WDrijver, 2026-11-04"
+BIGGUN = "BigGun, Apollo chat, 2026-11-04 (relayed by WDrijver)"
+BGS = "BigGun, 2026-11-04"
 APOLLOLIB = ("ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib "
              "(ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)")
 APOLLOLIB_OLD = ("ApolloLib, older copy in ApolloClaude docs/toolchain/_ApolloLib "
@@ -383,11 +385,20 @@ def colour_ports(rows):
                 "    move.l  #$00FF0000,$DFF380   ; colour 0 = red",
                 "    move.l  #$01FFFF00,$DFF380   ; colour 1 = yellow",
                 "```", "",
-                "The original also shows a Copper form, `dc.w $8380,$00FF,$0000` "
-                "(\"set color0 = RED\"). This is three words, while a classic Copper "
-                "MOVE has two. How the SAGA Copper encodes a 32-bit MOVE is an open "
-                "question (see [index.md](index.md)); don't use the form until it is "
-                "documented."]
+                "### Copper: 32-bit MOVE", "", "```asm",
+                "    dc.w    $8380,$00FF,$0000    ; colour 0 = red (original)",
+                "```", "",
+                f"- The SAGA Copper can do 32-bit moves ({BGS}).",
+                f"- A 32-bit MOVE has the high bit of its first word set ({BGS}): "
+                "`$8380` = bit 15 + register `$380`. The two words after it are the "
+                "32-bit value, high word first, as in the original's example.",
+                f"- It needs SAGA mode: set the SAGA bit in FMODE (`$DFF1FC` bit 4) "
+                f"first ({BGS}).",
+                f"- Without the SAGA bit, the Copper can write only `$DFF0xx` and "
+                f"`$DFF1xx` ({BGS}), so it can't reach the colour ports at `$DFF3xx`.", "",
+                "A classic Copper MOVE is two words (register, 16-bit value). Read the "
+                "classic way, `$8380` would be COLOR00 (`$180`), and the third word the "
+                "start of the next instruction."]
     return doc("colour-ports.md", "SAGA colour ports (24-bit palettes)",
                ["saga-video-isabelle"], ["saga", "isabelle", "palette", "colour", "registers"],
                "SAGA sets 24-bit palette entries through 32-bit colour ports: one "
@@ -398,8 +409,9 @@ def colour_ports(rows):
                 "reaches 256 through banks and BPLCON3. A SAGA port writes any of 256 "
                 "entries in one 32-bit write."],
                ["DO write the port with one `move.l`.",
-                "DON'T use the three-word Copper form from the original yet."],
-               sources=[APOLLOLIB], basis=["official", "source-code"])
+                "DO set FMODE bit 4 (SAGA) before a Copper list writes a colour port.",
+                "DO set bit 15 in the first word of a 32-bit Copper MOVE."],
+               sources=[APOLLOLIB, BIGGUN], basis=["official", "source-code", "other"])
 
 
 PIP2 = [("DFF3B0", "PIP2 X start"), ("DFF3B2", "PIP2 Y start"),
@@ -802,8 +814,9 @@ def system(rows):
          ("system.md", "Board ID, core revision, chip ID, SPI")]
 
 OPEN = [
-    "The Copper form `dc.w $8380,$00FF,$0000` in the colour port pages: how the "
-    "SAGA Copper encodes a 32-bit MOVE and which SAGA registers it reaches.",
+    "Copper in SAGA mode: does it reach every SAGA register, including Arne at "
+    "`$DFF400`–`$DFF4FF` (that needs register bit 10)? Can it also do 16-bit moves "
+    "above `$DFF1FF`, and does COPCON's danger bit still apply?",
     "\"IRQ $48\" (Ethernet) and \"IRQ $50\" (Arne channels 4–15): vector offsets or "
     "vector numbers, and at which interrupt level.",
     "Read-back above `$DFF1FF`: write-only registers at `$DFF000`–`$DFF1FF` read "
@@ -857,7 +870,9 @@ def index(rows, keep, applied):
                "(BPLxPT, SPRxPT, COPxLC, BLTxPT, AUDxLC, DSKPT) are 32 bits wide and "
                f"reach all RAM** ({WDS}). Their pages in the "
                "original still say 18 bits. FMODE (`$DFF1FC`) bit 4 \"SAGA\" enables "
-               "the SAGA features (original).", "",
+               "the SAGA features (original); among them, it lets the Copper write "
+               f"above `$DFF1FF` and do 32-bit moves ({BGS}, see "
+               "[colour-ports.md](colour-ports.md)).", "",
                "### Reading back write-only registers", "",
                "Every write-only register at `$DFF000`–`$DFF1FF` reads back at the "
                f"same offset in `$DFE000`–`$DFE1FF` ({WDS}). This holds for the "

From 8121cd02a8b82874e88181de6aa3402309c70bc1 Mon Sep 17 00:00:00 2001
From: Willem Drijver 
Date: Wed, 4 Nov 2026 15:44:35 +0300
Subject: [PATCH 08/12] SAGA registers: the Copper facts are from Gunnar (G)

BigGun is Gunnar, the core developer (WDrijver, 2026-11-04). Tag the
Copper facts (G) and add core-developer to the basis of the files that use
them.

Co-Authored-By: Claude Opus 5.5 
---
 core/saga-registers/colour-ports.md | 12 ++++++------
 core/saga-registers/index.md        |  5 +++--
 tools/intake/sagaregs.py            |  9 +++++----
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/core/saga-registers/colour-ports.md b/core/saga-registers/colour-ports.md
index b9076c8..4969280 100644
--- a/core/saga-registers/colour-ports.md
+++ b/core/saga-registers/colour-ports.md
@@ -4,7 +4,7 @@ type: reference
 owner: WDrijver
 status: draft
 origin: official
-basis: [official, source-code, other]
+basis: [core-developer, official, source-code]
 components: [saga-video-isabelle]
 applies_to:
   core: "Core 12000+"
@@ -15,7 +15,7 @@ related:
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)"
-  - "BigGun, Apollo chat, 2026-11-04 (relayed by WDrijver)"
+  - "Gunnar (core developer, BigGun), Apollo chat, 2026-11-04 (relayed by WDrijver)"
 generated_from: sources/official/saga-registers/index.htm
 ---
 
@@ -70,10 +70,10 @@ Each port is one 32-bit register (the original lists its high and low word, H an
     dc.w    $8380,$00FF,$0000    ; colour 0 = red (original)
 ```
 
-- The SAGA Copper can do 32-bit moves (BigGun, 2026-11-04).
-- A 32-bit MOVE has the high bit of its first word set (BigGun, 2026-11-04): `$8380` = bit 15 + register `$380`. The two words after it are the 32-bit value, high word first, as in the original's example.
-- It needs SAGA mode: set the SAGA bit in FMODE (`$DFF1FC` bit 4) first (BigGun, 2026-11-04).
-- Without the SAGA bit, the Copper can write only `$DFF0xx` and `$DFF1xx` (BigGun, 2026-11-04), so it can't reach the colour ports at `$DFF3xx`.
+- The SAGA Copper can do 32-bit moves (G, 2026-11-04).
+- A 32-bit MOVE has the high bit of its first word set (G, 2026-11-04): `$8380` = bit 15 + register `$380`. The two words after it are the 32-bit value, high word first, as in the original's example.
+- It needs SAGA mode: set the SAGA bit in FMODE (`$DFF1FC` bit 4) first (G, 2026-11-04).
+- Without the SAGA bit, the Copper can write only `$DFF0xx` and `$DFF1xx` (G, 2026-11-04), so it can't reach the colour ports at `$DFF3xx`.
 
 A classic Copper MOVE is two words (register, 16-bit value). Read the classic way, `$8380` would be COLOR00 (`$180`), and the third word the start of the next instruction.
 
diff --git a/core/saga-registers/index.md b/core/saga-registers/index.md
index e26b45f..61c7f47 100644
--- a/core/saga-registers/index.md
+++ b/core/saga-registers/index.md
@@ -4,7 +4,7 @@ type: reference
 owner: WDrijver
 status: draft
 origin: official
-basis: [official, source-code]
+basis: [core-developer, official, source-code]
 components: [saga-video-isabelle, saga-audio-arne, saga-3d-maggie, general]
 applies_to:
   core: "Core 12000+"
@@ -14,6 +14,7 @@ sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)"
   - "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04"
+  - "Gunnar (core developer, BigGun), Apollo chat, 2026-11-04 (relayed by WDrijver)"
 generated_from: sources/official/saga-registers/index.htm
 ---
 
@@ -36,7 +37,7 @@ The SAGA-specific chipset registers of the Apollo V4, converted from the officia
 
 Every one of the 419 rows of the original is marked SAGA, because SAGA contains the classic chipset. These files cover the 188 SAGA-specific rows: the rows where OCS, ECS and AGA are empty, plus the SAGA addresses that the original also marks as classic.
 
-For every other register, the Amiga Hardware Reference Manual applies, with one difference: **on SAGA, all classic pointer registers (BPLxPT, SPRxPT, COPxLC, BLTxPT, AUDxLC, DSKPT) are 32 bits wide and reach all RAM** (WDrijver, 2026-11-04). Their pages in the original still say 18 bits. FMODE (`$DFF1FC`) bit 4 "SAGA" enables the SAGA features (original); among them, it lets the Copper write above `$DFF1FF` and do 32-bit moves (BigGun, 2026-11-04, see [colour-ports.md](colour-ports.md)).
+For every other register, the Amiga Hardware Reference Manual applies, with one difference: **on SAGA, all classic pointer registers (BPLxPT, SPRxPT, COPxLC, BLTxPT, AUDxLC, DSKPT) are 32 bits wide and reach all RAM** (WDrijver, 2026-11-04). Their pages in the original still say 18 bits. FMODE (`$DFF1FC`) bit 4 "SAGA" enables the SAGA features (original); among them, it lets the Copper write above `$DFF1FF` and do 32-bit moves (G, 2026-11-04, see [colour-ports.md](colour-ports.md)).
 
 ### Reading back write-only registers
 
diff --git a/tools/intake/sagaregs.py b/tools/intake/sagaregs.py
index 5c46362..a89a8a4 100644
--- a/tools/intake/sagaregs.py
+++ b/tools/intake/sagaregs.py
@@ -30,8 +30,8 @@
 SOURCE_NAME = "SAGA register documentation, sources/official/saga-registers/ (HTML)"
 WD = "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04"
 WDS = "WDrijver, 2026-11-04"
-BIGGUN = "BigGun, Apollo chat, 2026-11-04 (relayed by WDrijver)"
-BGS = "BigGun, 2026-11-04"
+BIGGUN = "Gunnar (core developer, BigGun), Apollo chat, 2026-11-04 (relayed by WDrijver)"
+BGS = "G, 2026-11-04"
 APOLLOLIB = ("ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib "
              "(ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)")
 APOLLOLIB_OLD = ("ApolloLib, older copy in ApolloClaude docs/toolchain/_ApolloLib "
@@ -411,7 +411,7 @@ def colour_ports(rows):
                ["DO write the port with one `move.l`.",
                 "DO set FMODE bit 4 (SAGA) before a Copper list writes a colour port.",
                 "DO set bit 15 in the first word of a 32-bit Copper MOVE."],
-               sources=[APOLLOLIB, BIGGUN], basis=["official", "source-code", "other"])
+               sources=[APOLLOLIB, BIGGUN], basis=["core-developer", "official", "source-code"])
 
 
 PIP2 = [("DFF3B0", "PIP2 X start"), ("DFF3B2", "PIP2 Y start"),
@@ -927,7 +927,8 @@ def index(rows, keep, applied):
                 "registers here.",
                 "DON'T use a register listed under the open questions without checking "
                 "it on real hardware."],
-               sources=[APOLLOLIB, WD], basis=["official", "source-code"])
+               sources=[APOLLOLIB, WD, BIGGUN],
+               basis=["core-developer", "official", "source-code"])
 
 
 def build():

From 81d15595c387acdd268e5bcfdb88fa76dd63749d Mon Sep 17 00:00:00 2001
From: Willem Drijver 
Date: Wed, 4 Nov 2026 15:54:15 +0300
Subject: [PATCH 09/12] SAGA registers: Copper in SAGA mode reaches every SAGA
 register

Gunnar (G, 2026-11-04): the Copper is gated to $DFF0xx and $DFF1xx unless
the SAGA bit in FMODE is set; with it set, the Copper can write every SAGA
register up to $DFF4FF, with 16- and 32-bit moves. Drop the Copper open
question.

Co-Authored-By: Claude Opus 5.5 
---
 core/saga-registers/colour-ports.md |  3 ++-
 core/saga-registers/index.md        |  7 +++----
 tools/intake/sagaregs.py            | 11 +++++------
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/core/saga-registers/colour-ports.md b/core/saga-registers/colour-ports.md
index 4969280..e8dc848 100644
--- a/core/saga-registers/colour-ports.md
+++ b/core/saga-registers/colour-ports.md
@@ -73,7 +73,8 @@ Each port is one 32-bit register (the original lists its high and low word, H an
 - The SAGA Copper can do 32-bit moves (G, 2026-11-04).
 - A 32-bit MOVE has the high bit of its first word set (G, 2026-11-04): `$8380` = bit 15 + register `$380`. The two words after it are the 32-bit value, high word first, as in the original's example.
 - It needs SAGA mode: set the SAGA bit in FMODE (`$DFF1FC` bit 4) first (G, 2026-11-04).
-- Without the SAGA bit, the Copper can write only `$DFF0xx` and `$DFF1xx` (G, 2026-11-04), so it can't reach the colour ports at `$DFF3xx`.
+- Without the SAGA bit, the Copper is gated to `$DFF0xx` and `$DFF1xx` (G, 2026-11-04), so it can't reach the colour ports at `$DFF3xx`.
+- With the SAGA bit set, the Copper can write every SAGA register, up to Arne at `$DFF4FF`, with 16-bit and 32-bit moves (G, 2026-11-04).
 
 A classic Copper MOVE is two words (register, 16-bit value). Read the classic way, `$8380` would be COLOR00 (`$180`), and the third word the start of the next instruction.
 
diff --git a/core/saga-registers/index.md b/core/saga-registers/index.md
index 61c7f47..c1881b6 100644
--- a/core/saga-registers/index.md
+++ b/core/saga-registers/index.md
@@ -37,7 +37,7 @@ The SAGA-specific chipset registers of the Apollo V4, converted from the officia
 
 Every one of the 419 rows of the original is marked SAGA, because SAGA contains the classic chipset. These files cover the 188 SAGA-specific rows: the rows where OCS, ECS and AGA are empty, plus the SAGA addresses that the original also marks as classic.
 
-For every other register, the Amiga Hardware Reference Manual applies, with one difference: **on SAGA, all classic pointer registers (BPLxPT, SPRxPT, COPxLC, BLTxPT, AUDxLC, DSKPT) are 32 bits wide and reach all RAM** (WDrijver, 2026-11-04). Their pages in the original still say 18 bits. FMODE (`$DFF1FC`) bit 4 "SAGA" enables the SAGA features (original); among them, it lets the Copper write above `$DFF1FF` and do 32-bit moves (G, 2026-11-04, see [colour-ports.md](colour-ports.md)).
+For every other register, the Amiga Hardware Reference Manual applies, with one difference: **on SAGA, all classic pointer registers (BPLxPT, SPRxPT, COPxLC, BLTxPT, AUDxLC, DSKPT) are 32 bits wide and reach all RAM** (WDrijver, 2026-11-04). Their pages in the original still say 18 bits. FMODE (`$DFF1FC`) bit 4 "SAGA" enables the SAGA features (original); among them, it lets the Copper write every SAGA register up to `$DFF4FF` and do 32-bit moves (G, 2026-11-04, see [colour-ports.md](colour-ports.md)).
 
 ### Reading back write-only registers
 
@@ -175,9 +175,8 @@ Wrong or missing page links in the original: the 32-bit Arne rows link to the cl
 
 ### Open questions
 
-1. Copper in SAGA mode: does it reach every SAGA register, including Arne at `$DFF400`–`$DFF4FF` (that needs register bit 10)? Can it also do 16-bit moves above `$DFF1FF`, and does COPCON's danger bit still apply?
-2. "IRQ $48" (Ethernet) and "IRQ $50" (Arne channels 4–15): vector offsets or vector numbers, and at which interrupt level.
-3. Read-back above `$DFF1FF`: write-only registers at `$DFF000`–`$DFF1FF` read back at `$DFE000`–`$DFE1FF`. Is there a read-back for the write-only registers from `$DFF200` up (Maggie, DMACON2, colour ports, PIP, Arne)?
+1. "IRQ $48" (Ethernet) and "IRQ $50" (Arne channels 4–15): vector offsets or vector numbers, and at which interrupt level.
+2. Read-back above `$DFF1FF`: write-only registers at `$DFF000`–`$DFF1FF` read back at `$DFE000`–`$DFE1FF`. Is there a read-back for the write-only registers from `$DFF200` up (Maggie, DMACON2, colour ports, PIP, Arne)?
 
 ## Differences from AmigaOS / AROS / 68060
 
diff --git a/tools/intake/sagaregs.py b/tools/intake/sagaregs.py
index a89a8a4..4e16b39 100644
--- a/tools/intake/sagaregs.py
+++ b/tools/intake/sagaregs.py
@@ -394,8 +394,10 @@ def colour_ports(rows):
                 "32-bit value, high word first, as in the original's example.",
                 f"- It needs SAGA mode: set the SAGA bit in FMODE (`$DFF1FC` bit 4) "
                 f"first ({BGS}).",
-                f"- Without the SAGA bit, the Copper can write only `$DFF0xx` and "
-                f"`$DFF1xx` ({BGS}), so it can't reach the colour ports at `$DFF3xx`.", "",
+                f"- Without the SAGA bit, the Copper is gated to `$DFF0xx` and "
+                f"`$DFF1xx` ({BGS}), so it can't reach the colour ports at `$DFF3xx`.",
+                f"- With the SAGA bit set, the Copper can write every SAGA register, up "
+                f"to Arne at `$DFF4FF`, with 16-bit and 32-bit moves ({BGS}).", "",
                 "A classic Copper MOVE is two words (register, 16-bit value). Read the "
                 "classic way, `$8380` would be COLOR00 (`$180`), and the third word the "
                 "start of the next instruction."]
@@ -814,9 +816,6 @@ def system(rows):
          ("system.md", "Board ID, core revision, chip ID, SPI")]
 
 OPEN = [
-    "Copper in SAGA mode: does it reach every SAGA register, including Arne at "
-    "`$DFF400`–`$DFF4FF` (that needs register bit 10)? Can it also do 16-bit moves "
-    "above `$DFF1FF`, and does COPCON's danger bit still apply?",
     "\"IRQ $48\" (Ethernet) and \"IRQ $50\" (Arne channels 4–15): vector offsets or "
     "vector numbers, and at which interrupt level.",
     "Read-back above `$DFF1FF`: write-only registers at `$DFF000`–`$DFF1FF` read "
@@ -871,7 +870,7 @@ def index(rows, keep, applied):
                f"reach all RAM** ({WDS}). Their pages in the "
                "original still say 18 bits. FMODE (`$DFF1FC`) bit 4 \"SAGA\" enables "
                "the SAGA features (original); among them, it lets the Copper write "
-               f"above `$DFF1FF` and do 32-bit moves ({BGS}, see "
+               f"every SAGA register up to `$DFF4FF` and do 32-bit moves ({BGS}, see "
                "[colour-ports.md](colour-ports.md)).", "",
                "### Reading back write-only registers", "",
                "Every write-only register at `$DFF000`–`$DFF1FF` reads back at the "

From a0a286a11a183858665af99848ce2c339582b4a1 Mon Sep 17 00:00:00 2001
From: Willem Drijver 
Date: Wed, 4 Nov 2026 16:03:46 +0300
Subject: [PATCH 10/12] Best practice: prefer library calls over direct SAGA
 register access

WDrijver, 2026-11-04: for Arne, Isabelle and Maggie, the library calls are
preferred to direct register access; a best practice, not a forced rule.
ApolloLib for Arne and Isabelle until their official library is released;
maggie.library (github.com/RMortenB/MaggieLibrary, golden source) for
Maggie. Add core/best-practices/prefer-library-calls-for-saga-chips.md,
put the rule in the generated register files and the chip index files.

Co-Authored-By: Claude Opus 5.5 
---
 .github/CODEOWNERS                            |  1 +
 .../prefer-library-calls-for-saga-chips.md    | 65 +++++++++++++++++++
 core/saga-3d-maggie/index.md                  |  3 +
 core/saga-audio-arne/index.md                 |  3 +
 core/saga-registers/arne-channels.md          |  2 +
 .../saga-registers/arne-dma-and-interrupts.md |  2 +
 core/saga-registers/chunky-plane.md           |  2 +
 core/saga-registers/colour-ports.md           |  2 +
 core/saga-registers/display-control.md        |  2 +
 core/saga-registers/index.md                  |  5 +-
 core/saga-registers/input.md                  |  2 +
 core/saga-registers/maggie-3d.md              |  2 +
 core/saga-registers/pip.md                    |  2 +
 core/saga-registers/pointer.md                |  2 +
 core/saga-registers/sprite-collision.md       |  2 +
 core/saga-video-isabelle/index.md             |  3 +
 tools/intake/sagaregs.py                      | 26 +++++++-
 17 files changed, 124 insertions(+), 2 deletions(-)
 create mode 100644 core/best-practices/prefer-library-calls-for-saga-chips.md

diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 25c51f6..8b66d1d 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -26,6 +26,7 @@
 /core/best-practices/interleave-dependency-chains.md @TuKo1982
 /core/best-practices/memory-access-patterns.md @TuKo1982
 /core/best-practices/predicated-bcc-over-one-instruction.md @TuKo1982
+/core/best-practices/prefer-library-calls-for-saga-chips.md @WDrijver
 /core/best-practices/use-fusable-pairs.md @TuKo1982
 /core/cpu-68080/bank-prefix.md @TuKo1982
 /core/cpu-68080/branches-and-prediction.md @TuKo1982
diff --git a/core/best-practices/prefer-library-calls-for-saga-chips.md b/core/best-practices/prefer-library-calls-for-saga-chips.md
new file mode 100644
index 0000000..b351dea
--- /dev/null
+++ b/core/best-practices/prefer-library-calls-for-saga-chips.md
@@ -0,0 +1,65 @@
+---
+title: Prefer library calls over direct SAGA register access
+type: best-practice
+owner: WDrijver
+status: draft
+origin: ai-assisted
+basis: [other]
+components: [saga-audio-arne, saga-video-isabelle, saga-3d-maggie]
+applies_to:
+  core: "any"
+  os: [any]
+tags: [saga, arne, isabelle, maggie, library, apollolib, maggie-library, registers]
+related:
+  - core/saga-registers/index.md
+  - os/libraries/maggie-library.md
+  - core/saga-audio-arne/index.md
+  - core/saga-video-isabelle/index.md
+  - core/saga-3d-maggie/index.md
+sources:
+  - "WDrijver (maintainer), library calls for the SAGA chips, 2026-11-04"
+  - "maggie.library, github.com/RMortenB/MaggieLibrary (the author's source, golden source)"
+  - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib"
+---
+
+## Goal
+
+Code that keeps working when the SAGA hardware or its use changes. A library
+call hides register layouts, core differences and setup order, so the
+program doesn't depend on them.
+
+## Technique
+
+For the SAGA chips, prefer the library calls to direct register access
+(WDrijver, 2026-11-04):
+
+| Chip | Use | Source |
+|---|---|---|
+| Arne (SAGA audio) | ApolloLib | github.com/WDrijver/ApolloCrossDev, `Projects/ApolloLib` |
+| Isabelle (SAGA video) | ApolloLib | github.com/WDrijver/ApolloCrossDev, `Projects/ApolloLib` |
+| Maggie (SAGA 3D) | maggie.library | github.com/RMortenB/MaggieLibrary (the author's source, golden source) |
+
+- An official library for Arne and Isabelle is in development. Until it is
+  released, ApolloLib is the best choice for library calls to Arne and
+  Isabelle.
+- maggie.library is described in
+  [os/libraries/maggie-library.md](../../os/libraries/maggie-library.md).
+  When you need more than that file covers, the author's repository is the
+  golden source.
+- The registers are documented in
+  [core/saga-registers/](../saga-registers/index.md), for library work and
+  for code that must access them directly.
+
+## Evidence
+
+| Variant | Measurement | Core | Test setup |
+|---|---|---|---|
+| Library calls instead of direct register access | Preferred: a best practice, not a forced rule | any | Statement (WDrijver, 2026-11-04) |
+
+## When not to use
+
+- This is a best practice, not a rule. Direct register access stays
+  allowed, for example in `os-takeover` code (games, demos) or where a
+  library has no call for what you need.
+- When you write to SAGA registers directly, say so, as AGENTS.md section 2
+  asks.
diff --git a/core/saga-3d-maggie/index.md b/core/saga-3d-maggie/index.md
index 7357ed1..659d002 100644
--- a/core/saga-3d-maggie/index.md
+++ b/core/saga-3d-maggie/index.md
@@ -43,5 +43,8 @@ No content yet.
 
 ## Do / Don't
 
+- DO prefer the library calls (maggie.library) to direct register access: a best
+  practice, not a forced rule (see
+  [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DON'T invent register addresses, bit meanings or instruction behavior for
   the SAGA 3D (Maggie). Say that the knowledge base does not cover it.
diff --git a/core/saga-audio-arne/index.md b/core/saga-audio-arne/index.md
index 7e4974e..f81881d 100644
--- a/core/saga-audio-arne/index.md
+++ b/core/saga-audio-arne/index.md
@@ -41,5 +41,8 @@ No content yet.
 
 ## Do / Don't
 
+- DO prefer the library calls (ApolloLib) to direct register access: a best
+  practice, not a forced rule (see
+  [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DON'T invent register addresses, bit meanings or instruction behavior for
   the SAGA audio (Arne). Say that the knowledge base does not cover it.
diff --git a/core/saga-registers/arne-channels.md b/core/saga-registers/arne-channels.md
index a7d102d..20cdd62 100644
--- a/core/saga-registers/arne-channels.md
+++ b/core/saga-registers/arne-channels.md
@@ -14,6 +14,7 @@ related:
   - core/saga-registers/index.md
   - core/saga-audio-arne/registers.md
   - core/saga-registers/arne-dma-and-interrupts.md
+  - core/best-practices/prefer-library-calls-for-saga-chips.md
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)"
@@ -86,6 +87,7 @@ With the PAL clock of 3546895 Hz (ApolloLib), period 65 gives 3546895 / 65 = 54.
 
 ## Do / Don't
 
+- DO prefer the library calls (ApolloLib) to direct access to these registers: a best practice, not a forced rule (see [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DO keep the period at 65 or higher.
 - DO give AUDxLEN in sample pairs.
 - DO start channels 0–3 with DMACON and channels 4–15 with DMACON2.
diff --git a/core/saga-registers/arne-dma-and-interrupts.md b/core/saga-registers/arne-dma-and-interrupts.md
index 023c930..9f04b12 100644
--- a/core/saga-registers/arne-dma-and-interrupts.md
+++ b/core/saga-registers/arne-dma-and-interrupts.md
@@ -13,6 +13,7 @@ tags: [saga, arne, audio, dma, interrupts, ethernet, registers]
 related:
   - core/saga-registers/index.md
   - core/saga-registers/arne-channels.md
+  - core/best-practices/prefer-library-calls-for-saga-chips.md
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
 generated_from: sources/official/saga-registers/index.htm
@@ -96,5 +97,6 @@ Whether `$48` and `$50` are vector offsets or vector numbers, and at which inter
 
 ## Do / Don't
 
+- DO prefer the library calls (ApolloLib) to direct access to these registers: a best practice, not a forced rule (see [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DO use bit 15 as SET/CLR, as in the classic registers.
 - DO map channel n (4–15) to bit n − 4.
diff --git a/core/saga-registers/chunky-plane.md b/core/saga-registers/chunky-plane.md
index 6fd5788..3818d96 100644
--- a/core/saga-registers/chunky-plane.md
+++ b/core/saga-registers/chunky-plane.md
@@ -12,6 +12,7 @@ applies_to:
 tags: [saga, isabelle, gfxmode, chunky, registers]
 related:
   - core/saga-registers/index.md
+  - core/best-practices/prefer-library-calls-for-saga-chips.md
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)"
@@ -108,6 +109,7 @@ Every write-only register at `$DFF000`–`$DFF1FF` reads back at the same offset
 
 ## Do / Don't
 
+- DO prefer the library calls (ApolloLib) to direct access to these registers: a best practice, not a forced rule (see [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DO write GFXMODE as one word, resolution in the high byte.
 - DO set the pointer and modulo before you switch the mode.
 - DON'T rely on GFXMODE `$00` or pixel format `$07`: the original describes neither.
diff --git a/core/saga-registers/colour-ports.md b/core/saga-registers/colour-ports.md
index e8dc848..9faf194 100644
--- a/core/saga-registers/colour-ports.md
+++ b/core/saga-registers/colour-ports.md
@@ -12,6 +12,7 @@ applies_to:
 tags: [saga, isabelle, palette, colour, registers]
 related:
   - core/saga-registers/index.md
+  - core/best-practices/prefer-library-calls-for-saga-chips.md
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)"
@@ -84,6 +85,7 @@ A classic Copper MOVE is two words (register, 16-bit value). Read the classic wa
 
 ## Do / Don't
 
+- DO prefer the library calls (ApolloLib) to direct access to these registers: a best practice, not a forced rule (see [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DO write the port with one `move.l`.
 - DO set FMODE bit 4 (SAGA) before a Copper list writes a colour port.
 - DO set bit 15 in the first word of a 32-bit Copper MOVE.
diff --git a/core/saga-registers/display-control.md b/core/saga-registers/display-control.md
index 1045599..63ab868 100644
--- a/core/saga-registers/display-control.md
+++ b/core/saga-registers/display-control.md
@@ -12,6 +12,7 @@ applies_to:
 tags: [saga, isabelle, scanlines, zoom, registers]
 related:
   - core/saga-registers/index.md
+  - core/best-practices/prefer-library-calls-for-saga-chips.md
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04"
@@ -93,6 +94,7 @@ The original's example on this page is the one of the planar colour port (it set
 
 ## Do / Don't
 
+- DO prefer the library calls (ApolloLib) to direct access to these registers: a best practice, not a forced rule (see [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DO set bit 15 to set bits and clear it to clear them.
 - DON'T read `$DFF3EC`: it is write-only, although the original's Access column says R.
 - DO give the zoom shift in `$DFF3EE` as positive pixel counts.
diff --git a/core/saga-registers/index.md b/core/saga-registers/index.md
index c1881b6..13a9247 100644
--- a/core/saga-registers/index.md
+++ b/core/saga-registers/index.md
@@ -10,6 +10,8 @@ applies_to:
   core: "Core 12000+"
   os: [any]
 tags: [saga, registers, index]
+related:
+  - core/best-practices/prefer-library-calls-for-saga-chips.md
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)"
@@ -22,7 +24,7 @@ generated_from: sources/official/saga-registers/index.htm
 
 ## Summary
 
-The SAGA-specific chipset registers of the Apollo V4, converted from the official SAGA register documentation: video (chunky plane, colour ports, PIP, pointer), Arne audio, Maggie 3D, input and system registers. Classic OCS/ECS/AGA registers are not repeated here.
+The SAGA-specific chipset registers of the Apollo V4, converted from the official SAGA register documentation: video (chunky plane, colour ports, PIP, pointer), Arne audio, Maggie 3D, input and system registers. Classic OCS/ECS/AGA registers are not repeated here. For Arne, Isabelle and Maggie, prefer the library calls (ApolloLib, maggie.library) to direct register access: a best practice, not a forced rule.
 
 ## Details
 
@@ -185,5 +187,6 @@ Wrong or missing page links in the original: the 32-bit Arne rows link to the cl
 
 ## Do / Don't
 
+- DO prefer the library calls (ApolloLib and maggie.library) to direct access to these registers: a best practice, not a forced rule (see [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DO look up a classic register in the HRM, and its SAGA-specific registers here.
 - DON'T use a register listed under the open questions without checking it on real hardware.
diff --git a/core/saga-registers/input.md b/core/saga-registers/input.md
index 81abf56..9e15f92 100644
--- a/core/saga-registers/input.md
+++ b/core/saga-registers/input.md
@@ -12,6 +12,7 @@ applies_to:
 tags: [saga, input, joypad, usb, mouse, registers]
 related:
   - core/saga-registers/index.md
+  - core/best-practices/prefer-library-calls-for-saga-chips.md
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)"
@@ -93,5 +94,6 @@ The "vanilla" DB9 ports, with the layout of JOY0DAT/JOY1DAT. The original's inde
 
 ## Do / Don't
 
+- DO prefer the library calls (ApolloLib) to direct access to these registers: a best practice, not a forced rule (see [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DO test bit 0 (connected) before you trust a joypad register.
 - DO treat the wheel counter as signed and use the difference between two reads.
diff --git a/core/saga-registers/maggie-3d.md b/core/saga-registers/maggie-3d.md
index fd47afa..61c38e0 100644
--- a/core/saga-registers/maggie-3d.md
+++ b/core/saga-registers/maggie-3d.md
@@ -13,6 +13,7 @@ tags: [saga, maggie, 3d, texture, registers]
 related:
   - core/saga-registers/index.md
   - core/saga-3d-maggie/registers.md
+  - core/best-practices/prefer-library-calls-for-saga-chips.md
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
 generated_from: sources/official/saga-registers/index.htm
@@ -78,5 +79,6 @@ Offsets from `$DFF250`, for comparison with the measured layout in [registers.md
 
 ## Do / Don't
 
+- DO prefer the library calls (maggie.library) to direct access to these registers: a best practice, not a forced rule (see [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DO write TEXSTRT (`$DFF25E`) last: it starts the span.
 - DO check core/saga-3d-maggie/registers.md and its pitfalls for the measured behaviour.
diff --git a/core/saga-registers/pip.md b/core/saga-registers/pip.md
index 74e9d3f..925ab33 100644
--- a/core/saga-registers/pip.md
+++ b/core/saga-registers/pip.md
@@ -14,6 +14,7 @@ related:
   - core/saga-registers/index.md
   - core/saga-registers/colour-ports.md
   - core/saga-registers/chunky-plane.md
+  - core/best-practices/prefer-library-calls-for-saga-chips.md
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)"
@@ -100,6 +101,7 @@ Formats and transparent colours: WDrijver, 2026-11-04. The transparent colour is
 
 ## Do / Don't
 
+- DO prefer the library calls (ApolloLib) to direct access to these registers: a best practice, not a forced rule (see [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DO set the DMA row length last: it switches the PIP on.
 - DO write 0 to the DMA row length to switch a PIP off.
 - DON'T use the 24- or 32-bit formats (`$04`, `$05`) for a PIP.
diff --git a/core/saga-registers/pointer.md b/core/saga-registers/pointer.md
index 121aba9..d9332e0 100644
--- a/core/saga-registers/pointer.md
+++ b/core/saga-registers/pointer.md
@@ -12,6 +12,7 @@ applies_to:
 tags: [saga, isabelle, pointer, sprite, registers]
 related:
   - core/saga-registers/index.md
+  - core/best-practices/prefer-library-calls-for-saga-chips.md
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)"
@@ -84,6 +85,7 @@ These rows have no page in the original. An older ApolloLib copy adds colour 0 a
 
 ## Do / Don't
 
+- DO prefer the library calls (ApolloLib) to direct access to these registers: a best practice, not a forced rule (see [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DO write the palette through `$DFF3A8` (index) and `$DFF3AA` (colour).
 - DO keep colour index 0 for transparent pixels.
 - DON'T expect real alpha blending: a pixel is opaque or 50 % semi-transparent.
diff --git a/core/saga-registers/sprite-collision.md b/core/saga-registers/sprite-collision.md
index 5b799ec..5e61723 100644
--- a/core/saga-registers/sprite-collision.md
+++ b/core/saga-registers/sprite-collision.md
@@ -12,6 +12,7 @@ applies_to:
 tags: [saga, isabelle, sprites, collision, registers]
 related:
   - core/saga-registers/index.md
+  - core/best-practices/prefer-library-calls-for-saga-chips.md
 sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04"
@@ -68,5 +69,6 @@ SAGA has the 8 classic sprites, as on the classic Amiga (WDrijver, 2026-11-04).
 
 ## Do / Don't
 
+- DO prefer the library calls (ApolloLib) to direct access to these registers: a best practice, not a forced rule (see [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DO read the register of the sprite you are interested in.
 - DON'T use bits 8–15: SAGA has 8 sprites.
diff --git a/core/saga-video-isabelle/index.md b/core/saga-video-isabelle/index.md
index 63bda13..8e4523d 100644
--- a/core/saga-video-isabelle/index.md
+++ b/core/saga-video-isabelle/index.md
@@ -42,5 +42,8 @@ No content yet.
 
 ## Do / Don't
 
+- DO prefer the library calls (ApolloLib) to direct register access: a best
+  practice, not a forced rule (see
+  [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DON'T invent register addresses, bit meanings or instruction behavior for
   the SAGA video (Isabelle). Say that the knowledge base does not cover it.
diff --git a/tools/intake/sagaregs.py b/tools/intake/sagaregs.py
index 4e16b39..ea1b47d 100644
--- a/tools/intake/sagaregs.py
+++ b/tools/intake/sagaregs.py
@@ -289,9 +289,30 @@ def tidy(lines):
     return "\n".join(out) + "\n"
 
 
+BEST_PRACTICE = "core/best-practices/prefer-library-calls-for-saga-chips.md"
+LIBRARY = {"saga-audio-arne": "ApolloLib", "saga-video-isabelle": "ApolloLib",
+           "saga-3d-maggie": "maggie.library"}
+
+
+def library_rule(name, components):
+    """The best practice of library calls, for the files of the SAGA chips."""
+    libs = sorted({LIBRARY[c] for c in components if c in LIBRARY})
+    if name == "input.md":
+        libs = ["ApolloLib"]
+    if not libs:
+        return []
+    return [f"DO prefer the library calls ({' and '.join(libs)}) to direct access "
+            "to these registers: a best practice, not a forced rule (see "
+            "[prefer-library-calls-for-saga-chips.md]"
+            "(../best-practices/prefer-library-calls-for-saga-chips.md))."]
+
+
 def doc(name, title, components, tags, summary, details, diff, rules,
         sources=(), basis=("official",), related=()):
+    rules = library_rule(name, components) + list(rules)
     rel = ([] if name == "index.md" else [f"{OUTDIR}/index.md"]) + list(related)
+    if library_rule(name, components):
+        rel.append(BEST_PRACTICE)
     lines = frontmatter(title, components, tags, rel, list(sources), basis)
     lines += ["## Summary", "", summary, "", "## Details", ""] + details
     lines += ["", "## Differences from AmigaOS / AROS / 68060", ""] + diff
@@ -915,7 +936,10 @@ def index(rows, keep, applied):
                "The SAGA-specific chipset registers of the Apollo V4, converted from the "
                "official SAGA register documentation: video (chunky plane, colour "
                "ports, PIP, pointer), Arne audio, Maggie 3D, input and system "
-               "registers. Classic OCS/ECS/AGA registers are not repeated here.",
+               "registers. Classic OCS/ECS/AGA registers are not repeated here. "
+               "For Arne, Isabelle and Maggie, prefer the library calls (ApolloLib, "
+               "maggie.library) to direct register access: a best practice, not a "
+               "forced rule.",
                details,
                ["- SAGA contains the classic chipset at its classic addresses. The "
                 "registers here are added on top of it, mostly at `$DFF1E6`–`$DFF1F4`, "

From de0c3dba828ca71bcd7d4a3df8c3283e8ee7eff0 Mon Sep 17 00:00:00 2001
From: Willem Drijver 
Date: Wed, 4 Nov 2026 16:16:49 +0300
Subject: [PATCH 11/12] SAGA registers: only $DFF0xx and $DFF1xx have read-back
 shadows

WDrijver, 2026-11-04: only $DFF0xx and $DFF1xx have read-back shadows at
$DFExxx. The write-only registers from $DFF200 up can't be read back.
State it in the index and drop the read-back open question.

Co-Authored-By: Claude Opus 5.5 
---
 core/saga-registers/index.md |  5 ++++-
 tools/intake/sagaregs.py     | 12 +++++++++---
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/core/saga-registers/index.md b/core/saga-registers/index.md
index 13a9247..56c1511 100644
--- a/core/saga-registers/index.md
+++ b/core/saga-registers/index.md
@@ -45,6 +45,8 @@ For every other register, the Amiga Hardware Reference Manual applies, with one
 
 Every write-only register at `$DFF000`–`$DFF1FF` reads back at the same offset in `$DFE000`–`$DFE1FF` (WDrijver, 2026-11-04). This holds for the classic and the SAGA registers in that range, for example DMACON `$DFF096` at `$DFE096`, GFXMODE `$DFF1F4` at `$DFE1F4` and the pointer position `$DFF1D0` at `$DFE1D0`. The original doesn't mention it.
 
+Only `$DFF0xx` and `$DFF1xx` have these read-back shadows (WDrijver, 2026-11-04). The write-only registers from `$DFF200` up (Maggie, the colour ports, PIP, Arne) can't be read back: keep a copy in memory when you need the value. DMACON2, INTENA2 and INTREQ2 have their own read registers at `$DFF202`, `$DFF21C` and `$DFF21E`.
+
 ### Access codes (original)
 
 | Code | Meaning |
@@ -178,7 +180,6 @@ Wrong or missing page links in the original: the 32-bit Arne rows link to the cl
 ### Open questions
 
 1. "IRQ $48" (Ethernet) and "IRQ $50" (Arne channels 4–15): vector offsets or vector numbers, and at which interrupt level.
-2. Read-back above `$DFF1FF`: write-only registers at `$DFF000`–`$DFF1FF` read back at `$DFE000`–`$DFE1FF`. Is there a read-back for the write-only registers from `$DFF200` up (Maggie, DMACON2, colour ports, PIP, Arne)?
 
 ## Differences from AmigaOS / AROS / 68060
 
@@ -189,4 +190,6 @@ Wrong or missing page links in the original: the 32-bit Arne rows link to the cl
 
 - DO prefer the library calls (ApolloLib and maggie.library) to direct access to these registers: a best practice, not a forced rule (see [prefer-library-calls-for-saga-chips.md](../best-practices/prefer-library-calls-for-saga-chips.md)).
 - DO look up a classic register in the HRM, and its SAGA-specific registers here.
+- DO read a write-only register at `$DFF0xx`/`$DFF1xx` back at `$DFE0xx`/`$DFE1xx`.
+- DON'T try to read back a write-only register from `$DFF200` up: keep your own copy of the value.
 - DON'T use a register listed under the open questions without checking it on real hardware.
diff --git a/tools/intake/sagaregs.py b/tools/intake/sagaregs.py
index ea1b47d..f93e12c 100644
--- a/tools/intake/sagaregs.py
+++ b/tools/intake/sagaregs.py
@@ -839,9 +839,6 @@ def system(rows):
 OPEN = [
     "\"IRQ $48\" (Ethernet) and \"IRQ $50\" (Arne channels 4–15): vector offsets or "
     "vector numbers, and at which interrupt level.",
-    "Read-back above `$DFF1FF`: write-only registers at `$DFF000`–`$DFF1FF` read "
-    "back at `$DFE000`–`$DFE1FF`. Is there a read-back for the write-only registers "
-    "from `$DFF200` up (Maggie, DMACON2, colour ports, PIP, Arne)?",
 ]
 
 
@@ -899,6 +896,11 @@ def index(rows, keep, applied):
                "classic and the SAGA registers in that range, for example DMACON "
                "`$DFF096` at `$DFE096`, GFXMODE `$DFF1F4` at `$DFE1F4` and the pointer "
                "position `$DFF1D0` at `$DFE1D0`. The original doesn't mention it.", "",
+               f"Only `$DFF0xx` and `$DFF1xx` have these read-back shadows ({WDS}). The "
+               "write-only registers from `$DFF200` up (Maggie, the colour ports, PIP, "
+               "Arne) can't be read back: keep a copy in memory when you need the value. "
+               "DMACON2, INTENA2 and INTREQ2 have their own read registers at `$DFF202`, "
+               "`$DFF21C` and `$DFF21E`.", "",
                "### Access codes (original)", "",
                "| Code | Meaning |", "|---|---|"]
     details += [f"| {k} | {v} |" for k, v in ACCESS.items()]
@@ -948,6 +950,10 @@ def index(rows, keep, applied):
                 "are 32 bits."],
                ["DO look up a classic register in the HRM, and its SAGA-specific "
                 "registers here.",
+                "DO read a write-only register at `$DFF0xx`/`$DFF1xx` back at "
+                "`$DFE0xx`/`$DFE1xx`.",
+                "DON'T try to read back a write-only register from `$DFF200` up: keep "
+                "your own copy of the value.",
                 "DON'T use a register listed under the open questions without checking "
                 "it on real hardware."],
                sources=[APOLLOLIB, WD, BIGGUN],

From e85ef45cb0c3f018875e62281bcb4d098402be1a Mon Sep 17 00:00:00 2001
From: Willem Drijver 
Date: Wed, 4 Nov 2026 17:26:58 +0300
Subject: [PATCH 12/12] SAGA registers: Arne periods count Paula's clock (G)

Gunnar (BigGun), 2026-11-04: Arne's period coding is compatible with
Paula and runs at the same clock. State it in arne-channels.md (period 65
= 54.6 kHz with the PAL clock), and narrow the open question to the
minimum period and the "about 66 kHz" in core/saga-audio-arne/registers.md.

Co-Authored-By: Claude Opus 5.5 
---
 core/saga-registers/arne-channels.md |  7 +++++--
 core/saga-registers/index.md         |  1 +
 tools/intake/sagaregs.py             | 14 +++++++++++---
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/core/saga-registers/arne-channels.md b/core/saga-registers/arne-channels.md
index 20cdd62..1e07fb7 100644
--- a/core/saga-registers/arne-channels.md
+++ b/core/saga-registers/arne-channels.md
@@ -4,7 +4,7 @@ type: reference
 owner: WDrijver
 status: draft
 origin: official
-basis: [official, source-code]
+basis: [core-developer, official, source-code]
 components: [saga-audio-arne]
 applies_to:
   core: "Core 12000+"
@@ -19,6 +19,7 @@ sources:
   - "SAGA register documentation, sources/official/saga-registers/ (HTML)"
   - "ApolloLib, github.com/WDrijver/ApolloCrossDev Projects/ApolloLib (ApolloCrossDev_Defines.h, ApolloCrossDev_LibC.c), commit 2dfaa5c (2026-09-02)"
   - "WDrijver (maintainer), answers on the SAGA register documentation, 2026-11-04"
+  - "Gunnar (core developer, BigGun), Apollo chat, 2026-11-04 (relayed by WDrijver)"
 generated_from: sources/official/saga-registers/index.htm
 ---
 
@@ -78,7 +79,9 @@ Bits 15–8 left volume, bits 7–0 right volume (original). Each side ranges fr
 
 16bit PERIOD COUNT This register contains the period (rate) of audio channel x DMA data transfer. The minimum period is 65 color clocks. This means that the smallest number that should be placed in this register is 65 decimal. This corresponds to a maximum sample frequency of 56 khz.
 
-With the PAL clock of 3546895 Hz (ApolloLib), period 65 gives 3546895 / 65 = 54.6 kHz, not the 56 kHz in the original.
+The period coding is compatible with Paula: Arne runs at the same clock as Paula (G, 2026-11-04), the PAL colour clock of 3546895 Hz. So period = 3546895 / sample rate (44.1 kHz gives 80), and period 65 gives 3546895 / 65 = 54.6 kHz, not the 56 kHz in the original.
+
+Whether Arne accepts periods below 65 is not documented: core/saga-audio-arne/registers.md states a rate of about 66 kHz, which would need period 54 (see [index.md](index.md)).
 
 ## Differences from AmigaOS / AROS / 68060
 
diff --git a/core/saga-registers/index.md b/core/saga-registers/index.md
index 56c1511..b8c1067 100644
--- a/core/saga-registers/index.md
+++ b/core/saga-registers/index.md
@@ -180,6 +180,7 @@ Wrong or missing page links in the original: the 32-bit Arne rows link to the cl
 ### Open questions
 
 1. "IRQ $48" (Ethernet) and "IRQ $50" (Arne channels 4–15): vector offsets or vector numbers, and at which interrupt level.
+2. Arne maximum rate: the period counts Paula's clock (G), so period 65 is 54.6 kHz. Is 65 the minimum, and where does the "about 66 kHz" in core/saga-audio-arne/registers.md come from?
 
 ## Differences from AmigaOS / AROS / 68060
 
diff --git a/tools/intake/sagaregs.py b/tools/intake/sagaregs.py
index f93e12c..4c9148a 100644
--- a/tools/intake/sagaregs.py
+++ b/tools/intake/sagaregs.py
@@ -670,8 +670,13 @@ def arne_channels(rows):
                 "Bits 15–8 left volume, bits 7–0 right volume (original). Each side "
                 "ranges from `$00` to `$FF` (ApolloLib, SRC).", "",
                 "### AUDxPER", ""] + [" ".join(per)]
-    details += ["", "With the PAL clock of 3546895 Hz (ApolloLib), period 65 gives "
-                "3546895 / 65 = 54.6 kHz, not the 56 kHz in the original."]
+    details += ["", f"The period coding is compatible with Paula: Arne runs at the same "
+                f"clock as Paula ({BGS}), the PAL colour clock of 3546895 Hz. So "
+                "period = 3546895 / sample rate (44.1 kHz gives 80), and period 65 gives "
+                "3546895 / 65 = 54.6 kHz, not the 56 kHz in the original.", "",
+                "Whether Arne accepts periods below 65 is not documented: "
+                "core/saga-audio-arne/registers.md states a rate of about 66 kHz, which "
+                "would need period 54 (see [index.md](index.md))."]
     return doc("arne-channels.md", "SAGA Arne audio channel registers",
                ["saga-audio-arne"], ["saga", "arne", "audio", "registers"],
                "Arne, the SAGA audio unit, has 16 channels of 8- or 16-bit mono or "
@@ -687,7 +692,7 @@ def arne_channels(rows):
                 "DO give AUDxLEN in sample pairs.",
                 "DO start channels 0–3 with DMACON and channels 4–15 with DMACON2.",
                 "DON'T program channel 0–3 through both register sets at the same time."],
-               sources=[APOLLOLIB, WD], basis=["official", "source-code"],
+               sources=[APOLLOLIB, WD, BIGGUN], basis=["core-developer", "official", "source-code"],
                related=["core/saga-audio-arne/registers.md",
                         f"{OUTDIR}/arne-dma-and-interrupts.md"])
 
@@ -839,6 +844,9 @@ def system(rows):
 OPEN = [
     "\"IRQ $48\" (Ethernet) and \"IRQ $50\" (Arne channels 4–15): vector offsets or "
     "vector numbers, and at which interrupt level.",
+    "Arne maximum rate: the period counts Paula's clock (G), so period 65 is 54.6 kHz. "
+    "Is 65 the minimum, and where does the \"about 66 kHz\" in "
+    "core/saga-audio-arne/registers.md come from?",
 ]