| function ADC(cpu){ | 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){ | function AND(cpu){ | ||||
| break; | break; | ||||
| } | } | ||||
| cpu.N = BIT.isOn(t, 7); | |||||
| cpu.N = (t >= 0x80); | |||||
| cpu.Z = (t === 0); | cpu.Z = (t === 0); | ||||
| cpu.__op = -1; | cpu.__op = -1; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| 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; | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------- | ||||
| // -------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------- | ||||
| // -------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------- | ||||
| // Registers | // Registers | ||||
| this.__PC = 0; // Program Counter (16 bit) | this.__PC = 0; // Program Counter (16 bit) | ||||
| this.__SP = 255; // Stack Pointer (8 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.__XR = 0; // X Register (8 bit) | ||||
| this.__YR = 0; // Y Register (8 bit) | this.__YR = 0; // Y Register (8 bit) | ||||
| this.__AR = 0; // Accumulator Register (8 bit) | this.__AR = 0; // Accumulator Register (8 bit) |