|
|
@@ -1,7 +1,7 @@ |
|
|
|
/* |
|
|
|
* Emulate a basic 6502 (MOS) chip. |
|
|
|
*/ |
|
|
|
const BIT = require('../../utils/bitman.js'); |
|
|
|
const BITM = require('../../utils/bitman.js'); |
|
|
|
var Memory = require('../../common/memory.js'); |
|
|
|
|
|
|
|
|
|
|
@@ -319,7 +319,7 @@ function STACK(cpu){ |
|
|
|
} else if (cpu.__step === 1){ |
|
|
|
cpu.__AR = cpu.__mem.byte; |
|
|
|
cpu.Z = (cpu.__AR === 0); |
|
|
|
cpu.N = BIT.isOn(cpu.__AR, 7); |
|
|
|
cpu.N = BITM.isOn(cpu.__AR, 7); |
|
|
|
} else if (cpu.__step === 2){ |
|
|
|
cpu.__SP = (cpu.__SP === 255) ? 0 : cpu.__SP + 1; |
|
|
|
cpu.__op = -1; |
|
|
@@ -417,8 +417,8 @@ function ALU(cpu, m, b){ |
|
|
|
break; |
|
|
|
} |
|
|
|
cpu.__AR &= 0xFF; |
|
|
|
cpu.V = (BIT.isOn(cpu.__AR, 7) === BIT.isOn(b, 7)) && (BIT.val(v, 7) !== BIT.val(cpu.__AR, 7)); |
|
|
|
cpu.N = BIT.val(cpu.__AR, 7); |
|
|
|
cpu.V = (BITM.isOn(cpu.__AR, 7) === BITM.isOn(b, 7)) && (BITM.val(v, 7) !== BITM.val(cpu.__AR, 7)); |
|
|
|
cpu.N = BITM.val(cpu.__AR, 7); |
|
|
|
cpu.Z = (cpu.__AR === 0); |
|
|
|
return cpu.__AR; |
|
|
|
} |
|
|
@@ -467,26 +467,26 @@ class CPU{ |
|
|
|
|
|
|
|
// ---------------------------------------- |
|
|
|
// Quick Flag Access |
|
|
|
get N(){return (BIT.isOn(this.__PR, 7)) ? 1 : 0;} |
|
|
|
set N(n){this.__PR = (n === true || n === 1) ? BIT.set(this.__PR, 7) : BIT.clear(this.__PR, 7);} |
|
|
|
get N(){return (BITM.isOn(this.__PR, 7)) ? 1 : 0;} |
|
|
|
set N(n){this.__PR = (n === true || n === 1) ? BITM.set(this.__PR, 7) : BITM.clear(this.__PR, 7);} |
|
|
|
|
|
|
|
get V(){return (BIT.isOn(this.__PR, 6)) ? 1 : 0;} |
|
|
|
set V(v){this.__PR = (v === true || v === 1) ? BIT.set(this.__PR, 6) : BIT.clear(this.__PR, 6);} |
|
|
|
get V(){return (BITM.isOn(this.__PR, 6)) ? 1 : 0;} |
|
|
|
set V(v){this.__PR = (v === true || v === 1) ? BITM.set(this.__PR, 6) : BITM.clear(this.__PR, 6);} |
|
|
|
|
|
|
|
get B(){return (BIT.isOn(this.__PR, 4)) ? 1 : 0;} |
|
|
|
set B(b){this.__PR = (b === true || b === 1) ? BIT.set(this.__PR, 4) : BIT.clear(this.__PR, 4);} |
|
|
|
get B(){return (BITM.isOn(this.__PR, 4)) ? 1 : 0;} |
|
|
|
set B(b){this.__PR = (b === true || b === 1) ? BITM.set(this.__PR, 4) : BITM.clear(this.__PR, 4);} |
|
|
|
|
|
|
|
get D(){return (BIT.isOn(this.__PR, 3)) ? 1 : 0;} |
|
|
|
set D(d){this.__PR = (d === true || d === 1) ? BIT.set(this.__PR, 3) : BIT.clear(this.__PR, 3);} |
|
|
|
get D(){return (BITM.isOn(this.__PR, 3)) ? 1 : 0;} |
|
|
|
set D(d){this.__PR = (d === true || d === 1) ? BITM.set(this.__PR, 3) : BITM.clear(this.__PR, 3);} |
|
|
|
|
|
|
|
get I(){return (BIT.isOn(this.__PR, 2)) ? 1 : 0;} |
|
|
|
set I(i){this.__PR = (i === true || i === 1) ? BIT.set(this.__PR, 2) : BIT.clear(this.__PR, 2);} |
|
|
|
get I(){return (BITM.isOn(this.__PR, 2)) ? 1 : 0;} |
|
|
|
set I(i){this.__PR = (i === true || i === 1) ? BITM.set(this.__PR, 2) : BITM.clear(this.__PR, 2);} |
|
|
|
|
|
|
|
get Z(){return (BIT.isOn(this.__PR, 1)) ? 1 : 0;} |
|
|
|
set Z(z){this.__PR = (z === true || z === 1) ? BIT.set(this.__PR, 1) : BIT.clear(this.__PR, 1);} |
|
|
|
get Z(){return (BITM.isOn(this.__PR, 1)) ? 1 : 0;} |
|
|
|
set Z(z){this.__PR = (z === true || z === 1) ? BITM.set(this.__PR, 1) : BITM.clear(this.__PR, 1);} |
|
|
|
|
|
|
|
get C(){return (BIT.isOn(this.__PR, 0)) ? 1 : 0;} |
|
|
|
set C(c){this.__PR = (c === true || c === 1) ? BIT.set(this.__PR, 0) : BIT.clear(this.__PR, 0);} |
|
|
|
get C(){return (BITM.isOn(this.__PR, 0)) ? 1 : 0;} |
|
|
|
set C(c){this.__PR = (c === true || c === 1) ? BITM.set(this.__PR, 0) : BITM.clear(this.__PR, 0);} |
|
|
|
|
|
|
|
// ---------------------------------------- |
|
|
|
// Hardware interrupt triggers. Settable only. |
|
|
@@ -501,15 +501,21 @@ class CPU{ |
|
|
|
} |
|
|
|
|
|
|
|
reset(){ |
|
|
|
// TODO: Read memory address $FFFC - FFFD to find PC start location. |
|
|
|
// TODO: Reset status registers that get changed on a reset. |
|
|
|
this.__mem.address = 0xFFFC; |
|
|
|
this.__PC = this.__mem.byte; |
|
|
|
this.__mem.address = 0xFFFD; |
|
|
|
this.__PC |= this.__mem.byte << 8; |
|
|
|
|
|
|
|
// Disabling the IRQ interrupts is the ONLY flag that must be set |
|
|
|
// during reset. The others are random. |
|
|
|
this.I = 1; |
|
|
|
} |
|
|
|
|
|
|
|
// ----------------------------------------- |
|
|
|
// Set and Get Memory property. |
|
|
|
get memory(){return this.__mem;} |
|
|
|
set memory(m){ |
|
|
|
if (!(mem instanceof Memory)) |
|
|
|
if (!(m instanceof Memory)) |
|
|
|
throw new ValueError("Expected Memory instance object."); |
|
|
|
this.__mem = m; |
|
|
|
} |
|
|
@@ -531,7 +537,7 @@ class CPU{ |
|
|
|
// TODO: Handle NMI Interrupt. |
|
|
|
} else if (this.__irq) { |
|
|
|
this.__irq = false; |
|
|
|
if (!BIT.isOn(this.__PR, 5)){ |
|
|
|
if (!BITM.isOn(this.__PR, 5)){ |
|
|
|
// TODO: Handle IRQ Interrupt. |
|
|
|
} |
|
|
|
} else { |