Mockingboard Detection and patches for Lancaster, PitFall II & Berzap! (#63)

* Create hw.mockingboard.a

* Call HasMockingboard

* Mockingboard Detection

* Mockingboard Detection

* Mockingboard Detection update for FastChip //e

* Mockingboard Detection

* Mockingboard Detection

* Mockingboard Detection

* Add files via upload

* Mockingboard Detection

* Delete hw.mockingboard.a

* Correct location for Lancaster.a

* Pitfall II Mockingboard patch

* Add mockingboard patch to Berzap

Removed re-entry check because code is so long that it wont survive on stack. Instead have patched out the cheat2 entry so the code is only executed once.

* Changes requested by 4am

* Resolve conflicts

* Resolve conflicts
This commit is contained in:
Andrew Roughan 2020-01-30 10:52:33 +11:00 committed by GitHub
parent 36bb29b73d
commit 2a7865c91f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 175 additions and 9 deletions

View File

@ -128,6 +128,10 @@ SwitchToBank2
rts
!source "src/prodos.path.a" ; paths end up on the same page
; MockingboardSlot (label is in constants.a so prelaunchers can use it)
; slot number where Mockingboard was detected + $C0
; #$00 if no Mockingboard detected
!byte $FD ; MockingboardSlot ($FFF8)
; MachineStatus (label is in constants.a so prelaunchers can use it)
; 7 6 5 4 3 2 1 0
; | | | | | | | +- bit 0 reserved

View File

@ -167,6 +167,11 @@
dex
bpl -
jsr DisableAccelerator ; cycle counting requires 1MHz
jsr GetMockingboardSlot
stx MockingboardSlot ; save mockingboard slot in LC RAM
jsr EnableAccelerator
jmp OneTimeSetup
; ProRWTS2 has its own function to relocate itself
@ -176,6 +181,8 @@ ProRWTSBuffer
!source "src/hw.vidhd.a"
!source "src/hw.memcheck.a"
!source "src/hw.joystick.a"
!source "src/hw.mockingboard.a"
TOTAL
!text "T O T A L"
REPLAY

View File

@ -109,6 +109,7 @@ gVal = $1F81
; LC RAM 1
gCheatsAvailable = $D000 ; master cheats table, indexed by game index in gGamesListStore
; 1 byte per game, so max size = 256 games
MockingboardSlot = $FFF8
MachineStatus = $FFF9
; LC RAM 2

54
src/hw.mockingboard.a Normal file
View File

@ -0,0 +1,54 @@
;license:MIT
; By Andrew Roughan
; in the style of 4am for Total Replay
;
; Mockingboard support functions
;
;------------------------------------------------------------------------------
; GetMockingboardSlot
; detect Mockingboard card by searching for 6522 timers across all slots 7->1
; access 6522 timers with deterministic cycle counts
;
; based on prior art in Mockingboard Developers Toolkit
; with optimisation from deater/french touch
; also takes into account FastChip //e clock difference
;
; in: none
; accelerators should be off
; out:
; if card was found, X = #$Cn where n is the slot number of the card, otherwise #$00
; flags clobbered
; zp $80-$82 clobbered
; A/Y clobbered
;------------------------------------------------------------------------------
GetMockingboardSlot
lda #$00
sta $80
ldx #$C7
@slotLoop
stx $81
ldy #$04 ; 6522 #1 $Cx04
jsr timercheck
bne @nextSlot
ldy #$84 ; 6522 #2 $Cx84
jsr timercheck
bne @nextSlot
rts ; found
@nextSlot
dex
cpx #$C0
bne @slotLoop
ldx #$00 ; not found
rts
timercheck
lda ($80),y ; read 6522 timer low byte
sta $82
lda ($80),y ; second time
sec
sbc $82
cmp #$F8 ; looking for (-)8 cycles between reads
beq +
cmp #$F7 ; FastChip //e clock is different
+ rts

View File

@ -167,6 +167,19 @@
+READ_ROM_NO_WRITE
}
!macro GET_MOCKINGBOARD_SLOT {
+READ_RAM2_NO_WRITE
ldx MockingboardSlot
+READ_ROM_NO_WRITE
}
!macro GET_MACHINE_STATUS_AND_MOCKINGBOARD_SLOT {
+READ_RAM2_NO_WRITE
lda MachineStatus
ldx MockingboardSlot
+READ_ROM_NO_WRITE
}
!macro USES_TEXT_PAGE_2 {
lda ROM_MACHINEID
cmp #$06

View File

@ -1,5 +1,6 @@
;license:MIT
;(c) 2019 by qkumba
;mockingboard patch by Andrew Roughan
!cpu 6502
!to "build/PRELAUNCH/BERZAP",plain
@ -24,20 +25,67 @@ cheat1
jmp $b000
cheat2
+DISABLE_ACCEL
lda $b2cf
cmp #$2b
bne +
+GET_MACHINE_STATUS
+GET_MACHINE_STATUS_AND_MOCKINGBOARD_SLOT
and #CHEATS_ENABLED
beq +
lda #$ad
sta $3d94 ; patch - don't decrease lives
sta $6573 ; patch - don't increase lives
sta $76ba ; patch - don't increase lives
+
+ txa
beq skipmb
stx $3FCD ;Replace #$C4 with detected slot
stx $3FD5 ;Page $3F is relocated to $1F
stx $3FE1
stx $3FE6
stx $3FEB
stx $3FF0
stx $AB1D
firstPage
ldy #$32 ;Start scan at first patch $9743
- lda $9711,Y ;Find #$C4's in code (24 locations)
cmp #$C4
bne +
txa
sta $9711,Y ;Replace #$C4 with detected slot
+ iny ;Finish scan at $9811
bne -
secondPage
- lda $9811,Y ;Find #$C4's in code (17 locations)
cmp #$C4
bne +
txa
sta $9811,Y ;Replace #$C4 with detected slot
iny ;Skip next 2 bytes after a match because there is never another match so close
iny
+ iny ;Finish scan at $9911 = (last patch 990E)+3
;Check math: 9911-9743=1CE code length; 00 index end - CE code length = 32 index start
bne -
thirdPage
ldy #$7B ;Start scan at first patch $ACE0
- lda $AC65,Y ;Find #$C4's in code (21 locations)
cmp #$C4
bne +
txa
sta $AC65,Y ;Replace #$C4 with detected slot
iny ;Skip next 2 bytes after a match because there is never another match so close
iny
+ iny ;Finish scan at $AD65 = (last patch AD62)+3
;Check math: AD65-ACE0=85 code length; 00 index end - 85 code length = 7B index start
bne -
skipmb
lda #$6C ;Remove patch from code so it is only run once
sta $B20B
lda #$CE
sta $B20C
lda #$B2
sta $B20D
+DISABLE_ACCEL
jmp ($b2ce)
!if * > $1C0 {
!if * > $1F0 {
!error "code is too large, ends at ", *
}

View File

@ -7,9 +7,10 @@
!source "src/prelaunch/common.a"
+GET_MACHINE_STATUS
+GET_MACHINE_STATUS_AND_MOCKINGBOARD_SLOT
and #CHEATS_ENABLED
sta cheat+1
stx mbslot+1
lda #<cheat
sta $10da
lda #>cheat
@ -24,6 +25,23 @@ cheat
sta $1661
sta $1476
+
mbslot
ldx #0 ; SMC (will be non-zero if mockingboard slot is valid)
beq skipmb
stx $6609 ;Replace #$C4 with configured slot
ldy #$20 ;Start scan at $6720
-
lda $6700,Y ;Find #$C4's (21 locations) in code
cmp #$C4
bne +
txa
sta $6700,Y ;Replace #$C4 with configured slot
; iny ;potential optimisation to finish quicker
; iny ;not tested
+ iny ;Finish scan at $67FF
bne -
skipmb
jmp $1000
!if * > $1C0 {

View File

@ -11,9 +11,30 @@
lda #$60
sta $3D34
jsr $0800 ; decompress
+GET_MOCKINGBOARD_SLOT
txa
beq skipmb
stx $2E5B ;Replace #$C4 with detected slot
stx $2E5E
stx $2E67
stx $2E6A
ldy #$92 ;Start scan at first patch $2F1C
- lda $2E8A,Y ;Find #$C4's in code (20 locations)
cmp #$C4
bne +
txa
sta $2E8A,Y ;Replace #$C4 with detected slot
iny ;Skip next 2 bytes after a match because there is never another match so close
iny
+ iny ;Finish scan at $2F8A = (last patch 2F87)+3
;Check math: 2F8A-2F1C=6E code length; 00 index end - 6E code length = 92 index start
bne -
skipmb
+RESET_VECTOR reset
+DISABLE_ACCEL
jmp $6000
jmp $6000 ;612A copies pages 2E & 2F to AE & AF for final location
reset
+READ_RAM2_NO_WRITE