Skip to content

Instantly share code, notes, and snippets.

@mgcaret
Created May 23, 2017 17:53
Show Gist options
  • Save mgcaret/bb7a92a96e1ee3f20f8d31ce473d22e4 to your computer and use it in GitHub Desktop.
Save mgcaret/bb7a92a96e1ee3f20f8d31ce473d22e4 to your computer and use it in GitHub Desktop.
FizzBuzz!
; originally written by Dagen Brock
; https://gist.github.com/digarok/12ce4a12993c4c4444c0819e9fcc752a
; Reworked by M.G.
; changelog:
; * port to ca65
; * removed some redundancies
; * trade +1 byte of ZP usage to eliminate special case for "FizzBuzz"
; * improved output formatting
; * converted all addresses to labels
; * moved zero page usage away from AppleSoft vectors at $00
; * use minimalist local labels (:) where it doesn't impact readability
.macro hasc Arg
.repeat .strlen(Arg), I
.byte .strat(Arg, I) | $80
.endrep
.endmacro
.p02
.code
.org $300 ;Tiny program so we'll use the page at sh00
COUT := $FDED ;equates for two firmware routines we'll be using
PRHEX := $FDDA ;COUT prints a character, PRHEX prints a 2-digit hex value
CH := $24 ; cursor horizontal
t1 := $06 ; counter
t2 := $07 ; divisor for modulus
t3 := $08 ; fizz/buzz flag
sl := $09 ; pointer to string
sh := sl+1
Init: lda #0 ; starting number (will increment at beginning of loop)
sta t1
MainLoop: sed ; use decimal mode to increment
lda t1
clc
adc #1 ; increment our number using addition
sta t1
cld ; return to hex
bne :+ ; continue unless zero
rts
: lda #0
sta t3
lda #3 ; check mod 3
sta t2
jsr Modulus
bne ckBuzz ; not %3 (non-zero result)
inc t3 ; flag it
lda #<fizzS
sta sl
lda #>fizzS
sta sh
jsr PrintStr
ckBuzz: lda #5 ; check mod 5
sta t2
jsr Modulus
bne ckNum ; nope (non-zero)
inc t3
lda #<buzzS
sta sl
lda #>buzzS
sta sh
jsr PrintStr
ckNum: lda t3 ; did we print Fizz and/or Buzz?
beq prtNum ; no, so print number instead
lda #'!'|$80 ; otherwise print the bang
jsr COUT
jmp prtSP
prtNum: lda t1
jsr PRHEX
prtSP: lda #' '|$80
jsr COUT
lda CH
cmp #30 ; past 30 columns?
bcc :+ ; no, so don't wrap
lda #$8D ; CR for word wrap
jsr COUT
: jmp MainLoop
; Print a zero terminated string... pointer to string in sl,sh
PrintStr: ldy #0
: lda (sl),y
beq :+
jsr COUT
iny
bne :-
: rts
fizzS: hasc "Fizz"
.byte 0
buzzS: hasc "Buzz"
.byte 0
; Modulus function in decimal mode
; variables are in direct page locations t1 and t2
Modulus: sed
lda t1 ;load our main number
sec
: sbc t2 ;subract our mod number
bcs :- ;over and over until we underflow
adc t2 ;reverse our last subtraction to see where we ended up
cld
rts ;and return that value in A (the modulus)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment