Published on: Februrary 17, 2025
Initially, I planned to build a Snake game, but after facing challenges with movement, I switched to a simpler guessing game called Lucky Digits. This project was exciting and challenging as I explored low-level programming, ROM routines, and memory manipulation.
START:
LDA $FE ; Load random value from memory
AND #$07 ; Mask out upper bits, keeping values 1-5
CLC
ADC #$01 ; Ensure within range 1-5
STA random_number
GET_NUMBER:
LDA #$00 ; Clear value
STA value
JSR CHRIN ; Get input character
CMP #$30 ; Ensure valid digit ('0')
BCC GET_NUMBER
CMP #$36 ; Ensure valid digit ('5')
BCS GET_NUMBER
SEC
SBC #$30 ; Convert ASCII to binary
STA value
JSR CHROUT
CORRECT:
LDA #$05 ; Green color
JSR SET_COLOR
JMP END_GAME
INCORRECT:
LDA #$02 ; Red color
JSR SET_COLOR
JMP GUESSNUMBERS
SET_COLOR:
LDY #$00
STY SCRN_PTR
LDX #$02
STX SCRN_PTR_H
LDX #$04 ; Pages to fill
fill_screen:
STA (SCRN_PTR),Y
INY
BNE fill_screen
INC SCRN_PTR_H
DEX
BNE fill_screen
RTS
Working with assembly requires a deep understanding of memory operations. Debugging was particularly difficult as there were no built-in debugging tools. Managing screen color changes required careful memory handling. I experimented with ROM routines before implementing this lab.
Building Lucky Digits was a fascinating experience in low-level programming. I plan to improve this game with animations and remain enthusiastic about eventually implementing a Snake game.
; Lucky Digits - Infinite Guessing Game with Color Change
; If correct, screen turns GREEN
; If incorrect, screen turns RED
; ROM routine entry points
define SCINIT $ff81 ; initialize/clear screen
define CHRIN $ffcf ; input character from keyboard
define CHROUT $ffd2 ; output character to screen
define SCREEN $ffed ; get screen size
define PLOT $fff0 ; get/set cursor coordinates
; Constants
define random_number $0082; Define random variable
define value $23 ; Temporary storage for user input
define color $24 ; Color variable
; Zero-page variables
define PRINT_PTR $00
define PRINT_PTR_H $01
define SCRN_PTR $03
define SCRN_PTR_H $04
; Start of program
jsr PRINT ; Print title
dcb "L","u","c","k","y",32,"D","i","g","i","t","s",00
START:
LDA $FE ; Load random value from memory
AND #$07 ; Mask out upper bits, keeping only values 1-5
CLC
ADC #$01 ; Ensure it's within 1-5
STA random_number ; Store valid random number
LDA #$02
STA color
; Main game loop
GUESSNUMBERS:
jsr PRINT
dcb $0d,"C","a","n",32,"y","o","u",32,"c","r","a","c","k",32,"t","h","e",32,"c","o","d","e","?",$0d
dcb "P","i","c","k",32,"a",32,"l","u","c","k","y",32,"n","u","m","b","e","r","!",$0d
dcb "E","n","t","e","r",32,"a",32,"n","u","m","b","e","r",32,"b","e","t","w","e","e","n",32,"0","-","5",":",32,32,00
GET_NUMBER:
LDA #$00 ; Clear value
STA value
JSR CHRIN ; Get input character
CMP #$30 ; Ensure valid digit ('0')
BCC GET_NUMBER
CMP #$36 ; Ensure valid digit ('5')
BCS GET_NUMBER
SEC
SBC #$30 ; Convert ASCII to binary
STA value ; Store input
jsr CHROUT
lda random_number
cmp value
beq CORRECT ; Correct guess
jmp INCORRECT
; Correct guess - Turn screen GREEN
CORRECT:
jsr PRINT
dcb $0d,"B","r","a","v","o","!",32,"Y","o","u",32,"f","o","u","n","d",32,"t","h","e",32,"l","u","c","k","y",32,"d","i","g","i","t","!",00
lda #$05 ; Green color
jsr SET_COLOR
jmp END_GAME
; Incorrect guess - Turn screen RED, game continues
INCORRECT:
jsr PRINT
dcb $0d,"N","o","t",32,"q","u","i","t","e","!",32,"T","r","y",32,"a","g","a","i","n",46,46,46,00
lda #$02 ; Red color
jsr SET_COLOR
jmp GUESSNUMBERS ; Loop back to guessing
END_GAME:
jsr PRINT
dcb $0d,"W","e","l","l",32,"p","l","a","y","e","d","!",32,"T","h","a","n","k","s",32,"f","o","r",32,"p","l","a","y","i","n","g",32,"L","u","c","k","y",32,"D","i","g","i","t","s","!",00
RTS
; Color Fill Routine
SET_COLOR:
ldy #$00
sty SCRN_PTR
ldx #$02
stx SCRN_PTR_H
ldx #$04 ; Pages to fill
fill_screen:
sta (SCRN_PTR),y
iny
bne fill_screen
inc SCRN_PTR_H
dex
bne fill_screen
rts
; Print Routine
PRINT:
pla
clc
adc #$01
sta PRINT_PTR
pla
sta PRINT_PTR_H
tya
pha
ldy #$00
print_next:
lda (PRINT_PTR),y
beq print_done
jsr CHROUT
iny
jmp print_next
print_done:
tya
clc
adc PRINT_PTR
sta PRINT_PTR
lda PRINT_PTR_H
adc #$00
sta PRINT_PTR_H
pla
tay
lda PRINT_PTR_H
pha
lda PRINT_PTR
pha
rts