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 u8 result = ((i1<<8|i0)*acc)>>8; // keep hi byte
59 //^TODO! https://git.gir.st/Chiptunes.git/blob/d397f89:/foo.c#l83
60 //final: https://git.gir.st/Chiptunes.git/blob/f8e0502:/foo.S#l113
61 u8 a2 = 0; // can probably be overloaded onto mul3lo/hi
62 u8 a1 = 0; // -"-
63 u8 t = acc; // note input (as returned by idxm)
64 for (u8 loop = 0; loop < 8; loop++) {
65 SR (t)
66 if (flag_c) {
67 /*(2) ADDC a2, i1*/ a2 += i1 + ((a1+i0)>>8);
68 /*(1) ADD a1, i0*/ a1 += i0;
69 }
70 SR (a2)
71 SRC (a1)
72 }
73 acc = a1;
74 }
75 void main(void){
76 CLEAR (i0)
77 CLEAR (i1)
78 CLEAR (i2)
79
80 //rom is not mmapped; must load into ram first
81 MOV (acc, 0x84)
82 MOV (notes[0x0], acc)
83 MOV (notes[0x5], acc)
84 MOV (acc, 0x9d)
85 MOV (notes[0x1], acc)
86 MOV (notes[0x4], acc)
87 MOV (acc, 0xb0)
88 MOV (notes[0x2], acc)
89 MOV (notes[0xA], acc)
90 MOV (acc, 0x69)
91 MOV (notes[0x3], acc)
92 MOV (notes[0x6], acc)
93 MOV (notes[0xB], acc)
94 MOV (notes[0xE], acc)
95 MOV (acc, 0x58)
96 MOV (notes[0x7], acc)
97 MOV (notes[0xF], acc)
98 MOV (acc, 0x75)
99 MOV (notes[0x8], acc)
100 MOV (notes[0xD], acc)
101 MOV (acc, 0x8c)
102 MOV (notes[0x9], acc)
103 MOV (notes[0xC], acc)
104
105 for(;;) {
106 MOV (acc, i2)// "mov mem,mem"
107 MOV (n, acc)// does not exist
108 SL (n)
109 SL (n)
110 MOV (acc, i1)
111 SWAP (acc)
112 AND (acc, 0xf)
113 SR (acc)
114 SR (acc)
115 OR (n, acc)
116
117 MOV (acc, n)
118 CALL (g)
119 SWAP (acc)
120 AND (acc, 0x1)
121 MOV (sample, acc)
122
123 MOV (acc, i2)
124 SL (acc)
125 SL (acc)
126 SL (acc)
127 MOV (tmp_1, acc) // fresh tmp_1:
128 MOV (acc, i1)
129 SWAP (acc)
130 AND (acc, 0xf)
131 SR (acc)
132 OR (acc, tmp_1) // tmp_1 done.
133 XOR (acc, n)
134 CALL (g)
135 SR (acc)
136 AND (acc, i2)
137 SR (acc)
138 AND (acc, 3)
139 ADD (sample, acc)
140
141 MOV (acc, i2)
142 MOV (mod3hi, acc)
143 SR (mod3hi)
144 SR (mod3hi)
145 SR (mod3hi)
146 SWAP (acc)
147 AND (acc, 0xf0)
148 SL (acc)
149 MOV (mod3lo, acc)
150 MOV (acc, i1)
151 SR (acc)
152 SR (acc)
153 SR (acc)
154 OR (mod3lo, acc)
155 CALL (mod3)
156 ADD (acc, n)
157 CALL (g)
158 SR (acc)
159 SR (acc)
160 MOV (tmp_1, acc) // acc saved in tmp_1; fresh acc
161 MOV (acc, i2)
162 // shift-divide by six
163 // note: i2 is max 0x78; so acc will <= 20. (breaks vor values >=128)
164 SR (acc)
165 ADD (acc, i2)
166 SR (acc)
167 SR (acc)
168 ADD (acc, i2)
169 SR (acc)
170 SR (acc)
171 ADD (acc, i2)
172 SR (acc)
173 SR (acc)
174 SR (acc)
175 // end divide by six
176 AND (acc, tmp_1) // acc restored from tmp_1
177 AND (acc, 3)
178 ADD (sample, acc)
179
180 MOV (acc, i2)
181 MOV (mod3hi, acc)
182 SR (mod3hi)
183 SR (mod3hi)
184 SWAP (acc)
185 AND (acc, 0xf0)
186 SL (acc)
187 SL (acc)
188 MOV (mod3lo, acc)
189 MOV (acc, i1)
190 SR (acc)
191 SR (acc)
192 OR (mod3lo, acc)
193 CALL (mod3)
194 SUB (acc, n)
195 SUB (acc, 8)
196 NEG (acc)
197 CALL (g)
198 SR (acc)
199 MOV (tmp_1, acc) // acc saved in tmp_1; fresh acc
200 MOV (acc, i2)
201 // shift-divide by ten
202 // note: i2 is max 0x78; so acc will <= 12.
203 INC (i2)
204 SR (acc)
205 ADD (acc, i2)
206 SR (acc)
207 SR (acc)
208 SR (acc)
209 ADD (acc, i2)
210 SR (acc)
211 ADD (acc, i2)
212 SWAP (acc)
213 DEC (i2)
214 // end divide by ten
215 AND (acc, tmp_1) // acc restored from tmp_1
216 AND (acc, 3)
217 ADD (sample, acc)
218
219 MOV (acc, sample)
220 SWAP (acc)
221 putchar(acc);
222
223 INC (i0)
224 /*ADDC i1*/ i1 += !i0;
225 /*ADDC i2*/ i2 += !i1 && !i0;
226
227 if(i2 == 0x78) break;
228 }
229 }
Imprint / Impressum