Skip to content

Instantly share code, notes, and snippets.

@yackx
Created December 4, 2021 17:10
Show Gist options
  • Save yackx/260a648f179e2949c5b838391b3684a1 to your computer and use it in GitHub Desktop.
Save yackx/260a648f179e2949c5b838391b3684a1 to your computer and use it in GitHub Desktop.
FizzBuzz programming interview - 8 bits assembler MOS6502 for C64 ๐Ÿ’พ๐Ÿ‘ด
; The infamous FizzBuzz programming interview
;
; Youri Ackx
; assmbler=dasm
;
include "upstart.dasm"
processor 6502
PRINT_PTR equ $10 ; Print string at address
COUNT_TO equ 100 ; How much of FizzBuzz
; Main FizzBuzz loop
;
; 3 individual counters are used for FIZZBUZZ, FIZZ and BUZZ
; since the CPU does not have division instruction.
; Each counter is reset when the correspoding buzzword is reached.
; In case FIZZBUZZ is reached, the 2 other counters are reset
; as well as they collide (divisible by 15 -> divisible by 3 and by 5).
;
fizz_buzz: subroutine
ldx #1 ; Current number
.check_fizz_buzz
lda FIZZ_BUZZ
bne .check_fizz
lda #<FIZZ_BUZZ_STR ; It's FIZZBUZZ, print it
sta PRINT_PTR
lda #>FIZZ_BUZZ_STR
sta PRINT_PTR+1
jsr print_str
lda #15 ; Reset FIZZBUZZ counter
sta FIZZ_BUZZ
lda #3 ; Special case for FIZZBUZZ:
sta FIZZ ; it collides with FIZZ and BUZZ
lda #5 ; so we also reset those counters
sta BUZZ
jmp .next
.check_fizz
lda FIZZ
bne .check_buzz
lda #<FIZZ_STR ; It's FIZZ, print it
sta PRINT_PTR
lda #>FIZZ_STR
sta PRINT_PTR+1
jsr print_str
lda #3 ; Reset FIZZ counter
sta FIZZ
jmp .next
.check_buzz
lda BUZZ
bne .number
lda #<BUZZ_STR ; It's BUZZ, print it
sta PRINT_PTR
lda #>BUZZ_STR
sta PRINT_PTR+1
jsr print_str
lda #5 ; Reset BUZZ counter
sta BUZZ
jmp .next
.number ; It's regular number
txa
pha
jsr print_int8
pla
tax
.next
inx ; Next number
dec FIZZ_BUZZ ; Decrement all 3 counters
dec FIZZ
dec BUZZ
cpx #COUNT_TO ; Done?
bne .check_fizz_buzz
rts
; Buzzwords counters. Initialized as value-1 because we start counting from 1
FIZZ byte 2
BUZZ byte 4
FIZZ_BUZZ byte 14
; Buzzwords strings
FIZZ_STR dc "FIZZ", 32, 0
BUZZ_STR dc "BUZZ", 32, 0
FIZZ_BUZZ_STR dc "FIZZBUZZ", 32, 0
; Print the string at PRINT_PTR
; IN PRINT_PTR
; DIRTY A Y
print_str: subroutine
ldy #0
.loop lda (PRINT_PTR),Y
beq .done
jsr $ffd2
iny
jmp .loop
.done rts
; Print the integer contained in A
;
; Achived by successive substractions of 100, then 10, then 1
; IN A
; DIRTY A X Y
print_int8: subroutine
ldx #0 ; Index UNITS
ldy #0 ; Always 0
sty .DIGIT
.loop
cmp .UNITS,X ; Number smaller than unit?
bcc .print_digit ; Yes? Print it
sec ; No?
sbc .UNITS,X ; -Decrease number by current unit
inc .DIGIT ; -Increase digit
jmp .loop
.print_digit
pha
lda .DIGIT
clc
adc #48
jsr $ffd2
pla
sty .DIGIT ; Reset digit
inx ; Next unit
cpx #3 ; All units done?
bne .loop
lda #32 ; Space
jsr $ffd2
rts
.DIGIT byte 0 ; Current digit
.UNITS byte 100, 10, 1 ; Successive units
processor 6502
org $801
dc.w .nxt_line ; Calculate pointer to next BASIC line
dc.w 2012 ; BASIC line# (change this to any # you want)
hex 9e ; BASIC token for SYS
IF .main ; If ml_start not defined, skip it for now
dc.b [.main]d ; ML start address (use any address here)
ENDIF
hex 00 ; End of BASIC line
.nxt_line hex 00 00 ; The next BASIC line would start here
.main ; Start your ML code here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment