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
|
@@ -2,57 +2,54 @@ import { CPU } from './CPU';
|
|
|
2
2
|
import { RAM } from './RAM';
|
|
3
3
|
import { ROM } from './ROM';
|
|
4
4
|
import { Cart } from './Cart';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { GPIOKeypadAttachment } from './IO/GPIOAttachments/GPIOKeypadAttachment';
|
|
5
|
+
import { KeyboardMatrixAttachment } from './IO/Attachments/KeyboardMatrixAttachment';
|
|
6
|
+
import { KeyboardEncoderAttachment } from './IO/Attachments/KeyboardEncoderAttachment';
|
|
7
|
+
import { JoystickAttachment } from './IO/Attachments/JoystickAttachment';
|
|
8
|
+
import { LCDAttachment } from './IO/Attachments/LCDAttachment';
|
|
9
|
+
import { KeypadAttachment } from './IO/Attachments/KeypadAttachment';
|
|
11
10
|
import { IO } from './IO';
|
|
12
11
|
export declare class Machine {
|
|
13
12
|
static MAX_FPS: number;
|
|
14
13
|
static FRAME_INTERVAL_MS: number;
|
|
15
14
|
private ioCycleAccumulator;
|
|
16
15
|
private ioTickInterval;
|
|
16
|
+
private loopHandle?;
|
|
17
17
|
cpu: CPU;
|
|
18
18
|
ram: RAM;
|
|
19
19
|
rom: ROM;
|
|
20
|
+
cart?: Cart;
|
|
20
21
|
io1: IO;
|
|
21
22
|
io2: IO;
|
|
22
23
|
io3: IO;
|
|
23
24
|
io4: IO;
|
|
24
|
-
io5:
|
|
25
|
+
io5: IO;
|
|
25
26
|
io6: IO;
|
|
26
27
|
io7: IO;
|
|
27
28
|
io8: IO;
|
|
28
|
-
|
|
29
|
+
keyboardMatrixAttachment?: KeyboardMatrixAttachment;
|
|
30
|
+
keyboardEncoderAttachment?: KeyboardEncoderAttachment;
|
|
31
|
+
joystickAttachmentA?: JoystickAttachment;
|
|
32
|
+
joystickAttachmentB?: JoystickAttachment;
|
|
33
|
+
lcdAttachment?: LCDAttachment;
|
|
34
|
+
keypadAttachment?: KeypadAttachment;
|
|
29
35
|
target: string;
|
|
30
|
-
keyboardMatrixAttachment: GPIOKeyboardMatrixAttachment;
|
|
31
|
-
keyboardEncoderAttachment: GPIOKeyboardEncoderAttachment;
|
|
32
|
-
joystickAttachmentA: GPIOJoystickAttachment;
|
|
33
|
-
joystickAttachmentB: GPIOJoystickAttachment;
|
|
34
|
-
lcdAttachment?: GPIOLCDAttachment;
|
|
35
|
-
keypadAttachment?: GPIOKeypadAttachment;
|
|
36
|
-
isAlive: boolean;
|
|
37
36
|
isRunning: boolean;
|
|
38
37
|
frequency: number;
|
|
39
38
|
scale: number;
|
|
40
39
|
frames: number;
|
|
41
|
-
frameDelay: number;
|
|
42
|
-
frameDelayCount: number;
|
|
43
40
|
startTime: number;
|
|
44
41
|
previousTime: number;
|
|
45
42
|
transmit?: (data: number) => void;
|
|
46
43
|
render?: () => void;
|
|
47
|
-
|
|
48
|
-
constructor(target
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
end(): void;
|
|
44
|
+
play?: (samples: Float32Array) => void;
|
|
45
|
+
constructor(target: string);
|
|
46
|
+
configureTarget(target: string): void;
|
|
47
|
+
loadROM: (data: Uint8Array | number[] | ArrayBuffer) => void;
|
|
48
|
+
loadCart: (data: Uint8Array | number[] | ArrayBuffer) => void;
|
|
53
49
|
run(): void;
|
|
54
50
|
stop(): void;
|
|
55
51
|
step(): void;
|
|
52
|
+
reset(coldStart: boolean): void;
|
|
56
53
|
tick(): void;
|
|
57
54
|
onReceive(data: number): void;
|
|
58
55
|
onKeyDown(scancode: number): void;
|
|
@@ -60,7 +57,6 @@ export declare class Machine {
|
|
|
60
57
|
onJoystickA(buttons: number): void;
|
|
61
58
|
onJoystickB(buttons: number): void;
|
|
62
59
|
private loop;
|
|
63
|
-
reset(coldStart: boolean): void;
|
|
64
60
|
read(address: number): number;
|
|
65
61
|
write(address: number, data: number): void;
|
|
66
62
|
}
|
|
@@ -1,197 +1,273 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.Machine = void 0;
|
|
13
4
|
const CPU_1 = require("./CPU");
|
|
14
5
|
const RAM_1 = require("./RAM");
|
|
15
6
|
const ROM_1 = require("./ROM");
|
|
16
7
|
const Cart_1 = require("./Cart");
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const promises_1 = require("fs/promises");
|
|
8
|
+
const VIA_1 = require("./IO/VIA");
|
|
9
|
+
const RAMBank_1 = require("./IO/RAMBank");
|
|
10
|
+
const RTC_1 = require("./IO/RTC");
|
|
11
|
+
const ACIA_1 = require("./IO/ACIA");
|
|
12
|
+
const Sound_1 = require("./IO/Sound");
|
|
13
|
+
const Storage_1 = require("./IO/Storage");
|
|
14
|
+
const Video_1 = require("./IO/Video");
|
|
15
|
+
const KeyboardMatrixAttachment_1 = require("./IO/Attachments/KeyboardMatrixAttachment");
|
|
16
|
+
const KeyboardEncoderAttachment_1 = require("./IO/Attachments/KeyboardEncoderAttachment");
|
|
17
|
+
const JoystickAttachment_1 = require("./IO/Attachments/JoystickAttachment");
|
|
18
|
+
const LCDAttachment_1 = require("./IO/Attachments/LCDAttachment");
|
|
19
|
+
const KeypadAttachment_1 = require("./IO/Attachments/KeypadAttachment");
|
|
20
|
+
const Empty_1 = require("./IO/Empty");
|
|
21
|
+
const Terminal_1 = require("./IO/Terminal");
|
|
32
22
|
class Machine {
|
|
33
23
|
//
|
|
34
24
|
// Initialization
|
|
35
25
|
//
|
|
36
|
-
constructor(target
|
|
26
|
+
constructor(target) {
|
|
37
27
|
this.ioCycleAccumulator = 0;
|
|
38
28
|
this.ioTickInterval = 128; // adjust (64/128/256)
|
|
39
|
-
this.isAlive = false;
|
|
40
29
|
this.isRunning = false;
|
|
41
30
|
this.frequency = 2000000; // 2 MHz
|
|
42
31
|
this.scale = 2;
|
|
43
32
|
this.frames = 0;
|
|
44
|
-
this.frameDelay = 0;
|
|
45
|
-
this.frameDelayCount = 0;
|
|
46
33
|
this.startTime = Date.now();
|
|
47
34
|
this.previousTime = performance.now();
|
|
48
35
|
//
|
|
49
36
|
// Methods
|
|
50
37
|
//
|
|
51
|
-
this.loadROM = (
|
|
52
|
-
|
|
53
|
-
this.rom.load(Array.from(new Uint8Array(
|
|
38
|
+
this.loadROM = (data) => {
|
|
39
|
+
if (data instanceof ArrayBuffer) {
|
|
40
|
+
this.rom.load(Array.from(new Uint8Array(data)));
|
|
54
41
|
}
|
|
55
|
-
|
|
56
|
-
|
|
42
|
+
else if (data instanceof Uint8Array) {
|
|
43
|
+
this.rom.load(Array.from(data));
|
|
57
44
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
try {
|
|
61
|
-
const data = Array.from(new Uint8Array(yield (0, promises_1.readFile)(path)));
|
|
62
|
-
const cart = new Cart_1.Cart();
|
|
63
|
-
cart.load(data);
|
|
64
|
-
this.cart = cart;
|
|
45
|
+
else {
|
|
46
|
+
this.rom.load(data);
|
|
65
47
|
}
|
|
66
|
-
|
|
67
|
-
|
|
48
|
+
};
|
|
49
|
+
this.loadCart = (data) => {
|
|
50
|
+
let dataArray;
|
|
51
|
+
if (data instanceof ArrayBuffer) {
|
|
52
|
+
dataArray = Array.from(new Uint8Array(data));
|
|
53
|
+
}
|
|
54
|
+
else if (data instanceof Uint8Array) {
|
|
55
|
+
dataArray = Array.from(data);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
dataArray = data;
|
|
68
59
|
}
|
|
69
|
-
|
|
60
|
+
const cart = new Cart_1.Cart();
|
|
61
|
+
cart.load(dataArray);
|
|
62
|
+
this.cart = cart;
|
|
63
|
+
};
|
|
70
64
|
this.target = target;
|
|
71
65
|
this.cpu = new CPU_1.CPU(this.read.bind(this), this.write.bind(this));
|
|
72
66
|
this.ram = new RAM_1.RAM();
|
|
73
67
|
this.rom = new ROM_1.ROM();
|
|
74
|
-
this.
|
|
75
|
-
|
|
76
|
-
this.
|
|
77
|
-
this.
|
|
78
|
-
|
|
79
|
-
this.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
this.joystickAttachmentA = new GPIOJoystickAttachment_1.GPIOJoystickAttachment(false, 100);
|
|
88
|
-
this.joystickAttachmentB = new GPIOJoystickAttachment_1.GPIOJoystickAttachment(false, 100);
|
|
68
|
+
this.io1 = new Empty_1.Empty();
|
|
69
|
+
this.io2 = new Empty_1.Empty();
|
|
70
|
+
this.io3 = new Empty_1.Empty();
|
|
71
|
+
this.io4 = new Empty_1.Empty();
|
|
72
|
+
this.io5 = new Empty_1.Empty();
|
|
73
|
+
this.io6 = new Empty_1.Empty();
|
|
74
|
+
this.io7 = new Empty_1.Empty();
|
|
75
|
+
this.io8 = new Empty_1.Empty();
|
|
76
|
+
this.configureTarget(target);
|
|
77
|
+
this.startTime = Date.now();
|
|
78
|
+
this.cpu.reset();
|
|
79
|
+
}
|
|
80
|
+
configureTarget(target) {
|
|
89
81
|
if (target === 'kim') {
|
|
90
|
-
|
|
91
|
-
this.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
82
|
+
const acia = new ACIA_1.ACIA();
|
|
83
|
+
this.io5 = acia;
|
|
84
|
+
// Connect ACIA IRQ/NMI to CPU
|
|
85
|
+
acia.raiseIRQ = () => this.cpu.irq();
|
|
86
|
+
acia.raiseNMI = () => this.cpu.nmi();
|
|
87
|
+
// Connect ACIA transmit callback
|
|
88
|
+
acia.transmit = (data) => {
|
|
89
|
+
if (this.transmit) {
|
|
90
|
+
this.transmit(data);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
this.io1 = new Empty_1.Empty();
|
|
94
|
+
this.io2 = new Empty_1.Empty();
|
|
95
|
+
this.io3 = new Empty_1.Empty();
|
|
96
|
+
this.io4 = new Empty_1.Empty();
|
|
97
|
+
this.io6 = new Empty_1.Empty();
|
|
98
|
+
this.io7 = new Empty_1.Empty();
|
|
99
|
+
const via = new VIA_1.VIA();
|
|
100
|
+
this.io8 = via;
|
|
101
|
+
// Connect VIA IRQ/NMI to CPU
|
|
102
|
+
via.raiseIRQ = () => this.cpu.irq();
|
|
103
|
+
via.raiseNMI = () => this.cpu.nmi();
|
|
101
104
|
// Create KIM GPIO Attachments
|
|
102
|
-
this.lcdAttachment = new
|
|
103
|
-
this.keypadAttachment = new
|
|
105
|
+
this.lcdAttachment = new LCDAttachment_1.LCDAttachment(16, 2, 10);
|
|
106
|
+
this.keypadAttachment = new KeypadAttachment_1.KeypadAttachment(true, 20);
|
|
104
107
|
// Attach LCD to Port A (control: RS/RW/E on bits 5-7) and Port B (data bus)
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
via.attachToPortA(this.lcdAttachment);
|
|
109
|
+
via.attachToPortB(this.lcdAttachment);
|
|
107
110
|
// Attach keypad to Port A (bits 0-4)
|
|
108
|
-
|
|
111
|
+
via.attachToPortA(this.keypadAttachment);
|
|
109
112
|
}
|
|
110
113
|
else if (target === 'dev') {
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
114
|
+
const acia = new ACIA_1.ACIA();
|
|
115
|
+
this.io5 = acia;
|
|
116
|
+
// Connect ACIA IRQ/NMI to CPU
|
|
117
|
+
acia.raiseIRQ = () => this.cpu.irq();
|
|
118
|
+
acia.raiseNMI = () => this.cpu.nmi();
|
|
119
|
+
// Connect ACIA transmit callback
|
|
120
|
+
acia.transmit = (data) => {
|
|
121
|
+
if (this.transmit) {
|
|
122
|
+
this.transmit(data);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
const rtc = new RTC_1.RTC();
|
|
126
|
+
const storage = new Storage_1.Storage();
|
|
127
|
+
const via = new VIA_1.VIA();
|
|
128
|
+
this.io1 = new RAMBank_1.RAMBank();
|
|
129
|
+
this.io2 = new RAMBank_1.RAMBank();
|
|
130
|
+
this.io3 = rtc;
|
|
131
|
+
this.io4 = storage;
|
|
132
|
+
this.io6 = via;
|
|
133
|
+
this.io7 = new Empty_1.Empty();
|
|
134
|
+
this.io8 = new Terminal_1.Terminal();
|
|
135
|
+
// Connect RTC IRQ/NMI to CPU
|
|
136
|
+
rtc.raiseIRQ = () => this.cpu.irq();
|
|
137
|
+
rtc.raiseNMI = () => this.cpu.nmi();
|
|
138
|
+
// Create standard GPIO attachments
|
|
139
|
+
this.keyboardMatrixAttachment = new KeyboardMatrixAttachment_1.KeyboardMatrixAttachment(10);
|
|
140
|
+
this.keyboardEncoderAttachment = new KeyboardEncoderAttachment_1.KeyboardEncoderAttachment(20);
|
|
141
|
+
this.joystickAttachmentA = new JoystickAttachment_1.JoystickAttachment(false, 100);
|
|
142
|
+
this.joystickAttachmentB = new JoystickAttachment_1.JoystickAttachment(false, 100);
|
|
124
143
|
// Attach peripherals to GPIO Card
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
144
|
+
via.attachToPortA(this.keyboardMatrixAttachment);
|
|
145
|
+
via.attachToPortB(this.keyboardMatrixAttachment);
|
|
146
|
+
via.attachToPortA(this.keyboardEncoderAttachment);
|
|
147
|
+
via.attachToPortB(this.keyboardEncoderAttachment);
|
|
148
|
+
via.attachToPortA(this.joystickAttachmentA);
|
|
149
|
+
via.attachToPortB(this.joystickAttachmentB);
|
|
131
150
|
}
|
|
132
|
-
else {
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
const
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
this.
|
|
140
|
-
this.
|
|
141
|
-
this.
|
|
142
|
-
this.
|
|
143
|
-
this.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
videoCard.raiseNMI = () => this.cpu.nmi();
|
|
152
|
-
// Connect SoundCard pushSamples callback
|
|
153
|
-
soundCard.pushSamples = (samples) => {
|
|
154
|
-
if (this.pushAudioSamples) {
|
|
155
|
-
this.pushAudioSamples(samples);
|
|
151
|
+
else if (target === 'vcs') {
|
|
152
|
+
this.io5 = new Empty_1.Empty();
|
|
153
|
+
const via = new VIA_1.VIA();
|
|
154
|
+
const sound = new Sound_1.Sound();
|
|
155
|
+
const video = new Video_1.Video();
|
|
156
|
+
this.io1 = new Empty_1.Empty();
|
|
157
|
+
this.io2 = new Empty_1.Empty();
|
|
158
|
+
this.io3 = new Empty_1.Empty();
|
|
159
|
+
this.io4 = new Empty_1.Empty();
|
|
160
|
+
this.io6 = via;
|
|
161
|
+
this.io7 = sound;
|
|
162
|
+
this.io8 = video;
|
|
163
|
+
// Connect Video IRQ/NMI to CPU
|
|
164
|
+
video.raiseIRQ = () => this.cpu.irq();
|
|
165
|
+
video.raiseNMI = () => this.cpu.nmi();
|
|
166
|
+
// Connect Sound pushSamples callback
|
|
167
|
+
sound.pushSamples = (samples) => {
|
|
168
|
+
if (this.play) {
|
|
169
|
+
this.play(samples);
|
|
156
170
|
}
|
|
157
171
|
};
|
|
172
|
+
// Create standard GPIO attachments
|
|
173
|
+
this.keyboardMatrixAttachment = new KeyboardMatrixAttachment_1.KeyboardMatrixAttachment(10);
|
|
174
|
+
this.keyboardEncoderAttachment = new KeyboardEncoderAttachment_1.KeyboardEncoderAttachment(20);
|
|
175
|
+
this.joystickAttachmentA = new JoystickAttachment_1.JoystickAttachment(false, 100);
|
|
176
|
+
this.joystickAttachmentB = new JoystickAttachment_1.JoystickAttachment(false, 100);
|
|
158
177
|
// Attach peripherals to GPIO Card
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
178
|
+
via.attachToPortA(this.keyboardMatrixAttachment);
|
|
179
|
+
via.attachToPortB(this.keyboardMatrixAttachment);
|
|
180
|
+
via.attachToPortA(this.keyboardEncoderAttachment);
|
|
181
|
+
via.attachToPortB(this.keyboardEncoderAttachment);
|
|
182
|
+
via.attachToPortA(this.joystickAttachmentA);
|
|
183
|
+
via.attachToPortB(this.joystickAttachmentB);
|
|
184
|
+
}
|
|
185
|
+
else if (target === 'cob') {
|
|
186
|
+
const acia = new ACIA_1.ACIA();
|
|
187
|
+
this.io5 = acia;
|
|
188
|
+
// Connect ACIA IRQ/NMI to CPU
|
|
189
|
+
acia.raiseIRQ = () => this.cpu.irq();
|
|
190
|
+
acia.raiseNMI = () => this.cpu.nmi();
|
|
191
|
+
// Connect ACIA transmit callback
|
|
192
|
+
acia.transmit = (data) => {
|
|
193
|
+
if (this.transmit) {
|
|
194
|
+
this.transmit(data);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
const rtc = new RTC_1.RTC();
|
|
198
|
+
const storage = new Storage_1.Storage();
|
|
199
|
+
const gpio = new VIA_1.VIA();
|
|
200
|
+
const sound = new Sound_1.Sound();
|
|
201
|
+
const video = new Video_1.Video();
|
|
202
|
+
this.io1 = new RAMBank_1.RAMBank();
|
|
203
|
+
this.io2 = new RAMBank_1.RAMBank();
|
|
204
|
+
this.io3 = rtc;
|
|
205
|
+
this.io4 = storage;
|
|
206
|
+
this.io6 = gpio;
|
|
207
|
+
this.io7 = sound;
|
|
208
|
+
this.io8 = video;
|
|
209
|
+
// Connect RTC IRQ/NMI to CPU
|
|
210
|
+
rtc.raiseIRQ = () => this.cpu.irq();
|
|
211
|
+
rtc.raiseNMI = () => this.cpu.nmi();
|
|
212
|
+
// Connect Video IRQ/NMI to CPU
|
|
213
|
+
video.raiseIRQ = () => this.cpu.irq();
|
|
214
|
+
video.raiseNMI = () => this.cpu.nmi();
|
|
215
|
+
// Connect Sound pushSamples callback
|
|
216
|
+
sound.pushSamples = (samples) => {
|
|
217
|
+
if (this.play) {
|
|
218
|
+
this.play(samples);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
// Create standard GPIO attachments
|
|
222
|
+
this.keyboardMatrixAttachment = new KeyboardMatrixAttachment_1.KeyboardMatrixAttachment(10);
|
|
223
|
+
this.keyboardEncoderAttachment = new KeyboardEncoderAttachment_1.KeyboardEncoderAttachment(20);
|
|
224
|
+
this.joystickAttachmentA = new JoystickAttachment_1.JoystickAttachment(false, 100);
|
|
225
|
+
this.joystickAttachmentB = new JoystickAttachment_1.JoystickAttachment(false, 100);
|
|
226
|
+
// Attach peripherals to GPIO Card
|
|
227
|
+
gpio.attachToPortA(this.keyboardMatrixAttachment);
|
|
228
|
+
gpio.attachToPortB(this.keyboardMatrixAttachment);
|
|
229
|
+
gpio.attachToPortA(this.keyboardEncoderAttachment);
|
|
230
|
+
gpio.attachToPortB(this.keyboardEncoderAttachment);
|
|
231
|
+
gpio.attachToPortA(this.joystickAttachmentA);
|
|
232
|
+
gpio.attachToPortB(this.joystickAttachmentB);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
this.io1 = new Empty_1.Empty();
|
|
236
|
+
this.io2 = new Empty_1.Empty();
|
|
237
|
+
this.io3 = new Empty_1.Empty();
|
|
238
|
+
this.io4 = new Empty_1.Empty();
|
|
239
|
+
this.io5 = new Empty_1.Empty();
|
|
240
|
+
this.io6 = new Empty_1.Empty();
|
|
241
|
+
this.io7 = new Empty_1.Empty();
|
|
242
|
+
this.io8 = new Empty_1.Empty();
|
|
165
243
|
}
|
|
166
|
-
this.cpu.reset();
|
|
167
|
-
}
|
|
168
|
-
start() {
|
|
169
|
-
this.cpu.reset();
|
|
170
|
-
this.startTime = Date.now();
|
|
171
|
-
this.isRunning = true;
|
|
172
|
-
this.isAlive = true;
|
|
173
|
-
this.loop();
|
|
174
|
-
}
|
|
175
|
-
end() {
|
|
176
|
-
this.isRunning = false;
|
|
177
|
-
this.isAlive = false;
|
|
178
244
|
}
|
|
179
245
|
run() {
|
|
180
246
|
this.isRunning = true;
|
|
247
|
+
this.loop();
|
|
181
248
|
}
|
|
182
249
|
stop() {
|
|
183
250
|
this.isRunning = false;
|
|
251
|
+
if (this.loopHandle) {
|
|
252
|
+
if (typeof clearImmediate !== 'undefined') {
|
|
253
|
+
clearImmediate(this.loopHandle);
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
clearTimeout(this.loopHandle);
|
|
257
|
+
}
|
|
258
|
+
this.loopHandle = undefined;
|
|
259
|
+
}
|
|
184
260
|
}
|
|
185
261
|
step() {
|
|
186
262
|
// Step through one complete instruction
|
|
187
263
|
const cyclesExecuted = this.cpu.step();
|
|
188
264
|
// Tick IO cards for each cycle of the instruction
|
|
189
265
|
for (let i = 0; i < cyclesExecuted; i++) {
|
|
190
|
-
//
|
|
266
|
+
// ACIA must be cycle-accurate
|
|
191
267
|
this.io5.tick(this.frequency);
|
|
192
268
|
this.ioCycleAccumulator++;
|
|
193
269
|
if (this.ioCycleAccumulator >= this.ioTickInterval) {
|
|
194
|
-
// Skip ticking
|
|
270
|
+
// Skip ticking RAMBank IO1 and IO2 since they have no timing behavior
|
|
195
271
|
this.io3.tick(this.frequency);
|
|
196
272
|
this.io4.tick(this.frequency);
|
|
197
273
|
this.io6.tick(this.frequency);
|
|
@@ -201,15 +277,27 @@ class Machine {
|
|
|
201
277
|
}
|
|
202
278
|
}
|
|
203
279
|
}
|
|
280
|
+
reset(coldStart) {
|
|
281
|
+
this.cpu.reset();
|
|
282
|
+
this.ram.reset(coldStart);
|
|
283
|
+
this.io1.reset(coldStart);
|
|
284
|
+
this.io2.reset(coldStart);
|
|
285
|
+
this.io3.reset(coldStart);
|
|
286
|
+
this.io4.reset(coldStart);
|
|
287
|
+
this.io5.reset(coldStart);
|
|
288
|
+
this.io6.reset(coldStart);
|
|
289
|
+
this.io7.reset(coldStart);
|
|
290
|
+
this.io8.reset(coldStart);
|
|
291
|
+
}
|
|
204
292
|
tick() {
|
|
205
293
|
// Execute one CPU clock cycle
|
|
206
294
|
this.cpu.tick();
|
|
207
|
-
//
|
|
295
|
+
// ACIA must be cycle-accurate
|
|
208
296
|
this.io5.tick(this.frequency);
|
|
209
297
|
// Tick other IO cards at intervals
|
|
210
298
|
this.ioCycleAccumulator++;
|
|
211
299
|
if (this.ioCycleAccumulator >= this.ioTickInterval) {
|
|
212
|
-
// Skip ticking
|
|
300
|
+
// Skip ticking RAMBank IO1 and IO2 since they have no timing behavior
|
|
213
301
|
this.io3.tick(this.frequency);
|
|
214
302
|
this.io4.tick(this.frequency);
|
|
215
303
|
this.io6.tick(this.frequency);
|
|
@@ -219,22 +307,25 @@ class Machine {
|
|
|
219
307
|
}
|
|
220
308
|
}
|
|
221
309
|
onReceive(data) {
|
|
222
|
-
this.
|
|
310
|
+
if (this.target !== 'vcs') {
|
|
311
|
+
this.io5.onData(data); // Pass data to Serial card
|
|
312
|
+
}
|
|
223
313
|
}
|
|
224
314
|
onKeyDown(scancode) {
|
|
225
|
-
var _a;
|
|
315
|
+
var _a, _b, _c;
|
|
226
316
|
if (this.target === 'kim') {
|
|
227
317
|
(_a = this.keypadAttachment) === null || _a === void 0 ? void 0 : _a.updateKey(scancode, true);
|
|
228
318
|
}
|
|
229
319
|
else {
|
|
230
|
-
this.keyboardMatrixAttachment.updateKey(scancode, true);
|
|
231
|
-
this.keyboardEncoderAttachment.updateKey(scancode, true);
|
|
320
|
+
(_b = this.keyboardMatrixAttachment) === null || _b === void 0 ? void 0 : _b.updateKey(scancode, true);
|
|
321
|
+
(_c = this.keyboardEncoderAttachment) === null || _c === void 0 ? void 0 : _c.updateKey(scancode, true);
|
|
232
322
|
}
|
|
233
323
|
}
|
|
234
324
|
onKeyUp(scancode) {
|
|
325
|
+
var _a, _b;
|
|
235
326
|
if (this.target !== 'kim') {
|
|
236
|
-
this.keyboardMatrixAttachment.updateKey(scancode, false);
|
|
237
|
-
this.keyboardEncoderAttachment.updateKey(scancode, false);
|
|
327
|
+
(_a = this.keyboardMatrixAttachment) === null || _a === void 0 ? void 0 : _a.updateKey(scancode, false);
|
|
328
|
+
(_b = this.keyboardEncoderAttachment) === null || _b === void 0 ? void 0 : _b.updateKey(scancode, false);
|
|
238
329
|
}
|
|
239
330
|
}
|
|
240
331
|
onJoystickA(buttons) {
|
|
@@ -250,9 +341,6 @@ class Machine {
|
|
|
250
341
|
//
|
|
251
342
|
loop() {
|
|
252
343
|
var _a;
|
|
253
|
-
if (!this.isAlive) {
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
344
|
const now = performance.now();
|
|
257
345
|
const elapsedMs = now - this.previousTime;
|
|
258
346
|
this.previousTime = now;
|
|
@@ -267,11 +355,11 @@ class Machine {
|
|
|
267
355
|
if (ticksToRun > 0) {
|
|
268
356
|
for (let i = 0; i < ticksToRun; i++) {
|
|
269
357
|
this.cpu.tick();
|
|
270
|
-
//
|
|
358
|
+
// ACIA must be cycle-accurate
|
|
271
359
|
this.io5.tick(this.frequency);
|
|
272
360
|
this.ioCycleAccumulator++;
|
|
273
361
|
if (this.ioCycleAccumulator >= this.ioTickInterval) {
|
|
274
|
-
// Skip ticking
|
|
362
|
+
// Skip ticking RAMBank IO1 and IO2 since they have no timing behavior
|
|
275
363
|
this.io3.tick(this.frequency);
|
|
276
364
|
this.io4.tick(this.frequency);
|
|
277
365
|
this.io6.tick(this.frequency);
|
|
@@ -289,30 +377,25 @@ class Machine {
|
|
|
289
377
|
this.frames += 1;
|
|
290
378
|
}
|
|
291
379
|
else if (this.render && (this.target === 'cob' || this.target === 'vcs')) {
|
|
292
|
-
const
|
|
293
|
-
if (
|
|
294
|
-
|
|
380
|
+
const Video = this.io8;
|
|
381
|
+
if (Video.frameReady) {
|
|
382
|
+
Video.frameReady = false;
|
|
295
383
|
this.render();
|
|
296
384
|
this.frames += 1;
|
|
297
385
|
}
|
|
298
386
|
}
|
|
299
|
-
|
|
387
|
+
if (this.isRunning) {
|
|
388
|
+
if (typeof setImmediate !== 'undefined') {
|
|
389
|
+
this.loopHandle = setImmediate(() => this.loop());
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
this.loopHandle = setTimeout(() => this.loop(), 0);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
300
395
|
}
|
|
301
396
|
//
|
|
302
397
|
// Bus Operations
|
|
303
398
|
//
|
|
304
|
-
reset(coldStart) {
|
|
305
|
-
this.cpu.reset();
|
|
306
|
-
this.ram.reset(coldStart);
|
|
307
|
-
this.io1.reset(coldStart);
|
|
308
|
-
this.io2.reset(coldStart);
|
|
309
|
-
this.io3.reset(coldStart);
|
|
310
|
-
this.io4.reset(coldStart);
|
|
311
|
-
this.io5.reset(coldStart);
|
|
312
|
-
this.io6.reset(coldStart);
|
|
313
|
-
this.io7.reset(coldStart);
|
|
314
|
-
this.io8.reset(coldStart);
|
|
315
|
-
}
|
|
316
399
|
read(address) {
|
|
317
400
|
switch (true) {
|
|
318
401
|
case (this.cart && address >= Cart_1.Cart.CODE && address <= Cart_1.Cart.END):
|