Convert aci to Typescript
This commit is contained in:
parent
fc536fdb20
commit
62718d187d
160
js/cards/aci.js
160
js/cards/aci.js
|
@ -1,160 +0,0 @@
|
|||
import { debug } from '../util';
|
||||
|
||||
export default function ACI(cpu, cb) {
|
||||
var _last = cpu.cycles();
|
||||
var _next = _last;
|
||||
var _recording = false;
|
||||
var _readOffset = 0;
|
||||
var _flip = false;
|
||||
var _beKind = false;
|
||||
var _progress = 0;
|
||||
|
||||
var rom = [
|
||||
0xA9,0xAA,0x20,0xEF,0xFF,0xA9,0x8D,0x20,
|
||||
0xEF,0xFF,0xA0,0xFF,0xC8,0xAD,0x11,0xD0,
|
||||
0x10,0xFB,0xAD,0x10,0xD0,0x99,0x00,0x02,
|
||||
0x20,0xEF,0xFF,0xC9,0x9B,0xF0,0xE1,0xC9,
|
||||
0x8D,0xD0,0xE9,0xA2,0xFF,0xA9,0x00,0x85,
|
||||
0x24,0x85,0x25,0x85,0x26,0x85,0x27,0xE8,
|
||||
0xBD,0x00,0x02,0xC9,0xD2,0xF0,0x56,0xC9,
|
||||
0xD7,0xF0,0x35,0xC9,0xAE,0xF0,0x27,0xC9,
|
||||
0x8D,0xF0,0x20,0xC9,0xA0,0xF0,0xE8,0x49,
|
||||
0xB0,0xC9,0x0A,0x90,0x06,0x69,0x88,0xC9,
|
||||
0xFA,0x90,0xAD,0x0A,0x0A,0x0A,0x0A,0xA0,
|
||||
0x04,0x0A,0x26,0x24,0x26,0x25,0x88,0xD0,
|
||||
0xF8,0xF0,0xCC,0x4C,0x1A,0xFF,0xA5,0x24,
|
||||
0x85,0x26,0xA5,0x25,0x85,0x27,0xB0,0xBF,
|
||||
0xA9,0x40,0x20,0xCC,0xC1,0x88,0xA2,0x00,
|
||||
0xA1,0x26,0xA2,0x10,0x0A,0x20,0xDB,0xC1,
|
||||
0xD0,0xFA,0x20,0xF1,0xC1,0xA0,0x1E,0x90,
|
||||
0xEC,0xA6,0x28,0xB0,0x98,0x20,0xBC,0xC1,
|
||||
0xA9,0x16,0x20,0xCC,0xC1,0x20,0xBC,0xC1,
|
||||
0xA0,0x1F,0x20,0xBF,0xC1,0xB0,0xF9,0x20,
|
||||
0xBF,0xC1,0xA0,0x3A,0xA2,0x08,0x48,0x20,
|
||||
0xBC,0xC1,0x68,0x2A,0xA0,0x39,0xCA,0xD0,
|
||||
0xF5,0x81,0x26,0x20,0xF1,0xC1,0xA0,0x35,
|
||||
0x90,0xEA,0xB0,0xCD,0x20,0xBF,0xC1,0x88,
|
||||
0xAD,0x81,0xC0,0xC5,0x29,0xF0,0xF8,0x85,
|
||||
0x29,0xC0,0x80,0x60,0x86,0x28,0xA0,0x42,
|
||||
0x20,0xE0,0xC1,0xD0,0xF9,0x69,0xFE,0xB0,
|
||||
0xF5,0xA0,0x1E,0x20,0xE0,0xC1,0xA0,0x2C,
|
||||
0x88,0xD0,0xFD,0x90,0x05,0xA0,0x2F,0x88,
|
||||
0xD0,0xFD,0xBC,0x00,0xC0,0xA0,0x29,0xCA,
|
||||
0x60,0xA5,0x26,0xC5,0x24,0xA5,0x27,0xE5,
|
||||
0x25,0xE6,0x26,0xD0,0x02,0xE6,0x27,0x60
|
||||
];
|
||||
|
||||
return {
|
||||
start: function aci_start() {
|
||||
return 0xc0;
|
||||
},
|
||||
end: function aci_end() {
|
||||
return 0xc1;
|
||||
},
|
||||
read: function aci_read(page, off) {
|
||||
var now = cpu.cycles();
|
||||
var result = rom[off];
|
||||
if (page == 0xc0) {
|
||||
if (_recording) {
|
||||
var delta = now - _last;
|
||||
this.buffer.push(delta);
|
||||
_last = now;
|
||||
} else {
|
||||
var progress;
|
||||
if (_readOffset < this.buffer.length) {
|
||||
if (now > _next) {
|
||||
if ((_readOffset % 1000) == 0) {
|
||||
debug('Read ' + (_readOffset / 1000));
|
||||
}
|
||||
_flip = !_flip;
|
||||
_next = now + this.buffer[_readOffset++];
|
||||
}
|
||||
}
|
||||
result = _flip ? rom[off | 0x01] : rom[off & 0xfe];
|
||||
|
||||
progress = Math.round(_readOffset / this.buffer.length * 100) / 100;
|
||||
if (_progress != progress) {
|
||||
_progress = progress;
|
||||
cb.progress(_progress);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cpu.sync()) {
|
||||
switch (off) {
|
||||
case 0x00:
|
||||
_recording = false;
|
||||
_beKind = true;
|
||||
debug('Entering ACI CLI');
|
||||
break;
|
||||
case 0x63:
|
||||
if (_recording) {
|
||||
this.buffer.push(5000000);
|
||||
_recording = false;
|
||||
}
|
||||
debug('Exiting ACI CLI');
|
||||
break;
|
||||
case 0x70: // WRITE
|
||||
_recording = true;
|
||||
if (_beKind) {
|
||||
_beKind = false;
|
||||
this.buffer = [];
|
||||
}
|
||||
debug('Start write');
|
||||
_last = now;
|
||||
break;
|
||||
//case 0x7c: // WBITLOOP:
|
||||
// _debug = true;
|
||||
// debug("Write bit loop");
|
||||
// break;
|
||||
case 0x8d: // READ
|
||||
_recording = false;
|
||||
debug('Start read');
|
||||
if (_beKind) {
|
||||
_readOffset = 0;
|
||||
_next = now + 5000000;
|
||||
_beKind = false;
|
||||
|
||||
cb.progress(0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
write: function aci_write() {},
|
||||
|
||||
getState: function aci_getState() { return {}; },
|
||||
setState: function aci_setState() {},
|
||||
|
||||
setData: function aci_setData(data) {
|
||||
var seg, idx, jdx, d, b;
|
||||
this.buffer = [];
|
||||
for (seg = 0; seg < data.length; seg++) {
|
||||
for (idx = 0; idx < 16384; idx++) {
|
||||
this.buffer.push(592);
|
||||
}
|
||||
this.buffer.push(180);
|
||||
this.buffer.push(238);
|
||||
d = data[seg];
|
||||
for (idx = 0; idx < d.length; idx++) {
|
||||
b = d[idx];
|
||||
for (jdx = 0; jdx < 8; jdx++) {
|
||||
if (b & 0x80) {
|
||||
this.buffer.push(473);
|
||||
this.buffer.push(473);
|
||||
} else {
|
||||
this.buffer.push(238);
|
||||
this.buffer.push(238);
|
||||
}
|
||||
b <<= 1;
|
||||
}
|
||||
}
|
||||
this.buffer.push(5000000);
|
||||
}
|
||||
},
|
||||
buffer: []
|
||||
};
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
import CPU6502 from "../cpu6502";
|
||||
import { debug } from "../util";
|
||||
import { byte } from "../types";
|
||||
|
||||
const rom = [
|
||||
0xa9, 0xaa, 0x20, 0xef, 0xff, 0xa9, 0x8d, 0x20, 0xef, 0xff, 0xa0, 0xff, 0xc8,
|
||||
0xad, 0x11, 0xd0, 0x10, 0xfb, 0xad, 0x10, 0xd0, 0x99, 0x00, 0x02, 0x20, 0xef,
|
||||
0xff, 0xc9, 0x9b, 0xf0, 0xe1, 0xc9, 0x8d, 0xd0, 0xe9, 0xa2, 0xff, 0xa9, 0x00,
|
||||
0x85, 0x24, 0x85, 0x25, 0x85, 0x26, 0x85, 0x27, 0xe8, 0xbd, 0x00, 0x02, 0xc9,
|
||||
0xd2, 0xf0, 0x56, 0xc9, 0xd7, 0xf0, 0x35, 0xc9, 0xae, 0xf0, 0x27, 0xc9, 0x8d,
|
||||
0xf0, 0x20, 0xc9, 0xa0, 0xf0, 0xe8, 0x49, 0xb0, 0xc9, 0x0a, 0x90, 0x06, 0x69,
|
||||
0x88, 0xc9, 0xfa, 0x90, 0xad, 0x0a, 0x0a, 0x0a, 0x0a, 0xa0, 0x04, 0x0a, 0x26,
|
||||
0x24, 0x26, 0x25, 0x88, 0xd0, 0xf8, 0xf0, 0xcc, 0x4c, 0x1a, 0xff, 0xa5, 0x24,
|
||||
0x85, 0x26, 0xa5, 0x25, 0x85, 0x27, 0xb0, 0xbf, 0xa9, 0x40, 0x20, 0xcc, 0xc1,
|
||||
0x88, 0xa2, 0x00, 0xa1, 0x26, 0xa2, 0x10, 0x0a, 0x20, 0xdb, 0xc1, 0xd0, 0xfa,
|
||||
0x20, 0xf1, 0xc1, 0xa0, 0x1e, 0x90, 0xec, 0xa6, 0x28, 0xb0, 0x98, 0x20, 0xbc,
|
||||
0xc1, 0xa9, 0x16, 0x20, 0xcc, 0xc1, 0x20, 0xbc, 0xc1, 0xa0, 0x1f, 0x20, 0xbf,
|
||||
0xc1, 0xb0, 0xf9, 0x20, 0xbf, 0xc1, 0xa0, 0x3a, 0xa2, 0x08, 0x48, 0x20, 0xbc,
|
||||
0xc1, 0x68, 0x2a, 0xa0, 0x39, 0xca, 0xd0, 0xf5, 0x81, 0x26, 0x20, 0xf1, 0xc1,
|
||||
0xa0, 0x35, 0x90, 0xea, 0xb0, 0xcd, 0x20, 0xbf, 0xc1, 0x88, 0xad, 0x81, 0xc0,
|
||||
0xc5, 0x29, 0xf0, 0xf8, 0x85, 0x29, 0xc0, 0x80, 0x60, 0x86, 0x28, 0xa0, 0x42,
|
||||
0x20, 0xe0, 0xc1, 0xd0, 0xf9, 0x69, 0xfe, 0xb0, 0xf5, 0xa0, 0x1e, 0x20, 0xe0,
|
||||
0xc1, 0xa0, 0x2c, 0x88, 0xd0, 0xfd, 0x90, 0x05, 0xa0, 0x2f, 0x88, 0xd0, 0xfd,
|
||||
0xbc, 0x00, 0xc0, 0xa0, 0x29, 0xca, 0x60, 0xa5, 0x26, 0xc5, 0x24, 0xa5, 0x27,
|
||||
0xe5, 0x25, 0xe6, 0x26, 0xd0, 0x02, 0xe6, 0x27, 0x60,
|
||||
] as const;
|
||||
|
||||
export interface ACICallback {
|
||||
progress: (value: number) => void;
|
||||
}
|
||||
|
||||
export default class ACI {
|
||||
_last: number;
|
||||
_next: number;
|
||||
_recording = false;
|
||||
_readOffset = 0;
|
||||
_flip = false;
|
||||
_beKind = false;
|
||||
_progress = 0;
|
||||
|
||||
constructor(private cpu: CPU6502, private cb: ACICallback) {
|
||||
this._last = cpu.getCycles();
|
||||
this._next = this._last;
|
||||
}
|
||||
|
||||
start() {
|
||||
return 0xc0;
|
||||
}
|
||||
end() {
|
||||
return 0xc1;
|
||||
}
|
||||
read(page: byte, off: byte) {
|
||||
var now = this.cpu.getCycles();
|
||||
var result = rom[off];
|
||||
if (page == 0xc0) {
|
||||
if (this._recording) {
|
||||
var delta = now - this._last;
|
||||
this.buffer.push(delta);
|
||||
this._last = now;
|
||||
} else {
|
||||
var progress;
|
||||
if (this._readOffset < this.buffer.length) {
|
||||
if (now > this._next) {
|
||||
if (this._readOffset % 1000 == 0) {
|
||||
debug("Read " + this._readOffset / 1000);
|
||||
}
|
||||
this._flip = !this._flip;
|
||||
this._next = now + this.buffer[this._readOffset++];
|
||||
}
|
||||
}
|
||||
result = this._flip ? rom[off | 0x01] : rom[off & 0xfe];
|
||||
|
||||
progress =
|
||||
Math.round((this._readOffset / this.buffer.length) * 100) / 100;
|
||||
if (this._progress != progress) {
|
||||
this._progress = progress;
|
||||
this.cb.progress(this._progress);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this.cpu.getSync()) {
|
||||
switch (off) {
|
||||
case 0x00:
|
||||
this._recording = false;
|
||||
this._beKind = true;
|
||||
debug("Entering ACI CLI");
|
||||
break;
|
||||
case 0x63:
|
||||
if (this._recording) {
|
||||
this.buffer.push(5000000);
|
||||
this._recording = false;
|
||||
}
|
||||
debug("Exiting ACI CLI");
|
||||
break;
|
||||
case 0x70: // WRITE
|
||||
this._recording = true;
|
||||
if (this._beKind) {
|
||||
this._beKind = false;
|
||||
this.buffer = [];
|
||||
}
|
||||
debug("Start write");
|
||||
this._last = now;
|
||||
break;
|
||||
//case 0x7c: // WBITLOOP:
|
||||
// _debug = true;
|
||||
// debug("Write bit loop");
|
||||
// break;
|
||||
case 0x8d: // READ
|
||||
this._recording = false;
|
||||
debug("Start read");
|
||||
if (this._beKind) {
|
||||
this._readOffset = 0;
|
||||
this._next = now + 5000000;
|
||||
this._beKind = false;
|
||||
|
||||
this.cb.progress(0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
write() {}
|
||||
|
||||
getState() {
|
||||
return {};
|
||||
}
|
||||
setState() {}
|
||||
|
||||
setData(data: number[][]) {
|
||||
var seg, idx, jdx, d, b;
|
||||
this.buffer = [];
|
||||
for (seg = 0; seg < data.length; seg++) {
|
||||
for (idx = 0; idx < 16384; idx++) {
|
||||
this.buffer.push(592);
|
||||
}
|
||||
this.buffer.push(180);
|
||||
this.buffer.push(238);
|
||||
d = data[seg];
|
||||
for (idx = 0; idx < d.length; idx++) {
|
||||
b = d[idx];
|
||||
for (jdx = 0; jdx < 8; jdx++) {
|
||||
if (b & 0x80) {
|
||||
this.buffer.push(473);
|
||||
this.buffer.push(473);
|
||||
} else {
|
||||
this.buffer.push(238);
|
||||
this.buffer.push(238);
|
||||
}
|
||||
b <<= 1;
|
||||
}
|
||||
}
|
||||
this.buffer.push(5000000);
|
||||
}
|
||||
}
|
||||
buffer: byte[] = [];
|
||||
}
|
|
@ -14,6 +14,7 @@
|
|||
"devDependencies": {
|
||||
"@babel/core": "^7.4.0",
|
||||
"@babel/preset-env": "^7.4.2",
|
||||
"@types/micromodal": "^0.3.3",
|
||||
"ajv": "^6.9.2",
|
||||
"babel-jest": "^26.3.0",
|
||||
"eslint": "^8.3.0",
|
||||
|
@ -3521,6 +3522,12 @@
|
|||
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/micromodal": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/micromodal/-/micromodal-0.3.3.tgz",
|
||||
"integrity": "sha512-XQg6nqg15A6ZKkMkDdqLkC5LTxLb7CZU6BX8uHBj4AVU7+k/W6kfriW5HCsarrjFpONNOMAmhA1ReUsMm7297g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/mime": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
|
||||
|
@ -19331,6 +19338,12 @@
|
|||
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/micromodal": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/micromodal/-/micromodal-0.3.3.tgz",
|
||||
"integrity": "sha512-XQg6nqg15A6ZKkMkDdqLkC5LTxLb7CZU6BX8uHBj4AVU7+k/W6kfriW5HCsarrjFpONNOMAmhA1ReUsMm7297g==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/mime": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"devDependencies": {
|
||||
"@babel/core": "^7.4.0",
|
||||
"@babel/preset-env": "^7.4.2",
|
||||
"@types/micromodal": "^0.3.3",
|
||||
"ajv": "^6.9.2",
|
||||
"babel-jest": "^26.3.0",
|
||||
"eslint": "^8.3.0",
|
||||
|
|
Loading…
Reference in New Issue