fizzbuzz.s: Abstract out a number of system dependencies.
[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 a, (len)
61 ld b, 0
62 ld c, a
63 ld hl, buf - 1
64 add hl, bc
65 ld b, c
66
67 ld a, (hl)
68 ld d, a
69 srl a
70 srl a
71 srl a
72 srl a
73 jr z, skiplz
74 fixdig
75 print_a
76 skiplz: ld a, d
77 and 0x0f
78 fixdig
79 print_a
80 dec b
81 jr z, prnl
82
83 prdig: dec hl
84 ld a, (hl)
85 ld d, a
86 srl a
87 srl a
88 srl a
89 srl a
90 fixdig
91 print_a
92 ld a, d
93 and 0x0f
94 fixdig
95 print_a
96 djnz prdig
97
98 ;; Print the newline.
99 prnl: ld a, spc
100 print_a
101
102 ;; Increment the counter.
103 ld hl, buf
104 ld a, (len)
105 ld b, a
106 scf
107 incr: ld a, (hl)
108 adc a, 0
109 daa
110 ld (hl), a
111 jp nc, again
112 inc hl
113 djnz incr
114
115 ;; Carry out.
116 ld a, (len)
117 ld b, 0
118 ld c, a
119 ld hl, buf
120 add hl, bc
121 ld (hl), 1
122 inc a
123 ld (len), a
124 jp again
125
126 squish:
127 ;; Add the two halves of a.
128 ld c, a
129 and 0x0f
130 srl c
131 srl c
132 srl c
133 srl c
134 add a, c
135 daa
136 ret
137
138 print:
139 ;; Print the string at hl.
140 ld a, (hl)
141 endstrp
142 ret z
143 print_a
144 inc hl
145 jr print
146
147 ;; Initial state. The buffer notionally continues for another 254
148 ;; bytes, but there's no point in including them in the image.
149 len: db 1
150 buf: db 1