ac6502 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +261 -0
- package/dist/components/CPU.js +1170 -0
- package/dist/components/CPU.js.map +1 -0
- package/dist/components/Cart.js +23 -0
- package/dist/components/Cart.js.map +1 -0
- package/dist/components/IO/Empty.js +19 -0
- package/dist/components/IO/Empty.js.map +1 -0
- package/dist/components/IO/GPIOAttachments/GPIOAttachment.js +71 -0
- package/dist/components/IO/GPIOAttachments/GPIOAttachment.js.map +1 -0
- package/dist/components/IO/GPIOAttachments/GPIOJoystickAttachment.js +90 -0
- package/dist/components/IO/GPIOAttachments/GPIOJoystickAttachment.js.map +1 -0
- package/dist/components/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.js +489 -0
- package/dist/components/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.js.map +1 -0
- package/dist/components/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.js +274 -0
- package/dist/components/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.js.map +1 -0
- package/dist/components/IO/GPIOCard.js +597 -0
- package/dist/components/IO/GPIOCard.js.map +1 -0
- package/dist/components/IO/InputBoard.js +19 -0
- package/dist/components/IO/InputBoard.js.map +1 -0
- package/dist/components/IO/LCDCard.js +19 -0
- package/dist/components/IO/LCDCard.js.map +1 -0
- package/dist/components/IO/RAMCard.js +63 -0
- package/dist/components/IO/RAMCard.js.map +1 -0
- package/dist/components/IO/RTCCard.js +483 -0
- package/dist/components/IO/RTCCard.js.map +1 -0
- package/dist/components/IO/SerialCard.js +282 -0
- package/dist/components/IO/SerialCard.js.map +1 -0
- package/dist/components/IO/SoundCard.js +620 -0
- package/dist/components/IO/SoundCard.js.map +1 -0
- package/dist/components/IO/StorageCard.js +428 -0
- package/dist/components/IO/StorageCard.js.map +1 -0
- package/dist/components/IO/VGACard.js +9 -0
- package/dist/components/IO/VGACard.js.map +1 -0
- package/dist/components/IO/VideoCard.js +623 -0
- package/dist/components/IO/VideoCard.js.map +1 -0
- package/dist/components/IO.js +3 -0
- package/dist/components/IO.js.map +1 -0
- package/dist/components/Machine.js +310 -0
- package/dist/components/Machine.js.map +1 -0
- package/dist/components/RAM.js +24 -0
- package/dist/components/RAM.js.map +1 -0
- package/dist/components/ROM.js +23 -0
- package/dist/components/ROM.js.map +1 -0
- package/dist/index.js +441 -0
- package/dist/index.js.map +1 -0
- package/dist/tests/CPU.test.js +1626 -0
- package/dist/tests/CPU.test.js.map +1 -0
- package/dist/tests/Cart.test.js +119 -0
- package/dist/tests/Cart.test.js.map +1 -0
- package/dist/tests/IO/GPIOAttachments/GPIOAttachment.test.js +339 -0
- package/dist/tests/IO/GPIOAttachments/GPIOAttachment.test.js.map +1 -0
- package/dist/tests/IO/GPIOAttachments/GPIOJoystickAttachment.test.js +126 -0
- package/dist/tests/IO/GPIOAttachments/GPIOJoystickAttachment.test.js.map +1 -0
- package/dist/tests/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.test.js +779 -0
- package/dist/tests/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.test.js.map +1 -0
- package/dist/tests/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.test.js +355 -0
- package/dist/tests/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.test.js.map +1 -0
- package/dist/tests/IO/GPIOCard.test.js +503 -0
- package/dist/tests/IO/GPIOCard.test.js.map +1 -0
- package/dist/tests/IO/RAMCard.test.js +229 -0
- package/dist/tests/IO/RAMCard.test.js.map +1 -0
- package/dist/tests/IO/RTCCard.test.js +177 -0
- package/dist/tests/IO/RTCCard.test.js.map +1 -0
- package/dist/tests/IO/SerialCard.test.js +423 -0
- package/dist/tests/IO/SerialCard.test.js.map +1 -0
- package/dist/tests/IO/SoundCard.test.js +528 -0
- package/dist/tests/IO/SoundCard.test.js.map +1 -0
- package/dist/tests/IO/StorageCard.test.js +647 -0
- package/dist/tests/IO/StorageCard.test.js.map +1 -0
- package/dist/tests/IO/VideoCard.test.js +549 -0
- package/dist/tests/IO/VideoCard.test.js.map +1 -0
- package/dist/tests/Machine.test.js +383 -0
- package/dist/tests/Machine.test.js.map +1 -0
- package/dist/tests/RAM.test.js +160 -0
- package/dist/tests/RAM.test.js.map +1 -0
- package/dist/tests/ROM.test.js +123 -0
- package/dist/tests/ROM.test.js.map +1 -0
- package/jest.config.cjs +9 -0
- package/package.json +43 -0
- package/src/components/CPU.ts +1371 -0
- package/src/components/Cart.ts +20 -0
- package/src/components/IO/GPIOAttachments/GPIOAttachment.ts +189 -0
- package/src/components/IO/GPIOAttachments/GPIOJoystickAttachment.ts +99 -0
- package/src/components/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.ts +465 -0
- package/src/components/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.ts +287 -0
- package/src/components/IO/GPIOCard.ts +677 -0
- package/src/components/IO/RAMCard.ts +68 -0
- package/src/components/IO/RTCCard.ts +518 -0
- package/src/components/IO/SerialCard.ts +335 -0
- package/src/components/IO/SoundCard.ts +711 -0
- package/src/components/IO/StorageCard.ts +473 -0
- package/src/components/IO/VideoCard.ts +730 -0
- package/src/components/IO.ts +11 -0
- package/src/components/Machine.ts +364 -0
- package/src/components/RAM.ts +23 -0
- package/src/components/ROM.ts +19 -0
- package/src/index.ts +474 -0
- package/src/tests/CPU.test.ts +2045 -0
- package/src/tests/Cart.test.ts +149 -0
- package/src/tests/IO/GPIOAttachments/GPIOAttachment.test.ts +413 -0
- package/src/tests/IO/GPIOAttachments/GPIOJoystickAttachment.test.ts +147 -0
- package/src/tests/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.test.ts +961 -0
- package/src/tests/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.test.ts +449 -0
- package/src/tests/IO/GPIOCard.test.ts +644 -0
- package/src/tests/IO/RAMCard.test.ts +284 -0
- package/src/tests/IO/RTCCard.test.ts +222 -0
- package/src/tests/IO/SerialCard.test.ts +530 -0
- package/src/tests/IO/SoundCard.test.ts +659 -0
- package/src/tests/IO/StorageCard.test.ts +787 -0
- package/src/tests/IO/VideoCard.test.ts +668 -0
- package/src/tests/Machine.test.ts +437 -0
- package/src/tests/RAM.test.ts +196 -0
- package/src/tests/ROM.test.ts +154 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SoundCard = exports.SIDVoice = exports.SID_CLOCK_PAL = exports.SID_CLOCK_NTSC = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* MOS 6581 SID (Sound Interface Device) Emulation
|
|
6
|
+
*
|
|
7
|
+
* Register Map ($00-$1C):
|
|
8
|
+
* Voice 1: $00-$06
|
|
9
|
+
* Voice 2: $07-$0D
|
|
10
|
+
* Voice 3: $0E-$14
|
|
11
|
+
* Filter: $15-$17
|
|
12
|
+
* Volume: $18
|
|
13
|
+
* Paddle: $19-$1A (read-only)
|
|
14
|
+
* OSC 3: $1B (read-only)
|
|
15
|
+
* ENV 3: $1C (read-only)
|
|
16
|
+
*
|
|
17
|
+
* Each voice has:
|
|
18
|
+
* Frequency (16-bit, lo/hi)
|
|
19
|
+
* Pulse Width (12-bit, lo/hi)
|
|
20
|
+
* Control Register (waveform select, gate, sync, ring mod, test)
|
|
21
|
+
* Attack/Decay (4-bit each)
|
|
22
|
+
* Sustain/Release (4-bit each)
|
|
23
|
+
*
|
|
24
|
+
* Waveforms: Triangle, Sawtooth, Pulse, Noise
|
|
25
|
+
* Filter: 12-bit cutoff, resonance, low/band/high-pass, voice routing
|
|
26
|
+
*
|
|
27
|
+
* Clock rate: ~1 MHz (NTSC: 1,022,727 Hz, PAL: 985,248 Hz)
|
|
28
|
+
* Output: mono audio samples passed via callback to the host emulator
|
|
29
|
+
*
|
|
30
|
+
* Reference: MOS 6581 SID datasheet, reSID by Dag Lem
|
|
31
|
+
*/
|
|
32
|
+
// ================================================================
|
|
33
|
+
// Constants
|
|
34
|
+
// ================================================================
|
|
35
|
+
/** Default SID clock rate (NTSC) */
|
|
36
|
+
exports.SID_CLOCK_NTSC = 1022727;
|
|
37
|
+
exports.SID_CLOCK_PAL = 985248;
|
|
38
|
+
/** Number of SID registers */
|
|
39
|
+
const NUM_REGISTERS = 29;
|
|
40
|
+
/** Cycles per tick from Machine.ts ioTickInterval */
|
|
41
|
+
const CYCLES_PER_TICK = 128;
|
|
42
|
+
// Register offsets within each voice (relative to voice base)
|
|
43
|
+
const REG_FREQ_LO = 0;
|
|
44
|
+
const REG_FREQ_HI = 1;
|
|
45
|
+
const REG_PW_LO = 2;
|
|
46
|
+
const REG_PW_HI = 3;
|
|
47
|
+
const REG_CONTROL = 4;
|
|
48
|
+
const REG_AD = 5;
|
|
49
|
+
const REG_SR = 6;
|
|
50
|
+
// Control register bits
|
|
51
|
+
const CTRL_GATE = 0x01;
|
|
52
|
+
const CTRL_SYNC = 0x02;
|
|
53
|
+
const CTRL_RING_MOD = 0x04;
|
|
54
|
+
const CTRL_TEST = 0x08;
|
|
55
|
+
const CTRL_TRIANGLE = 0x10;
|
|
56
|
+
const CTRL_SAWTOOTH = 0x20;
|
|
57
|
+
const CTRL_PULSE = 0x40;
|
|
58
|
+
const CTRL_NOISE = 0x80;
|
|
59
|
+
// Global register addresses
|
|
60
|
+
const REG_FC_LO = 0x15;
|
|
61
|
+
const REG_FC_HI = 0x16;
|
|
62
|
+
const REG_RES_FILT = 0x17;
|
|
63
|
+
const REG_MODE_VOL = 0x18;
|
|
64
|
+
const REG_POTX = 0x19;
|
|
65
|
+
const REG_POTY = 0x1A;
|
|
66
|
+
const REG_OSC3 = 0x1B;
|
|
67
|
+
const REG_ENV3 = 0x1C;
|
|
68
|
+
// ADSR timing tables: cycles per increment/decrement
|
|
69
|
+
// Based on the real SID chip's exponential envelope counter rates
|
|
70
|
+
// Index = 4-bit register value (0-15)
|
|
71
|
+
const ATTACK_RATES = [
|
|
72
|
+
2, 8, 16, 24, 38, 56, 68, 80,
|
|
73
|
+
100, 250, 500, 800, 1000, 3000, 5000, 8000,
|
|
74
|
+
];
|
|
75
|
+
const DECAY_RELEASE_RATES = [
|
|
76
|
+
6, 24, 48, 72, 114, 168, 204, 240,
|
|
77
|
+
300, 750, 1500, 2400, 3000, 9000, 15000, 24000,
|
|
78
|
+
];
|
|
79
|
+
// Sustain level table: maps 4-bit value to 8-bit level
|
|
80
|
+
const SUSTAIN_LEVELS = [
|
|
81
|
+
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
|
82
|
+
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
|
83
|
+
];
|
|
84
|
+
// Filter constants
|
|
85
|
+
const FILTER_LOWPASS = 0x10;
|
|
86
|
+
const FILTER_BANDPASS = 0x20;
|
|
87
|
+
const FILTER_HIGHPASS = 0x40;
|
|
88
|
+
const FILTER_3OFF = 0x80;
|
|
89
|
+
// ================================================================
|
|
90
|
+
// Voice
|
|
91
|
+
// ================================================================
|
|
92
|
+
class SIDVoice {
|
|
93
|
+
constructor() {
|
|
94
|
+
// Oscillator
|
|
95
|
+
this.accumulator = 0; // 24-bit phase accumulator
|
|
96
|
+
this.frequency = 0; // 16-bit frequency
|
|
97
|
+
this.pulseWidth = 0; // 12-bit pulse width
|
|
98
|
+
this.control = 0; // Control register
|
|
99
|
+
this.prevGate = false; // Previous gate state for edge detection
|
|
100
|
+
// Noise LFSR (23-bit, initial value)
|
|
101
|
+
this.noiseShift = 0x7FFFF8; // 23-bit noise shift register
|
|
102
|
+
// Waveform output (12-bit, 0-4095)
|
|
103
|
+
this.waveformOutput = 0;
|
|
104
|
+
// Envelope
|
|
105
|
+
this.envelopeState = 3 /* EnvelopeState.RELEASE */;
|
|
106
|
+
this.envelopeLevel = 0; // 0-255
|
|
107
|
+
this.envelopeCounter = 0; // Cycle counter for rate timing
|
|
108
|
+
this.attackRate = 0; // 4-bit attack value
|
|
109
|
+
this.decayRate = 0; // 4-bit decay value
|
|
110
|
+
this.sustainLevel = 0; // 4-bit sustain value
|
|
111
|
+
this.releaseRate = 0; // 4-bit release value
|
|
112
|
+
// Exponential counter for decay/release (models SID's exponential behavior)
|
|
113
|
+
this.exponentialCounter = 0;
|
|
114
|
+
this.exponentialCounterPeriod = 1;
|
|
115
|
+
}
|
|
116
|
+
reset() {
|
|
117
|
+
this.accumulator = 0;
|
|
118
|
+
this.frequency = 0;
|
|
119
|
+
this.pulseWidth = 0;
|
|
120
|
+
this.control = 0;
|
|
121
|
+
this.prevGate = false;
|
|
122
|
+
this.noiseShift = 0x7FFFF8;
|
|
123
|
+
this.waveformOutput = 0;
|
|
124
|
+
this.envelopeState = 3 /* EnvelopeState.RELEASE */;
|
|
125
|
+
this.envelopeLevel = 0;
|
|
126
|
+
this.envelopeCounter = 0;
|
|
127
|
+
this.attackRate = 0;
|
|
128
|
+
this.decayRate = 0;
|
|
129
|
+
this.sustainLevel = 0;
|
|
130
|
+
this.releaseRate = 0;
|
|
131
|
+
this.exponentialCounter = 0;
|
|
132
|
+
this.exponentialCounterPeriod = 1;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
exports.SIDVoice = SIDVoice;
|
|
136
|
+
// ================================================================
|
|
137
|
+
// SoundCard (SID)
|
|
138
|
+
// ================================================================
|
|
139
|
+
class SoundCard {
|
|
140
|
+
constructor() {
|
|
141
|
+
this.raiseIRQ = () => { };
|
|
142
|
+
this.raiseNMI = () => { };
|
|
143
|
+
// ---- SID Internal State ----
|
|
144
|
+
/** Raw register file (write-only from CPU perspective, except reads at $19-$1C) */
|
|
145
|
+
this.registers = new Uint8Array(NUM_REGISTERS);
|
|
146
|
+
/** Three oscillator voices */
|
|
147
|
+
this.voices = [
|
|
148
|
+
new SIDVoice(),
|
|
149
|
+
new SIDVoice(),
|
|
150
|
+
new SIDVoice(),
|
|
151
|
+
];
|
|
152
|
+
/** Filter state */
|
|
153
|
+
this.filterCutoff = 0; // 11-bit filter cutoff (register value)
|
|
154
|
+
this.filterResonance = 0; // 4-bit resonance
|
|
155
|
+
this.filterRouting = 0; // Which voices feed the filter (bits 0-2)
|
|
156
|
+
this.filterMode = 0; // LP/BP/HP/3OFF flags
|
|
157
|
+
this.masterVolume = 0; // 4-bit master volume
|
|
158
|
+
/** Filter integrator state (continuous) */
|
|
159
|
+
this.filterLP = 0;
|
|
160
|
+
this.filterBP = 0;
|
|
161
|
+
this.filterHP = 0;
|
|
162
|
+
/** Cycle accumulator for sample rate conversion */
|
|
163
|
+
this.cycleAccumulator = 0;
|
|
164
|
+
/** Target audio sample rate */
|
|
165
|
+
this.sampleRate = 44100;
|
|
166
|
+
/** SID clock rate */
|
|
167
|
+
this.sidClock = exports.SID_CLOCK_NTSC;
|
|
168
|
+
/** Internal sample buffer for pushing to host */
|
|
169
|
+
this.sampleBuffer = new Float32Array(4096);
|
|
170
|
+
this.sampleBufferIndex = 0;
|
|
171
|
+
}
|
|
172
|
+
// ================================================================
|
|
173
|
+
// IO Interface
|
|
174
|
+
// ================================================================
|
|
175
|
+
read(address) {
|
|
176
|
+
const reg = address & 0x1F;
|
|
177
|
+
switch (reg) {
|
|
178
|
+
case REG_POTX:
|
|
179
|
+
return this.registers[REG_POTX];
|
|
180
|
+
case REG_POTY:
|
|
181
|
+
return this.registers[REG_POTY];
|
|
182
|
+
case REG_OSC3:
|
|
183
|
+
// Return upper 8 bits of voice 3 waveform
|
|
184
|
+
return (this.voices[2].waveformOutput >> 4) & 0xFF;
|
|
185
|
+
case REG_ENV3:
|
|
186
|
+
// Return voice 3 envelope level
|
|
187
|
+
return this.voices[2].envelopeLevel;
|
|
188
|
+
default:
|
|
189
|
+
// All other SID registers are write-only
|
|
190
|
+
return 0;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
write(address, data) {
|
|
194
|
+
const reg = address & 0x1F;
|
|
195
|
+
if (reg >= NUM_REGISTERS)
|
|
196
|
+
return;
|
|
197
|
+
this.registers[reg] = data;
|
|
198
|
+
// Update internal state from register writes
|
|
199
|
+
if (reg <= 0x14) {
|
|
200
|
+
// Voice registers
|
|
201
|
+
const voiceIndex = Math.floor(reg / 7);
|
|
202
|
+
const voiceReg = reg % 7;
|
|
203
|
+
this.updateVoiceRegister(voiceIndex, voiceReg, data);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
// Global registers
|
|
207
|
+
this.updateGlobalRegister(reg, data);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
tick(frequency) {
|
|
211
|
+
// Each tick represents CYCLES_PER_TICK SID clock cycles
|
|
212
|
+
const cycles = CYCLES_PER_TICK;
|
|
213
|
+
for (let c = 0; c < cycles; c++) {
|
|
214
|
+
this.clockOneCycle();
|
|
215
|
+
// Sample rate conversion: accumulate and downsample
|
|
216
|
+
this.cycleAccumulator += this.sampleRate;
|
|
217
|
+
if (this.cycleAccumulator >= this.sidClock) {
|
|
218
|
+
this.cycleAccumulator -= this.sidClock;
|
|
219
|
+
const sample = this.generateSample();
|
|
220
|
+
this.sampleBuffer[this.sampleBufferIndex++] = sample;
|
|
221
|
+
// Buffer full - push to host
|
|
222
|
+
if (this.sampleBufferIndex >= this.sampleBuffer.length) {
|
|
223
|
+
this.flushSampleBuffer();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// Flush remaining samples
|
|
228
|
+
if (this.sampleBufferIndex > 0) {
|
|
229
|
+
this.flushSampleBuffer();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
reset(coldStart) {
|
|
233
|
+
this.registers.fill(0);
|
|
234
|
+
this.voices[0].reset();
|
|
235
|
+
this.voices[1].reset();
|
|
236
|
+
this.voices[2].reset();
|
|
237
|
+
this.filterCutoff = 0;
|
|
238
|
+
this.filterResonance = 0;
|
|
239
|
+
this.filterRouting = 0;
|
|
240
|
+
this.filterMode = 0;
|
|
241
|
+
this.masterVolume = 0;
|
|
242
|
+
this.filterLP = 0;
|
|
243
|
+
this.filterBP = 0;
|
|
244
|
+
this.filterHP = 0;
|
|
245
|
+
this.cycleAccumulator = 0;
|
|
246
|
+
this.sampleBufferIndex = 0;
|
|
247
|
+
}
|
|
248
|
+
// ================================================================
|
|
249
|
+
// Register Update Helpers
|
|
250
|
+
// ================================================================
|
|
251
|
+
updateVoiceRegister(voiceIndex, reg, data) {
|
|
252
|
+
const voice = this.voices[voiceIndex];
|
|
253
|
+
switch (reg) {
|
|
254
|
+
case REG_FREQ_LO:
|
|
255
|
+
voice.frequency = (voice.frequency & 0xFF00) | data;
|
|
256
|
+
break;
|
|
257
|
+
case REG_FREQ_HI:
|
|
258
|
+
voice.frequency = (voice.frequency & 0x00FF) | (data << 8);
|
|
259
|
+
break;
|
|
260
|
+
case REG_PW_LO:
|
|
261
|
+
voice.pulseWidth = (voice.pulseWidth & 0x0F00) | data;
|
|
262
|
+
break;
|
|
263
|
+
case REG_PW_HI:
|
|
264
|
+
voice.pulseWidth = (voice.pulseWidth & 0x00FF) | ((data & 0x0F) << 8);
|
|
265
|
+
break;
|
|
266
|
+
case REG_CONTROL: {
|
|
267
|
+
const gate = !!(data & CTRL_GATE);
|
|
268
|
+
const prevGate = voice.prevGate;
|
|
269
|
+
voice.control = data;
|
|
270
|
+
// Test bit resets accumulator and noise LFSR
|
|
271
|
+
if (data & CTRL_TEST) {
|
|
272
|
+
voice.accumulator = 0;
|
|
273
|
+
voice.noiseShift = 0x7FFFF8;
|
|
274
|
+
}
|
|
275
|
+
// Gate edge detection
|
|
276
|
+
if (gate && !prevGate) {
|
|
277
|
+
// Gate on: start attack
|
|
278
|
+
voice.envelopeState = 0 /* EnvelopeState.ATTACK */;
|
|
279
|
+
voice.envelopeCounter = 0;
|
|
280
|
+
voice.exponentialCounter = 0;
|
|
281
|
+
voice.exponentialCounterPeriod = 1;
|
|
282
|
+
}
|
|
283
|
+
else if (!gate && prevGate) {
|
|
284
|
+
// Gate off: start release
|
|
285
|
+
voice.envelopeState = 3 /* EnvelopeState.RELEASE */;
|
|
286
|
+
voice.envelopeCounter = 0;
|
|
287
|
+
}
|
|
288
|
+
voice.prevGate = gate;
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
case REG_AD:
|
|
292
|
+
voice.attackRate = (data >> 4) & 0x0F;
|
|
293
|
+
voice.decayRate = data & 0x0F;
|
|
294
|
+
break;
|
|
295
|
+
case REG_SR:
|
|
296
|
+
voice.sustainLevel = (data >> 4) & 0x0F;
|
|
297
|
+
voice.releaseRate = data & 0x0F;
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
updateGlobalRegister(reg, data) {
|
|
302
|
+
switch (reg) {
|
|
303
|
+
case REG_FC_LO:
|
|
304
|
+
// Filter cutoff low 3 bits
|
|
305
|
+
this.filterCutoff = (this.filterCutoff & 0x7F8) | (data & 0x07);
|
|
306
|
+
break;
|
|
307
|
+
case REG_FC_HI:
|
|
308
|
+
// Filter cutoff high 8 bits
|
|
309
|
+
this.filterCutoff = (this.filterCutoff & 0x07) | (data << 3);
|
|
310
|
+
break;
|
|
311
|
+
case REG_RES_FILT:
|
|
312
|
+
this.filterResonance = (data >> 4) & 0x0F;
|
|
313
|
+
this.filterRouting = data & 0x0F; // bits 0-2: voice routing, bit 3: external input
|
|
314
|
+
break;
|
|
315
|
+
case REG_MODE_VOL:
|
|
316
|
+
this.filterMode = data & 0xF0;
|
|
317
|
+
this.masterVolume = data & 0x0F;
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
// ================================================================
|
|
322
|
+
// Clock / Oscillator
|
|
323
|
+
// ================================================================
|
|
324
|
+
clockOneCycle() {
|
|
325
|
+
for (let i = 0; i < 3; i++) {
|
|
326
|
+
this.clockOscillator(i);
|
|
327
|
+
this.clockEnvelope(i);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
clockOscillator(voiceIndex) {
|
|
331
|
+
const voice = this.voices[voiceIndex];
|
|
332
|
+
// Don't clock if test bit is set
|
|
333
|
+
if (voice.control & CTRL_TEST)
|
|
334
|
+
return;
|
|
335
|
+
const prevAccBit19 = (voice.accumulator >> 19) & 1;
|
|
336
|
+
// Advance phase accumulator (24-bit)
|
|
337
|
+
voice.accumulator = (voice.accumulator + voice.frequency) & 0xFFFFFF;
|
|
338
|
+
const currAccBit19 = (voice.accumulator >> 19) & 1;
|
|
339
|
+
// Clock noise LFSR on bit 19 transition (0->1)
|
|
340
|
+
if (!prevAccBit19 && currAccBit19) {
|
|
341
|
+
// LFSR feedback: bit 17 XOR bit 22
|
|
342
|
+
const bit0 = ((voice.noiseShift >> 17) ^ (voice.noiseShift >> 22)) & 1;
|
|
343
|
+
voice.noiseShift = ((voice.noiseShift << 1) | bit0) & 0x7FFFFF;
|
|
344
|
+
}
|
|
345
|
+
// Hard sync: if this voice syncs to the previous voice,
|
|
346
|
+
// reset accumulator when sync source MSB transitions 0->1
|
|
347
|
+
if (voice.control & CTRL_SYNC) {
|
|
348
|
+
const syncSource = this.voices[(voiceIndex + 2) % 3];
|
|
349
|
+
const prevMSB = ((syncSource.accumulator - syncSource.frequency) >> 23) & 1;
|
|
350
|
+
const currMSB = (syncSource.accumulator >> 23) & 1;
|
|
351
|
+
if (!prevMSB && currMSB) {
|
|
352
|
+
voice.accumulator = 0;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
// Generate waveform output (12-bit, 0-4095)
|
|
356
|
+
voice.waveformOutput = this.generateWaveform(voiceIndex);
|
|
357
|
+
}
|
|
358
|
+
generateWaveform(voiceIndex) {
|
|
359
|
+
const voice = this.voices[voiceIndex];
|
|
360
|
+
const acc = voice.accumulator;
|
|
361
|
+
const control = voice.control;
|
|
362
|
+
// No waveform selected: output 0
|
|
363
|
+
if (!(control & 0xF0))
|
|
364
|
+
return 0;
|
|
365
|
+
let output = 0;
|
|
366
|
+
let waveformCount = 0;
|
|
367
|
+
// Triangle waveform (12-bit)
|
|
368
|
+
if (control & CTRL_TRIANGLE) {
|
|
369
|
+
let tri;
|
|
370
|
+
// Ring modulation: XOR with MSB of modulating voice
|
|
371
|
+
if (control & CTRL_RING_MOD) {
|
|
372
|
+
const modVoice = this.voices[(voiceIndex + 2) % 3];
|
|
373
|
+
const msb = ((acc >> 23) ^ (modVoice.accumulator >> 23)) & 1;
|
|
374
|
+
tri = msb
|
|
375
|
+
? (~(acc >> 11) & 0xFFF)
|
|
376
|
+
: ((acc >> 11) & 0xFFF);
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
const msb = (acc >> 23) & 1;
|
|
380
|
+
tri = msb
|
|
381
|
+
? (~(acc >> 11) & 0xFFF)
|
|
382
|
+
: ((acc >> 11) & 0xFFF);
|
|
383
|
+
}
|
|
384
|
+
output |= tri;
|
|
385
|
+
waveformCount++;
|
|
386
|
+
}
|
|
387
|
+
// Sawtooth waveform (12-bit)
|
|
388
|
+
if (control & CTRL_SAWTOOTH) {
|
|
389
|
+
const saw = (acc >> 12) & 0xFFF;
|
|
390
|
+
if (waveformCount > 0) {
|
|
391
|
+
output &= saw; // Combined waveforms use AND (SID behavior)
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
output = saw;
|
|
395
|
+
}
|
|
396
|
+
waveformCount++;
|
|
397
|
+
}
|
|
398
|
+
// Pulse waveform (12-bit)
|
|
399
|
+
if (control & CTRL_PULSE) {
|
|
400
|
+
const testBit = !!(control & CTRL_TEST);
|
|
401
|
+
const pulse = testBit
|
|
402
|
+
? 0xFFF // Test bit forces pulse high
|
|
403
|
+
: ((acc >> 12) >= voice.pulseWidth ? 0xFFF : 0x000);
|
|
404
|
+
if (waveformCount > 0) {
|
|
405
|
+
output &= pulse;
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
output = pulse;
|
|
409
|
+
}
|
|
410
|
+
waveformCount++;
|
|
411
|
+
}
|
|
412
|
+
// Noise waveform (12-bit, selected bits from LFSR)
|
|
413
|
+
if (control & CTRL_NOISE) {
|
|
414
|
+
// Extract bits from noise shift register
|
|
415
|
+
const noise = ((voice.noiseShift >> 12) & 0x800) |
|
|
416
|
+
((voice.noiseShift >> 10) & 0x400) |
|
|
417
|
+
((voice.noiseShift >> 7) & 0x200) |
|
|
418
|
+
((voice.noiseShift >> 5) & 0x100) |
|
|
419
|
+
((voice.noiseShift >> 4) & 0x080) |
|
|
420
|
+
((voice.noiseShift >> 1) & 0x040) |
|
|
421
|
+
((voice.noiseShift << 1) & 0x020) |
|
|
422
|
+
((voice.noiseShift << 2) & 0x010);
|
|
423
|
+
if (waveformCount > 0) {
|
|
424
|
+
output &= noise;
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
output = noise;
|
|
428
|
+
}
|
|
429
|
+
waveformCount++;
|
|
430
|
+
}
|
|
431
|
+
return output & 0xFFF;
|
|
432
|
+
}
|
|
433
|
+
// ================================================================
|
|
434
|
+
// Envelope Generator (ADSR)
|
|
435
|
+
// ================================================================
|
|
436
|
+
clockEnvelope(voiceIndex) {
|
|
437
|
+
const voice = this.voices[voiceIndex];
|
|
438
|
+
voice.envelopeCounter++;
|
|
439
|
+
switch (voice.envelopeState) {
|
|
440
|
+
case 0 /* EnvelopeState.ATTACK */: {
|
|
441
|
+
const rate = ATTACK_RATES[voice.attackRate];
|
|
442
|
+
if (voice.envelopeCounter >= rate) {
|
|
443
|
+
voice.envelopeCounter = 0;
|
|
444
|
+
voice.envelopeLevel++;
|
|
445
|
+
if (voice.envelopeLevel >= 0xFF) {
|
|
446
|
+
voice.envelopeLevel = 0xFF;
|
|
447
|
+
voice.envelopeState = 1 /* EnvelopeState.DECAY */;
|
|
448
|
+
voice.envelopeCounter = 0;
|
|
449
|
+
voice.exponentialCounter = 0;
|
|
450
|
+
this.updateExponentialPeriod(voice);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
break;
|
|
454
|
+
}
|
|
455
|
+
case 1 /* EnvelopeState.DECAY */: {
|
|
456
|
+
const rate = DECAY_RELEASE_RATES[voice.decayRate];
|
|
457
|
+
if (voice.envelopeCounter >= rate) {
|
|
458
|
+
voice.envelopeCounter = 0;
|
|
459
|
+
voice.exponentialCounter++;
|
|
460
|
+
if (voice.exponentialCounter >= voice.exponentialCounterPeriod) {
|
|
461
|
+
voice.exponentialCounter = 0;
|
|
462
|
+
if (voice.envelopeLevel > SUSTAIN_LEVELS[voice.sustainLevel]) {
|
|
463
|
+
voice.envelopeLevel--;
|
|
464
|
+
this.updateExponentialPeriod(voice);
|
|
465
|
+
}
|
|
466
|
+
if (voice.envelopeLevel <= SUSTAIN_LEVELS[voice.sustainLevel]) {
|
|
467
|
+
voice.envelopeLevel = SUSTAIN_LEVELS[voice.sustainLevel];
|
|
468
|
+
voice.envelopeState = 2 /* EnvelopeState.SUSTAIN */;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
break;
|
|
473
|
+
}
|
|
474
|
+
case 2 /* EnvelopeState.SUSTAIN */:
|
|
475
|
+
// Sustain stays at level until gate off
|
|
476
|
+
// Level tracks changes to sustain register
|
|
477
|
+
voice.envelopeLevel = SUSTAIN_LEVELS[voice.sustainLevel];
|
|
478
|
+
break;
|
|
479
|
+
case 3 /* EnvelopeState.RELEASE */: {
|
|
480
|
+
const rate = DECAY_RELEASE_RATES[voice.releaseRate];
|
|
481
|
+
if (voice.envelopeCounter >= rate) {
|
|
482
|
+
voice.envelopeCounter = 0;
|
|
483
|
+
voice.exponentialCounter++;
|
|
484
|
+
if (voice.exponentialCounter >= voice.exponentialCounterPeriod) {
|
|
485
|
+
voice.exponentialCounter = 0;
|
|
486
|
+
if (voice.envelopeLevel > 0) {
|
|
487
|
+
voice.envelopeLevel--;
|
|
488
|
+
this.updateExponentialPeriod(voice);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
break;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Update the exponential counter period based on current envelope level.
|
|
498
|
+
* The real SID uses an exponential curve for decay/release by varying
|
|
499
|
+
* the counter period at specific envelope level thresholds.
|
|
500
|
+
*/
|
|
501
|
+
updateExponentialPeriod(voice) {
|
|
502
|
+
if (voice.envelopeLevel >= 0x5D) {
|
|
503
|
+
voice.exponentialCounterPeriod = 1;
|
|
504
|
+
}
|
|
505
|
+
else if (voice.envelopeLevel >= 0x36) {
|
|
506
|
+
voice.exponentialCounterPeriod = 2;
|
|
507
|
+
}
|
|
508
|
+
else if (voice.envelopeLevel >= 0x1A) {
|
|
509
|
+
voice.exponentialCounterPeriod = 4;
|
|
510
|
+
}
|
|
511
|
+
else if (voice.envelopeLevel >= 0x0E) {
|
|
512
|
+
voice.exponentialCounterPeriod = 8;
|
|
513
|
+
}
|
|
514
|
+
else if (voice.envelopeLevel >= 0x06) {
|
|
515
|
+
voice.exponentialCounterPeriod = 16;
|
|
516
|
+
}
|
|
517
|
+
else if (voice.envelopeLevel >= 0x00) {
|
|
518
|
+
voice.exponentialCounterPeriod = 30;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
// ================================================================
|
|
522
|
+
// Sample Generation & Filter
|
|
523
|
+
// ================================================================
|
|
524
|
+
generateSample() {
|
|
525
|
+
let filtered = 0;
|
|
526
|
+
let direct = 0;
|
|
527
|
+
for (let i = 0; i < 3; i++) {
|
|
528
|
+
const voice = this.voices[i];
|
|
529
|
+
// Voice output: waveform (12-bit) * envelope (8-bit)
|
|
530
|
+
// Center around zero: subtract 0x800 from waveform to make it bipolar
|
|
531
|
+
const waveform = voice.waveformOutput - 0x800;
|
|
532
|
+
const output = (waveform * voice.envelopeLevel) / 256;
|
|
533
|
+
// Voice 3 mute (3OFF bit) - mutes voice 3 from audio but envelope still runs
|
|
534
|
+
if (i === 2 && (this.filterMode & FILTER_3OFF) && !(this.filterRouting & (1 << 2))) {
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
// Route to filter or direct output
|
|
538
|
+
if (this.filterRouting & (1 << i)) {
|
|
539
|
+
filtered += output;
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
direct += output;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
// Apply state-variable filter (SVF)
|
|
546
|
+
const cutoffFreq = this.computeFilterCutoff();
|
|
547
|
+
const w0 = (2 * Math.PI * cutoffFreq) / this.sampleRate;
|
|
548
|
+
const f = Math.min(w0, 0.9); // Clamp to avoid instability
|
|
549
|
+
// Resonance: Q ranges from ~0.7 to ~20 as register goes 0-15
|
|
550
|
+
const q = 1.0 / (1.0 - (this.filterResonance / 17.0));
|
|
551
|
+
// State variable filter update
|
|
552
|
+
this.filterHP = filtered - this.filterLP - (this.filterBP / q);
|
|
553
|
+
this.filterBP += f * this.filterHP;
|
|
554
|
+
this.filterLP += f * this.filterBP;
|
|
555
|
+
// Sum selected filter outputs
|
|
556
|
+
let filterOutput = 0;
|
|
557
|
+
if (this.filterMode & FILTER_LOWPASS)
|
|
558
|
+
filterOutput += this.filterLP;
|
|
559
|
+
if (this.filterMode & FILTER_BANDPASS)
|
|
560
|
+
filterOutput += this.filterBP;
|
|
561
|
+
if (this.filterMode & FILTER_HIGHPASS)
|
|
562
|
+
filterOutput += this.filterHP;
|
|
563
|
+
// Mix filtered and direct, apply master volume
|
|
564
|
+
const mixed = (filterOutput + direct) * (this.masterVolume / 15);
|
|
565
|
+
// Normalize to -1..1 range
|
|
566
|
+
const normalized = mixed / 4096;
|
|
567
|
+
// Clamp
|
|
568
|
+
return Math.max(-1, Math.min(1, normalized));
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Convert the 11-bit filter cutoff register value to a frequency in Hz.
|
|
572
|
+
* The SID's cutoff mapping is complex and varies between chips.
|
|
573
|
+
* This approximation covers the usable range (~30 Hz to ~12 kHz).
|
|
574
|
+
*/
|
|
575
|
+
computeFilterCutoff() {
|
|
576
|
+
const fc = this.filterCutoff;
|
|
577
|
+
if (fc === 0)
|
|
578
|
+
return 30;
|
|
579
|
+
// Piecewise approximation matching 6581 filter characteristics
|
|
580
|
+
const base = 30;
|
|
581
|
+
const maxFreq = 12000;
|
|
582
|
+
const normalized = fc / 2047;
|
|
583
|
+
return base + (maxFreq - base) * normalized * normalized;
|
|
584
|
+
}
|
|
585
|
+
// ================================================================
|
|
586
|
+
// Sample Buffer Management
|
|
587
|
+
// ================================================================
|
|
588
|
+
flushSampleBuffer() {
|
|
589
|
+
if (this.pushSamples && this.sampleBufferIndex > 0) {
|
|
590
|
+
const samples = this.sampleBuffer.subarray(0, this.sampleBufferIndex);
|
|
591
|
+
this.pushSamples(new Float32Array(samples));
|
|
592
|
+
}
|
|
593
|
+
this.sampleBufferIndex = 0;
|
|
594
|
+
}
|
|
595
|
+
// ================================================================
|
|
596
|
+
// Getters for testing / debug
|
|
597
|
+
// ================================================================
|
|
598
|
+
/** Get a voice for inspection */
|
|
599
|
+
getVoice(index) {
|
|
600
|
+
return this.voices[index];
|
|
601
|
+
}
|
|
602
|
+
/** Get current register value */
|
|
603
|
+
getRegister(reg) {
|
|
604
|
+
return this.registers[reg & 0x1F];
|
|
605
|
+
}
|
|
606
|
+
/** Get current filter cutoff frequency in Hz */
|
|
607
|
+
getFilterCutoffHz() {
|
|
608
|
+
return this.computeFilterCutoff();
|
|
609
|
+
}
|
|
610
|
+
/** Get master volume (0-15) */
|
|
611
|
+
getMasterVolume() {
|
|
612
|
+
return this.masterVolume;
|
|
613
|
+
}
|
|
614
|
+
/** Get filter routing bitmask */
|
|
615
|
+
getFilterRouting() {
|
|
616
|
+
return this.filterRouting;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
exports.SoundCard = SoundCard;
|
|
620
|
+
//# sourceMappingURL=SoundCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SoundCard.js","sourceRoot":"","sources":["../../../src/components/IO/SoundCard.ts"],"names":[],"mappings":"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"}
|