ac6502 1.2.0 → 1.4.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 (182) hide show
  1. package/README.md +12 -12
  2. package/dist/components/CPU.d.ts +162 -0
  3. package/dist/components/Cart.d.ts +9 -0
  4. package/dist/components/IO/ACIA.d.ts +76 -0
  5. package/dist/components/IO/ACIA.js +282 -0
  6. package/dist/components/IO/ACIA.js.map +1 -0
  7. package/dist/components/IO/Attachments/Attachment.d.ts +112 -0
  8. package/dist/components/IO/Attachments/Attachment.js +71 -0
  9. package/dist/components/IO/Attachments/Attachment.js.map +1 -0
  10. package/dist/components/IO/Attachments/JoystickAttachment.d.ts +53 -0
  11. package/dist/components/IO/Attachments/JoystickAttachment.js +90 -0
  12. package/dist/components/IO/Attachments/JoystickAttachment.js.map +1 -0
  13. package/dist/components/IO/Attachments/KeyboardEncoderAttachment.d.ts +63 -0
  14. package/dist/components/IO/Attachments/KeyboardEncoderAttachment.js +489 -0
  15. package/dist/components/IO/Attachments/KeyboardEncoderAttachment.js.map +1 -0
  16. package/dist/components/IO/Attachments/KeyboardMatrixAttachment.d.ts +44 -0
  17. package/dist/components/IO/Attachments/KeyboardMatrixAttachment.js +274 -0
  18. package/dist/components/IO/Attachments/KeyboardMatrixAttachment.js.map +1 -0
  19. package/dist/components/IO/Attachments/KeypadAttachment.d.ts +47 -0
  20. package/dist/components/IO/Attachments/KeypadAttachment.js +141 -0
  21. package/dist/components/IO/Attachments/KeypadAttachment.js.map +1 -0
  22. package/dist/components/IO/Attachments/LCDAttachment.d.ts +110 -0
  23. package/dist/components/IO/Attachments/LCDAttachment.js +716 -0
  24. package/dist/components/IO/Attachments/LCDAttachment.js.map +1 -0
  25. package/dist/components/IO/Attachments/SNESAttachment.d.ts +85 -0
  26. package/dist/components/IO/Attachments/SNESAttachment.js +184 -0
  27. package/dist/components/IO/Attachments/SNESAttachment.js.map +1 -0
  28. package/dist/components/IO/DevOutputBoard.d.ts +19 -0
  29. package/dist/components/IO/DevOutputBoard.js +33 -0
  30. package/dist/components/IO/DevOutputBoard.js.map +1 -0
  31. package/dist/components/IO/Empty.d.ts +9 -0
  32. package/dist/components/IO/Empty.js +5 -7
  33. package/dist/components/IO/Empty.js.map +1 -1
  34. package/dist/components/IO/EmptyCard.d.ts +9 -0
  35. package/dist/components/IO/GPIOAttachments/GPIOAttachment.d.ts +112 -0
  36. package/dist/components/IO/GPIOAttachments/GPIOJoystickAttachment.d.ts +53 -0
  37. package/dist/components/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.d.ts +63 -0
  38. package/dist/components/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.d.ts +44 -0
  39. package/dist/components/IO/GPIOAttachments/GPIOKeypadAttachment.d.ts +47 -0
  40. package/dist/components/IO/GPIOAttachments/GPIOLCDAttachment.d.ts +110 -0
  41. package/dist/components/IO/GPIOCard.d.ts +105 -0
  42. package/dist/components/IO/GPIOCard.js.map +1 -1
  43. package/dist/components/IO/RAMBank.d.ts +37 -0
  44. package/dist/components/IO/RAMBank.js +63 -0
  45. package/dist/components/IO/RAMBank.js.map +1 -0
  46. package/dist/components/IO/RAMCard.d.ts +37 -0
  47. package/dist/components/IO/RTC.d.ts +107 -0
  48. package/dist/components/IO/RTC.js +483 -0
  49. package/dist/components/IO/RTC.js.map +1 -0
  50. package/dist/components/IO/RTCCard.d.ts +107 -0
  51. package/dist/components/IO/SerialCard.d.ts +76 -0
  52. package/dist/components/IO/Sound.d.ts +120 -0
  53. package/dist/components/IO/Sound.js +622 -0
  54. package/dist/components/IO/Sound.js.map +1 -0
  55. package/dist/components/IO/SoundCard.d.ts +120 -0
  56. package/dist/components/IO/Storage.d.ts +74 -0
  57. package/dist/components/IO/Storage.js +409 -0
  58. package/dist/components/IO/Storage.js.map +1 -0
  59. package/dist/components/IO/StorageCard.d.ts +74 -0
  60. package/dist/components/IO/Terminal.d.ts +19 -0
  61. package/dist/components/IO/Terminal.js +33 -0
  62. package/dist/components/IO/Terminal.js.map +1 -0
  63. package/dist/components/IO/VIA.d.ts +105 -0
  64. package/dist/components/IO/VIA.js +597 -0
  65. package/dist/components/IO/VIA.js.map +1 -0
  66. package/dist/components/IO/Video.d.ts +141 -0
  67. package/dist/components/IO/Video.js +630 -0
  68. package/dist/components/IO/Video.js.map +1 -0
  69. package/dist/components/IO/VideoCard.d.ts +141 -0
  70. package/dist/components/IO.d.ts +8 -0
  71. package/dist/components/Machine.d.ts +62 -0
  72. package/dist/components/Machine.js +260 -153
  73. package/dist/components/Machine.js.map +1 -1
  74. package/dist/components/RAM.d.ts +9 -0
  75. package/dist/components/ROM.d.ts +9 -0
  76. package/dist/index.d.ts +2 -0
  77. package/dist/index.js +61 -28
  78. package/dist/index.js.map +1 -1
  79. package/dist/lib.d.ts +22 -0
  80. package/dist/lib.js +47 -0
  81. package/dist/lib.js.map +1 -0
  82. package/dist/tests/CPU.test.d.ts +1 -0
  83. package/dist/tests/Cart.test.d.ts +1 -0
  84. package/dist/tests/IO/ACIA.test.d.ts +1 -0
  85. package/dist/tests/IO/ACIA.test.js +423 -0
  86. package/dist/tests/IO/ACIA.test.js.map +1 -0
  87. package/dist/tests/IO/Attachments/Attachment.test.d.ts +1 -0
  88. package/dist/tests/IO/Attachments/Attachment.test.js +339 -0
  89. package/dist/tests/IO/Attachments/Attachment.test.js.map +1 -0
  90. package/dist/tests/IO/Attachments/JoystickAttachment.test.d.ts +1 -0
  91. package/dist/tests/IO/Attachments/JoystickAttachment.test.js +126 -0
  92. package/dist/tests/IO/Attachments/JoystickAttachment.test.js.map +1 -0
  93. package/dist/tests/IO/Attachments/KeyboardEncoderAttachment.test.d.ts +1 -0
  94. package/dist/tests/IO/Attachments/KeyboardEncoderAttachment.test.js +779 -0
  95. package/dist/tests/IO/Attachments/KeyboardEncoderAttachment.test.js.map +1 -0
  96. package/dist/tests/IO/Attachments/KeyboardMatrixAttachment.test.d.ts +1 -0
  97. package/dist/tests/IO/Attachments/KeyboardMatrixAttachment.test.js +355 -0
  98. package/dist/tests/IO/Attachments/KeyboardMatrixAttachment.test.js.map +1 -0
  99. package/dist/tests/IO/Attachments/KeypadAttachment.test.d.ts +1 -0
  100. package/dist/tests/IO/Attachments/KeypadAttachment.test.js +323 -0
  101. package/dist/tests/IO/Attachments/KeypadAttachment.test.js.map +1 -0
  102. package/dist/tests/IO/Attachments/LCDAttachment.test.d.ts +1 -0
  103. package/dist/tests/IO/Attachments/LCDAttachment.test.js +627 -0
  104. package/dist/tests/IO/Attachments/LCDAttachment.test.js.map +1 -0
  105. package/dist/tests/IO/Attachments/SNESAttachment.test.d.ts +1 -0
  106. package/dist/tests/IO/Attachments/SNESAttachment.test.js +331 -0
  107. package/dist/tests/IO/Attachments/SNESAttachment.test.js.map +1 -0
  108. package/dist/tests/IO/Empty.test.d.ts +1 -0
  109. package/dist/tests/IO/Empty.test.js +121 -0
  110. package/dist/tests/IO/Empty.test.js.map +1 -0
  111. package/dist/tests/IO/GPIOAttachments/GPIOAttachment.test.d.ts +1 -0
  112. package/dist/tests/IO/GPIOAttachments/GPIOJoystickAttachment.test.d.ts +1 -0
  113. package/dist/tests/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.test.d.ts +1 -0
  114. package/dist/tests/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.test.d.ts +1 -0
  115. package/dist/tests/IO/GPIOAttachments/GPIOKeypadAttachment.test.d.ts +1 -0
  116. package/dist/tests/IO/GPIOAttachments/GPIOLCDAttachment.test.d.ts +1 -0
  117. package/dist/tests/IO/GPIOCard.test.d.ts +1 -0
  118. package/dist/tests/IO/GPIOCard.test.js.map +1 -1
  119. package/dist/tests/IO/RAMBank.test.d.ts +1 -0
  120. package/dist/tests/IO/RAMBank.test.js +229 -0
  121. package/dist/tests/IO/RAMBank.test.js.map +1 -0
  122. package/dist/tests/IO/RAMCard.test.d.ts +1 -0
  123. package/dist/tests/IO/RTC.test.d.ts +1 -0
  124. package/dist/tests/IO/RTC.test.js +177 -0
  125. package/dist/tests/IO/RTC.test.js.map +1 -0
  126. package/dist/tests/IO/RTCCard.test.d.ts +1 -0
  127. package/dist/tests/IO/SerialCard.test.d.ts +1 -0
  128. package/dist/tests/IO/Sound.test.d.ts +1 -0
  129. package/dist/tests/IO/Sound.test.js +528 -0
  130. package/dist/tests/IO/Sound.test.js.map +1 -0
  131. package/dist/tests/IO/SoundCard.test.d.ts +1 -0
  132. package/dist/tests/IO/Storage.test.d.ts +1 -0
  133. package/dist/tests/IO/Storage.test.js +656 -0
  134. package/dist/tests/IO/Storage.test.js.map +1 -0
  135. package/dist/tests/IO/StorageCard.test.d.ts +1 -0
  136. package/dist/tests/IO/VIA.test.d.ts +1 -0
  137. package/dist/tests/IO/VIA.test.js +503 -0
  138. package/dist/tests/IO/VIA.test.js.map +1 -0
  139. package/dist/tests/IO/Video.test.d.ts +1 -0
  140. package/dist/tests/IO/Video.test.js +549 -0
  141. package/dist/tests/IO/Video.test.js.map +1 -0
  142. package/dist/tests/IO/VideoCard.test.d.ts +1 -0
  143. package/dist/tests/Machine.test.d.ts +1 -0
  144. package/dist/tests/Machine.test.js +27 -42
  145. package/dist/tests/Machine.test.js.map +1 -1
  146. package/dist/tests/RAM.test.d.ts +1 -0
  147. package/dist/tests/ROM.test.d.ts +1 -0
  148. package/package.json +5 -3
  149. package/src/components/IO/{SerialCard.ts → ACIA.ts} +2 -2
  150. package/src/components/IO/{GPIOAttachments/GPIOAttachment.ts → Attachments/Attachment.ts} +2 -2
  151. package/src/components/IO/{GPIOAttachments/GPIOJoystickAttachment.ts → Attachments/JoystickAttachment.ts} +3 -3
  152. package/src/components/IO/{GPIOAttachments/GPIOKeyboardEncoderAttachment.ts → Attachments/KeyboardEncoderAttachment.ts} +3 -3
  153. package/src/components/IO/{GPIOAttachments/GPIOKeyboardMatrixAttachment.ts → Attachments/KeyboardMatrixAttachment.ts} +5 -5
  154. package/src/components/IO/{GPIOAttachments/GPIOKeypadAttachment.ts → Attachments/KeypadAttachment.ts} +3 -3
  155. package/src/components/IO/{GPIOAttachments/GPIOLCDAttachment.ts → Attachments/LCDAttachment.ts} +7 -7
  156. package/src/components/IO/{EmptyCard.ts → Empty.ts} +1 -1
  157. package/src/components/IO/{RAMCard.ts → RAMBank.ts} +8 -8
  158. package/src/components/IO/{RTCCard.ts → RTC.ts} +1 -1
  159. package/src/components/IO/{SoundCard.ts → Sound.ts} +2 -2
  160. package/src/components/IO/{StorageCard.ts → Storage.ts} +70 -73
  161. package/src/components/IO/Terminal.ts +34 -0
  162. package/src/components/IO/{GPIOCard.ts → VIA.ts} +64 -64
  163. package/src/components/IO/{VideoCard.ts → Video.ts} +1 -1
  164. package/src/components/Machine.ts +286 -160
  165. package/src/index.ts +65 -35
  166. package/src/lib.ts +27 -0
  167. package/src/tests/IO/{SerialCard.test.ts → ACIA.test.ts} +5 -5
  168. package/src/tests/IO/{GPIOAttachments/GPIOAttachment.test.ts → Attachments/Attachment.test.ts} +12 -12
  169. package/src/tests/IO/{GPIOAttachments/GPIOJoystickAttachment.test.ts → Attachments/JoystickAttachment.test.ts} +23 -23
  170. package/src/tests/IO/{GPIOAttachments/GPIOKeyboardEncoderAttachment.test.ts → Attachments/KeyboardEncoderAttachment.test.ts} +4 -4
  171. package/src/tests/IO/{GPIOAttachments/GPIOKeyboardMatrixAttachment.test.ts → Attachments/KeyboardMatrixAttachment.test.ts} +5 -5
  172. package/src/tests/IO/{GPIOAttachments/GPIOKeypadAttachment.test.ts → Attachments/KeypadAttachment.test.ts} +38 -38
  173. package/src/tests/IO/{GPIOAttachments/GPIOLCDAttachment.test.ts → Attachments/LCDAttachment.test.ts} +12 -12
  174. package/src/tests/IO/Empty.test.ts +143 -0
  175. package/src/tests/IO/{RAMCard.test.ts → RAMBank.test.ts} +33 -33
  176. package/src/tests/IO/{RTCCard.test.ts → RTC.test.ts} +6 -6
  177. package/src/tests/IO/{SoundCard.test.ts → Sound.test.ts} +6 -6
  178. package/src/tests/IO/{StorageCard.test.ts → Storage.test.ts} +34 -25
  179. package/src/tests/IO/{GPIOCard.test.ts → VIA.test.ts} +7 -7
  180. package/src/tests/IO/{VideoCard.test.ts → Video.test.ts} +13 -13
  181. package/src/tests/Machine.test.ts +31 -38
  182. package/tsconfig.json +1 -0
@@ -0,0 +1,120 @@
1
+ import { IO } from '../IO';
2
+ /**
3
+ * MOS 6581 SID (Sound Interface Device) Emulation
4
+ *
5
+ * Register Map ($00-$1C):
6
+ * Voice 1: $00-$06
7
+ * Voice 2: $07-$0D
8
+ * Voice 3: $0E-$14
9
+ * Filter: $15-$17
10
+ * Volume: $18
11
+ * Paddle: $19-$1A (read-only)
12
+ * OSC 3: $1B (read-only)
13
+ * ENV 3: $1C (read-only)
14
+ *
15
+ * Each voice has:
16
+ * Frequency (16-bit, lo/hi)
17
+ * Pulse Width (12-bit, lo/hi)
18
+ * Control Register (waveform select, gate, sync, ring mod, test)
19
+ * Attack/Decay (4-bit each)
20
+ * Sustain/Release (4-bit each)
21
+ *
22
+ * Waveforms: Triangle, Sawtooth, Pulse, Noise
23
+ * Filter: 12-bit cutoff, resonance, low/band/high-pass, voice routing
24
+ *
25
+ * Clock rate: ~1 MHz (NTSC: 1,022,727 Hz, PAL: 985,248 Hz)
26
+ * Output: mono audio samples passed via callback to the host emulator
27
+ *
28
+ * Reference: MOS 6581 SID datasheet, reSID by Dag Lem
29
+ */
30
+ /** Default SID clock rate (NTSC) */
31
+ export declare const SID_CLOCK_NTSC = 1022727;
32
+ export declare const SID_CLOCK_PAL = 985248;
33
+ export declare const enum EnvelopeState {
34
+ ATTACK = 0,
35
+ DECAY = 1,
36
+ SUSTAIN = 2,
37
+ RELEASE = 3
38
+ }
39
+ export declare class SIDVoice {
40
+ accumulator: number;
41
+ frequency: number;
42
+ pulseWidth: number;
43
+ control: number;
44
+ prevGate: boolean;
45
+ noiseShift: number;
46
+ waveformOutput: number;
47
+ envelopeState: EnvelopeState;
48
+ envelopeLevel: number;
49
+ envelopeCounter: number;
50
+ attackRate: number;
51
+ decayRate: number;
52
+ sustainLevel: number;
53
+ releaseRate: number;
54
+ exponentialCounter: number;
55
+ exponentialCounterPeriod: number;
56
+ reset(): void;
57
+ }
58
+ export declare class SoundCard implements IO {
59
+ raiseIRQ: () => void;
60
+ raiseNMI: () => void;
61
+ /** Callback to push audio samples to the host emulator */
62
+ pushSamples?: (samples: Float32Array) => void;
63
+ /** Raw register file (write-only from CPU perspective, except reads at $19-$1C) */
64
+ private registers;
65
+ /** Three oscillator voices */
66
+ private voices;
67
+ /** Filter state */
68
+ private filterCutoff;
69
+ private filterResonance;
70
+ private filterRouting;
71
+ private filterMode;
72
+ private masterVolume;
73
+ /** Filter integrator state (continuous) */
74
+ private filterLP;
75
+ private filterBP;
76
+ private filterHP;
77
+ /** Cycle accumulator for sample rate conversion */
78
+ private cycleAccumulator;
79
+ /** Target audio sample rate */
80
+ sampleRate: number;
81
+ /** SID clock rate */
82
+ sidClock: number;
83
+ /** Internal sample buffer for pushing to host */
84
+ private sampleBuffer;
85
+ private sampleBufferIndex;
86
+ read(address: number): number;
87
+ write(address: number, data: number): void;
88
+ tick(frequency: number): void;
89
+ reset(coldStart: boolean): void;
90
+ private updateVoiceRegister;
91
+ private updateGlobalRegister;
92
+ private clockOneCycle;
93
+ private clockOscillator;
94
+ private generateWaveform;
95
+ private clockEnvelope;
96
+ /**
97
+ * Update the exponential counter period based on current envelope level.
98
+ * The real SID uses an exponential curve for decay/release by varying
99
+ * the counter period at specific envelope level thresholds.
100
+ */
101
+ private updateExponentialPeriod;
102
+ private generateSample;
103
+ /**
104
+ * Convert the 11-bit filter cutoff register value to a frequency in Hz.
105
+ * The SID's cutoff mapping is complex and varies between chips.
106
+ * This approximation covers the usable range (~30 Hz to ~12 kHz).
107
+ */
108
+ private computeFilterCutoff;
109
+ private flushSampleBuffer;
110
+ /** Get a voice for inspection */
111
+ getVoice(index: number): SIDVoice;
112
+ /** Get current register value */
113
+ getRegister(reg: number): number;
114
+ /** Get current filter cutoff frequency in Hz */
115
+ getFilterCutoffHz(): number;
116
+ /** Get master volume (0-15) */
117
+ getMasterVolume(): number;
118
+ /** Get filter routing bitmask */
119
+ getFilterRouting(): number;
120
+ }
@@ -0,0 +1,74 @@
1
+ import { IO } from '../IO';
2
+ /**
3
+ * Storage - Emulates a Compact Flash card in 8-bit IDE mode
4
+ *
5
+ * Emulates a 128MB CF card with ATA-style register interface.
6
+ * Uses LBA (Logical Block Addressing) for sector access.
7
+ *
8
+ * Register Map (address & 0x07):
9
+ * $00: Data Register (read/write)
10
+ * $01: Error Register (read) / Feature Register (write)
11
+ * $02: Sector Count Register (read/write)
12
+ * $03: LBA0 Register (read/write) - bits 0-7 of LBA
13
+ * $04: LBA1 Register (read/write) - bits 8-15 of LBA
14
+ * $05: LBA2 Register (read/write) - bits 16-23 of LBA
15
+ * $06: LBA3 Register (read/write) - bits 24-27 of LBA + mode bits
16
+ * $07: Status Register (read) / Command Register (write)
17
+ *
18
+ * Supported Commands:
19
+ * 0x20, 0x21: Read Sector(s)
20
+ * 0x30, 0x31: Write Sector(s)
21
+ * 0xC0: Erase Sector
22
+ * 0xEC: Identify Drive
23
+ * 0xEF: Set Features (accepted but not implemented)
24
+ */
25
+ export declare class Storage implements IO {
26
+ private static readonly STORAGE_SIZE;
27
+ private static readonly SECTOR_SIZE;
28
+ private static readonly SECTOR_COUNT;
29
+ private static readonly STATUS_ERR;
30
+ private static readonly STATUS_DRQ;
31
+ private static readonly STATUS_RDY;
32
+ private static readonly ERR_AMNF;
33
+ private static readonly ERR_ABRT;
34
+ private static readonly ERR_IDNF;
35
+ private storage;
36
+ private identity;
37
+ private buffer;
38
+ private bufferIndex;
39
+ private commandDataSize;
40
+ private sectorOffset;
41
+ private error;
42
+ private feature;
43
+ private sectorCount;
44
+ private lba0;
45
+ private lba1;
46
+ private lba2;
47
+ private lba3;
48
+ private status;
49
+ private command;
50
+ private isIdentifying;
51
+ private isTransferring;
52
+ raiseIRQ: () => void;
53
+ raiseNMI: () => void;
54
+ constructor();
55
+ read(address: number): number;
56
+ write(address: number, data: number): void;
57
+ tick(frequency: number): void;
58
+ reset(coldStart: boolean): void;
59
+ private executeCommand;
60
+ private readBuffer;
61
+ private writeBuffer;
62
+ private sectorIndex;
63
+ private sectorValid;
64
+ private generateIdentity;
65
+ /**
66
+ * Load storage data from a Uint8Array, ArrayBuffer, or number array
67
+ * If data is not provided or wrong size, storage remains empty
68
+ */
69
+ loadData(data: Uint8Array | ArrayBuffer | number[] | null): void;
70
+ /**
71
+ * Get storage data as Uint8Array for saving
72
+ */
73
+ getData(): Uint8Array;
74
+ }
@@ -0,0 +1,409 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Storage = void 0;
4
+ /**
5
+ * Storage - Emulates a Compact Flash card in 8-bit IDE mode
6
+ *
7
+ * Emulates a 128MB CF card with ATA-style register interface.
8
+ * Uses LBA (Logical Block Addressing) for sector access.
9
+ *
10
+ * Register Map (address & 0x07):
11
+ * $00: Data Register (read/write)
12
+ * $01: Error Register (read) / Feature Register (write)
13
+ * $02: Sector Count Register (read/write)
14
+ * $03: LBA0 Register (read/write) - bits 0-7 of LBA
15
+ * $04: LBA1 Register (read/write) - bits 8-15 of LBA
16
+ * $05: LBA2 Register (read/write) - bits 16-23 of LBA
17
+ * $06: LBA3 Register (read/write) - bits 24-27 of LBA + mode bits
18
+ * $07: Status Register (read) / Command Register (write)
19
+ *
20
+ * Supported Commands:
21
+ * 0x20, 0x21: Read Sector(s)
22
+ * 0x30, 0x31: Write Sector(s)
23
+ * 0xC0: Erase Sector
24
+ * 0xEC: Identify Drive
25
+ * 0xEF: Set Features (accepted but not implemented)
26
+ */
27
+ class Storage {
28
+ constructor() {
29
+ // Data buffer (512 bytes)
30
+ this.buffer = new Uint8Array(Storage.SECTOR_SIZE);
31
+ this.bufferIndex = 0;
32
+ this.commandDataSize = Storage.SECTOR_SIZE;
33
+ this.sectorOffset = 0;
34
+ // Registers
35
+ this.error = 0x00;
36
+ this.feature = 0x00;
37
+ this.sectorCount = 0x00;
38
+ this.lba0 = 0x00;
39
+ this.lba1 = 0x00;
40
+ this.lba2 = 0x00;
41
+ this.lba3 = 0xE0;
42
+ this.status = 0x00;
43
+ this.command = 0x00;
44
+ // State flags
45
+ this.isIdentifying = false;
46
+ this.isTransferring = false;
47
+ this.raiseIRQ = () => { };
48
+ this.raiseNMI = () => { };
49
+ // Initialize storage and identity buffers
50
+ this.storage = new Uint8Array(Storage.STORAGE_SIZE);
51
+ this.identity = new Uint8Array(Storage.SECTOR_SIZE);
52
+ this.generateIdentity();
53
+ this.reset(true);
54
+ }
55
+ read(address) {
56
+ switch (address & 0x0007) {
57
+ case 0x00: // Data Register
58
+ return this.readBuffer();
59
+ case 0x01: // Error Register
60
+ return this.error;
61
+ case 0x02: // Sector Count Register
62
+ return this.sectorCount;
63
+ case 0x03: // LBA0 Register
64
+ return this.lba0;
65
+ case 0x04: // LBA1 Register
66
+ return this.lba1;
67
+ case 0x05: // LBA2 Register
68
+ return this.lba2;
69
+ case 0x06: // LBA3 Register
70
+ return this.lba3;
71
+ case 0x07: // Status Register
72
+ return this.status;
73
+ default:
74
+ return 0x00;
75
+ }
76
+ }
77
+ write(address, data) {
78
+ switch (address & 0x0007) {
79
+ case 0x00: // Data Register
80
+ this.writeBuffer(data);
81
+ break;
82
+ case 0x01: // Feature Register
83
+ this.feature = data;
84
+ break;
85
+ case 0x02: // Sector Count Register
86
+ this.sectorCount = data;
87
+ break;
88
+ case 0x03: // LBA0 Register
89
+ this.lba0 = data;
90
+ break;
91
+ case 0x04: // LBA1 Register
92
+ this.lba1 = data;
93
+ break;
94
+ case 0x05: // LBA2 Register
95
+ this.lba2 = data;
96
+ break;
97
+ case 0x06: // LBA3 Register
98
+ this.lba3 = (data & 0x0F) | 0xE0;
99
+ break;
100
+ case 0x07: // Command Register
101
+ this.command = data;
102
+ this.executeCommand();
103
+ break;
104
+ }
105
+ }
106
+ tick(frequency) {
107
+ // No timing behavior needed for this implementation
108
+ }
109
+ reset(coldStart) {
110
+ this.bufferIndex = 0x0000;
111
+ this.commandDataSize = Storage.SECTOR_SIZE;
112
+ this.sectorOffset = 0;
113
+ this.error = 0x00;
114
+ this.feature = 0x00;
115
+ this.sectorCount = 0x00;
116
+ this.lba0 = 0x00;
117
+ this.lba1 = 0x00;
118
+ this.lba2 = 0x00;
119
+ this.lba3 = 0xE0;
120
+ this.status = 0x00 | Storage.STATUS_RDY;
121
+ this.command = 0x00;
122
+ this.isIdentifying = false;
123
+ this.isTransferring = false;
124
+ this.buffer.fill(0x00);
125
+ }
126
+ //
127
+ // Private methods
128
+ //
129
+ executeCommand() {
130
+ // New command so clear errors and flags
131
+ this.status &= ~Storage.STATUS_ERR;
132
+ this.status &= ~Storage.STATUS_DRQ;
133
+ this.error = 0x00;
134
+ this.commandDataSize = Storage.SECTOR_SIZE * this.sectorCount;
135
+ this.bufferIndex = 0;
136
+ this.sectorOffset = 0;
137
+ // Check if already executing a command
138
+ if (this.isTransferring || this.isIdentifying) {
139
+ this.status |= Storage.STATUS_ERR;
140
+ this.error |= Storage.ERR_ABRT;
141
+ return;
142
+ }
143
+ switch (this.command) {
144
+ case 0xC0: { // Erase sector
145
+ if (!this.sectorValid()) {
146
+ this.status |= Storage.STATUS_ERR;
147
+ this.error |= Storage.ERR_ABRT | Storage.ERR_IDNF;
148
+ }
149
+ else {
150
+ const offset = this.sectorIndex() * Storage.SECTOR_SIZE;
151
+ this.storage.fill(0x00, offset, offset + Storage.SECTOR_SIZE);
152
+ }
153
+ break;
154
+ }
155
+ case 0xEC: { // Identify drive
156
+ this.buffer.set(this.identity.subarray(0, Storage.SECTOR_SIZE));
157
+ this.commandDataSize = Storage.SECTOR_SIZE;
158
+ this.status |= Storage.STATUS_DRQ;
159
+ this.isIdentifying = true;
160
+ break;
161
+ }
162
+ case 0x20: // Read sector
163
+ case 0x21:
164
+ if (!this.sectorValid()) {
165
+ this.status |= Storage.STATUS_ERR;
166
+ this.error |= Storage.ERR_ABRT | Storage.ERR_IDNF;
167
+ }
168
+ else {
169
+ // Load first sector into buffer
170
+ const offset = this.sectorIndex() * Storage.SECTOR_SIZE;
171
+ this.buffer.set(this.storage.subarray(offset, offset + Storage.SECTOR_SIZE));
172
+ this.status |= Storage.STATUS_DRQ;
173
+ this.isTransferring = true;
174
+ }
175
+ break;
176
+ case 0xEF: // Set features
177
+ // We don't support setting features but accept them without error
178
+ break;
179
+ case 0x30: // Write sector
180
+ case 0x31:
181
+ if (!this.sectorValid()) {
182
+ this.status |= Storage.STATUS_ERR;
183
+ this.error |= Storage.ERR_ABRT | Storage.ERR_IDNF;
184
+ }
185
+ else {
186
+ this.status |= Storage.STATUS_DRQ;
187
+ this.isTransferring = true;
188
+ }
189
+ break;
190
+ default:
191
+ // Unsupported command
192
+ this.status |= Storage.STATUS_ERR;
193
+ this.error |= Storage.ERR_ABRT;
194
+ break;
195
+ }
196
+ }
197
+ readBuffer() {
198
+ if (this.isIdentifying) {
199
+ const data = this.buffer[this.bufferIndex];
200
+ if (this.bufferIndex < this.commandDataSize - 1) {
201
+ this.bufferIndex++;
202
+ }
203
+ else {
204
+ this.bufferIndex = 0;
205
+ this.isIdentifying = false;
206
+ this.status &= ~Storage.STATUS_DRQ;
207
+ }
208
+ return data;
209
+ }
210
+ else if (this.isTransferring) {
211
+ const data = this.buffer[this.bufferIndex];
212
+ if (this.bufferIndex < Storage.SECTOR_SIZE - 1) {
213
+ this.bufferIndex++;
214
+ }
215
+ else {
216
+ this.bufferIndex = 0;
217
+ this.sectorOffset++;
218
+ if (this.sectorOffset < this.sectorCount) {
219
+ // Load the next sector
220
+ const offset = (this.sectorIndex() + this.sectorOffset) * Storage.SECTOR_SIZE;
221
+ this.buffer.set(this.storage.subarray(offset, offset + Storage.SECTOR_SIZE));
222
+ }
223
+ else {
224
+ this.isTransferring = false;
225
+ this.status &= ~Storage.STATUS_DRQ;
226
+ }
227
+ }
228
+ return data;
229
+ }
230
+ else {
231
+ return 0x00;
232
+ }
233
+ }
234
+ writeBuffer(value) {
235
+ this.buffer[this.bufferIndex] = value;
236
+ if (this.bufferIndex < Storage.SECTOR_SIZE - 1) {
237
+ this.bufferIndex++;
238
+ }
239
+ else {
240
+ this.bufferIndex = 0;
241
+ // Write the current sector to storage
242
+ const offset = (this.sectorIndex() + this.sectorOffset) * Storage.SECTOR_SIZE;
243
+ this.storage.set(this.buffer.subarray(0, Storage.SECTOR_SIZE), offset);
244
+ this.sectorOffset++;
245
+ // Check if all sectors have been written
246
+ if (this.sectorOffset >= this.sectorCount) {
247
+ this.isTransferring = false;
248
+ this.status &= ~Storage.STATUS_DRQ;
249
+ }
250
+ }
251
+ }
252
+ sectorIndex() {
253
+ return ((this.lba3 & 0x0F) << 24) | (this.lba2 << 16) | (this.lba1 << 8) | this.lba0;
254
+ }
255
+ sectorValid() {
256
+ return this.sectorIndex() < Storage.SECTOR_COUNT;
257
+ }
258
+ generateIdentity() {
259
+ // Generate emulated 128MB CF card identity
260
+ // Based on real Promaster 128MB CF card data
261
+ // Fill with zeros first
262
+ this.identity.fill(0x00);
263
+ // Word 0: General configuration
264
+ this.identity[0] = 0x84;
265
+ this.identity[1] = 0x8A; // Removable Disk
266
+ // Word 1: Number of cylinders
267
+ this.identity[2] = 0x00;
268
+ this.identity[3] = 0x04;
269
+ // Word 2: Reserved
270
+ this.identity[4] = 0x00;
271
+ this.identity[5] = 0x00;
272
+ // Word 3: Number of heads
273
+ this.identity[6] = 0x08;
274
+ this.identity[7] = 0x00;
275
+ // Word 4: Unformatted bytes per track
276
+ this.identity[8] = 0x00;
277
+ this.identity[9] = 0x40;
278
+ // Word 5: Unformatted bytes per sector
279
+ this.identity[10] = 0x00;
280
+ this.identity[11] = 0x02;
281
+ // Word 6: Sectors per track
282
+ this.identity[12] = 0x20;
283
+ this.identity[13] = 0x00;
284
+ // Words 7-9: Reserved
285
+ this.identity[14] = 0x04;
286
+ this.identity[15] = 0x00;
287
+ this.identity[16] = 0x00;
288
+ this.identity[17] = 0x00;
289
+ this.identity[18] = 0x00;
290
+ this.identity[19] = 0x00;
291
+ // Words 10-19: Serial number (20 ASCII characters)
292
+ const serial = 'ACWD6502EMUCF1010101';
293
+ for (let i = 0; i < serial.length; i++) {
294
+ this.identity[20 + i] = serial.charCodeAt(i);
295
+ }
296
+ // Word 20: Buffer type
297
+ this.identity[40] = 0x01;
298
+ this.identity[41] = 0x00;
299
+ // Word 21: Buffer size in 512 byte increments
300
+ this.identity[42] = 0x04;
301
+ this.identity[43] = 0x00;
302
+ // Word 22: ECC bytes
303
+ this.identity[44] = 0x04;
304
+ this.identity[45] = 0x00;
305
+ // Words 23-26: Firmware revision (8 ASCII characters)
306
+ const firmware = '1.0 ';
307
+ for (let i = 0; i < firmware.length; i++) {
308
+ this.identity[46 + i] = firmware.charCodeAt(i);
309
+ }
310
+ // Words 27-46: Model number (40 ASCII characters)
311
+ const model = 'ACWD6502EMUCF ';
312
+ for (let i = 0; i < model.length; i++) {
313
+ this.identity[54 + i] = model.charCodeAt(i);
314
+ }
315
+ // Word 47: Multiple sector setting
316
+ this.identity[94] = 0x01;
317
+ this.identity[95] = 0x00;
318
+ // Word 48: Double word not supported
319
+ this.identity[96] = 0x00;
320
+ this.identity[97] = 0x00;
321
+ // Word 49: Capabilities (LBA supported)
322
+ this.identity[98] = 0x00;
323
+ this.identity[99] = 0x02;
324
+ // Word 50: Reserved
325
+ this.identity[100] = 0x00;
326
+ this.identity[101] = 0x00;
327
+ // Word 51: PIO data transfer cycle timing
328
+ this.identity[102] = 0x00;
329
+ this.identity[103] = 0x02;
330
+ // Word 52: DMA transfer cycle timing
331
+ this.identity[104] = 0x00;
332
+ this.identity[105] = 0x00;
333
+ // Word 53: Field validity
334
+ this.identity[106] = 0x01;
335
+ this.identity[107] = 0x00;
336
+ // Word 54: Current number of cylinders
337
+ this.identity[108] = 0x00;
338
+ this.identity[109] = 0x04;
339
+ // Word 55: Current number of heads
340
+ this.identity[110] = 0x08;
341
+ this.identity[111] = 0x00;
342
+ // Word 56: Current sectors per track
343
+ this.identity[112] = 0x20;
344
+ this.identity[113] = 0x00;
345
+ // Words 57-58: Current capacity in sectors
346
+ this.identity[114] = 0x00;
347
+ this.identity[115] = 0x00;
348
+ this.identity[116] = 0x04;
349
+ this.identity[117] = 0x00;
350
+ // Word 59: Multiple sector setting
351
+ this.identity[118] = 0x01;
352
+ this.identity[119] = 0x01;
353
+ // Words 60-61: Total number of sectors in LBA mode
354
+ this.identity[120] = 0x00;
355
+ this.identity[121] = 0x00;
356
+ this.identity[122] = 0x04;
357
+ this.identity[123] = 0x00;
358
+ // Remaining words are zero
359
+ }
360
+ /**
361
+ * Load storage data from a Uint8Array, ArrayBuffer, or number array
362
+ * If data is not provided or wrong size, storage remains empty
363
+ */
364
+ loadData(data) {
365
+ if (!data) {
366
+ console.log('No storage data provided. Storage will remain empty.');
367
+ return;
368
+ }
369
+ let uint8Data;
370
+ if (data instanceof ArrayBuffer) {
371
+ uint8Data = new Uint8Array(data);
372
+ }
373
+ else if (data instanceof Uint8Array) {
374
+ uint8Data = data;
375
+ }
376
+ else {
377
+ uint8Data = new Uint8Array(data);
378
+ }
379
+ // Ensure the data is exactly the expected size
380
+ if (uint8Data.length === Storage.STORAGE_SIZE) {
381
+ this.storage.set(uint8Data);
382
+ console.log(`Storage loaded (${Storage.STORAGE_SIZE} bytes)`);
383
+ }
384
+ else {
385
+ console.warn(`Warning: Storage data size mismatch. Expected ${Storage.STORAGE_SIZE} bytes, got ${uint8Data.length} bytes.`);
386
+ console.warn('Storage will remain empty.');
387
+ }
388
+ }
389
+ /**
390
+ * Get storage data as Uint8Array for saving
391
+ */
392
+ getData() {
393
+ return new Uint8Array(this.storage);
394
+ }
395
+ }
396
+ exports.Storage = Storage;
397
+ // Constants
398
+ Storage.STORAGE_SIZE = 128 * 1024 * 1024; // 128MB
399
+ Storage.SECTOR_SIZE = 512;
400
+ Storage.SECTOR_COUNT = Storage.STORAGE_SIZE / Storage.SECTOR_SIZE; // 262144 sectors
401
+ // Status Register Flags
402
+ Storage.STATUS_ERR = 0x01; // Error
403
+ Storage.STATUS_DRQ = 0x08; // Data Request
404
+ Storage.STATUS_RDY = 0x40; // Ready
405
+ // Error Register Flags
406
+ Storage.ERR_AMNF = 0x01; // Address Mark Not Found
407
+ Storage.ERR_ABRT = 0x04; // Aborted Command
408
+ Storage.ERR_IDNF = 0x10; // ID Not Found
409
+ //# sourceMappingURL=Storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Storage.js","sourceRoot":"","sources":["../../../src/components/IO/Storage.ts"],"names":[],"mappings":"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"}