|
|
|
|
|
|
|
|
function BRANCH(cpu){ |
|
|
function BRANCH(cpu){ |
|
|
switch(cpu.__step){ |
|
|
switch(cpu.__step){ |
|
|
case 0: |
|
|
case 0: |
|
|
cpu.__mem.address = this.__PC; |
|
|
|
|
|
let v = cpu.__mem.byte; |
|
|
|
|
|
cpu.__opv = v; |
|
|
|
|
|
break; |
|
|
|
|
|
case 1: |
|
|
|
|
|
let branch = false; |
|
|
let branch = false; |
|
|
switch(cpu.__op){ |
|
|
switch(cpu.__op){ |
|
|
case 0x10: // BPL |
|
|
case 0x10: // BPL |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
if (branch === false) |
|
|
if (branch === false) |
|
|
PCUp(cpu, 1); |
|
|
PCUp(cpu, 1); |
|
|
case 2: |
|
|
|
|
|
if (cpu.__step === 2){ |
|
|
|
|
|
if (cpu.__opv > 128){ |
|
|
|
|
|
PCDown(cpu, 255 - cpu.__opv); |
|
|
|
|
|
|
|
|
case 1: |
|
|
|
|
|
if (cpu.__step === 1){ |
|
|
|
|
|
cpu.__mem.address = this.__PC; |
|
|
|
|
|
let v = cpu.__mem.byte; |
|
|
|
|
|
if (v > 128){ |
|
|
|
|
|
PCDown(cpu, 255 - v); |
|
|
} else { |
|
|
} else { |
|
|
PCUp(cpu, cpu.__opv); |
|
|
|
|
|
|
|
|
PCUp(cpu, v); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
cpu.__op = -1; |
|
|
cpu.__op = -1; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function FLAG(cpu){ |
|
|
function FLAG(cpu){ |
|
|
|
|
|
|
|
|
|
|
|
switch (cpu.__op){ |
|
|
|
|
|
case 0x18: // CLC |
|
|
|
|
|
cpu.C = 0; break; |
|
|
|
|
|
case 0x38: // SEC |
|
|
|
|
|
cpu.C = 1; break; |
|
|
|
|
|
case 0x58: // CLI |
|
|
|
|
|
cpu.I = 0; break; |
|
|
|
|
|
case 0x78: // SEI |
|
|
|
|
|
cpu.I = 1; break; |
|
|
|
|
|
case 0xB8: // CLV |
|
|
|
|
|
cpu.V = 0; break; |
|
|
|
|
|
case 0xD8: // CLD |
|
|
|
|
|
cpu.D = 0; break; |
|
|
|
|
|
case 0xF8: // SED |
|
|
|
|
|
cpu.D = 1; break; |
|
|
|
|
|
} |
|
|
|
|
|
cpu.__op = -1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function INC(cpu){ |
|
|
function INC(cpu){ |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function REGISTER(cpu){ |
|
|
function REGISTER(cpu){ |
|
|
|
|
|
let t = 0; |
|
|
|
|
|
switch(this.__op){ |
|
|
|
|
|
case 0xAA: // TAX |
|
|
|
|
|
cpu.__XR = cpu.__AR; |
|
|
|
|
|
t = cpu.__XR; |
|
|
|
|
|
break; |
|
|
|
|
|
case 0x8A: // TXA |
|
|
|
|
|
cpu.__AR = cpu.__XR; |
|
|
|
|
|
t = cpu.__AR; |
|
|
|
|
|
break; |
|
|
|
|
|
case 0xCA: // DEX |
|
|
|
|
|
cpu.__XR = (cpu.__XR === 0) ? 255 : cpu.__XR - 1; |
|
|
|
|
|
t = cpu.__XR; |
|
|
|
|
|
break; |
|
|
|
|
|
case 0xE8: // INX |
|
|
|
|
|
cpu.__XR = (cpu.__XR === 255) ? 0 : cpu.__XR + 1; |
|
|
|
|
|
t = cpu.__XR; |
|
|
|
|
|
break; |
|
|
|
|
|
case 0xA8: // TAY |
|
|
|
|
|
cpu.__YR = cpu.__AR; |
|
|
|
|
|
t = cpu.__YR; |
|
|
|
|
|
break; |
|
|
|
|
|
case 0x98: // TYA |
|
|
|
|
|
cpu.__AR = cpu.__YR; |
|
|
|
|
|
t = cpu.__AR; |
|
|
|
|
|
break; |
|
|
|
|
|
case 0x88: // DEY |
|
|
|
|
|
cpu.__YR = (cpu.__YR === 0) ? 255 : cpu.__YR - 1; |
|
|
|
|
|
t = cpu.__YR; |
|
|
|
|
|
break; |
|
|
|
|
|
case 0xC8: // INY |
|
|
|
|
|
cpu.__YR = (cpu.__YR === 255) ? 0 : cpu.__YR + 1; |
|
|
|
|
|
t = cpu.__YR; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
cpu.N = BIT.isOn(t, 7); |
|
|
|
|
|
cpu.Z = (t === 0); |
|
|
|
|
|
cpu.__op = -1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function ROL(cpu){ |
|
|
function ROL(cpu){ |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function STACK(cpu){ |
|
|
function STACK(cpu){ |
|
|
|
|
|
|
|
|
|
|
|
switch(cpu.__op){ |
|
|
|
|
|
case 0x9A: // TXS |
|
|
|
|
|
cpu.__SP = cpu.__XR; |
|
|
|
|
|
cpu.__op = -1; |
|
|
|
|
|
break; |
|
|
|
|
|
case 0xBA: // TSX |
|
|
|
|
|
cpu.__XR = cpu.__SP; |
|
|
|
|
|
cpu.__op = -1; |
|
|
|
|
|
break; |
|
|
|
|
|
case 0x48: // PHA |
|
|
|
|
|
if (cpu.__step === 0){ |
|
|
|
|
|
cpu.__mem.address = 0x0100 | cpu.__SP; |
|
|
|
|
|
} else if (cpu.__step === 1){ |
|
|
|
|
|
cpu.__mem.byte = cpu.__AR; |
|
|
|
|
|
cpu.__SP = (cpu.__SP === 0) ? 255 : cpu.__SP - 1; |
|
|
|
|
|
cpu.__op = -1; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case 0x68: // PLA |
|
|
|
|
|
if (cpu.__step === 0){ |
|
|
|
|
|
cpu.__mem.address = 0x0100 | cpu.__SP; |
|
|
|
|
|
} else if (cpu.__step === 1){ |
|
|
|
|
|
cpu.__AR = cpu.__mem.byte; |
|
|
|
|
|
cpu.Z = (cpu.__AR === 0); |
|
|
|
|
|
cpu.N = BIT.isOn(cpu.__AR, 7); |
|
|
|
|
|
} else if (cpu.__step === 2){ |
|
|
|
|
|
cpu.__SP = (cpu.__SP === 255) ? 0 : cpu.__SP + 1; |
|
|
|
|
|
cpu.__op = -1; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case 0x08: // PHP |
|
|
|
|
|
if (cpu.__step === 0){ |
|
|
|
|
|
cpu.__mem.address = 0x0100 | cpu.__SP; |
|
|
|
|
|
} else if (cpu.__step === 1){ |
|
|
|
|
|
cpu.__mem.byte = cpu.__PR; |
|
|
|
|
|
cpu.__SP = (cpu.__SP === 0) ? 255 : cpu.__SP - 1; |
|
|
|
|
|
cpu.__op = -1; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case 0x28: // PLP |
|
|
|
|
|
if (cpu.__step === 0){ |
|
|
|
|
|
cpu.__mem.address = 0x0100 | cpu.__SP; |
|
|
|
|
|
} else if (cpu.__step === 1){ |
|
|
|
|
|
cpu.__SP = cpu.__mem.byte; |
|
|
|
|
|
} else if (cpu.__step === 2){ |
|
|
|
|
|
cpu.__SP = (cpu.__SP === 255) ? 0 : cpu.__SP + 1; |
|
|
|
|
|
cpu.__op = -1; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
cpu.__step += 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function STX(cpu){ |
|
|
function STX(cpu){ |
|
|
|
|
|
|
|
|
constructor(){ |
|
|
constructor(){ |
|
|
// Registers |
|
|
// Registers |
|
|
this.__PC = 0; // Program Counter (16 bit) |
|
|
this.__PC = 0; // Program Counter (16 bit) |
|
|
this.__IRQ = 0; // IRQ interrupt address code (16 bit) |
|
|
|
|
|
|
|
|
this.__SP = 255; // Stack Pointer (8 bit) |
|
|
this.__PR = 0; // Status Register (8 bit) |
|
|
this.__PR = 0; // Status Register (8 bit) |
|
|
this.__XR = 0; // X Register (8 bit) |
|
|
this.__XR = 0; // X Register (8 bit) |
|
|
this.__YR = 0; // Y Register (8 bit) |
|
|
this.__YR = 0; // Y Register (8 bit) |
|
|
|
|
|
|
|
|
// ---------------------------------------- |
|
|
// ---------------------------------------- |
|
|
// CPU Registers. Here for debug purposes. |
|
|
// CPU Registers. Here for debug purposes. |
|
|
get PC(){return this.__PC;} |
|
|
get PC(){return this.__PC;} |
|
|
|
|
|
get SP(){return this.__SP;} |
|
|
get P(){return this.__PR;} |
|
|
get P(){return this.__PR;} |
|
|
get X(){return this.__XR;} |
|
|
get X(){return this.__XR;} |
|
|
get Y(){return this.__YR;} |
|
|
get Y(){return this.__YR;} |
|
|
|
|
|
|
|
|
// ---------------------------------------- |
|
|
// ---------------------------------------- |
|
|
// Quick Flag Access |
|
|
// Quick Flag Access |
|
|
get N(){return (BIT.isOn(this.__PR, 0)) ? 1 : 0;} |
|
|
get N(){return (BIT.isOn(this.__PR, 0)) ? 1 : 0;} |
|
|
|
|
|
set N(n){this.__PR = (n === true || n === 1) ? BIT.set(this.__PR, 0) : BIT.clear(this.__PR, 0);} |
|
|
|
|
|
|
|
|
get V(){return (BIT.isOn(this.__PR, 1)) ? 1 : 0;} |
|
|
get V(){return (BIT.isOn(this.__PR, 1)) ? 1 : 0;} |
|
|
|
|
|
set V(v){this.__PR = (v === true || v === 1) ? BIT.set(this.__PR, 1) : BIT.clear(this.__PR, 1);} |
|
|
|
|
|
|
|
|
get B(){return (BIT.isOn(this.__PR, 3)) ? 1 : 0;} |
|
|
get B(){return (BIT.isOn(this.__PR, 3)) ? 1 : 0;} |
|
|
|
|
|
set B(b){this.__PR = (b === true || b === 1) ? BIT.set(this.__PR, 3) : BIT.clear(this.__PR, 3);} |
|
|
|
|
|
|
|
|
get D(){return (BIT.isOn(this.__PR, 4)) ? 1 : 0;} |
|
|
get D(){return (BIT.isOn(this.__PR, 4)) ? 1 : 0;} |
|
|
|
|
|
set D(d){this.__PR = (d === true || d === 1) ? BIT.set(this.__PR, 4) : BIT.clear(this.__PR, 4);} |
|
|
|
|
|
|
|
|
get I(){return (BIT.isOn(this.__PR, 5)) ? 1 : 0;} |
|
|
get I(){return (BIT.isOn(this.__PR, 5)) ? 1 : 0;} |
|
|
|
|
|
set I(i){this.__PR = (i === true || i === 1) ? BIT.set(this.__PR, 5) : BIT.clear(this.__PR, 5);} |
|
|
|
|
|
|
|
|
get Z(){return (BIT.isOn(this.__PR, 6)) ? 1 : 0;} |
|
|
get Z(){return (BIT.isOn(this.__PR, 6)) ? 1 : 0;} |
|
|
|
|
|
set Z(z){this.__PR = (z === true || z === 1) ? BIT.set(this.__PR, 6) : BIT.clear(this.__PR, 6);} |
|
|
|
|
|
|
|
|
get C(){return (BIT.isOn(this.__PR, 7)) ? 1 : 0;} |
|
|
get C(){return (BIT.isOn(this.__PR, 7)) ? 1 : 0;} |
|
|
|
|
|
set C(c){this.__PR = (c === true || c === 1) ? BIT.set(this.__PR, 7) : BIT.clear(this.__PR, 7);} |
|
|
|
|
|
|
|
|
// ---------------------------------------- |
|
|
// ---------------------------------------- |
|
|
// Hardware interrupt triggers. Settable only. |
|
|
// Hardware interrupt triggers. Settable only. |