|
|
@@ -6,7 +6,97 @@ var Memory = require('../../common/memory.js'); |
|
|
|
|
|
|
|
|
|
|
|
function ADC(cpu){ |
|
|
|
|
|
|
|
switch(cpu.__step){ |
|
|
|
case 0: |
|
|
|
cpu.__mem.address = cpu.__PC; |
|
|
|
PCUp(cpu, 1); |
|
|
|
cpu.__opv = cpu.__mem.byte; |
|
|
|
if (cpu.__op == 0x69){ // Immediate |
|
|
|
cpu.__AR = ALU(cpu, 0, cpu.__AR, cpu.__opv); |
|
|
|
cpu.__op = -1; break; |
|
|
|
} |
|
|
|
case 1: |
|
|
|
switch (cpu.__op){ |
|
|
|
case 0x65: // Zero Page |
|
|
|
cpu.__mem.address = cpu.__opv; |
|
|
|
cpu.__AR = ALU(cpu, 0, cpu.__AR, 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; |
|
|
|
cpu.__AR = ALU(cpu, 0, cpu.__AR, 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; |
|
|
|
cpu.__AR = ALU(cpu, 0, cpu.__AR, 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); |
|
|
|
cpu.__AR = ALU(cpu, 0, cpu.__AR, 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; |
|
|
|
cpu.__AR = ALU(cpu, 0, cpu.__AR, 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; |
|
|
|
cpu.__AR = ALU(cpu, 0, cpu.__AR, cpu.__mem.byte); |
|
|
|
cpu.__op = -1; break; |
|
|
|
} |
|
|
|
cpu.__step += 1; |
|
|
|
} |
|
|
|
|
|
|
|
function AND(cpu){ |
|
|
@@ -173,7 +263,7 @@ function REGISTER(cpu){ |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
cpu.N = BIT.isOn(t, 7); |
|
|
|
cpu.N = (t >= 0x80); |
|
|
|
cpu.Z = (t === 0); |
|
|
|
cpu.__op = -1; |
|
|
|
} |
|
|
@@ -304,6 +394,33 @@ function PCDown(cpu, amount){ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function MemAddrFrom(cpu, addr){ |
|
|
|
cpu.__mem.address = addr; |
|
|
|
let v = cpu.__mem.byte; |
|
|
|
cpu.__mem.address = (addr + 1) & 0xFF; |
|
|
|
v |= cpu.__mem.byte << 8; |
|
|
|
return v; |
|
|
|
} |
|
|
|
|
|
|
|
function ALU(cpu, m, a, b){ |
|
|
|
let v = 0; |
|
|
|
switch(m){ |
|
|
|
case 0: // Addition |
|
|
|
v = (a + b) + ((cpu.C === 1) ? 1 : 0); |
|
|
|
cpu.C = (v >= 256); |
|
|
|
break; |
|
|
|
case 1: // Subtraction |
|
|
|
v = (a - b) - ((cpu.C === 0) ? 1 : 0); |
|
|
|
cpu.C = (v >= 0); |
|
|
|
break; |
|
|
|
} |
|
|
|
v &= 0xFF; |
|
|
|
cpu.V = (BIT.isOn(a, 7) === BIT.isOn(b, 7)) && (BIT.val(v, 7) !== BIT.val(a, 7)); |
|
|
|
cpu.N = BIT.val(v, 7); |
|
|
|
cpu.Z = (v === 0); |
|
|
|
return v; |
|
|
|
} |
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------- |
|
|
|
// -------------------------------------------------------------------------------------------- |
|
|
|
// -------------------------------------------------------------------------------------------- |
|
|
@@ -314,7 +431,7 @@ class CPU{ |
|
|
|
// Registers |
|
|
|
this.__PC = 0; // Program Counter (16 bit) |
|
|
|
this.__SP = 255; // Stack Pointer (8 bit) |
|
|
|
this.__PR = 0; // Status Register (8 bit) |
|
|
|
this.__PR = 32; // Status Register (8 bit, bit 5 is always 1) |
|
|
|
this.__XR = 0; // X Register (8 bit) |
|
|
|
this.__YR = 0; // Y Register (8 bit) |
|
|
|
this.__AR = 0; // Accumulator Register (8 bit) |