Commit | Line | Data |
---|---|---|
a221d644 MW |
1 | ;;; -*-asm-*- |
2 | ;;; | |
3 | ;;; Best not to ask why. | |
4 | ||
a221d644 MW |
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 | ||
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 | ||
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 | |
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 |
74 | skiplz: ld a, d |
75 | and 0x0f | |
64b6fca5 MW |
76 | fixdig |
77 | print_a | |
a221d644 MW |
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 | |
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 |
97 | prnl: 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 | |
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 b, 0 | |
116 | ld c, a | |
117 | ld hl, buf | |
118 | add hl, bc | |
119 | ld (hl), 1 | |
120 | inc a | |
121 | ld (len), a | |
122 | jp again | |
123 | ||
124 | squish: | |
125 | ;; Add the two halves of a. | |
126 | ld c, a | |
127 | and 0x0f | |
128 | srl c | |
129 | srl c | |
130 | srl c | |
131 | srl c | |
132 | add a, c | |
133 | daa | |
134 | ret | |
135 | ||
136 | print: | |
137 | ;; Print the string at hl. | |
138 | ld a, (hl) | |
64b6fca5 | 139 | endstrp |
a221d644 | 140 | ret z |
64b6fca5 | 141 | print_a |
a221d644 MW |
142 | inc hl |
143 | jr print | |
144 | ||
64b6fca5 MW |
145 | ;; Initial state. The buffer notionally continues for another 254 |
146 | ;; bytes, but there's no point in including them in the image. | |
0bf6b60e | 147 | len: db 1, 0 |
64b6fca5 | 148 | buf: db 1 |