News: 11 March 2016 - Forum Rules

Author Topic: Donkey Kong (NES) - Bonus Timer Fix?  (Read 2169 times)

SMB2J-2Q

  • Full Member
  • ***
  • Posts: 135
    • View Profile
Donkey Kong (NES) - Bonus Timer Fix?
« on: May 17, 2020, 07:13:07 pm »
http://www.donhodges.com/how_high_can_you_get.htm

We all remember that on the arcade Donkey Kong, the bonus timer goes bonkers the moment skilled players reach level 22. At first, the timer shows 100 points, then it counts down from "4000," but in reality there are only 400 points ticking away because 260 (computed from (22*10)+40) is higher than 256 by 4.

How the bonus timer for the arcade DK was originally computed:
Code: [Select]
0F7A - 3A 29 62 - LD A,(#6229) ; load A with level number
0F7D - 47       - LD B,A       ; copy A into B
0F7E - A7       - AND A        ; perform bitwise AND of A with A (or, clear the carry flag)
0F7F - 17       - RLA          ; rotate left the bits in A
0F80 - A7       - AND A        ; perform bitwise AND of A with A
0F81 - 17       - RLA          ; rotate left the bits in A
0F82 - A7       - AND A        ; perform bitwise AND of A with A
0F83 - 17       - RLA          ; rotate left the bits in A
0F84 - 80       - ADD A,B      ; A = A + B
0F85 - 80       - ADD A,B      ; A = A + B
0F86 - C6 28    - ADD A,#28    ; A = A + #28 (40 decimal)
0F88 - FE 51    - CP #51       ; is A ≥ #51 (81 decimal)?
0F8A - 38 02    - JR C,#0F8E   ; no, then skip ahead to #0F8E
0F8C - 3E 50    - LD A,#50     ; yes, then A = #50 (80 decimal)
0F8E - 21 B0 62 - LD HL,#62B0  ; load HL address to store the result

Don Hodges was able to come up with a hack that changes how the bonus timer is computed. His fix involved removing the instruction that checked to see if the value stored in A for the timer went higher than 80, and if it did, to force it back down to 80, and changed it so that the check involved deriving the maximum bonus points from the level number instead; if the level number was higher than 4 in this new check, to keep it at 4, which now means the timer will always count down from 8000 on levels 4 and up:
Code: [Select]
0F7A - 3A 29 62 - LD A,(#6229) ; load A with level number
0F7D - FE 04    - CP #04       ; is the level ≥ 4?
0F7F - 38 02    - JR C,#0F83   ; if not, jump ahead and compute bonus normally
0F81 - 3E 04    - LD A,#04     ; if it is, then set A = 4
0F83 - 47       - LD B,A       ; copy A into B
0F84 - A7       - AND A        ; clear the carry flag
0F85 - 17       - RLA          ; rotate left the bits in A
0F86 - A7       - AND A        ; clear the carry flag
0F87 - 17       - RLA          ; rotate left the bits in A
0F88 - A7       - AND A        ; clear the carry flag
0F89 - 17       - RLA          ; rotate left the bits in A
0F8A - 80       - ADD A,B      ; A = A + B
0F8B - 80       - ADD A,B      ; A = A + B
0F8C - C6 28    - ADD A,#28    ; A = A + #28 (40 decimal)
0F8E - 21 B0 62 - LD HL,#62B0  ; load HL address to store the result   

The bonus timer on the NES version of Donkey Kong behaves the same way.
http://metopal.com/2012/03/24/porting-the-kill-screen/

But how it is computed is obviously different:
Code: [Select]
CB7E - A4 54    - LDY $54     ;
CB80 - C8       - INY         ;
CB81 - 20 D1 F4 - JSR $F4D1   ;
...
; set initial bonus value
; if the level number stored in Y is lower than 4,
; load the bonus value from memory (C207,Y)
; else, cap it at 8000
CB88 - A9 80    - LDA #$80    ;
CB8A - 88       - DEY         ;
CB8B - C0 04    - CPY #$04    ;
CB8D - 10 03    - BPL $CB92   ;
CB8F - B9 07 C2 - LDA $C207,Y ;
CB92 - 85 2E    - STA $2E     ;

The kill screen for level 133 is done is due to the byte $80, since this begins the two's complement cycle (-127 to 127). Since level 133 is given as byte $84, subtracting 4 ($04) from this value yields $80. What I want to do is change this so that the check does not trigger the two's complement rule.

Additionally, there is also a fifth bonus value stored in the instruction beginning at $C207: $90, for 9000 points.
Code: [Select]
C207 - .BYTE $50
C208 - .BYTE $60
C209 - .BYTE $70
C20A - .BYTE $80
C20B - .BYTE $90

Why it's there, I don't know. But you can make this happen on levels 5 and up by doing two alterations:
Code: [Select]
CB88 - A9 90     - LDA #$90    ;
CB8A - 88        - DEY         ;
CB8B - C0 05     - CPY #$05    ;
Doing these two changes also mean the kill screen will now be on level 134 ($85). On level 133, just as on level 22 in the arcade version, the timer will also behave graphically odd, which is the other reason I am hoping to fix this so the timer will always count down from 9000 - without being glitchy - on levels 5 and up.

Thank you,



Ben
« Last Edit: May 17, 2020, 07:56:33 pm by SMB2J-2Q »

Euyira

  • Jr. Member
  • **
  • Posts: 14
  • I am not nice. :|
    • View Profile
Re: Donkey Kong (NES) - Bonus Timer Fix?
« Reply #1 on: August 05, 2020, 11:40:19 pm »
Not sure if you'll see this, but to fix the kill timer

Code: [Select]
Japan
 00:CB88: A9 80     LDA #$80
 00:CB8A: 88        DEY
 00:CB8B: C0 04     CPY #$04
 00:CB8D: B0 03     BCS $CB92  --  fix
 00:CB8F: B9 07 C2  LDA $C207,Y
 00:CB92: 85 2E     STA $2E

Code: [Select]
World Rev 1
 00:CB94: A9 80     LDA #$80
 00:CB96: 88        DEY
 00:CB97: C0 04     CPY #$04
 00:CB99: B0 03     BCS $CB9E  --  fix
 00:CB9B: B9 07 C2  LDA $C207,Y
 00:CB9E: 85 2E     STA $2E

Code: [Select]
Original Edition USA, Europe
 01:CB94: A9 80     LDA #$80
 01:CB96: 88        DEY
 01:CB97: C0 04     CPY #$04
 01:CB99: B0 03     BCS $CB9E  --  fix
 01:CB9B: B9 07 C2  LDA $C207,Y
 01:CB9E: 85 2E     STA $2E

BPL (signed compare) ==> BCS (unsigned compare)