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