typescript linting

This commit is contained in:
Will Scullin 2020-11-07 15:49:05 -08:00
parent b3cb64357f
commit f600f7c6b4
No known key found for this signature in database
GPG Key ID: 9092A5C0A673416B
14 changed files with 561 additions and 269 deletions

View File

@ -1,28 +1,47 @@
{ {
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint/eslint-plugin"],
"rules": { "rules": {
"indent": [ "indent": [
2, "error",
4 4
], ],
"quotes": [ "quotes": [
2, "error",
"single" "single"
], ],
"linebreak-style": [ "linebreak-style": [
2, "error",
"unix" "unix"
], ],
"prefer-const": [
"error"
],
"semi": [ "semi": [
1, "error",
"always" "always"
], ],
"no-use-before-define": [ "no-use-before-define": "off",
2, "@typescript-eslint/no-use-before-define": [
{ "functions": false } "error",
{
"functions": false,
"classes": false
}
], ],
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["error"],
"no-redeclare": "off",
"@typescript-eslint/no-redeclare": ["error"],
"no-console": [ "no-console": [
2, "error",
{ "allow": ["info", "warn", "error"] } {
"allow": [
"info",
"warn",
"error"
]
}
] ]
}, },
"env": { "env": {
@ -36,7 +55,19 @@
"extends": "eslint:recommended", "extends": "eslint:recommended",
"overrides": [ "overrides": [
{ {
"files": [ "bin/*", "babel.config.js", "webpack.config.js" ], "files": [
"**/*.ts"
],
"rules": {
"no-var": "error"
}
},
{
"files": [
"bin/*",
"babel.config.js",
"webpack.config.js"
],
"rules": { "rules": {
"no-console": 0 "no-console": 0
}, },
@ -45,18 +76,26 @@
"jquery": false, "jquery": false,
"browser": false "browser": false
} }
}, { },
"files": [ "test/**/*"], {
"files": [
"test/**/*"
],
"env": { "env": {
"jest": true, "jest": true,
"jasmine": true,
"node": true "node": true
}, },
"rules": { "rules": {
"no-console": 0 "no-console": 0
} }
},
}, { {
"files": [ "js/entry2.js", "js/entry2e.js", "jest.config.js"], "files": [
"js/entry2.js",
"js/entry2e.js",
"jest.config.js"
],
"env": { "env": {
"commonjs": true "commonjs": true
} }

View File

@ -1,10 +1,10 @@
import { byte, memory } from "./types"; import { memory } from './types';
const B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; const B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
/** Encode an array of bytes in base64. */ /** Encode an array of bytes in base64. */
export function base64_encode(data: memory) { export function base64_encode(data: memory) {
// Twacked by Will Scullin to handle arrays of "bytes" // Twacked by Will Scullin to handle arrays of 'bytes'
// http://kevin.vanzonneveld.net // http://kevin.vanzonneveld.net
// + original by: Tyler Akins (http://rumkin.com) // + original by: Tyler Akins (http://rumkin.com)
@ -23,8 +23,9 @@ export function base64_encode(data: memory) {
// return atob(data); // return atob(data);
//} //}
var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, enc='', tmp_arr = []; let o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, enc='';
const tmp_arr = [];
if (!data) { if (!data) {
return data; return data;
@ -66,7 +67,7 @@ export function base64_decode(data: null | undefined): undefined;
export function base64_decode(data: string): memory; export function base64_decode(data: string): memory;
/** Returns an array of bytes from the given base64-encoded string. */ /** Returns an array of bytes from the given base64-encoded string. */
export function base64_decode(data: string | null | undefined): memory | undefined { export function base64_decode(data: string | null | undefined): memory | undefined {
// Twacked by Will Scullin to handle arrays of "bytes" // Twacked by Will Scullin to handle arrays of 'bytes'
// http://kevin.vanzonneveld.net // http://kevin.vanzonneveld.net
// + original by: Tyler Akins (http://rumkin.com) // + original by: Tyler Akins (http://rumkin.com)
@ -88,7 +89,8 @@ export function base64_decode(data: string | null | undefined): memory | undefin
// return btoa(data); // return btoa(data);
//} //}
var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, tmp_arr = []; let o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0;
const tmp_arr = [];
if (!data) { if (!data) {
return undefined; return undefined;

View File

@ -193,7 +193,7 @@ export default class CPU6502 {
const opary: Instruction[] = []; const opary: Instruction[] = [];
for (let idx = 0; idx < 0x100; idx++) { for (let idx = 0; idx < 0x100; idx++) {
opary[idx] = ops[idx] || this.unknown(idx) opary[idx] = ops[idx] || this.unknown(idx);
} }
this.opary = opary; this.opary = opary;
} }
@ -230,7 +230,7 @@ export default class CPU6502 {
b ^= 0xff; b ^= 0xff;
// KEGS // KEGS
var c, v; let c, v;
if ((this.sr & flags.D) !== 0) { if ((this.sr & flags.D) !== 0) {
// BCD // BCD
c = (a & 0x0f) + (b & 0x0f) + (this.sr & flags.C); c = (a & 0x0f) + (b & 0x0f) + (this.sr & flags.C);
@ -274,11 +274,11 @@ export default class CPU6502 {
} }
private readBytePC(): byte { private readBytePC(): byte {
let addr = this.pc, const addr = this.pc,
page = addr >> 8, page = addr >> 8,
off = addr & 0xff; off = addr & 0xff;
var result = this.readPages[page].read(page, off); const result = this.readPages[page].read(page, off);
this.pc = (this.pc + 1) & 0xffff; this.pc = (this.pc + 1) & 0xffff;
@ -288,10 +288,10 @@ export default class CPU6502 {
} }
private readByte(addr: word): byte { private readByte(addr: word): byte {
var page = addr >> 8, const page = addr >> 8,
off = addr & 0xff; off = addr & 0xff;
var result = this.readPages[page].read(page, off); const result = this.readPages[page].read(page, off);
this.cycles++; this.cycles++;
@ -299,14 +299,14 @@ export default class CPU6502 {
} }
private readByteDebug(addr: word) { private readByteDebug(addr: word) {
var page = addr >> 8, const page = addr >> 8,
off = addr & 0xff; off = addr & 0xff;
return this.readPages[page].read(page, off); return this.readPages[page].read(page, off);
} }
private writeByte(addr: word, val: byte) { private writeByte(addr: word, val: byte) {
var page = addr >> 8, const page = addr >> 8,
off = addr & 0xff; off = addr & 0xff;
this.writePages[page].write(page, off, val); this.writePages[page].write(page, off, val);
@ -327,10 +327,8 @@ export default class CPU6502 {
} }
private readZPWord(addr: byte): word { private readZPWord(addr: byte): word {
var lsb, msb; const lsb = this.readByte(addr & 0xff);
const msb = this.readByte((addr + 1) & 0xff);
lsb = this.readByte(addr & 0xff);
msb = this.readByte((addr + 1) & 0xff);
return (msb << 8) | lsb; return (msb << 8) | lsb;
} }
@ -351,8 +349,8 @@ export default class CPU6502 {
} }
private pullWordRaw(): word { private pullWordRaw(): word {
var lsb = this.pullByte(); const lsb = this.pullByte();
var msb = this.pullByte(); const msb = this.pullByte();
return (msb << 8) | lsb; return (msb << 8) | lsb;
} }
@ -385,12 +383,12 @@ export default class CPU6502 {
// $0000,X // $0000,X
readAbsoluteX= (): byte => { readAbsoluteX= (): byte => {
var addr = this.readWordPC(); let addr = this.readWordPC();
var oldPage = addr >> 8; const oldPage = addr >> 8;
addr = (addr + this.xr) & 0xffff; addr = (addr + this.xr) & 0xffff;
var newPage = addr >> 8; const newPage = addr >> 8;
if (newPage != oldPage) { if (newPage != oldPage) {
var off = addr & 0xff; const off = addr & 0xff;
this.readByte(oldPage << 8 | off); this.readByte(oldPage << 8 | off);
} }
return this.readByte(addr); return this.readByte(addr);
@ -398,12 +396,12 @@ export default class CPU6502 {
// $0000,Y // $0000,Y
readAbsoluteY = (): byte => { readAbsoluteY = (): byte => {
var addr = this.readWordPC(); let addr = this.readWordPC();
var oldPage = addr >> 8; const oldPage = addr >> 8;
addr = (addr + this.yr) & 0xffff; addr = (addr + this.yr) & 0xffff;
var newPage = addr >> 8; const newPage = addr >> 8;
if (newPage != oldPage) { if (newPage != oldPage) {
var off = addr & 0xff; const off = addr & 0xff;
this.readByte(oldPage << 8 | off); this.readByte(oldPage << 8 | off);
} }
return this.readByte(addr); return this.readByte(addr);
@ -411,34 +409,34 @@ export default class CPU6502 {
// $00,X // $00,X
readZeroPageX = (): byte => { readZeroPageX = (): byte => {
var zpAddr = this.readBytePC(); const zpAddr = this.readBytePC();
this.readByte(zpAddr); this.readByte(zpAddr);
return this.readByte((zpAddr + this.xr) & 0xff); return this.readByte((zpAddr + this.xr) & 0xff);
} }
// $00,Y // $00,Y
readZeroPageY = (): byte => { readZeroPageY = (): byte => {
var zpAddr = this.readBytePC(); const zpAddr = this.readBytePC();
this.readByte(zpAddr); this.readByte(zpAddr);
return this.readByte((zpAddr + this.yr) & 0xff); return this.readByte((zpAddr + this.yr) & 0xff);
} }
// ($00,X) // ($00,X)
readZeroPageXIndirect = (): byte => { readZeroPageXIndirect = (): byte => {
var zpAddr = this.readBytePC(); const zpAddr = this.readBytePC();
this.readByte(zpAddr); this.readByte(zpAddr);
var addr = this.readZPWord((zpAddr + this.xr) & 0xff); const addr = this.readZPWord((zpAddr + this.xr) & 0xff);
return this.readByte(addr); return this.readByte(addr);
} }
// ($00),Y // ($00),Y
readZeroPageIndirectY = (): byte => { readZeroPageIndirectY = (): byte => {
var addr = this.readZPWord(this.readBytePC()); let addr = this.readZPWord(this.readBytePC());
var oldPage = addr >> 8; const oldPage = addr >> 8;
addr = (addr + this.yr) & 0xffff; addr = (addr + this.yr) & 0xffff;
var newPage = addr >> 8; const newPage = addr >> 8;
if (newPage != oldPage) { if (newPage != oldPage) {
var off = addr & 0xff; const off = addr & 0xff;
this.readByte(oldPage << 8 | off); this.readByte(oldPage << 8 | off);
} }
return this.readByte(addr); return this.readByte(addr);
@ -465,49 +463,52 @@ export default class CPU6502 {
// $0000,X // $0000,X
writeAbsoluteX = (val: byte) => { writeAbsoluteX = (val: byte) => {
var addr = this.readWordPC(), oldPage = addr >> 8; let addr = this.readWordPC();
const oldPage = addr >> 8;
addr = (addr + this.xr) & 0xffff; addr = (addr + this.xr) & 0xffff;
var off = addr & 0xff; const off = addr & 0xff;
this.readByte(oldPage << 8 | off); this.readByte(oldPage << 8 | off);
this.writeByte(addr, val); this.writeByte(addr, val);
} }
// $0000,Y // $0000,Y
writeAbsoluteY = (val: byte) => { writeAbsoluteY = (val: byte) => {
var addr = this.readWordPC(), oldPage = addr >> 8; let addr = this.readWordPC();
const oldPage = addr >> 8;
addr = (addr + this.yr) & 0xffff; addr = (addr + this.yr) & 0xffff;
var off = addr & 0xff; const off = addr & 0xff;
this.readByte(oldPage << 8 | off); this.readByte(oldPage << 8 | off);
this.writeByte(addr, val); this.writeByte(addr, val);
} }
// $00,X // $00,X
writeZeroPageX = (val: byte) => { writeZeroPageX = (val: byte) => {
var zpAddr = this.readBytePC(); const zpAddr = this.readBytePC();
this.readByte(zpAddr); this.readByte(zpAddr);
this.writeByte((zpAddr + this.xr) & 0xff, val); this.writeByte((zpAddr + this.xr) & 0xff, val);
} }
// $00,Y // $00,Y
writeZeroPageY = (val: byte) => { writeZeroPageY = (val: byte) => {
var zpAddr = this.readBytePC(); const zpAddr = this.readBytePC();
this.readByte(zpAddr); this.readByte(zpAddr);
this.writeByte((zpAddr + this.yr) & 0xff, val); this.writeByte((zpAddr + this.yr) & 0xff, val);
} }
// ($00,X) // ($00,X)
writeZeroPageXIndirect = (val: byte) => { writeZeroPageXIndirect = (val: byte) => {
var zpAddr = this.readBytePC(); const zpAddr = this.readBytePC();
this.readByte(zpAddr); this.readByte(zpAddr);
var addr = this.readZPWord((zpAddr + this.xr) & 0xff); const addr = this.readZPWord((zpAddr + this.xr) & 0xff);
this.writeByte(addr, val); this.writeByte(addr, val);
} }
// ($00),Y // ($00),Y
writeZeroPageIndirectY = (val: byte) => { writeZeroPageIndirectY = (val: byte) => {
var addr = this.readZPWord(this.readBytePC()), oldPage = addr >> 8; let addr = this.readZPWord(this.readBytePC());
const oldPage = addr >> 8;
addr = (addr + this.yr) & 0xffff; addr = (addr + this.yr) & 0xffff;
var off = addr & 0xff; const off = addr & 0xff;
this.readByte(oldPage << 8 | off); this.readByte(oldPage << 8 | off);
this.writeByte(addr, val); this.writeByte(addr, val);
} }
@ -524,7 +525,7 @@ export default class CPU6502 {
// $00,X // $00,X
readAddrZeroPageX = () => { readAddrZeroPageX = () => {
var zpAddr = this.readBytePC(); const zpAddr = this.readBytePC();
this.readByte(zpAddr); this.readByte(zpAddr);
return (zpAddr + this.xr) & 0xff; return (zpAddr + this.xr) & 0xff;
} }
@ -536,25 +537,25 @@ export default class CPU6502 {
// ($0000) (6502) // ($0000) (6502)
readAddrAbsoluteIndirectBug = (): word => { readAddrAbsoluteIndirectBug = (): word => {
var addr = this.readWordPC(); const addr = this.readWordPC();
var page = addr & 0xff00; const page = addr & 0xff00;
var off = addr & 0x00ff; const off = addr & 0x00ff;
var lsb = this.readByte(addr); const lsb = this.readByte(addr);
var msb = this.readByte(page | ((off + 0x01) & 0xff)); const msb = this.readByte(page | ((off + 0x01) & 0xff));
return msb << 8 | lsb; return msb << 8 | lsb;
} }
// ($0000) (65C02) // ($0000) (65C02)
readAddrAbsoluteIndirect = (): word => { readAddrAbsoluteIndirect = (): word => {
var lsb = this.readBytePC(); const lsb = this.readBytePC();
var msb = this.readBytePC(); const msb = this.readBytePC();
this.readByte(this.pc); this.readByte(this.pc);
return this.readWord(msb << 8 | lsb); return this.readWord(msb << 8 | lsb);
} }
// $0000,X // $0000,X
readAddrAbsoluteX = (opts: Opts = {}): word => { readAddrAbsoluteX = (opts: Opts = {}): word => {
var addr = this.readWordPC(); const addr = this.readWordPC();
if (!this.is65C02 || opts.rwm) { if (!this.is65C02 || opts.rwm) {
this.readByte(addr); this.readByte(addr);
} else { } else {
@ -565,7 +566,7 @@ export default class CPU6502 {
// $(0000,X) (65C02) // $(0000,X) (65C02)
readAddrAbsoluteXIndirect = (): word => { readAddrAbsoluteXIndirect = (): word => {
var address = this.readWordPC(); const address = this.readWordPC();
this.readByte(this.pc); this.readByte(this.pc);
return this.readWord((address + this.xr) & 0xffff); return this.readWord((address + this.xr) & 0xffff);
} }
@ -634,10 +635,10 @@ export default class CPU6502 {
} }
inc = (readAddrFn: ReadAddrFn) => { inc = (readAddrFn: ReadAddrFn) => {
var addr = readAddrFn({rwm: true}); const addr = readAddrFn({rwm: true});
var oldVal = this.readByte(addr); const oldVal = this.readByte(addr);
this.writeByte(addr, oldVal); this.writeByte(addr, oldVal);
var val = this.increment(oldVal); const val = this.increment(oldVal);
this.writeByte(addr, val); this.writeByte(addr, val);
} }
@ -660,10 +661,10 @@ export default class CPU6502 {
} }
dec = (readAddrFn: ReadAddrFn) => { dec = (readAddrFn: ReadAddrFn) => {
var addr = readAddrFn({rwm: true}); const addr = readAddrFn({rwm: true});
var oldVal = this.readByte(addr); const oldVal = this.readByte(addr);
this.writeByte(addr, oldVal); this.writeByte(addr, oldVal);
var val = this.decrement(oldVal); const val = this.decrement(oldVal);
this.writeByte(addr, val); this.writeByte(addr, val);
} }
@ -691,10 +692,10 @@ export default class CPU6502 {
} }
asl = (readAddrFn: ReadAddrFn) => { asl = (readAddrFn: ReadAddrFn) => {
var addr = readAddrFn({rwm: true}); const addr = readAddrFn({rwm: true});
var oldVal = this.readByte(addr); const oldVal = this.readByte(addr);
this.writeByte(addr, oldVal); this.writeByte(addr, oldVal);
var val = this.shiftLeft(oldVal); const val = this.shiftLeft(oldVal);
this.writeByte(addr, val); this.writeByte(addr, val);
} }
@ -710,15 +711,15 @@ export default class CPU6502 {
} }
lsr = (readAddrFn: ReadAddrFn) => { lsr = (readAddrFn: ReadAddrFn) => {
var addr = readAddrFn({rwm: true}); const addr = readAddrFn({rwm: true});
var oldVal = this.readByte(addr); const oldVal = this.readByte(addr);
this.writeByte(addr, oldVal); this.writeByte(addr, oldVal);
var val = this.shiftRight(oldVal); const val = this.shiftRight(oldVal);
this.writeByte(addr, val); this.writeByte(addr, val);
} }
rotateLeft = (val: byte) => { rotateLeft = (val: byte) => {
var c = (this.sr & flags.C); const c = (this.sr & flags.C);
this.setFlag(flags.C, !!(val & 0x80)); this.setFlag(flags.C, !!(val & 0x80));
return this.testNZ(((val << 1) | (c ? 0x01 : 0x00)) & 0xff); return this.testNZ(((val << 1) | (c ? 0x01 : 0x00)) & 0xff);
} }
@ -730,15 +731,15 @@ export default class CPU6502 {
} }
rol = (readAddrFn: ReadAddrFn) => { rol = (readAddrFn: ReadAddrFn) => {
var addr = readAddrFn({rwm: true}); const addr = readAddrFn({rwm: true});
var oldVal = this.readByte(addr); const oldVal = this.readByte(addr);
this.writeByte(addr, oldVal); this.writeByte(addr, oldVal);
var val = this.rotateLeft(oldVal); const val = this.rotateLeft(oldVal);
this.writeByte(addr, val); this.writeByte(addr, val);
} }
private rotateRight(a: byte) { private rotateRight(a: byte) {
var c = (this.sr & flags.C); const c = (this.sr & flags.C);
this.setFlag(flags.C, !!(a & 0x01)); this.setFlag(flags.C, !!(a & 0x01));
return this.testNZ((a >> 1) | (c ? 0x80 : 0x00)); return this.testNZ((a >> 1) | (c ? 0x80 : 0x00));
} }
@ -750,10 +751,10 @@ export default class CPU6502 {
} }
ror = (readAddrFn: ReadAddrFn) => { ror = (readAddrFn: ReadAddrFn) => {
var addr = readAddrFn({rwm: true}); const addr = readAddrFn({rwm: true});
var oldVal = this.readByte(addr); const oldVal = this.readByte(addr);
this.writeByte(addr, oldVal); this.writeByte(addr, oldVal);
var val = this.rotateRight(oldVal); const val = this.rotateRight(oldVal);
this.writeByte(addr, val); this.writeByte(addr, val);
} }
@ -775,9 +776,9 @@ export default class CPU6502 {
/* Reset Bit */ /* Reset Bit */
rmb = (b: byte) => { rmb = (b: byte) => {
var bit = (0x1 << b) ^ 0xFF; const bit = (0x1 << b) ^ 0xFF;
var addr = this.readBytePC(); const addr = this.readBytePC();
var val = this.readByte(addr); let val = this.readByte(addr);
this.readByte(addr); this.readByte(addr);
val &= bit; val &= bit;
this.writeByte(addr, val); this.writeByte(addr, val);
@ -786,9 +787,9 @@ export default class CPU6502 {
/* Set Bit */ /* Set Bit */
smb = (b: byte) => { smb = (b: byte) => {
var bit = 0x1 << b; const bit = 0x1 << b;
var addr = this.readBytePC(); const addr = this.readBytePC();
var val = this.readByte(addr); let val = this.readByte(addr);
this.readByte(addr); this.readByte(addr);
val |= bit; val |= bit;
this.writeByte(addr, val); this.writeByte(addr, val);
@ -796,8 +797,8 @@ export default class CPU6502 {
/* Test and Reset Bits */ /* Test and Reset Bits */
trb = (readAddrFn: ReadAddrFn) => { trb = (readAddrFn: ReadAddrFn) => {
var addr = readAddrFn(); const addr = readAddrFn();
var val = this.readByte(addr); const val = this.readByte(addr);
this.testZ(val & this.ar); this.testZ(val & this.ar);
this.readByte(addr); this.readByte(addr);
this.writeByte(addr, val & ~this.ar); this.writeByte(addr, val & ~this.ar);
@ -805,8 +806,8 @@ export default class CPU6502 {
/* Test and Set Bits */ /* Test and Set Bits */
tsb = (readAddrFn: ReadAddrFn) => { tsb = (readAddrFn: ReadAddrFn) => {
var addr = readAddrFn(); const addr = readAddrFn();
var val = this.readByte(addr); const val = this.readByte(addr);
this.testZ(val & this.ar); this.testZ(val & this.ar);
this.readByte(addr); this.readByte(addr);
this.writeByte(addr, val | this.ar); this.writeByte(addr, val | this.ar);
@ -814,7 +815,7 @@ export default class CPU6502 {
/* Bit */ /* Bit */
bit = (readFn: ReadFn) => { bit = (readFn: ReadFn) => {
var val = readFn(); const val = readFn();
this.setFlag(flags.Z, (val & this.ar) === 0); this.setFlag(flags.Z, (val & this.ar) === 0);
this.setFlag(flags.N, !!(val & 0x80)); this.setFlag(flags.N, !!(val & 0x80));
this.setFlag(flags.V, !!(val & 0x40)); this.setFlag(flags.V, !!(val & 0x40));
@ -822,13 +823,13 @@ export default class CPU6502 {
/* Bit Immediate*/ /* Bit Immediate*/
bitI = (readFn: ReadFn) => { bitI = (readFn: ReadFn) => {
var val = readFn(); const val = readFn();
this.setFlag(flags.Z, (val & this.ar) === 0); this.setFlag(flags.Z, (val & this.ar) === 0);
} }
private compare(a: byte, b: byte) { private compare(a: byte, b: byte) {
b = (b ^ 0xff); b = (b ^ 0xff);
var c = a + b + 1; const c = a + b + 1;
this.setFlag(flags.C, c > 0xff); this.setFlag(flags.C, c > 0xff);
this.testNZ(c & 0xff); this.testNZ(c & 0xff);
} }
@ -847,61 +848,61 @@ export default class CPU6502 {
/* Branches */ /* Branches */
brs = (f: flag) => { brs = (f: flag) => {
let off = this.readBytePC(); // changes pc const off = this.readBytePC(); // changes pc
if ((f & this.sr) !== 0) { if ((f & this.sr) !== 0) {
this.readByte(this.pc); this.readByte(this.pc);
let oldPage = this.pc >> 8; const oldPage = this.pc >> 8;
this.pc += off > 127 ? off - 256 : off; this.pc += off > 127 ? off - 256 : off;
let newPage = this.pc >> 8; const newPage = this.pc >> 8;
let newOff = this.pc & 0xff; const newOff = this.pc & 0xff;
if (newPage != oldPage) this.readByte(oldPage << 8 | newOff); if (newPage != oldPage) this.readByte(oldPage << 8 | newOff);
} }
} }
brc = (f: flag) => { brc = (f: flag) => {
let off = this.readBytePC(); // changes pc const off = this.readBytePC(); // changes pc
if ((f & this.sr) === 0) { if ((f & this.sr) === 0) {
this.readByte(this.pc); this.readByte(this.pc);
let oldPage = this.pc >> 8; const oldPage = this.pc >> 8;
this.pc += off > 127 ? off - 256 : off; this.pc += off > 127 ? off - 256 : off;
let newPage = this.pc >> 8; const newPage = this.pc >> 8;
let newOff = this.pc & 0xff; const newOff = this.pc & 0xff;
if (newPage != oldPage) this.readByte(oldPage << 8 | newOff); if (newPage != oldPage) this.readByte(oldPage << 8 | newOff);
} }
} }
/* WDC 65C02 branches */ /* WDC 65C02 branches */
bbr = (b: flag) => { bbr = (b: byte) => {
let zpAddr = this.readBytePC(); const zpAddr = this.readBytePC();
let val = this.readByte(zpAddr); const val = this.readByte(zpAddr);
this.readByte(zpAddr); this.readByte(zpAddr);
let off = this.readBytePC(); // changes pc const off = this.readBytePC(); // changes pc
if (((1 << b) & val) === 0) { if (((1 << b) & val) === 0) {
let oldPc = this.pc; const oldPc = this.pc;
let oldPage = oldPc >> 8; const oldPage = oldPc >> 8;
this.readByte(oldPc); this.readByte(oldPc);
this.pc += off > 127 ? off - 256 : off; this.pc += off > 127 ? off - 256 : off;
let newPage = this.pc >> 8; const newPage = this.pc >> 8;
if (oldPage != newPage) { if (oldPage != newPage) {
this.readByte(oldPc); this.readByte(oldPc);
} }
} }
} }
bbs = (b: flag) => { bbs = (b: byte) => {
let zpAddr = this.readBytePC(); const zpAddr = this.readBytePC();
let val = this.readByte(zpAddr); const val = this.readByte(zpAddr);
this.readByte(zpAddr); this.readByte(zpAddr);
let off = this.readBytePC(); // changes pc const off = this.readBytePC(); // changes pc
if (((1 << b) & val) !== 0) { if (((1 << b) & val) !== 0) {
let oldPc = this.pc; const oldPc = this.pc;
let oldPage = oldPc >> 8; const oldPage = oldPc >> 8;
this.readByte(oldPc); this.readByte(oldPc);
this.pc += off > 127 ? off - 256 : off; this.pc += off > 127 ? off - 256 : off;
let newPage = this.pc >> 8; const newPage = this.pc >> 8;
if (oldPage != newPage) { if (oldPage != newPage) {
this.readByte(oldPc); this.readByte(oldPc);
} }
@ -944,10 +945,10 @@ export default class CPU6502 {
/* Jump Subroutine */ /* Jump Subroutine */
jsr = () => { jsr = () => {
let lsb = this.readBytePC(); const lsb = this.readBytePC();
this.readByte(0x0100 | this.sp); this.readByte(0x0100 | this.sp);
this.pushWord(this.pc); this.pushWord(this.pc);
let msb = this.readBytePC(); const msb = this.readBytePC();
this.pc = (msb << 8 | lsb) & 0xffff; this.pc = (msb << 8 | lsb) & 0xffff;
} }
@ -955,7 +956,7 @@ export default class CPU6502 {
rts = () => { rts = () => {
this.readByte(this.pc); this.readByte(this.pc);
this.readByte(0x0100 | this.sp); this.readByte(0x0100 | this.sp);
let addr = this.pullWordRaw(); const addr = this.pullWordRaw();
this.readByte(addr); this.readByte(addr);
this.pc = (addr + 1) & 0xffff; this.pc = (addr + 1) & 0xffff;
} }
@ -994,17 +995,17 @@ export default class CPU6502 {
op: this.nop, op: this.nop,
modeFn: this.implied, modeFn: this.implied,
mode: 'implied', mode: 'implied',
} };
} else { } else {
unk = { unk = {
name: '???', name: '???',
op: function() { op: function() {
debug('Unknown OpCode: ' + toHex(b) + debug('Unknown OpCode: ' + toHex(b) +
' at ' + toHex(this.pc - 1, 4)); ' at ' + toHex(this.pc - 1, 4));
}, },
modeFn: this.implied, modeFn: this.implied,
mode: 'implied' mode: 'implied'
} };
} }
this.ops[b] = unk; this.ops[b] = unk;
return unk; return unk;
@ -1019,6 +1020,7 @@ export default class CPU6502 {
} }
} }
let off, val;
let result = ''; let result = '';
switch (m) { switch (m) {
case 'implied': case 'implied':
@ -1073,8 +1075,8 @@ export default class CPU6502 {
result = '(' + toHexOrSymbol(this.readWordDebug(addr), 4) + ',X)'; result = '(' + toHexOrSymbol(this.readWordDebug(addr), 4) + ',X)';
break; break;
case 'zeroPage_relative': case 'zeroPage_relative':
let val = this.readByteDebug(addr); val = this.readByteDebug(addr);
let off = this.readByteDebug(addr + 1); off = this.readByteDebug(addr + 1);
if (off > 127) { if (off > 127) {
off -= 256; off -= 256;
} }
@ -1089,7 +1091,7 @@ export default class CPU6502 {
public step(cb: callback) { public step(cb: callback) {
this.sync = true; this.sync = true;
let op = this.opary[this.readBytePC()]; const op = this.opary[this.readBytePC()];
this.sync = false; this.sync = false;
op.op(op.modeFn); op.op(op.modeFn);
@ -1101,7 +1103,7 @@ export default class CPU6502 {
public stepDebug(n: number, cb: callback) { public stepDebug(n: number, cb: callback) {
for (let idx = 0; idx < n; idx++) { for (let idx = 0; idx < n; idx++) {
this.sync = true; this.sync = true;
let op = this.opary[this.readBytePC()]; const op = this.opary[this.readBytePC()];
this.sync = false; this.sync = false;
op.op(op.modeFn); op.op(op.modeFn);
@ -1112,22 +1114,22 @@ export default class CPU6502 {
} }
public stepCycles(c: number) { public stepCycles(c: number) {
let end = this.cycles + c; const end = this.cycles + c;
while (this.cycles < end) { while (this.cycles < end) {
this.sync = true; this.sync = true;
let op = this.opary[this.readBytePC()]; const op = this.opary[this.readBytePC()];
this.sync = false; this.sync = false;
op.op(op.modeFn); op.op(op.modeFn);
} }
} }
public stepCyclesDebug(c: number, cb: callback): void { public stepCyclesDebug(c: number, cb: callback): void {
var op, end = this.cycles + c; const end = this.cycles + c;
while (this.cycles < end) { while (this.cycles < end) {
this.sync = true; this.sync = true;
op = this.opary[this.readBytePC()]; const op = this.opary[this.readBytePC()];
this.sync = false; this.sync = false;
op.op(op.modeFn); op.op(op.modeFn);
@ -1198,10 +1200,10 @@ export default class CPU6502 {
if (pc === undefined) { if (pc === undefined) {
pc = this.pc; pc = this.pc;
} }
let b = this.readByte(pc), const b = this.readByte(pc),
op = this.ops[b], op = this.ops[b],
size = sizes[op.mode], size = sizes[op.mode];
result = toHex(pc, 4) + '- '; let result = toHex(pc, 4) + '- ';
if (symbols) { if (symbols) {
if (symbols[pc]) { if (symbols[pc]) {
@ -1212,7 +1214,7 @@ export default class CPU6502 {
} }
} }
for (var idx = 0; idx < 4; idx++) { for (let idx = 0; idx < 4; idx++) {
if (idx < size) { if (idx < size) {
result += toHex(this.readByte(pc + idx)) + ' '; result += toHex(this.readByte(pc + idx)) + ' ';
} else { } else {
@ -1229,24 +1231,23 @@ export default class CPU6502 {
} }
public dumpPage(start?: word, end?: word) { public dumpPage(start?: word, end?: word) {
var result = ''; let result = '';
if (start === undefined) { if (start === undefined) {
start = this.pc >> 8; start = this.pc >> 8;
} }
if (end === undefined) { if (end === undefined) {
end = start; end = start;
} }
for (var page = start; page <= end; page++) { for (let page = start; page <= end; page++) {
var b, idx, jdx; for (let idx = 0; idx < 16; idx++) {
for (idx = 0; idx < 16; idx++) {
result += toHex(page) + toHex(idx << 4) + ': '; result += toHex(page) + toHex(idx << 4) + ': ';
for (jdx = 0; jdx < 16; jdx++) { for (let jdx = 0; jdx < 16; jdx++) {
b = this.readByteDebug(page * 256 + idx * 16 + jdx); const b = this.readByteDebug(page * 256 + idx * 16 + jdx);
result += toHex(b) + ' '; result += toHex(b) + ' ';
} }
result += ' '; result += ' ';
for (jdx = 0; jdx < 16; jdx++) { for (let jdx = 0; jdx < 16; jdx++) {
b = this.readByte(page * 256 + idx * 16 + jdx) & 0x7f; const b = this.readByte(page * 256 + idx * 16 + jdx) & 0x7f;
if (b >= 0x20 && b < 0x7f) { if (b >= 0x20 && b < 0x7f) {
result += String.fromCharCode(b); result += String.fromCharCode(b);
} else { } else {
@ -1263,9 +1264,9 @@ export default class CPU6502 {
if (_pc === undefined) { if (_pc === undefined) {
_pc = this.pc; _pc = this.pc;
} }
var results = []; const results = [];
for (var jdx = 0; jdx < 20; jdx++) { for (let jdx = 0; jdx < 20; jdx++) {
var b = this.readByte(_pc), op = this.ops[b]; const b = this.readByte(_pc), op = this.ops[b];
results.push(this.dumpPC(_pc, symbols)); results.push(this.dumpPC(_pc, symbols));
_pc += sizes[op.mode]; _pc += sizes[op.mode];
} }
@ -1281,7 +1282,7 @@ export default class CPU6502 {
} }
public registers() { public registers() {
return [this.pc,this.ar,this.xr,this.yr,this.sr,this.sp]; return [this.pc,this.ar,this.xr,this.yr,this.sr,this.sp];
} }
public getState(): CpuState { public getState(): CpuState {
@ -1600,7 +1601,7 @@ export default class CPU6502 {
0x00: { name: 'BRK', op: this.brk, modeFn: this.readImmediate, mode: 'immediate' } 0x00: { name: 'BRK', op: this.brk, modeFn: this.readImmediate, mode: 'immediate' }
}; };
/* 65C02 Instructions */ /* 65C02 Instructions */
OPS_65C02: Instructions = { OPS_65C02: Instructions = {
// INC / DEC A // INC / DEC A
@ -1714,4 +1715,4 @@ export default class CPU6502 {
0x04: { name: 'TSB', op: this.tsb, modeFn: this.readAddrZeroPage, mode: 'zeroPage' }, 0x04: { name: 'TSB', op: this.tsb, modeFn: this.readAddrZeroPage, mode: 'zeroPage' },
0x0C: { name: 'TSB', op: this.tsb, modeFn: this.readAddrAbsolute, mode: 'absolute' } 0x0C: { name: 'TSB', op: this.tsb, modeFn: this.readAddrAbsolute, mode: 'absolute' }
} }
}; }

View File

@ -10,7 +10,7 @@
*/ */
import { base64_decode, base64_encode } from './base64'; import { base64_decode, base64_encode } from './base64';
import { byte, memory } from './types'; import { byte } from './types';
import { allocMemPages } from './util'; import { allocMemPages } from './util';
export interface State { export interface State {
@ -20,7 +20,7 @@ export interface State {
end: byte; end: byte;
/** Base64-encoded contents. */ /** Base64-encoded contents. */
mem: string; mem: string;
}; }
/** /**
* Represents RAM from the start page `sp` to end page `ep`. The memory * Represents RAM from the start page `sp` to end page `ep`. The memory

View File

@ -15,7 +15,7 @@ export interface Drive {
volume: number, volume: number,
tracks: Array<byte[] | Uint8Array>, tracks: Array<byte[] | Uint8Array>,
trackMap: unknown, trackMap: unknown,
}; }
export interface DiskIIDrive extends Drive { export interface DiskIIDrive extends Drive {
rawTracks: unknown, rawTracks: unknown,
@ -24,4 +24,4 @@ export interface DiskIIDrive extends Drive {
phase: number, phase: number,
readOnly: boolean, readOnly: boolean,
dirty: boolean, dirty: boolean,
}; }

View File

@ -766,11 +766,11 @@ export function openOptions() {
} }
export function openPrinterModal() { export function openPrinterModal() {
let mimeType = 'application/octet-stream'; const mimeType = 'application/octet-stream';
let data = _printer.getRawOutput(); const data = _printer.getRawOutput();
let a = document.querySelector('#raw_printer_output'); const a = document.querySelector('#raw_printer_output');
let blob = new Blob([data], { 'type': mimeType}); const blob = new Blob([data], { 'type': mimeType});
a.href = window.URL.createObjectURL(blob); a.href = window.URL.createObjectURL(blob);
a.download = 'raw_printer_output.bin'; a.download = 'raw_printer_output.bin';
MicroModal.show('printer-modal'); MicroModal.show('printer-modal');

View File

@ -61,7 +61,7 @@ export default function Printer(el) {
_raw[_rawLen] = val; _raw[_rawLen] = val;
_rawLen++; _rawLen++;
if (_rawLen > _raw.length) { if (_rawLen > _raw.length) {
let newRaw = new Uint8Array(_raw.length * 2); const newRaw = new Uint8Array(_raw.length * 2);
newRaw.set(_raw); newRaw.set(_raw);
_raw = newRaw; _raw = newRaw;
} }

View File

@ -5,11 +5,11 @@
* the above copyright notice appear in all copies and that both that * the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting * copyright notice and this permission notice appear in supporting
* documentation. No representations are made about the suitability of this * documentation. No representations are made about the suitability of this
* software for any purpose. It is provided "as is" without express or * software for any purpose. It is provided ' as is' without express or
* implied warranty. * implied warranty.
*/ */
import { byte, memory, word } from "./types"; import { byte, memory, word } from './types';
/*eslint no-console: 0*/ /*eslint no-console: 0*/
@ -36,7 +36,7 @@ export function allocMem(size: number) {
} else { } else {
result = new Array(size); result = new Array(size);
} }
for (let idx = 0; idx < size; idx++) { for (let idx = 0; idx < size; idx++) {
result[idx] = (idx & 0x02) ? 0x00 : 0xff; result[idx] = (idx & 0x02) ? 0x00 : 0xff;
} }
@ -65,9 +65,8 @@ export function bytify(ary: number[]): memory {
} }
/** Writes to the console. */ /** Writes to the console. */
export function debug(...args: any[]): void; export function debug(...args: any[]): void {
export function debug() { console.log.apply(console, ...args);
console.log.apply(console, arguments);
} }
/** /**
@ -80,8 +79,8 @@ export function toHex(v: byte | word | number, n?: number) {
if (!n) { if (!n) {
n = v < 256 ? 2 : 4; n = v < 256 ? 2 : 4;
} }
var result = ''; let result = '';
for (var idx = 0; idx < n; idx++) { for (let idx = 0; idx < n; idx++) {
result = hex_digits[v & 0x0f] + result; result = hex_digits[v & 0x0f] + result;
v >>= 4; v >>= 4;
} }
@ -93,8 +92,8 @@ export function toHex(v: byte | word | number, n?: number) {
* @param v the value to encode * @param v the value to encode
*/ */
export function toBinary(v: byte) { export function toBinary(v: byte) {
var result = ''; let result = '';
for (var idx = 0; idx < 8; idx++) { for (let idx = 0; idx < 8; idx++) {
result = bin_digits[v & 0x01] + result; result = bin_digits[v & 0x01] + result;
v >>= 1; v >>= 1;
} }
@ -110,9 +109,9 @@ export function toBinary(v: byte) {
// From http://www.netlobo.com/url_query_string_javascript.html // From http://www.netlobo.com/url_query_string_javascript.html
export function gup(name: string) { export function gup(name: string) {
name = name.replace(/[[]/, '\\[').replace(/[\]]/, '\\]'); name = name.replace(/[[]/, '\\[').replace(/[\]]/, '\\]');
var regexS = '[\\?&]' + name + '=([^&#]*)'; const regexS = '[\\?&]' + name + '=([^&#]*)';
var regex = new RegExp(regexS); const regex = new RegExp(regexS);
var results = regex.exec(window.location.href); const results = regex.exec(window.location.href);
if (!results) if (!results)
return ''; return '';
else else
@ -121,8 +120,8 @@ export function gup(name: string) {
/** Returns the URL fragment. */ /** Returns the URL fragment. */
export function hup() { export function hup() {
var regex = new RegExp('#(.*)'); const regex = new RegExp('#(.*)');
var results = regex.exec(window.location.hash); const results = regex.exec(window.location.hash);
if (!results) if (!results)
return ''; return '';
else else

247
package-lock.json generated
View File

@ -2209,6 +2209,32 @@
} }
} }
}, },
"@nodelib/fs.scandir": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
"integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
"dev": true,
"requires": {
"@nodelib/fs.stat": "2.0.3",
"run-parallel": "^1.1.9"
}
},
"@nodelib/fs.stat": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
"integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
"dev": true
},
"@nodelib/fs.walk": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
"integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
"dev": true,
"requires": {
"@nodelib/fs.scandir": "2.1.3",
"fastq": "^1.6.0"
}
},
"@sinonjs/commons": { "@sinonjs/commons": {
"version": "1.8.1", "version": "1.8.1",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz",
@ -2319,6 +2345,12 @@
"pretty-format": "^25.2.1" "pretty-format": "^25.2.1"
} }
}, },
"@types/json-schema": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz",
"integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
"dev": true
},
"@types/minimatch": { "@types/minimatch": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@ -2364,6 +2396,156 @@
"integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==",
"dev": true "dev": true
}, },
"@typescript-eslint/eslint-plugin": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.6.1.tgz",
"integrity": "sha512-SNZyflefTMK2JyrPfFFzzoy2asLmZvZJ6+/L5cIqg4HfKGiW2Gr1Go1OyEVqne/U4QwmoasuMwppoBHWBWF2nA==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "4.6.1",
"@typescript-eslint/scope-manager": "4.6.1",
"debug": "^4.1.1",
"functional-red-black-tree": "^1.0.1",
"regexpp": "^3.0.0",
"semver": "^7.3.2",
"tsutils": "^3.17.1"
},
"dependencies": {
"regexpp": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
"integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
"dev": true
},
"semver": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
"dev": true
}
}
},
"@typescript-eslint/experimental-utils": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.6.1.tgz",
"integrity": "sha512-qyPqCFWlHZXkEBoV56UxHSoXW2qnTr4JrWVXOh3soBP3q0o7p4pUEMfInDwIa0dB/ypdtm7gLOS0hg0a73ijfg==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.3",
"@typescript-eslint/scope-manager": "4.6.1",
"@typescript-eslint/types": "4.6.1",
"@typescript-eslint/typescript-estree": "4.6.1",
"eslint-scope": "^5.0.0",
"eslint-utils": "^2.0.0"
},
"dependencies": {
"eslint-utils": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
"integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^1.1.0"
}
}
}
},
"@typescript-eslint/parser": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.6.1.tgz",
"integrity": "sha512-lScKRPt1wM9UwyKkGKyQDqf0bh6jm8DQ5iN37urRIXDm16GEv+HGEmum2Fc423xlk5NUOkOpfTnKZc/tqKZkDQ==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "4.6.1",
"@typescript-eslint/types": "4.6.1",
"@typescript-eslint/typescript-estree": "4.6.1",
"debug": "^4.1.1"
}
},
"@typescript-eslint/scope-manager": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.6.1.tgz",
"integrity": "sha512-f95+80r6VdINYscJY1KDUEDcxZ3prAWHulL4qRDfNVD0I5QAVSGqFkwHERDoLYJJWmEAkUMdQVvx7/c2Hp+Bjg==",
"dev": true,
"requires": {
"@typescript-eslint/types": "4.6.1",
"@typescript-eslint/visitor-keys": "4.6.1"
}
},
"@typescript-eslint/types": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.6.1.tgz",
"integrity": "sha512-k2ZCHhJ96YZyPIsykickez+OMHkz06xppVLfJ+DY90i532/Cx2Z+HiRMH8YZQo7a4zVd/TwNBuRCdXlGK4yo8w==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.6.1.tgz",
"integrity": "sha512-/J/kxiyjQQKqEr5kuKLNQ1Finpfb8gf/NpbwqFFYEBjxOsZ621r9AqwS9UDRA1Rrr/eneX/YsbPAIhU2rFLjXQ==",
"dev": true,
"requires": {
"@typescript-eslint/types": "4.6.1",
"@typescript-eslint/visitor-keys": "4.6.1",
"debug": "^4.1.1",
"globby": "^11.0.1",
"is-glob": "^4.0.1",
"lodash": "^4.17.15",
"semver": "^7.3.2",
"tsutils": "^3.17.1"
},
"dependencies": {
"array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
"dev": true
},
"globby": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
"integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==",
"dev": true,
"requires": {
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
"fast-glob": "^3.1.1",
"ignore": "^5.1.4",
"merge2": "^1.3.0",
"slash": "^3.0.0"
}
},
"ignore": {
"version": "5.1.8",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
"dev": true
},
"semver": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
"dev": true
}
}
},
"@typescript-eslint/visitor-keys": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.6.1.tgz",
"integrity": "sha512-owABze4toX7QXwOLT3/D5a8NecZEjEWU1srqxENTfqsY3bwVnl3YYbOh6s1rp2wQKO9RTHFGjKes08FgE7SVMw==",
"dev": true,
"requires": {
"@typescript-eslint/types": "4.6.1",
"eslint-visitor-keys": "^2.0.0"
},
"dependencies": {
"eslint-visitor-keys": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz",
"integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==",
"dev": true
}
}
},
"@webassemblyjs/ast": { "@webassemblyjs/ast": {
"version": "1.8.5", "version": "1.8.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
@ -4784,6 +4966,15 @@
"randombytes": "^2.0.0" "randombytes": "^2.0.0"
} }
}, },
"dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
"dev": true,
"requires": {
"path-type": "^4.0.0"
}
},
"dns-equal": { "dns-equal": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
@ -5536,6 +5727,20 @@
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
"dev": true "dev": true
}, },
"fast-glob": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
"integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==",
"dev": true,
"requires": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
"glob-parent": "^5.1.0",
"merge2": "^1.3.0",
"micromatch": "^4.0.2",
"picomatch": "^2.2.1"
}
},
"fast-json-stable-stringify": { "fast-json-stable-stringify": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
@ -5548,6 +5753,15 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true "dev": true
}, },
"fastq": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz",
"integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==",
"dev": true,
"requires": {
"reusify": "^1.0.4"
}
},
"faye-websocket": { "faye-websocket": {
"version": "0.10.0", "version": "0.10.0",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
@ -9606,6 +9820,12 @@
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"dev": true "dev": true
}, },
"merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"dev": true
},
"methods": { "methods": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@ -10355,6 +10575,12 @@
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
"dev": true "dev": true
}, },
"path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true
},
"pbkdf2": { "pbkdf2": {
"version": "3.0.17", "version": "3.0.17",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
@ -11302,6 +11528,12 @@
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
"dev": true "dev": true
}, },
"reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
"dev": true
},
"rimraf": { "rimraf": {
"version": "2.6.3", "version": "2.6.3",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
@ -11336,6 +11568,12 @@
"is-promise": "^2.1.0" "is-promise": "^2.1.0"
} }
}, },
"run-parallel": {
"version": "1.1.10",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz",
"integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==",
"dev": true
},
"run-queue": { "run-queue": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
@ -12768,6 +13006,15 @@
"integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==",
"dev": true "dev": true
}, },
"tsutils": {
"version": "3.17.1",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
"integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==",
"dev": true,
"requires": {
"tslib": "^1.8.1"
}
},
"tty-browserify": { "tty-browserify": {
"version": "0.0.0", "version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",

View File

@ -6,7 +6,7 @@
"build": "webpack --mode=production", "build": "webpack --mode=production",
"dev": "webpack-dev-server", "dev": "webpack-dev-server",
"index": "bin/index > json/disks/index.js", "index": "bin/index > json/disks/index.js",
"lint": "eslint .", "lint": "eslint '**/*.js' '**/*.ts'",
"start": "webpack-dev-server", "start": "webpack-dev-server",
"test": "jest" "test": "jest"
}, },
@ -27,6 +27,8 @@
"@babel/core": "^7.9.0", "@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.0", "@babel/preset-env": "^7.9.0",
"@types/jest": "^26.0.14", "@types/jest": "^26.0.14",
"@typescript-eslint/eslint-plugin": "^4.6.1",
"@typescript-eslint/parser": "^4.6.1",
"ajv": "^6.12.0", "ajv": "^6.12.0",
"babel-jest": "^25.1.0", "babel-jest": "^25.1.0",
"eslint": "^6.8.0", "eslint": "^6.8.0",

View File

@ -11,7 +11,7 @@ describe('CPU', function () {
let done = false; let done = false;
function traceCB() { function traceCB() {
var pc = cpu.getPC(); const pc = cpu.getPC();
done = lastPC == pc; done = lastPC == pc;
lastPC = pc; lastPC = pc;
} }
@ -19,7 +19,7 @@ describe('CPU', function () {
describe('6502', function () { describe('6502', function () {
it('completes the test ROM', function () { it('completes the test ROM', function () {
cpu = new CPU6502(); cpu = new CPU6502();
var test = new Test6502(); const test = new Test6502();
cpu.addPageHandler(test); cpu.addPageHandler(test);
cpu.setPC(0x400); cpu.setPC(0x400);
@ -34,7 +34,7 @@ describe('CPU', function () {
describe('65C02', function () { describe('65C02', function () {
it('completes the test ROM', function () { it('completes the test ROM', function () {
cpu = new CPU6502({'65C02': true}); cpu = new CPU6502({'65C02': true});
var test = new Test65C02(); const test = new Test65C02();
cpu.addPageHandler(test); cpu.addPageHandler(test);
cpu.setPC(0x400); cpu.setPC(0x400);

View File

@ -1,99 +1,99 @@
/** @fileoverview Test for utils.ts. */ /** @fileoverview Test for utils.ts. */
import { allocMem, allocMemPages, numToString, testables, toBinary, toHex } from "../../js/util"; import { allocMem, allocMemPages, numToString, testables, toBinary, toHex } from '../../js/util';
describe('garbage', () => { describe('garbage', () => {
it('returns 0 <= x <= 255', () => { it('returns 0 <= x <= 255', () => {
for (let i = 0; i < 1024; i++) { for (let i = 0; i < 1024; i++) {
expect(testables.garbage()).toBeGreaterThanOrEqual(0); expect(testables.garbage()).toBeGreaterThanOrEqual(0);
} }
}); });
}); });
describe('allocMem', () => { describe('allocMem', () => {
it('returns an array of the correct size', () => { it('returns an array of the correct size', () => {
expect(allocMem(2048).length).toBe(2048); expect(allocMem(2048).length).toBe(2048);
}); });
it('has 0xff and 0x00 patterns', () => { it('has 0xff and 0x00 patterns', () => {
let memory = allocMem(2048); const memory = allocMem(2048);
expect(memory[0]).toBe(0xff); expect(memory[0]).toBe(0xff);
expect(memory[1]).toBe(0xff); expect(memory[1]).toBe(0xff);
expect(memory[2]).toBe(0x00); expect(memory[2]).toBe(0x00);
expect(memory[3]).toBe(0x00); expect(memory[3]).toBe(0x00);
expect(memory[4]).toBe(0xff); expect(memory[4]).toBe(0xff);
}); });
it('has garbage in the right places', () => { it('has garbage in the right places', () => {
let memory = allocMem(0x800); const memory = allocMem(0x800);
for (let i = 0; i < 0x800; i += 0x200) { for (let i = 0; i < 0x800; i += 0x200) {
let passed = memory[i + 0x28] != 0xff const passed = memory[i + 0x28] != 0xff
&& memory[i + 0x29] != 0xff && memory[i + 0x29] != 0xff
&& memory[i + 0x68] != 0xff && memory[i + 0x68] != 0xff
&& memory[i + 0x69] != 0xff; && memory[i + 0x69] != 0xff;
if (passed) { if (passed) {
return; return;
} }
} }
fail('garbage not found'); fail('garbage not found');
}); });
}); });
describe('allocMemPages', () => { describe('allocMemPages', () => {
it('allocates 256 * the size', () => { it('allocates 256 * the size', () => {
expect(allocMemPages(5).length).toBe(5 * 256); expect(allocMemPages(5).length).toBe(5 * 256);
}); });
}); });
describe('toHex', () => { describe('toHex', () => {
it('converts an odd number of characters', () => { it('converts an odd number of characters', () => {
expect(toHex(0xfedcb, 5)).toEqual("FEDCB"); expect(toHex(0xfedcb, 5)).toEqual('FEDCB');
}); });
it('correctly guesses byte values', () => { it('correctly guesses byte values', () => {
expect(toHex(0xa5)).toEqual("A5"); expect(toHex(0xa5)).toEqual('A5');
}); });
it('correctly guesses word values', () => { it('correctly guesses word values', () => {
expect(toHex(0x1abc)).toEqual("1ABC"); expect(toHex(0x1abc)).toEqual('1ABC');
}); });
it('only uses the bottom work of larger values', () => { it('only uses the bottom work of larger values', () => {
expect(toHex(0xabcdef)).toEqual("CDEF"); expect(toHex(0xabcdef)).toEqual('CDEF');
}); });
it('correctly prepends zeros', () => { it('correctly prepends zeros', () => {
expect(toHex(0xa5, 4)).toEqual("00A5"); expect(toHex(0xa5, 4)).toEqual('00A5');
}); });
}); });
describe('toBinary', () => { describe('toBinary', () => {
it('has 8 digits for zero', () => { it('has 8 digits for zero', () => {
expect(toBinary(0x00)).toEqual("00000000"); expect(toBinary(0x00)).toEqual('00000000');
}); });
it('correctly sets bits', () => { it('correctly sets bits', () => {
expect(toBinary(0xa5)).toEqual("10100101"); expect(toBinary(0xa5)).toEqual('10100101');
}); });
}); });
describe('gup', () => { describe('gup', () => {
// untestable due to direct reference to window.location // untestable due to direct reference to window.location
}); });
describe('hup', () => { describe('hup', () => {
// untestable due to direct reference to window.location // untestable due to direct reference to window.location
}); });
describe('numToString', () => { describe('numToString', () => {
it('packs a zero byte into a string of all zeros', () => { it('packs a zero byte into a string of all zeros', () => {
expect(numToString(0x00)).toEqual("\0\0\0\0"); expect(numToString(0x00)).toEqual('\0\0\0\0');
});
it('packs a byte in the printable ASCII range into a zero-padded string',
() => {
expect(numToString(0x41)).toEqual("A\0\0\0");
}); });
it('packs a word into a string', () => { it('packs a byte in the printable ASCII range into a zero-padded string',
expect(numToString(0x4142)).toEqual("BA\0\0"); () => {
}); expect(numToString(0x41)).toEqual('A\0\0\0');
it('packs a 32-bit value into a string', () => { });
expect(numToString(0x41424344)).toEqual("DCBA"); it('packs a word into a string', () => {
}); expect(numToString(0x4142)).toEqual('BA\0\0');
it('ignores more than 32 bits', () => { });
expect(numToString(0x4142434445)).toEqual("EDCB"); it('packs a 32-bit value into a string', () => {
}); expect(numToString(0x41424344)).toEqual('DCBA');
}); });
it('ignores more than 32 bits', () => {
expect(numToString(0x4142434445)).toEqual('EDCB');
});
});

View File

@ -2,13 +2,16 @@
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { PageHandler } from '../../js/cpu6502' import { PageHandler } from '../../js/cpu6502';
import { byte } from '../../js/types' import { byte } from '../../js/types';
const data = fs.readFileSync(path.join(__dirname, '6502_functional_test.bin'));
export default class Test6502 implements PageHandler { export default class Test6502 implements PageHandler {
private data: Buffer private data: Buffer
constructor() {
this.data = fs.readFileSync(path.join(__dirname, '6502_functional_test.bin'));
}
start = () => { start = () => {
return 0x00; return 0x00;
} }
@ -18,10 +21,10 @@ export default class Test6502 implements PageHandler {
} }
read = (page: byte, off: byte) => { read = (page: byte, off: byte) => {
return data[page << 8 | off]; return this.data[page << 8 | off];
} }
write = (page: byte, off: byte, val: byte) => { write = (page: byte, off: byte, val: byte) => {
data[page << 8 | off] = val; this.data[page << 8 | off] = val;
} }
} }

View File

@ -2,15 +2,14 @@
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { PageHandler } from '../../js/cpu6502' import { PageHandler } from '../../js/cpu6502';
import { byte } from '../../js/types' import { byte } from '../../js/types';
const data = fs.readFileSync(path.join(__dirname, '65C02_extended_opcodes_test.bin'));
export default class Test65C02 implements PageHandler { export default class Test65C02 implements PageHandler {
private data: Buffer private data: Buffer
constructor() { constructor() {
this.data = fs.readFileSync(path.join(__dirname, '65C02_extended_opcodes_test.bin'));
} }
start = function() { start = function() {
@ -22,10 +21,10 @@ export default class Test65C02 implements PageHandler {
} }
read = function(page: byte, off: byte) { read = function(page: byte, off: byte) {
return data[page << 8 | off]; return this.data[page << 8 | off];
} }
write = function(page: byte, off: byte, val: byte) { write = function(page: byte, off: byte, val: byte) {
data[page << 8 | off] = val; this.data[page << 8 | off] = val;
} }
} }