chiark / gitweb /
Add GPL3 notices and a copy of the GPL3.
[zx-fizzbuzz] / fizzbuzz.s
1 ;;; -*-asm-*-
2 ;;; (c) 2021 Mark Wooding
3 ;;;
4 ;;; Best not to ask why.
5
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
24         ;; Look at the buffer and decide what to do.
25 again:  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.
36 mod3:   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
44 mod3_1: djnz    mod3
45
46         call    squish
47         call    squish
48
49         and     a
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
58 prfizz: ld      hl, fizz
59         call    print
60         inc     e
61
62         ;; Next, decide whether it's a multiple of five.  This is easier.
63 nofizz: ld      a, (buf)
64         and     0x0f
65         jr      z, prbuzz
66         cp      5
67         jr      nz, nobuzz
68
69 prbuzz: 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.
74 nobuzz: ld      a, e
75         and     a
76         jr      nz, prnl
77
78         ;; OK, so just print the value.
79         ld      hl, buf - 1
80         ld      bc, (len)
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
91         fixdig
92         print_a
93 skiplz: ld      a, d
94         and     0x0f
95         fixdig
96         print_a
97         dec     b
98         jr      z, prnl
99
100 prdig:  dec     hl
101         ld      a, (hl)
102         ld      d, a
103         srl     a
104         srl     a
105         srl     a
106         srl     a
107         fixdig
108         print_a
109         ld      a, d
110         and     0x0f
111         fixdig
112         print_a
113         djnz    prdig
114
115         ;; Print the newline.
116 prnl:   ld      a, spc
117         print_a
118
119         ;; Increment the counter.
120         ld      hl, buf
121         ld      a, (len)
122         ld      b, a
123         scf
124 incr:   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.
133         ld      (hl), 1
134         ld      hl, len
135         inc     (hl)
136         jp      again
137
138 squish:
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
150 print:
151         ;; Print the string at hl.
152         ld      a, (hl)
153         endstrp
154         ret     z
155         print_a
156         inc     hl
157         jr      print
158
159         ;; Initial state.  The buffer notionally continues for another 254
160         ;; bytes, but there's no point in including them in the image.
161 len:    db      1, 0
162 buf:    db      1