8 enum { MAXBUF = 2000 };
19 u8int apuseq, apuctr[13];
20 u16int dmcaddr, dmccnt;
22 static short sbuf[2*MAXBUF], *sbufp;
29 m = mem[0x4001 + i * 4];
30 p = mem[0x4002 + i * 4];
31 p |= (mem[0x4003 + i * 4] & 7) << 8;
48 for(i = 0; i < 4; i++){
49 m = mem[0x4000 + i * 4];
54 if(apuctr[LEN + i] != 0)
57 for(i = 0, a = apuctr + SWEEP; i < 2; i++, a++){
58 m = mem[0x4001 + i * 4];
59 if((m & 0x80) != 0 && (m & 0x07) != 0 && (*a & 7) == 0){
62 mem[0x4002 + i * 4] = p;
63 mem[0x4003 + i * 4] = p >> 8;
66 if((*a & 0x80) != 0 || (*a & 7) == 0 && (m & 0x80) != 0)
79 for(i = 0, a = apuctr + ENV; i < 4; i++, a++){
82 m = mem[0x4000 + 4 * i];
83 if((apuctr[RELOAD] & (1<<i)) != 0){
85 apuctr[RELOAD] &= ~(1<<i);
86 }else if((*a & 0x0f) == 0){
97 if((apuctr[RELOAD] & (1<<2)) != 0)
98 *a = mem[0x4008] & 0x7f;
101 if((mem[0x4008] & 0x80) == 0)
102 apuctr[RELOAD] &= ~(1<<2);
110 mode = mem[APUFRAME];
111 if((mode & 0x80) != 0){
117 len = (apuseq & 1) == 0;
122 len = (apuseq & 1) != 0;
124 if((mode & 0x40) == 0)
141 f = mem[0x4002 + 4 * i];
142 f |= (mem[0x4003 + 4 * i] & 0x7) << 8;
153 if(f < 8 || targperiod(i) > 0x7ff)
156 f = muldiv(16 * (f + 1), RATE, FREQ/12);
161 m = mem[0x4000 + 4 * i];
165 s = apuctr[ENV + i] >> 4;
166 if(c[i] >= f/2 || apuctr[LEN + i] == 0)
180 f = muldiv(32 * (f + 1), RATE, FREQ / 12);
186 i ^= (i < 16) ? 0xf : 0x10;
187 if(apuctr[LEN + 2] == 0 || (apuctr[TRILIN] & 0x7f) == 0)
198 0x004, 0x008, 0x010, 0x020, 0x040, 0x060, 0x080, 0x0A0,
199 0x0CA, 0x0FE, 0x17C, 0x1FC, 0x2FA, 0x3F8, 0x7F2, 0xFE4,
203 f = muldiv(per[m & 0x0f], RATE * 1000, FREQ/24);
206 r |= ((r ^ (r >> ((m & 0x80) != 0 ? 6 : 1))) & 1) << 15;
210 if(apuctr[LEN + 3] == 0 || (r & 1) != 0)
215 return apuctr[ENV + 3] >> 4;
231 d = 95.88 / (8128.0 / (0.01 + pulse(0) + pulse(1)) + 100);
232 d += 159.79 / (1.0 / (0.01 + tri()/8227.0 + noise()/12241.0 + dmc()/22638.0) + 100.0);
233 if(sbufp < sbuf + nelem(sbuf) - 1){
234 *sbufp++ = d * 10000;
235 *sbufp++ = d * 10000;
242 if((apuctr[DMCCTR] & 7) == 0){
245 apuctr[DMCSHFT] = memread(dmcaddr);
246 if(dmcaddr == 0xFFFF)
251 if((mem[DMCCTRL] & 0x40) != 0){
252 dmcaddr = mem[DMCADDR] * 0x40 + 0xC000;
253 dmccnt = mem[DMCLEN] * 0x10 + 1;
254 }else if((mem[DMCCTRL] & 0x80) != 0)
258 apuctr[DMCCTR] |= 0x80;
260 if((apuctr[DMCCTR] & 0x80) == 0){
261 if((apuctr[DMCSHFT] & 1) != 0){
262 if(mem[DMCBUF] < 126)
269 apuctr[DMCSHFT] >>= 1;
282 rc = write(fd, sbuf, (sbufp - sbuf) * 2);
293 fd = open("/dev/audio", OWRITE);
300 0x0A, 0xFE, 0x14, 0x02, 0x28, 0x04, 0x50, 0x06,
301 0xA0, 0x08, 0x3C, 0x0A, 0x0E, 0x0C, 0x1A, 0x0E,
302 0x0C, 0x10, 0x18, 0x12, 0x30, 0x14, 0x60, 0x16,
303 0xC0, 0x18, 0x48, 0x1A, 0x10, 0x1C, 0x20, 0x1E,
306 u16int dmclen[16] = {
307 0x1AC, 0x17C, 0x154, 0x140, 0x11E, 0x0FE, 0x0E2, 0x0D6,
308 0x0BE, 0x0A0, 0x08E, 0x080, 0x06A, 0x054, 0x048, 0x036,