add support for David's Midnight Magic, Genetic Drift, Red Alert, and Space Quarks

This commit is contained in:
4am 2019-03-10 13:03:51 -04:00
parent ad4902f7ca
commit 78860e6c13
5 changed files with 230 additions and 95 deletions

View File

@ -21,24 +21,28 @@ then press `<RETURN>`. The game should boot normally.
## Which games are supported?
- Choplifter (Broderbund) (*)
- David's Midnight Magic (Broderbund) (*)
- Dueling Digits (Broderbund)
- Eggs-It (Gebelli Software)
- Eggs-It (Gebelli)
- Frogger (On-Line Systems) (*)
- High Orbit (Gebelli Software)
- Horizon V (Gebelli Software)
- Genetic Drift (Broderbund)
- High Orbit (Gebelli)
- Horizon V (Gebelli)
- Jawbreaker ][ (On-Line Systems)
- Labyrinth (Broderbund)
- Lazer Silk (Gebelli Software)
- Lazer Silk (Gebelli)
- Lunar Leepers (On-Line Systems)
- Neptune (Gebelli Software)
- Neptune (Gebelli)
- Pest Patrol (On-Line Systems)
- Phaser Fire (Gebelli Software)
- Russki Duck (Gebelli Software)
- Phaser Fire (Gebelli)
- Red Alert (Broderbund)
- Russki Duck (Gebelli)
- Seafox (Broderbund)
- Serpentine (Broderbund) (*)
- Sky Blazer (Broderbund)
- Space Quarks (Broderbund)
- Star Blazer (Broderbund)
- Zenith (Gebelli Software)
- Zenith (Gebelli)
(*) later re-released with different copy protection. Only the first release
requires Anti-M.

View File

@ -2,10 +2,6 @@ Untested (Gebelli):
- Lazer Silk
Do not work yet:
- David's Midnight Magic (Broderbund)
- Genetic Drift (Broderbund)
- Red Alert (Broderbund)
- Space Quarks (Broderbund)
- Raster Blaster (BudgeCo)
- Bug Attack (Cavalier)
- Star Thief (Cavalier)

View File

@ -86,7 +86,7 @@ Boot
@iigs
ldy $16FB
cpy #$4C
bne @unknowncontroller
bne RebootImmediately
; entry point for IIgs smart controller
sta $16FC ; lo byte of callback
stx $16FD ; hi byte of callback
@ -94,8 +94,21 @@ Boot
@unknowncontroller
jmp REBOOT
Unsupported
lda $C082
jsr TEXT
jsr HOME
lda #s_unsupported
jsr PrintByID
bit STROBE
- lda KEY
bpl -
bit STROBE
RebootImmediately
jmp REBOOT
Tracer
jsr IDChoplifter
jsr IDBroderbund
bcc @jmpboot
jsr IDSpiraDisc
bcc @jmpboot
@ -136,11 +149,13 @@ PrintByID
;
s_header = $00
s_mainmenu = $01
STRINGCOUNT = $02
s_unsupported =$02
STRINGCOUNT = $03
StringTable
!word @header
!word @mainmenu
!word @unsupported
@header
!text "Anti-M by 4am 2019-03-10",$00
@ -150,7 +165,10 @@ StringTable
!text " Insert original disk in slot 6 drive 1",$8D
!text $8D
!text " and press <RETURN> to boot",$00
@unsupported
!text $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
!text " Unsupported game (sorry)",$00
!src "src/compare.a"
!src "src/idchoplifter.a"
!src "src/idbroderbund.a"
!src "src/idspiradisc.a"

196
src/idbroderbund.a Normal file
View File

@ -0,0 +1,196 @@
IDBroderbund
; first stage is just a standard hybrid DOS 3.2/3.3 bootloader
lda #8
ldx #1
ldy #11
jsr CompareMemory
!byte $A2,$00 ;LDX #$00
!byte $BD,$00,$08 ;LDA $0800,X
!byte $9D,$00,$02 ;STA $0200,X
!byte $E8 ;INX
!byte $D0,$F7 ;BNE *-7
bcs @exit
; patch code to regain control after it loads 1 sector into $0300
lda #<@BroderbundCallback
sta $0838
lda #>@BroderbundCallback
sta $0839
@exit
rts
@BroderbundCallback
; distinguish between different Broderbund bootloaders
; by examining decryption routine at $0300
lda $0301
cmp #$A2
bne @maybeDMM
lda $0302
cmp #$2E
bne @unsupported
lda $0303
cmp #$9A
bne @unsupported
;
; found Choplifter protection
;
; duplicate bootloader from $0300 to $0200 and our callback code to $1700
; [must preserve Y here]
ldx #$00
- lda $0300,x
sta $0200,x
lda @copyChoplifter,x
sta $1700,x
inx
bne -
; patch bootloader so it reads the pristine copy at $0200
dec $030A
dec $0310
dec $0316
dec $031C
; patch bootloader to regain control after it decrypts itself into $0100
lda #$4C
sta $0325
lda #<@choplifterCallback
sta $0326
lda #>@choplifterCallback
sta $0327
jmp $0301
@maybeDMM
cmp #$8C
bne @unsupported
lda $030B
cmp #$4D
bne @unsupported
lda $0323
cmp #$60
bne @unsupported
;
; found David's Midnight Magic protection
;
; duplicate bootloader from $0300 to $2300 and our callback code to $1700
; [must preserve Y here]
ldx #$00
- lda $0300,x
sta $2300,x
lda @copyDMM,x
sta $1700,x
inx
bne -
lda #$23
sta $030A
sta $0320
lda #$4C
sta $0321
lda #<@DMMCallback
sta $0322
lda #>@DMMCallback
sta $0323
jmp $0301
; TODO
@unsupported
jmp Unsupported
@copyChoplifter
!pseudopc $1700 {
@choplifterCallback
; patch bootloader to regain control after it loads 4 sectors into $0400
lda #$4C
sta $01FB
lda #<@choplifterCallback2
sta $01FC
lda #>@choplifterCallback2
sta $01FD
rts
@choplifterCallback2
; patch bootloader so it doesn't wipe main memory
lda #$60
sta $04E2
; patch bootloader to regain control
; after it loads title screen and code into $2000+
lda #$4C
sta $0498
lda #<@choplifterCallback3
sta $0499
lda #>@choplifterCallback3
sta $049A
; restore bytes on stack page that we patched earlier
; because they're checksummed soon
lda #$AE
sta $01FB
lda #$65
sta $01FC
lda #$05
sta $01FD
jmp $01FB
@choplifterCallback3
; patch bootloader to bypass ROM check at $6300
lda #$60
sta $0421
jmp $0400
}
@copyDMM
!pseudopc $1700 {
@DMMCallback
; patch bootloader to regain control after it loads 4 sectors into $0400
lda #$4C
sta $FD
lda #<@DMMCallback2
sta $FE
lda #>@DMMCallback2
sta $FF
rts
@DMMCallback2
; distinguish between two variants here
; [must preserve A here]
sta @restore+1
lda $0406
cmp #$48
beq @harderVariant
; one variant JSRs to a ROM check that exits via JMP $0606
; on failure, which can be fooled by putting an RTS there
; e.g. Genetic Drift, Red Alert, or Space Quarks
;
; patch bootloader to continue booting after ROM check fails
lda #$60
sta $0606
bne @restore ; always branches
@harderVariant
; this variant has a ROM check that exits via JMP $0606
; but first uses all of $0400..$7FF as a decryption key
; e.g. David's Midnight Magic
;
; patch bootloader to regain control after loading title page
lda #$4C
sta $0461
lda #<@DMMCallback3
sta $0462
lda #>@DMMCallback3
sta $0463
@restore lda #$FD ; SMC
rts
@DMMCallback3
; restore bytes that we patched earlier because they're used
; as part of a decryption key soon, and patch bootloader to
; bypass ROM check at $6300 (called from $8B5D)
; [must preserve A here]
sta @restore2+1
lda #$60
sta $0461
sta $8B5D
lda #$00
sta $0462
sta $0463
@restore2
lda #$FD ; SMC
rts
}

View File

@ -1,79 +0,0 @@
IDChoplifter
lda #8
ldx #1
ldy #11
jsr CompareMemory
!byte $A2,$00 ;LDX #$00
!byte $BD,$00,$08 ;LDA $0800,X
!byte $9D,$00,$02 ;STA $0200,X
!byte $E8 ;INX
!byte $D0,$F7 ;BNE *-7
bcs @exit
; patch code to regain control after it loads 1 sector into $0300
lda #<@callback1
sta $0838
lda #>@callback1
sta $0839
@exit
rts
@callback1
; duplicate bootloader from $0300 to $0200
ldx #$00
- lda $0300,x
sta $0200,x
lda @copysrc,x
sta $1700,x
inx
bne -
; patch bootloader so it reads the pristine copy at $0200
dec $030A
dec $0310
dec $0316
dec $031C
; patch bootloader to regain control after it decrypts itself into $0100
lda #$4C
sta $0325
lda #<@callback2
sta $0326
lda #>@callback2
sta $0327
jmp $0301
@copysrc
!pseudopc $1700 {
@callback2
; patch bootloader to regain control after it loads 4 sectors into $0400
lda #$4C
sta $01FB
lda #<@callback3
sta $01FC
lda #>@callback3
sta $01FD
rts
@callback3
; patch bootloader so it doesn't wipe main memory
lda #$60
sta $04E2
; patch bootloader to regain control after it loads title screen and code into $2000+
lda #$4C
sta $0498
lda #<@callback4
sta $0499
lda #>@callback4
sta $049A
; restore bytes on stack page that we patched earlier because they're checksummed soon
lda #$AE
sta $01FB
lda #$65
sta $01FC
lda #$05
sta $01FD
jmp $01FB
@callback4
; patch bootloader to bypass ROM check at $6300
lda #$60
sta $0421
jmp $0400
}