Skip to content

Latest commit

 

History

History
218 lines (182 loc) · 10 KB

File metadata and controls

218 lines (182 loc) · 10 KB

06 — AGA measured to zero, Akiko measured to zero

Two questions, both answered negatively, and on this disc both are answerable without any ambiguity because the program says what it is doing in three independent places.

Reproduce with:

python tools/agascan.py    "<image>.iso" _work/files _work/unpacked
python tools/customregs.py _work/unpacked/QuestII.hunk1
python tools/copperfind.py _work/unpacked --min 20
python tools/copper.py     _work/unpacked/QuestII.hunk4 2 3534

Raw output: notes/aga-akiko.txt, notes/regs-questii.txt, notes/copper-questii.txt, notes/copper-lists.txt.

Akiko: zero, on every test that means anything

Test Raw image (52.5 MB) 97 extracted files 111 decrunched blocks
lea/movea.l of $00B80000 0 0 0
$00B80038 (the C2P port) 0 0 0
$00B8003C 0 0 0
$C0DE0000 (the id constant) 0 0 0
akiko / AKIKO as a string 0 0 0
bare 00 B8 00 byte pattern 2 2 81

Ninth CD32 disc, ninth negative. The bare-pattern hits are the checklist's own false positive and all six in the game's code hunk are identifiable:

QuestII.hunk1 + 0x006d6   23 e8 00 b8 00 03 6f 9c   move.l $b8(a0),$36f9c.l   -- a struct field
QuestII.hunk1 + 0x0b2da   ... 00 e8 00 db 00 ce 00 c3 00 b8 00 ae 00 a4 00 9b ...
QuestII.hunk1 + 0x0b51c   ... 00 e8 00 db 00 ce 00 c3 00 b8 00 ae 00 a4 00 9b ...
QuestII.hunk1 + 0x12cfc   ... 00 08 b8 24 00 08 b8 28 00 b8 00 2e ...   -- an offset table
QuestII.hunk1 + 0x132c2   ... 00 b0 00 48 00 b4 00 47 00 b8 00 47 ...   -- a coordinate table
QuestII.hunk1 + 0x14892   ... 00 be 00 21 00 04 00 19 00 b8 00 21 ...   -- a coordinate table

The two at 0xb2da and 0xb51c are worth stopping on. The platform checklist warns about Gloom's false positive and quotes it as "eight consecutive entries of one descending 16-bit table (… 00c3 00b8 00ae 00a4 …)". The same four words, in the same order, are here — twice, in a different game by a different studio a year earlier. Successive ratios are 0.944, which is 2^(−1/12): it is a chromatic period table, the ProTracker note table the music player indexes, and $00B8 = 184 is simply one of its entries. The false positive is not a coincidence of one disc; it is a property of every Amiga program that ships a note table, which is most of them.

AGA: no register, anywhere, by any route

Three independent tests, all zero.

1. The palette calls. graphics.library is opened and, in 113,112 bytes of code, never called at all — no movea.l $d5c8,a6 exists (doc 05). So LoadRGB4 (−192) is zero and LoadRGB32 (−858) is zero, and this is the checklist's third outcome — "this program programs the display itself" — in its strongest form: Microcosm at least called LoadView and WaitTOF, Gloom four functions; this program calls none.

2. The register scan. The absolute-address scan finds only 13 registers, because /QuestII loads $DFF000 into an address register 83 times and then addresses everything as d16(An) — the exact failure mode the checklist warns about, inverted. tools/customregs.py tracks which address registers currently hold the base and names every d16(An) access through a live one: 57 distinct registers, 427 accesses.

BLTSIZE   x62   BLTDPTH  x51   BLTAPTH  x34   DMACONR  x35   DMACON   x29
BLTCON0   x25   BLTAFWM  x23   BLTAMOD  x21   BLTDMOD  x20   BLTCON1  x16
INTENA    x13   BLTBPTH  x10   INTREQ    x9   BLTALWM   x7   COP1LCH   x6
BLTCPTH    x6   BLTCMOD   x5   BLTBMOD   x5   COPJMP1   x5   INTREQR   x4
AUD0-3 LCH/LEN/PER/VOL  x1 each        BPL1PTH/PTL, BPL2PTH/PTL  x1 each
BPLCON0 x1   BPLCON1 x1   BPLCON2 x1   BPL1MOD x1   BPL2MOD x1
DIWSTRT x1   DIWSTOP x1   DDFSTRT x1   DDFSTOP x1
COLOR00 x2   COLOR15 x1   ADKCON x1   POTGOR x1

The shape is a Blitter program — BLTSIZE 62 times, everything else in the Blitter block behind it — with all four Paula channels set up once (the ProTracker replay, doc 09) and the display touched a handful of times.

BPLCON3 ($DFF106), BPLCON4 ($DFF10C), FMODE ($DFF1FC) and DIWHIGH ($DFF1E4) do not appear at all, in either the absolute or the base-relative form, in the executable, in any other file, or in the raw disc image.

3. The copper lists. tools/copperfind.py walks backwards from every FFFF FFFE in the whole decrunched tree and keeps runs of at least 20 valid copper instructions. Not one of them writes an AGA register. (Almost all of them are false positives in bitmap and sample data; the disc has exactly one real copper list.)

So the conclusion is not an inference from asset formats: there is no AGA register write on this disc. HeroQuest II is an ECS-class display running on AGA silicon, which puts it with Dragonstone — and it is only the second such disc out of ten.

The one copper list on the disc

The chip DATA hunk of /QuestII is 3,536 bytes; a single zero word, then a 256-byte copper list at bytes 2–0x101, then 3,278 bytes of other chip data.

00e2/00e0  BPL1PTL/PTH   <- 0        \
00e6/00e4  BPL2PTL/PTH   <- 0         |
00ea/00e8  BPL3PTL/PTH   <- 0         |  six bitplane pointers,
00ee/00ec  BPL4PTL/PTH   <- 0         |  patched at run time
00f2/00f0  BPL5PTL/PTH   <- 0         |
00f6/00f4  BPL6PTL/PTH   <- 0        /
0086/0084  COP2LCL/LCH   <- 0
008a       COPJMP2       <- 0
           ... the same twelve pointer MOVEs and the COP2 jump again  (double buffer)
0102       BPLCON1       <- 0000
0104       BPLCON2       <- 0024        <- KILLEHB clear
008e       DIWSTRT       <- 4081
0090       DIWSTOP       <- 08c1
0092       DDFSTRT       <- 0038
0094       DDFSTOP       <- 00d0
0108/010a  BPL1MOD/BPL2MOD <- 0
0100       BPLCON0       <- 5000        <- BPU = 5, five bitplanes
0120..013e SPR0..SPR7 pointers <- 0
0180       COLOR00       <- 0000
0086/0084/008a  COP2LC / COPJMP2 again
019e       COLOR15       <- 0071
cc01 fffe  WAIT VP=$cc (raster line 204)
0100       BPLCON0       <- 6000        <- BPU = 6, six bitplanes
019e       COLOR15       <- 0666
ffff fffe  END

Everything about the display falls out of those twenty-odd instructions.

Geometry. DIWSTRT $4081 / DIWSTOP $08c1 is 129–449 horizontally and 64–263 vertically: 320 × 200, lores, PAL. DDFSTRT $38 / DDFSTOP $D0 agrees. BPL1MOD and BPL2MOD are zero, so the bitmap is exactly as wide as the screen and nothing is windowed out of a larger one.

Depth, and a split. BPLCON0 = $5000 sets BPU = 101five bitplanes, 32 colours — for the display from line 64. At raster line 204, 140 lines down, the list waits and writes BPLCON0 = $6000, BPU = 110six bitplanes — for the remaining 60 lines. So the screen is a 320 × 140 game view over a 320 × 60 panel, and the panel is one plane deeper.

And six planes with no BPLCON3 is Extra-Half-Brite. AGA reaches colour registers 32–63 only through BPLCON3's bank field, which this disc never writes, so registers 32–63 are never loaded — and BPLCON2 = $0024 leaves KILLEHB (bit 9) clear, which is the bit that would turn EHB off. Six bitplanes, KILLEHB clear, registers 32–63 untouched: the bottom strip is genuine Extra-Half-Brite, a mode that exists on OCS and ECS and behaves identically on AGA. Nothing in this display needs an A1200.

And the disc states the colour count outright. /loaderblackpal (doc 03) ends with

lea     $DFF180.l,a0
move.w  #$1f,d7
move.w  #$0,(a0)+
dbra    d7

32 registers, COLOR00 through COLOR31, and stop. On a disc with no palette call and no BPLCON3, that loop is the cleanest possible statement that the palette is 32 entries deep. A program with 64 or 256 colours to blank would have written 64 or 256.

Where the palettes actually are

There is no .pal file, no CMAP, and no run of 32 or 64 $0RGB words at a fixed place in any data file. The colour registers are written directly, with the register number in a data register:

QuestII.hunk1 + 0xe95a
  lea     $edf4.l,a6            ; the palette
  moveq   #2,d6                 ; three entries
  move.w  #$182,d7              ; COLOR01
  move.w  (a6)+,(a2,d7.w)       ; a2 = $DFF000
  addq.w  #2,d7
  dbra    d6

That particular loop belongs to a four-colour screen (BPLCON0 = $2200, BPU = 010, written at 0xe94c), and there are three more loop initialisers of the same shape in the file, at 0x87c8 ($190 = COLOR08), 0xdf2e ($198 = COLOR12) and 0xfd8e ($1a0 = COLOR16). Colour data is therefore scattered through the code hunk in short runs addressed by whichever routine needs them, rather than collected in a palette file — which is why a scan for palette-shaped data in the files returns nothing usable and why the loaderblackpal count is the better evidence.

Every value that could be checked is a 12-bit $0RGB word: $0071, $0666 in the copper list, and the only two direct absolute colour writes on the disc are to $DFF182 (COLOR01) and $DFF1AE (COLOR23). Nothing on this disc can express more than four bits per gun, because there is no LOCT write to make the low nibbles reachable.

Summary against the checklist's five kinds of AGA use

Kind of AGA use This disc
More than five bitplanes no — 5, and 6 as EHB
24-bit colour (BPLCON3 LOCT) no — BPLCON3 never written
32-bit fetch (FMODE) no — never written
BPLCON4 / BPLAM tricks no — never written
Akiko chunky-to-planar no — zero on every test

And to the checklist's newer question, "does the frame ever have to become bitplanes?": on this disc the frame is never anything else. Every asset is stored planar (doc 07), the renderer is the Blitter, and the destination is a bitmap. There is no chunky pixel anywhere in the pipeline, so there is nothing for a chunky-to-planar converter to convert — the same reason Liberation gives, reached from the same direction, on a disc that is a board game rather than a 3D engine.