mirror of
https://github.com/a2-4am/passport.git
synced 2024-05-28 21:41:27 +00:00
522 lines
11 KiB
Plaintext
522 lines
11 KiB
Plaintext
;-------------------------------
|
|
; #Choplifter
|
|
; insane protection by Roland Gustafsson
|
|
; licensed by Broderbund, Gebelli, and others
|
|
;
|
|
; module by qkumba
|
|
;
|
|
; tested on
|
|
; - Choplifter (Broderbund)
|
|
; - Dueling Digits (Broderbund)
|
|
; - Eggs-It (Gebelli)
|
|
; - High Orbit (Gebelli)
|
|
; - Horizon V (Gebelli)
|
|
; - Labyrinth (Broderbund)
|
|
; - Lazer Silk (Broderbund)
|
|
; - Neptune (Gebelli)
|
|
; - Phaser Fire (Gebelli)
|
|
; - Russki Duck (Gebelli)
|
|
; - Seafox (Broderbund)
|
|
; - Serpentine (Broderbund)
|
|
; - Sky Blazer (Broderbund)
|
|
; - Star Blazer (Broderbund)
|
|
;-------------------------------
|
|
!zone {
|
|
Choplifter
|
|
lda #$00
|
|
sta gCommand ; passport-test-suite/Eggs-It.woz [Z=1] reaches here
|
|
sta dct+1
|
|
jsr ChangeTrackNW
|
|
jsr IncProgress
|
|
ldx #$00
|
|
- lda .readtracki,x
|
|
sta $2000,x
|
|
inx
|
|
bne -
|
|
|
|
.read
|
|
asl gTrack
|
|
jsr ReadChoplifter
|
|
lsr gTrack
|
|
jsr WriteTrackNA
|
|
ldx gTrack
|
|
inx
|
|
txa
|
|
pha
|
|
jsr ChangeTrackNW
|
|
jsr IncProgress
|
|
pla
|
|
cmp #$23
|
|
bne .read
|
|
|
|
bit gMode ; done if in verify-only mode
|
|
bpl .exit
|
|
|
|
; start with RDOS as a minimal SD base
|
|
; and copy SD code for free
|
|
|
|
ldx #ID_RDOS13
|
|
jsr ConstructStandardDelivery
|
|
ldx #$B0
|
|
stx $104E ; exit address
|
|
stx $1050 ; next-stage addressing
|
|
inx
|
|
stx $104F ; next-stage addressing
|
|
inx
|
|
stx $105D ; next-stage addressing
|
|
|
|
lda #$10
|
|
sta modsrc+1
|
|
lda #$5E
|
|
sta modsrc
|
|
ldx #$27
|
|
lda #$67
|
|
jsr .inittable
|
|
|
|
lda #$1F
|
|
sta modsrc+1
|
|
lda #$00
|
|
sta modsrc
|
|
ldx #$87
|
|
lda #$C7
|
|
jsr .inittable
|
|
|
|
dec modsrc+1
|
|
ldx #$0F
|
|
lda #$27
|
|
jsr .inittable
|
|
ldx #$47
|
|
lda #$87
|
|
jsr .inittable2
|
|
|
|
dec $1E00
|
|
lda #$C0
|
|
sta $10DD
|
|
sta $1EAF
|
|
sta $1F7F
|
|
|
|
ldy #0
|
|
- lda .stage2,y
|
|
sta $1D00,y
|
|
iny
|
|
cpy #.exit2-.stage2
|
|
bne -
|
|
|
|
jsr PrintByID
|
|
!byte s_bootwrite
|
|
lda #$00
|
|
sta gTrack
|
|
jsr WriteTrackNA
|
|
inc gPatchCount
|
|
|
|
.exit
|
|
jsr .cleanup
|
|
jmp Pass
|
|
|
|
.cleanup
|
|
lda $C0E8
|
|
lda #$01
|
|
sta gCommand
|
|
sta dct+1
|
|
rts
|
|
|
|
ReadChoplifter
|
|
lda #BASEPAGE
|
|
sta modsrc+1
|
|
lda #$00
|
|
sta modsrc
|
|
- jsr ReadSector ; really just seek
|
|
lda $C0E9 ; turn the drive back on
|
|
; no need for spin-up because we are fast enough
|
|
ldx #$04
|
|
lda gTrack
|
|
beq .settrack00
|
|
cmp #$12
|
|
bcc .settrack01
|
|
cmp #$16
|
|
bcc .ignore
|
|
beq .readtrack0B
|
|
cmp #$3E
|
|
bcs .checktrack1E
|
|
jsr .readtrack
|
|
inc gTrack
|
|
lda gTrack
|
|
lsr
|
|
bcs -
|
|
dec gTrack
|
|
.ignore
|
|
rts
|
|
|
|
.cancel
|
|
jsr .cleanup
|
|
jmp Cancel
|
|
|
|
.settrack00
|
|
lda #$D5
|
|
sta cmp1+1
|
|
sta cmp2+1
|
|
lda #$DD
|
|
sta cmp1+0
|
|
sta cmp2+0
|
|
!byte $2C
|
|
.settrack01
|
|
ldx #$08
|
|
|
|
.readtrack
|
|
stx tmpx
|
|
jsr $2000 ; must run from page-aligned address for precise timing
|
|
|
|
;back-up in case of read failure
|
|
|
|
lda unform+0 ; prologue 2
|
|
sta cmp2+0
|
|
lda unform+1 ; prologue 1
|
|
sta cmp2+1
|
|
lda prbuf+0 ; epilog
|
|
sta cmp1+0
|
|
lda prbuf+1 ; prologue 3
|
|
sta cmp1+1
|
|
lda moddest+1
|
|
sta modsrc+1
|
|
rts
|
|
|
|
.readtrack0B
|
|
|
|
.checkkey1
|
|
lda KEY
|
|
bmi .cancel
|
|
jsr ReadNib
|
|
- cmp #$DD
|
|
bne .checkkey1
|
|
jsr ReadNib
|
|
cmp #$F5
|
|
bne -
|
|
jsr ReadNib
|
|
cmp #$D5
|
|
bne - ; this had the same bug (see below)
|
|
ldx #$03
|
|
- jsr Read4x4
|
|
jsr Read4x4
|
|
jsr Read4x4
|
|
sta cmp1+0,x
|
|
dex
|
|
bpl -
|
|
rts
|
|
|
|
.checktrack1E
|
|
cmp #$40
|
|
bcs .checktrack20
|
|
rts
|
|
|
|
.checktrack20
|
|
beq .readtrack20
|
|
cmp #$44
|
|
beq .readtrack22
|
|
rts
|
|
|
|
.readtrack20
|
|
ldx #1
|
|
jsr .readtrack
|
|
lda (BASEPAGE<<8)+$C5
|
|
sta .readtrack20i+.prolog1+1-.reloc
|
|
lda (BASEPAGE<<8)+$CC
|
|
sta .readtrack20i+.prolog2+1-.reloc
|
|
lda (BASEPAGE<<8)+$D3
|
|
sta .readtrack20i+.prolog3+1-.reloc
|
|
ldy #$00
|
|
- lda .readtrack20i,y
|
|
sta $2100,y
|
|
iny
|
|
bne -
|
|
ldx #$60
|
|
jmp $2100 ; must run from page-aligned address for precise timing
|
|
|
|
.readtrack20i !pseudopc $2100 {
|
|
.reloc
|
|
-- jsr .readnibx
|
|
|
|
.prolog1
|
|
- cmp #$D1 ; SMC
|
|
bne --
|
|
jsr .readnibx
|
|
.prolog2
|
|
cmp #$D1 ; SMC
|
|
bne -
|
|
jsr .readnibx
|
|
.prolog3
|
|
cmp #$D1 ; SMC
|
|
bne - ; this had the same bug
|
|
.x1
|
|
-- lda $C0EC ; timing issue requires unrolling part of this
|
|
bpl --
|
|
!if >.x1 != >* {
|
|
!serious "branch crosses a page"
|
|
}
|
|
sec
|
|
rol
|
|
sta tmp
|
|
jsr .readnibx
|
|
and tmp
|
|
sta (BASEPAGE+8)<<8,y
|
|
iny
|
|
jsr .read4x4x
|
|
sta (BASEPAGE+8)<<8,y
|
|
iny
|
|
jsr .readnibx
|
|
sec
|
|
rol
|
|
sta tmp
|
|
.x2
|
|
- lda $C0EC
|
|
bpl -
|
|
!if >.x2 != >* {
|
|
!serious "branch crosses a page"
|
|
}
|
|
and tmp
|
|
sta (BASEPAGE+8)<<8,y
|
|
iny
|
|
cmp #$EA
|
|
bne --
|
|
rts
|
|
|
|
.read4x4x
|
|
- lda $C08C,x
|
|
bpl -
|
|
sec
|
|
rol
|
|
sta tmp
|
|
- lda $C08C,x
|
|
bpl -
|
|
and tmp
|
|
rts
|
|
}
|
|
|
|
.readtrack22
|
|
ldx #$40
|
|
ldy #$00
|
|
-- dey
|
|
bne +
|
|
dex
|
|
beq ++
|
|
+ ldx #$60
|
|
jsr .readnibx
|
|
- cmp #$D5
|
|
bne --
|
|
jsr .readnibx
|
|
cmp #$FF
|
|
bne -
|
|
jsr .readnibx
|
|
cmp #$DD
|
|
bne - ; this had the same bug
|
|
ldy #$00
|
|
- jsr .read4x4x
|
|
sta BASEPAGE<<8,y
|
|
iny
|
|
bne -
|
|
++ rts
|
|
|
|
.readtracki !pseudopc $2000 {
|
|
ldx #$60
|
|
lda #$E0
|
|
sta tmpa
|
|
sta tmpy
|
|
|
|
.retry
|
|
lda tmpx
|
|
sta nibcount
|
|
lda modsrc
|
|
sta moddest
|
|
lda modsrc+1
|
|
sta moddest+1
|
|
ldy #$00
|
|
--- inc tmpa
|
|
beq .inc_tmpy
|
|
jsr .readnibx
|
|
-- cmp cmp2+1
|
|
bne ---
|
|
jsr .readnibx
|
|
- cmp cmp2+0
|
|
bne --
|
|
jsr .readnibx
|
|
cmp cmp1+1
|
|
bne - ; this has a bug which is also present in the original code
|
|
; it branches to the middle nibble instead of the first one
|
|
; it allows PR0 PR1 [any] PR1 PR2 instead of requiring PR0 PR1 PR2
|
|
-- lda $C08C,x
|
|
bpl --
|
|
rol
|
|
sta tmp
|
|
- lda $C08C,x
|
|
bpl -
|
|
and tmp
|
|
sta (moddest), y
|
|
iny
|
|
bne --
|
|
asl $C000
|
|
- lda $C08C,x
|
|
bpl -
|
|
cmp cmp1+0
|
|
bne .retry
|
|
inc moddest+1
|
|
dec nibcount
|
|
bne --
|
|
jsr .readnibx
|
|
sta prbuf+1 ; prologue 3
|
|
jsr .readnibx
|
|
sta unform+0 ; prologue 2
|
|
jsr .readnibx
|
|
sta unform+1 ; prologue 1
|
|
jsr .readnibx
|
|
sta prbuf+0 ; epilog
|
|
jsr .readnibx
|
|
cmp unform+1 ; trailer epilog
|
|
bne .retry
|
|
rts
|
|
|
|
.inc_tmpy
|
|
inc tmpy
|
|
bne ---
|
|
;;something
|
|
jsr .cleanup
|
|
jmp FatalError
|
|
|
|
.readnibx
|
|
- lda $C08C,x
|
|
bpl -
|
|
rts
|
|
}
|
|
|
|
.inittable
|
|
ldy #$08
|
|
|
|
.inittable2
|
|
sta tmp
|
|
|
|
.buildtable
|
|
txa
|
|
sta (modsrc),y
|
|
dex
|
|
iny
|
|
tya
|
|
and #$0F
|
|
cmp #$0F
|
|
bne .buildtable
|
|
tya
|
|
sbc #$0F
|
|
tay
|
|
txa
|
|
sta (modsrc),y
|
|
tya
|
|
adc #$18-1 ; carry set by sbc
|
|
tay
|
|
txa
|
|
adc #$0F
|
|
tax
|
|
cmp tmp
|
|
bne .buildtable
|
|
rts
|
|
|
|
.stage2 !pseudopc $B000 { ; high address that won't be hit on the first round of SD
|
|
lda $c057
|
|
lda $c054
|
|
lda $c052
|
|
lda $c050
|
|
ldx #0
|
|
- lda $800,x
|
|
sta $B300,x
|
|
inx
|
|
bne -
|
|
ldx #$42
|
|
txs
|
|
lda #>(.resume-1)
|
|
pha
|
|
lda #<(.resume-1)
|
|
pha
|
|
jmp $4000
|
|
|
|
.resume
|
|
ldx #0
|
|
- lda .stager,x
|
|
sta $500,x
|
|
lda (*+$ff) and $ff00,x
|
|
sta $200,x
|
|
lda (*+$1ff) and $ff00,x
|
|
sta $400,x
|
|
lda $B300,x
|
|
sta $800,x
|
|
txs
|
|
inx
|
|
bne -
|
|
jsr .dostep4
|
|
ldy #2 ; pagehi, first table
|
|
sty $807
|
|
ldy #$60 ; rts
|
|
sty $84c
|
|
ldx $2b ; SD requires X=boot slot x16
|
|
jsr .callSD ; including original $8xx to $7xx
|
|
asl $807 ; 4xx, second table
|
|
jmp $500
|
|
|
|
.stager !pseudopc $500 {
|
|
jsr .callSD
|
|
jsr .step
|
|
lda #$60 ; rts
|
|
sta $801
|
|
|
|
; to enable writing requires finding three spare pages
|
|
; that is common to all games. I did not succeed.
|
|
; for that reason, auto-crack is read-only.
|
|
|
|
sta $207
|
|
|
|
lda #6
|
|
sta $27
|
|
jsr $823 ; read patch table to $600
|
|
jsr .dostep2 ; reach track $22
|
|
sta $3d
|
|
lda #4
|
|
sta $27
|
|
jsr $823 ; read high scores to $400
|
|
lda $C088,x
|
|
ldy #0 ; avoid CFFA bug (Y is not zero on return)
|
|
- lda $700,y
|
|
sta $800,y
|
|
iny
|
|
bne -
|
|
- lda $600,y
|
|
sta .patcher+1
|
|
lda $601,y
|
|
sta .patcher+2
|
|
lda $602,y
|
|
iny
|
|
iny
|
|
iny
|
|
|
|
.patcher
|
|
sta $d1d1
|
|
cmp #$ea
|
|
bne -
|
|
jmp ($20)
|
|
|
|
.callSD
|
|
sta $806 ; pagelo
|
|
ldy #$ff
|
|
jsr $805
|
|
beq .step
|
|
|
|
.dostep4
|
|
jsr .dostep2
|
|
|
|
.dostep2
|
|
jsr .step
|
|
|
|
.step
|
|
jsr $82F
|
|
lsr $40
|
|
rts
|
|
} ;$5xx
|
|
} ;$Bxxx
|
|
|
|
.exit2
|
|
}
|