We just released a Feb. 5 '89 prototype of DuckTales for the NES!
If you'd like to support our preservation efforts (and this wasn't cheap), please consider donating or supporting us on Patreon. Thank you!

Notes:Magic Jewelry

From The Cutting Room Floor
Jump to navigation Jump to search

This page contains notes for the game Magic Jewelry.


CHR Checksum

The following is the CHR checksum that occurs when a new game is started.

  • Tile bitmaps are stored at $0000-$1FFF in the PPU's address map.
  • Magic Jewelry only uses $0000-$0FFF for graphics, so this routine only checks $0000-$0FFF.
  • The expected checksum is hardcoded into this routine.
$E510:A2 00     LDX #$00
$E512:8E 06 20  STX $2006   ; Set PPU address to $0000
$E515:8E 06 20  STX $2006
$E518:8E F5 05  STX $05F5   ; This address will hold LSB of the calculated checksum
$E51B:8E F6 05  STX $05F6   ; And this, the MSB
$E51E:A0 10     LDY #$10
$E520:AD 07 20  LDA $2007   ; The NES requires a dummy read before you start reading from the PPU
$E523:18        CLC
$E524:AD 07 20  LDA $2007   ; Read a byte of graphics data (PPU automatically advances to next byte after this)
$E527:6D F5 05  ADC $05F5   ; Add it to the LSB of the current total
$E52A:8D F5 05  STA $05F5   ; Store updated LSB
$E52D:A9 00     LDA #$00
$E52F:6D F6 05  ADC $05F6   ; Add carry to MSB
$E532:8D F6 05  STA $05F6   ; Store updated MSB
$E535:CA        DEX
$E536:D0 EB     BNE $E523   ; Loop 256 times
$E538:88        DEY
$E539:D0 E8     BNE $E523   ; Loop 16 times (loop runs a total of 256 * 16 = 4096 times)
$E53B:AD F5 05  LDA $05F5   ; Compare the LSB of the calculated checksum
$E53E:C9 14     CMP #$14    ; with the expected value
$E540:D0 07     BNE $E549   ; If the LSB doesn't match, die
$E542:AD F6 05  LDA $05F6   : Do the same for the MSB
$E545:C9 11     CMP #$11
$E547:F0 01     BEQ $E54A   ; If the MSB does match, don't die
$E549:60        RTS         ; Uh oh! CPU jumps to $0000, executes garbage, and crashes.

PRG Checksum

The following is the PRG checksum routine that occurs during a level up.

  • Magic Jewelry's code is only 8k, and runs in $E000-$FFFF of the NES's address space.
  • At $E000 is the 16-bit checksum that the game is expecting. If the actual calculated checksum does not match this value, the check fails and the program purposely crashes.
  • This checksum routine only actually checks $E002-$FDFF. $FE00-$FFFF may be reserved for bootstrap code, which can vary from multicart to multicart.
$E767:A9 20     LDA #$20    ; Initialize ram for checksum
$E769:85 02     STA $0002
$E76B:A0 00     LDY #$00
$E76D:84 00     STY $0000
$E76F:8C F3 05  STY $05F3
$E772:8C F4 05  STY $05F4
$E775:98        TYA
$E776:38        SEC
$E777:E5 02     SBC $0002
$E779:85 01     STA $0001   ; = $E0
$E77B:E6 00     INC $0000
$E77D:E6 00     INC $0000   ; $00-$01 is a pointer to E002 now
$E77F:18        CLC
$E780:AD F3 05  LDA $05F3
$E783:71 00     ADC ($00),Y ; Add a byte from ROM to the total
$E785:8D F3 05  STA $05F3
$E788:AD F4 05  LDA $05F4
$E78B:69 00     ADC #$00    ; Add carry to the MSB of the total
$E78D:8D F4 05  STA $05F4
$E790:18        CLC
$E791:A5 00     LDA $0000
$E793:69 01     ADC #$01    ; Update pointer to the next byte in ROM
$E795:85 00     STA $0000
$E797:A5 01     LDA $0001
$E799:69 00     ADC #$00    ; Add carry to MSB
$E79B:85 01     STA $0001
$E79D:18        CLC
$E79E:69 02     ADC #$02    ; Stop reading bytes when we get to $FE00
$E7A0:90 DD     BCC $E77F
$E7A2:AD F3 05  LDA $05F3   ; Compare the LSB of the total
$E7A5:4D 00 E0  EOR $E000   ; against its expected value
$E7A8:D0 0B     BNE $E7B5   ; Die if it doesn't match
$E7AA:AD F4 05  LDA $05F4   ; Same, but with the MSB
$E7AD:4D 01 E0  EOR $E001
$E7B0:D0 03     BNE $E7B5   ; Die if it doesn't match
$E7B2:4C 8B E5  JMP $E58B   ; Checksum matched, don't die
$E7B5:60        RTS         ; Same as CHR; jumps to $0000, CPU crashes after trying to execute garbage