ac6502 1.3.0 → 1.4.1
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 +139 -32
- 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/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/GPIOCard.d.ts +5 -5
- 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/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/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/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/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/Machine.d.ts +20 -24
- package/dist/components/Machine.js +249 -166
- package/dist/components/Machine.js.map +1 -1
- package/dist/index.js +28 -14
- package/dist/index.js.map +1 -1
- package/dist/lib.d.ts +16 -16
- package/dist/lib.js +32 -32
- package/dist/lib.js.map +1 -1
- 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/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/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/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/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/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/Machine.test.js +27 -42
- package/dist/tests/Machine.test.js.map +1 -1
- package/package.json +1 -1
- 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/{DevOutputBoard.ts → Terminal.ts} +2 -2
- 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 +276 -176
- package/src/index.ts +34 -21
- package/src/lib.ts +16 -16
- 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
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Video, TmsMode, TmsColor } from '../../components/IO/Video'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Helper: write a register value through the control port (two-stage write)
|
|
5
5
|
*/
|
|
6
|
-
const writeRegister = (vdp:
|
|
6
|
+
const writeRegister = (vdp: Video, reg: number, value: number): void => {
|
|
7
7
|
vdp.write(1, value) // Stage 0: register value
|
|
8
8
|
vdp.write(1, 0x80 | reg) // Stage 1: register number with bit 7 set
|
|
9
9
|
}
|
|
@@ -11,7 +11,7 @@ const writeRegister = (vdp: VideoCard, reg: number, value: number): void => {
|
|
|
11
11
|
/**
|
|
12
12
|
* Helper: set VRAM write address through the control port
|
|
13
13
|
*/
|
|
14
|
-
const setWriteAddress = (vdp:
|
|
14
|
+
const setWriteAddress = (vdp: Video, addr: number): void => {
|
|
15
15
|
vdp.write(1, addr & 0xFF) // Stage 0: address low byte
|
|
16
16
|
vdp.write(1, ((addr >> 8) & 0x3F) | 0x40) // Stage 1: address high + write flag
|
|
17
17
|
}
|
|
@@ -19,7 +19,7 @@ const setWriteAddress = (vdp: VideoCard, addr: number): void => {
|
|
|
19
19
|
/**
|
|
20
20
|
* Helper: set VRAM read address through the control port
|
|
21
21
|
*/
|
|
22
|
-
const setReadAddress = (vdp:
|
|
22
|
+
const setReadAddress = (vdp: Video, addr: number): void => {
|
|
23
23
|
vdp.write(1, addr & 0xFF) // Stage 0: address low byte
|
|
24
24
|
vdp.write(1, (addr >> 8) & 0x3F) // Stage 1: address high (no write flag)
|
|
25
25
|
}
|
|
@@ -27,7 +27,7 @@ const setReadAddress = (vdp: VideoCard, addr: number): void => {
|
|
|
27
27
|
/**
|
|
28
28
|
* Helper: write a sequence of bytes to VRAM starting at an address
|
|
29
29
|
*/
|
|
30
|
-
const writeVramBytes = (vdp:
|
|
30
|
+
const writeVramBytes = (vdp: Video, addr: number, bytes: number[]): void => {
|
|
31
31
|
setWriteAddress(vdp, addr)
|
|
32
32
|
for (const b of bytes) {
|
|
33
33
|
vdp.write(0, b) // Data port
|
|
@@ -37,7 +37,7 @@ const writeVramBytes = (vdp: VideoCard, addr: number, bytes: number[]): void =>
|
|
|
37
37
|
/**
|
|
38
38
|
* Helper: setup Graphics I mode with standard table addresses
|
|
39
39
|
*/
|
|
40
|
-
const setupGraphicsI = (vdp:
|
|
40
|
+
const setupGraphicsI = (vdp: Video): void => {
|
|
41
41
|
writeRegister(vdp, 0, 0x00) // No external VDP, Graphics I
|
|
42
42
|
writeRegister(vdp, 1, 0x60) // 16K, display active, interrupts enabled, Graphics I
|
|
43
43
|
writeRegister(vdp, 2, 0x0E) // Name table at 0x3800
|
|
@@ -51,7 +51,7 @@ const setupGraphicsI = (vdp: VideoCard): void => {
|
|
|
51
51
|
/**
|
|
52
52
|
* Helper: setup Graphics II mode with standard table addresses
|
|
53
53
|
*/
|
|
54
|
-
const setupGraphicsII = (vdp:
|
|
54
|
+
const setupGraphicsII = (vdp: Video): void => {
|
|
55
55
|
writeRegister(vdp, 0, 0x02) // Graphics II mode
|
|
56
56
|
writeRegister(vdp, 1, 0x60) // 16K, display active, interrupts enabled
|
|
57
57
|
writeRegister(vdp, 2, 0x0E) // Name table at 0x3800
|
|
@@ -65,7 +65,7 @@ const setupGraphicsII = (vdp: VideoCard): void => {
|
|
|
65
65
|
/**
|
|
66
66
|
* Helper: setup Text mode
|
|
67
67
|
*/
|
|
68
|
-
const setupTextMode = (vdp:
|
|
68
|
+
const setupTextMode = (vdp: Video): void => {
|
|
69
69
|
writeRegister(vdp, 0, 0x00) // No external VDP
|
|
70
70
|
writeRegister(vdp, 1, 0x70) // 16K, display active, interrupts, Text mode
|
|
71
71
|
writeRegister(vdp, 2, 0x0E) // Name table at 0x3800
|
|
@@ -78,7 +78,7 @@ const setupTextMode = (vdp: VideoCard): void => {
|
|
|
78
78
|
* Must not overshoot into the next frame (scanline 0 of the next
|
|
79
79
|
* frame clears the status register during sprite processing).
|
|
80
80
|
*/
|
|
81
|
-
const renderOneFrame = (vdp:
|
|
81
|
+
const renderOneFrame = (vdp: Video, frequency: number = 2000000): void => {
|
|
82
82
|
// At 2MHz: cyclesPerFrame ≈ 33333, each tick = 128 cycles → ~261 ticks/frame
|
|
83
83
|
const ticksPerFrame = Math.ceil((frequency / 60) / 128)
|
|
84
84
|
for (let i = 0; i < ticksPerFrame; i++) {
|
|
@@ -89,7 +89,7 @@ const renderOneFrame = (vdp: VideoCard, frequency: number = 2000000): void => {
|
|
|
89
89
|
/**
|
|
90
90
|
* Helper: clear sprite attribute table (set all Y positions to 0xD0 = stop)
|
|
91
91
|
*/
|
|
92
|
-
const clearSprites = (vdp:
|
|
92
|
+
const clearSprites = (vdp: Video, spriteAttrAddr: number = 0x3B00): void => {
|
|
93
93
|
setWriteAddress(vdp, spriteAttrAddr)
|
|
94
94
|
for (let i = 0; i < 32; i++) {
|
|
95
95
|
vdp.write(0, 0xD0) // Y = stop sentinel
|
|
@@ -99,11 +99,11 @@ const clearSprites = (vdp: VideoCard, spriteAttrAddr: number = 0x3B00): void =>
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
describe('
|
|
103
|
-
let vdp:
|
|
102
|
+
describe('Video (TMS9918 VDP)', () => {
|
|
103
|
+
let vdp: Video
|
|
104
104
|
|
|
105
105
|
beforeEach(() => {
|
|
106
|
-
vdp = new
|
|
106
|
+
vdp = new Video()
|
|
107
107
|
})
|
|
108
108
|
|
|
109
109
|
// ================================================================
|
|
@@ -2,17 +2,18 @@ import { Machine } from '../components/Machine'
|
|
|
2
2
|
import { RAM } from '../components/RAM'
|
|
3
3
|
import { ROM } from '../components/ROM'
|
|
4
4
|
import { Cart } from '../components/Cart'
|
|
5
|
+
import { ACIA } from '../components/IO/ACIA'
|
|
5
6
|
|
|
6
7
|
describe('Machine', () => {
|
|
7
8
|
let machine: Machine
|
|
8
9
|
|
|
9
10
|
beforeEach(() => {
|
|
10
|
-
machine = new Machine()
|
|
11
|
+
machine = new Machine('cob')
|
|
11
12
|
})
|
|
12
13
|
|
|
13
14
|
afterEach(() => {
|
|
14
15
|
// Ensure the machine loop is stopped after each test
|
|
15
|
-
machine.
|
|
16
|
+
machine.stop()
|
|
16
17
|
})
|
|
17
18
|
|
|
18
19
|
describe('Initialization', () => {
|
|
@@ -22,7 +23,6 @@ describe('Machine', () => {
|
|
|
22
23
|
})
|
|
23
24
|
|
|
24
25
|
test('Machine initializes with correct default properties', () => {
|
|
25
|
-
expect(machine.isAlive).toBe(false)
|
|
26
26
|
expect(machine.isRunning).toBe(false)
|
|
27
27
|
expect(machine.frequency).toBe(2000000)
|
|
28
28
|
expect(machine.scale).toBe(2)
|
|
@@ -54,26 +54,11 @@ describe('Machine', () => {
|
|
|
54
54
|
})
|
|
55
55
|
|
|
56
56
|
describe('State Management', () => {
|
|
57
|
-
test('start() sets isRunning and isAlive to true', () => {
|
|
58
|
-
expect(machine.isRunning).toBe(false)
|
|
59
|
-
expect(machine.isAlive).toBe(false)
|
|
60
|
-
machine.start()
|
|
61
|
-
expect(machine.isRunning).toBe(true)
|
|
62
|
-
expect(machine.isAlive).toBe(true)
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
test('end() sets isRunning and isAlive to false', () => {
|
|
66
|
-
machine.start()
|
|
67
|
-
expect(machine.isRunning).toBe(true)
|
|
68
|
-
machine.end()
|
|
69
|
-
expect(machine.isRunning).toBe(false)
|
|
70
|
-
expect(machine.isAlive).toBe(false)
|
|
71
|
-
})
|
|
72
|
-
|
|
73
57
|
test('run() sets isRunning to true', () => {
|
|
74
58
|
expect(machine.isRunning).toBe(false)
|
|
75
59
|
machine.run()
|
|
76
60
|
expect(machine.isRunning).toBe(true)
|
|
61
|
+
machine.stop() // Cleanup
|
|
77
62
|
})
|
|
78
63
|
|
|
79
64
|
test('stop() sets isRunning to false', () => {
|
|
@@ -215,19 +200,19 @@ describe('Machine', () => {
|
|
|
215
200
|
expect(machine.cart).toBeUndefined()
|
|
216
201
|
})
|
|
217
202
|
|
|
218
|
-
test('loadCart should load cart data',
|
|
219
|
-
//
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
expect(machine.cart).
|
|
203
|
+
test('loadCart should load cart data', () => {
|
|
204
|
+
// Load cart with test data
|
|
205
|
+
const testData = new Uint8Array(16384).fill(0xEA) // NOP instruction
|
|
206
|
+
machine.loadCart(testData)
|
|
207
|
+
expect(machine.cart).toBeDefined()
|
|
223
208
|
})
|
|
224
209
|
})
|
|
225
210
|
|
|
226
211
|
describe('ROM Operations', () => {
|
|
227
|
-
test('loadROM should load ROM data',
|
|
228
|
-
//
|
|
229
|
-
|
|
230
|
-
|
|
212
|
+
test('loadROM should load ROM data', () => {
|
|
213
|
+
// Load ROM with test data
|
|
214
|
+
const testData = new Uint8Array(16384).fill(0xEA) // NOP instruction
|
|
215
|
+
machine.loadROM(testData)
|
|
231
216
|
expect(machine.rom).toBeDefined()
|
|
232
217
|
})
|
|
233
218
|
})
|
|
@@ -266,15 +251,18 @@ describe('Machine', () => {
|
|
|
266
251
|
|
|
267
252
|
describe('Input Handling', () => {
|
|
268
253
|
test('onReceive() passes data to Serial card', () => {
|
|
269
|
-
const
|
|
254
|
+
const acia = machine.io5 as ACIA
|
|
255
|
+
const spy = jest.spyOn(acia, 'onData')
|
|
270
256
|
machine.onReceive(0x41)
|
|
271
257
|
expect(spy).toHaveBeenCalledWith(0x41)
|
|
272
258
|
spy.mockRestore()
|
|
273
259
|
})
|
|
274
260
|
|
|
275
261
|
test('onKeyDown() routes key to GPIO attachments', () => {
|
|
276
|
-
|
|
277
|
-
|
|
262
|
+
expect(machine.keyboardMatrixAttachment).toBeDefined()
|
|
263
|
+
expect(machine.keyboardEncoderAttachment).toBeDefined()
|
|
264
|
+
const matrixSpy = jest.spyOn(machine.keyboardMatrixAttachment!, 'updateKey')
|
|
265
|
+
const encoderSpy = jest.spyOn(machine.keyboardEncoderAttachment!, 'updateKey')
|
|
278
266
|
machine.onKeyDown(0x52) // Arrow Up USB HID keycode
|
|
279
267
|
expect(matrixSpy).toHaveBeenCalledWith(0x52, true)
|
|
280
268
|
expect(encoderSpy).toHaveBeenCalledWith(0x52, true)
|
|
@@ -283,8 +271,10 @@ describe('Machine', () => {
|
|
|
283
271
|
})
|
|
284
272
|
|
|
285
273
|
test('onKeyUp() routes key to GPIO attachments', () => {
|
|
286
|
-
|
|
287
|
-
|
|
274
|
+
expect(machine.keyboardMatrixAttachment).toBeDefined()
|
|
275
|
+
expect(machine.keyboardEncoderAttachment).toBeDefined()
|
|
276
|
+
const matrixSpy = jest.spyOn(machine.keyboardMatrixAttachment!, 'updateKey')
|
|
277
|
+
const encoderSpy = jest.spyOn(machine.keyboardEncoderAttachment!, 'updateKey')
|
|
288
278
|
machine.onKeyUp(0x52) // Arrow Up USB HID keycode
|
|
289
279
|
expect(matrixSpy).toHaveBeenCalledWith(0x52, false)
|
|
290
280
|
expect(encoderSpy).toHaveBeenCalledWith(0x52, false)
|
|
@@ -293,14 +283,16 @@ describe('Machine', () => {
|
|
|
293
283
|
})
|
|
294
284
|
|
|
295
285
|
test('onJoystickA() routes button state to joystick A attachment', () => {
|
|
296
|
-
|
|
286
|
+
expect(machine.joystickAttachmentA).toBeDefined()
|
|
287
|
+
const spy = jest.spyOn(machine.joystickAttachmentA!, 'updateJoystick')
|
|
297
288
|
machine.onJoystickA(0xFF)
|
|
298
289
|
expect(spy).toHaveBeenCalledWith(0xFF)
|
|
299
290
|
spy.mockRestore()
|
|
300
291
|
})
|
|
301
292
|
|
|
302
293
|
test('onJoystickB() routes button state to joystick B attachment', () => {
|
|
303
|
-
|
|
294
|
+
expect(machine.joystickAttachmentB).toBeDefined()
|
|
295
|
+
const spy = jest.spyOn(machine.joystickAttachmentB!, 'updateJoystick')
|
|
304
296
|
machine.onJoystickB(0xFF)
|
|
305
297
|
expect(spy).toHaveBeenCalledWith(0xFF)
|
|
306
298
|
spy.mockRestore()
|
|
@@ -374,11 +366,12 @@ describe('Machine', () => {
|
|
|
374
366
|
expect(machine.render).toBe(mockRender)
|
|
375
367
|
})
|
|
376
368
|
|
|
377
|
-
test('
|
|
369
|
+
test('ACIA uses transmit callback when set', () => {
|
|
378
370
|
const mockTransmit = jest.fn()
|
|
379
371
|
machine.transmit = mockTransmit
|
|
380
|
-
// Trigger
|
|
381
|
-
machine.io5
|
|
372
|
+
// Trigger ACIA to transmit if possible
|
|
373
|
+
const acia = machine.io5 as ACIA
|
|
374
|
+
acia.transmit?.(0x41)
|
|
382
375
|
expect(mockTransmit).toHaveBeenCalledWith(0x41)
|
|
383
376
|
})
|
|
384
377
|
})
|