chiark / gitweb /
Import yesterday's source.
[zx-fizzbuzz] / fizzbuzz.s
1 ;;; -*-asm-*-
2 ;;;
3 ;;; Best not to ask why.
4
5         org     0xf000
6
7 print_a: equ    0x10
8 tvflag: equ     0x5c3c
9
10 entry:
11         ;; Initialize the buffer.
12         ld      a, 1
13         ld      (buf), a
14         ld      (len), a
15
16         ;; Use the main screen.
17         xor     a
18         ld      (tvflag), a
19
20         ;; Look at the buffer and decide what to do.
21 again:  ld      e, 0
22
23         ;; First, decide whether it's a multiple of three.  This is a bit
24         ;; fiddly.
25         ld      a, (len)
26         ld      b, a
27         ld      hl, buf
28         xor     a
29
30         ;; Main `mod 3' loop.  Load a byte and add it into the accumulator in
31         ;; decimal.
32 mod3:   ld      c, (hl)
33         inc     hl
34         add     a, c
35         daa
36         jr      nc, mod3_1
37         call    squish
38         add     a, 1
39         daa
40 mod3_1: djnz    mod3
41
42         call    squish
43         call    squish
44
45         cp      0
46         jr      z, prfizz
47         cp      3
48         jr      z, prfizz
49         cp      6
50         jr      z, prfizz
51         cp      9
52         jr      nz, nofizz
53
54 prfizz: ld      hl, fizz
55         call    print
56         inc     e
57
58         ;; Next, decide whether it's a multiple of five.  This is easier.
59 nofizz: ld      a, (buf)
60         and     0x0f
61         jr      z, prbuzz
62         cp      5
63         jr      nz, nobuzz
64
65 prbuzz: ld      hl, buzz
66         call    print
67         jr      prnl
68
69         ;; Not a multiple of five.  Skip ahead if it was a multiple of three.
70 nobuzz: ld      a, e
71         cp      0
72         jr      nz, prnl
73
74         ;; OK, so just print the value.
75         ld      a, (len)
76         ld      b, 0
77         ld      c, a
78         ld      hl, buf - 1
79         add     hl, bc
80         ld      b, c
81
82         ld      a, (hl)
83         ld      d, a
84         srl     a
85         srl     a
86         srl     a
87         srl     a
88         jr      z, skiplz
89         or      0x30
90         rst     print_a
91 skiplz: ld      a, d
92         and     0x0f
93         or      0x30
94         rst     print_a
95         dec     b
96         jr      z, prnl
97
98 prdig:  dec     hl
99         ld      a, (hl)
100         ld      d, a
101         srl     a
102         srl     a
103         srl     a
104         srl     a
105         or      0x30
106         rst     print_a
107         ld      a, d
108         and     0x0f
109         or      0x30
110         rst     print_a
111         djnz    prdig
112
113         ;; Print the newline.
114 prnl:   ld      a, ' '
115         rst     print_a
116
117         ;; Increment the counter.
118         ld      hl, buf
119         ld      a, (len)
120         ld      b, a
121         scf
122 incr:   ld      a, (hl)
123         adc     a, 0
124         daa
125         ld      (hl), a
126         jp      nc, again
127         inc     hl
128         djnz    incr
129
130         ;; Carry out.
131         ld      a, (len)
132         ld      b, 0
133         ld      c, a
134         ld      hl, buf
135         add     hl, bc
136         ld      (hl), 1
137         inc     a
138         ld      (len), a
139         jp      again
140
141 squish:
142         ;; Add the two halves of a.
143         ld      c, a
144         and     0x0f
145         srl     c
146         srl     c
147         srl     c
148         srl     c
149         add     a, c
150         daa
151         ret
152
153 print:
154         ;; Print the string at hl.
155         ld      a, (hl)
156         cp      0
157         ret     z
158         rst     print_a
159         inc     hl
160         jr      print
161
162 fizz:   defb    "fizz", 0
163 buzz:   defb    "buzz", 0
164
165 len:    defb    0
166 buf:    defs    256