Preserving a Hi-Score on NES

So I was at work thinking to myself. I said to myself, I says, “Self, what was it that you had heard about that one time… you know, about preserving a hi score on NES in the 700 page of RAM?”

What I’m babbling about, is this. You know how you play some game that has a hi score feature in it, but if you press reset, the hi score is still there? Well, oddly enough I never put much thought into it. But tonight it popped into my head, and I figured out how to do it. I remember someone telling me that the way you can do it is by having a space in RAM set aside that you don’t erase at the reset routine, and fill it with specific bytes. When it gets reset after those bytes are fed into it, you test them against the same bytes in ROM, and if they match, you don’t zero out the hi score. I don’t know if that sounds confusing, but here’s the code I came up with:

; in the declarations, of course
ram_check		=	$700
hi_ten			=	$706
hi_hundreds		=	$707
hi_thousands		=	$708
hi_ten_thousands	=	$709
hi_hun_thousands	=	$70a

; this is in ROM
rom_check:					; The string that gets put in RAM for
	.byte "SLYDOG"				; the hi score check

; and the actual subroutine that happens at reset
slydog_ram_check:
	ldx #$00
@start_ram_check:
	lda ram_check, x			; compare the RAM starting at $700 to
	cmp rom_check, x			; the ROM at rom_check
	beq @fill_ram_check			; if one of the bytes don't match
		ldx #$00			; throw zero back in the X register
@write_rom_ram:
		lda rom_check, x		; load a byte from rom_check
		sta ram_check, x		; store it in ram_check
		inx				; increment X and repeat until
		cpx #$06			; X is 6
		bne @write_rom_ram
			lda #$00		; Now throw a zero in all of the
			sta hi_ten		; hi score bytes. This means it
			sta hi_hundreds		; was a hard power up, so there is
			sta hi_thousands	; no hi score saved. If we don't do
			sta hi_ten_thousands	; this, the NES will print garbage
			sta hi_hun_thousands	; on-screen as the hi score
			jmp @done_check		; routine is done
@fill_ram_check:
	inx					; if the original comparison matched
	cpx #$06				; then we increment X six times
	bne @start_ram_check			; to be sure the whole string matches
@done_check:
	rts					; and we're outta here

It seems to work for me fairly well. It can also be used in other pages of RAM. I had heard that the 700 page was for stuff that needed to be saved, but it works in other places I tested. Anyway, I just thought it was cool and that I’d share : )

Leave a Reply