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