Browse Source

More opcodes finished.

master
Bryan Miller 5 years ago
parent
commit
3e179155fd
1 changed files with 235 additions and 119 deletions
  1. +235
    -119
      src/chip/MOS6502/cpu.js

+ 235
- 119
src/chip/MOS6502/cpu.js View File

@@ -14,12 +14,16 @@ var Memory = require('../../common/memory.js');
// mode = 7 - Indirect, X
// mode = 8 - Indirect, Y
function ProcessOp(cpu, mode){
if (mode < 0 || mode > 9){return false;}

switch(cpu.__cycle){
case 0:
cpu.__mem.address = cpu.__PC;
PCUp(cpu, 1);
cpu.__opv = cpu.__mem.byte;
return (mode === 0);
if (mode === 0){
cpu.__mem.address = cpu.__PC;
PCUp(cpu, 1);
cpu.__opv = cpu.__mem.byte;
}
return (mode === 0 || mode === 9);
case 1:
switch(mode){
case 1: // Zero Page
@@ -108,119 +112,55 @@ function ProcessOp(cpu, mode){


function ADC(cpu){ // To be used by both the ADC and SBC op codes.
let pmode = [0x69, 0x65, 0x75, null, 0x6D, 0x7D, 0x79, 0x61, 0x71].indexOf(cpu.__op);
let pmode = [0x69, 0x65, 0x75, null, 0x6D, 0x7D, 0x79, 0x61, 0x71, null].indexOf(cpu.__op);
if (ProcessOp(cpu, pmode) === true){
cpu.__op = -1;
ALU(cpu, 0, cpu.__opv);
}
}

/*function MATHC(cpu, m){ // To be used by both the ADC and SBC op codes.
// m == 0 - Add
// m == 1 - Subtract
switch(cpu.__step){
case 0:
cpu.__mem.address = cpu.__PC;
PCUp(cpu, 1);
cpu.__opv = cpu.__mem.byte;
if (cpu.__op == 0x69){ // Immediate
ALU(cpu, m, cpu.__opv);
cpu.__op = -1; break;
}
case 1:
switch (cpu.__op){
case 0x65: // Zero Page
cpu.__mem.address = cpu.__opv;
ALU(cpu, m, cpu.__mem.byte);
cpu.__op = -1; break;
case 0x75: // Zero Page, X
cpu.__opv = (cpu.__opv + cpu.__XR) & 0xFF; break;
case 0x6D: // Absolute
case 0x7D: // Absolute, X
case 0x79: // Absolute, Y
cpu.__mem.address = cpu.__PC;
PCUp(cpu, 1);
cpu.__opv |= cpu.__mem.byte << 8; break;
case 0x61: // Indirect, X
cpu.__opv = (cpu.__opv + cpu.__XR) & 0xFF; break;
case 0x71: // Indirect, Y
cpu.__mem.address = cpu.__opv;
cpu.__opv = cpu.__mem.byte;
break;
}
break;
case 2:
switch (cpu.__op){
case 0x75: // Zero Page, X
case 0x6D: // Absolute
cpu.__mem.address = cpu.__opv;
ALU(cpu, m, cpu.__mem.byte);
cpu.__op = -1; break;
case 0x7D: // Absolute, X
case 0x79: // Absolute, Y
let s = (cpu.__op === 0x7D) ? cpu.__XR : cpu.__YR;
let l = (cpu.__opv & 0xFF) + s;
cpu.__opv = (cpu.__opv & 0xFF00) | (l & 0xFF);
if (l < 255){
cpu.__mem.address = cpu.__opv;
ALU(cpu, m, cpu.__mem.byte);
cpu.__op = -1;
}
break;
case 0x61: // Indirect, X
cpu.__mem.address = cpu.__opv;
cpu.__opv = cpu.__mem.byte;
break;
case 0x71: // Indirect, Y
cpu.__mem.address += 1;
cpu.__opv |= cpu.__mem.byte << 8;
break;
}
break;
case 3:
switch (cpu.__op){
case 0x7D: // Absolute, X
case 0x79: // Absolute, Y
let h = (cpu.__opv >> 8) + 1;
cpu.__mem.address = (cpu.__opv & 0xFF) | (h << 8);
ALU(cpu, m, cpu.__mem.byte);
cpu.__op = -1; break;
case 0x61: // Indirect, X
cpu.__mem.address += 1;
cpu.__opv |= cpu.__mem.byte << 8;
break;
case 0x71: // Indirect, Y
let l = (cpu.__opv & 0xFF) + cpu.__YR;
cpu.__opv = (cpu.__opv & 0xFF00) | (l & 0xFF);
if (l <= 255){
cpu.__mem.address = cpu.__opv;
ALU(cpu, m, cpu.__mem.byte);
cpu.__op = -1; break;
}
}
break;
case 4:
if (cpu.__op === 0x71){
let h = (cpu.__opv >> 8) + 1;
cpu.__opv = (cpu.__opv & 0x00FF) | (h << 8);
}
cpu.__mem.address = cpu.__opv;
ALU(cpu, m, cpu.__mem.byte);
cpu.__op = -1; break;
}
cpu.__step += 1;
}*/

function AND(cpu){

let pmode = [0x29, 0x25, 0x35, null, 0x2D, 0x3D, 0x39, 0x21, 0x31, null].indexOf(cpu.__op);
if (ProcessOp(cpu, pmode) === true){
cpu.__op = -1;
this.__AR &= this.__opv;
cpu.Z = (this.__AR === 0);
cpu.N = BITM.val(this.__AR, 7);
}
}

function ASL(cpu){

let pmode = [null, 0x06, 0x16, null, 0x0E, 0x1E, null, null, null, 0x0A].indexOf(cpu.__op);
if (cpu.__ophold === 1){pmode = -1;}
if (cpu.__ophold === 1 || ProcessOp(cpu, pmode) === true){
if (cpu.__ophold === 0){
cpu.__opv = (mode === 9) ? cpu.__AR : cpu.__opv;
cpu.C = BITM.val(cpu.__opv, 7);
cpu.__opv = cpu.__opv << 1;
cpu.__ophold = 1;
} else {
if (mode === 9){
cpu.__AR = cpu.__opv;
} else {
cpu.__mem.byte = cpu.__opv;
}
cpu.Z = (this.__opv === 0);
cpu.N = BITM.val(this.__opv, 7);
cpu.__op = -1;
cpu.__ophold = 0;
}
}
}

function BIT(cpu){

let pmode = [null, 0x24, null, null, 0x2C, null, null, null, null, null].indexOf(cpu.__op);
if (ProcessOp(cpu, pmode) === true){
cpu.__op = -1;
let v = this.__AR & this.__opv;
cpu.Z = (v === 0);
cpu.N = BITM.val(this.__opv, 7);
cpu.V = BITM.val(this.__opv, 6);
}
}

function BRANCH(cpu){
@@ -263,27 +203,98 @@ function BRANCH(cpu){
}

function BRK(cpu){

switch(cpu.__cycle){
case 0:
PCUp(cpu, 1);
case 1:
cpu.__mem.address = cpu.__SP;
cpu.__mem.byte = cpu.__PC & 0xFF;
cpu.__SP = ByteWrap(cpu.__SP, -1);
break;
case 2:
cpu.__mem.address += 1;
cpu.__mem.byte = cpu.__PC >> 8;
cpu.__SP = ByteWrap(cpu.__SP, -1);
break;
case 3:
cpu.__mem.address += 1;
cpu.__mem.byte = cpu.__PR;
cpu.__SP = ByteWrap(cpu.__SP, -1);
case 4:
cpu.__mem.address = 0xFFFE;
cpu.__PC = cpu.__mem.byte;
break;
case 5:
cpu.__mem.address = 0xFFFF;
cpu.__PC |= cpu.__mem.byte << 8;
cpu.B = 1;
cpu.__op = -1;
break;
}
cpu.__cycle += 1;
}

function CMP(cpu){

let pmode = [0xC9, 0xC5, 0xD5, null, 0xCD, 0xDD, 0xD9, 0xC1, 0xD1, null].indexOf(cpu.__op);
if (ProcessOp(cpu, pmode) === true){
cpu.__op = -1;
cpu.C = (cpu.__AR >= cpu.__opv);
cpu.Z = (this.__AR === cpu.__opv);
let v = this.__AR - cpu.__opv;
if (v < 0){v += 256;}
cpu.N = BITM.val(v, 7);
}
}

function CPX(cpu){

let pmode = [0xE0, 0xE4, null, null, 0xEC, null, null, null, null, null].indexOf(cpu.__op);
if (ProcessOp(cpu, pmode) === true){
cpu.__op = -1;
cpu.C = (cpu.__XR >= cpu.__opv);
cpu.Z = (this.__XR === cpu.__opv);
let v = this.__XR - cpu.__opv;
if (v < 0){v += 256;}
cpu.N = BITM.val(v, 7);
}
}

function CPY(cpu){

let pmode = [0xC0, 0xC4, null, null, 0xCC, null, null, null, null, null].indexOf(cpu.__op);
if (ProcessOp(cpu, pmode) === true){
cpu.__op = -1;
cpu.C = (cpu.__YR >= cpu.__opv);
cpu.Z = (this.__YR === cpu.__opv);
let v = this.__YR - cpu.__opv;
if (v < 0){v += 256;}
cpu.N = BITM.val(v, 7);
}
}

function DEC(cpu){

let pmode = [null, 0xC6, 0xD6, null, 0xCE, 0xDE, null, null, null, null].indexOf(cpu.__op);
if (cpu.__ophold === 1){pmode = -1;}
if (cpu.__ophold === 1 || ProcessOp(cpu, pmode) === true){
if (cpu.__ophold === 0){
cpu.__opv = ByteWrap(cpu.__opv, -1);
cpu.__ophold = 1;
} else {
cpu.__mem.byte = cpu.__opv;
cpu.Z = (this.__opv === 0);
cpu.N = BITM.val(this.__opv, 7);
cpu.__op = -1;
cpu.__ophold = 0;
}
}
}

function EOR(cpu){

let pmode = [0x49, 0x45, 0x55, null, 0x4D, 0x5D, 0x59, 0x41, 0x51, null].indexOf(cpu.__op);
if (ProcessOp(cpu, pmode) === true){
cpu.__op = -1;
cpu.__AR ^= cpu.__opv;
cpu.Z = (cpu.__AR === 0);
cpu.N = BITM.val(cpu.__AR, 7);
}
}

function FLAG(cpu){
@@ -307,19 +318,79 @@ function FLAG(cpu){
}

function INC(cpu){

let pmode = [null, 0xE6, 0xF6, null, 0xEE, 0xFE, null, null, null, null].indexOf(cpu.__op);
if (cpu.__ophold === 1){pmode = -1;}
if (cpu.__ophold === 1 || ProcessOp(cpu, pmode) === true){
if (cpu.__ophold === 0){
cpu.__opv = ByteWrap(cpu.__opv, 1);
cpu.__ophold = 1;
} else {
cpu.__mem.byte = cpu.__opv;
cpu.Z = (this.__opv === 0);
cpu.N = BITM.val(this.__opv, 7);
cpu.__op = -1;
cpu.__ophold = 0;
}
}
}

function JMP(cpu){

switch(cpu.__cycle){
case 0:
cpu.__mem.address = cpu.__PC;
cpu.__opv = cpu.__mem.byte;
PCUp(cpu, 1); break;
case 1:
cpu.__mem.address = cpu.__PC;
cpu.__opv |= cpu.__mem.byte << 8;
if (cpu.__op === 0x4C){
cpu.__PC = cpu.__opv;
cpu.__op = -1;
}
break;
case 2:
cpu.__mem.address = cpu.__opv;
cpu.__PC = cpu.__mem.byte;
break;
case 3:
cpu.__mem.address += 1;
cpu.__PC |= cpu.__mem.byte << 8;
cpu.__op = -1;
break;
}
cpu.__cycle += 1;
}

function JRS(cpu){

switch(cpu.__cycle){
case 0:
cpu.__mem.address = cpu.__PC;
cpu.__opv = cpu.__mem.byte;
PCUp(cpu, 1); break;
case 1:
// Discard stack data (or... No Op)
break;
case 2:
cpu.__mem.address = cpu.__SP;
cpu.__mem.byte = cpu.__PC & 0xFF;
cpu.__SP = ByteWrap(cpu.__SP, -1);
break;
case 3:
cpu.__mem.address -= 1;
cpu.__mem.byte = cpu.__PC >> 8;
cpu.__SP = ByteWrap(cpu.__SP, -1);
break;
case 4:
cpu.__mem.address = cpu.__PC;
cpu.__PC = cpu.__opv | (cpu.__mem.byte << 8)
cpu.__op = -1;
break;
}
cpu.__cycle += 1;
}

function LDA(cpu){
let pmode = [0xA9, 0xA5, 0xB5, null, 0xAD, 0xBD, 0xB9, 0xA1, 0xB1].indexOf(cpu.__op);
let pmode = [0xA9, 0xA5, 0xB5, null, 0xAD, 0xBD, 0xB9, 0xA1, 0xB1, null].indexOf(cpu.__op);
if (ProcessOp(cpu, pmode) === true){
cpu.__op = -1;
cpu.__AR = cpu.__opv;
@@ -329,19 +400,57 @@ function LDA(cpu){
}

function LDX(cpu){

let pmode = [0xA2, 0xA6, null, 0xB6, 0xAE, null, 0xBE, null, null, null].indexOf(cpu.__op);
if (ProcessOp(cpu, pmode) === true){
cpu.__op = -1;
cpu.__XR = cpu.__opv;
cpu.Z = (cpu.__XR === 0);
cpu.N = (cpu.__XR >= 0x80);
}
}

function LDY(cpu){

let pmode = [0xA0, 0xA4, 0xB4, null, 0xAC, 0xBC, null, null, null, null].indexOf(cpu.__op);
if (ProcessOp(cpu, pmode) === true){
cpu.__op = -1;
cpu.__YR = cpu.__opv;
cpu.Z = (cpu.__YR === 0);
cpu.N = (cpu.__YR >= 0x80);
}
}

function LSR(cpu){

let pmode = [null, 0x46, 0x56, null, 0x4E, 0x5E, null, null, null, 0x4A].indexOf(cpu.__op);
if (cpu.__ophold === 1){pmode = -1;}
if (cpu.__ophold === 1 || ProcessOp(cpu, pmode) === true){
if (cpu.__ophold === 0){
cpu.__opv = (mode === 9) ? cpu.__AR : cpu.__opv;
cpu.C = BITM.val(cpu.__opv, 0);
cpu.__opv = cpu.__opv >> 1;
cpu.__ophold = 1;
} else {
if (mode === 9){
cpu.__AR = cpu.__opv;
} else {
cpu.__mem.byte = cpu.__opv;
}
// TODO: Is Z and N effected by the A register, or by the resulting value? I think the latter.
cpu.Z = (this.__opv === 0);
cpu.N = BITM.val(this.__opv, 7);
cpu.__op = -1;
cpu.__ophold = 0;
}
}
}

function ORA(cpu){

let pmode = [0x09, 0x05, 0x15, null, 0x0D, 0x1D, 0x19, 0x01, 0x11, null].indexOf(cpu.__op);
if (ProcessOp(cpu, pmode) === true){
cpu.__op = -1;
cpu.__AR |= cpu.__opv;
cpu.Z = (cpu.__AR === 0);
cpu.N = BITM.val(cpu.__AR, 7);
}
}

function REGISTER(cpu){
@@ -484,6 +593,13 @@ function SamePage(a, b){
return ((a >> 8) == (b >> 8));
}

function ByteWrap(v, a){
v += a;
if (v < 0){v += 256;}
else if (v > 255){v -= 256;}
return v;
}

function PCHI(cpu, b){
cpu.__PC = (cpu.__PC & 0x00FF) | (b << 8);
}
@@ -566,7 +682,7 @@ class CPU{

// Variable for tracking tick operations.
this.__op = -1;
this.__opmem = 0;
this.__ophold = 0;
this.__opv = 0;
this.__cycle = 0;
this.__pcc = 0; // Program Counter Carry.

Loading…
Cancel
Save