(back to project page)

Battlezone Revision 1 ROM

If you look at the Battlezone ROM sets, there are two revisions, called simply "rev 1" and "rev 2". The only difference between them is in the E1 ROM:

 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
    2048  Defl:X     1707  17% 1996-12-24 23:32 efbc3fa0  036414-01.e1
    2048  Defl:X     1701  17% 1996-12-24 23:32 13de36d5  036414-02.e1

This is the game ROM that spans addresses $5000-57ff. The exact differences are revealed by a diff of the hex dumps:

53c53
< 00000340: 7045 4452 a200 86d2 8e3c 03bc 0003 c4b8  pEDR.....<......
---
> 00000340: 6745 4452 a200 86d2 8e3c 03bc 0003 c4b8  gEDR.....<......
75,84c75,84
< 000004a0: 2098 6c20 6a7a a000 8c40 03a9 e0a2 1e8e   .l jz...@......
< 000004b0: 7103 208e 7aae 4003 bd00 0385 0a1d 0103  q. .z.@.........
< 000004c0: f07b bd01 0385 0ba9 0a20 9e7b a21c 2098  .{....... .{.. .
< 000004d0: 6cae 4003 bd1e 0320 6a55 ae40 03bd 1f03  l.@.... jU.@....
< 000004e0: 206a 55ae 4003 bd20 0320 6a55 a000 ae40   jU.@.. . jU...@
< 000004f0: 03bd 0103 f024 aaad f033 9102 c8ad f133  .....$...3.....3
< 00000500: 9102 e00a 9002 a20a c8ad 9035 9102 c8ad  ...........5....
< 00000510: 9135 9102 cad0 f120 767a ae40 03e0 1bb0  .5..... vz.@....
< 00000520: 1ce8 e8e8 8e40 0320 6a7a ad71 0338 e90a  .....@. jz.q.8..
< 00000530: 8d71 03aa a9e0 a000 4cb2 5445 52ad 000a  .q......L.TER...
---
> 000004a0: 2098 6c20 6a7a a000 a9e0 a21a 208e 7aa2   .l jz...... .z.
> 000004b0: 008e 4003 ae40 03bd 0003 850a 1d01 03f0  ..@..@..........
> 000004c0: 7cbd 0103 850b a90a 209e 7ba2 1c20 986c  |....... .{.. .l
> 000004d0: ae40 03bd 1e03 206a 55ae 4003 bd1f 0320  .@.... jU.@.... 
> 000004e0: 6a55 ae40 03bd 2003 206a 55a0 00ae 4003  jU.@.. . jU...@.
> 000004f0: bd01 03f0 1aad f033 9102 c8ad f133 9102  .......3.....3..
> 00000500: c8ad 9035 9102 c8ad 9135 9102 2076 7aae  ...5.....5.. vz.
> 00000510: 4003 e01b b027 e8e8 e88e 4003 a9d8 8506  @....'....@.....
> 00000520: a9ff 8507 a9fe 8505 98f0 04a9 a3d0 02a9  ................
> 00000530: f485 04a9 0085 0120 ab7a 4cb4 54ad 000a  ....... .zL.T...

The byte at +340 is the checksum adjustment for this 2K section (see notes on ROM checksums, below).

The code from +4a8 to +53c ($54a8-553c) has been rewritten. This is the code that draws the high score list on the screen. Here's what the revision 1 code looks like:

                   ]score_tmp      .var    $0a    {addr/2}

549b: 20 2e 6d     HighScoreList   jsr     DrawScoreLives
549e: a2 1a                        ldx     #$1a              ;"high scores"
54a0: 20 98 6c                     jsr     DrawString
54a3: 20 6a 7a                     jsr     VgCenter
54a6: a0 00                        ldy     #$00
54a8: 8c 40 03                     sty     hs_index
54ab: a9 e0                        lda     #$e0
54ad: a2 1e                        ldx     #$1e              ;first entry is at screen Y=+30
54af: 8e 71 03                     stx     hs_y_posn
54b2: 20 8e 7a     :ScoreLoop      jsr     VgVec8I           ;move to -128,+30
54b5: ae 40 03                     ldx     hs_index
54b8: bd 00 03                     lda     hs_scores,x
54bb: 85 0a                        sta     ]score_tmp
54bd: 1d 01 03                     ora     hs_scores+1,x
54c0: f0 7b                        beq     DrawBonusTankStr
54c2: bd 01 03                     lda     hs_scores+1,x
54c5: 85 0b                        sta     ]score_tmp+1
54c7: a9 0a                        lda     #$0a              ;draw digits from $0a/0b
54c9: 20 9e 7b                     jsr     DrawFourDigits
54cc: a2 1c                        ldx     #$1c              ;"000"
54ce: 20 98 6c                     jsr     DrawString
                   ; Now draw the initials.
54d1: ae 40 03                     ldx     hs_index
54d4: bd 1e 03                     lda     hs_initials,x
54d7: 20 6a 55                     jsr     DrawChar
54da: ae 40 03                     ldx     hs_index
54dd: bd 1f 03                     lda     hs_initials+1,x
54e0: 20 6a 55                     jsr     DrawChar
54e3: ae 40 03                     ldx     hs_index
54e6: bd 20 03                     lda     hs_initials+2,x
54e9: 20 6a 55                     jsr     DrawChar
54ec: a0 00                        ldy     #$00
54ee: ae 40 03                     ldx     hs_index
54f1: bd 01 03                     lda     hs_scores+1,x     ;check high byte
54f4: f0 24                        beq     :Sub100k
                   ; Score >= 100K, draw 1-10 tank icons.
54f6: aa                           tax
54f7: ad f0 33                     lda     vg_glyph_calls    ;draw a ' '
54fa: 91 02                        sta     (vg_cmd_ptr),y
54fc: c8                           iny
54fd: ad f1 33                     lda     vg_glyph_calls+1
5500: 91 02                        sta     (vg_cmd_ptr),y
5502: e0 0a                        cpx     #10
5504: 90 02                        bcc     :DrawTankIcon
5506: a2 0a                        ldx     #10               ;cap tank icons at 10
5508: c8           :DrawTankIcon   iny
5509: ad 90 35                     lda     vg_life_icon
550c: 91 02                        sta     (vg_cmd_ptr),y
550e: c8                           iny
550f: ad 91 35                     lda     vg_life_icon+1
5512: 91 02                        sta     (vg_cmd_ptr),y
5514: ca                           dex
5515: d0 f1                        bne     :DrawTankIcon
5517: 20 76 7a                     jsr     VgPtrAddY         ;update cmd list pointer
551a: ae 40 03     :Sub100k        ldx     hs_index
551d: e0 1b                        cpx     #27               ;done yet?
551f: b0 1c                        bcs     DrawBonusTankStr  ;yes, bail
5521: e8                           inx                       ;no, move on to next entry
5522: e8                           inx
5523: e8                           inx
5524: 8e 40 03                     stx     hs_index
5527: 20 6a 7a                     jsr     VgCenter          ;center beam
552a: ad 71 03                     lda     hs_y_posn         ;update screen Y coordinate
552d: 38                           sec
552e: e9 0a                        sbc     #$0a
5530: 8d 71 03                     sta     hs_y_posn
5533: aa                           tax
5534: a9 e0                        lda     #$e0              ;X position is the same
5536: a0 00                        ldy     #$00
5538: 4c b2 54                     jmp     :ScoreLoop

553b: 45 52                        .str    ‘ER’

ROM Checksums

The self-test code performs a rolling XOR of each 2K ROM bank with an initial seed of $FF, and complains if the result isn't zero. To make this work, each 2K ROM has one byte that gets altered after the ROM is assembled. The addresses aren't listed in a table, but their locations can be determined by looking for data bytes that aren't referenced by anything. These are noted with the comment "checksum adj?" in the disassembly. Here's the set from the rev 2 ROM:

5340: 67
5c5b: 5e
6417: d5
6c8f: 6b
74ca: dd
7b9d: e3
3784: 92
3885: d4

There's also a run-time check that performs some odd calculations (search the listing for "strange"). It appears to be a check for badly-cloned ROMs.


Copyright 2020 by Andy McFadden