Apply Sather to stack operations.

This commit is contained in:
Will Scullin 2019-09-22 20:04:47 -07:00
parent 6348d52cfe
commit 859bd1ff8f
No known key found for this signature in database
GPG Key ID: 9092A5C0A673416B
2 changed files with 55 additions and 76 deletions

View File

@ -163,12 +163,12 @@ export default function CPU6502(options)
} }
function increment(a) { function increment(a) {
cycles += 1; cycles++;
return testNZ((a + 0x01) & 0xff); return testNZ((a + 0x01) & 0xff);
} }
function decrement(a) { function decrement(a) {
cycles += 1; cycles++;
return testNZ((a + 0xff) & 0xff); return testNZ((a + 0xff) & 0xff);
} }
@ -193,7 +193,7 @@ export default function CPU6502(options)
var result = readPages[page].read(page, off, dbg); var result = readPages[page].read(page, off, dbg);
if (!dbg) { if (!dbg) {
cycles += 1; cycles++;
} }
return result; return result;
@ -205,7 +205,7 @@ export default function CPU6502(options)
writePages[page].write(page, off, val); writePages[page].write(page, off, val);
cycles += 1; cycles++;
} }
function readWord(addr, dbg) { function readWord(addr, dbg) {
@ -225,51 +225,24 @@ export default function CPU6502(options)
return (msb << 8) | lsb; return (msb << 8) | lsb;
} }
function rawPushByte(val) {
writeByte(loc.STACK | sp, val);
sp = (sp + 0xff) & 0xff;
}
function rawPushWord(val) {
rawPushByte(val >> 8);
rawPushByte(val & 0xff);
}
function pushByte(val) { function pushByte(val) {
writeByte(loc.STACK | sp, val); writeByte(loc.STACK | sp, val);
sp = (sp + 0xff) & 0xff; sp = (sp + 0xff) & 0xff;
cycles += 1;
} }
function pushWord(val) { function pushWord(val) {
rawPushWord(val); pushByte(val >> 8);
cycles += 1; pushByte(val & 0xff);
}
function rawPullByte() {
sp = (sp + 0x01) & 0xff;
return readByte(loc.STACK | sp);
}
function rawPullWord() {
var lsb = rawPullByte(loc.STACK | sp);
var msb = rawPullByte(loc.STACK | sp);
return (msb << 8) | lsb;
} }
function pullByte() { function pullByte() {
sp = (sp + 0x01) & 0xff; sp = (sp + 0x01) & 0xff;
var result = readByte(loc.STACK | sp); return readByte(loc.STACK | sp);
cycles +=2;
return result;
} }
function pullWord() { function pullWordRaw() {
var lsb = rawPullByte(loc.STACK | sp); var lsb = pullByte(loc.STACK | sp);
var msb = rawPullByte(loc.STACK | sp); var msb = pullByte(loc.STACK | sp);
cycles += 2;
return (msb << 8) | lsb; return (msb << 8) | lsb;
} }
@ -466,7 +439,7 @@ export default function CPU6502(options)
// $0000,X // $0000,X
function readAddrAbsoluteX(opts) { function readAddrAbsoluteX(opts) {
var addr = readWordPC(); var addr = readWordPC();
if (!is65C02 || (opts && opts.inc)) { if (!is65C02 || (opts && opts.rwm)) {
readByte(addr); readByte(addr);
} else { } else {
cycles++; cycles++;
@ -484,8 +457,8 @@ export default function CPU6502(options)
/* Break */ /* Break */
function brk(readFn) { function brk(readFn) {
readFn(); readFn();
rawPushWord(pc); pushWord(pc);
rawPushByte(sr | flags.B); pushByte(sr | flags.B);
if (is65C02) { if (is65C02) {
setFlag(flags.D, false); setFlag(flags.D, false);
} }
@ -544,7 +517,7 @@ export default function CPU6502(options)
} }
function inc(readAddrFn) { function inc(readAddrFn) {
var addr = readAddrFn({inc: true}); var addr = readAddrFn({rwm: true});
writeByte(addr, increment(readByte(addr))); writeByte(addr, increment(readByte(addr)));
} }
@ -564,7 +537,7 @@ export default function CPU6502(options)
} }
function dec(readAddrFn) { function dec(readAddrFn) {
var addr = readAddrFn({inc: true}); var addr = readAddrFn({rwm: true});
writeByte(addr, decrement(readByte(addr))); writeByte(addr, decrement(readByte(addr)));
} }
@ -590,7 +563,7 @@ export default function CPU6502(options)
} }
function asl(readAddrFn) { function asl(readAddrFn) {
var addr = readAddrFn(); var addr = readAddrFn({rwm: true});
writeByte(addr, shiftLeft(readByte(addr))); writeByte(addr, shiftLeft(readByte(addr)));
} }
@ -606,7 +579,7 @@ export default function CPU6502(options)
} }
function lsr(readAddrFn) { function lsr(readAddrFn) {
var addr = readAddrFn(); var addr = readAddrFn({rwm: true});
writeByte(addr, shiftRight(readByte(addr))); writeByte(addr, shiftRight(readByte(addr)));
} }
@ -623,7 +596,7 @@ export default function CPU6502(options)
} }
function rol(readAddrFn) { function rol(readAddrFn) {
var addr = readAddrFn(); var addr = readAddrFn({rwm: true});
writeByte(addr, rotateLeft(readByte(addr))); writeByte(addr, rotateLeft(readByte(addr)));
} }
@ -640,7 +613,7 @@ export default function CPU6502(options)
} }
function ror(readAddrFn) { function ror(readAddrFn) {
var addr = readAddrFn(); var addr = readAddrFn({rwm: true});
writeByte(addr, rotateRight(readByte(addr))); writeByte(addr, rotateRight(readByte(addr)));
} }
@ -775,33 +748,33 @@ export default function CPU6502(options)
} }
/* Transfers and stack */ /* Transfers and stack */
function tax() { testNZ(xr = ar); cycles += 1; } function tax() { testNZ(xr = ar); cycles++; }
function txa() { testNZ(ar = xr); cycles += 1; } function txa() { testNZ(ar = xr); cycles++; }
function tay() { testNZ(yr = ar); cycles += 1; } function tay() { testNZ(yr = ar); cycles++; }
function tya() { testNZ(ar = yr); cycles += 1; } function tya() { testNZ(ar = yr); cycles++; }
function tsx() { testNZ(xr = sp); cycles += 1; } function tsx() { testNZ(xr = sp); cycles++; }
function txs() { sp = xr; cycles += 1; } function txs() { sp = xr; cycles++; }
function pha() { pushByte(ar); } function pha() { cycles++; pushByte(ar); }
function pla() { testNZ(ar = pullByte()); } function pla() { cycles++; readByte(0x0100 | sp); testNZ(ar = pullByte()); }
function phx() { pushByte(xr); } function phx() { cycles++; pushByte(xr); }
function plx() { testNZ(xr = pullByte()); } function plx() { cycles++; readByte(0x0100 | sp);testNZ(xr = pullByte()); }
function phy() { pushByte(yr); } function phy() { cycles++; pushByte(yr); }
function ply() { testNZ(yr = pullByte()); } function ply() { cycles++; readByte(0x0100 | sp); testNZ(yr = pullByte()); }
function php() { pushByte(sr | flags.B); } function php() { cycles++; pushByte(sr | flags.B); }
function plp() { sr = (pullByte() & ~flags.B) | 0x20; } function plp() { cycles++; readByte(0x0100 | sp); sr = (pullByte() & ~flags.B) | 0x20; }
/* Jump */ /* Jump */
function jmp(readAddrFn) { function jmp(readAddrFn) {
@ -809,40 +782,46 @@ export default function CPU6502(options)
} }
/* Jump Subroutine */ /* Jump Subroutine */
function jsr(readAddrFn) { function jsr() {
var dest = readAddrFn(); var lsb = readBytePC();
pushWord(pc - 1); readByte(0x0100 | sp);
pc = dest; pushWord(pc);
var msb = readBytePC();
pc = (msb << 8 | lsb) & 0xffff;
} }
/* Return from Subroutine */ /* Return from Subroutine */
function rts() { function rts() {
pc = (pullWord() + 1) & 0xffff; cycles++;
cycles += 1; readByte(0x0100 | sp);
var addr = pullWordRaw();
readByte(addr);
pc = (addr + 1) & 0xffff;
} }
/* Return from Subroutine */ /* Return from Subroutine */
function rti() { function rti() {
sr = rawPullByte() & ~flags.B; cycles++;
pc = rawPullWord(); readByte(0x0100 | sp);
cycles += 2; sr = pullByte() & ~flags.B;
pc = pullWordRaw();
} }
/* Set and Clear */ /* Set and Clear */
function set(flag) { function set(flag) {
sr |= flag; sr |= flag;
cycles += 1; cycles++;
} }
function clr(flag) { function clr(flag) {
sr &= ~flag; sr &= ~flag;
cycles += 1; cycles++;
} }
/* No-Op */ /* No-Op */
function nop(readAddrFn) { function nop(readAddrFn) {
readAddrFn(); readAddrFn();
cycles += 1; cycles++;
} }
var ops = { var ops = {

View File

@ -190,7 +190,7 @@ describe('CPU6502', function() {
cpu.irq(); cpu.irq();
expectState(DEFAULT_STATE, { expectState(DEFAULT_STATE, {
cycles: 7, cycles: 5,
s: FLAGS.DEFAULT | FLAGS.I, s: FLAGS.DEFAULT | FLAGS.I,
sp: 0xfc, sp: 0xfc,
pc: 0xff00 pc: 0xff00
@ -214,7 +214,7 @@ describe('CPU6502', function() {
cpu.nmi(); cpu.nmi();
expectState(DEFAULT_STATE, { expectState(DEFAULT_STATE, {
cycles: 7, cycles: 5,
s: FLAGS.DEFAULT | FLAGS.I, s: FLAGS.DEFAULT | FLAGS.I,
sp: 0xfc, sp: 0xfc,
pc: 0xff00 pc: 0xff00
@ -1544,7 +1544,7 @@ describe('65c02', function() {
cpu.irq(); cpu.irq();
expectState(DEFAULT_STATE, { expectState(DEFAULT_STATE, {
cycles: 7, cycles: 5,
s: FLAGS.DEFAULT | FLAGS.I, s: FLAGS.DEFAULT | FLAGS.I,
sp: 0xfc, sp: 0xfc,
pc: 0xff00 pc: 0xff00
@ -1559,7 +1559,7 @@ describe('65c02', function() {
cpu.nmi(); cpu.nmi();
expectState(DEFAULT_STATE, { expectState(DEFAULT_STATE, {
cycles: 7, cycles: 5,
s: FLAGS.DEFAULT | FLAGS.I, s: FLAGS.DEFAULT | FLAGS.I,
sp: 0xfc, sp: 0xfc,
pc: 0xff00 pc: 0xff00