9 enum { MAXBUF = 2000 };
20 u8int apuseq, apuctr[13];
21 u16int dmcaddr, dmccnt;
23 static short sbuf[2*MAXBUF], *sbufp;
30 m = mem[0x4001 + i * 4];
31 p = mem[0x4002 + i * 4];
32 p |= (mem[0x4003 + i * 4] & 7) << 8;
49 for(i = 0; i < 4; i++){
50 m = mem[0x4000 + i * 4];
55 if(apuctr[LEN + i] != 0)
58 for(i = 0, a = apuctr + SWEEP; i < 2; i++, a++){
59 m = mem[0x4001 + i * 4];
60 if((m & 0x80) != 0 && (m & 0x07) != 0 && (*a & 7) == 0){
63 mem[0x4002 + i * 4] = p;
64 mem[0x4003 + i * 4] = p >> 8;
67 if((*a & 0x80) != 0 || (*a & 7) == 0 && (m & 0x80) != 0)
80 for(i = 0, a = apuctr + ENV; i < 4; i++, a++){
83 m = mem[0x4000 + 4 * i];
84 if((apuctr[RELOAD] & (1<<i)) != 0){
86 apuctr[RELOAD] &= ~(1<<i);
87 }else if((*a & 0x0f) == 0){
98 if((apuctr[RELOAD] & (1<<2)) != 0)
99 *a = mem[0x4008] & 0x7f;
102 if((mem[0x4008] & 0x80) == 0)
103 apuctr[RELOAD] &= ~(1<<2);
111 mode = mem[APUFRAME];
112 if((mode & 0x80) != 0){
118 len = (apuseq & 1) == 0;
123 len = (apuseq & 1) != 0;
125 if((mode & 0x40) == 0)
142 f = mem[0x4002 + 4 * i];
143 f |= (mem[0x4003 + 4 * i] & 0x7) << 8;
154 if(f < 8 || targperiod(i) > 0x7ff)
157 f = muldiv(16 * (f + 1), RATE, FREQ/12);
162 m = mem[0x4000 + 4 * i];
166 s = apuctr[ENV + i] >> 4;
167 if(c[i] >= f/2 || apuctr[LEN + i] == 0)
181 f = muldiv(32 * (f + 1), RATE, FREQ / 12);
187 i ^= (i < 16) ? 0xf : 0x10;
188 if(apuctr[LEN + 2] == 0 || (apuctr[TRILIN] & 0x7f) == 0)
199 0x004, 0x008, 0x010, 0x020, 0x040, 0x060, 0x080, 0x0A0,
200 0x0CA, 0x0FE, 0x17C, 0x1FC, 0x2FA, 0x3F8, 0x7F2, 0xFE4,
204 f = muldiv(per[m & 0x0f], RATE * 1000, FREQ/24);
207 r |= ((r ^ (r >> ((m & 0x80) != 0 ? 6 : 1))) & 1) << 15;
211 if(apuctr[LEN + 3] == 0 || (r & 1) != 0)
216 return apuctr[ENV + 3] >> 4;
232 d = 95.88 / (8128.0 / (0.01 + pulse(0) + pulse(1)) + 100);
233 d += 159.79 / (1.0 / (0.01 + tri()/8227.0 + noise()/12241.0 + dmc()/22638.0) + 100.0);
234 if(sbufp < sbuf + nelem(sbuf) - 1){
235 *sbufp++ = d * 10000;
236 *sbufp++ = d * 10000;
243 if((apuctr[DMCCTR] & 7) == 0){
246 apuctr[DMCSHFT] = memread(dmcaddr);
247 if(dmcaddr == 0xFFFF)
252 if((mem[DMCCTRL] & 0x40) != 0){
253 dmcaddr = mem[DMCADDR] * 0x40 + 0xC000;
254 dmccnt = mem[DMCLEN] * 0x10 + 1;
255 }else if((mem[DMCCTRL] & 0x80) != 0)
259 apuctr[DMCCTR] |= 0x80;
261 if((apuctr[DMCCTR] & 0x80) == 0){
262 if((apuctr[DMCSHFT] & 1) != 0){
263 if(mem[DMCBUF] < 126)
270 apuctr[DMCSHFT] >>= 1;
283 rc = warp10 ? (sbufp - sbuf) * 2 : write(fd, sbuf, (sbufp - sbuf) * 2);
294 fd = open("/dev/audio", OWRITE);
301 0x0A, 0xFE, 0x14, 0x02, 0x28, 0x04, 0x50, 0x06,
302 0xA0, 0x08, 0x3C, 0x0A, 0x0E, 0x0C, 0x1A, 0x0E,
303 0x0C, 0x10, 0x18, 0x12, 0x30, 0x14, 0x60, 0x16,
304 0xC0, 0x18, 0x48, 0x1A, 0x10, 0x1C, 0x20, 0x1E,
307 u16int dmclen[16] = {
308 0x1AC, 0x17C, 0x154, 0x140, 0x11E, 0x0FE, 0x0E2, 0x0D6,
309 0x0BE, 0x0A0, 0x08E, 0x080, 0x06A, 0x054, 0x048, 0x036,