Update eslint, fix issues
This commit is contained in:
parent
badc2fdb74
commit
2978b72fec
|
@ -78,7 +78,7 @@ export class Apple2 implements Restorable<State>, DebuggerContainer {
|
||||||
renderedFrames: 0
|
renderedFrames: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
public ready: Promise<void>
|
public ready: Promise<void>;
|
||||||
|
|
||||||
constructor(options: Apple2Options) {
|
constructor(options: Apple2Options) {
|
||||||
this.ready = this.init(options);
|
this.ready = this.init(options);
|
||||||
|
|
|
@ -122,9 +122,9 @@ export class LoresPage2D implements LoresPage {
|
||||||
private _refreshing = false;
|
private _refreshing = false;
|
||||||
private _blink = false;
|
private _blink = false;
|
||||||
|
|
||||||
private highColorTextMode = false
|
private highColorTextMode = false;
|
||||||
|
|
||||||
dirty: Region = {...notDirty}
|
dirty: Region = {...notDirty};
|
||||||
imageData: ImageData;
|
imageData: ImageData;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|
|
@ -27,9 +27,9 @@ const LOC = {
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export class RAMFactorState {
|
export class RAMFactorState {
|
||||||
loc: number
|
loc: number;
|
||||||
firmware: byte
|
firmware: byte;
|
||||||
mem: memory
|
mem: memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class RAMFactor implements Card, Restorable<RAMFactorState> {
|
export default class RAMFactor implements Card, Restorable<RAMFactorState> {
|
||||||
|
|
194
js/cpu6502.ts
194
js/cpu6502.ts
|
@ -174,7 +174,7 @@ export default class CPU6502 {
|
||||||
/** Program counter */
|
/** Program counter */
|
||||||
private pc: word = 0;
|
private pc: word = 0;
|
||||||
/** Status register */
|
/** Status register */
|
||||||
private sr: byte = flags.X
|
private sr: byte = flags.X;
|
||||||
/** Accumulator */
|
/** Accumulator */
|
||||||
private ar: byte = 0;
|
private ar: byte = 0;
|
||||||
/** X index */
|
/** X index */
|
||||||
|
@ -185,7 +185,7 @@ export default class CPU6502 {
|
||||||
private sp: byte = 0xff;
|
private sp: byte = 0xff;
|
||||||
|
|
||||||
/** Current instruction */
|
/** Current instruction */
|
||||||
private op: Instruction
|
private op: Instruction;
|
||||||
/** Last accessed memory address */
|
/** Last accessed memory address */
|
||||||
private addr: word = 0;
|
private addr: word = 0;
|
||||||
|
|
||||||
|
@ -437,7 +437,7 @@ export default class CPU6502 {
|
||||||
|
|
||||||
implied = () => {
|
implied = () => {
|
||||||
this.readByte(this.pc);
|
this.readByte(this.pc);
|
||||||
}
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read functions
|
* Read functions
|
||||||
|
@ -446,17 +446,17 @@ export default class CPU6502 {
|
||||||
// #$00
|
// #$00
|
||||||
readImmediate = (): byte => {
|
readImmediate = (): byte => {
|
||||||
return this.readBytePC();
|
return this.readBytePC();
|
||||||
}
|
};
|
||||||
|
|
||||||
// $0000
|
// $0000
|
||||||
readAbsolute = (): byte => {
|
readAbsolute = (): byte => {
|
||||||
return this.readByte(this.readWordPC());
|
return this.readByte(this.readWordPC());
|
||||||
}
|
};
|
||||||
|
|
||||||
// $00
|
// $00
|
||||||
readZeroPage = (): byte => {
|
readZeroPage = (): byte => {
|
||||||
return this.readByte(this.readBytePC());
|
return this.readByte(this.readBytePC());
|
||||||
}
|
};
|
||||||
|
|
||||||
// $0000,X
|
// $0000,X
|
||||||
readAbsoluteX = (): byte => {
|
readAbsoluteX = (): byte => {
|
||||||
|
@ -465,7 +465,7 @@ export default class CPU6502 {
|
||||||
const addrIdx = (addr + this.xr) & 0xffff;
|
const addrIdx = (addr + this.xr) & 0xffff;
|
||||||
this.workCycleIndexedRead(pc, addr, addrIdx);
|
this.workCycleIndexedRead(pc, addr, addrIdx);
|
||||||
return this.readByte(addrIdx);
|
return this.readByte(addrIdx);
|
||||||
}
|
};
|
||||||
|
|
||||||
// $0000,Y
|
// $0000,Y
|
||||||
readAbsoluteY = (): byte => {
|
readAbsoluteY = (): byte => {
|
||||||
|
@ -474,21 +474,21 @@ export default class CPU6502 {
|
||||||
const addrIdx = (addr + this.yr) & 0xffff;
|
const addrIdx = (addr + this.yr) & 0xffff;
|
||||||
this.workCycleIndexedRead(pc, addr, addrIdx);
|
this.workCycleIndexedRead(pc, addr, addrIdx);
|
||||||
return this.readByte(addrIdx);
|
return this.readByte(addrIdx);
|
||||||
}
|
};
|
||||||
|
|
||||||
// $00,X
|
// $00,X
|
||||||
readZeroPageX = (): byte => {
|
readZeroPageX = (): byte => {
|
||||||
const 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 => {
|
||||||
const 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 => {
|
||||||
|
@ -496,7 +496,7 @@ export default class CPU6502 {
|
||||||
this.readByte(zpAddr);
|
this.readByte(zpAddr);
|
||||||
const 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 => {
|
||||||
|
@ -506,12 +506,12 @@ export default class CPU6502 {
|
||||||
const addrIdx = (addr + this.yr) & 0xffff;
|
const addrIdx = (addr + this.yr) & 0xffff;
|
||||||
this.workCycleIndexedRead(pc, addr, addrIdx);
|
this.workCycleIndexedRead(pc, addr, addrIdx);
|
||||||
return this.readByte(addrIdx);
|
return this.readByte(addrIdx);
|
||||||
}
|
};
|
||||||
|
|
||||||
// ($00) (65C02)
|
// ($00) (65C02)
|
||||||
readZeroPageIndirect = (): byte => {
|
readZeroPageIndirect = (): byte => {
|
||||||
return this.readByte(this.readZPWord(this.readBytePC()));
|
return this.readByte(this.readZPWord(this.readBytePC()));
|
||||||
}
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write Functions
|
* Write Functions
|
||||||
|
@ -520,12 +520,12 @@ export default class CPU6502 {
|
||||||
// $0000
|
// $0000
|
||||||
writeAbsolute = (val: byte) => {
|
writeAbsolute = (val: byte) => {
|
||||||
this.writeByte(this.readWordPC(), val);
|
this.writeByte(this.readWordPC(), val);
|
||||||
}
|
};
|
||||||
|
|
||||||
// $00
|
// $00
|
||||||
writeZeroPage = (val: byte) => {
|
writeZeroPage = (val: byte) => {
|
||||||
this.writeByte(this.readBytePC(), val);
|
this.writeByte(this.readBytePC(), val);
|
||||||
}
|
};
|
||||||
|
|
||||||
// $0000,X
|
// $0000,X
|
||||||
writeAbsoluteX = (val: byte) => {
|
writeAbsoluteX = (val: byte) => {
|
||||||
|
@ -534,7 +534,7 @@ export default class CPU6502 {
|
||||||
const addrIdx = (addr + this.xr) & 0xffff;
|
const addrIdx = (addr + this.xr) & 0xffff;
|
||||||
this.workCycleIndexedWrite(pc, addr, addrIdx);
|
this.workCycleIndexedWrite(pc, addr, addrIdx);
|
||||||
this.writeByte(addrIdx, val);
|
this.writeByte(addrIdx, val);
|
||||||
}
|
};
|
||||||
|
|
||||||
// $0000,Y
|
// $0000,Y
|
||||||
writeAbsoluteY = (val: byte) => {
|
writeAbsoluteY = (val: byte) => {
|
||||||
|
@ -543,21 +543,21 @@ export default class CPU6502 {
|
||||||
const addrIdx = (addr + this.yr) & 0xffff;
|
const addrIdx = (addr + this.yr) & 0xffff;
|
||||||
this.workCycleIndexedWrite(pc, addr, addrIdx);
|
this.workCycleIndexedWrite(pc, addr, addrIdx);
|
||||||
this.writeByte(addrIdx, val);
|
this.writeByte(addrIdx, val);
|
||||||
}
|
};
|
||||||
|
|
||||||
// $00,X
|
// $00,X
|
||||||
writeZeroPageX = (val: byte) => {
|
writeZeroPageX = (val: byte) => {
|
||||||
const 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) => {
|
||||||
const 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) => {
|
||||||
|
@ -565,7 +565,7 @@ export default class CPU6502 {
|
||||||
this.readByte(zpAddr);
|
this.readByte(zpAddr);
|
||||||
const 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) => {
|
||||||
|
@ -575,29 +575,29 @@ export default class CPU6502 {
|
||||||
const addrIdx = (addr + this.yr) & 0xffff;
|
const addrIdx = (addr + this.yr) & 0xffff;
|
||||||
this.workCycleIndexedWrite(pc, addr, addrIdx);
|
this.workCycleIndexedWrite(pc, addr, addrIdx);
|
||||||
this.writeByte(addrIdx, val);
|
this.writeByte(addrIdx, val);
|
||||||
}
|
};
|
||||||
|
|
||||||
// ($00) (65C02)
|
// ($00) (65C02)
|
||||||
writeZeroPageIndirect = (val: byte) => {
|
writeZeroPageIndirect = (val: byte) => {
|
||||||
this.writeByte(this.readZPWord(this.readBytePC()), val);
|
this.writeByte(this.readZPWord(this.readBytePC()), val);
|
||||||
}
|
};
|
||||||
|
|
||||||
// $00
|
// $00
|
||||||
readAddrZeroPage = () => {
|
readAddrZeroPage = () => {
|
||||||
return this.readBytePC();
|
return this.readBytePC();
|
||||||
}
|
};
|
||||||
|
|
||||||
// $00,X
|
// $00,X
|
||||||
readAddrZeroPageX = () => {
|
readAddrZeroPageX = () => {
|
||||||
const zpAddr = this.readBytePC();
|
const zpAddr = this.readBytePC();
|
||||||
this.readByte(zpAddr);
|
this.readByte(zpAddr);
|
||||||
return (zpAddr + this.xr) & 0xff;
|
return (zpAddr + this.xr) & 0xff;
|
||||||
}
|
};
|
||||||
|
|
||||||
// $0000 (65C02)
|
// $0000 (65C02)
|
||||||
readAddrAbsolute = (): word => {
|
readAddrAbsolute = (): word => {
|
||||||
return this.readWordPC();
|
return this.readWordPC();
|
||||||
}
|
};
|
||||||
|
|
||||||
// ($0000) (6502)
|
// ($0000) (6502)
|
||||||
readAddrAbsoluteIndirectBug = (): word => {
|
readAddrAbsoluteIndirectBug = (): word => {
|
||||||
|
@ -607,14 +607,14 @@ export default class CPU6502 {
|
||||||
const lsb = this.readByte(addr);
|
const lsb = this.readByte(addr);
|
||||||
const 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 => {
|
||||||
const addr = this.readWord(this.readWordPC());
|
const addr = this.readWord(this.readWordPC());
|
||||||
this.readByte(this.addr);
|
this.readByte(this.addr);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
};
|
||||||
|
|
||||||
// $0000,X
|
// $0000,X
|
||||||
readAddrAbsoluteX = (opts?: Opts): word => {
|
readAddrAbsoluteX = (opts?: Opts): word => {
|
||||||
|
@ -635,7 +635,7 @@ export default class CPU6502 {
|
||||||
this.readByte(page | off);
|
this.readByte(page | off);
|
||||||
}
|
}
|
||||||
return addr;
|
return addr;
|
||||||
}
|
};
|
||||||
|
|
||||||
// $(0000,X) (65C02)
|
// $(0000,X) (65C02)
|
||||||
readAddrAbsoluteXIndirect = (): word => {
|
readAddrAbsoluteXIndirect = (): word => {
|
||||||
|
@ -645,13 +645,13 @@ export default class CPU6502 {
|
||||||
const addr = (((msb << 8) | lsb) + this.xr) & 0xffff;
|
const addr = (((msb << 8) | lsb) + this.xr) & 0xffff;
|
||||||
this.readByte(pc);
|
this.readByte(pc);
|
||||||
return this.readWord(addr);
|
return this.readWord(addr);
|
||||||
}
|
};
|
||||||
|
|
||||||
// 5C, DC, FC NOP
|
// 5C, DC, FC NOP
|
||||||
readNop = (): void => {
|
readNop = (): void => {
|
||||||
this.readWordPC();
|
this.readWordPC();
|
||||||
this.readByte(this.addr);
|
this.readByte(this.addr);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Break */
|
/* Break */
|
||||||
brk = (readFn: ReadFn) => {
|
brk = (readFn: ReadFn) => {
|
||||||
|
@ -663,58 +663,58 @@ export default class CPU6502 {
|
||||||
}
|
}
|
||||||
this.setFlag(flags.I, true);
|
this.setFlag(flags.I, true);
|
||||||
this.pc = this.readWord(loc.BRK);
|
this.pc = this.readWord(loc.BRK);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Load Accumulator */
|
/* Load Accumulator */
|
||||||
lda = (readFn: ReadFn) => {
|
lda = (readFn: ReadFn) => {
|
||||||
this.ar = this.testNZ(readFn());
|
this.ar = this.testNZ(readFn());
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Load X Register */
|
/* Load X Register */
|
||||||
ldx = (readFn: ReadFn) => {
|
ldx = (readFn: ReadFn) => {
|
||||||
this.xr = this.testNZ(readFn());
|
this.xr = this.testNZ(readFn());
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Load Y Register */
|
/* Load Y Register */
|
||||||
ldy = (readFn: ReadFn) => {
|
ldy = (readFn: ReadFn) => {
|
||||||
this.yr = this.testNZ(readFn());
|
this.yr = this.testNZ(readFn());
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Store Accumulator */
|
/* Store Accumulator */
|
||||||
sta = (writeFn: WriteFn) => {
|
sta = (writeFn: WriteFn) => {
|
||||||
writeFn(this.ar);
|
writeFn(this.ar);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Store X Register */
|
/* Store X Register */
|
||||||
stx = (writeFn: WriteFn) => {
|
stx = (writeFn: WriteFn) => {
|
||||||
writeFn(this.xr);
|
writeFn(this.xr);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Store Y Register */
|
/* Store Y Register */
|
||||||
sty = (writeFn: WriteFn) => {
|
sty = (writeFn: WriteFn) => {
|
||||||
writeFn(this.yr);
|
writeFn(this.yr);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Store Zero */
|
/* Store Zero */
|
||||||
stz = (writeFn: WriteFn) => {
|
stz = (writeFn: WriteFn) => {
|
||||||
writeFn(0);
|
writeFn(0);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Add with Carry */
|
/* Add with Carry */
|
||||||
adc = (readFn: ReadFn) => {
|
adc = (readFn: ReadFn) => {
|
||||||
this.ar = this.add(this.ar, readFn(), /* sub= */ false);
|
this.ar = this.add(this.ar, readFn(), /* sub= */ false);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Subtract with Carry */
|
/* Subtract with Carry */
|
||||||
sbc = (readFn: ReadFn) => {
|
sbc = (readFn: ReadFn) => {
|
||||||
this.ar = this.add(this.ar, readFn() ^ 0xff, /* sub= */ true);
|
this.ar = this.add(this.ar, readFn() ^ 0xff, /* sub= */ true);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Increment Memory */
|
/* Increment Memory */
|
||||||
incA = () => {
|
incA = () => {
|
||||||
this.readByte(this.pc);
|
this.readByte(this.pc);
|
||||||
this.ar = this.increment(this.ar);
|
this.ar = this.increment(this.ar);
|
||||||
}
|
};
|
||||||
|
|
||||||
inc = (readAddrFn: ReadAddrFn) => {
|
inc = (readAddrFn: ReadAddrFn) => {
|
||||||
const addr = readAddrFn({ inc: true });
|
const addr = readAddrFn({ inc: true });
|
||||||
|
@ -722,25 +722,25 @@ export default class CPU6502 {
|
||||||
this.workCycle(addr, oldVal);
|
this.workCycle(addr, oldVal);
|
||||||
const val = this.increment(oldVal);
|
const val = this.increment(oldVal);
|
||||||
this.writeByte(addr, val);
|
this.writeByte(addr, val);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Increment X */
|
/* Increment X */
|
||||||
inx = () => {
|
inx = () => {
|
||||||
this.readByte(this.pc);
|
this.readByte(this.pc);
|
||||||
this.xr = this.increment(this.xr);
|
this.xr = this.increment(this.xr);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Increment Y */
|
/* Increment Y */
|
||||||
iny = () => {
|
iny = () => {
|
||||||
this.readByte(this.pc);
|
this.readByte(this.pc);
|
||||||
this.yr = this.increment(this.yr);
|
this.yr = this.increment(this.yr);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Decrement Memory */
|
/* Decrement Memory */
|
||||||
decA = () => {
|
decA = () => {
|
||||||
this.readByte(this.pc);
|
this.readByte(this.pc);
|
||||||
this.ar = this.decrement(this.ar);
|
this.ar = this.decrement(this.ar);
|
||||||
}
|
};
|
||||||
|
|
||||||
dec = (readAddrFn: ReadAddrFn) => {
|
dec = (readAddrFn: ReadAddrFn) => {
|
||||||
const addr = readAddrFn({ inc: true});
|
const addr = readAddrFn({ inc: true});
|
||||||
|
@ -748,30 +748,30 @@ export default class CPU6502 {
|
||||||
this.workCycle(addr, oldVal);
|
this.workCycle(addr, oldVal);
|
||||||
const val = this.decrement(oldVal);
|
const val = this.decrement(oldVal);
|
||||||
this.writeByte(addr, val);
|
this.writeByte(addr, val);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Decrement X */
|
/* Decrement X */
|
||||||
dex = () => {
|
dex = () => {
|
||||||
this.readByte(this.pc);
|
this.readByte(this.pc);
|
||||||
this.xr = this.decrement(this.xr);
|
this.xr = this.decrement(this.xr);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Decrement Y */
|
/* Decrement Y */
|
||||||
dey = () => {
|
dey = () => {
|
||||||
this.readByte(this.pc);
|
this.readByte(this.pc);
|
||||||
this.yr = this.decrement(this.yr);
|
this.yr = this.decrement(this.yr);
|
||||||
}
|
};
|
||||||
|
|
||||||
shiftLeft = (val: byte) => {
|
shiftLeft = (val: byte) => {
|
||||||
this.setFlag(flags.C, !!(val & 0x80));
|
this.setFlag(flags.C, !!(val & 0x80));
|
||||||
return this.testNZ((val << 1) & 0xff);
|
return this.testNZ((val << 1) & 0xff);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Arithmetic Shift Left */
|
/* Arithmetic Shift Left */
|
||||||
aslA = () => {
|
aslA = () => {
|
||||||
this.readByte(this.pc);
|
this.readByte(this.pc);
|
||||||
this.ar = this.shiftLeft(this.ar);
|
this.ar = this.shiftLeft(this.ar);
|
||||||
}
|
};
|
||||||
|
|
||||||
asl = (readAddrFn: ReadAddrFn) => {
|
asl = (readAddrFn: ReadAddrFn) => {
|
||||||
const addr = readAddrFn();
|
const addr = readAddrFn();
|
||||||
|
@ -779,18 +779,18 @@ export default class CPU6502 {
|
||||||
this.workCycle(addr, oldVal);
|
this.workCycle(addr, oldVal);
|
||||||
const val = this.shiftLeft(oldVal);
|
const val = this.shiftLeft(oldVal);
|
||||||
this.writeByte(addr, val);
|
this.writeByte(addr, val);
|
||||||
}
|
};
|
||||||
|
|
||||||
shiftRight = (val: byte) => {
|
shiftRight = (val: byte) => {
|
||||||
this.setFlag(flags.C, !!(val & 0x01));
|
this.setFlag(flags.C, !!(val & 0x01));
|
||||||
return this.testNZ(val >> 1);
|
return this.testNZ(val >> 1);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Logical Shift Right */
|
/* Logical Shift Right */
|
||||||
lsrA = () => {
|
lsrA = () => {
|
||||||
this.readByte(this.pc);
|
this.readByte(this.pc);
|
||||||
this.ar = this.shiftRight(this.ar);
|
this.ar = this.shiftRight(this.ar);
|
||||||
}
|
};
|
||||||
|
|
||||||
lsr = (readAddrFn: ReadAddrFn) => {
|
lsr = (readAddrFn: ReadAddrFn) => {
|
||||||
const addr = readAddrFn();
|
const addr = readAddrFn();
|
||||||
|
@ -798,19 +798,19 @@ export default class CPU6502 {
|
||||||
this.workCycle(addr, oldVal);
|
this.workCycle(addr, oldVal);
|
||||||
const val = this.shiftRight(oldVal);
|
const val = this.shiftRight(oldVal);
|
||||||
this.writeByte(addr, val);
|
this.writeByte(addr, val);
|
||||||
}
|
};
|
||||||
|
|
||||||
rotateLeft = (val: byte) => {
|
rotateLeft = (val: byte) => {
|
||||||
const 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);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Rotate Left */
|
/* Rotate Left */
|
||||||
rolA = () => {
|
rolA = () => {
|
||||||
this.readByte(this.pc);
|
this.readByte(this.pc);
|
||||||
this.ar = this.rotateLeft(this.ar);
|
this.ar = this.rotateLeft(this.ar);
|
||||||
}
|
};
|
||||||
|
|
||||||
rol = (readAddrFn: ReadAddrFn) => {
|
rol = (readAddrFn: ReadAddrFn) => {
|
||||||
const addr = readAddrFn();
|
const addr = readAddrFn();
|
||||||
|
@ -818,7 +818,7 @@ export default class CPU6502 {
|
||||||
this.workCycle(addr, oldVal);
|
this.workCycle(addr, oldVal);
|
||||||
const 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) {
|
||||||
const c = (this.sr & flags.C);
|
const c = (this.sr & flags.C);
|
||||||
|
@ -830,7 +830,7 @@ export default class CPU6502 {
|
||||||
rorA = () => {
|
rorA = () => {
|
||||||
this.readByte(this.pc);
|
this.readByte(this.pc);
|
||||||
this.ar = this.rotateRight(this.ar);
|
this.ar = this.rotateRight(this.ar);
|
||||||
}
|
};
|
||||||
|
|
||||||
ror = (readAddrFn: ReadAddrFn) => {
|
ror = (readAddrFn: ReadAddrFn) => {
|
||||||
const addr = readAddrFn();
|
const addr = readAddrFn();
|
||||||
|
@ -838,22 +838,22 @@ export default class CPU6502 {
|
||||||
this.workCycle(addr, oldVal);
|
this.workCycle(addr, oldVal);
|
||||||
const val = this.rotateRight(oldVal);
|
const val = this.rotateRight(oldVal);
|
||||||
this.writeByte(addr, val);
|
this.writeByte(addr, val);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Logical And Accumulator */
|
/* Logical And Accumulator */
|
||||||
and = (readFn: ReadFn) => {
|
and = (readFn: ReadFn) => {
|
||||||
this.ar = this.testNZ(this.ar & readFn());
|
this.ar = this.testNZ(this.ar & readFn());
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Logical Or Accumulator */
|
/* Logical Or Accumulator */
|
||||||
ora = (readFn: ReadFn) => {
|
ora = (readFn: ReadFn) => {
|
||||||
this.ar = this.testNZ(this.ar | readFn());
|
this.ar = this.testNZ(this.ar | readFn());
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Logical Exclusive Or Accumulator */
|
/* Logical Exclusive Or Accumulator */
|
||||||
eor = (readFn: ReadFn) => {
|
eor = (readFn: ReadFn) => {
|
||||||
this.ar = this.testNZ(this.ar ^ readFn());
|
this.ar = this.testNZ(this.ar ^ readFn());
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Reset Bit */
|
/* Reset Bit */
|
||||||
|
|
||||||
|
@ -864,7 +864,7 @@ export default class CPU6502 {
|
||||||
this.readByte(addr);
|
this.readByte(addr);
|
||||||
val &= bit;
|
val &= bit;
|
||||||
this.writeByte(addr, val);
|
this.writeByte(addr, val);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Set Bit */
|
/* Set Bit */
|
||||||
|
|
||||||
|
@ -875,7 +875,7 @@ export default class CPU6502 {
|
||||||
this.readByte(addr);
|
this.readByte(addr);
|
||||||
val |= bit;
|
val |= bit;
|
||||||
this.writeByte(addr, val);
|
this.writeByte(addr, val);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Test and Reset Bits */
|
/* Test and Reset Bits */
|
||||||
trb = (readAddrFn: ReadAddrFn) => {
|
trb = (readAddrFn: ReadAddrFn) => {
|
||||||
|
@ -884,7 +884,7 @@ export default class CPU6502 {
|
||||||
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);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Test and Set Bits */
|
/* Test and Set Bits */
|
||||||
tsb = (readAddrFn: ReadAddrFn) => {
|
tsb = (readAddrFn: ReadAddrFn) => {
|
||||||
|
@ -893,7 +893,7 @@ export default class CPU6502 {
|
||||||
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);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Bit */
|
/* Bit */
|
||||||
bit = (readFn: ReadFn) => {
|
bit = (readFn: ReadFn) => {
|
||||||
|
@ -901,13 +901,13 @@ export default class CPU6502 {
|
||||||
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));
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Bit Immediate*/
|
/* Bit Immediate*/
|
||||||
bitI = (readFn: ReadFn) => {
|
bitI = (readFn: ReadFn) => {
|
||||||
const 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);
|
||||||
|
@ -918,15 +918,15 @@ export default class CPU6502 {
|
||||||
|
|
||||||
cmp = (readFn: ReadFn) => {
|
cmp = (readFn: ReadFn) => {
|
||||||
this.compare(this.ar, readFn());
|
this.compare(this.ar, readFn());
|
||||||
}
|
};
|
||||||
|
|
||||||
cpx = (readFn: ReadFn) => {
|
cpx = (readFn: ReadFn) => {
|
||||||
this.compare(this.xr, readFn());
|
this.compare(this.xr, readFn());
|
||||||
}
|
};
|
||||||
|
|
||||||
cpy = (readFn: ReadFn) => {
|
cpy = (readFn: ReadFn) => {
|
||||||
this.compare(this.yr, readFn());
|
this.compare(this.yr, readFn());
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Branches */
|
/* Branches */
|
||||||
brs = (f: flag) => {
|
brs = (f: flag) => {
|
||||||
|
@ -940,7 +940,7 @@ export default class CPU6502 {
|
||||||
const newOff = this.pc & 0xff;
|
const newOff = this.pc & 0xff;
|
||||||
if (newPage !== oldPage) this.readByte(oldPage | newOff);
|
if (newPage !== oldPage) this.readByte(oldPage | newOff);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
brc = (f: flag|0) => {
|
brc = (f: flag|0) => {
|
||||||
const off = this.readBytePC(); // changes pc
|
const off = this.readBytePC(); // changes pc
|
||||||
|
@ -953,7 +953,7 @@ export default class CPU6502 {
|
||||||
const newOff = this.pc & 0xff;
|
const newOff = this.pc & 0xff;
|
||||||
if (newPage !== oldPage) this.readByte(oldPage | newOff);
|
if (newPage !== oldPage) this.readByte(oldPage | newOff);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/* WDC 65C02 branches */
|
/* WDC 65C02 branches */
|
||||||
|
|
||||||
|
@ -972,7 +972,7 @@ export default class CPU6502 {
|
||||||
if (((1 << b) & val) === 0) {
|
if (((1 << b) & val) === 0) {
|
||||||
this.pc = newPC;
|
this.pc = newPC;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
bbs = (b: byte) => {
|
bbs = (b: byte) => {
|
||||||
const zpAddr = this.readBytePC();
|
const zpAddr = this.readBytePC();
|
||||||
|
@ -989,41 +989,41 @@ export default class CPU6502 {
|
||||||
if (((1 << b) & val) !== 0) {
|
if (((1 << b) & val) !== 0) {
|
||||||
this.pc = newPC;
|
this.pc = newPC;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Transfers and stack */
|
/* Transfers and stack */
|
||||||
tax = () => { this.readByte(this.pc); this.testNZ(this.xr = this.ar); }
|
tax = () => { this.readByte(this.pc); this.testNZ(this.xr = this.ar); };
|
||||||
|
|
||||||
txa = () => { this.readByte(this.pc); this.testNZ(this.ar = this.xr); }
|
txa = () => { this.readByte(this.pc); this.testNZ(this.ar = this.xr); };
|
||||||
|
|
||||||
tay = () => { this.readByte(this.pc); this.testNZ(this.yr = this.ar); }
|
tay = () => { this.readByte(this.pc); this.testNZ(this.yr = this.ar); };
|
||||||
|
|
||||||
tya = () => { this.readByte(this.pc); this.testNZ(this.ar = this.yr); }
|
tya = () => { this.readByte(this.pc); this.testNZ(this.ar = this.yr); };
|
||||||
|
|
||||||
tsx = () => { this.readByte(this.pc); this.testNZ(this.xr = this.sp); }
|
tsx = () => { this.readByte(this.pc); this.testNZ(this.xr = this.sp); };
|
||||||
|
|
||||||
txs = () => { this.readByte(this.pc); this.sp = this.xr; }
|
txs = () => { this.readByte(this.pc); this.sp = this.xr; };
|
||||||
|
|
||||||
pha = () => { this.readByte(this.pc); this.pushByte(this.ar); }
|
pha = () => { this.readByte(this.pc); this.pushByte(this.ar); };
|
||||||
|
|
||||||
pla = () => { this.readByte(this.pc); this.readByte(0x0100 | this.sp); this.testNZ(this.ar = this.pullByte()); }
|
pla = () => { this.readByte(this.pc); this.readByte(0x0100 | this.sp); this.testNZ(this.ar = this.pullByte()); };
|
||||||
|
|
||||||
phx = () => { this.readByte(this.pc); this.pushByte(this.xr); }
|
phx = () => { this.readByte(this.pc); this.pushByte(this.xr); };
|
||||||
|
|
||||||
plx = () => { this.readByte(this.pc); this.readByte(0x0100 | this.sp); this.testNZ(this.xr = this.pullByte()); }
|
plx = () => { this.readByte(this.pc); this.readByte(0x0100 | this.sp); this.testNZ(this.xr = this.pullByte()); };
|
||||||
|
|
||||||
phy = () => { this.readByte(this.pc); this.pushByte(this.yr); }
|
phy = () => { this.readByte(this.pc); this.pushByte(this.yr); };
|
||||||
|
|
||||||
ply = () => { this.readByte(this.pc); this.readByte(0x0100 | this.sp); this.testNZ(this.yr = this.pullByte()); }
|
ply = () => { this.readByte(this.pc); this.readByte(0x0100 | this.sp); this.testNZ(this.yr = this.pullByte()); };
|
||||||
|
|
||||||
php = () => { this.readByte(this.pc); this.pushByte(this.sr | flags.B); }
|
php = () => { this.readByte(this.pc); this.pushByte(this.sr | flags.B); };
|
||||||
|
|
||||||
plp = () => { this.readByte(this.pc); this.readByte(0x0100 | this.sp); this.sr = (this.pullByte() & ~flags.B) | flags.X; }
|
plp = () => { this.readByte(this.pc); this.readByte(0x0100 | this.sp); this.sr = (this.pullByte() & ~flags.B) | flags.X; };
|
||||||
|
|
||||||
/* Jump */
|
/* Jump */
|
||||||
jmp = (readAddrFn: ReadAddrFn) => {
|
jmp = (readAddrFn: ReadAddrFn) => {
|
||||||
this.pc = readAddrFn();
|
this.pc = readAddrFn();
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Jump Subroutine */
|
/* Jump Subroutine */
|
||||||
jsr = () => {
|
jsr = () => {
|
||||||
|
@ -1032,7 +1032,7 @@ export default class CPU6502 {
|
||||||
this.pushWord(this.pc);
|
this.pushWord(this.pc);
|
||||||
const msb = this.readBytePC();
|
const msb = this.readBytePC();
|
||||||
this.pc = (msb << 8 | lsb) & 0xffff;
|
this.pc = (msb << 8 | lsb) & 0xffff;
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Return from Subroutine */
|
/* Return from Subroutine */
|
||||||
rts = () => {
|
rts = () => {
|
||||||
|
@ -1041,7 +1041,7 @@ export default class CPU6502 {
|
||||||
const addr = this.pullWordRaw();
|
const addr = this.pullWordRaw();
|
||||||
this.readByte(addr);
|
this.readByte(addr);
|
||||||
this.pc = (addr + 1) & 0xffff;
|
this.pc = (addr + 1) & 0xffff;
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Return from Interrupt */
|
/* Return from Interrupt */
|
||||||
rti = () => {
|
rti = () => {
|
||||||
|
@ -1049,23 +1049,23 @@ export default class CPU6502 {
|
||||||
this.readByte(0x0100 | this.sp);
|
this.readByte(0x0100 | this.sp);
|
||||||
this.sr = (this.pullByte() & ~flags.B) | flags.X;
|
this.sr = (this.pullByte() & ~flags.B) | flags.X;
|
||||||
this.pc = this.pullWordRaw();
|
this.pc = this.pullWordRaw();
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Set and Clear */
|
/* Set and Clear */
|
||||||
set = (flag: flag) => {
|
set = (flag: flag) => {
|
||||||
this.readByte(this.pc);
|
this.readByte(this.pc);
|
||||||
this.sr |= flag;
|
this.sr |= flag;
|
||||||
}
|
};
|
||||||
|
|
||||||
clr = (flag: flag) => {
|
clr = (flag: flag) => {
|
||||||
this.readByte(this.pc);
|
this.readByte(this.pc);
|
||||||
this.sr &= ~flag;
|
this.sr &= ~flag;
|
||||||
}
|
};
|
||||||
|
|
||||||
/* No-Op */
|
/* No-Op */
|
||||||
nop = (readFn: ImpliedFn | ReadFn) => {
|
nop = (readFn: ImpliedFn | ReadFn) => {
|
||||||
readFn();
|
readFn();
|
||||||
}
|
};
|
||||||
|
|
||||||
private unknown(b: byte) {
|
private unknown(b: byte) {
|
||||||
let unk: StrictInstruction;
|
let unk: StrictInstruction;
|
||||||
|
@ -1663,5 +1663,5 @@ export default class CPU6502 {
|
||||||
// TSB
|
// TSB
|
||||||
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' }
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ export default class Debugger {
|
||||||
|
|
||||||
break = () => {
|
break = () => {
|
||||||
this.container.stop();
|
this.container.stop();
|
||||||
}
|
};
|
||||||
|
|
||||||
step = () => {
|
step = () => {
|
||||||
this.cpu.step(() => {
|
this.cpu.step(() => {
|
||||||
|
@ -65,45 +65,45 @@ export default class Debugger {
|
||||||
debug(this.printDebugInfo(info));
|
debug(this.printDebugInfo(info));
|
||||||
this.updateTrace(info);
|
this.updateTrace(info);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
continue = () => {
|
continue = () => {
|
||||||
this.container.run();
|
this.container.run();
|
||||||
}
|
};
|
||||||
|
|
||||||
setVerbose = (verbose: boolean) => {
|
setVerbose = (verbose: boolean) => {
|
||||||
this.verbose = verbose;
|
this.verbose = verbose;
|
||||||
}
|
};
|
||||||
|
|
||||||
setMaxTrace = (maxTrace: number) => {
|
setMaxTrace = (maxTrace: number) => {
|
||||||
this.maxTrace = maxTrace;
|
this.maxTrace = maxTrace;
|
||||||
}
|
};
|
||||||
|
|
||||||
getTrace = () => {
|
getTrace = () => {
|
||||||
return this.trace.map(this.printDebugInfo).join('\n');
|
return this.trace.map(this.printDebugInfo).join('\n');
|
||||||
}
|
};
|
||||||
|
|
||||||
printTrace = () => {
|
printTrace = () => {
|
||||||
debug(this.getTrace());
|
debug(this.getTrace());
|
||||||
}
|
};
|
||||||
|
|
||||||
setBreakpoint = (addr: word, exp?: breakpointFn) => {
|
setBreakpoint = (addr: word, exp?: breakpointFn) => {
|
||||||
this.breakpoints.set(addr, exp || alwaysBreak);
|
this.breakpoints.set(addr, exp || alwaysBreak);
|
||||||
}
|
};
|
||||||
|
|
||||||
clearBreakpoint = (addr: word) => {
|
clearBreakpoint = (addr: word) => {
|
||||||
this.breakpoints.delete(addr);
|
this.breakpoints.delete(addr);
|
||||||
}
|
};
|
||||||
|
|
||||||
listBreakpoints = () => {
|
listBreakpoints = () => {
|
||||||
for(const [addr, fn] of this.breakpoints.entries()) {
|
for(const [addr, fn] of this.breakpoints.entries()) {
|
||||||
debug(toHex(addr, 4), fn);
|
debug(toHex(addr, 4), fn);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
addSymbols = (symbols: symbols) => {
|
addSymbols = (symbols: symbols) => {
|
||||||
this.symbols = { ...this.symbols, ...symbols };
|
this.symbols = { ...this.symbols, ...symbols };
|
||||||
}
|
};
|
||||||
|
|
||||||
printDebugInfo = (info: DebugInfo) => {
|
printDebugInfo = (info: DebugInfo) => {
|
||||||
const { pc, cmd } = info;
|
const { pc, cmd } = info;
|
||||||
|
@ -118,7 +118,7 @@ export default class Debugger {
|
||||||
' ',
|
' ',
|
||||||
this.dumpOp(pc, cmd)
|
this.dumpOp(pc, cmd)
|
||||||
].join('');
|
].join('');
|
||||||
}
|
};
|
||||||
|
|
||||||
dumpPC = (pc: word) => {
|
dumpPC = (pc: word) => {
|
||||||
const b = this.cpu.read(pc);
|
const b = this.cpu.read(pc);
|
||||||
|
@ -136,7 +136,7 @@ export default class Debugger {
|
||||||
result += this.dumpRawOp(cmd) + ' ' + this.dumpOp(pc, cmd);
|
result += this.dumpRawOp(cmd) + ' ' + this.dumpOp(pc, cmd);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
};
|
||||||
|
|
||||||
dumpRegisters = (debugInfo?: DebugInfo) => {
|
dumpRegisters = (debugInfo?: DebugInfo) => {
|
||||||
if (debugInfo === undefined) {
|
if (debugInfo === undefined) {
|
||||||
|
@ -152,7 +152,7 @@ export default class Debugger {
|
||||||
' ',
|
' ',
|
||||||
dumpStatusRegister(sr),
|
dumpStatusRegister(sr),
|
||||||
].join('');
|
].join('');
|
||||||
}
|
};
|
||||||
|
|
||||||
dumpPage = (start: byte, end?: byte) => {
|
dumpPage = (start: byte, end?: byte) => {
|
||||||
let result = '';
|
let result = '';
|
||||||
|
@ -179,7 +179,7 @@ export default class Debugger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
};
|
||||||
|
|
||||||
list = (pc: word) => {
|
list = (pc: word) => {
|
||||||
const results = [];
|
const results = [];
|
||||||
|
@ -190,7 +190,7 @@ export default class Debugger {
|
||||||
pc += sizes[op.mode];
|
pc += sizes[op.mode];
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
};
|
||||||
|
|
||||||
private updateTrace(info: DebugInfo) {
|
private updateTrace(info: DebugInfo) {
|
||||||
this.trace.push(info);
|
this.trace.push(info);
|
||||||
|
|
|
@ -97,13 +97,13 @@ export type DiskFormat = MemberOf<typeof DISK_FORMATS>;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export class JSONDiskBase {
|
export class JSONDiskBase {
|
||||||
type: DiskFormat
|
type: DiskFormat;
|
||||||
name: string
|
name: string;
|
||||||
disk?: string
|
disk?: string;
|
||||||
category?: string
|
category?: string;
|
||||||
volume?: byte
|
volume?: byte;
|
||||||
readOnly?: boolean
|
readOnly?: boolean;
|
||||||
gamepad?: GamepadConfiguration
|
gamepad?: GamepadConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -37,22 +37,22 @@ function stringFromBytes(data: DataView, start: number, end: number): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InfoChunk {
|
export class InfoChunk {
|
||||||
version: byte
|
version: byte;
|
||||||
|
|
||||||
// Version 1
|
// Version 1
|
||||||
diskType: byte
|
diskType: byte;
|
||||||
writeProtected: byte
|
writeProtected: byte;
|
||||||
synchronized: byte
|
synchronized: byte;
|
||||||
cleaned: byte
|
cleaned: byte;
|
||||||
creator: string
|
creator: string;
|
||||||
|
|
||||||
// Version 2
|
// Version 2
|
||||||
sides: byte = 0
|
sides: byte = 0;
|
||||||
bootSector: byte = 0
|
bootSector: byte = 0;
|
||||||
bitTiming: byte = 0
|
bitTiming: byte = 0;
|
||||||
compatibleHardware: word = 0
|
compatibleHardware: word = 0;
|
||||||
requiredRAM: word = 0
|
requiredRAM: word = 0;
|
||||||
largestTrack: word = 0
|
largestTrack: word = 0;
|
||||||
|
|
||||||
constructor(data: DataView) {
|
constructor(data: DataView) {
|
||||||
this.version = data.getUint8(0);
|
this.version = data.getUint8(0);
|
||||||
|
@ -74,7 +74,7 @@ export class InfoChunk {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TMapChunk {
|
export class TMapChunk {
|
||||||
trackMap: byte[]
|
trackMap: byte[];
|
||||||
|
|
||||||
constructor(data: DataView) {
|
constructor(data: DataView) {
|
||||||
this.trackMap = [];
|
this.trackMap = [];
|
||||||
|
@ -89,8 +89,8 @@ const WOZ_TRACK_SIZE = 6656;
|
||||||
const WOZ_TRACK_INFO_BITS = 6648;
|
const WOZ_TRACK_INFO_BITS = 6648;
|
||||||
|
|
||||||
export class TrksChunk {
|
export class TrksChunk {
|
||||||
rawTracks: Uint8Array[]
|
rawTracks: Uint8Array[];
|
||||||
tracks: Uint8Array[]
|
tracks: Uint8Array[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TrksChunk1 extends TrksChunk {
|
export class TrksChunk1 extends TrksChunk {
|
||||||
|
@ -135,7 +135,7 @@ export interface Trk {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TrksChunk2 extends TrksChunk {
|
export class TrksChunk2 extends TrksChunk {
|
||||||
trks: Trk[]
|
trks: Trk[];
|
||||||
|
|
||||||
constructor (data: DataView) {
|
constructor (data: DataView) {
|
||||||
super();
|
super();
|
||||||
|
@ -188,7 +188,7 @@ export class TrksChunk2 extends TrksChunk {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MetaChunk {
|
export class MetaChunk {
|
||||||
values: Record<string, string>
|
values: Record<string, string>;
|
||||||
|
|
||||||
constructor (data: DataView) {
|
constructor (data: DataView) {
|
||||||
const infoStr = stringFromBytes(data, 0, data.byteLength);
|
const infoStr = stringFromBytes(data, 0, data.byteLength);
|
||||||
|
|
4
js/gl.ts
4
js/gl.ts
|
@ -51,7 +51,7 @@ export class LoresPageGL implements LoresPage {
|
||||||
private _refreshing = false;
|
private _refreshing = false;
|
||||||
private _blink = false;
|
private _blink = false;
|
||||||
|
|
||||||
dirty: Region = {...notDirty}
|
dirty: Region = {...notDirty};
|
||||||
imageData: ImageData;
|
imageData: ImageData;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -563,7 +563,7 @@ export class VideoModesGL implements VideoModes {
|
||||||
private _refreshFlag: boolean = true;
|
private _refreshFlag: boolean = true;
|
||||||
private _canvas: HTMLCanvasElement;
|
private _canvas: HTMLCanvasElement;
|
||||||
|
|
||||||
public ready: Promise<void>
|
public ready: Promise<void>;
|
||||||
|
|
||||||
public textMode: boolean;
|
public textMode: boolean;
|
||||||
public mixedMode: boolean;
|
public mixedMode: boolean;
|
||||||
|
|
|
@ -116,7 +116,7 @@ export class Audio implements OptionHandler {
|
||||||
console.warn('audio not started', error);
|
console.warn('audio not started', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
start = () => {
|
start = () => {
|
||||||
if (this.audioContext) {
|
if (this.audioContext) {
|
||||||
|
@ -125,11 +125,11 @@ export class Audio implements OptionHandler {
|
||||||
console.warn('audio not resumed', error);
|
console.warn('audio not resumed', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
isEnabled = () => {
|
isEnabled = () => {
|
||||||
return this.sound;
|
return this.sound;
|
||||||
}
|
};
|
||||||
|
|
||||||
getOptions() {
|
getOptions() {
|
||||||
return [
|
return [
|
||||||
|
@ -152,5 +152,5 @@ export class Audio implements OptionHandler {
|
||||||
case SOUND_ENABLED_OPTION:
|
case SOUND_ENABLED_OPTION:
|
||||||
this.sound = value;
|
this.sound = value;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ declare global {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AppleAudioProcessor extends AudioWorkletProcessor {
|
export class AppleAudioProcessor extends AudioWorkletProcessor {
|
||||||
private samples: Float32Array[] = []
|
private samples: Float32Array[] = [];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
|
@ -100,5 +100,5 @@ export class JoyStick implements OptionHandler {
|
||||||
|
|
||||||
this.io.paddle(0, this.flipX ? 1 - x : x);
|
this.io.paddle(0, this.flipX ? 1 - x : x);
|
||||||
this.io.paddle(1, this.flipY ? 1 - y : y);
|
this.io.paddle(1, this.flipY ? 1 - y : y);
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -548,7 +548,7 @@ export default class KeyBoard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
private keyup = (evt: KeyboardEvent) => {
|
private keyup = (evt: KeyboardEvent) => {
|
||||||
if (!this.dialogOpen()) {
|
if (!this.dialogOpen()) {
|
||||||
|
@ -568,5 +568,5 @@ export default class KeyBoard {
|
||||||
this.optionKey(false);
|
this.optionKey(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,9 +34,9 @@ export interface OptionHandler {
|
||||||
|
|
||||||
export class OptionsModal {
|
export class OptionsModal {
|
||||||
private prefs: Prefs = new Prefs();
|
private prefs: Prefs = new Prefs();
|
||||||
private options: Record<string, Option> = {}
|
private options: Record<string, Option> = {};
|
||||||
private handlers: Record<string, OptionHandler> = {}
|
private handlers: Record<string, OptionHandler> = {};
|
||||||
private sections: OptionSection[] = []
|
private sections: OptionSection[] = [];
|
||||||
|
|
||||||
addOptions(handler: OptionHandler) {
|
addOptions(handler: OptionHandler) {
|
||||||
const sections = handler.getOptions();
|
const sections = handler.getOptions();
|
||||||
|
|
|
@ -42,7 +42,7 @@ export class Screen implements OptionHandler {
|
||||||
elem.mozRequestFullScreen();
|
elem.mozRequestFullScreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
getOptions() {
|
getOptions() {
|
||||||
return [
|
return [
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -31,12 +31,12 @@
|
||||||
"@types/jest": "^27.0.2",
|
"@types/jest": "^27.0.2",
|
||||||
"@types/jest-image-snapshot": "^4.3.1",
|
"@types/jest-image-snapshot": "^4.3.1",
|
||||||
"@types/micromodal": "^0.3.2",
|
"@types/micromodal": "^0.3.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.28.2",
|
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||||
"@typescript-eslint/parser": "^4.28.2",
|
"@typescript-eslint/parser": "^5.4.0",
|
||||||
"ajv": "^6.12.0",
|
"ajv": "^6.12.0",
|
||||||
"babel-jest": "^27.2.4",
|
"babel-jest": "^27.2.4",
|
||||||
"canvas": "^2.7.0",
|
"canvas": "^2.7.0",
|
||||||
"eslint": "^7.22.0",
|
"eslint": "^8.3.0",
|
||||||
"file-loader": "^6.0.0",
|
"file-loader": "^6.0.0",
|
||||||
"jest": "^27.2.4",
|
"jest": "^27.2.4",
|
||||||
"jest-image-snapshot": "^4.5.1",
|
"jest-image-snapshot": "^4.5.1",
|
||||||
|
|
|
@ -5,7 +5,7 @@ import path from 'path';
|
||||||
import { MemoryPages, byte } from '../../js/types';
|
import { MemoryPages, byte } from '../../js/types';
|
||||||
|
|
||||||
export default class Test6502 implements MemoryPages {
|
export default class Test6502 implements MemoryPages {
|
||||||
private data: Buffer
|
private data: Buffer;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.data = fs.readFileSync(path.join(__dirname, '6502_functional_test.bin'));
|
this.data = fs.readFileSync(path.join(__dirname, '6502_functional_test.bin'));
|
||||||
|
@ -13,17 +13,17 @@ export default class Test6502 implements MemoryPages {
|
||||||
|
|
||||||
start = () => {
|
start = () => {
|
||||||
return 0x00;
|
return 0x00;
|
||||||
}
|
};
|
||||||
|
|
||||||
end = () => {
|
end = () => {
|
||||||
return 0xff;
|
return 0xff;
|
||||||
}
|
};
|
||||||
|
|
||||||
read = (page: byte, off: byte) => {
|
read = (page: byte, off: byte) => {
|
||||||
return this.data[page << 8 | off];
|
return this.data[page << 8 | off];
|
||||||
}
|
};
|
||||||
|
|
||||||
write = (page: byte, off: byte, val: byte) => {
|
write = (page: byte, off: byte, val: byte) => {
|
||||||
this.data[page << 8 | off] = val;
|
this.data[page << 8 | off] = val;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import path from 'path';
|
||||||
import { MemoryPages, byte } from '../../js/types';
|
import { MemoryPages, byte } from '../../js/types';
|
||||||
|
|
||||||
export default class Test65C02 implements MemoryPages {
|
export default class Test65C02 implements MemoryPages {
|
||||||
private data: Buffer
|
private data: Buffer;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.data = fs.readFileSync(path.join(__dirname, '65C02_extended_opcodes_test.bin'));
|
this.data = fs.readFileSync(path.join(__dirname, '65C02_extended_opcodes_test.bin'));
|
||||||
|
@ -13,17 +13,17 @@ export default class Test65C02 implements MemoryPages {
|
||||||
|
|
||||||
start = () => {
|
start = () => {
|
||||||
return 0x00;
|
return 0x00;
|
||||||
}
|
};
|
||||||
|
|
||||||
end = () => {
|
end = () => {
|
||||||
return 0xff;
|
return 0xff;
|
||||||
}
|
};
|
||||||
|
|
||||||
read = (page: byte, off: byte) => {
|
read = (page: byte, off: byte) => {
|
||||||
return this.data[page << 8 | off];
|
return this.data[page << 8 | off];
|
||||||
}
|
};
|
||||||
|
|
||||||
write = (page: byte, off: byte, val: byte) => {
|
write = (page: byte, off: byte, val: byte) => {
|
||||||
this.data[page << 8 | off] = val;
|
this.data[page << 8 | off] = val;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue