| @@ -24,11 +24,6 @@ function BIT(cpu){ | |||
| function BRANCH(cpu){ | |||
| switch(cpu.__step){ | |||
| case 0: | |||
| cpu.__mem.address = this.__PC; | |||
| let v = cpu.__mem.byte; | |||
| cpu.__opv = v; | |||
| break; | |||
| case 1: | |||
| let branch = false; | |||
| switch(cpu.__op){ | |||
| case 0x10: // BPL | |||
| @@ -50,12 +45,14 @@ function BRANCH(cpu){ | |||
| } | |||
| if (branch === false) | |||
| 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 { | |||
| PCUp(cpu, cpu.__opv); | |||
| PCUp(cpu, v); | |||
| } | |||
| } | |||
| cpu.__op = -1; | |||
| @@ -88,7 +85,23 @@ function EOR(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){ | |||
| @@ -124,7 +137,45 @@ function ORA(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){ | |||
| @@ -152,7 +203,57 @@ function STA(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){ | |||
| @@ -212,7 +313,7 @@ class CPU{ | |||
| constructor(){ | |||
| // Registers | |||
| 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.__XR = 0; // X Register (8 bit) | |||
| this.__YR = 0; // Y Register (8 bit) | |||
| @@ -239,6 +340,7 @@ class CPU{ | |||
| // ---------------------------------------- | |||
| // CPU Registers. Here for debug purposes. | |||
| get PC(){return this.__PC;} | |||
| get SP(){return this.__SP;} | |||
| get P(){return this.__PR;} | |||
| get X(){return this.__XR;} | |||
| get Y(){return this.__YR;} | |||
| @@ -247,12 +349,25 @@ class CPU{ | |||
| // ---------------------------------------- | |||
| // Quick Flag Access | |||
| 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;} | |||
| 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;} | |||
| 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;} | |||
| 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;} | |||
| 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;} | |||
| 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;} | |||
| set C(c){this.__PR = (c === true || c === 1) ? BIT.set(this.__PR, 7) : BIT.clear(this.__PR, 7);} | |||
| // ---------------------------------------- | |||
| // Hardware interrupt triggers. Settable only. | |||