Add GPL3 notices and a copy of the GPL3.
[zx-fizzbuzz] / fizzbuzz.s
CommitLineData
a221d644 1;;; -*-asm-*-
4278b406 2;;; (c) 2021 Mark Wooding
a221d644
MW
3;;;
4;;; Best not to ask why.
5
4278b406
MW
6;;;----- Licensing notice ---------------------------------------------------
7;;;
8;;; This file is part of ZX Fizzbuzz.
9;;;
10;;; ZX Fizzbuzz is free software: you can redistribute it and/or modify it
11;;; under the terms of the GNU Lesser General Public License as published
12;;; by the Free Software Foundation; either version 3 of the License, or
13;;; (at your option) any later version.
14;;;
15;;; ZX Fizzbuzz is distributed in the hope that it will be useful, but
16;;; WITHOUT ANY WARRANTY; without even the implied warranty of
17;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18;;; Lesser General Public License for more details.
19;;;
20;;; You should have received a copy of the GNU Lesser General Public
21;;; License along with ZX Fizzbuzz. If not, see
22;;; <https://www.gnu.org/licenses/>.
23
a221d644
MW
24 ;; Look at the buffer and decide what to do.
25again: ld e, 0
26
27 ;; First, decide whether it's a multiple of three. This is a bit
28 ;; fiddly.
29 ld a, (len)
30 ld b, a
31 ld hl, buf
32 xor a
33
34 ;; Main `mod 3' loop. Load a byte and add it into the accumulator in
35 ;; decimal.
36mod3: ld c, (hl)
37 inc hl
38 add a, c
39 daa
40 jr nc, mod3_1
41 call squish
42 add a, 1
43 daa
44mod3_1: djnz mod3
45
46 call squish
47 call squish
48
64b6fca5 49 and a
a221d644
MW
50 jr z, prfizz
51 cp 3
52 jr z, prfizz
53 cp 6
54 jr z, prfizz
55 cp 9
56 jr nz, nofizz
57
58prfizz: ld hl, fizz
59 call print
60 inc e
61
62 ;; Next, decide whether it's a multiple of five. This is easier.
63nofizz: ld a, (buf)
64 and 0x0f
65 jr z, prbuzz
66 cp 5
67 jr nz, nobuzz
68
69prbuzz: ld hl, buzz
70 call print
71 jr prnl
72
73 ;; Not a multiple of five. Skip ahead if it was a multiple of three.
74nobuzz: ld a, e
64b6fca5 75 and a
a221d644
MW
76 jr nz, prnl
77
78 ;; OK, so just print the value.
a221d644 79 ld hl, buf - 1
0bf6b60e 80 ld bc, (len)
a221d644
MW
81 add hl, bc
82 ld b, c
83
84 ld a, (hl)
85 ld d, a
86 srl a
87 srl a
88 srl a
89 srl a
90 jr z, skiplz
64b6fca5
MW
91 fixdig
92 print_a
a221d644
MW
93skiplz: ld a, d
94 and 0x0f
64b6fca5
MW
95 fixdig
96 print_a
a221d644
MW
97 dec b
98 jr z, prnl
99
100prdig: dec hl
101 ld a, (hl)
102 ld d, a
103 srl a
104 srl a
105 srl a
106 srl a
64b6fca5
MW
107 fixdig
108 print_a
a221d644
MW
109 ld a, d
110 and 0x0f
64b6fca5
MW
111 fixdig
112 print_a
a221d644
MW
113 djnz prdig
114
115 ;; Print the newline.
64b6fca5
MW
116prnl: ld a, spc
117 print_a
a221d644
MW
118
119 ;; Increment the counter.
120 ld hl, buf
121 ld a, (len)
122 ld b, a
123 scf
124incr: ld a, (hl)
125 adc a, 0
126 daa
127 ld (hl), a
128 jp nc, again
129 inc hl
130 djnz incr
131
132 ;; Carry out.
a221d644 133 ld (hl), 1
b4fd0180
MW
134 ld hl, len
135 inc (hl)
a221d644
MW
136 jp again
137
138squish:
139 ;; Add the two halves of a.
140 ld c, a
141 and 0x0f
142 srl c
143 srl c
144 srl c
145 srl c
146 add a, c
147 daa
148 ret
149
150print:
151 ;; Print the string at hl.
152 ld a, (hl)
64b6fca5 153 endstrp
a221d644 154 ret z
64b6fca5 155 print_a
a221d644
MW
156 inc hl
157 jr print
158
64b6fca5
MW
159 ;; Initial state. The buffer notionally continues for another 254
160 ;; bytes, but there's no point in including them in the image.
0bf6b60e 161len: db 1, 0
64b6fca5 162buf: db 1