new version
[Chiptunes-pms150c.git] / bsv.c
1 #include <stdio.h>
2 #include "fakeasm.h"
3 typedef unsigned char u8;
4
5 u8 notes[16]; //MEM
6 u8 i0, i1, i2; //MEM
7 u8 n; //MEM
8 u8 sample; //MEM
9 u8 tmp_1; //MEM
10 u8 acc; //ACC
11
12 u8 mod3hi, mod3lo; //MEM
13 //todo: can mod3hi be aliased to tmp_1?
14 void mod3(void) {
15 MOV (acc,mod3hi)
16 ADD (mod3lo,acc) // mod3lo = hi+lo
17 CLEAR (acc)
18 ADDC0 (acc) // mod3hi, 1bit
19 SWAP (acc)
20 MOV (mod3hi, acc)
21
22 MOV (acc, mod3lo)
23 SWAP (acc)
24 AND (acc, 0xf) // (mod3lo>>4)
25 XCH (mod3lo) // acc=mod3lo, mod3lo=mod3lo>>4
26 AND (acc, 0xF) // acc=mod3lo&0xf, mod3lo=mod3lo>>4
27 ADD (acc, mod3lo) // (mod3lo & 0xF)
28 ADD (acc, mod3hi)
29 MOV (mod3lo, acc)
30
31 AND (acc, 0x3) // acc = (mod3lo & 0x3)
32 SR (mod3lo)
33 SR (mod3lo) // (mod3lo >> 2)
34 ADD (acc, mod3lo)
35 MOV (mod3lo, acc)
36
37 AND (acc, 0x3) // acc = (mod3lo & 0x3)
38 SR (mod3lo)
39 SR (mod3lo) // (mod3lo >> 2)
40 ADD (acc, mod3lo)
41
42 SUB (acc,3)
43 /*T0SN FLAG.C (0x00.1)*/ if (flag_c){ // skip if carry clear
44 ADD (acc,3) }
45 }
46
47 void g(void){
48 // notes_ix_hi = always 0
49 u8 notes_ix;//lo
50 AND (acc, 0x7)
51 MOV (notes_ix, acc)
52 // test i2 & 3:
53 MOV (acc, i2)
54 AND (acc, 3)
55 /*T0SN FLAG.Z (0x00.0)*/ if(3&i2) {// skip if !(3&i0)
56 SET1 (notes_ix, 3) } // ix += 8 <=> ix |= 8
57 IDXM (acc, notes+notes_ix)
58
59 //unrolled: https://git.gir.st/Chiptunes.git/blob/f8e0502:/foo.S#l113
60 u8 a2 = 0; // can probably be overloaded onto mul3lo/hi
61 u8 a1 = 0; // -"-
62 u8 t = acc; // note input (as returned by idxm)
63 for (u8 loop = 0; loop < 8; loop++) {
64 SR (t)
65 /*T1SN FLAG.C (0x00.1)*/ if (!flag_c) // skip if carry set
66 goto skip;
67 MOV (acc, i0)
68 ADD (a1, acc)
69 MOV (acc, i1)
70 ADDC (a2, acc)
71 skip: SR (a2)
72 SRC (a1)
73 }
74 MOV (acc, a1)
75 }
76 void main(void){
77 CLEAR (i0)
78 CLEAR (i1)
79 CLEAR (i2)
80
81 //rom is not mmapped; must load into ram first
82 MOV (acc, 0x84)
83 MOV (notes[0x0], acc)
84 MOV (notes[0x5], acc)
85 MOV (acc, 0x9d)
86 MOV (notes[0x1], acc)
87 MOV (notes[0x4], acc)
88 MOV (acc, 0xb0)
89 MOV (notes[0x2], acc)
90 MOV (notes[0xA], acc)
91 MOV (acc, 0x69)
92 MOV (notes[0x3], acc)
93 MOV (notes[0x6], acc)
94 MOV (notes[0xB], acc)
95 MOV (notes[0xE], acc)
96 MOV (acc, 0x58)
97 MOV (notes[0x7], acc)
98 MOV (notes[0xF], acc)
99 MOV (acc, 0x75)
100 MOV (notes[0x8], acc)
101 MOV (notes[0xD], acc)
102 MOV (acc, 0x8c)
103 MOV (notes[0x9], acc)
104 MOV (notes[0xC], acc)
105
106 for(;;) {
107 MOV (acc, i2)// "mov mem,mem"
108 MOV (n, acc)// does not exist
109 SL (n)
110 SL (n)
111 MOV (acc, i1)
112 SWAP (acc)
113 AND (acc, 0xf)
114 SR (acc)
115 SR (acc)
116 OR (n, acc)
117
118 MOV (acc, n)
119 CALL (g)
120 SWAP (acc)
121 AND (acc, 0x1)
122 MOV (sample, acc)
123
124 MOV (acc, i2)
125 SL (acc)
126 SL (acc)
127 SL (acc)
128 MOV (tmp_1, acc) // fresh tmp_1:
129 MOV (acc, i1)
130 SWAP (acc)
131 AND (acc, 0xf)
132 SR (acc)
133 OR (acc, tmp_1) // tmp_1 done.
134 XOR (acc, n)
135 CALL (g)
136 SR (acc)
137 AND (acc, i2)
138 SR (acc)
139 AND (acc, 3)
140 ADD (sample, acc)
141
142 MOV (acc, i2)
143 MOV (mod3hi, acc)
144 SR (mod3hi)
145 SR (mod3hi)
146 SR (mod3hi)
147 SWAP (acc)
148 AND (acc, 0xf0)
149 SL (acc)
150 MOV (mod3lo, acc)
151 MOV (acc, i1)
152 SR (acc)
153 SR (acc)
154 SR (acc)
155 OR (mod3lo, acc)
156 CALL (mod3)
157 ADD (acc, n)
158 CALL (g)
159 SR (acc)
160 SR (acc)
161 MOV (tmp_1, acc) // acc saved in tmp_1; fresh acc
162 MOV (acc, i2)
163 // shift-divide by six
164 // note: i2 is max 0x78; so acc will <= 20. (breaks vor values >=128)
165 SR (acc)
166 ADD (acc, i2)
167 SR (acc)
168 SR (acc)
169 ADD (acc, i2)
170 SR (acc)
171 SR (acc)
172 ADD (acc, i2)
173 SR (acc)
174 SR (acc)
175 SR (acc)
176 // end divide by six
177 AND (acc, tmp_1) // acc restored from tmp_1
178 AND (acc, 3)
179 ADD (sample, acc)
180
181 MOV (acc, i2)
182 MOV (mod3hi, acc)
183 SR (mod3hi)
184 SR (mod3hi)
185 SWAP (acc)
186 AND (acc, 0xf0)
187 SL (acc)
188 SL (acc)
189 MOV (mod3lo, acc)
190 MOV (acc, i1)
191 SR (acc)
192 SR (acc)
193 OR (mod3lo, acc)
194 CALL (mod3)
195 SUB (acc, n)
196 SUB (acc, 8)
197 NEG (acc)
198 CALL (g)
199 SR (acc)
200 MOV (tmp_1, acc) // acc saved in tmp_1; fresh acc
201 MOV (acc, i2)
202 // shift-divide by ten
203 // note: i2 is max 0x78; so acc will <= 12.
204 INC (i2)
205 SR (acc)
206 ADD (acc, i2)
207 SR (acc)
208 SR (acc)
209 SR (acc)
210 ADD (acc, i2)
211 SR (acc)
212 ADD (acc, i2)
213 SWAP (acc)
214 DEC (i2)
215 // end divide by ten
216 AND (acc, tmp_1) // acc restored from tmp_1
217 AND (acc, 3)
218 ADD (sample, acc)
219
220 MOV (acc, sample)
221 SWAP (acc)
222 putchar(acc);
223
224 INC (i0)
225 /*ADDC i1*/ i1 += !i0;
226 /*ADDC i2*/ i2 += !i1 && !i0;
227
228 if(i2 == 0x78) break;
229 }
230 }
Imprint / Impressum