mirror of
https://github.com/whscullin/apple2js.git
synced 2024-01-12 14:14:38 +00:00
No CPU cycle left behind.
This commit is contained in:
parent
859bd1ff8f
commit
7d9090133b
|
@ -314,7 +314,10 @@ export function LoresPage(page, charset, e, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_80colMode) {
|
if (!doubleHiresMode && bank == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_80colMode && doubleHiresMode) {
|
||||||
off = (col * 14 + (bank ? 0 : 1) * 7 + row * 560 * 8 * 2) * 4;
|
off = (col * 14 + (bank ? 0 : 1) * 7 + row * 560 * 8 * 2) * 4;
|
||||||
if (_greenMode) {
|
if (_greenMode) {
|
||||||
fore = _green;
|
fore = _green;
|
||||||
|
|
240
js/cpu6502.js
240
js/cpu6502.js
|
@ -163,12 +163,10 @@ export default function CPU6502(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
function increment(a) {
|
function increment(a) {
|
||||||
cycles++;
|
|
||||||
return testNZ((a + 0x01) & 0xff);
|
return testNZ((a + 0x01) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
function decrement(a) {
|
function decrement(a) {
|
||||||
cycles++;
|
|
||||||
return testNZ((a + 0xff) & 0xff);
|
return testNZ((a + 0xff) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,15 +245,6 @@ export default function CPU6502(options)
|
||||||
return (msb << 8) | lsb;
|
return (msb << 8) | lsb;
|
||||||
}
|
}
|
||||||
|
|
||||||
function indirectBug(addr) {
|
|
||||||
var page = addr & 0xff00;
|
|
||||||
var off = addr & 0xff;
|
|
||||||
var lsb = readByte(page | (off & 0xff));
|
|
||||||
var msb = readByte(page | ((off + 0x01) & 0xff));
|
|
||||||
|
|
||||||
return (msb << 8) | lsb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read functions
|
* Read functions
|
||||||
*/
|
*/
|
||||||
|
@ -280,10 +269,11 @@ export default function CPU6502(options)
|
||||||
|
|
||||||
// $0000,X
|
// $0000,X
|
||||||
function readAbsoluteX() {
|
function readAbsoluteX() {
|
||||||
var addr = readWordPC(), oldPage = addr >> 8, page;
|
var addr = readWordPC();
|
||||||
|
var oldPage = addr >> 8;
|
||||||
addr = (addr + xr) & 0xffff;
|
addr = (addr + xr) & 0xffff;
|
||||||
page = addr >> 8;
|
var newPage = addr >> 8;
|
||||||
if (page != oldPage) {
|
if (newPage != oldPage) {
|
||||||
var off = addr & 0xff;
|
var off = addr & 0xff;
|
||||||
readByte(oldPage << 8 | off);
|
readByte(oldPage << 8 | off);
|
||||||
}
|
}
|
||||||
|
@ -292,10 +282,11 @@ export default function CPU6502(options)
|
||||||
|
|
||||||
// $0000,Y
|
// $0000,Y
|
||||||
function readAbsoluteY() {
|
function readAbsoluteY() {
|
||||||
var addr = readWordPC(), oldPage = addr >> 8, page;
|
var addr = readWordPC();
|
||||||
|
var oldPage = addr >> 8;
|
||||||
addr = (addr + yr) & 0xffff;
|
addr = (addr + yr) & 0xffff;
|
||||||
page = addr >> 8;
|
var newPage = addr >> 8;
|
||||||
if (page != oldPage) {
|
if (newPage != oldPage) {
|
||||||
var off = addr & 0xff;
|
var off = addr & 0xff;
|
||||||
readByte(oldPage << 8 | off);
|
readByte(oldPage << 8 | off);
|
||||||
}
|
}
|
||||||
|
@ -304,31 +295,33 @@ export default function CPU6502(options)
|
||||||
|
|
||||||
// $00,X
|
// $00,X
|
||||||
function readZeroPageX() {
|
function readZeroPageX() {
|
||||||
var result = readByte((readBytePC() + xr) & 0xff);
|
var zpAddr = readBytePC();
|
||||||
cycles++;
|
readByte(zpAddr);
|
||||||
return result;
|
return readByte((zpAddr + xr) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
// $00,Y
|
// $00,Y
|
||||||
function readZeroPageY() {
|
function readZeroPageY() {
|
||||||
var addr = (readBytePC() + yr) & 0xff;
|
var zpAddr = readBytePC();
|
||||||
cycles++;
|
readByte(zpAddr);
|
||||||
return readByte(addr);
|
return readByte((zpAddr + yr) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ($00,X)
|
// ($00,X)
|
||||||
function readZeroPageXIndirect() {
|
function readZeroPageXIndirect() {
|
||||||
var addr = readZPWord((readBytePC() + xr) & 0xff);
|
var zpAddr = readBytePC();
|
||||||
cycles++;
|
readByte(zpAddr);
|
||||||
|
var addr = readZPWord((zpAddr + xr) & 0xff);
|
||||||
return readByte(addr);
|
return readByte(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ($00),Y
|
// ($00),Y
|
||||||
function readZeroPageIndirectY() {
|
function readZeroPageIndirectY() {
|
||||||
var addr = readZPWord(readBytePC()), oldPage = addr >> 8, page;
|
var addr = readZPWord(readBytePC());
|
||||||
|
var oldPage = addr >> 8;
|
||||||
addr = (addr + yr) & 0xffff;
|
addr = (addr + yr) & 0xffff;
|
||||||
page = addr >> 8;
|
var newPage = addr >> 8;
|
||||||
if (page != oldPage) {
|
if (newPage != oldPage) {
|
||||||
var off = addr & 0xff;
|
var off = addr & 0xff;
|
||||||
readByte(oldPage << 8 | off);
|
readByte(oldPage << 8 | off);
|
||||||
}
|
}
|
||||||
|
@ -374,23 +367,24 @@ export default function CPU6502(options)
|
||||||
|
|
||||||
// $00,X
|
// $00,X
|
||||||
function writeZeroPageX(val) {
|
function writeZeroPageX(val) {
|
||||||
var address = (readBytePC() + xr) & 0xff;
|
var zpAddr = readBytePC();
|
||||||
cycles++;
|
readByte(zpAddr);
|
||||||
writeByte(address, val);
|
writeByte((zpAddr + xr) & 0xff, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// $00,Y
|
// $00,Y
|
||||||
function writeZeroPageY(val) {
|
function writeZeroPageY(val) {
|
||||||
var address = (readBytePC() + yr) & 0xff;
|
var zpAddr = readBytePC();
|
||||||
cycles++;
|
readByte(zpAddr);
|
||||||
writeByte(address, val);
|
writeByte((zpAddr + yr) & 0xff, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ($00,X)
|
// ($00,X)
|
||||||
function writeZeroPageXIndirect(val) {
|
function writeZeroPageXIndirect(val) {
|
||||||
var address = readZPWord((readBytePC() + xr) & 0xff);
|
var zpAddr = readBytePC();
|
||||||
cycles++;
|
readByte(zpAddr);
|
||||||
writeByte(address, val);
|
var addr = readZPWord((zpAddr + xr) & 0xff);
|
||||||
|
writeByte(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ($00),Y
|
// ($00),Y
|
||||||
|
@ -414,9 +408,9 @@ export default function CPU6502(options)
|
||||||
|
|
||||||
// $00,X
|
// $00,X
|
||||||
function readAddrZeroPageX() {
|
function readAddrZeroPageX() {
|
||||||
var result = (readBytePC() + xr) & 0xff;
|
var zpAddr = readBytePC();
|
||||||
cycles++;
|
readByte(zpAddr);
|
||||||
return result;
|
return (zpAddr + xr) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
// $0000 (65C02)
|
// $0000 (65C02)
|
||||||
|
@ -426,14 +420,20 @@ export default function CPU6502(options)
|
||||||
|
|
||||||
// ($0000) (6502)
|
// ($0000) (6502)
|
||||||
function readAddrAbsoluteIndirectBug() {
|
function readAddrAbsoluteIndirectBug() {
|
||||||
return indirectBug(readWordPC());
|
var addr = readWordPC();
|
||||||
|
var page = addr & 0xff00;
|
||||||
|
var off = addr & 0x00ff;
|
||||||
|
var lsb = readByte(addr);
|
||||||
|
var msb = readByte(page | ((off + 0x01) & 0xff));
|
||||||
|
return msb << 8 | lsb;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ($0000) (65C02)
|
// ($0000) (65C02)
|
||||||
function readAddrAbsoluteIndirect() {
|
function readAddrAbsoluteIndirect() {
|
||||||
var address = readWordPC();
|
var lsb = readBytePC();
|
||||||
cycles++;
|
var msb = readBytePC();
|
||||||
return readWord(address);
|
readByte(pc);
|
||||||
|
return readWord(msb << 8 | lsb);
|
||||||
}
|
}
|
||||||
|
|
||||||
// $0000,X
|
// $0000,X
|
||||||
|
@ -442,16 +442,16 @@ export default function CPU6502(options)
|
||||||
if (!is65C02 || (opts && opts.rwm)) {
|
if (!is65C02 || (opts && opts.rwm)) {
|
||||||
readByte(addr);
|
readByte(addr);
|
||||||
} else {
|
} else {
|
||||||
cycles++;
|
readByte(pc);
|
||||||
}
|
}
|
||||||
return (addr + xr) & 0xffff;
|
return (addr + xr) & 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
// $(0000,X)
|
// $(0000,X) (65C02)
|
||||||
function readAddrAbsoluteXIndirect() {
|
function readAddrAbsoluteXIndirect() {
|
||||||
var address = (readWordPC() + xr) & 0xffff;
|
var address = readWordPC();
|
||||||
cycles++;
|
readByte(pc);
|
||||||
return readWord(address);
|
return readWord((address + xr) & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Break */
|
/* Break */
|
||||||
|
@ -513,108 +513,132 @@ export default function CPU6502(options)
|
||||||
|
|
||||||
/* Increment Memory */
|
/* Increment Memory */
|
||||||
function incA() {
|
function incA() {
|
||||||
|
readByte(pc);
|
||||||
ar = increment(ar);
|
ar = increment(ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
function inc(readAddrFn) {
|
function inc(readAddrFn) {
|
||||||
var addr = readAddrFn({rwm: true});
|
var addr = readAddrFn({rwm: true});
|
||||||
writeByte(addr, increment(readByte(addr)));
|
var oldVal = readByte(addr);
|
||||||
|
writeByte(addr, oldVal);
|
||||||
|
var val = increment(oldVal);
|
||||||
|
writeByte(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Increment X */
|
/* Increment X */
|
||||||
function inx() {
|
function inx() {
|
||||||
|
readByte(pc);
|
||||||
xr = increment(xr);
|
xr = increment(xr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Increment Y */
|
/* Increment Y */
|
||||||
function iny() {
|
function iny() {
|
||||||
|
readByte(pc);
|
||||||
yr = increment(yr);
|
yr = increment(yr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decrement Memory */
|
/* Decrement Memory */
|
||||||
function decA() {
|
function decA() {
|
||||||
|
readByte(pc);
|
||||||
ar = decrement(ar);
|
ar = decrement(ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
function dec(readAddrFn) {
|
function dec(readAddrFn) {
|
||||||
var addr = readAddrFn({rwm: true});
|
var addr = readAddrFn({rwm: true});
|
||||||
writeByte(addr, decrement(readByte(addr)));
|
var oldVal = readByte(addr);
|
||||||
|
writeByte(addr, oldVal);
|
||||||
|
var val = decrement(oldVal);
|
||||||
|
writeByte(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decrement X */
|
/* Decrement X */
|
||||||
function dex() {
|
function dex() {
|
||||||
|
readByte(pc);
|
||||||
xr = decrement(xr);
|
xr = decrement(xr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decrement Y */
|
/* Decrement Y */
|
||||||
function dey() {
|
function dey() {
|
||||||
|
readByte(pc);
|
||||||
yr = decrement(yr);
|
yr = decrement(yr);
|
||||||
}
|
}
|
||||||
|
|
||||||
function shiftLeft(val) {
|
function shiftLeft(val) {
|
||||||
setFlag(flags.C, val & 0x80);
|
setFlag(flags.C, val & 0x80);
|
||||||
cycles++;
|
|
||||||
return testNZ((val << 1) & 0xff);
|
return testNZ((val << 1) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Arithmatic Shift Left */
|
/* Arithmetic Shift Left */
|
||||||
function aslA() {
|
function aslA() {
|
||||||
|
readByte(pc);
|
||||||
ar = shiftLeft(ar);
|
ar = shiftLeft(ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
function asl(readAddrFn) {
|
function asl(readAddrFn) {
|
||||||
var addr = readAddrFn({rwm: true});
|
var addr = readAddrFn({rwm: true});
|
||||||
writeByte(addr, shiftLeft(readByte(addr)));
|
var oldVal = readByte(addr);
|
||||||
|
writeByte(addr, oldVal);
|
||||||
|
var val = shiftLeft(oldVal);
|
||||||
|
writeByte(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
function shiftRight(val) {
|
function shiftRight(val) {
|
||||||
setFlag(flags.C, val & 0x01);
|
setFlag(flags.C, val & 0x01);
|
||||||
cycles++;
|
|
||||||
return testNZ(val >> 1);
|
return testNZ(val >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Logical Shift Right */
|
/* Logical Shift Right */
|
||||||
function lsrA() {
|
function lsrA() {
|
||||||
|
readByte(pc);
|
||||||
ar = shiftRight(ar);
|
ar = shiftRight(ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
function lsr(readAddrFn) {
|
function lsr(readAddrFn) {
|
||||||
var addr = readAddrFn({rwm: true});
|
var addr = readAddrFn({rwm: true});
|
||||||
writeByte(addr, shiftRight(readByte(addr)));
|
var oldVal = readByte(addr);
|
||||||
|
writeByte(addr, oldVal);
|
||||||
|
var val = shiftRight(oldVal);
|
||||||
|
writeByte(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
function rotateLeft(val) {
|
function rotateLeft(val) {
|
||||||
var c = (sr & flags.C);
|
var c = (sr & flags.C);
|
||||||
setFlag(flags.C, val & 0x80);
|
setFlag(flags.C, val & 0x80);
|
||||||
cycles++;
|
|
||||||
return testNZ(((val << 1) | (c ? 0x01 : 0x00)) & 0xff);
|
return testNZ(((val << 1) | (c ? 0x01 : 0x00)) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rotate Left */
|
/* Rotate Left */
|
||||||
function rolA() {
|
function rolA() {
|
||||||
|
readByte(pc);
|
||||||
ar = rotateLeft(ar);
|
ar = rotateLeft(ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
function rol(readAddrFn) {
|
function rol(readAddrFn) {
|
||||||
var addr = readAddrFn({rwm: true});
|
var addr = readAddrFn({rwm: true});
|
||||||
writeByte(addr, rotateLeft(readByte(addr)));
|
var oldVal = readByte(addr);
|
||||||
|
writeByte(oldVal);
|
||||||
|
var val = rotateLeft(oldVal);
|
||||||
|
writeByte(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
function rotateRight(a) {
|
function rotateRight(a) {
|
||||||
var c = (sr & flags.C);
|
var c = (sr & flags.C);
|
||||||
setFlag(flags.C, a & 0x01);
|
setFlag(flags.C, a & 0x01);
|
||||||
cycles++;
|
|
||||||
return testNZ((a >> 1) | (c ? 0x80 : 0x00));
|
return testNZ((a >> 1) | (c ? 0x80 : 0x00));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rotate Right */
|
/* Rotate Right */
|
||||||
function rorA() {
|
function rorA() {
|
||||||
|
readByte(pc);
|
||||||
ar = rotateRight(ar);
|
ar = rotateRight(ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ror(readAddrFn) {
|
function ror(readAddrFn) {
|
||||||
var addr = readAddrFn({rwm: true});
|
var addr = readAddrFn({rwm: true});
|
||||||
writeByte(addr, rotateRight(readByte(addr)));
|
var oldVal = readByte(addr);
|
||||||
|
writeByte(addr, val);
|
||||||
|
var val = rotateRight(oldVal);
|
||||||
|
writeByte(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Logical And Accumulator */
|
/* Logical And Accumulator */
|
||||||
|
@ -638,8 +662,8 @@ export default function CPU6502(options)
|
||||||
var bit = (0x1 << b) ^ 0xFF;
|
var bit = (0x1 << b) ^ 0xFF;
|
||||||
var addr = readBytePC();
|
var addr = readBytePC();
|
||||||
var val = readByte(addr);
|
var val = readByte(addr);
|
||||||
|
readByte(addr);
|
||||||
val &= bit;
|
val &= bit;
|
||||||
cycles++;
|
|
||||||
writeByte(addr, val);
|
writeByte(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,26 +673,26 @@ export default function CPU6502(options)
|
||||||
var bit = 0x1 << b;
|
var bit = 0x1 << b;
|
||||||
var addr = readBytePC();
|
var addr = readBytePC();
|
||||||
var val = readByte(addr);
|
var val = readByte(addr);
|
||||||
|
readByte(addr);
|
||||||
val |= bit;
|
val |= bit;
|
||||||
cycles++;
|
|
||||||
writeByte(addr, val);
|
writeByte(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test and Reset Bits */
|
/* Test and Reset Bits */
|
||||||
function trb(readAddrFn) {
|
function trb(readAddrFn) {
|
||||||
var addr = readAddrFn(),
|
var addr = readAddrFn();
|
||||||
val = readByte(addr);
|
var val = readByte(addr);
|
||||||
testZ(val & ar);
|
testZ(val & ar);
|
||||||
cycles++;
|
readByte(addr);
|
||||||
writeByte(addr, val & ~ar);
|
writeByte(addr, val & ~ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test and Set Bits */
|
/* Test and Set Bits */
|
||||||
function tsb(readAddrFn) {
|
function tsb(readAddrFn) {
|
||||||
var addr = readAddrFn(),
|
var addr = readAddrFn();
|
||||||
val = readByte(addr);
|
var val = readByte(addr);
|
||||||
testZ(val & ar);
|
testZ(val & ar);
|
||||||
cycles++;
|
readByte(addr);
|
||||||
writeByte(addr, val | ar);
|
writeByte(addr, val | ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,71 +734,93 @@ export default function CPU6502(options)
|
||||||
function brs(f) {
|
function brs(f) {
|
||||||
var off = readBytePC(); // changes pc
|
var off = readBytePC(); // changes pc
|
||||||
if ((f & sr) !== 0) {
|
if ((f & sr) !== 0) {
|
||||||
var oldPC = pc;
|
readByte(pc);
|
||||||
|
var oldPage = pc >> 8;
|
||||||
pc += off > 127 ? off - 256 : off;
|
pc += off > 127 ? off - 256 : off;
|
||||||
cycles++;
|
var newPage = pc >> 8;
|
||||||
if ((pc >> 8) != (oldPC >> 8)) cycles++;
|
var newOff = pc & 0xff;
|
||||||
|
if (newPage != oldPage) readByte(oldPage << 8 | newOff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function brc(f) {
|
function brc(f) {
|
||||||
var off = readBytePC(); // changes pc
|
var off = readBytePC(); // changes pc
|
||||||
if ((f & sr) === 0) {
|
if ((f & sr) === 0) {
|
||||||
var oldPC = pc;
|
readByte(pc);
|
||||||
|
var oldPage = pc >> 8;
|
||||||
pc += off > 127 ? off - 256 : off;
|
pc += off > 127 ? off - 256 : off;
|
||||||
cycles++;
|
var newPage = pc >> 8;
|
||||||
if ((pc >> 8) != (oldPC >> 8)) cycles++;
|
var newOff = pc & 0xff;
|
||||||
|
if (newPage != oldPage) readByte(oldPage << 8 | newOff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WDC 65C02 branches */
|
/* WDC 65C02 branches */
|
||||||
|
|
||||||
function bbr(b) {
|
function bbr(b) {
|
||||||
var val = readZeroPage();
|
var zpAddr = readBytePC();
|
||||||
|
var val = readByte(zpAddr);
|
||||||
|
readByte(zpAddr);
|
||||||
var off = readBytePC(); // changes pc
|
var off = readBytePC(); // changes pc
|
||||||
cycles++;
|
|
||||||
if (((1 << b) & val) === 0) {
|
if (((1 << b) & val) === 0) {
|
||||||
|
var oldPc = pc;
|
||||||
|
var oldPage = oldPc >> 8;
|
||||||
|
readByte(oldPc);
|
||||||
pc += off > 127 ? off - 256 : off;
|
pc += off > 127 ? off - 256 : off;
|
||||||
|
var newPage = pc >> 8;
|
||||||
|
if (oldPage != newPage) {
|
||||||
|
readByte(oldPc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function bbs(b) {
|
function bbs(b) {
|
||||||
var val = readZeroPage(); // ZP
|
var zpAddr = readBytePC();
|
||||||
|
var val = readByte(zpAddr);
|
||||||
|
readByte(zpAddr);
|
||||||
var off = readBytePC(); // changes pc
|
var off = readBytePC(); // changes pc
|
||||||
cycles++;
|
|
||||||
if (((1 << b) & val) !== 0) {
|
if (((1 << b) & val) !== 0) {
|
||||||
|
var oldPc = pc;
|
||||||
|
var oldPage = oldPc >> 8;
|
||||||
|
readByte(oldPc);
|
||||||
pc += off > 127 ? off - 256 : off;
|
pc += off > 127 ? off - 256 : off;
|
||||||
|
var newPage = pc >> 8;
|
||||||
|
if (oldPage != newPage) {
|
||||||
|
readByte(oldPc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Transfers and stack */
|
/* Transfers and stack */
|
||||||
function tax() { testNZ(xr = ar); cycles++; }
|
function tax() { readByte(pc); testNZ(xr = ar); }
|
||||||
|
|
||||||
function txa() { testNZ(ar = xr); cycles++; }
|
function txa() { readByte(pc); testNZ(ar = xr); }
|
||||||
|
|
||||||
function tay() { testNZ(yr = ar); cycles++; }
|
function tay() { readByte(pc); testNZ(yr = ar); }
|
||||||
|
|
||||||
function tya() { testNZ(ar = yr); cycles++; }
|
function tya() { readByte(pc); testNZ(ar = yr); }
|
||||||
|
|
||||||
function tsx() { testNZ(xr = sp); cycles++; }
|
function tsx() { readByte(pc); testNZ(xr = sp); }
|
||||||
|
|
||||||
function txs() { sp = xr; cycles++; }
|
function txs() { readByte(pc); sp = xr; }
|
||||||
|
|
||||||
function pha() { cycles++; pushByte(ar); }
|
function pha() { readByte(pc); pushByte(ar); }
|
||||||
|
|
||||||
function pla() { cycles++; readByte(0x0100 | sp); testNZ(ar = pullByte()); }
|
function pla() { readByte(pc); readByte(0x0100 | sp); testNZ(ar = pullByte()); }
|
||||||
|
|
||||||
function phx() { cycles++; pushByte(xr); }
|
function phx() { readByte(pc); pushByte(xr); }
|
||||||
|
|
||||||
function plx() { cycles++; readByte(0x0100 | sp);testNZ(xr = pullByte()); }
|
function plx() { readByte(pc); readByte(0x0100 | sp);testNZ(xr = pullByte()); }
|
||||||
|
|
||||||
function phy() { cycles++; pushByte(yr); }
|
function phy() { readByte(pc); pushByte(yr); }
|
||||||
|
|
||||||
function ply() { cycles++; readByte(0x0100 | sp); testNZ(yr = pullByte()); }
|
function ply() { readByte(pc); readByte(0x0100 | sp); testNZ(yr = pullByte()); }
|
||||||
|
|
||||||
function php() { cycles++; pushByte(sr | flags.B); }
|
function php() { readByte(pc); pushByte(sr | flags.B); }
|
||||||
|
|
||||||
function plp() { cycles++; readByte(0x0100 | sp); sr = (pullByte() & ~flags.B) | 0x20; }
|
function plp() { readByte(pc); readByte(0x0100 | sp); sr = (pullByte() & ~flags.B) | 0x20; }
|
||||||
|
|
||||||
/* Jump */
|
/* Jump */
|
||||||
function jmp(readAddrFn) {
|
function jmp(readAddrFn) {
|
||||||
|
@ -792,7 +838,7 @@ export default function CPU6502(options)
|
||||||
|
|
||||||
/* Return from Subroutine */
|
/* Return from Subroutine */
|
||||||
function rts() {
|
function rts() {
|
||||||
cycles++;
|
readByte(pc);
|
||||||
readByte(0x0100 | sp);
|
readByte(0x0100 | sp);
|
||||||
var addr = pullWordRaw();
|
var addr = pullWordRaw();
|
||||||
readByte(addr);
|
readByte(addr);
|
||||||
|
@ -801,7 +847,7 @@ export default function CPU6502(options)
|
||||||
|
|
||||||
/* Return from Subroutine */
|
/* Return from Subroutine */
|
||||||
function rti() {
|
function rti() {
|
||||||
cycles++;
|
readByte(pc);
|
||||||
readByte(0x0100 | sp);
|
readByte(0x0100 | sp);
|
||||||
sr = pullByte() & ~flags.B;
|
sr = pullByte() & ~flags.B;
|
||||||
pc = pullWordRaw();
|
pc = pullWordRaw();
|
||||||
|
@ -809,19 +855,19 @@ export default function CPU6502(options)
|
||||||
|
|
||||||
/* Set and Clear */
|
/* Set and Clear */
|
||||||
function set(flag) {
|
function set(flag) {
|
||||||
|
readByte(pc);
|
||||||
sr |= flag;
|
sr |= flag;
|
||||||
cycles++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clr(flag) {
|
function clr(flag) {
|
||||||
|
readByte(pc);
|
||||||
sr &= ~flag;
|
sr &= ~flag;
|
||||||
cycles++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No-Op */
|
/* No-Op */
|
||||||
function nop(readAddrFn) {
|
function nop(readAddrFn) {
|
||||||
|
readByte(pc);
|
||||||
readAddrFn();
|
readAddrFn();
|
||||||
cycles++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var ops = {
|
var ops = {
|
||||||
|
|
|
@ -1785,7 +1785,7 @@ describe('65c02', function() {
|
||||||
it('BBR0 should branch if bit 0 clear', function() {
|
it('BBR0 should branch if bit 0 clear', function() {
|
||||||
initMemory([[0x00, 0x33, [0xFE]]]);
|
initMemory([[0x00, 0x33, [0xFE]]]);
|
||||||
testCode([0x0F, 0x33, 0x7F], 1, {}, {
|
testCode([0x0F, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1793,7 +1793,7 @@ describe('65c02', function() {
|
||||||
it('BBR0 should branch backward', function () {
|
it('BBR0 should branch backward', function () {
|
||||||
initMemory([[0x00, 0x33, [0xFE]]]);
|
initMemory([[0x00, 0x33, [0xFE]]]);
|
||||||
testCode([0x0F, 0x33, 0xFF], 1, {}, {
|
testCode([0x0F, 0x33, 0xFF], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0402
|
pc: 0x0402
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1801,7 +1801,7 @@ describe('65c02', function() {
|
||||||
it('BBR1 should branch if bit 1 clear', function() {
|
it('BBR1 should branch if bit 1 clear', function() {
|
||||||
initMemory([[0x00, 0x33, [0xFD]]]);
|
initMemory([[0x00, 0x33, [0xFD]]]);
|
||||||
testCode([0x1F, 0x33, 0x7F], 1, {}, {
|
testCode([0x1F, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1809,7 +1809,7 @@ describe('65c02', function() {
|
||||||
it('BBR2 should branch if bit 2 clear', function() {
|
it('BBR2 should branch if bit 2 clear', function() {
|
||||||
initMemory([[0x00, 0x33, [0xFB]]]);
|
initMemory([[0x00, 0x33, [0xFB]]]);
|
||||||
testCode([0x2F, 0x33, 0x7F], 1, {}, {
|
testCode([0x2F, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1817,7 +1817,7 @@ describe('65c02', function() {
|
||||||
it('BBR3 should branch if bit 3 clear', function() {
|
it('BBR3 should branch if bit 3 clear', function() {
|
||||||
initMemory([[0x00, 0x33, [0xF7]]]);
|
initMemory([[0x00, 0x33, [0xF7]]]);
|
||||||
testCode([0x3F, 0x33, 0x7F], 1, {}, {
|
testCode([0x3F, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1825,7 +1825,7 @@ describe('65c02', function() {
|
||||||
it('BBR4 should branch if bit 4 clear', function() {
|
it('BBR4 should branch if bit 4 clear', function() {
|
||||||
initMemory([[0x00, 0x33, [0xEF]]]);
|
initMemory([[0x00, 0x33, [0xEF]]]);
|
||||||
testCode([0x4F, 0x33, 0x7F], 1, {}, {
|
testCode([0x4F, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1833,7 +1833,7 @@ describe('65c02', function() {
|
||||||
it('BBR5 should branch if bit 5 clear', function() {
|
it('BBR5 should branch if bit 5 clear', function() {
|
||||||
initMemory([[0x00, 0x33, [0xDF]]]);
|
initMemory([[0x00, 0x33, [0xDF]]]);
|
||||||
testCode([0x5F, 0x33, 0x7F], 1, {}, {
|
testCode([0x5F, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1841,7 +1841,7 @@ describe('65c02', function() {
|
||||||
it('BBR6 should branch if bit 6 clear', function() {
|
it('BBR6 should branch if bit 6 clear', function() {
|
||||||
initMemory([[0x00, 0x33, [0xBF]]]);
|
initMemory([[0x00, 0x33, [0xBF]]]);
|
||||||
testCode([0x6F, 0x33, 0x7F], 1, {}, {
|
testCode([0x6F, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1849,7 +1849,7 @@ describe('65c02', function() {
|
||||||
it('BBR7 should branch if bit 7 clear', function() {
|
it('BBR7 should branch if bit 7 clear', function() {
|
||||||
initMemory([[0x00, 0x33, [0x7F]]]);
|
initMemory([[0x00, 0x33, [0x7F]]]);
|
||||||
testCode([0x7F, 0x33, 0x7F], 1, {}, {
|
testCode([0x7F, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1922,7 +1922,7 @@ describe('65c02', function() {
|
||||||
it('BBS0 should branch if bit 0 set', function() {
|
it('BBS0 should branch if bit 0 set', function() {
|
||||||
initMemory([[0x00, 0x33, [0x01]]]);
|
initMemory([[0x00, 0x33, [0x01]]]);
|
||||||
testCode([0x8F, 0x33, 0x7F], 1, {}, {
|
testCode([0x8F, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1930,7 +1930,7 @@ describe('65c02', function() {
|
||||||
it('BBS0 should branch backward', function () {
|
it('BBS0 should branch backward', function () {
|
||||||
initMemory([[0x00, 0x33, [0x01]]]);
|
initMemory([[0x00, 0x33, [0x01]]]);
|
||||||
testCode([0x8F, 0x33, 0xFF], 1, {}, {
|
testCode([0x8F, 0x33, 0xFF], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0402
|
pc: 0x0402
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1938,7 +1938,7 @@ describe('65c02', function() {
|
||||||
it('BBS1 should branch if bit 1 set', function() {
|
it('BBS1 should branch if bit 1 set', function() {
|
||||||
initMemory([[0x00, 0x33, [0x02]]]);
|
initMemory([[0x00, 0x33, [0x02]]]);
|
||||||
testCode([0x9F, 0x33, 0x7F], 1, {}, {
|
testCode([0x9F, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1946,7 +1946,7 @@ describe('65c02', function() {
|
||||||
it('BBS2 should branch if bit 2 set', function() {
|
it('BBS2 should branch if bit 2 set', function() {
|
||||||
initMemory([[0x00, 0x33, [0x04]]]);
|
initMemory([[0x00, 0x33, [0x04]]]);
|
||||||
testCode([0xAF, 0x33, 0x7F], 1, {}, {
|
testCode([0xAF, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1954,7 +1954,7 @@ describe('65c02', function() {
|
||||||
it('BBS3 should branch if bit 3 set', function() {
|
it('BBS3 should branch if bit 3 set', function() {
|
||||||
initMemory([[0x00, 0x33, [0x08]]]);
|
initMemory([[0x00, 0x33, [0x08]]]);
|
||||||
testCode([0xBF, 0x33, 0x7F], 1, {}, {
|
testCode([0xBF, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1962,7 +1962,7 @@ describe('65c02', function() {
|
||||||
it('BBS4 should branch if bit 4 set', function() {
|
it('BBS4 should branch if bit 4 set', function() {
|
||||||
initMemory([[0x00, 0x33, [0x10]]]);
|
initMemory([[0x00, 0x33, [0x10]]]);
|
||||||
testCode([0xCF, 0x33, 0x7F], 1, {}, {
|
testCode([0xCF, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1970,7 +1970,7 @@ describe('65c02', function() {
|
||||||
it('BBS5 should branch if bit 5 set', function() {
|
it('BBS5 should branch if bit 5 set', function() {
|
||||||
initMemory([[0x00, 0x33, [0x20]]]);
|
initMemory([[0x00, 0x33, [0x20]]]);
|
||||||
testCode([0xDF, 0x33, 0x7F], 1, {}, {
|
testCode([0xDF, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1978,7 +1978,7 @@ describe('65c02', function() {
|
||||||
it('BBS6 should branch if bit 6 set', function() {
|
it('BBS6 should branch if bit 6 set', function() {
|
||||||
initMemory([[0x00, 0x33, [0x40]]]);
|
initMemory([[0x00, 0x33, [0x40]]]);
|
||||||
testCode([0xEF, 0x33, 0x7F], 1, {}, {
|
testCode([0xEF, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1986,7 +1986,7 @@ describe('65c02', function() {
|
||||||
it('BBS7 should branch if bit 7 set', function() {
|
it('BBS7 should branch if bit 7 set', function() {
|
||||||
initMemory([[0x00, 0x33, [0x80]]]);
|
initMemory([[0x00, 0x33, [0x80]]]);
|
||||||
testCode([0xFF, 0x33, 0x7F], 1, {}, {
|
testCode([0xFF, 0x33, 0x7F], 1, {}, {
|
||||||
cycles: 5,
|
cycles: 6,
|
||||||
pc: 0x0482
|
pc: 0x0482
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user