Commit | Line | Data |
---|---|---|
a221d644 MW |
1 | ;;; -*-asm-*- |
2 | ;;; | |
3 | ;;; Best not to ask why. | |
4 | ||
5 | org 0xf000 | |
6 | ||
7 | print_a: equ 0x10 | |
8 | tvflag: equ 0x5c3c | |
9 | ||
10 | entry: | |
11 | ;; Initialize the buffer. | |
12 | ld a, 1 | |
13 | ld (buf), a | |
14 | ld (len), a | |
15 | ||
16 | ;; Use the main screen. | |
17 | xor a | |
18 | ld (tvflag), a | |
19 | ||
20 | ;; Look at the buffer and decide what to do. | |
21 | again: ld e, 0 | |
22 | ||
23 | ;; First, decide whether it's a multiple of three. This is a bit | |
24 | ;; fiddly. | |
25 | ld a, (len) | |
26 | ld b, a | |
27 | ld hl, buf | |
28 | xor a | |
29 | ||
30 | ;; Main `mod 3' loop. Load a byte and add it into the accumulator in | |
31 | ;; decimal. | |
32 | mod3: ld c, (hl) | |
33 | inc hl | |
34 | add a, c | |
35 | daa | |
36 | jr nc, mod3_1 | |
37 | call squish | |
38 | add a, 1 | |
39 | daa | |
40 | mod3_1: djnz mod3 | |
41 | ||
42 | call squish | |
43 | call squish | |
44 | ||
45 | cp 0 | |
46 | jr z, prfizz | |
47 | cp 3 | |
48 | jr z, prfizz | |
49 | cp 6 | |
50 | jr z, prfizz | |
51 | cp 9 | |
52 | jr nz, nofizz | |
53 | ||
54 | prfizz: ld hl, fizz | |
55 | call print | |
56 | inc e | |
57 | ||
58 | ;; Next, decide whether it's a multiple of five. This is easier. | |
59 | nofizz: ld a, (buf) | |
60 | and 0x0f | |
61 | jr z, prbuzz | |
62 | cp 5 | |
63 | jr nz, nobuzz | |
64 | ||
65 | prbuzz: ld hl, buzz | |
66 | call print | |
67 | jr prnl | |
68 | ||
69 | ;; Not a multiple of five. Skip ahead if it was a multiple of three. | |
70 | nobuzz: ld a, e | |
71 | cp 0 | |
72 | jr nz, prnl | |
73 | ||
74 | ;; OK, so just print the value. | |
75 | ld a, (len) | |
76 | ld b, 0 | |
77 | ld c, a | |
78 | ld hl, buf - 1 | |
79 | add hl, bc | |
80 | ld b, c | |
81 | ||
82 | ld a, (hl) | |
83 | ld d, a | |
84 | srl a | |
85 | srl a | |
86 | srl a | |
87 | srl a | |
88 | jr z, skiplz | |
89 | or 0x30 | |
90 | rst print_a | |
91 | skiplz: ld a, d | |
92 | and 0x0f | |
93 | or 0x30 | |
94 | rst print_a | |
95 | dec b | |
96 | jr z, prnl | |
97 | ||
98 | prdig: dec hl | |
99 | ld a, (hl) | |
100 | ld d, a | |
101 | srl a | |
102 | srl a | |
103 | srl a | |
104 | srl a | |
105 | or 0x30 | |
106 | rst print_a | |
107 | ld a, d | |
108 | and 0x0f | |
109 | or 0x30 | |
110 | rst print_a | |
111 | djnz prdig | |
112 | ||
113 | ;; Print the newline. | |
114 | prnl: ld a, ' ' | |
115 | rst print_a | |
116 | ||
117 | ;; Increment the counter. | |
118 | ld hl, buf | |
119 | ld a, (len) | |
120 | ld b, a | |
121 | scf | |
122 | incr: ld a, (hl) | |
123 | adc a, 0 | |
124 | daa | |
125 | ld (hl), a | |
126 | jp nc, again | |
127 | inc hl | |
128 | djnz incr | |
129 | ||
130 | ;; Carry out. | |
131 | ld a, (len) | |
132 | ld b, 0 | |
133 | ld c, a | |
134 | ld hl, buf | |
135 | add hl, bc | |
136 | ld (hl), 1 | |
137 | inc a | |
138 | ld (len), a | |
139 | jp again | |
140 | ||
141 | squish: | |
142 | ;; Add the two halves of a. | |
143 | ld c, a | |
144 | and 0x0f | |
145 | srl c | |
146 | srl c | |
147 | srl c | |
148 | srl c | |
149 | add a, c | |
150 | daa | |
151 | ret | |
152 | ||
153 | print: | |
154 | ;; Print the string at hl. | |
155 | ld a, (hl) | |
156 | cp 0 | |
157 | ret z | |
158 | rst print_a | |
159 | inc hl | |
160 | jr print | |
161 | ||
162 | fizz: defb "fizz", 0 | |
163 | buzz: defb "buzz", 0 | |
164 | ||
165 | len: defb 0 | |
166 | buf: defs 256 |