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
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { IO } from '../IO';
|
|
2
|
+
/**
|
|
3
|
+
* Storage - Emulates a Compact Flash card in 8-bit IDE mode
|
|
4
|
+
*
|
|
5
|
+
* Emulates a 128MB CF card with ATA-style register interface.
|
|
6
|
+
* Uses LBA (Logical Block Addressing) for sector access.
|
|
7
|
+
*
|
|
8
|
+
* Register Map (address & 0x07):
|
|
9
|
+
* $00: Data Register (read/write)
|
|
10
|
+
* $01: Error Register (read) / Feature Register (write)
|
|
11
|
+
* $02: Sector Count Register (read/write)
|
|
12
|
+
* $03: LBA0 Register (read/write) - bits 0-7 of LBA
|
|
13
|
+
* $04: LBA1 Register (read/write) - bits 8-15 of LBA
|
|
14
|
+
* $05: LBA2 Register (read/write) - bits 16-23 of LBA
|
|
15
|
+
* $06: LBA3 Register (read/write) - bits 24-27 of LBA + mode bits
|
|
16
|
+
* $07: Status Register (read) / Command Register (write)
|
|
17
|
+
*
|
|
18
|
+
* Supported Commands:
|
|
19
|
+
* 0x20, 0x21: Read Sector(s)
|
|
20
|
+
* 0x30, 0x31: Write Sector(s)
|
|
21
|
+
* 0xC0: Erase Sector
|
|
22
|
+
* 0xEC: Identify Drive
|
|
23
|
+
* 0xEF: Set Features (accepted but not implemented)
|
|
24
|
+
*/
|
|
25
|
+
export declare class Storage implements IO {
|
|
26
|
+
private static readonly STORAGE_SIZE;
|
|
27
|
+
private static readonly SECTOR_SIZE;
|
|
28
|
+
private static readonly SECTOR_COUNT;
|
|
29
|
+
private static readonly STATUS_ERR;
|
|
30
|
+
private static readonly STATUS_DRQ;
|
|
31
|
+
private static readonly STATUS_RDY;
|
|
32
|
+
private static readonly ERR_AMNF;
|
|
33
|
+
private static readonly ERR_ABRT;
|
|
34
|
+
private static readonly ERR_IDNF;
|
|
35
|
+
private storage;
|
|
36
|
+
private identity;
|
|
37
|
+
private buffer;
|
|
38
|
+
private bufferIndex;
|
|
39
|
+
private commandDataSize;
|
|
40
|
+
private sectorOffset;
|
|
41
|
+
private error;
|
|
42
|
+
private feature;
|
|
43
|
+
private sectorCount;
|
|
44
|
+
private lba0;
|
|
45
|
+
private lba1;
|
|
46
|
+
private lba2;
|
|
47
|
+
private lba3;
|
|
48
|
+
private status;
|
|
49
|
+
private command;
|
|
50
|
+
private isIdentifying;
|
|
51
|
+
private isTransferring;
|
|
52
|
+
raiseIRQ: () => void;
|
|
53
|
+
raiseNMI: () => void;
|
|
54
|
+
constructor();
|
|
55
|
+
read(address: number): number;
|
|
56
|
+
write(address: number, data: number): void;
|
|
57
|
+
tick(frequency: number): void;
|
|
58
|
+
reset(coldStart: boolean): void;
|
|
59
|
+
private executeCommand;
|
|
60
|
+
private readBuffer;
|
|
61
|
+
private writeBuffer;
|
|
62
|
+
private sectorIndex;
|
|
63
|
+
private sectorValid;
|
|
64
|
+
private generateIdentity;
|
|
65
|
+
/**
|
|
66
|
+
* Load storage data from a Uint8Array, ArrayBuffer, or number array
|
|
67
|
+
* If data is not provided or wrong size, storage remains empty
|
|
68
|
+
*/
|
|
69
|
+
loadData(data: Uint8Array | ArrayBuffer | number[] | null): void;
|
|
70
|
+
/**
|
|
71
|
+
* Get storage data as Uint8Array for saving
|
|
72
|
+
*/
|
|
73
|
+
getData(): Uint8Array;
|
|
74
|
+
}
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Storage = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Storage - Emulates a Compact Flash card in 8-bit IDE mode
|
|
6
|
+
*
|
|
7
|
+
* Emulates a 128MB CF card with ATA-style register interface.
|
|
8
|
+
* Uses LBA (Logical Block Addressing) for sector access.
|
|
9
|
+
*
|
|
10
|
+
* Register Map (address & 0x07):
|
|
11
|
+
* $00: Data Register (read/write)
|
|
12
|
+
* $01: Error Register (read) / Feature Register (write)
|
|
13
|
+
* $02: Sector Count Register (read/write)
|
|
14
|
+
* $03: LBA0 Register (read/write) - bits 0-7 of LBA
|
|
15
|
+
* $04: LBA1 Register (read/write) - bits 8-15 of LBA
|
|
16
|
+
* $05: LBA2 Register (read/write) - bits 16-23 of LBA
|
|
17
|
+
* $06: LBA3 Register (read/write) - bits 24-27 of LBA + mode bits
|
|
18
|
+
* $07: Status Register (read) / Command Register (write)
|
|
19
|
+
*
|
|
20
|
+
* Supported Commands:
|
|
21
|
+
* 0x20, 0x21: Read Sector(s)
|
|
22
|
+
* 0x30, 0x31: Write Sector(s)
|
|
23
|
+
* 0xC0: Erase Sector
|
|
24
|
+
* 0xEC: Identify Drive
|
|
25
|
+
* 0xEF: Set Features (accepted but not implemented)
|
|
26
|
+
*/
|
|
27
|
+
class Storage {
|
|
28
|
+
constructor() {
|
|
29
|
+
// Data buffer (512 bytes)
|
|
30
|
+
this.buffer = new Uint8Array(Storage.SECTOR_SIZE);
|
|
31
|
+
this.bufferIndex = 0;
|
|
32
|
+
this.commandDataSize = Storage.SECTOR_SIZE;
|
|
33
|
+
this.sectorOffset = 0;
|
|
34
|
+
// Registers
|
|
35
|
+
this.error = 0x00;
|
|
36
|
+
this.feature = 0x00;
|
|
37
|
+
this.sectorCount = 0x00;
|
|
38
|
+
this.lba0 = 0x00;
|
|
39
|
+
this.lba1 = 0x00;
|
|
40
|
+
this.lba2 = 0x00;
|
|
41
|
+
this.lba3 = 0xE0;
|
|
42
|
+
this.status = 0x00;
|
|
43
|
+
this.command = 0x00;
|
|
44
|
+
// State flags
|
|
45
|
+
this.isIdentifying = false;
|
|
46
|
+
this.isTransferring = false;
|
|
47
|
+
this.raiseIRQ = () => { };
|
|
48
|
+
this.raiseNMI = () => { };
|
|
49
|
+
// Initialize storage and identity buffers
|
|
50
|
+
this.storage = new Uint8Array(Storage.STORAGE_SIZE);
|
|
51
|
+
this.identity = new Uint8Array(Storage.SECTOR_SIZE);
|
|
52
|
+
this.generateIdentity();
|
|
53
|
+
this.reset(true);
|
|
54
|
+
}
|
|
55
|
+
read(address) {
|
|
56
|
+
switch (address & 0x0007) {
|
|
57
|
+
case 0x00: // Data Register
|
|
58
|
+
return this.readBuffer();
|
|
59
|
+
case 0x01: // Error Register
|
|
60
|
+
return this.error;
|
|
61
|
+
case 0x02: // Sector Count Register
|
|
62
|
+
return this.sectorCount;
|
|
63
|
+
case 0x03: // LBA0 Register
|
|
64
|
+
return this.lba0;
|
|
65
|
+
case 0x04: // LBA1 Register
|
|
66
|
+
return this.lba1;
|
|
67
|
+
case 0x05: // LBA2 Register
|
|
68
|
+
return this.lba2;
|
|
69
|
+
case 0x06: // LBA3 Register
|
|
70
|
+
return this.lba3;
|
|
71
|
+
case 0x07: // Status Register
|
|
72
|
+
return this.status;
|
|
73
|
+
default:
|
|
74
|
+
return 0x00;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
write(address, data) {
|
|
78
|
+
switch (address & 0x0007) {
|
|
79
|
+
case 0x00: // Data Register
|
|
80
|
+
this.writeBuffer(data);
|
|
81
|
+
break;
|
|
82
|
+
case 0x01: // Feature Register
|
|
83
|
+
this.feature = data;
|
|
84
|
+
break;
|
|
85
|
+
case 0x02: // Sector Count Register
|
|
86
|
+
this.sectorCount = data;
|
|
87
|
+
break;
|
|
88
|
+
case 0x03: // LBA0 Register
|
|
89
|
+
this.lba0 = data;
|
|
90
|
+
break;
|
|
91
|
+
case 0x04: // LBA1 Register
|
|
92
|
+
this.lba1 = data;
|
|
93
|
+
break;
|
|
94
|
+
case 0x05: // LBA2 Register
|
|
95
|
+
this.lba2 = data;
|
|
96
|
+
break;
|
|
97
|
+
case 0x06: // LBA3 Register
|
|
98
|
+
this.lba3 = (data & 0x0F) | 0xE0;
|
|
99
|
+
break;
|
|
100
|
+
case 0x07: // Command Register
|
|
101
|
+
this.command = data;
|
|
102
|
+
this.executeCommand();
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
tick(frequency) {
|
|
107
|
+
// No timing behavior needed for this implementation
|
|
108
|
+
}
|
|
109
|
+
reset(coldStart) {
|
|
110
|
+
this.bufferIndex = 0x0000;
|
|
111
|
+
this.commandDataSize = Storage.SECTOR_SIZE;
|
|
112
|
+
this.sectorOffset = 0;
|
|
113
|
+
this.error = 0x00;
|
|
114
|
+
this.feature = 0x00;
|
|
115
|
+
this.sectorCount = 0x00;
|
|
116
|
+
this.lba0 = 0x00;
|
|
117
|
+
this.lba1 = 0x00;
|
|
118
|
+
this.lba2 = 0x00;
|
|
119
|
+
this.lba3 = 0xE0;
|
|
120
|
+
this.status = 0x00 | Storage.STATUS_RDY;
|
|
121
|
+
this.command = 0x00;
|
|
122
|
+
this.isIdentifying = false;
|
|
123
|
+
this.isTransferring = false;
|
|
124
|
+
this.buffer.fill(0x00);
|
|
125
|
+
}
|
|
126
|
+
//
|
|
127
|
+
// Private methods
|
|
128
|
+
//
|
|
129
|
+
executeCommand() {
|
|
130
|
+
// New command so clear errors and flags
|
|
131
|
+
this.status &= ~Storage.STATUS_ERR;
|
|
132
|
+
this.status &= ~Storage.STATUS_DRQ;
|
|
133
|
+
this.error = 0x00;
|
|
134
|
+
this.commandDataSize = Storage.SECTOR_SIZE * this.sectorCount;
|
|
135
|
+
this.bufferIndex = 0;
|
|
136
|
+
this.sectorOffset = 0;
|
|
137
|
+
// Check if already executing a command
|
|
138
|
+
if (this.isTransferring || this.isIdentifying) {
|
|
139
|
+
this.status |= Storage.STATUS_ERR;
|
|
140
|
+
this.error |= Storage.ERR_ABRT;
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
switch (this.command) {
|
|
144
|
+
case 0xC0: { // Erase sector
|
|
145
|
+
if (!this.sectorValid()) {
|
|
146
|
+
this.status |= Storage.STATUS_ERR;
|
|
147
|
+
this.error |= Storage.ERR_ABRT | Storage.ERR_IDNF;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const offset = this.sectorIndex() * Storage.SECTOR_SIZE;
|
|
151
|
+
this.storage.fill(0x00, offset, offset + Storage.SECTOR_SIZE);
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case 0xEC: { // Identify drive
|
|
156
|
+
this.buffer.set(this.identity.subarray(0, Storage.SECTOR_SIZE));
|
|
157
|
+
this.commandDataSize = Storage.SECTOR_SIZE;
|
|
158
|
+
this.status |= Storage.STATUS_DRQ;
|
|
159
|
+
this.isIdentifying = true;
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
case 0x20: // Read sector
|
|
163
|
+
case 0x21:
|
|
164
|
+
if (!this.sectorValid()) {
|
|
165
|
+
this.status |= Storage.STATUS_ERR;
|
|
166
|
+
this.error |= Storage.ERR_ABRT | Storage.ERR_IDNF;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
// Load first sector into buffer
|
|
170
|
+
const offset = this.sectorIndex() * Storage.SECTOR_SIZE;
|
|
171
|
+
this.buffer.set(this.storage.subarray(offset, offset + Storage.SECTOR_SIZE));
|
|
172
|
+
this.status |= Storage.STATUS_DRQ;
|
|
173
|
+
this.isTransferring = true;
|
|
174
|
+
}
|
|
175
|
+
break;
|
|
176
|
+
case 0xEF: // Set features
|
|
177
|
+
// We don't support setting features but accept them without error
|
|
178
|
+
break;
|
|
179
|
+
case 0x30: // Write sector
|
|
180
|
+
case 0x31:
|
|
181
|
+
if (!this.sectorValid()) {
|
|
182
|
+
this.status |= Storage.STATUS_ERR;
|
|
183
|
+
this.error |= Storage.ERR_ABRT | Storage.ERR_IDNF;
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
this.status |= Storage.STATUS_DRQ;
|
|
187
|
+
this.isTransferring = true;
|
|
188
|
+
}
|
|
189
|
+
break;
|
|
190
|
+
default:
|
|
191
|
+
// Unsupported command
|
|
192
|
+
this.status |= Storage.STATUS_ERR;
|
|
193
|
+
this.error |= Storage.ERR_ABRT;
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
readBuffer() {
|
|
198
|
+
if (this.isIdentifying) {
|
|
199
|
+
const data = this.buffer[this.bufferIndex];
|
|
200
|
+
if (this.bufferIndex < this.commandDataSize - 1) {
|
|
201
|
+
this.bufferIndex++;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
this.bufferIndex = 0;
|
|
205
|
+
this.isIdentifying = false;
|
|
206
|
+
this.status &= ~Storage.STATUS_DRQ;
|
|
207
|
+
}
|
|
208
|
+
return data;
|
|
209
|
+
}
|
|
210
|
+
else if (this.isTransferring) {
|
|
211
|
+
const data = this.buffer[this.bufferIndex];
|
|
212
|
+
if (this.bufferIndex < Storage.SECTOR_SIZE - 1) {
|
|
213
|
+
this.bufferIndex++;
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
this.bufferIndex = 0;
|
|
217
|
+
this.sectorOffset++;
|
|
218
|
+
if (this.sectorOffset < this.sectorCount) {
|
|
219
|
+
// Load the next sector
|
|
220
|
+
const offset = (this.sectorIndex() + this.sectorOffset) * Storage.SECTOR_SIZE;
|
|
221
|
+
this.buffer.set(this.storage.subarray(offset, offset + Storage.SECTOR_SIZE));
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
this.isTransferring = false;
|
|
225
|
+
this.status &= ~Storage.STATUS_DRQ;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return data;
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
return 0x00;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
writeBuffer(value) {
|
|
235
|
+
this.buffer[this.bufferIndex] = value;
|
|
236
|
+
if (this.bufferIndex < Storage.SECTOR_SIZE - 1) {
|
|
237
|
+
this.bufferIndex++;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
this.bufferIndex = 0;
|
|
241
|
+
// Write the current sector to storage
|
|
242
|
+
const offset = (this.sectorIndex() + this.sectorOffset) * Storage.SECTOR_SIZE;
|
|
243
|
+
this.storage.set(this.buffer.subarray(0, Storage.SECTOR_SIZE), offset);
|
|
244
|
+
this.sectorOffset++;
|
|
245
|
+
// Check if all sectors have been written
|
|
246
|
+
if (this.sectorOffset >= this.sectorCount) {
|
|
247
|
+
this.isTransferring = false;
|
|
248
|
+
this.status &= ~Storage.STATUS_DRQ;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
sectorIndex() {
|
|
253
|
+
return ((this.lba3 & 0x0F) << 24) | (this.lba2 << 16) | (this.lba1 << 8) | this.lba0;
|
|
254
|
+
}
|
|
255
|
+
sectorValid() {
|
|
256
|
+
return this.sectorIndex() < Storage.SECTOR_COUNT;
|
|
257
|
+
}
|
|
258
|
+
generateIdentity() {
|
|
259
|
+
// Generate emulated 128MB CF card identity
|
|
260
|
+
// Based on real Promaster 128MB CF card data
|
|
261
|
+
// Fill with zeros first
|
|
262
|
+
this.identity.fill(0x00);
|
|
263
|
+
// Word 0: General configuration
|
|
264
|
+
this.identity[0] = 0x84;
|
|
265
|
+
this.identity[1] = 0x8A; // Removable Disk
|
|
266
|
+
// Word 1: Number of cylinders
|
|
267
|
+
this.identity[2] = 0x00;
|
|
268
|
+
this.identity[3] = 0x04;
|
|
269
|
+
// Word 2: Reserved
|
|
270
|
+
this.identity[4] = 0x00;
|
|
271
|
+
this.identity[5] = 0x00;
|
|
272
|
+
// Word 3: Number of heads
|
|
273
|
+
this.identity[6] = 0x08;
|
|
274
|
+
this.identity[7] = 0x00;
|
|
275
|
+
// Word 4: Unformatted bytes per track
|
|
276
|
+
this.identity[8] = 0x00;
|
|
277
|
+
this.identity[9] = 0x40;
|
|
278
|
+
// Word 5: Unformatted bytes per sector
|
|
279
|
+
this.identity[10] = 0x00;
|
|
280
|
+
this.identity[11] = 0x02;
|
|
281
|
+
// Word 6: Sectors per track
|
|
282
|
+
this.identity[12] = 0x20;
|
|
283
|
+
this.identity[13] = 0x00;
|
|
284
|
+
// Words 7-9: Reserved
|
|
285
|
+
this.identity[14] = 0x04;
|
|
286
|
+
this.identity[15] = 0x00;
|
|
287
|
+
this.identity[16] = 0x00;
|
|
288
|
+
this.identity[17] = 0x00;
|
|
289
|
+
this.identity[18] = 0x00;
|
|
290
|
+
this.identity[19] = 0x00;
|
|
291
|
+
// Words 10-19: Serial number (20 ASCII characters)
|
|
292
|
+
const serial = 'ACWD6502EMUCF1010101';
|
|
293
|
+
for (let i = 0; i < serial.length; i++) {
|
|
294
|
+
this.identity[20 + i] = serial.charCodeAt(i);
|
|
295
|
+
}
|
|
296
|
+
// Word 20: Buffer type
|
|
297
|
+
this.identity[40] = 0x01;
|
|
298
|
+
this.identity[41] = 0x00;
|
|
299
|
+
// Word 21: Buffer size in 512 byte increments
|
|
300
|
+
this.identity[42] = 0x04;
|
|
301
|
+
this.identity[43] = 0x00;
|
|
302
|
+
// Word 22: ECC bytes
|
|
303
|
+
this.identity[44] = 0x04;
|
|
304
|
+
this.identity[45] = 0x00;
|
|
305
|
+
// Words 23-26: Firmware revision (8 ASCII characters)
|
|
306
|
+
const firmware = '1.0 ';
|
|
307
|
+
for (let i = 0; i < firmware.length; i++) {
|
|
308
|
+
this.identity[46 + i] = firmware.charCodeAt(i);
|
|
309
|
+
}
|
|
310
|
+
// Words 27-46: Model number (40 ASCII characters)
|
|
311
|
+
const model = 'ACWD6502EMUCF ';
|
|
312
|
+
for (let i = 0; i < model.length; i++) {
|
|
313
|
+
this.identity[54 + i] = model.charCodeAt(i);
|
|
314
|
+
}
|
|
315
|
+
// Word 47: Multiple sector setting
|
|
316
|
+
this.identity[94] = 0x01;
|
|
317
|
+
this.identity[95] = 0x00;
|
|
318
|
+
// Word 48: Double word not supported
|
|
319
|
+
this.identity[96] = 0x00;
|
|
320
|
+
this.identity[97] = 0x00;
|
|
321
|
+
// Word 49: Capabilities (LBA supported)
|
|
322
|
+
this.identity[98] = 0x00;
|
|
323
|
+
this.identity[99] = 0x02;
|
|
324
|
+
// Word 50: Reserved
|
|
325
|
+
this.identity[100] = 0x00;
|
|
326
|
+
this.identity[101] = 0x00;
|
|
327
|
+
// Word 51: PIO data transfer cycle timing
|
|
328
|
+
this.identity[102] = 0x00;
|
|
329
|
+
this.identity[103] = 0x02;
|
|
330
|
+
// Word 52: DMA transfer cycle timing
|
|
331
|
+
this.identity[104] = 0x00;
|
|
332
|
+
this.identity[105] = 0x00;
|
|
333
|
+
// Word 53: Field validity
|
|
334
|
+
this.identity[106] = 0x01;
|
|
335
|
+
this.identity[107] = 0x00;
|
|
336
|
+
// Word 54: Current number of cylinders
|
|
337
|
+
this.identity[108] = 0x00;
|
|
338
|
+
this.identity[109] = 0x04;
|
|
339
|
+
// Word 55: Current number of heads
|
|
340
|
+
this.identity[110] = 0x08;
|
|
341
|
+
this.identity[111] = 0x00;
|
|
342
|
+
// Word 56: Current sectors per track
|
|
343
|
+
this.identity[112] = 0x20;
|
|
344
|
+
this.identity[113] = 0x00;
|
|
345
|
+
// Words 57-58: Current capacity in sectors
|
|
346
|
+
this.identity[114] = 0x00;
|
|
347
|
+
this.identity[115] = 0x00;
|
|
348
|
+
this.identity[116] = 0x04;
|
|
349
|
+
this.identity[117] = 0x00;
|
|
350
|
+
// Word 59: Multiple sector setting
|
|
351
|
+
this.identity[118] = 0x01;
|
|
352
|
+
this.identity[119] = 0x01;
|
|
353
|
+
// Words 60-61: Total number of sectors in LBA mode
|
|
354
|
+
this.identity[120] = 0x00;
|
|
355
|
+
this.identity[121] = 0x00;
|
|
356
|
+
this.identity[122] = 0x04;
|
|
357
|
+
this.identity[123] = 0x00;
|
|
358
|
+
// Remaining words are zero
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Load storage data from a Uint8Array, ArrayBuffer, or number array
|
|
362
|
+
* If data is not provided or wrong size, storage remains empty
|
|
363
|
+
*/
|
|
364
|
+
loadData(data) {
|
|
365
|
+
if (!data) {
|
|
366
|
+
console.log('No storage data provided. Storage will remain empty.');
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
let uint8Data;
|
|
370
|
+
if (data instanceof ArrayBuffer) {
|
|
371
|
+
uint8Data = new Uint8Array(data);
|
|
372
|
+
}
|
|
373
|
+
else if (data instanceof Uint8Array) {
|
|
374
|
+
uint8Data = data;
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
uint8Data = new Uint8Array(data);
|
|
378
|
+
}
|
|
379
|
+
// Ensure the data is exactly the expected size
|
|
380
|
+
if (uint8Data.length === Storage.STORAGE_SIZE) {
|
|
381
|
+
this.storage.set(uint8Data);
|
|
382
|
+
console.log(`Storage loaded (${Storage.STORAGE_SIZE} bytes)`);
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
console.warn(`Warning: Storage data size mismatch. Expected ${Storage.STORAGE_SIZE} bytes, got ${uint8Data.length} bytes.`);
|
|
386
|
+
console.warn('Storage will remain empty.');
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Get storage data as Uint8Array for saving
|
|
391
|
+
*/
|
|
392
|
+
getData() {
|
|
393
|
+
return new Uint8Array(this.storage);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
exports.Storage = Storage;
|
|
397
|
+
// Constants
|
|
398
|
+
Storage.STORAGE_SIZE = 128 * 1024 * 1024; // 128MB
|
|
399
|
+
Storage.SECTOR_SIZE = 512;
|
|
400
|
+
Storage.SECTOR_COUNT = Storage.STORAGE_SIZE / Storage.SECTOR_SIZE; // 262144 sectors
|
|
401
|
+
// Status Register Flags
|
|
402
|
+
Storage.STATUS_ERR = 0x01; // Error
|
|
403
|
+
Storage.STATUS_DRQ = 0x08; // Data Request
|
|
404
|
+
Storage.STATUS_RDY = 0x40; // Ready
|
|
405
|
+
// Error Register Flags
|
|
406
|
+
Storage.ERR_AMNF = 0x01; // Address Mark Not Found
|
|
407
|
+
Storage.ERR_ABRT = 0x04; // Aborted Command
|
|
408
|
+
Storage.ERR_IDNF = 0x10; // ID Not Found
|
|
409
|
+
//# sourceMappingURL=Storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Storage.js","sourceRoot":"","sources":["../../../src/components/IO/Storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { IO } from '../IO';
|
|
2
|
+
import { VTAC } from 'vtac-terminal';
|
|
3
|
+
/**
|
|
4
|
+
* Terminal - Emulates the VTAC fantasy terminal
|
|
5
|
+
*
|
|
6
|
+
* Register Map:
|
|
7
|
+
* $00: Data / Status Register
|
|
8
|
+
* Write: sends byte to VTAC for processing
|
|
9
|
+
* Read: always returns 0 (bit 7 is a busy flag on the real device; busy is never set here)
|
|
10
|
+
*/
|
|
11
|
+
export declare class Terminal implements IO {
|
|
12
|
+
raiseIRQ: () => void;
|
|
13
|
+
raiseNMI: () => void;
|
|
14
|
+
readonly vtac: VTAC;
|
|
15
|
+
read(address: number): number;
|
|
16
|
+
write(address: number, data: number): void;
|
|
17
|
+
tick(frequency: number): void;
|
|
18
|
+
reset(coldStart: boolean): void;
|
|
19
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Terminal = void 0;
|
|
4
|
+
const vtac_terminal_1 = require("vtac-terminal");
|
|
5
|
+
/**
|
|
6
|
+
* Terminal - Emulates the VTAC fantasy terminal
|
|
7
|
+
*
|
|
8
|
+
* Register Map:
|
|
9
|
+
* $00: Data / Status Register
|
|
10
|
+
* Write: sends byte to VTAC for processing
|
|
11
|
+
* Read: always returns 0 (bit 7 is a busy flag on the real device; busy is never set here)
|
|
12
|
+
*/
|
|
13
|
+
class Terminal {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.raiseIRQ = () => { };
|
|
16
|
+
this.raiseNMI = () => { };
|
|
17
|
+
this.vtac = new vtac_terminal_1.VTAC();
|
|
18
|
+
}
|
|
19
|
+
read(address) {
|
|
20
|
+
// Status register: bit 7 is busy flag on real device, never busy in emulation
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
write(address, data) {
|
|
24
|
+
const register = address & 0x00;
|
|
25
|
+
if (register === 0x00) {
|
|
26
|
+
this.vtac.parse(data);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
tick(frequency) { }
|
|
30
|
+
reset(coldStart) { }
|
|
31
|
+
}
|
|
32
|
+
exports.Terminal = Terminal;
|
|
33
|
+
//# sourceMappingURL=Terminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Terminal.js","sourceRoot":"","sources":["../../../src/components/IO/Terminal.ts"],"names":[],"mappings":";;;AACA,iDAAoC;AAEpC;;;;;;;GAOG;AACH,MAAa,QAAQ;IAArB;QAEE,aAAQ,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;QACnB,aAAQ,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;QAEV,SAAI,GAAS,IAAI,oBAAI,EAAE,CAAA;IAiBlC,CAAC;IAfC,IAAI,CAAC,OAAe;QAClB,8EAA8E;QAC9E,OAAO,CAAC,CAAA;IACV,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,IAAY;QACjC,MAAM,QAAQ,GAAG,OAAO,GAAG,IAAI,CAAA;QAC/B,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACvB,CAAC;IACH,CAAC;IAED,IAAI,CAAC,SAAiB,IAAS,CAAC;IAChC,KAAK,CAAC,SAAkB,IAAS,CAAC;CAEnC;AAtBD,4BAsBC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { IO } from '../IO';
|
|
2
|
+
import { Attachment } from './Attachments/Attachment';
|
|
3
|
+
/**
|
|
4
|
+
* VIA - Emulates the 65C22 VIA (Versatile Interface Adapter)
|
|
5
|
+
*
|
|
6
|
+
* The 65C22 VIA provides:
|
|
7
|
+
* - Two 8-bit bidirectional I/O ports (Port A and Port B)
|
|
8
|
+
* - Two 16-bit timers with interrupt generation
|
|
9
|
+
* - Shift register for serial I/O
|
|
10
|
+
* - Handshaking lines for data transfer
|
|
11
|
+
*/
|
|
12
|
+
export declare class VIA implements IO {
|
|
13
|
+
private static readonly VIA_ORB;
|
|
14
|
+
private static readonly VIA_ORA;
|
|
15
|
+
private static readonly VIA_DDRB;
|
|
16
|
+
private static readonly VIA_DDRA;
|
|
17
|
+
private static readonly VIA_T1CL;
|
|
18
|
+
private static readonly VIA_T1CH;
|
|
19
|
+
private static readonly VIA_T1LL;
|
|
20
|
+
private static readonly VIA_T1LH;
|
|
21
|
+
private static readonly VIA_T2CL;
|
|
22
|
+
private static readonly VIA_T2CH;
|
|
23
|
+
private static readonly VIA_SR;
|
|
24
|
+
private static readonly VIA_ACR;
|
|
25
|
+
private static readonly VIA_PCR;
|
|
26
|
+
private static readonly VIA_IFR;
|
|
27
|
+
private static readonly VIA_IER;
|
|
28
|
+
private static readonly VIA_ORA_NH;
|
|
29
|
+
private static readonly IRQ_CA2;
|
|
30
|
+
private static readonly IRQ_CA1;
|
|
31
|
+
private static readonly IRQ_SR;
|
|
32
|
+
private static readonly IRQ_CB2;
|
|
33
|
+
private static readonly IRQ_CB1;
|
|
34
|
+
private static readonly IRQ_T2;
|
|
35
|
+
private static readonly IRQ_T1;
|
|
36
|
+
private static readonly IRQ_IRQ;
|
|
37
|
+
private static readonly MAX_ATTACHMENTS_PER_PORT;
|
|
38
|
+
private regORB;
|
|
39
|
+
private regORA;
|
|
40
|
+
private regDDRB;
|
|
41
|
+
private regDDRA;
|
|
42
|
+
private regT1C;
|
|
43
|
+
private regT1L;
|
|
44
|
+
private regT2C;
|
|
45
|
+
private regT2L;
|
|
46
|
+
private regSR;
|
|
47
|
+
private regACR;
|
|
48
|
+
private regPCR;
|
|
49
|
+
private regIFR;
|
|
50
|
+
private regIER;
|
|
51
|
+
private CA1;
|
|
52
|
+
private CA2;
|
|
53
|
+
private CB1;
|
|
54
|
+
private CB2;
|
|
55
|
+
private T1_running;
|
|
56
|
+
private T2_running;
|
|
57
|
+
private T1_IRQ_enabled;
|
|
58
|
+
private T2_IRQ_enabled;
|
|
59
|
+
private tickCounter;
|
|
60
|
+
private ticksPerMicrosecond;
|
|
61
|
+
private portA_attachments;
|
|
62
|
+
private portB_attachments;
|
|
63
|
+
private portA_attachmentCount;
|
|
64
|
+
private portB_attachmentCount;
|
|
65
|
+
raiseIRQ: () => void;
|
|
66
|
+
raiseNMI: () => void;
|
|
67
|
+
constructor();
|
|
68
|
+
reset(coldStart: boolean): void;
|
|
69
|
+
read(address: number): number;
|
|
70
|
+
write(address: number, data: number): void;
|
|
71
|
+
tick(frequency: number): void;
|
|
72
|
+
private updateIRQ;
|
|
73
|
+
private setIRQFlag;
|
|
74
|
+
private clearIRQFlag;
|
|
75
|
+
private readPortA;
|
|
76
|
+
private readPortB;
|
|
77
|
+
private writePortA;
|
|
78
|
+
private writePortB;
|
|
79
|
+
private updateCA2;
|
|
80
|
+
private updateCB2;
|
|
81
|
+
private notifyAttachmentsControlLines;
|
|
82
|
+
private sortAttachmentsByPriority;
|
|
83
|
+
/**
|
|
84
|
+
* Attach a GPIO device to Port A
|
|
85
|
+
* @param attachment - The attachment to add
|
|
86
|
+
*/
|
|
87
|
+
attachToPortA(attachment: Attachment): void;
|
|
88
|
+
/**
|
|
89
|
+
* Attach a GPIO device to Port B
|
|
90
|
+
* @param attachment - The attachment to add
|
|
91
|
+
*/
|
|
92
|
+
attachToPortB(attachment: Attachment): void;
|
|
93
|
+
/**
|
|
94
|
+
* Get a Port A attachment by index
|
|
95
|
+
* @param index - The attachment index
|
|
96
|
+
* @returns The attachment or null if not found
|
|
97
|
+
*/
|
|
98
|
+
getPortAAttachment(index: number): Attachment | null;
|
|
99
|
+
/**
|
|
100
|
+
* Get a Port B attachment by index
|
|
101
|
+
* @param index - The attachment index
|
|
102
|
+
* @returns The attachment or null if not found
|
|
103
|
+
*/
|
|
104
|
+
getPortBAttachment(index: number): Attachment | null;
|
|
105
|
+
}
|