76242efd254854ce6a5bcb1cd99a3b2e552027c2
[zx-fizzbuzz] / fizzbuzz.s
1 ;;; -*-asm-*-
2 ;;;
3 ;;; Best not to ask why.
4
5 ;; Look at the buffer and decide what to do.
6 again: ld e, 0
7
8 ;; First, decide whether it's a multiple of three. This is a bit
9 ;; fiddly.
10 ld a, (len)
11 ld b, a
12 ld hl, buf
13 xor a
14
15 ;; Main `mod 3' loop. Load a byte and add it into the accumulator in
16 ;; decimal.
17 mod3: ld c, (hl)
18 inc hl
19 add a, c
20 daa
21 jr nc, mod3_1
22 call squish
23 add a, 1
24 daa
25 mod3_1: djnz mod3
26
27 call squish
28 call squish
29
30 and a
31 jr z, prfizz
32 cp 3
33 jr z, prfizz
34 cp 6
35 jr z, prfizz
36 cp 9
37 jr nz, nofizz
38
39 prfizz: ld hl, fizz
40 call print
41 inc e
42
43 ;; Next, decide whether it's a multiple of five. This is easier.
44 nofizz: ld a, (buf)
45 and 0x0f
46 jr z, prbuzz
47 cp 5
48 jr nz, nobuzz
49
50 prbuzz: ld hl, buzz
51 call print
52 jr prnl
53
54 ;; Not a multiple of five. Skip ahead if it was a multiple of three.
55 nobuzz: ld a, e
56 and a
57 jr nz, prnl
58
59 ;; OK, so just print the value.
60 ld hl, buf - 1
61 ld bc, (len)
62 add hl, bc
63 ld b, c
64
65 ld a, (hl)
66 ld d, a
67 srl a
68 srl a
69 srl a
70 srl a
71 jr z, skiplz
72 fixdig
73 print_a
74 skiplz: ld a, d
75 and 0x0f
76 fixdig
77 print_a
78 dec b
79 jr z, prnl
80
81 prdig: dec hl
82 ld a, (hl)
83 ld d, a
84 srl a
85 srl a
86 srl a
87 srl a
88 fixdig
89 print_a
90 ld a, d
91 and 0x0f
92 fixdig
93 print_a
94 djnz prdig
95
96 ;; Print the newline.
97 prnl: ld a, spc
98 print_a
99
100 ;; Increment the counter.
101 ld hl, buf
102 ld a, (len)
103 ld b, a
104 scf
105 incr: ld a, (hl)
106 adc a, 0
107 daa
108 ld (hl), a
109 jp nc, again
110 inc hl
111 djnz incr
112
113 ;; Carry out.
114 ld (hl), 1
115 ld hl, len
116 inc (hl)
117 jp again
118
119 squish:
120 ;; Add the two halves of a.
121 ld c, a
122 and 0x0f
123 srl c
124 srl c
125 srl c
126 srl c
127 add a, c
128 daa
129 ret
130
131 print:
132 ;; Print the string at hl.
133 ld a, (hl)
134 endstrp
135 ret z
136 print_a
137 inc hl
138 jr print
139
140 ;; Initial state. The buffer notionally continues for another 254
141 ;; bytes, but there's no point in including them in the image.
142 len: db 1, 0
143 buf: db 1