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