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