; Pengo High-score Save - JROK Feb. 2000
; --------------------------------------
;
; Target assembler is - TASM Version 3.1 February, 1998.
;
;
;
; Notes:
;
; Save scores to unused RAM at $8A00 ( lots and lots of unused RAM !! )
; Patch code lives at $4D00 in ROM IC21
;
;
; ROM order
; ---------
;
; 0000-0FFF - IC8
; 1000-1FFF - IC7
; 2000-2FFF - IC15
; 3000-3FFF - IC14
; 4000-4FFF - IC21
; 5000-5FFF - IC20
; 6000-6FFF - IC32  
; 7000-7FFF - IC31
;
;
;
;
;
;
; Game Patches
; ------------
;
;
; Theory:
;
; 1. Intercept high-score clearing and restore high-score table
; from NVRAM if checksum matches.
;
; 2. Write high-score table to NVRAM at the end of entering Initials
; two points are intercepted
; - user enters all 3 digits
; - music/timer runs out )
;
;
; 3. 1P + 2P start held down during power on will RESET the high-score
; table back to the defaults.
;
;
;
; -----------------------
; ROM PATCHES
; -----------------------
;
;
; $0F13 = Return from whole ROM checksum test - totally not needed )
; $21 -> $C9
;

; $1051 = Force RAM test start at $8c00
; $88 -> $8c 
;

; $10f7 = RAM testing, tests $800 bytes - change to test only $400
; $08 -> $04 (only test 1k)
;
; $2540 = jump to $4d00 - restore or reset high-score table from NVRAM
; $21 00 00 -> $c3 00 4d
;
; $2644 = call to $4d03 - save high-score to NVRAM at end of enter intials
; $cd d1 28 -> $cd 03 4d
;
;
; $270e = call to $4d03 - save high-score to NVRAM at end of enter intials
; when timer/music ends
; $cd d1 28 -> $cd 03 4d
;
;
; $7ff8 = 83 - checksum fix ROM0/1 ( ic8 & 7 )
; $7ffa = b1 - checksum fix ROM2/3 ( ic15 & 14 )
; $7ffc = a1 - checksum fix ROM4/5 ( ic21 & 20 )
; $7ffe = A9 - checksum fix ( popcorn music )
; c3 - checksum fix ( alternate music )
;
;
;
;
;
;
;
; High score table format in NVRAM
; --------------------------------
;
; 2 bytes for 16bit checksum
;
; NN NN - 2 bytes score value
; LL - 1 byte level
; xx xx xx - 3 bytes initials
; _________ 
; total 6 * 5 entries = 30 bytes for HST
;
;
;
; High-score table saved to NVRAM at $8A00 
; - there's very little of the $8800-$8fff RAM used
; so this is a good place to put it
;
;
;
;
; ----------------------------------------------------------



; this is the return jump back to the end of entering
; high-score initials in the game rom
; see patch $2644 $270e


END_OF_HST_RTN .equ $28d1



; There are HUGE area's of free space in the pengo
; ROMset so $4d00 is totally free for use.
; There's so much free you could probably put
; another game in there.



.org $4d00



; jump table for routines to call


jp check_HST ; $4d00 
jp write_HST ; $4d03 
jp restore_HST ; $4d06 


;-----------------------
check_HST:
;-----------------------

ld a, ( $9080 )     ; switch inputs ( low = active )
and $60             ; mask off unwanted bits
jr z, reset_hst     ; 1p + 2p together at power on = reset scores



call HST_chksum     ; de = 16bit checksum
ld hl, ( $8a00 )
ld a, l
cp e
jr nz, reset_hst    ; checksum failiures

ld a, h
cp d
jr z, restore_HST   ; checksum OK



;-----------------------
reset_hst:
;-----------------------
; reset the HST and store it !


ld hl,0             ; '0' for top scores
call $2543          ; call to clear/reset the HS
ld hl, ( $8858 )    ; top score spot ( 5th entry )
ld (8810h), hl      ; put HS on screen


call save_the_HST   ; save HS table & return
ret



;-----------------------
write_HST:
;-----------------------



; 270e & 2644 calls to 2d81 are revectored to this
; routine which should exit by jumping to $2d81


call save_the_HST
jp END_OF_HST_RTN    ; exit through jump




;-----------------------
save_the_HST:
;-----------------------

; write the HS table into NVRAM

push af
push bc
push de
push hl

ld de, $8a02     ; destination in NVRAM
ld bc, 5 * 6     ; size of HS table
ld hl, $8840     ; number of entries
ldir             ; copy the names to the NVRAM at $8A00

call HST_chksum 
ld ( $8a00 ), de ; set the HST checksum 


pop hl
pop de
pop bc
pop af
ret


;-----------------------
HST_chksum: 
;-----------------------
ld b, 6 * 5 ; number of High-score entries

ld c, 0         ; used as temp register
ld de, 255      ; start value for checksum
ld hl, $8A02    ; high-score table in NVRAM
    
hstck_nextb:
ld a,e          ; 16bit add
add a,(hl)
ld e,a
ld a,d
adc a,c
ld d,a
inc hl
djnz hstck_nextb 

; de = 16bit checksum ( overkill ?? ) ;-)

ret

;-----------------------
restore_HST:
;-----------------------

; copy the names FOR the NVRAM to the HS Table

ld hl, $8a02     ; location in NVRAM
ld bc, 5 * 6     ; size of HS table
ld de, $8840     ; destination
ldir 

ld hl, ( $8858 ) ; top score spot ( 5th entry )
ld (8810h), hl   ; make HS on screen

ret 

.end