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
@@ -1,12 +1,12 @@
1
- import { GPIOKeypadAttachment } from '../../../components/IO/GPIOAttachments/GPIOKeypadAttachment'
1
+ import { KeypadAttachment } from '../../../components/IO/Attachments/KeypadAttachment'
2
2
 
3
- describe('GPIOKeypadAttachment', () => {
4
- let keypadA: GPIOKeypadAttachment // attached to Port A
5
- let keypadB: GPIOKeypadAttachment // attached to Port B
3
+ describe('KeypadAttachment', () => {
4
+ let keypadA: KeypadAttachment // attached to Port A
5
+ let keypadB: KeypadAttachment // attached to Port B
6
6
 
7
7
  beforeEach(() => {
8
- keypadA = new GPIOKeypadAttachment(true, 0)
9
- keypadB = new GPIOKeypadAttachment(false, 0)
8
+ keypadA = new KeypadAttachment(true, 0)
9
+ keypadB = new KeypadAttachment(false, 0)
10
10
  })
11
11
 
12
12
  // ---------------------------------------------------------------------------
@@ -36,7 +36,7 @@ describe('GPIOKeypadAttachment', () => {
36
36
  })
37
37
 
38
38
  it('should report the correct priority', () => {
39
- const kp = new GPIOKeypadAttachment(true, 7)
39
+ const kp = new KeypadAttachment(true, 7)
40
40
  expect(kp.getPriority()).toBe(7)
41
41
  })
42
42
 
@@ -62,134 +62,134 @@ describe('GPIOKeypadAttachment', () => {
62
62
  // ---------------------------------------------------------------------------
63
63
  describe('Key press → keypad value mapping', () => {
64
64
  // Helpers: assert OE (CA2/CB2 LOW) then press and read
65
- const pressAndReadA = (kp: GPIOKeypadAttachment, hid: number) => {
65
+ const pressAndReadA = (kp: KeypadAttachment, hid: number) => {
66
66
  kp.updateControlLines(false, false, false, true) // CA2 LOW → OE asserted for Port A
67
67
  kp.updateKey(hid, true)
68
68
  return kp.readPortA(0x00, 0x00)
69
69
  }
70
- const pressAndReadB = (kp: GPIOKeypadAttachment, hid: number) => {
70
+ const pressAndReadB = (kp: KeypadAttachment, hid: number) => {
71
71
  kp.updateControlLines(false, true, false, false) // CB2 LOW → OE asserted for Port B
72
72
  kp.updateKey(hid, true)
73
73
  return kp.readPortB(0x00, 0x00)
74
74
  }
75
75
 
76
76
  it('Left Arrow (0x50) → $00 ◄', () => {
77
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x50)).toBe(0x00)
77
+ expect(pressAndReadA(new KeypadAttachment(true), 0x50)).toBe(0x00)
78
78
  })
79
79
 
80
80
  it('Backspace is not on this keypad', () => {
81
- const kp = new GPIOKeypadAttachment(true)
81
+ const kp = new KeypadAttachment(true)
82
82
  kp.updateControlLines(false, false, false, true)
83
83
  kp.updateKey(0x2A, true) // Backspace – unmapped
84
84
  expect(kp.readPortA(0x00, 0x00)).toBe(0xFF)
85
85
  })
86
86
 
87
87
  it('1 (0x1E) → $01', () => {
88
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x1E)).toBe(0x01)
88
+ expect(pressAndReadA(new KeypadAttachment(true), 0x1E)).toBe(0x01)
89
89
  })
90
90
 
91
91
  it('2 (0x1F) → $02', () => {
92
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x1F)).toBe(0x02)
92
+ expect(pressAndReadA(new KeypadAttachment(true), 0x1F)).toBe(0x02)
93
93
  })
94
94
 
95
95
  it('3 (0x20) → $03', () => {
96
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x20)).toBe(0x03)
96
+ expect(pressAndReadA(new KeypadAttachment(true), 0x20)).toBe(0x03)
97
97
  })
98
98
 
99
99
  it('4 (0x21) → $04', () => {
100
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x21)).toBe(0x04)
100
+ expect(pressAndReadA(new KeypadAttachment(true), 0x21)).toBe(0x04)
101
101
  })
102
102
 
103
103
  it('5 (0x22) → $05', () => {
104
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x22)).toBe(0x05)
104
+ expect(pressAndReadA(new KeypadAttachment(true), 0x22)).toBe(0x05)
105
105
  })
106
106
 
107
107
  it('6 (0x23) → $06', () => {
108
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x23)).toBe(0x06)
108
+ expect(pressAndReadA(new KeypadAttachment(true), 0x23)).toBe(0x06)
109
109
  })
110
110
 
111
111
  it('7 (0x24) → $07', () => {
112
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x24)).toBe(0x07)
112
+ expect(pressAndReadA(new KeypadAttachment(true), 0x24)).toBe(0x07)
113
113
  })
114
114
 
115
115
  it('8 (0x25) → $08', () => {
116
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x25)).toBe(0x08)
116
+ expect(pressAndReadA(new KeypadAttachment(true), 0x25)).toBe(0x08)
117
117
  })
118
118
 
119
119
  it('9 (0x26) → $09', () => {
120
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x26)).toBe(0x09)
120
+ expect(pressAndReadA(new KeypadAttachment(true), 0x26)).toBe(0x09)
121
121
  })
122
122
 
123
123
  it('0 (0x27) → $0A', () => {
124
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x27)).toBe(0x0A)
124
+ expect(pressAndReadA(new KeypadAttachment(true), 0x27)).toBe(0x0A)
125
125
  })
126
126
 
127
127
  it('Right Arrow (0x4F) → $0B ►', () => {
128
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x4F)).toBe(0x0B)
128
+ expect(pressAndReadA(new KeypadAttachment(true), 0x4F)).toBe(0x0B)
129
129
  })
130
130
 
131
131
  it('Enter is not mapped to $0B (it maps to $14)', () => {
132
- const kp = new GPIOKeypadAttachment(true)
132
+ const kp = new KeypadAttachment(true)
133
133
  kp.updateControlLines(false, false, false, true)
134
134
  kp.updateKey(0x28, true) // Enter → $14
135
135
  expect(kp.readPortA(0x00, 0x00)).toBe(0x14)
136
136
  })
137
137
 
138
138
  it('f (0x09) → $0C F', () => {
139
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x09)).toBe(0x0C)
139
+ expect(pressAndReadA(new KeypadAttachment(true), 0x09)).toBe(0x0C)
140
140
  })
141
141
 
142
142
  it('e (0x08) → $0D E', () => {
143
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x08)).toBe(0x0D)
143
+ expect(pressAndReadA(new KeypadAttachment(true), 0x08)).toBe(0x0D)
144
144
  })
145
145
 
146
146
  it('d (0x07) → $0E D', () => {
147
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x07)).toBe(0x0E)
147
+ expect(pressAndReadA(new KeypadAttachment(true), 0x07)).toBe(0x0E)
148
148
  })
149
149
 
150
150
  it('c (0x06) → $0F C', () => {
151
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x06)).toBe(0x0F)
151
+ expect(pressAndReadA(new KeypadAttachment(true), 0x06)).toBe(0x0F)
152
152
  })
153
153
 
154
154
  it('Escape (0x29) → $10 ESC', () => {
155
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x29)).toBe(0x10)
155
+ expect(pressAndReadA(new KeypadAttachment(true), 0x29)).toBe(0x10)
156
156
  })
157
157
 
158
158
  it('Insert (0x49) → $11 INS', () => {
159
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x49)).toBe(0x11)
159
+ expect(pressAndReadA(new KeypadAttachment(true), 0x49)).toBe(0x11)
160
160
  })
161
161
 
162
162
  it('Page Up (0x4B) → $12 PGUP', () => {
163
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x4B)).toBe(0x12)
163
+ expect(pressAndReadA(new KeypadAttachment(true), 0x4B)).toBe(0x12)
164
164
  })
165
165
 
166
166
  it('a (0x04) → $13 A', () => {
167
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x04)).toBe(0x13)
167
+ expect(pressAndReadA(new KeypadAttachment(true), 0x04)).toBe(0x13)
168
168
  })
169
169
 
170
170
  it('Up Arrow (0x52) → $14 ▲', () => {
171
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x52)).toBe(0x14)
171
+ expect(pressAndReadA(new KeypadAttachment(true), 0x52)).toBe(0x14)
172
172
  })
173
173
 
174
174
  it('Enter (0x28) → $14 ▲', () => {
175
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x28)).toBe(0x14)
175
+ expect(pressAndReadA(new KeypadAttachment(true), 0x28)).toBe(0x14)
176
176
  })
177
177
 
178
178
  it('Delete (0x4C) → $15 DEL', () => {
179
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x4C)).toBe(0x15)
179
+ expect(pressAndReadA(new KeypadAttachment(true), 0x4C)).toBe(0x15)
180
180
  })
181
181
 
182
182
  it('Page Down (0x4E) → $16 PGDN', () => {
183
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x4E)).toBe(0x16)
183
+ expect(pressAndReadA(new KeypadAttachment(true), 0x4E)).toBe(0x16)
184
184
  })
185
185
 
186
186
  it('b (0x05) → $17 B', () => {
187
- expect(pressAndReadA(new GPIOKeypadAttachment(true), 0x05)).toBe(0x17)
187
+ expect(pressAndReadA(new KeypadAttachment(true), 0x05)).toBe(0x17)
188
188
  })
189
189
 
190
190
  it('should also map correctly on Port B', () => {
191
- expect(pressAndReadB(new GPIOKeypadAttachment(false), 0x1E)).toBe(0x01) // '1' → $01
192
- expect(pressAndReadB(new GPIOKeypadAttachment(false), 0x05)).toBe(0x17) // 'b' → $17
191
+ expect(pressAndReadB(new KeypadAttachment(false), 0x1E)).toBe(0x01) // '1' → $01
192
+ expect(pressAndReadB(new KeypadAttachment(false), 0x05)).toBe(0x17) // 'b' → $17
193
193
  })
194
194
  })
195
195
 
@@ -1,5 +1,5 @@
1
1
  import {
2
- GPIOLCDAttachment,
2
+ LCDAttachment,
3
3
  LCD_CMD_CLEAR,
4
4
  LCD_CMD_HOME,
5
5
  LCD_CMD_ENTRY_MODE,
@@ -16,36 +16,36 @@ import {
16
16
  LCD_CMD_FUNCTION_LCD_2LINE,
17
17
  LCD_CMD_SET_CGRAM_ADDR,
18
18
  LCD_CMD_SET_DRAM_ADDR,
19
- } from '../../../components/IO/GPIOAttachments/GPIOLCDAttachment'
19
+ } from '../../../components/IO/Attachments/LCDAttachment'
20
20
 
21
21
  // VIA Port A pin masks
22
22
  const PIN_RS = 0x20
23
23
  const PIN_RW = 0x40
24
24
  const PIN_E = 0x80
25
25
 
26
- describe('GPIOLCDAttachment', () => {
27
- let lcd: GPIOLCDAttachment
26
+ describe('LCDAttachment', () => {
27
+ let lcd: LCDAttachment
28
28
 
29
29
  beforeEach(() => {
30
- lcd = new GPIOLCDAttachment(16, 2)
30
+ lcd = new LCDAttachment(16, 2)
31
31
  })
32
32
 
33
33
  // ── Helper: write a command via the GPIO bus ────────────────────
34
34
 
35
35
  /** Simulate a command write: RS=0, RW=0 */
36
- function writeCommand(lcd: GPIOLCDAttachment, cmd: number): void {
36
+ function writeCommand(lcd: LCDAttachment, cmd: number): void {
37
37
  lcd.sendCommand(cmd)
38
38
  lcd.updatePixels()
39
39
  }
40
40
 
41
41
  /** Simulate a data byte write: RS=1, RW=0 */
42
- function writeData(lcd: GPIOLCDAttachment, data: number): void {
42
+ function writeData(lcd: LCDAttachment, data: number): void {
43
43
  lcd.writeByte(data)
44
44
  lcd.updatePixels()
45
45
  }
46
46
 
47
47
  /** Write a string to the LCD */
48
- function writeString(lcd: GPIOLCDAttachment, str: string): void {
48
+ function writeString(lcd: LCDAttachment, str: string): void {
49
49
  for (let i = 0; i < str.length; i++) {
50
50
  writeData(lcd, str.charCodeAt(i))
51
51
  }
@@ -53,7 +53,7 @@ describe('GPIOLCDAttachment', () => {
53
53
 
54
54
  /** Simulate full GPIO bus cycle: set Port B data, set Port A control,
55
55
  * raise E, then lower E (falling-edge latch) */
56
- function gpioBusWrite(lcd: GPIOLCDAttachment, rs: boolean, data: number): void {
56
+ function gpioBusWrite(lcd: LCDAttachment, rs: boolean, data: number): void {
57
57
  const portAValue = (rs ? PIN_RS : 0) // RW = 0 (write)
58
58
  const ddr = 0xFF // all outputs
59
59
 
@@ -107,7 +107,7 @@ describe('GPIOLCDAttachment', () => {
107
107
  })
108
108
 
109
109
  it('should support different display sizes', () => {
110
- const lcd20x4 = new GPIOLCDAttachment(20, 4)
110
+ const lcd20x4 = new LCDAttachment(20, 4)
111
111
  expect(lcd20x4.cols).toBe(20)
112
112
  expect(lcd20x4.rows).toBe(4)
113
113
  // 20 × (5+1) - 1 = 119
@@ -655,10 +655,10 @@ describe('GPIOLCDAttachment', () => {
655
655
  })
656
656
 
657
657
  describe('1-row mode', () => {
658
- let lcd1: GPIOLCDAttachment
658
+ let lcd1: LCDAttachment
659
659
 
660
660
  beforeEach(() => {
661
- lcd1 = new GPIOLCDAttachment(16, 1)
661
+ lcd1 = new LCDAttachment(16, 1)
662
662
  })
663
663
 
664
664
  it('should wrap from position 79 to 0', () => {
@@ -0,0 +1,143 @@
1
+ import { Empty } from '../../components/IO/Empty'
2
+
3
+ describe('Empty', () => {
4
+ let empty: Empty
5
+
6
+ beforeEach(() => {
7
+ empty = new Empty()
8
+ })
9
+
10
+ describe('Initialization', () => {
11
+ it('should have IRQ callback', () => {
12
+ expect(typeof empty.raiseIRQ).toBe('function')
13
+ })
14
+
15
+ it('should have NMI callback', () => {
16
+ expect(typeof empty.raiseNMI).toBe('function')
17
+ })
18
+
19
+ it('should not throw when calling raiseIRQ', () => {
20
+ expect(() => empty.raiseIRQ()).not.toThrow()
21
+ })
22
+
23
+ it('should not throw when calling raiseNMI', () => {
24
+ expect(() => empty.raiseNMI()).not.toThrow()
25
+ })
26
+ })
27
+
28
+ describe('Reading', () => {
29
+ it('should return 0 for any address', () => {
30
+ expect(empty.read(0x00)).toBe(0)
31
+ expect(empty.read(0x42)).toBe(0)
32
+ expect(empty.read(0xFF)).toBe(0)
33
+ expect(empty.read(0x1000)).toBe(0)
34
+ })
35
+
36
+ it('should consistently return 0 for the same address', () => {
37
+ const address = 0x80
38
+ expect(empty.read(address)).toBe(0)
39
+ expect(empty.read(address)).toBe(0)
40
+ expect(empty.read(address)).toBe(0)
41
+ })
42
+ })
43
+
44
+ describe('Writing', () => {
45
+ it('should accept writes without throwing errors', () => {
46
+ expect(() => empty.write(0x00, 0x00)).not.toThrow()
47
+ expect(() => empty.write(0x42, 0xAA)).not.toThrow()
48
+ expect(() => empty.write(0xFF, 0xFF)).not.toThrow()
49
+ })
50
+
51
+ it('should not affect read values after writing', () => {
52
+ empty.write(0x10, 0x55)
53
+ expect(empty.read(0x10)).toBe(0)
54
+
55
+ empty.write(0x20, 0xAA)
56
+ expect(empty.read(0x20)).toBe(0)
57
+ })
58
+
59
+ it('should handle multiple writes to the same address', () => {
60
+ const address = 0x30
61
+ expect(() => {
62
+ empty.write(address, 0x11)
63
+ empty.write(address, 0x22)
64
+ empty.write(address, 0x33)
65
+ }).not.toThrow()
66
+
67
+ expect(empty.read(address)).toBe(0)
68
+ })
69
+ })
70
+
71
+ describe('Tick', () => {
72
+ it('should not throw when ticked', () => {
73
+ expect(() => empty.tick(1000000)).not.toThrow()
74
+ })
75
+
76
+ it('should handle various frequencies', () => {
77
+ expect(() => empty.tick(0)).not.toThrow()
78
+ expect(() => empty.tick(1)).not.toThrow()
79
+ expect(() => empty.tick(1000000)).not.toThrow()
80
+ expect(() => empty.tick(10000000)).not.toThrow()
81
+ })
82
+
83
+ it('should not affect read values', () => {
84
+ empty.tick(1000000)
85
+ expect(empty.read(0x50)).toBe(0)
86
+ })
87
+ })
88
+
89
+ describe('Reset', () => {
90
+ it('should not throw when reset with cold start', () => {
91
+ expect(() => empty.reset(true)).not.toThrow()
92
+ })
93
+
94
+ it('should not throw when reset without cold start', () => {
95
+ expect(() => empty.reset(false)).not.toThrow()
96
+ })
97
+
98
+ it('should not affect read values after reset', () => {
99
+ empty.reset(true)
100
+ expect(empty.read(0x60)).toBe(0)
101
+
102
+ empty.reset(false)
103
+ expect(empty.read(0x60)).toBe(0)
104
+ })
105
+
106
+ it('should handle multiple resets', () => {
107
+ expect(() => {
108
+ empty.reset(true)
109
+ empty.reset(false)
110
+ empty.reset(true)
111
+ }).not.toThrow()
112
+ })
113
+ })
114
+
115
+ describe('Integration', () => {
116
+ it('should handle a sequence of operations', () => {
117
+ expect(() => {
118
+ empty.reset(true)
119
+ empty.write(0x00, 0xFF)
120
+ const value = empty.read(0x00)
121
+ expect(value).toBe(0)
122
+ empty.tick(1000000)
123
+ empty.raiseIRQ()
124
+ empty.raiseNMI()
125
+ empty.reset(false)
126
+ }).not.toThrow()
127
+ })
128
+
129
+ it('should remain functional after extensive use', () => {
130
+ for (let i = 0; i < 100; i++) {
131
+ empty.write(i, i & 0xFF)
132
+ empty.tick(1000)
133
+ }
134
+
135
+ for (let i = 0; i < 100; i++) {
136
+ expect(empty.read(i)).toBe(0)
137
+ }
138
+
139
+ empty.reset(true)
140
+ expect(empty.read(0x00)).toBe(0)
141
+ })
142
+ })
143
+ })
@@ -1,33 +1,33 @@
1
- import { RAMCard } from '../../components/IO/RAMCard'
1
+ import { RAMBank } from '../../components/IO/RAMBank'
2
2
 
3
- describe('RAMCard', () => {
4
- let ramCard: RAMCard
3
+ describe('RAMBank', () => {
4
+ let ramCard: RAMBank
5
5
 
6
6
  beforeEach(() => {
7
- ramCard = new RAMCard()
7
+ ramCard = new RAMBank()
8
8
  })
9
9
 
10
10
  describe('Static Properties', () => {
11
11
  it('should have correct total size', () => {
12
- expect(RAMCard.TOTAL_SIZE).toBe(256 * 1024)
12
+ expect(RAMBank.TOTAL_SIZE).toBe(256 * 1024)
13
13
  })
14
14
 
15
15
  it('should have correct bank size', () => {
16
- expect(RAMCard.BANK_SIZE).toBe(1024)
16
+ expect(RAMBank.BANK_SIZE).toBe(1024)
17
17
  })
18
18
 
19
19
  it('should have correct number of banks', () => {
20
- expect(RAMCard.NUM_BANKS).toBe(256)
20
+ expect(RAMBank.NUM_BANKS).toBe(256)
21
21
  })
22
22
 
23
23
  it('should have correct bank control register address', () => {
24
- expect(RAMCard.BANK_CONTROL_REGISTER).toBe(0x3FF)
24
+ expect(RAMBank.BANK_CONTROL_REGISTER).toBe(0x3FF)
25
25
  })
26
26
  })
27
27
 
28
28
  describe('Initialization', () => {
29
29
  it('should initialize with all data as 0x00', () => {
30
- for (let i = 0; i < RAMCard.TOTAL_SIZE; i++) {
30
+ for (let i = 0; i < RAMBank.TOTAL_SIZE; i++) {
31
31
  expect(ramCard.data[i]).toBe(0x00)
32
32
  }
33
33
  })
@@ -60,13 +60,13 @@ describe('RAMCard', () => {
60
60
 
61
61
  it('should read bank control register and return current bank', () => {
62
62
  ramCard.currentBank = 0
63
- expect(ramCard.read(RAMCard.BANK_CONTROL_REGISTER)).toBe(0)
63
+ expect(ramCard.read(RAMBank.BANK_CONTROL_REGISTER)).toBe(0)
64
64
 
65
65
  ramCard.currentBank = 42
66
- expect(ramCard.read(RAMCard.BANK_CONTROL_REGISTER)).toBe(42)
66
+ expect(ramCard.read(RAMBank.BANK_CONTROL_REGISTER)).toBe(42)
67
67
 
68
68
  ramCard.currentBank = 255
69
- expect(ramCard.read(RAMCard.BANK_CONTROL_REGISTER)).toBe(255)
69
+ expect(ramCard.read(RAMBank.BANK_CONTROL_REGISTER)).toBe(255)
70
70
  })
71
71
  })
72
72
 
@@ -98,15 +98,15 @@ describe('RAMCard', () => {
98
98
  })
99
99
 
100
100
  it('should switch banks via bank control register', () => {
101
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, 5)
101
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, 5)
102
102
  expect(ramCard.currentBank).toBe(5)
103
103
  })
104
104
 
105
105
  it('should mask bank number to 0xFF', () => {
106
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, 0x1FF)
106
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, 0x1FF)
107
107
  expect(ramCard.currentBank).toBe(0xFF)
108
108
 
109
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, 0x100)
109
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, 0x100)
110
110
  expect(ramCard.currentBank).toBe(0x00)
111
111
  })
112
112
  })
@@ -118,7 +118,7 @@ describe('RAMCard', () => {
118
118
  expect(ramCard.read(50)).toBe(0x11)
119
119
 
120
120
  // Switch to bank 1
121
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, 1)
121
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, 1)
122
122
  expect(ramCard.read(50)).toBe(0x00)
123
123
 
124
124
  // Write different value to address 50 in bank 1
@@ -126,7 +126,7 @@ describe('RAMCard', () => {
126
126
  expect(ramCard.read(50)).toBe(0x22)
127
127
 
128
128
  // Switch back to bank 0
129
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, 0)
129
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, 0)
130
130
  expect(ramCard.read(50)).toBe(0x11)
131
131
  })
132
132
 
@@ -136,38 +136,38 @@ describe('RAMCard', () => {
136
136
  ramCard.write(200, 0xBB)
137
137
 
138
138
  // Switch to bank 1
139
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, 1)
139
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, 1)
140
140
  ramCard.write(100, 0xCC)
141
141
  ramCard.write(200, 0xDD)
142
142
 
143
143
  // Switch to bank 2
144
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, 2)
144
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, 2)
145
145
  ramCard.write(100, 0xEE)
146
146
 
147
147
  // Verify data in bank 2
148
148
  expect(ramCard.read(100)).toBe(0xEE)
149
149
 
150
150
  // Switch to bank 1
151
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, 1)
151
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, 1)
152
152
  expect(ramCard.read(100)).toBe(0xCC)
153
153
  expect(ramCard.read(200)).toBe(0xDD)
154
154
 
155
155
  // Switch to bank 0
156
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, 0)
156
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, 0)
157
157
  expect(ramCard.read(100)).toBe(0xAA)
158
158
  expect(ramCard.read(200)).toBe(0xBB)
159
159
  })
160
160
 
161
161
  it('should switch between all 256 banks', () => {
162
162
  // Write unique val to each bank at address 0
163
- for (let bank = 0; bank < RAMCard.NUM_BANKS; bank++) {
164
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, bank)
163
+ for (let bank = 0; bank < RAMBank.NUM_BANKS; bank++) {
164
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, bank)
165
165
  ramCard.write(0, bank & 0xFF)
166
166
  }
167
167
 
168
168
  // Verify each bank has correct value
169
- for (let bank = 0; bank < RAMCard.NUM_BANKS; bank++) {
170
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, bank)
169
+ for (let bank = 0; bank < RAMBank.NUM_BANKS; bank++) {
170
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, bank)
171
171
  expect(ramCard.read(0)).toBe(bank & 0xFF)
172
172
  }
173
173
  })
@@ -176,7 +176,7 @@ describe('RAMCard', () => {
176
176
  describe('Reset', () => {
177
177
  it('should not reset on warm start', () => {
178
178
  ramCard.write(100, 0x42)
179
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, 42)
179
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, 42)
180
180
 
181
181
  ramCard.reset(false)
182
182
 
@@ -187,17 +187,17 @@ describe('RAMCard', () => {
187
187
  it('should reset all data on cold start', () => {
188
188
  ramCard.write(100, 0x42)
189
189
  ramCard.write(500, 0xAB)
190
- ramCard.write(RAMCard.TOTAL_SIZE - 1, 0xFF)
190
+ ramCard.write(RAMBank.TOTAL_SIZE - 1, 0xFF)
191
191
 
192
192
  ramCard.reset(true)
193
193
 
194
194
  expect(ramCard.data[100]).toBe(0x00)
195
195
  expect(ramCard.data[500]).toBe(0x00)
196
- expect(ramCard.data[RAMCard.TOTAL_SIZE - 1]).toBe(0x00)
196
+ expect(ramCard.data[RAMBank.TOTAL_SIZE - 1]).toBe(0x00)
197
197
  })
198
198
 
199
199
  it('should reset to bank 0 on cold start', () => {
200
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, 100)
200
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, 100)
201
201
  expect(ramCard.currentBank).toBe(100)
202
202
 
203
203
  ramCard.reset(true)
@@ -208,8 +208,8 @@ describe('RAMCard', () => {
208
208
  it('should clear all RAM on cold start', () => {
209
209
  // Fill multiple banks with data
210
210
  for (let bank = 0; bank < 10; bank++) {
211
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, bank)
212
- for (let addr = 0; addr < RAMCard.BANK_SIZE; addr++) {
211
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, bank)
212
+ for (let addr = 0; addr < RAMBank.BANK_SIZE; addr++) {
213
213
  ramCard.write(addr, bank)
214
214
  }
215
215
  }
@@ -217,7 +217,7 @@ describe('RAMCard', () => {
217
217
  ramCard.reset(true)
218
218
 
219
219
  // Verify all data is cleared
220
- for (let i = 0; i < RAMCard.TOTAL_SIZE; i++) {
220
+ for (let i = 0; i < RAMBank.TOTAL_SIZE; i++) {
221
221
  expect(ramCard.data[i]).toBe(0x00)
222
222
  }
223
223
  })
@@ -257,7 +257,7 @@ describe('RAMCard', () => {
257
257
 
258
258
  it('should handle rapid bank switches', () => {
259
259
  for (let i = 0; i < 100; i++) {
260
- ramCard.write(RAMCard.BANK_CONTROL_REGISTER, i % 256)
260
+ ramCard.write(RAMBank.BANK_CONTROL_REGISTER, i % 256)
261
261
  ramCard.write(0, i & 0xFF)
262
262
  }
263
263
 
@@ -1,13 +1,13 @@
1
- import { RTCCard } from '../../components/IO/RTCCard'
1
+ import { RTC } from '../../components/IO/RTC'
2
2
 
3
3
  const bcdToDecimal = (bcd: number): number => (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f)
4
4
 
5
- const enableTransfers = (rtc: RTCCard): void => {
5
+ const enableTransfers = (rtc: RTC): void => {
6
6
  rtc.write(0x0f, 0x80)
7
7
  rtc.tick(1)
8
8
  }
9
9
 
10
- const setTime = (rtc: RTCCard, values: {
10
+ const setTime = (rtc: RTC, values: {
11
11
  seconds: number
12
12
  minutes: number
13
13
  hours: number
@@ -28,11 +28,11 @@ const setTime = (rtc: RTCCard, values: {
28
28
  rtc.write(0x07, values.century)
29
29
  }
30
30
 
31
- describe('RTCCard', () => {
32
- let rtc: RTCCard
31
+ describe('RTC', () => {
32
+ let rtc: RTC
33
33
 
34
34
  beforeEach(() => {
35
- rtc = new RTCCard()
35
+ rtc = new RTC()
36
36
  })
37
37
 
38
38
  describe('Initialization', () => {
@@ -1,4 +1,4 @@
1
- import { SoundCard, SIDVoice, EnvelopeState, SID_CLOCK_NTSC } from '../../components/IO/SoundCard'
1
+ import { Sound, SIDVoice, EnvelopeState, SID_CLOCK_NTSC } from '../../components/IO/Sound'
2
2
 
3
3
  // Voice register offsets (relative to voice base)
4
4
  const VOICE1_BASE = 0x00
@@ -35,21 +35,21 @@ const CTRL_PULSE = 0x40
35
35
  const CTRL_NOISE = 0x80
36
36
 
37
37
  /**
38
- * Helper: tick the SoundCard for a given number of macro-ticks
38
+ * Helper: tick the Sound for a given number of macro-ticks
39
39
  * Each tick processes 128 SID clock cycles internally
40
40
  */
41
- const tickN = (sid: SoundCard, n: number): void => {
41
+ const tickN = (sid: Sound, n: number): void => {
42
42
  for (let i = 0; i < n; i++) {
43
43
  sid.tick(SID_CLOCK_NTSC)
44
44
  }
45
45
  }
46
46
 
47
- describe('SoundCard (MOS 6581 SID)', () => {
47
+ describe('Sound (MOS 6581 SID)', () => {
48
48
 
49
- let sid: SoundCard
49
+ let sid: Sound
50
50
 
51
51
  beforeEach(() => {
52
- sid = new SoundCard()
52
+ sid = new Sound()
53
53
  sid.sampleRate = 44100
54
54
  sid.sidClock = SID_CLOCK_NTSC
55
55
  })