8 u8int apuseq, apuctr[10];
11 enum { RATE = 44100 };
18 m = mem[0x4001 + i * 4];
19 p = mem[0x4002 + i * 4];
20 p |= (mem[0x4003 + i * 4] & 7) << 8;
37 for(i = 0; i < 4; i++){
38 m = mem[0x4000 + i * 4];
46 for(i = 0, a = apuctr + 8; i < 2; i++, a++){
47 m = mem[0x4001 + i * 4];
48 if((m & 0x80) != 0 && (m & 0x07) != 0 && (*a & 7) == 0){
51 mem[0x4002 + i * 4] = p;
52 mem[0x4003 + i * 4] = p >> 8;
55 if((*a & 0x80) != 0 || (*a & 7) == 0 && (m & 0x80) != 0)
68 for(i = 0, a = apuctr + 4; i < 4; i++, a++){
71 m = mem[0x4000 + 4 * i];
73 *a = *a & 0x70 | 0x0f;
93 if((mode & 0x80) != 0){
99 len = (apuseq & 1) == 0;
104 len = (apuseq & 1) != 0;
106 if((mode & 0x40) == 0)
123 f = mem[0x4002 + 4 * i];
124 f |= (mem[0x4003 + 4 * i] & 0x7) << 8;
135 if(f < 8 || targperiod(i) > 0x7ff)
138 f = muldiv(16 * (f + 1), RATE, FREQ/12);
143 m = mem[0x4000 + 4 * i];
149 if(c[i] >= f/2 || apuctr[i] == 0)
163 f = muldiv(32 * (f + 1), RATE, FREQ / 12);
169 i ^= (i < 16) ? 0xf : 0x10;
170 if(apuctr[2] == 0 || (apuctr[6] & 0x7f) == 0)
181 0x004, 0x008, 0x010, 0x020, 0x040, 0x060, 0x080, 0x0A0,
182 0x0CA, 0x0FE, 0x17C, 0x1FC, 0x2FA, 0x3F8, 0x7F2, 0xFE4,
186 f = muldiv(per[m & 0x0f], RATE * 1000, FREQ/24);
189 r |= ((r ^ (r >> ((m & 0x80) != 0 ? 6 : 1))) & 1) << 15;
193 if(apuctr[3] == 0 || (r & 1) != 0)
198 return apuctr[7] & 0xf;
212 d = 95.88 / (8128.0 / (0.01 + pulse(0) + pulse(1)) + 100);
213 d += 159.79 / (1.0 / (0.01 + tri()/8227.0 + noise()/12241.0 + dmc()/22638.0) + 100.0);
221 static short samples[500 * 2];
226 memset(samples, 0, sizeof samples);
228 for(i = 0; i < sizeof samples/4; i++)
229 sample(samples + 2 * i);
230 write(fd, samples, sizeof samples);
237 fd = open("/dev/audio", OWRITE);
240 proccreate(audioproc, nil, 8192);
244 0x0A, 0xFE, 0x14, 0x02, 0x28, 0x04, 0x50, 0x06,
245 0xA0, 0x08, 0x3C, 0x0A, 0x0E, 0x0C, 0x1A, 0x0E,
246 0x0C, 0x10, 0x18, 0x12, 0x30, 0x14, 0x60, 0x16,
247 0xC0, 0x18, 0x48, 0x1A, 0x10, 0x1C, 0x20, 0x1E,