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’
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