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.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +261 -0
  3. package/dist/components/CPU.js +1170 -0
  4. package/dist/components/CPU.js.map +1 -0
  5. package/dist/components/Cart.js +23 -0
  6. package/dist/components/Cart.js.map +1 -0
  7. package/dist/components/IO/Empty.js +19 -0
  8. package/dist/components/IO/Empty.js.map +1 -0
  9. package/dist/components/IO/GPIOAttachments/GPIOAttachment.js +71 -0
  10. package/dist/components/IO/GPIOAttachments/GPIOAttachment.js.map +1 -0
  11. package/dist/components/IO/GPIOAttachments/GPIOJoystickAttachment.js +90 -0
  12. package/dist/components/IO/GPIOAttachments/GPIOJoystickAttachment.js.map +1 -0
  13. package/dist/components/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.js +489 -0
  14. package/dist/components/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.js.map +1 -0
  15. package/dist/components/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.js +274 -0
  16. package/dist/components/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.js.map +1 -0
  17. package/dist/components/IO/GPIOCard.js +597 -0
  18. package/dist/components/IO/GPIOCard.js.map +1 -0
  19. package/dist/components/IO/InputBoard.js +19 -0
  20. package/dist/components/IO/InputBoard.js.map +1 -0
  21. package/dist/components/IO/LCDCard.js +19 -0
  22. package/dist/components/IO/LCDCard.js.map +1 -0
  23. package/dist/components/IO/RAMCard.js +63 -0
  24. package/dist/components/IO/RAMCard.js.map +1 -0
  25. package/dist/components/IO/RTCCard.js +483 -0
  26. package/dist/components/IO/RTCCard.js.map +1 -0
  27. package/dist/components/IO/SerialCard.js +282 -0
  28. package/dist/components/IO/SerialCard.js.map +1 -0
  29. package/dist/components/IO/SoundCard.js +620 -0
  30. package/dist/components/IO/SoundCard.js.map +1 -0
  31. package/dist/components/IO/StorageCard.js +428 -0
  32. package/dist/components/IO/StorageCard.js.map +1 -0
  33. package/dist/components/IO/VGACard.js +9 -0
  34. package/dist/components/IO/VGACard.js.map +1 -0
  35. package/dist/components/IO/VideoCard.js +623 -0
  36. package/dist/components/IO/VideoCard.js.map +1 -0
  37. package/dist/components/IO.js +3 -0
  38. package/dist/components/IO.js.map +1 -0
  39. package/dist/components/Machine.js +310 -0
  40. package/dist/components/Machine.js.map +1 -0
  41. package/dist/components/RAM.js +24 -0
  42. package/dist/components/RAM.js.map +1 -0
  43. package/dist/components/ROM.js +23 -0
  44. package/dist/components/ROM.js.map +1 -0
  45. package/dist/index.js +441 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/tests/CPU.test.js +1626 -0
  48. package/dist/tests/CPU.test.js.map +1 -0
  49. package/dist/tests/Cart.test.js +119 -0
  50. package/dist/tests/Cart.test.js.map +1 -0
  51. package/dist/tests/IO/GPIOAttachments/GPIOAttachment.test.js +339 -0
  52. package/dist/tests/IO/GPIOAttachments/GPIOAttachment.test.js.map +1 -0
  53. package/dist/tests/IO/GPIOAttachments/GPIOJoystickAttachment.test.js +126 -0
  54. package/dist/tests/IO/GPIOAttachments/GPIOJoystickAttachment.test.js.map +1 -0
  55. package/dist/tests/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.test.js +779 -0
  56. package/dist/tests/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.test.js.map +1 -0
  57. package/dist/tests/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.test.js +355 -0
  58. package/dist/tests/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.test.js.map +1 -0
  59. package/dist/tests/IO/GPIOCard.test.js +503 -0
  60. package/dist/tests/IO/GPIOCard.test.js.map +1 -0
  61. package/dist/tests/IO/RAMCard.test.js +229 -0
  62. package/dist/tests/IO/RAMCard.test.js.map +1 -0
  63. package/dist/tests/IO/RTCCard.test.js +177 -0
  64. package/dist/tests/IO/RTCCard.test.js.map +1 -0
  65. package/dist/tests/IO/SerialCard.test.js +423 -0
  66. package/dist/tests/IO/SerialCard.test.js.map +1 -0
  67. package/dist/tests/IO/SoundCard.test.js +528 -0
  68. package/dist/tests/IO/SoundCard.test.js.map +1 -0
  69. package/dist/tests/IO/StorageCard.test.js +647 -0
  70. package/dist/tests/IO/StorageCard.test.js.map +1 -0
  71. package/dist/tests/IO/VideoCard.test.js +549 -0
  72. package/dist/tests/IO/VideoCard.test.js.map +1 -0
  73. package/dist/tests/Machine.test.js +383 -0
  74. package/dist/tests/Machine.test.js.map +1 -0
  75. package/dist/tests/RAM.test.js +160 -0
  76. package/dist/tests/RAM.test.js.map +1 -0
  77. package/dist/tests/ROM.test.js +123 -0
  78. package/dist/tests/ROM.test.js.map +1 -0
  79. package/jest.config.cjs +9 -0
  80. package/package.json +43 -0
  81. package/src/components/CPU.ts +1371 -0
  82. package/src/components/Cart.ts +20 -0
  83. package/src/components/IO/GPIOAttachments/GPIOAttachment.ts +189 -0
  84. package/src/components/IO/GPIOAttachments/GPIOJoystickAttachment.ts +99 -0
  85. package/src/components/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.ts +465 -0
  86. package/src/components/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.ts +287 -0
  87. package/src/components/IO/GPIOCard.ts +677 -0
  88. package/src/components/IO/RAMCard.ts +68 -0
  89. package/src/components/IO/RTCCard.ts +518 -0
  90. package/src/components/IO/SerialCard.ts +335 -0
  91. package/src/components/IO/SoundCard.ts +711 -0
  92. package/src/components/IO/StorageCard.ts +473 -0
  93. package/src/components/IO/VideoCard.ts +730 -0
  94. package/src/components/IO.ts +11 -0
  95. package/src/components/Machine.ts +364 -0
  96. package/src/components/RAM.ts +23 -0
  97. package/src/components/ROM.ts +19 -0
  98. package/src/index.ts +474 -0
  99. package/src/tests/CPU.test.ts +2045 -0
  100. package/src/tests/Cart.test.ts +149 -0
  101. package/src/tests/IO/GPIOAttachments/GPIOAttachment.test.ts +413 -0
  102. package/src/tests/IO/GPIOAttachments/GPIOJoystickAttachment.test.ts +147 -0
  103. package/src/tests/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.test.ts +961 -0
  104. package/src/tests/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.test.ts +449 -0
  105. package/src/tests/IO/GPIOCard.test.ts +644 -0
  106. package/src/tests/IO/RAMCard.test.ts +284 -0
  107. package/src/tests/IO/RTCCard.test.ts +222 -0
  108. package/src/tests/IO/SerialCard.test.ts +530 -0
  109. package/src/tests/IO/SoundCard.test.ts +659 -0
  110. package/src/tests/IO/StorageCard.test.ts +787 -0
  111. package/src/tests/IO/VideoCard.test.ts +668 -0
  112. package/src/tests/Machine.test.ts +437 -0
  113. package/src/tests/RAM.test.ts +196 -0
  114. package/src/tests/ROM.test.ts +154 -0
  115. package/tsconfig.json +12 -0
@@ -0,0 +1,528 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const SoundCard_1 = require("../../components/IO/SoundCard");
4
+ // Voice register offsets (relative to voice base)
5
+ const VOICE1_BASE = 0x00;
6
+ const VOICE2_BASE = 0x07;
7
+ const VOICE3_BASE = 0x0E;
8
+ // Register offsets within each voice
9
+ const REG_FREQ_LO = 0;
10
+ const REG_FREQ_HI = 1;
11
+ const REG_PW_LO = 2;
12
+ const REG_PW_HI = 3;
13
+ const REG_CONTROL = 4;
14
+ const REG_AD = 5;
15
+ const REG_SR = 6;
16
+ // Global registers
17
+ const REG_FC_LO = 0x15;
18
+ const REG_FC_HI = 0x16;
19
+ const REG_RES_FILT = 0x17;
20
+ const REG_MODE_VOL = 0x18;
21
+ const REG_POTX = 0x19;
22
+ const REG_POTY = 0x1A;
23
+ const REG_OSC3 = 0x1B;
24
+ const REG_ENV3 = 0x1C;
25
+ // Control register bits
26
+ const CTRL_GATE = 0x01;
27
+ const CTRL_SYNC = 0x02;
28
+ const CTRL_RING_MOD = 0x04;
29
+ const CTRL_TEST = 0x08;
30
+ const CTRL_TRIANGLE = 0x10;
31
+ const CTRL_SAWTOOTH = 0x20;
32
+ const CTRL_PULSE = 0x40;
33
+ const CTRL_NOISE = 0x80;
34
+ /**
35
+ * Helper: tick the SoundCard for a given number of macro-ticks
36
+ * Each tick processes 128 SID clock cycles internally
37
+ */
38
+ const tickN = (sid, n) => {
39
+ for (let i = 0; i < n; i++) {
40
+ sid.tick(SoundCard_1.SID_CLOCK_NTSC);
41
+ }
42
+ };
43
+ describe('SoundCard (MOS 6581 SID)', () => {
44
+ let sid;
45
+ beforeEach(() => {
46
+ sid = new SoundCard_1.SoundCard();
47
+ sid.sampleRate = 44100;
48
+ sid.sidClock = SoundCard_1.SID_CLOCK_NTSC;
49
+ });
50
+ // ================================================================
51
+ // Initialization & Reset
52
+ // ================================================================
53
+ describe('initialization', () => {
54
+ test('should initialize with all registers zero', () => {
55
+ for (let i = 0; i < 29; i++) {
56
+ expect(sid.getRegister(i)).toBe(0);
57
+ }
58
+ });
59
+ test('should initialize with zero master volume', () => {
60
+ expect(sid.getMasterVolume()).toBe(0);
61
+ });
62
+ test('should initialize voices in release state with zero level', () => {
63
+ for (let i = 0; i < 3; i++) {
64
+ const voice = sid.getVoice(i);
65
+ expect(voice.envelopeLevel).toBe(0);
66
+ expect(voice.envelopeState).toBe(3 /* EnvelopeState.RELEASE */);
67
+ expect(voice.frequency).toBe(0);
68
+ expect(voice.pulseWidth).toBe(0);
69
+ expect(voice.control).toBe(0);
70
+ }
71
+ });
72
+ });
73
+ describe('reset', () => {
74
+ test('should clear all registers on reset', () => {
75
+ // Write some register values
76
+ sid.write(VOICE1_BASE + REG_FREQ_LO, 0xAB);
77
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0xCD);
78
+ sid.write(REG_MODE_VOL, 0x1F);
79
+ sid.reset(true);
80
+ for (let i = 0; i < 29; i++) {
81
+ expect(sid.getRegister(i)).toBe(0);
82
+ }
83
+ expect(sid.getMasterVolume()).toBe(0);
84
+ });
85
+ test('should reset all voice state', () => {
86
+ // Configure a voice and gate on
87
+ sid.write(VOICE1_BASE + REG_FREQ_LO, 0xFF);
88
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0xFF);
89
+ sid.write(VOICE1_BASE + REG_AD, 0x00);
90
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_TRIANGLE | CTRL_GATE);
91
+ tickN(sid, 10);
92
+ sid.reset(true);
93
+ const voice = sid.getVoice(0);
94
+ expect(voice.accumulator).toBe(0);
95
+ expect(voice.frequency).toBe(0);
96
+ expect(voice.envelopeLevel).toBe(0);
97
+ expect(voice.envelopeState).toBe(3 /* EnvelopeState.RELEASE */);
98
+ });
99
+ });
100
+ // ================================================================
101
+ // Register Read / Write
102
+ // ================================================================
103
+ describe('register writes', () => {
104
+ test('should set voice 1 frequency (16-bit)', () => {
105
+ sid.write(VOICE1_BASE + REG_FREQ_LO, 0x34);
106
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0x12);
107
+ expect(sid.getVoice(0).frequency).toBe(0x1234);
108
+ });
109
+ test('should set voice 2 frequency', () => {
110
+ sid.write(VOICE2_BASE + REG_FREQ_LO, 0xCD);
111
+ sid.write(VOICE2_BASE + REG_FREQ_HI, 0xAB);
112
+ expect(sid.getVoice(1).frequency).toBe(0xABCD);
113
+ });
114
+ test('should set voice 3 frequency', () => {
115
+ sid.write(VOICE3_BASE + REG_FREQ_LO, 0xFF);
116
+ sid.write(VOICE3_BASE + REG_FREQ_HI, 0xFF);
117
+ expect(sid.getVoice(2).frequency).toBe(0xFFFF);
118
+ });
119
+ test('should set pulse width (12-bit)', () => {
120
+ sid.write(VOICE1_BASE + REG_PW_LO, 0xFF);
121
+ sid.write(VOICE1_BASE + REG_PW_HI, 0x0F);
122
+ expect(sid.getVoice(0).pulseWidth).toBe(0xFFF);
123
+ });
124
+ test('should mask pulse width high byte to 4 bits', () => {
125
+ sid.write(VOICE1_BASE + REG_PW_LO, 0x00);
126
+ sid.write(VOICE1_BASE + REG_PW_HI, 0xFF); // Only lower 4 bits should matter
127
+ expect(sid.getVoice(0).pulseWidth).toBe(0x0F00);
128
+ });
129
+ test('should set attack/decay', () => {
130
+ sid.write(VOICE1_BASE + REG_AD, 0xA5);
131
+ const voice = sid.getVoice(0);
132
+ expect(voice.attackRate).toBe(0x0A);
133
+ expect(voice.decayRate).toBe(0x05);
134
+ });
135
+ test('should set sustain/release', () => {
136
+ sid.write(VOICE1_BASE + REG_SR, 0xC3);
137
+ const voice = sid.getVoice(0);
138
+ expect(voice.sustainLevel).toBe(0x0C);
139
+ expect(voice.releaseRate).toBe(0x03);
140
+ });
141
+ test('should set control register', () => {
142
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE);
143
+ expect(sid.getVoice(0).control).toBe(CTRL_SAWTOOTH | CTRL_GATE);
144
+ });
145
+ test('should set master volume', () => {
146
+ sid.write(REG_MODE_VOL, 0x0F);
147
+ expect(sid.getMasterVolume()).toBe(15);
148
+ });
149
+ test('should set filter cutoff (11-bit)', () => {
150
+ sid.write(REG_FC_LO, 0x07); // Low 3 bits
151
+ sid.write(REG_FC_HI, 0xFF); // High 8 bits
152
+ // Result: (0xFF << 3) | 0x07 = 0x7FF = 2047
153
+ expect(sid.getFilterCutoffHz()).toBeGreaterThan(30);
154
+ });
155
+ test('should set filter resonance and routing', () => {
156
+ sid.write(REG_RES_FILT, 0xF7); // Resonance=15, route voices 1-3
157
+ expect(sid.getFilterRouting()).toBe(0x07);
158
+ });
159
+ test('should ignore writes to addresses >= 29', () => {
160
+ sid.write(0x1D, 0xFF); // Out of range
161
+ // Should not crash
162
+ });
163
+ });
164
+ describe('register reads', () => {
165
+ test('should return 0 for write-only registers', () => {
166
+ sid.write(VOICE1_BASE + REG_FREQ_LO, 0xFF);
167
+ expect(sid.read(VOICE1_BASE + REG_FREQ_LO)).toBe(0);
168
+ });
169
+ test('should read POTX', () => {
170
+ // POTX is stored in register file
171
+ expect(sid.read(REG_POTX)).toBe(0);
172
+ });
173
+ test('should read POTY', () => {
174
+ expect(sid.read(REG_POTY)).toBe(0);
175
+ });
176
+ test('should read OSC3 (voice 3 waveform output)', () => {
177
+ // Initially 0
178
+ expect(sid.read(REG_OSC3)).toBe(0);
179
+ });
180
+ test('should read ENV3 (voice 3 envelope level)', () => {
181
+ expect(sid.read(REG_ENV3)).toBe(0);
182
+ });
183
+ test('should read ENV3 after voice 3 attack', () => {
184
+ // Set voice 3 to fastest attack, sawtooth waveform
185
+ sid.write(VOICE3_BASE + REG_FREQ_HI, 0x10);
186
+ sid.write(VOICE3_BASE + REG_AD, 0x00); // fastest attack
187
+ sid.write(VOICE3_BASE + REG_SR, 0xF0); // max sustain
188
+ sid.write(VOICE3_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE);
189
+ // Tick enough for the envelope to rise
190
+ tickN(sid, 50);
191
+ expect(sid.read(REG_ENV3)).toBeGreaterThan(0);
192
+ });
193
+ test('should wrap register address to 5 bits', () => {
194
+ // Address 0x3B should wrap to 0x1B (OSC3)
195
+ expect(sid.read(0x3B)).toBe(sid.read(REG_OSC3));
196
+ });
197
+ });
198
+ // ================================================================
199
+ // Gate / Envelope
200
+ // ================================================================
201
+ describe('envelope generator', () => {
202
+ test('should start attack on gate on', () => {
203
+ sid.write(VOICE1_BASE + REG_AD, 0x00); // fastest attack/decay
204
+ sid.write(VOICE1_BASE + REG_SR, 0xF0); // max sustain
205
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_TRIANGLE | CTRL_GATE);
206
+ const voice = sid.getVoice(0);
207
+ expect(voice.envelopeState).toBe(0 /* EnvelopeState.ATTACK */);
208
+ });
209
+ test('should increase envelope level during attack', () => {
210
+ sid.write(VOICE1_BASE + REG_AD, 0x00); // fastest attack
211
+ sid.write(VOICE1_BASE + REG_SR, 0xF0); // max sustain
212
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_TRIANGLE | CTRL_GATE);
213
+ tickN(sid, 10);
214
+ expect(sid.getVoice(0).envelopeLevel).toBeGreaterThan(0);
215
+ });
216
+ test('should reach max level and transition to decay', () => {
217
+ sid.write(VOICE1_BASE + REG_AD, 0x00); // fastest attack/decay
218
+ sid.write(VOICE1_BASE + REG_SR, 0x80); // sustain=8, release=0
219
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_TRIANGLE | CTRL_GATE);
220
+ // Tick enough times for attack to complete (fastest = 2 cycles per step, 255 steps)
221
+ tickN(sid, 20);
222
+ const voice = sid.getVoice(0);
223
+ // Should have reached 255 and started decay
224
+ expect(voice.envelopeLevel).toBeLessThanOrEqual(255);
225
+ });
226
+ test('should transition to release on gate off', () => {
227
+ sid.write(VOICE1_BASE + REG_AD, 0x00);
228
+ sid.write(VOICE1_BASE + REG_SR, 0xF0);
229
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_TRIANGLE | CTRL_GATE);
230
+ tickN(sid, 20); // Let attack progress
231
+ // Gate off
232
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_TRIANGLE); // gate off
233
+ const voice = sid.getVoice(0);
234
+ expect(voice.envelopeState).toBe(3 /* EnvelopeState.RELEASE */);
235
+ });
236
+ test('should decrease envelope during release', () => {
237
+ // Gate on with fast attack
238
+ sid.write(VOICE1_BASE + REG_AD, 0x00);
239
+ sid.write(VOICE1_BASE + REG_SR, 0xF0); // max sustain, fastest release
240
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_TRIANGLE | CTRL_GATE);
241
+ tickN(sid, 20);
242
+ const levelBeforeRelease = sid.getVoice(0).envelopeLevel;
243
+ expect(levelBeforeRelease).toBeGreaterThan(0);
244
+ // Gate off
245
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_TRIANGLE);
246
+ tickN(sid, 20);
247
+ expect(sid.getVoice(0).envelopeLevel).toBeLessThan(levelBeforeRelease);
248
+ });
249
+ });
250
+ // ================================================================
251
+ // Control Register Features
252
+ // ================================================================
253
+ describe('control register', () => {
254
+ test('test bit should reset accumulator', () => {
255
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0xFF);
256
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE);
257
+ tickN(sid, 5);
258
+ // Set test bit
259
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE | CTRL_TEST);
260
+ expect(sid.getVoice(0).accumulator).toBe(0);
261
+ });
262
+ test('test bit should reset noise LFSR', () => {
263
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_NOISE | CTRL_GATE);
264
+ tickN(sid, 10);
265
+ // Set test bit
266
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_NOISE | CTRL_GATE | CTRL_TEST);
267
+ expect(sid.getVoice(0).noiseShift).toBe(0x7FFFF8);
268
+ });
269
+ test('should handle multiple waveform selection', () => {
270
+ // Select both triangle and sawtooth (combined waveforms use AND)
271
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0x10);
272
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_TRIANGLE | CTRL_SAWTOOTH | CTRL_GATE);
273
+ sid.write(REG_MODE_VOL, 0x0F);
274
+ tickN(sid, 5);
275
+ // Should not crash and voice should produce output
276
+ const voice = sid.getVoice(0);
277
+ expect(voice.waveformOutput).toBeDefined();
278
+ });
279
+ });
280
+ // ================================================================
281
+ // Oscillator / Waveforms
282
+ // ================================================================
283
+ describe('oscillator', () => {
284
+ test('accumulator should advance by frequency each cycle', () => {
285
+ sid.write(VOICE1_BASE + REG_FREQ_LO, 0x00);
286
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0x01); // freq = 256
287
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE);
288
+ // After one tick (128 cycles), accumulator should be 256 * 128 = 32768
289
+ tickN(sid, 1);
290
+ const voice = sid.getVoice(0);
291
+ expect(voice.accumulator).toBe(256 * 128);
292
+ });
293
+ test('accumulator should wrap at 24 bits', () => {
294
+ sid.write(VOICE1_BASE + REG_FREQ_LO, 0xFF);
295
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0xFF); // max frequency
296
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE);
297
+ // Many ticks should cause wrapping
298
+ tickN(sid, 200);
299
+ const voice = sid.getVoice(0);
300
+ expect(voice.accumulator).toBeLessThan(0x1000000);
301
+ });
302
+ test('sawtooth should produce non-zero output', () => {
303
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0x10);
304
+ sid.write(VOICE1_BASE + REG_AD, 0x00);
305
+ sid.write(VOICE1_BASE + REG_SR, 0xF0);
306
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE);
307
+ sid.write(REG_MODE_VOL, 0x0F);
308
+ tickN(sid, 10);
309
+ const voice = sid.getVoice(0);
310
+ // Sawtooth = acc >> 12, with some frequency should be non-zero
311
+ expect(voice.waveformOutput).toBeGreaterThanOrEqual(0);
312
+ });
313
+ test('pulse waveform should depend on pulse width', () => {
314
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0x10);
315
+ sid.write(VOICE1_BASE + REG_PW_LO, 0x00);
316
+ sid.write(VOICE1_BASE + REG_PW_HI, 0x08); // 50% duty cycle (0x800)
317
+ sid.write(VOICE1_BASE + REG_AD, 0x00);
318
+ sid.write(VOICE1_BASE + REG_SR, 0xF0);
319
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_PULSE | CTRL_GATE);
320
+ tickN(sid, 20);
321
+ // Pulse output should be either 0x000 or 0xFFF
322
+ const voice = sid.getVoice(0);
323
+ const output = voice.waveformOutput;
324
+ expect(output === 0x000 || output === 0xFFF).toBe(true);
325
+ });
326
+ test('no waveform selected should output 0', () => {
327
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0x10);
328
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_GATE); // gate on but no waveform
329
+ tickN(sid, 5);
330
+ expect(sid.getVoice(0).waveformOutput).toBe(0);
331
+ });
332
+ });
333
+ // ================================================================
334
+ // Filter
335
+ // ================================================================
336
+ describe('filter', () => {
337
+ test('should set filter cutoff from registers', () => {
338
+ sid.write(REG_FC_LO, 0x07);
339
+ sid.write(REG_FC_HI, 0xFF);
340
+ expect(sid.getFilterCutoffHz()).toBeGreaterThan(30);
341
+ });
342
+ test('should return minimum cutoff for zero register value', () => {
343
+ sid.write(REG_FC_LO, 0x00);
344
+ sid.write(REG_FC_HI, 0x00);
345
+ expect(sid.getFilterCutoffHz()).toBe(30);
346
+ });
347
+ test('should set filter voice routing', () => {
348
+ sid.write(REG_RES_FILT, 0x03); // Route voices 1 and 2 to filter
349
+ expect(sid.getFilterRouting()).toBe(0x03);
350
+ });
351
+ test('should set filter mode in volume register', () => {
352
+ sid.write(REG_MODE_VOL, 0x1F); // Low-pass, volume=15
353
+ expect(sid.getMasterVolume()).toBe(15);
354
+ });
355
+ });
356
+ // ================================================================
357
+ // Audio Output / pushSamples Callback
358
+ // ================================================================
359
+ describe('audio output', () => {
360
+ test('should call pushSamples during tick', () => {
361
+ const receivedSamples = [];
362
+ sid.pushSamples = (samples) => {
363
+ receivedSamples.push(new Float32Array(samples));
364
+ };
365
+ // Set up a voice producing sound
366
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0x10);
367
+ sid.write(VOICE1_BASE + REG_AD, 0x00);
368
+ sid.write(VOICE1_BASE + REG_SR, 0xF0);
369
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE);
370
+ sid.write(REG_MODE_VOL, 0x0F);
371
+ tickN(sid, 100);
372
+ // Should have received some sample data
373
+ expect(receivedSamples.length).toBeGreaterThan(0);
374
+ // Samples should be valid floats
375
+ const firstBatch = receivedSamples[0];
376
+ for (let i = 0; i < firstBatch.length; i++) {
377
+ expect(firstBatch[i]).toBeGreaterThanOrEqual(-1);
378
+ expect(firstBatch[i]).toBeLessThanOrEqual(1);
379
+ }
380
+ });
381
+ test('should produce silence with zero volume', () => {
382
+ const receivedSamples = [];
383
+ sid.pushSamples = (samples) => {
384
+ receivedSamples.push(new Float32Array(samples));
385
+ };
386
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0x10);
387
+ sid.write(VOICE1_BASE + REG_AD, 0x00);
388
+ sid.write(VOICE1_BASE + REG_SR, 0xF0);
389
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE);
390
+ sid.write(REG_MODE_VOL, 0x00); // Volume = 0
391
+ tickN(sid, 100);
392
+ // All samples should be near zero (silence)
393
+ for (const batch of receivedSamples) {
394
+ for (let i = 0; i < batch.length; i++) {
395
+ expect(Math.abs(batch[i])).toBeLessThan(0.001);
396
+ }
397
+ }
398
+ });
399
+ test('should not call pushSamples if callback not set', () => {
400
+ sid.pushSamples = undefined;
401
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0x10);
402
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE);
403
+ sid.write(REG_MODE_VOL, 0x0F);
404
+ // Should not throw
405
+ expect(() => tickN(sid, 10)).not.toThrow();
406
+ });
407
+ test('should produce sound from all three voices simultaneously', () => {
408
+ const receivedSamples = [];
409
+ sid.pushSamples = (samples) => {
410
+ receivedSamples.push(new Float32Array(samples));
411
+ };
412
+ // Voice 1: triangle
413
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0x10);
414
+ sid.write(VOICE1_BASE + REG_AD, 0x00);
415
+ sid.write(VOICE1_BASE + REG_SR, 0xF0);
416
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_TRIANGLE | CTRL_GATE);
417
+ // Voice 2: sawtooth
418
+ sid.write(VOICE2_BASE + REG_FREQ_HI, 0x20);
419
+ sid.write(VOICE2_BASE + REG_AD, 0x00);
420
+ sid.write(VOICE2_BASE + REG_SR, 0xF0);
421
+ sid.write(VOICE2_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE);
422
+ // Voice 3: pulse
423
+ sid.write(VOICE3_BASE + REG_FREQ_HI, 0x30);
424
+ sid.write(VOICE3_BASE + REG_PW_HI, 0x08);
425
+ sid.write(VOICE3_BASE + REG_AD, 0x00);
426
+ sid.write(VOICE3_BASE + REG_SR, 0xF0);
427
+ sid.write(VOICE3_BASE + REG_CONTROL, CTRL_PULSE | CTRL_GATE);
428
+ sid.write(REG_MODE_VOL, 0x0F);
429
+ tickN(sid, 100);
430
+ expect(receivedSamples.length).toBeGreaterThan(0);
431
+ // Check that some samples are non-zero (sound is being produced)
432
+ const hasNonZero = receivedSamples.some(batch => {
433
+ for (let i = 0; i < batch.length; i++) {
434
+ if (Math.abs(batch[i]) > 0.001)
435
+ return true;
436
+ }
437
+ return false;
438
+ });
439
+ expect(hasNonZero).toBe(true);
440
+ });
441
+ });
442
+ // ================================================================
443
+ // Multi-voice & Special Features
444
+ // ================================================================
445
+ describe('special features', () => {
446
+ test('voice 3 mute (3OFF) should suppress voice 3 audio', () => {
447
+ const samplesWithVoice3 = [];
448
+ const samplesWithout = [];
449
+ // First: voice 3 unmuted
450
+ sid.write(VOICE3_BASE + REG_FREQ_HI, 0x20);
451
+ sid.write(VOICE3_BASE + REG_AD, 0x00);
452
+ sid.write(VOICE3_BASE + REG_SR, 0xF0);
453
+ sid.write(VOICE3_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE);
454
+ sid.write(REG_MODE_VOL, 0x0F); // No 3OFF
455
+ sid.pushSamples = (samples) => {
456
+ samplesWithVoice3.push(new Float32Array(samples));
457
+ };
458
+ tickN(sid, 50);
459
+ // Now mute voice 3 (set 3OFF = 0x80 in mode/vol)
460
+ sid.reset(true);
461
+ sid.write(VOICE3_BASE + REG_FREQ_HI, 0x20);
462
+ sid.write(VOICE3_BASE + REG_AD, 0x00);
463
+ sid.write(VOICE3_BASE + REG_SR, 0xF0);
464
+ sid.write(VOICE3_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE);
465
+ sid.write(REG_MODE_VOL, 0x8F); // 3OFF + volume=15
466
+ sid.pushSamples = (samples) => {
467
+ samplesWithout.push(new Float32Array(samples));
468
+ };
469
+ tickN(sid, 50);
470
+ // The muted version should have less total energy
471
+ const energy = (batches) => {
472
+ let sum = 0;
473
+ for (const b of batches) {
474
+ for (let i = 0; i < b.length; i++)
475
+ sum += b[i] * b[i];
476
+ }
477
+ return sum;
478
+ };
479
+ const energyWith = energy(samplesWithVoice3);
480
+ const energyWithout = energy(samplesWithout);
481
+ // When voice 3 is muted via 3OFF and NOT routed to filter, it should be silent
482
+ expect(energyWithout).toBeLessThan(energyWith);
483
+ });
484
+ test('should handle rapid gate on/off', () => {
485
+ sid.write(VOICE1_BASE + REG_FREQ_HI, 0x10);
486
+ sid.write(VOICE1_BASE + REG_AD, 0x00);
487
+ sid.write(VOICE1_BASE + REG_SR, 0xF0);
488
+ sid.write(REG_MODE_VOL, 0x0F);
489
+ // Rapid gate toggling
490
+ for (let i = 0; i < 20; i++) {
491
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_SAWTOOTH | CTRL_GATE); // on
492
+ tickN(sid, 2);
493
+ sid.write(VOICE1_BASE + REG_CONTROL, CTRL_SAWTOOTH); // off
494
+ tickN(sid, 2);
495
+ }
496
+ // Should not crash or produce invalid state
497
+ const voice = sid.getVoice(0);
498
+ expect(voice.envelopeLevel).toBeLessThanOrEqual(255);
499
+ expect(voice.envelopeLevel).toBeGreaterThanOrEqual(0);
500
+ });
501
+ });
502
+ // ================================================================
503
+ // IO Interface Compliance
504
+ // ================================================================
505
+ describe('IO interface', () => {
506
+ test('should have raiseIRQ and raiseNMI callbacks', () => {
507
+ expect(sid.raiseIRQ).toBeDefined();
508
+ expect(sid.raiseNMI).toBeDefined();
509
+ expect(typeof sid.raiseIRQ).toBe('function');
510
+ expect(typeof sid.raiseNMI).toBe('function');
511
+ });
512
+ test('read should handle any address value', () => {
513
+ // Should not throw for any address
514
+ for (let addr = 0; addr < 64; addr++) {
515
+ expect(() => sid.read(addr)).not.toThrow();
516
+ }
517
+ });
518
+ test('write should handle any address/data combination', () => {
519
+ for (let addr = 0; addr < 64; addr++) {
520
+ expect(() => sid.write(addr, 0xFF)).not.toThrow();
521
+ }
522
+ });
523
+ test('tick should not throw when called repeatedly', () => {
524
+ expect(() => tickN(sid, 100)).not.toThrow();
525
+ });
526
+ });
527
+ });
528
+ //# sourceMappingURL=SoundCard.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SoundCard.test.js","sourceRoot":"","sources":["../../../src/tests/IO/SoundCard.test.ts"],"names":[],"mappings":"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"}