Import yesterday's source.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 14 Nov 2021 10:28:22 +0000 (10:28 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 14 Nov 2021 10:28:22 +0000 (10:28 +0000)
fizzbuzz.s [new file with mode: 0644]

diff --git a/fizzbuzz.s b/fizzbuzz.s
new file mode 100644 (file)
index 0000000..58d4928
--- /dev/null
@@ -0,0 +1,166 @@
+;;; -*-asm-*-
+;;;
+;;; Best not to ask why.
+
+       org     0xf000
+
+print_a: equ   0x10
+tvflag:        equ     0x5c3c
+
+entry:
+       ;; Initialize the buffer.
+       ld      a, 1
+       ld      (buf), a
+       ld      (len), a
+
+       ;; Use the main screen.
+       xor     a
+       ld      (tvflag), a
+
+       ;; Look at the buffer and decide what to do.
+again: ld      e, 0
+
+       ;; First, decide whether it's a multiple of three.  This is a bit
+       ;; fiddly.
+       ld      a, (len)
+       ld      b, a
+       ld      hl, buf
+       xor     a
+
+       ;; Main `mod 3' loop.  Load a byte and add it into the accumulator in
+       ;; decimal.
+mod3:  ld      c, (hl)
+       inc     hl
+       add     a, c
+       daa
+       jr      nc, mod3_1
+       call    squish
+       add     a, 1
+       daa
+mod3_1:        djnz    mod3
+
+       call    squish
+       call    squish
+
+       cp      0
+       jr      z, prfizz
+       cp      3
+       jr      z, prfizz
+       cp      6
+       jr      z, prfizz
+       cp      9
+       jr      nz, nofizz
+
+prfizz:        ld      hl, fizz
+       call    print
+       inc     e
+
+       ;; Next, decide whether it's a multiple of five.  This is easier.
+nofizz:        ld      a, (buf)
+       and     0x0f
+       jr      z, prbuzz
+       cp      5
+       jr      nz, nobuzz
+
+prbuzz:        ld      hl, buzz
+       call    print
+       jr      prnl
+
+       ;; Not a multiple of five.  Skip ahead if it was a multiple of three.
+nobuzz:        ld      a, e
+       cp      0
+       jr      nz, prnl
+
+       ;; OK, so just print the value.
+       ld      a, (len)
+       ld      b, 0
+       ld      c, a
+       ld      hl, buf - 1
+       add     hl, bc
+       ld      b, c
+
+       ld      a, (hl)
+       ld      d, a
+       srl     a
+       srl     a
+       srl     a
+       srl     a
+       jr      z, skiplz
+       or      0x30
+       rst     print_a
+skiplz:        ld      a, d
+       and     0x0f
+       or      0x30
+       rst     print_a
+       dec     b
+       jr      z, prnl
+
+prdig: dec     hl
+       ld      a, (hl)
+       ld      d, a
+       srl     a
+       srl     a
+       srl     a
+       srl     a
+       or      0x30
+       rst     print_a
+       ld      a, d
+       and     0x0f
+       or      0x30
+       rst     print_a
+       djnz    prdig
+
+       ;; Print the newline.
+prnl:  ld      a, ' '
+       rst     print_a
+
+       ;; Increment the counter.
+       ld      hl, buf
+       ld      a, (len)
+       ld      b, a
+       scf
+incr:  ld      a, (hl)
+       adc     a, 0
+       daa
+       ld      (hl), a
+       jp      nc, again
+       inc     hl
+       djnz    incr
+
+       ;; Carry out.
+       ld      a, (len)
+       ld      b, 0
+       ld      c, a
+       ld      hl, buf
+       add     hl, bc
+       ld      (hl), 1
+       inc     a
+       ld      (len), a
+       jp      again
+
+squish:
+       ;; Add the two halves of a.
+       ld      c, a
+       and     0x0f
+       srl     c
+       srl     c
+       srl     c
+       srl     c
+       add     a, c
+       daa
+       ret
+
+print:
+       ;; Print the string at hl.
+       ld      a, (hl)
+       cp      0
+       ret     z
+       rst     print_a
+       inc     hl
+       jr      print
+
+fizz:  defb    "fizz", 0
+buzz:  defb    "buzz", 0
+
+len:   defb    0
+buf:   defs    256