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.
- package/README.md +12 -12
- package/dist/components/CPU.d.ts +162 -0
- package/dist/components/Cart.d.ts +9 -0
- package/dist/components/IO/ACIA.d.ts +76 -0
- package/dist/components/IO/ACIA.js +282 -0
- package/dist/components/IO/ACIA.js.map +1 -0
- package/dist/components/IO/Attachments/Attachment.d.ts +112 -0
- package/dist/components/IO/Attachments/Attachment.js +71 -0
- package/dist/components/IO/Attachments/Attachment.js.map +1 -0
- package/dist/components/IO/Attachments/JoystickAttachment.d.ts +53 -0
- package/dist/components/IO/Attachments/JoystickAttachment.js +90 -0
- package/dist/components/IO/Attachments/JoystickAttachment.js.map +1 -0
- package/dist/components/IO/Attachments/KeyboardEncoderAttachment.d.ts +63 -0
- package/dist/components/IO/Attachments/KeyboardEncoderAttachment.js +489 -0
- package/dist/components/IO/Attachments/KeyboardEncoderAttachment.js.map +1 -0
- package/dist/components/IO/Attachments/KeyboardMatrixAttachment.d.ts +44 -0
- package/dist/components/IO/Attachments/KeyboardMatrixAttachment.js +274 -0
- package/dist/components/IO/Attachments/KeyboardMatrixAttachment.js.map +1 -0
- package/dist/components/IO/Attachments/KeypadAttachment.d.ts +47 -0
- package/dist/components/IO/Attachments/KeypadAttachment.js +141 -0
- package/dist/components/IO/Attachments/KeypadAttachment.js.map +1 -0
- package/dist/components/IO/Attachments/LCDAttachment.d.ts +110 -0
- package/dist/components/IO/Attachments/LCDAttachment.js +716 -0
- package/dist/components/IO/Attachments/LCDAttachment.js.map +1 -0
- package/dist/components/IO/Attachments/SNESAttachment.d.ts +85 -0
- package/dist/components/IO/Attachments/SNESAttachment.js +184 -0
- package/dist/components/IO/Attachments/SNESAttachment.js.map +1 -0
- package/dist/components/IO/DevOutputBoard.d.ts +19 -0
- package/dist/components/IO/DevOutputBoard.js +33 -0
- package/dist/components/IO/DevOutputBoard.js.map +1 -0
- package/dist/components/IO/Empty.d.ts +9 -0
- package/dist/components/IO/Empty.js +5 -7
- package/dist/components/IO/Empty.js.map +1 -1
- package/dist/components/IO/EmptyCard.d.ts +9 -0
- package/dist/components/IO/GPIOAttachments/GPIOAttachment.d.ts +112 -0
- package/dist/components/IO/GPIOAttachments/GPIOJoystickAttachment.d.ts +53 -0
- package/dist/components/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.d.ts +63 -0
- package/dist/components/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.d.ts +44 -0
- package/dist/components/IO/GPIOAttachments/GPIOKeypadAttachment.d.ts +47 -0
- package/dist/components/IO/GPIOAttachments/GPIOLCDAttachment.d.ts +110 -0
- package/dist/components/IO/GPIOCard.d.ts +105 -0
- package/dist/components/IO/GPIOCard.js.map +1 -1
- package/dist/components/IO/RAMBank.d.ts +37 -0
- package/dist/components/IO/RAMBank.js +63 -0
- package/dist/components/IO/RAMBank.js.map +1 -0
- package/dist/components/IO/RAMCard.d.ts +37 -0
- package/dist/components/IO/RTC.d.ts +107 -0
- package/dist/components/IO/RTC.js +483 -0
- package/dist/components/IO/RTC.js.map +1 -0
- package/dist/components/IO/RTCCard.d.ts +107 -0
- package/dist/components/IO/SerialCard.d.ts +76 -0
- package/dist/components/IO/Sound.d.ts +120 -0
- package/dist/components/IO/Sound.js +622 -0
- package/dist/components/IO/Sound.js.map +1 -0
- package/dist/components/IO/SoundCard.d.ts +120 -0
- package/dist/components/IO/Storage.d.ts +74 -0
- package/dist/components/IO/Storage.js +409 -0
- package/dist/components/IO/Storage.js.map +1 -0
- package/dist/components/IO/StorageCard.d.ts +74 -0
- package/dist/components/IO/Terminal.d.ts +19 -0
- package/dist/components/IO/Terminal.js +33 -0
- package/dist/components/IO/Terminal.js.map +1 -0
- package/dist/components/IO/VIA.d.ts +105 -0
- package/dist/components/IO/VIA.js +597 -0
- package/dist/components/IO/VIA.js.map +1 -0
- package/dist/components/IO/Video.d.ts +141 -0
- package/dist/components/IO/Video.js +630 -0
- package/dist/components/IO/Video.js.map +1 -0
- package/dist/components/IO/VideoCard.d.ts +141 -0
- package/dist/components/IO.d.ts +8 -0
- package/dist/components/Machine.d.ts +62 -0
- package/dist/components/Machine.js +260 -153
- package/dist/components/Machine.js.map +1 -1
- package/dist/components/RAM.d.ts +9 -0
- package/dist/components/ROM.d.ts +9 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +61 -28
- package/dist/index.js.map +1 -1
- package/dist/lib.d.ts +22 -0
- package/dist/lib.js +47 -0
- package/dist/lib.js.map +1 -0
- package/dist/tests/CPU.test.d.ts +1 -0
- package/dist/tests/Cart.test.d.ts +1 -0
- package/dist/tests/IO/ACIA.test.d.ts +1 -0
- package/dist/tests/IO/ACIA.test.js +423 -0
- package/dist/tests/IO/ACIA.test.js.map +1 -0
- package/dist/tests/IO/Attachments/Attachment.test.d.ts +1 -0
- package/dist/tests/IO/Attachments/Attachment.test.js +339 -0
- package/dist/tests/IO/Attachments/Attachment.test.js.map +1 -0
- package/dist/tests/IO/Attachments/JoystickAttachment.test.d.ts +1 -0
- package/dist/tests/IO/Attachments/JoystickAttachment.test.js +126 -0
- package/dist/tests/IO/Attachments/JoystickAttachment.test.js.map +1 -0
- package/dist/tests/IO/Attachments/KeyboardEncoderAttachment.test.d.ts +1 -0
- package/dist/tests/IO/Attachments/KeyboardEncoderAttachment.test.js +779 -0
- package/dist/tests/IO/Attachments/KeyboardEncoderAttachment.test.js.map +1 -0
- package/dist/tests/IO/Attachments/KeyboardMatrixAttachment.test.d.ts +1 -0
- package/dist/tests/IO/Attachments/KeyboardMatrixAttachment.test.js +355 -0
- package/dist/tests/IO/Attachments/KeyboardMatrixAttachment.test.js.map +1 -0
- package/dist/tests/IO/Attachments/KeypadAttachment.test.d.ts +1 -0
- package/dist/tests/IO/Attachments/KeypadAttachment.test.js +323 -0
- package/dist/tests/IO/Attachments/KeypadAttachment.test.js.map +1 -0
- package/dist/tests/IO/Attachments/LCDAttachment.test.d.ts +1 -0
- package/dist/tests/IO/Attachments/LCDAttachment.test.js +627 -0
- package/dist/tests/IO/Attachments/LCDAttachment.test.js.map +1 -0
- package/dist/tests/IO/Attachments/SNESAttachment.test.d.ts +1 -0
- package/dist/tests/IO/Attachments/SNESAttachment.test.js +331 -0
- package/dist/tests/IO/Attachments/SNESAttachment.test.js.map +1 -0
- package/dist/tests/IO/Empty.test.d.ts +1 -0
- package/dist/tests/IO/Empty.test.js +121 -0
- package/dist/tests/IO/Empty.test.js.map +1 -0
- package/dist/tests/IO/GPIOAttachments/GPIOAttachment.test.d.ts +1 -0
- package/dist/tests/IO/GPIOAttachments/GPIOJoystickAttachment.test.d.ts +1 -0
- package/dist/tests/IO/GPIOAttachments/GPIOKeyboardEncoderAttachment.test.d.ts +1 -0
- package/dist/tests/IO/GPIOAttachments/GPIOKeyboardMatrixAttachment.test.d.ts +1 -0
- package/dist/tests/IO/GPIOAttachments/GPIOKeypadAttachment.test.d.ts +1 -0
- package/dist/tests/IO/GPIOAttachments/GPIOLCDAttachment.test.d.ts +1 -0
- package/dist/tests/IO/GPIOCard.test.d.ts +1 -0
- package/dist/tests/IO/GPIOCard.test.js.map +1 -1
- package/dist/tests/IO/RAMBank.test.d.ts +1 -0
- package/dist/tests/IO/RAMBank.test.js +229 -0
- package/dist/tests/IO/RAMBank.test.js.map +1 -0
- package/dist/tests/IO/RAMCard.test.d.ts +1 -0
- package/dist/tests/IO/RTC.test.d.ts +1 -0
- package/dist/tests/IO/RTC.test.js +177 -0
- package/dist/tests/IO/RTC.test.js.map +1 -0
- package/dist/tests/IO/RTCCard.test.d.ts +1 -0
- package/dist/tests/IO/SerialCard.test.d.ts +1 -0
- package/dist/tests/IO/Sound.test.d.ts +1 -0
- package/dist/tests/IO/Sound.test.js +528 -0
- package/dist/tests/IO/Sound.test.js.map +1 -0
- package/dist/tests/IO/SoundCard.test.d.ts +1 -0
- package/dist/tests/IO/Storage.test.d.ts +1 -0
- package/dist/tests/IO/Storage.test.js +656 -0
- package/dist/tests/IO/Storage.test.js.map +1 -0
- package/dist/tests/IO/StorageCard.test.d.ts +1 -0
- package/dist/tests/IO/VIA.test.d.ts +1 -0
- package/dist/tests/IO/VIA.test.js +503 -0
- package/dist/tests/IO/VIA.test.js.map +1 -0
- package/dist/tests/IO/Video.test.d.ts +1 -0
- package/dist/tests/IO/Video.test.js +549 -0
- package/dist/tests/IO/Video.test.js.map +1 -0
- package/dist/tests/IO/VideoCard.test.d.ts +1 -0
- package/dist/tests/Machine.test.d.ts +1 -0
- package/dist/tests/Machine.test.js +27 -42
- package/dist/tests/Machine.test.js.map +1 -1
- package/dist/tests/RAM.test.d.ts +1 -0
- package/dist/tests/ROM.test.d.ts +1 -0
- package/package.json +5 -3
- package/src/components/IO/{SerialCard.ts → ACIA.ts} +2 -2
- package/src/components/IO/{GPIOAttachments/GPIOAttachment.ts → Attachments/Attachment.ts} +2 -2
- package/src/components/IO/{GPIOAttachments/GPIOJoystickAttachment.ts → Attachments/JoystickAttachment.ts} +3 -3
- package/src/components/IO/{GPIOAttachments/GPIOKeyboardEncoderAttachment.ts → Attachments/KeyboardEncoderAttachment.ts} +3 -3
- package/src/components/IO/{GPIOAttachments/GPIOKeyboardMatrixAttachment.ts → Attachments/KeyboardMatrixAttachment.ts} +5 -5
- package/src/components/IO/{GPIOAttachments/GPIOKeypadAttachment.ts → Attachments/KeypadAttachment.ts} +3 -3
- package/src/components/IO/{GPIOAttachments/GPIOLCDAttachment.ts → Attachments/LCDAttachment.ts} +7 -7
- package/src/components/IO/{EmptyCard.ts → Empty.ts} +1 -1
- package/src/components/IO/{RAMCard.ts → RAMBank.ts} +8 -8
- package/src/components/IO/{RTCCard.ts → RTC.ts} +1 -1
- package/src/components/IO/{SoundCard.ts → Sound.ts} +2 -2
- package/src/components/IO/{StorageCard.ts → Storage.ts} +70 -73
- package/src/components/IO/Terminal.ts +34 -0
- package/src/components/IO/{GPIOCard.ts → VIA.ts} +64 -64
- package/src/components/IO/{VideoCard.ts → Video.ts} +1 -1
- package/src/components/Machine.ts +286 -160
- package/src/index.ts +65 -35
- package/src/lib.ts +27 -0
- package/src/tests/IO/{SerialCard.test.ts → ACIA.test.ts} +5 -5
- package/src/tests/IO/{GPIOAttachments/GPIOAttachment.test.ts → Attachments/Attachment.test.ts} +12 -12
- package/src/tests/IO/{GPIOAttachments/GPIOJoystickAttachment.test.ts → Attachments/JoystickAttachment.test.ts} +23 -23
- package/src/tests/IO/{GPIOAttachments/GPIOKeyboardEncoderAttachment.test.ts → Attachments/KeyboardEncoderAttachment.test.ts} +4 -4
- package/src/tests/IO/{GPIOAttachments/GPIOKeyboardMatrixAttachment.test.ts → Attachments/KeyboardMatrixAttachment.test.ts} +5 -5
- package/src/tests/IO/{GPIOAttachments/GPIOKeypadAttachment.test.ts → Attachments/KeypadAttachment.test.ts} +38 -38
- package/src/tests/IO/{GPIOAttachments/GPIOLCDAttachment.test.ts → Attachments/LCDAttachment.test.ts} +12 -12
- package/src/tests/IO/Empty.test.ts +143 -0
- package/src/tests/IO/{RAMCard.test.ts → RAMBank.test.ts} +33 -33
- package/src/tests/IO/{RTCCard.test.ts → RTC.test.ts} +6 -6
- package/src/tests/IO/{SoundCard.test.ts → Sound.test.ts} +6 -6
- package/src/tests/IO/{StorageCard.test.ts → Storage.test.ts} +34 -25
- package/src/tests/IO/{GPIOCard.test.ts → VIA.test.ts} +7 -7
- package/src/tests/IO/{VideoCard.test.ts → Video.test.ts} +13 -13
- package/src/tests/Machine.test.ts +31 -38
- package/tsconfig.json +1 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { KeypadAttachment } from '../../../components/IO/Attachments/KeypadAttachment'
|
|
2
2
|
|
|
3
|
-
describe('
|
|
4
|
-
let keypadA:
|
|
5
|
-
let keypadB:
|
|
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
|
|
9
|
-
keypadB = new
|
|
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
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
88
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x1E)).toBe(0x01)
|
|
89
89
|
})
|
|
90
90
|
|
|
91
91
|
it('2 (0x1F) → $02', () => {
|
|
92
|
-
expect(pressAndReadA(new
|
|
92
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x1F)).toBe(0x02)
|
|
93
93
|
})
|
|
94
94
|
|
|
95
95
|
it('3 (0x20) → $03', () => {
|
|
96
|
-
expect(pressAndReadA(new
|
|
96
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x20)).toBe(0x03)
|
|
97
97
|
})
|
|
98
98
|
|
|
99
99
|
it('4 (0x21) → $04', () => {
|
|
100
|
-
expect(pressAndReadA(new
|
|
100
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x21)).toBe(0x04)
|
|
101
101
|
})
|
|
102
102
|
|
|
103
103
|
it('5 (0x22) → $05', () => {
|
|
104
|
-
expect(pressAndReadA(new
|
|
104
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x22)).toBe(0x05)
|
|
105
105
|
})
|
|
106
106
|
|
|
107
107
|
it('6 (0x23) → $06', () => {
|
|
108
|
-
expect(pressAndReadA(new
|
|
108
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x23)).toBe(0x06)
|
|
109
109
|
})
|
|
110
110
|
|
|
111
111
|
it('7 (0x24) → $07', () => {
|
|
112
|
-
expect(pressAndReadA(new
|
|
112
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x24)).toBe(0x07)
|
|
113
113
|
})
|
|
114
114
|
|
|
115
115
|
it('8 (0x25) → $08', () => {
|
|
116
|
-
expect(pressAndReadA(new
|
|
116
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x25)).toBe(0x08)
|
|
117
117
|
})
|
|
118
118
|
|
|
119
119
|
it('9 (0x26) → $09', () => {
|
|
120
|
-
expect(pressAndReadA(new
|
|
120
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x26)).toBe(0x09)
|
|
121
121
|
})
|
|
122
122
|
|
|
123
123
|
it('0 (0x27) → $0A', () => {
|
|
124
|
-
expect(pressAndReadA(new
|
|
124
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x27)).toBe(0x0A)
|
|
125
125
|
})
|
|
126
126
|
|
|
127
127
|
it('Right Arrow (0x4F) → $0B ►', () => {
|
|
128
|
-
expect(pressAndReadA(new
|
|
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
|
|
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
|
|
139
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x09)).toBe(0x0C)
|
|
140
140
|
})
|
|
141
141
|
|
|
142
142
|
it('e (0x08) → $0D E', () => {
|
|
143
|
-
expect(pressAndReadA(new
|
|
143
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x08)).toBe(0x0D)
|
|
144
144
|
})
|
|
145
145
|
|
|
146
146
|
it('d (0x07) → $0E D', () => {
|
|
147
|
-
expect(pressAndReadA(new
|
|
147
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x07)).toBe(0x0E)
|
|
148
148
|
})
|
|
149
149
|
|
|
150
150
|
it('c (0x06) → $0F C', () => {
|
|
151
|
-
expect(pressAndReadA(new
|
|
151
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x06)).toBe(0x0F)
|
|
152
152
|
})
|
|
153
153
|
|
|
154
154
|
it('Escape (0x29) → $10 ESC', () => {
|
|
155
|
-
expect(pressAndReadA(new
|
|
155
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x29)).toBe(0x10)
|
|
156
156
|
})
|
|
157
157
|
|
|
158
158
|
it('Insert (0x49) → $11 INS', () => {
|
|
159
|
-
expect(pressAndReadA(new
|
|
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
|
|
163
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x4B)).toBe(0x12)
|
|
164
164
|
})
|
|
165
165
|
|
|
166
166
|
it('a (0x04) → $13 A', () => {
|
|
167
|
-
expect(pressAndReadA(new
|
|
167
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x04)).toBe(0x13)
|
|
168
168
|
})
|
|
169
169
|
|
|
170
170
|
it('Up Arrow (0x52) → $14 ▲', () => {
|
|
171
|
-
expect(pressAndReadA(new
|
|
171
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x52)).toBe(0x14)
|
|
172
172
|
})
|
|
173
173
|
|
|
174
174
|
it('Enter (0x28) → $14 ▲', () => {
|
|
175
|
-
expect(pressAndReadA(new
|
|
175
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x28)).toBe(0x14)
|
|
176
176
|
})
|
|
177
177
|
|
|
178
178
|
it('Delete (0x4C) → $15 DEL', () => {
|
|
179
|
-
expect(pressAndReadA(new
|
|
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
|
|
183
|
+
expect(pressAndReadA(new KeypadAttachment(true), 0x4E)).toBe(0x16)
|
|
184
184
|
})
|
|
185
185
|
|
|
186
186
|
it('b (0x05) → $17 B', () => {
|
|
187
|
-
expect(pressAndReadA(new
|
|
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
|
|
192
|
-
expect(pressAndReadB(new
|
|
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
|
|
package/src/tests/IO/{GPIOAttachments/GPIOLCDAttachment.test.ts → Attachments/LCDAttachment.test.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
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/
|
|
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('
|
|
27
|
-
let lcd:
|
|
26
|
+
describe('LCDAttachment', () => {
|
|
27
|
+
let lcd: LCDAttachment
|
|
28
28
|
|
|
29
29
|
beforeEach(() => {
|
|
30
|
-
lcd = new
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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:
|
|
658
|
+
let lcd1: LCDAttachment
|
|
659
659
|
|
|
660
660
|
beforeEach(() => {
|
|
661
|
-
lcd1 = new
|
|
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 {
|
|
1
|
+
import { RAMBank } from '../../components/IO/RAMBank'
|
|
2
2
|
|
|
3
|
-
describe('
|
|
4
|
-
let ramCard:
|
|
3
|
+
describe('RAMBank', () => {
|
|
4
|
+
let ramCard: RAMBank
|
|
5
5
|
|
|
6
6
|
beforeEach(() => {
|
|
7
|
-
ramCard = new
|
|
7
|
+
ramCard = new RAMBank()
|
|
8
8
|
})
|
|
9
9
|
|
|
10
10
|
describe('Static Properties', () => {
|
|
11
11
|
it('should have correct total size', () => {
|
|
12
|
-
expect(
|
|
12
|
+
expect(RAMBank.TOTAL_SIZE).toBe(256 * 1024)
|
|
13
13
|
})
|
|
14
14
|
|
|
15
15
|
it('should have correct bank size', () => {
|
|
16
|
-
expect(
|
|
16
|
+
expect(RAMBank.BANK_SIZE).toBe(1024)
|
|
17
17
|
})
|
|
18
18
|
|
|
19
19
|
it('should have correct number of banks', () => {
|
|
20
|
-
expect(
|
|
20
|
+
expect(RAMBank.NUM_BANKS).toBe(256)
|
|
21
21
|
})
|
|
22
22
|
|
|
23
23
|
it('should have correct bank control register address', () => {
|
|
24
|
-
expect(
|
|
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 <
|
|
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(
|
|
63
|
+
expect(ramCard.read(RAMBank.BANK_CONTROL_REGISTER)).toBe(0)
|
|
64
64
|
|
|
65
65
|
ramCard.currentBank = 42
|
|
66
|
-
expect(ramCard.read(
|
|
66
|
+
expect(ramCard.read(RAMBank.BANK_CONTROL_REGISTER)).toBe(42)
|
|
67
67
|
|
|
68
68
|
ramCard.currentBank = 255
|
|
69
|
-
expect(ramCard.read(
|
|
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(
|
|
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(
|
|
106
|
+
ramCard.write(RAMBank.BANK_CONTROL_REGISTER, 0x1FF)
|
|
107
107
|
expect(ramCard.currentBank).toBe(0xFF)
|
|
108
108
|
|
|
109
|
-
ramCard.write(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 <
|
|
164
|
-
ramCard.write(
|
|
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 <
|
|
170
|
-
ramCard.write(
|
|
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(
|
|
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(
|
|
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[
|
|
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(
|
|
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(
|
|
212
|
-
for (let addr = 0; 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 <
|
|
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(
|
|
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 {
|
|
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:
|
|
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:
|
|
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('
|
|
32
|
-
let rtc:
|
|
31
|
+
describe('RTC', () => {
|
|
32
|
+
let rtc: RTC
|
|
33
33
|
|
|
34
34
|
beforeEach(() => {
|
|
35
|
-
rtc = new
|
|
35
|
+
rtc = new RTC()
|
|
36
36
|
})
|
|
37
37
|
|
|
38
38
|
describe('Initialization', () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
|
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:
|
|
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('
|
|
47
|
+
describe('Sound (MOS 6581 SID)', () => {
|
|
48
48
|
|
|
49
|
-
let sid:
|
|
49
|
+
let sid: Sound
|
|
50
50
|
|
|
51
51
|
beforeEach(() => {
|
|
52
|
-
sid = new
|
|
52
|
+
sid = new Sound()
|
|
53
53
|
sid.sampleRate = 44100
|
|
54
54
|
sid.sidClock = SID_CLOCK_NTSC
|
|
55
55
|
})
|