chiark / gitweb /
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