zx81-loader.p: Improve the ZX81 loading program.
[zx-fizzbuzz] / fizzbuzz.s
CommitLineData
a221d644
MW
1;;; -*-asm-*-
2;;;
3;;; Best not to ask why.
4
a221d644
MW
5 ;; Look at the buffer and decide what to do.
6again: 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.
17mod3: 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
25mod3_1: djnz mod3
26
27 call squish
28 call squish
29
64b6fca5 30 and a
a221d644
MW
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
39prfizz: ld hl, fizz
40 call print
41 inc e
42
43 ;; Next, decide whether it's a multiple of five. This is easier.
44nofizz: ld a, (buf)
45 and 0x0f
46 jr z, prbuzz
47 cp 5
48 jr nz, nobuzz
49
50prbuzz: 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.
55nobuzz: ld a, e
64b6fca5 56 and a
a221d644
MW
57 jr nz, prnl
58
59 ;; OK, so just print the value.
a221d644 60 ld hl, buf - 1
0bf6b60e 61 ld bc, (len)
a221d644
MW
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
64b6fca5
MW
72 fixdig
73 print_a
a221d644
MW
74skiplz: ld a, d
75 and 0x0f
64b6fca5
MW
76 fixdig
77 print_a
a221d644
MW
78 dec b
79 jr z, prnl
80
81prdig: dec hl
82 ld a, (hl)
83 ld d, a
84 srl a
85 srl a
86 srl a
87 srl a
64b6fca5
MW
88 fixdig
89 print_a
a221d644
MW
90 ld a, d
91 and 0x0f
64b6fca5
MW
92 fixdig
93 print_a
a221d644
MW
94 djnz prdig
95
96 ;; Print the newline.
64b6fca5
MW
97prnl: ld a, spc
98 print_a
a221d644
MW
99
100 ;; Increment the counter.
101 ld hl, buf
102 ld a, (len)
103 ld b, a
104 scf
105incr: 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.
a221d644 114 ld (hl), 1
b4fd0180
MW
115 ld hl, len
116 inc (hl)
a221d644
MW
117 jp again
118
119squish:
120 ;; Add the two halves of a.
121 ld c, a
122 and 0x0f
123 srl c
124 srl c
125 srl c
126 srl c
127 add a, c
128 daa
129 ret
130
131print:
132 ;; Print the string at hl.
133 ld a, (hl)
64b6fca5 134 endstrp
a221d644 135 ret z
64b6fca5 136 print_a
a221d644
MW
137 inc hl
138 jr print
139
64b6fca5
MW
140 ;; Initial state. The buffer notionally continues for another 254
141 ;; bytes, but there's no point in including them in the image.
0bf6b60e 142len: db 1, 0
64b6fca5 143buf: db 1