The Amazing Spider-Man and Captain America in Dr. Doom's Revenge!

From Software Archive
Jump to navigation Jump to search

mobygames link

Source 1

Property Data
Title The Amazing Spider-Man and Captain America in Dr. Doom's Revenge!
Publisher and/or Developer Paragon Software Corp., Empire, Marvel Comics
Year 1989
Disk(s) 2
Number of Index Holes 1
Media Type 5.25 DSDD
Retail, Budget or Compilation (with name) Retail
Country of Release UK
Language(s) English, German, Italian
Platform C64
NTSC or PAL PAL
Protection GMA89 only the loader, no protection
Working? Yes
Archived 20 Feb 2013 Rakki
Verified by enigma

Purchased from: amibay.com

Rakki: Redumped with realigned drive 20th Feb 2013.

Streams

Disk 1

File:Streams DrDoomsRevenge disk1 rakki.zip

Disk 2

File:Streams DrDoomsRevenge disk2 rakki.zip

G64

Disk 1

File:DrDoomsRevenge Disk1 rakki s0.g64

File:DrDoomsRevenge Disk1 rakki s1.g64

Disk 2

File:DrDoomsRevenge Disk2 rakki s0.g64

File:DrDoomsRevenge Disk2 rakki s1.g64

Source 2

Property Data
Title The Amazing Spider-Man and Captain America in Dr. Doom's Revenge!
Publisher and/or Developer Paragon Software Corp., Empire, Marvel Comics
Year 1989
Disk(s) 2
Number of Index Holes 1
Media Type 5.25 DSDD
Retail, Budget or Compilation (with name) Retail
Country of Release UK
Language(s) English, German, Italian
Platform C64
NTSC or PAL PAL
Protection GMA89 only the loader, no protection
Working? Yes
Archived 15 Aug 2022 stefan_h
Verified by enigma

Streams

Disk 1

File:Streams Dr. Doom`s Revenge! (Empire) disk1 stefan h.zip

Disk 2

File:Streams Dr. Doom`s Revenge! (Empire) disk2 stefan h.zip

G64

Disk 1

File:Dr. Doom`s Revenge! disk1 stefan h s0.g64

File:Dr. Doom`s Revenge! disk1 stefan h s1.g64

Disk 2

File:Dr. Doom`s Revenge! disk2 stefan h s0.g64

File:Dr. Doom`s Revenge! disk2 stefan h s1.g64

Manual

Comics
Manual


Ghostbusters II vs. Dr. Doom's Revenge: a GMA89 comparison

Both Ghostbusters II and The Amazing Spider-Man and Captain America in Dr. Doom's Revenge! are titles whose gm1.prg loads at the identical address ($0334) and shares large stretches of byte-identical code — strong evidence both were built from the same generic loader toolkit. Live tracing and static disk analysis, however, found the two behave completely differently: Ghostbusters II's protection is fully active and live-confirmed (measured key $18); every locally-archived Dr. Doom's Revenge source (two independent dumps, byte-identical to each other) shows no functioning check at all, confirmed decisively by a clean D64-conversion load with no hang. This article lays the two loaders side by side at the disassembly level to show exactly where they diverge.

Summary

  • Both loaders share an identical, byte-for-byte 224-byte GCR sector-read/verify routine embedded directly in gm1.prgbut this is ordinary fast-loader machinery, not the protection check itself. It reads and verifies a GCR-encoded sector via the standard 1541 GCRBIN/CHKBLK ROM calls, used for regular data transfer regardless of whether protection is active.
  • Ghostbusters II's main flow contains JSR $C800 — the fixed drive-upload-and-execute trigger used throughout the whole GMA family — immediately followed by a PHA/.../PLA/TAX handoff that carries the measured signature byte into a self-modifying EOR decrypt loop.
  • Dr. Doom's Revenge's main flow has neither. No JSR $C800 anywhere in the file, and no PHA/PLA/TAX key-handoff idiom anywhere at all — not patched out of an otherwise identical file (compare Hollywood Collection's Disk 4, a confirmed *crack* of this same game elsewhere in the GMA89 survey), but simply absent from a differently-shaped loader.
  • No genuine, actively-protected Dr. Doom's Revenge source is known to this project. Unlike the Hollywood Collection case, this comparison can't prove a specific patch was applied to a specific original file — only that the two loaders diverge exactly where the protection logic would need to be.

What's shared: the ordinary fast-loader sector routine

Byte-for-byte identical in both files (confirmed by direct comparison, zero differences across all 224 bytes):

; ---- read a full GCR-encoded sector from the VIA into a 256-byte buffer ----
        LDA #$06
        STA $31
        JSR $F50A          ; 1541 KERNAL DSTRT - seek/prep
        BVC *               ; wait for VIA SR byte-ready
        CLV
        LDA $1C01           ; read GCR byte from VIA2
        STA $0600,Y
        INY
        BNE *-8              ; fill $0600-$06FF (256 bytes)
        ...                  ; (second block similarly fills $01BA-$01FF)

; ---- decode GCR, verify header track and checksum (standard DOS ROM calls) ----
        JSR $F8E0           ; GCRBIN
        LDA $38
        CMP $47              ; header track check
        BEQ +4
        LDA #$04
        BNE <error>          ; status $04 on mismatch

        JSR $F5E9           ; CHKBLK
        CMP $3A              ; checksum check
        BEQ +4
        LDA #$05
        BNE <error>          ; status $05 on mismatch
        ...

This is plain, disk-independent sector I/O — the same GCR-decode and header/checksum verification every 1541 fast-loader of this era needs for ordinary data transfer, structurally identical to the sector-read half of GMA87's Eagles drive-side program. Its presence in both files, byte for byte, confirms nothing about protection status either way — a cracked or never-protected build still needs to load its own data quickly.

Ghostbusters II: the protection check, live and complete

The genuine source's main flow, immediately after the boot preamble:

L03A6:  BNE L03A6
        LDA #$37
        STA $01
        LDA #$00
        JSR sub_0461         ; load file 0 (an off-directory block, hidden
                              ;   by this disk's own obfuscated BAM - not
                              ;   statically present in gm1.prg itself)
        JSR $C800              ; <=== the fixed drive-upload-and-execute
                               ;      trigger. Runs the code just loaded as
                               ;      "file 0", collecting the measured
                               ;      signature byte in A.
        PHA                   ; stash the measured key
        LDA #$01
        JSR sub_0461          ; load file 1
        JSR sub_03EC
        LDA #$02
        JSR sub_0461          ; load file 2
        LDA #$03
        JSR sub_0461          ; load file 3
        LDA #$04
        JSR sub_0461          ; load file 4
        JSR sub_0449           ; KERNAL vector setup
        LDX #$59
L03D1:  LDA $2000,X
        STA $02A7,X
        DEX
        BPL L03D1
        PLA                   ; recover the measured key
        TAX                   ; X = $18 (this disk's live-confirmed key)
        JSR sub_041B            ; run the decrypt loop
        LDA #$37
        STA $01
        CLI
        LDA #$00
        JSR SETMSG
        JMP $02A7               ; jump into the freshly-decrypted code

The decrypt loop itself, reached via that TAX:

sub_041B:
        SEI
        LDY #$00
L041E:  LDA #$24                ; bank OUT I/O
        STA $01
        TXA
        EOR $D000,Y              ; <=== actual XOR decrypt against the
        STA $D000,Y               ;      measured key in X, byte by byte
        PHA
        LDA #$27                ; bank I/O back IN
        STA $01
        PLA
        INY
        BNE L041E
        INC $0425
        INC $0428
        LDA $0428
        CMP #$E0
        BNE L041E
        LDA #$37
        STA $01
        LDA #$00
        STA $D418
        RTS

Separately, and confirmed live during this project's GMA89 survey (breakpoint freeze on the drive's own DRVTRK variable becoming 38, then a static disassembly of drive RAM without resuming) — the code that JSR $C800 actually uploads to and runs on the 1541 is the family's standard shared signature-measurement routine, structurally identical to every other GMA85/86/87/88/89 title documented in this project:

; ---- sync-marker search, 90-attempt retry budget ----
$0300  AD 00 1C    LDA $1C00
$0303  29 9F       AND #$9F
$0305  8D 00 1C    STA $1C00
        ...                     ; (full listing: see GMA89-protection)
; ---- 10-sample pulse-width measurement, folded via CMP/ROL ----
$035C  AE 0A 05    LDX $050A    ; X = computed result: $18 for this disk
; ---- job dispatch: target track 38 ----
$0397  A9 26       LDA #$26     ; $26 = 38 decimal
        ...
$03B4  60          RTS          ; plain RTS - C64-side consumption

Live sample buffer for this disk, read directly from $0500- $0509: 12 35 19 19 19 52 52 19 19 19 (sample[0]=$12 discarded, sample[1]=$35 the reference); hand-folding samples[2..9] against the reference reproduces $18 exactly, matching the live X register at the fold's completion.

Dr. Doom's Revenge: the same points, absent

The equivalent stretch of the main flow — same load address, same overall loader shape, same boot preamble immediately before this point:

L039A:  BNE L039A
        LDA #$37
        STA $01
        LDA #$01
        JSR sub_03EF          ; load file 1 (note: starts at file INDEX 1,
                               ;   not 0 - this loader's file table is laid
                               ;   out differently from Ghostbusters II's)
        JSR sub_03AB           ; <=== NOT a drive-upload trigger. Sets up
                               ;      KERNAL vectors and a name pointer
                               ;      ($0330/$0331 <- "A7","02" = $02A7),
                               ;      then copies 24 bytes into $BB00.
                               ;      No PHA anywhere near this call.
        JMP loc_080D            ; jumps straight on - no PLA, no TAX,
                                ; no decrypt loop ever reached from here

Nothing resembling JSR $C800 exists anywhere in this file — a direct byte search for 20 00 C8 across the entire 1330-byte gm1.prg finds zero matches (compare Ghostbusters II's own file, where the identical search finds it once, at file offset 127). A further search for the decrypt loop's own signature shape (TXA followed by an indexed operation on a fixed page then an indexed store — the 8A xx xx xx 99 xx xx byte pattern) also finds nothing anywhere in the file. There is no decrypt loop to find, patched or otherwise — not a neutralized copy of Ghostbusters II's sub_041B, just no equivalent code at all.

The shared GCR-sector-read block (see above) is still present and intact, confirming this loader can and does load its own data — it simply never attempts to derive or apply a decryption key while doing so.

Side by side

Ghostbusters II (genuine) Dr. Doom's Revenge (both sources)
gm1.prg size 1444 bytes 1330 bytes
Shared GCR sector-read block present, byte-identical present, byte-identical
JSR $C800 (drive-upload trigger) present, file offset 127 absent (searched entire file)
PHA/PLA/TAX key handoff present absent anywhere in the file
Decrypt loop (TXA/indexed-op/indexed-store shape) present (sub_041B, uses EOR) absent anywhere in the file
Directory obfuscation near-empty, garbled (standard GMA convention) near-empty, garbled (standard GMA convention) - same as genuine, unlike a confirmed crack
D64-conversion test (not applicable - protection genuinely active) loads and runs correctly, confirmed directly - decisive evidence of no functioning dependency on the out-of-range track
Live-measured key $18, confirmed and cross-validated across 3 sources none - nothing to measure

What this does and doesn't prove

The Hollywood Collection Disk 4 case (a confirmed crack of this same Ghostbusters II release, documented separately) shows what a minimal patch on top of an identical genuine file looks like: a 4-byte size difference, one 3-byte instruction deleted, one 1-byte opcode changed, everything else untouched byte-for-byte, and a directory re-saved into legible plaintext assets as the tell-tale sign of a completed crack.

Dr. Doom's Revenge does not match that shape. The 114-byte size difference, the differently-numbered file-load sequence (starting at index 1, not 0), the entirely different subroutine reached in place of the upload trigger, and — notably — a directory that still carries the genuine obfuscation convention rather than being unpacked to plaintext, all point away from "the same crack, applied to a different game." What's solidly established is narrower but real: this loader was built (or ended up, however it got that way) without the upload-trigger/key-handoff/decrypt-loop sequence Ghostbusters II's genuine build has in the equivalent place, and every locally-archived copy agrees. Whether an original, actively-protected Dr. Doom's Revenge release exists anywhere that this project hasn't seen a copy of is not something this comparison can settle.

See also