New Program Code
Kong Junior shares a lot of base code with Donkey Kong,
this too made adding the high-score save much easier, some of the patches were
exactly the same. Like Kong the high-score table could support 12 character
names, but was limited to only 3, so it was expanded to take the full width (
hey ! if it's there why not just use it !! )
Size Constraints
The amount of free space in Kong Junior was a little less than Donkey Kong, I removed the checksum routine from the code to cut down the code a little more. I might revisit and see about squeezing it back in.
Patches
Patching this game is a little more interesting, the boardset uses a PAL or PROM to do the ROM decoding, so the ROMs don't appear in linear order. I've included the decoding table for which ROMs appear when in the memory map.
EEPROM routines fit at $3F39 and the save/restore code
at $3565. For reference the location $3565 used to contain the default
high-score table that was restored on power-up. Because this is now all done in
code it could simply be removed and used to store the new routines.
Full Source + Patch Comments
The source was compiled using "TASM Z80 Assembler. Version 3.1 February, 1998.
Copyright (C) 1998 Squak Valley Software"
Features Added
; -------------------------------------------------------------- ; Donkey Kong Jr. High-Score save & Serial EEPROM driver ; -------------------------------------------------------------- ; ; - Version 1.0 ; - Another JROK production ; - Feb 6st JAN 2001 ; ; Note: this code has been written purely to keep size to a ; minimum, so some of it may appear a little bizarre but it ; saves bytes.. trust me on that ;-) ; ; -------------------------------------------------------------- ; - code designed for STM - M93C56 / M93C66 - serial EEPROM ; - National NM93c56A / NM93c66A <- 'A' is very important !! ; - Microchip 93lc56A / 93lc66 <- not the 'B' part ; - any other 93C56/66 device ; - which supports 8bit read/write ; -------------------------------------------------------------- ; ; Notes: with 94C66 ; ; A8 is always set to '1' on read/write, this address bit is unused on ; the 93C56, with the 93c66 the data is written to $100-$1AA ; ; ; ; ; ; -------------------------------------------------------------- ; ROM decoding Notes: ; -------------------------------------------------------------- ; ; ; ROM decoding is carried out via a PAL/PROM which means the ; memory map is not ROM contiguous. ; ; This is a breakdown of the decoding of linear memory address ; space and where each ROM appears in that space. ; ; ; -------------------------------------------------------------- ; Memory Order ; -------------------------------------------------------------- ; ; location ROM offset ; ; 0000-1000 - 5b - 0000-0FFF ; 1000-17FF - 5c - 1000-17FF ; 1800-1FFF - 5e - 1800-1FFF ; 2000-27FF - 5c - 0000-07FF ; 2800-2FFF - 5e - 0800-0FFF ; 3000-4000 - 5b - 1000-1FFF ; 4000-47FF - 5e - 0000-07FF ; 4800-4fff - 5c - 0800-1000 ; 5000-57ff - 5e - 1000-17FF ; 5800-5fff - 5c - 1800-1FFF ; ; -------------------------------------------------------------- ; ROM offset order ; -------------------------------------------------------------- ; ; location ROM offset ; 0000-1000 - 5b - 0000-0FFF ; 3000-4000 - 5b - 1000-1FFF ; ; 2000-27FF - 5c - 0000-07FF ; 4800-4fff - 5c - 0800-1000 ; 1000-17FF - 5c - 1000-17FF ; 5800-5fff - 5c - 1800-1FFF ; ; 1800-1FFF - 5e - 1800-1FFF ; 2800-2FFF - 5e - 0800-0FFF ; 4000-47FF 5e - 0000-07FF ; 5000-57ff - 5e - 1000-17FF ; ; ; -------------------------------------------------------------- ; patch into ROM 5B ; -------------------------------------------------------------- ; ; $1C6 - sets on screen "high score" ; - patch to call 'restore high-scores' @$25B ; - $cd 25 0b ; ; $1CA - start location of copy changed ( $1B2 -> $1b8 ) = $b8 ; $1CD - length of copy changed ( 9 bytes -> 3 bytes ) = $03 ; ; $25A - old initialize HS Table now just a return ( $C9 - ret ) ; $25b - new call to restore high-scores and set on-screen HS ; ; $25a c9 ret ; $25b cd 65 35 call 3565h ; call restore or initialize ; $25e 21 1d 61 ld hl, 611Dh ; $261 c9 ret ; ; ; $3565 - Save Scores Code ; $3F39 - EEPROM routines ; ; -------------------------------------------------------------- ; Patch in to 5C ; -------------------------------------------------------------- ; ; $14A6: 1E 3C <- high-score time ( 60 seconds ) ; $14CD: F3 <- subract to start of initials ; ; $15d4 - number of initials to copy to high-score table ; changed to 12 digits ; ; $15F3 - calls save_inits (ROM 5B) - jp $3567 ; c3 67 35 ; ; ; ; $1557: 88 68 <- high-score data end of entry area ; $1558: 75 74 for 12 digits ; ; $373D: 3F 2D <- underscore characters ; $373E: 0 2D ; $373F: 0 2D ; $3740: 0 2D ; $3741: 0 2D ; $3742: 0 2D ; $3743: 0 2D ; $3744: 0 2D ; $3745: 0 2D ; $3746: 0 3F <- end of string marker ; ; -------------------------------------------------------------- ; -------------------------------------------------------------- ; Kong Jr High Score Saver ; -------------------------------------------------------------- INo .EQU $7C00 ; 7c82 = Q2 -clock ; 7c83 = Q3 -serial data in ; 7c87 = Q7 -Select (hl) ; 7c00 = ( bit 7 ) serial data out read port ; note - only bit zero of latches are used to set ; output. ; Within the EEPROM routines ; 'l' bit zero will always be high and ; 'h' bit zero will always be low ; ; to save a few byts 'h' and 'l' are written to ; the latches to set output ( high or low ) .DEFINE cs_active ld ( hl ), l .DEFINE cs_inactive ld ( hl ), h .org $3565 jr CHECK_HST ; $3565 jr SAVE_INITS ; $3567 ; ------------------------------------------------------------------------ CHECK_HST: ; ------------------------------------------------------------------------ call enable_write ; always enable the write ; check for 1p & 2p start + 1p JUMP held down ; if all held down then reset the high-score table ld a, ( $7d00 ) and $0C ld c,a ld a, ( $7c00 ) and $10 or c cp $1C jr z, RESET_HST ld c,0 ; read call READ_WRITE_HST ; read in the HST ld a, ( $6100 ) cp $94 ; first byte must be $94 ret z ; ; no checksum on this version ; just the above check to set $94 is the ; first byte of the seriall EEPROM ; jr nz, RESET_HST ; ret ; ------------------------------------------------------------------------ RESET_HST: ; ------------------------------------------------------------------------ ; free 7 bytes move to $259 ( call addy ) ld hl, $6100 ld a, 1 ld c, $94 ld e, $F4 chr_next_entry: ld ( hl ), c inc hl ld ( hl ), $77 ; screen address inc hl ld ( hl ),a ; 1st inc hl ld b, 4 ; spaces cht_l0: ld ( hl ) , $10 inc hl djnz cht_l0 ; score digits ld b, 6 cht_l1: ld ( hl ) ,0 inc hl djnz cht_l1 ld b, 14 ; NAME cht_l2: ld (hl), $10 inc hl djnz cht_l2 ld ( hl ), $3F ; end of text char inc hl ld b, 4 cht_l3: ld ( hl ) , 0 ; score value inc hl djnz cht_l3 ld ( hl ), e ; end address inc hl ld ( hl ), $76 inc hl inc c inc c inc e inc e inc a cp 6 jr nz, chr_next_entry ; now save the HST ; ------------------------------------------------------------------------ SAVE_HS_TABLE: ; ------------------------------------------------------------------------ ld c, 1 ; read/write ;c = 0 read ;c = 1 write ; ------------------------------------------------------------------------ READ_WRITE_HST: ; ------------------------------------------------------------------------ ld de, $6100 rw_hst_lop0: ld b,e ld a,c and a jr z, dord dowr: ld a, ( de ) call write_a_byte jr cntn dord: call get_a_byte ld ( de ),a cntn: inc de ld a,e cp $aa ; address 0 to $AA jr nz, rw_hst_lop0 ld a,c and a ret z ret ; ------------------------------------------------------------------------ SAVE_INITS: ; ------------------------------------------------------------------------ ; called FROM #15F3 call SAVE_HS_TABLE ld de, $31a ; Name has been registered ret ; ------------------------------------------------------------------------ start_bit: ; ------------------------------------------------------------------------ ld ( ix + 01 ), l ; start bit !! ; ------------------------------------------------------------------------ do_clock: ; ------------------------------------------------------------------------ ld ( ix + 00 ), l ; clock high ld ( ix + 00 ), h ; clock low ret ; ------------------------------------------------------------------------ send_op_code: ; ------------------------------------------------------------------------ ld hl, $7c87 ; Select l=1 h=0 ld ix, $7c82 ; Clk/Data cs_active call start_bit ; A reg. bit 7 & 6 = opcode call send_opc send_opc: rlca ld ( ix + 01 ), a jr do_clock ; ------------------------------------------------------------------------ ; UPPER SECTION OF CODE ; ------------------------------------------------------------------------ .org $3f39 ; ------------------------------------------------------------------------ write_a_byte: ; ------------------------------------------------------------------------ ; b = address (0-255) ; a = value to write push af ld a, $40 ; 12 345 call send_op_and_address pop af wb_sb: call send_8_bits cs_inactive ; signal do write jr wait_end ; ------------------------------------------------------------------------ get_a_byte: ; ------------------------------------------------------------------------ ; b = address to read ; a = value read ld a, $80 call send_op_and_address push bc ld b,8 gb_lop0: call do_clock ; 1st bit = dummy bit ld a, ( INo ) rlca rl c djnz gb_lop0 ld a,c xor 255 pop bc jr we_end ; cs_inactive ; signal done ; ret ; ------------------------------------------------------------------------ send_op_and_address: ; ------------------------------------------------------------------------ call send_op_code call start_bit ; write A8 of address ; unused on 93c56 on 93C66 ; data is stored at $100->$1AA ld a,b ; 8 remaining bits of address ; ------------------------------------------------------------------------ send_8_bits: ; ------------------------------------------------------------------------ ; a = byte to send ld b, 8 sb_lop1: rlca ld ( ix + 01 ), a call do_clock djnz sb_lop1 ret ------------------------------------------------------------------------ enable_write: ; ------------------------------------------------------------------------ xor a call send_op_code dec a ; a= 11111111 ld b,9 ; enable opcode call sb_lop1 ; write 9 bits jr we_end ; ** old code ** the above saves 2 bytes ;-) ;ld a, $C0 ;call send_8_bits ;call do_clock ; do a clock - does not matter state of bit ;jr we_end ;------------------------------------------------------------------------ wait_end: ;------------------------------------------------------------------------ cs_active ; when Q = low ( data=high ) ; Q = high ( data=low ) we_wait: ld a, ( INo ) ; bit7 = (0=1) (1=0) 1= EEPROM write busy rlca jr c, we_wait ; loop while 1 we_end: cs_inactive ; disable EEPROM ret .end |