modemwars/disassembly/boot/titleScreenRam9C00.s
2026-08-23 02:09:40 -05:00

184 lines
17 KiB
ArmAsm

; ============================================================================
; LOAD ($9C00-$9FFF) - title picture screen RAM (copied to $8C00 by $C23F; VIC bank 2, $D018=$38)
; ============================================================================
; High nibble = colour 1, low nibble = colour 2 of each multicolour cell.
.setcpu "6502"
.include "c64.inc"
.include "kernal.inc"
.include "zeropage.inc"
.org $9C00
; titleScreenRam - the video matrix of the title picture: 1000 bytes, one per 4x8-pixel multicolour
; cell, 40 cells to a screen row and 25 rows, index = row*40 + column, so each line below is one whole
; screen row and a cell's address is $9C00 + row*40 + col. Every byte carries two of that cell's four
; colours: the high nibble colours the %01 pixel pairs and the low nibble the %10 pairs. The %11 pairs
; take the low nibble of titleColorRam ($9800 + the same index) and %00 takes VIC_BG0, which bootMain
; sets to black at $C14E. The pixels themselves live in titleBitmap ($A000 + row*320 + col*8).
; docs/titleScreen.png is this picture decoded. Read exactly once, by bootShowTitlePicture: the
; self-modifying loop at $C288 copies four whole pages ($9C00-$9FFF, so the padding at the end travels
; with them) to $8C00-$8FFF, and $D018 = $38 with VIC bank 2 then puts the video matrix at $8C00 and
; the bitmap at $A000. Copying is what makes this page disposable: the loader's later data load at
; $C1EB pulls track 28 sectors 0-12 into
; $9300-$9FFF, so from that moment these addresses hold the game's graphics tables (unit
; game/graphicsData9300) while the picture keeps showing from the copy at $8C00 for the rest of the
; load. Nothing else in the boot image touches $9C00-$9FFF: $C288 is the only reader XREF lists under
; boot/fastLoaderC000. The cursorBlockShape / circle*Table references from game/mainProgram0800 that
; XREF also shows for these addresses belong to that run-time data, not to the picture - they are why
; unrelated labels and block breaks appear in the middle of this file, and each note below says which
; row and column of the picture the break falls on. Values: 86 distinct bytes are used. $00 (280
; cells, the commonest) means nothing is drawn in the %01/%10 colours there, so the cell shows only
; background and the colour-RAM colour; $70 = yellow over black (both text lines and the logo
; highlight), $E0 = light blue over black (sky beside the logo), $B0/$BC/$C0/$F0/$FC = the greys and
; white of the machine, $90 = brown over black (the dirt band) and $50 = green over black (the playing
; field). Row map:
; $9C00 rows 0-1 light blue sky (colour RAM $0E) with the yellow 'DAN BUNTEN'S' credit line in
; cells 13-24; in row 1 the yellow is also the bevel highlight along the top
; edge of the logo, and cells 26-39 are the grey smoke plume.
; $9C50 rows 2-7 the big red 'MODEM WARS' logo - colour RAM $02 (red) across the whole band -
; with yellow highlights over sky; the white and orange muzzle flash of the
; walker's gun is at cells 1-5 of rows 4-6.
; $9D40 rows 8-18 the walking tank in greys and white against the sky, black smoke behind it
; and the orange/white explosion in cells 31-39.
; $9EF8 rows 19-20 the horizon: brown ground under the sky and the top edge of the field.
; $9F48 rows 21-22 the green playing field with its white yard lines, and the walker's legs.
; $9F98 rows 23-24 a black band carrying the yellow 'COPYRIGHT (C) 1988 OZARK SOFTSCAPE' line
; (cells 5-36) and a small grey 'MK' monogram in row 24, cells 37-39,
; probably the artist's initials.
; Only rows 0-1 and the head of row 2 survive as whole 40-byte rows in the listing; from $9C6E on the
; run-time structures named above cut the block into the fragments annotated below.
titleScreenRam:
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$70,$70,$70,$70,$00,$70,$70,$70,$70,$70,$70,$70,$27,$BE,$EF,$F0,$C0,$BC,$EC,$00,$00,$00,$BC,$00,$BC,$FC,$BF; 9C00 .............pppp.ppppppp'.............. row 0: cells 0-12 plain sky ($00), cells 13-24 the top halves of the DAN BUNTEN'S letters ($70)
.byte $70,$70,$70,$00,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$27,$E2,$C7,$C7,$FB,$F7,$C7,$7C,$B7,$FC,$FB,$F7,$CF,$CF; 9C28 ppp.pppppppppppppppppppppp'......|......
; Screen row 2 - the first row of the red 'MODEM WARS' logo, and the start of the picture's main body
; (rows 2-24). Through rows 2-7 the colour RAM is $02 in nearly every cell, so the logo itself is
; painted with the %11 pixels; the bytes here supply the yellow bevel ($70, $27, $2F, $7B) and the
; light blue sky showing between and around the letters ($E0, $E7, $20).
titleScreenLogoRows:
.byte $20,$E0,$00,$27,$00,$E0,$E7,$00,$E7,$E0,$E0,$70,$27,$00,$E0,$00,$E0,$00,$00,$E7,$E0,$20,$00,$00,$70,$70,$00,$FE,$7E,$70; 9C50 ..'.......p'........ ..pp..~p row 2: $E0/$E7/$20 sky-plus-red cells, $70/$27 where the logo highlight starts
; Screen row 2, column 30 (that is $9C50 + 30) - the middle of the 'WARS' half of the logo. The
; listing breaks here only because the run-time overlay puts terrainTileShapes at $9C6E-$9DCD: 44
; one-bit 8x8 terrain tiles addressed as $9C6E + index*8 by setTerrainTilePtr ($2DBD) in
; game/mainProgram0800, loaded over this page from track 28. In the title picture the same 352 bytes
; are just the right-hand end of logo row 2 and rows 3-11 up to column 21: the rest of the logo, the
; sky, the smoke plume and the top of the walking tank. Each line below still holds 40 bytes, but it
; starts 30 cells into a screen row, so a line spans the tail of one row and the head of the next.
titleScreenRow02Col30:
.byte $F0,$C0,$00,$C0,$70,$C7,$7B,$B0,$70,$20,$E7,$7E,$70,$20,$70,$E7,$00,$20,$70,$E0,$E0,$E0,$E7,$E0,$27,$E0,$E0,$00,$27,$00,$E0,$C0,$E0,$70,$00,$00,$00,$F2,$00,$70; 9C6E ....p.{.p .~p p.. p.....'...'....p.....p row 2 col 30 to row 11 col 21 - logo, sky and the top of the walker
.byte $B0,$B0,$00,$C0,$00,$70,$70,$27,$BF,$2F,$17,$18,$78,$78,$27,$E1,$00,$00,$00,$E0,$E0,$E0,$7E,$E0,$E7,$00,$E0,$00,$E7,$00,$E0,$EF,$00,$70,$00,$70,$BC,$CB,$00,$00; 9C96 .....pp'./..xx'.......~..........p.p....
.byte $2C,$BC,$00,$70,$70,$20,$00,$70,$7B,$70,$27,$E7,$18,$78,$72,$1E,$00,$00,$00,$E0,$E0,$E0,$00,$E0,$E0,$70,$E0,$00,$00,$00,$CE,$FE,$FC,$70,$00,$70,$BF,$B7,$7B,$00; 9CBE ,..pp .p{p'..xr..........p.......p.p..{.
.byte $27,$F0,$00,$00,$70,$2E,$B7,$B0,$00,$B7,$00,$28,$17,$12,$27,$12,$F2,$12,$00,$E0,$E0,$E7,$E0,$E0,$00,$E7,$E0,$E0,$00,$E0,$FC,$C0,$CF,$00,$00,$00,$2B,$70,$20,$00; 9CE6 '...p......(..'.....................+p .
.byte $B7,$00,$00,$00,$00,$7B,$7B,$00,$00,$B0,$27,$E7,$E1,$E7,$E0,$C0,$1F,$1C,$1C,$1E,$70,$00,$27,$70,$E7,$00,$E7,$E7,$C0,$EF,$70,$B0,$E2,$00,$BC,$00,$27,$00,$7B,$7E; 9D0E .....{{...'.........p.'p......p.....'.{~
.byte $70,$B7,$00,$B7,$B0,$BF,$B0,$70,$70,$20,$00,$00,$00,$00,$00,$00,$00,$FC,$1E,$FB,$FE,$1F,$00,$00,$00,$00,$FC,$CE,$CB,$BF,$B0,$00,$FE,$B0,$C0,$C1,$C0,$B0,$BE,$E0; 9D36 p......pp ..............................
.byte $00,$2B,$00,$F0,$E0,$9F,$E0,$E0,$F0,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$F0,$FB,$1B,$1F,$F1,$FC,$FC,$FC,$C0,$F0,$C0,$B0,$B0,$B0,$B0,$C0,$10,$00,$00,$00,$00; 9D5E .+......................................
.byte $80,$82,$B7,$00,$98,$FB,$BE,$00,$F0,$E0,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$C1,$FE,$FB,$BF,$1F,$BC,$C1,$1C,$FC,$B1,$B1,$FB,$FC,$1F,$CF,$F0,$00,$00,$00,$00; 9D86 ........................................
.byte $89,$1F,$F2,$79,$80,$82,$72,$F0,$9B,$87,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1E,$1B,$B0,$C0,$CF,$BC,$FB,$B0,$B0,$B1,$B1,$1C; 9DAE ...y..r.........................
; Screen row 11, column 22. Break caused by unitSymbolShapes ($9DCE-$9E6D in the run-time page): 20
; one-cell unit symbols (five unit types x four facings) that continue the terrain tile table. In the
; picture these 160 bytes cover rows 11-15 up to column 21 - the tank's hull and gun barrel, the white
; highlights along its back and the black smoke to the right of it.
titleScreenRow11Col22:
.byte $FC,$FC,$1C,$F1,$00,$00,$00,$00,$89,$78,$E7,$29,$B8,$92,$79,$1E,$17,$2B,$00,$00,$00,$00,$00,$00,$00,$C0,$CF,$CF,$F0,$F0,$B1,$B1,$FB,$BC,$B1,$B1,$B0,$F0,$F0,$B0; 9DCE .........x.)..y..+...................... row 11 col 22 to row 15 col 21 - the tank's hull and barrel
.byte $10,$1C,$BF,$B1,$F1,$00,$E0,$E0,$E0,$89,$29,$17,$8F,$79,$21,$A7,$2F,$F2,$00,$00,$00,$00,$00,$00,$B0,$BF,$C0,$C0,$F0,$FC,$CF,$C0,$C0,$C0,$00,$C0,$C0,$00,$F0,$F0; 9DF6 ..........)..y!./.......................
.byte $F0,$FB,$F1,$BF,$CE,$B0,$00,$F9,$F2,$2F,$97,$27,$87,$78,$72,$72,$72,$00,$00,$00,$00,$00,$00,$F0,$CF,$FB,$BC,$CB,$BF,$CF,$F1,$FC,$C0,$7C,$C7,$B7,$B7,$C0,$B0,$C0; 9E1E ........./.'.xrrr................|......
.byte $00,$00,$10,$F1,$CE,$00,$90,$92,$79,$FB,$12,$27,$27,$72,$72,$1F,$1F,$F1,$00,$F0,$1F,$1F,$F0,$CE,$CB,$FC,$FC,$F0,$00,$F0,$00,$F1,$CB,$C0,$CF,$BC,$BC,$BC,$BC,$BC; 9E46 ........y..''rr.........................
; Screen row 15, column 22. Break caused by spareCursorShapes ($9E6E-$9E91 in the run-time page), two
; 18-byte cursor sprite fragments that nothing in the disassembly reads. Here the 36 bytes are the
; dark smoke under and behind the tank plus the first cells of row 16.
titleScreenRow15Col22:
.byte $CB,$F0,$FC,$FB,$10,$1F,$00,$00,$EB,$BE,$9F,$B1,$87,$72,$78,$7B,$FE,$1A,$00,$00,$00,$F0,$BE,$B1,$FC,$F0,$F0,$00,$F0,$00,$00,$E0,$E0,$BC,$CF,$FB; 9E6E .............rx{.................... row 15 col 22 to row 16 col 17 - smoke below the tank
; Screen row 16, column 18. Not a boundary of the picture: cursorBlockShape lives here in the run-time
; page (18 bytes copied into the battlefield cursor sprite by setCursorShapeBlock, read from
; $300C in game/mainProgram0800), so the address carries a label in every listing that covers it.
; These 18 cells are sky between the walker's legs and the left edge of the explosion.
titleScreenRow16Col18:
.byte $00,$00,$00,$00,$00,$00,$00,$BC,$FB,$10,$F1,$00,$1B,$BE,$1E,$7B,$8F,$7B; 9E92 ...............{.{ row 16, cells 18-35 - sky between the legs
; Screen row 16, column 36. Break caused by cursorBoxSprite ($9EA4-$9EE2 in the run-time page), the
; complete 24x21 centre cursor sprite that showCursorBoxSprite ($3306) copies into sprite 2. In the
; picture the 63 bytes run from the explosion at the end of row 16 through rows 17 and 18 up to column
; 18 - sky, the walker's right leg and the fire burst.
titleScreenRow16Col36:
.byte $87,$97,$1E,$B0,$00,$00,$00,$CB,$FE,$1B,$CB,$B1,$B1,$1B,$B1,$E0,$B0,$B0,$00,$F1,$F1,$B1,$00,$00,$00,$00,$00,$00,$00,$00,$BC,$FB,$1C,$1B,$00,$C1,$1B,$AB,$89,$B7; 9EA4 ........................................ row 16 col 36 to row 18 col 18 - explosion and right leg
.byte $87,$1F,$17,$FA,$00,$00,$00,$B0,$CF,$F1,$F0,$F0,$FC,$FC,$FC,$CF,$00,$00,$00,$1C,$1F,$CF,$00; 9ECC .......................
; Screen row 18, column 19. Break caused by crosshairSprite ($9EE3-$9F21 in the run-time page), the
; second full 24x21 sprite (a diamond crosshair) used by showCrosshairSprite ($3302). Here the 63
; bytes are the sky to the right of the walker, the brown horizon of row 19 and the first two cells of
; row 20.
titleScreenRow18Col19:
.byte $00,$00,$00,$00,$00,$00,$00,$00,$CB,$FB,$C1,$00,$00,$1E,$B9,$98,$9B,$F1,$71,$FC,$90,$90,$90,$90,$00,$00,$B0,$F9,$CF,$CE,$E9,$E0,$CE,$F1,$00,$C1,$CE,$1C,$CE,$00; 9EE3 ..................q..................... row 18 col 19 to row 20 col 1 - sky, then the brown horizon
.byte $00,$00,$90,$90,$90,$90,$E0,$EF,$CB,$CB,$CE,$E0,$BE,$8E,$89,$10,$B9,$BC,$BF,$F0,$00,$90,$90; 9F0B .......................
; Screen row 20, column 2. Break caused by comcenCrossMarkerShape ($9F22-$9F36 in the run-time page),
; seven 3-byte sprite rows drawing the comcen marker (showComcenCrossMarker, $3383). These 21 cells
; are the brown-to-green transition band of row 20 with the walker's legs crossing it.
titleScreenRow20Col02:
.byte $90,$00,$50,$90,$9C,$1F,$50,$90,$90,$C9,$BC,$9E,$CE,$BC,$C0,$B5,$9E,$9E,$90,$90,$90; 9F22 ..P...P.............. row 20, cells 2-22 - the dirt/field transition
; Screen row 20, columns 23-32 - green field and the third leg. The ten bytes are one half of a split
; pointer pair in the run-time page: circleDxPtrLoTable, the low bytes of ten dx point-list pointers
; for drawCircleInSprite ($323D); the matching high bytes are the next ten bytes at $9F41. They have
; no meaning in the title picture.
titleScreenRow20Col23:
.byte $90,$90,$5C,$C9,$FC,$C0,$9C,$90,$9B,$5B; 9F37 ..\......[ row 20, cells 23-32
; Screen row 20, column 33 - the end of row 20 (cells 33-39) and the first three cells of row 21. The
; run-time page has circleDxPtrHiTable here, the high-byte half of the pointer table whose low bytes
; are at $9F37 (all $9F); read at $3242.
titleScreenRow20Col33:
.byte $89,$C9,$FC,$C1,$9F,$9F,$90,$00,$00,$00; 9F41 .......... row 20 cells 33-39 and row 21 cells 0-2
; Screen row 21, columns 3-12 - green field with a white yard line and the walker's left leg. The
; run-time page has circleDyPtrLoTable here: the low bytes of the ten dy point-list pointers, read at
; $3247; its high-byte half is the next ten bytes at $9F55.
titleScreenRow21Col03:
.byte $50,$B0,$00,$5F,$1C,$00,$00,$00,$5C,$C5; 9F4B P.._....\. row 21, cells 3-12
; Screen row 21, columns 13-22 - the field and the walker's middle leg. The run-time page has
; circleDyPtrHiTable here, the high-byte half of the table whose low bytes are at $9F4B (all $9F);
; read at $324C.
titleScreenRow21Col13:
.byte $5C,$F0,$BF,$1F,$C0,$00,$00,$00,$00,$00; 9F55 \......... row 21, cells 13-22
; Screen row 21, columns 23-32 - plain green field. The run-time page has circleStepCountTable here
; (the highest point index of each circle radius 1-10, read at $3251).
titleScreenRow21Col23:
.byte $00,$C0,$C5,$BC,$1C,$C1,$00,$00,$00,$9F; 9F5F .......... row 21, cells 23-32
; Screen row 21, column 33. Break caused by circlePointDeltaLists ($9F69-$9FD0 in the run-time page),
; the ten dx and ten dy point lists the four pointer tables above point into. In the picture these 104
; bytes are the end of row 21, all of rows 22 and 23 and the start of row 24: the field with its yard
; lines, the walker's legs and the first half of the copyright line.
titleScreenRow21Col33:
.byte $15,$FC,$FB,$C0,$00,$FB,$00,$00,$00,$00,$FB,$FB,$1F,$BF,$51,$00,$00,$1B,$BF,$FC,$FB,$FB,$F1,$50,$00,$00,$00,$00,$00,$00,$00,$C1,$B0,$BC,$BF,$F5,$00,$00,$F0,$F5; 9F69 ..............Q........P................ row 21 col 33 to row 24 col 16 - field, legs and the copyright line
.byte $1F,$FB,$FC,$BC,$00,$B0,$00,$00,$00,$00,$00,$00,$70,$1B,$CB,$00,$15,$10,$1F,$1F,$B1,$7B,$70,$C7,$7C,$70,$70,$70,$00,$70,$7F,$F1,$1F,$1F,$F0,$C5,$70,$70,$70,$50; 9F91 ............p........{p.|ppp.p......pppP
.byte $7F,$F0,$CF,$BC,$00,$00,$00,$00,$00,$00,$00,$00,$70,$70,$70,$70,$70,$75,$F7,$7B,$B7,$F7,$7B,$C7; 9FB9 ............pppppu.{..{.
; Screen row 24, column 17 - the last 23 cells of the picture: the tail of the copyright line
; ('SOFTSCAPE') and the small grey 'MK' monogram in cells 37-39, probably the artist's initials. The
; break is the run-time page's graphicsBlockTail ($9FD1-$9FFF), 47 bytes of filler that nothing reads
; there either.
titleScreenRow24Col17:
.byte $7B,$50,$00,$00,$00,$F7,$70,$B7,$F7,$B7,$1C,$C7,$B7,$70,$70,$70,$70,$70,$00,$00,$00,$00,$B5; 9FD1 {P....p......ppppp..... row 24, cells 17-39 - end of the copyright line and the MK monogram
; titleScreenRamPadding - the 24 bytes after the 1000-byte video matrix, to the end of the page. They
; are not picture data, but they are still copied: the loop at $C288 moves four whole pages, so they
; land at $8FE8-$8FFF. $8FF8-$8FFF is where the VIC reads the sprite pointers for a video matrix at
; $8C00, so these last eight bytes would be sprite shape pointers - harmless, because
; bootShowTitlePicture zeroes every sprite register and clears VIC_SPR_ENA at $C24F before the copy.
; The bytes themselves are filler: alternating $FF/$00 with two phase slips ($9FEC, $9FF0) and one
; stray $0B at $9FF4. The last 19 of them ($9FED-$9FFF) are byte for byte the 19 bytes at
; $BFED-$BFFF, the tail of the title bitmap's page, so both pages were probably padded from the same
; stale buffer in the mastering system; the colour RAM page ends the same way at $9BE8 (the same
; alternation in the opposite phase). Nothing reads any of it, and track 28 overwrites it a moment
; later along with the rest of the page.
titleScreenRamPadding:
.byte $FF,$00,$FF,$00,$00,$00,$FF,$00,$00,$FF,$00,$FF,$0B,$FF,$00,$FF,$00,$FF,$00,$FF,$00,$FF,$00,$FF; 9FE8 ........................ $FF/$00 filler; $9FF8-$9FFF would become the sprite pointers of the copy at $8C00