Created
May 23, 2017 17:53
-
-
Save mgcaret/bb7a92a96e1ee3f20f8d31ce473d22e4 to your computer and use it in GitHub Desktop.
FizzBuzz!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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