| /* | /* | ||||
| * Emulate a basic 6502 (MOS) chip. | * Emulate a basic 6502 (MOS) chip. | ||||
| */ | */ | ||||
| const BIT = require('../../utils/bitman.js'); | |||||
| const BITM = require('../../utils/bitman.js'); | |||||
| var Memory = require('../../common/memory.js'); | var Memory = require('../../common/memory.js'); | ||||
| } else if (cpu.__step === 1){ | } else if (cpu.__step === 1){ | ||||
| cpu.__AR = cpu.__mem.byte; | cpu.__AR = cpu.__mem.byte; | ||||
| cpu.Z = (cpu.__AR === 0); | cpu.Z = (cpu.__AR === 0); | ||||
| cpu.N = BIT.isOn(cpu.__AR, 7); | |||||
| cpu.N = BITM.isOn(cpu.__AR, 7); | |||||
| } else if (cpu.__step === 2){ | } else if (cpu.__step === 2){ | ||||
| cpu.__SP = (cpu.__SP === 255) ? 0 : cpu.__SP + 1; | cpu.__SP = (cpu.__SP === 255) ? 0 : cpu.__SP + 1; | ||||
| cpu.__op = -1; | cpu.__op = -1; | ||||
| break; | break; | ||||
| } | } | ||||
| cpu.__AR &= 0xFF; | cpu.__AR &= 0xFF; | ||||
| cpu.V = (BIT.isOn(cpu.__AR, 7) === BIT.isOn(b, 7)) && (BIT.val(v, 7) !== BIT.val(cpu.__AR, 7)); | |||||
| cpu.N = BIT.val(cpu.__AR, 7); | |||||
| cpu.V = (BITM.isOn(cpu.__AR, 7) === BITM.isOn(b, 7)) && (BITM.val(v, 7) !== BITM.val(cpu.__AR, 7)); | |||||
| cpu.N = BITM.val(cpu.__AR, 7); | |||||
| cpu.Z = (cpu.__AR === 0); | cpu.Z = (cpu.__AR === 0); | ||||
| return cpu.__AR; | return cpu.__AR; | ||||
| } | } | ||||
| // ---------------------------------------- | // ---------------------------------------- | ||||
| // Quick Flag Access | // Quick Flag Access | ||||
| get N(){return (BIT.isOn(this.__PR, 7)) ? 1 : 0;} | |||||
| set N(n){this.__PR = (n === true || n === 1) ? BIT.set(this.__PR, 7) : BIT.clear(this.__PR, 7);} | |||||
| get N(){return (BITM.isOn(this.__PR, 7)) ? 1 : 0;} | |||||
| set N(n){this.__PR = (n === true || n === 1) ? BITM.set(this.__PR, 7) : BITM.clear(this.__PR, 7);} | |||||
| get V(){return (BIT.isOn(this.__PR, 6)) ? 1 : 0;} | |||||
| set V(v){this.__PR = (v === true || v === 1) ? BIT.set(this.__PR, 6) : BIT.clear(this.__PR, 6);} | |||||
| get V(){return (BITM.isOn(this.__PR, 6)) ? 1 : 0;} | |||||
| set V(v){this.__PR = (v === true || v === 1) ? BITM.set(this.__PR, 6) : BITM.clear(this.__PR, 6);} | |||||
| get B(){return (BIT.isOn(this.__PR, 4)) ? 1 : 0;} | |||||
| set B(b){this.__PR = (b === true || b === 1) ? BIT.set(this.__PR, 4) : BIT.clear(this.__PR, 4);} | |||||
| get B(){return (BITM.isOn(this.__PR, 4)) ? 1 : 0;} | |||||
| set B(b){this.__PR = (b === true || b === 1) ? BITM.set(this.__PR, 4) : BITM.clear(this.__PR, 4);} | |||||
| get D(){return (BIT.isOn(this.__PR, 3)) ? 1 : 0;} | |||||
| set D(d){this.__PR = (d === true || d === 1) ? BIT.set(this.__PR, 3) : BIT.clear(this.__PR, 3);} | |||||
| get D(){return (BITM.isOn(this.__PR, 3)) ? 1 : 0;} | |||||
| set D(d){this.__PR = (d === true || d === 1) ? BITM.set(this.__PR, 3) : BITM.clear(this.__PR, 3);} | |||||
| get I(){return (BIT.isOn(this.__PR, 2)) ? 1 : 0;} | |||||
| set I(i){this.__PR = (i === true || i === 1) ? BIT.set(this.__PR, 2) : BIT.clear(this.__PR, 2);} | |||||
| get I(){return (BITM.isOn(this.__PR, 2)) ? 1 : 0;} | |||||
| set I(i){this.__PR = (i === true || i === 1) ? BITM.set(this.__PR, 2) : BITM.clear(this.__PR, 2);} | |||||
| get Z(){return (BIT.isOn(this.__PR, 1)) ? 1 : 0;} | |||||
| set Z(z){this.__PR = (z === true || z === 1) ? BIT.set(this.__PR, 1) : BIT.clear(this.__PR, 1);} | |||||
| get Z(){return (BITM.isOn(this.__PR, 1)) ? 1 : 0;} | |||||
| set Z(z){this.__PR = (z === true || z === 1) ? BITM.set(this.__PR, 1) : BITM.clear(this.__PR, 1);} | |||||
| get C(){return (BIT.isOn(this.__PR, 0)) ? 1 : 0;} | |||||
| set C(c){this.__PR = (c === true || c === 1) ? BIT.set(this.__PR, 0) : BIT.clear(this.__PR, 0);} | |||||
| get C(){return (BITM.isOn(this.__PR, 0)) ? 1 : 0;} | |||||
| set C(c){this.__PR = (c === true || c === 1) ? BITM.set(this.__PR, 0) : BITM.clear(this.__PR, 0);} | |||||
| // ---------------------------------------- | // ---------------------------------------- | ||||
| // Hardware interrupt triggers. Settable only. | // Hardware interrupt triggers. Settable only. | ||||
| } | } | ||||
| reset(){ | reset(){ | ||||
| // TODO: Read memory address $FFFC - FFFD to find PC start location. | |||||
| // TODO: Reset status registers that get changed on a reset. | |||||
| this.__mem.address = 0xFFFC; | |||||
| this.__PC = this.__mem.byte; | |||||
| this.__mem.address = 0xFFFD; | |||||
| this.__PC |= this.__mem.byte << 8; | |||||
| // Disabling the IRQ interrupts is the ONLY flag that must be set | |||||
| // during reset. The others are random. | |||||
| this.I = 1; | |||||
| } | } | ||||
| // ----------------------------------------- | // ----------------------------------------- | ||||
| // Set and Get Memory property. | // Set and Get Memory property. | ||||
| get memory(){return this.__mem;} | get memory(){return this.__mem;} | ||||
| set memory(m){ | set memory(m){ | ||||
| if (!(mem instanceof Memory)) | |||||
| if (!(m instanceof Memory)) | |||||
| throw new ValueError("Expected Memory instance object."); | throw new ValueError("Expected Memory instance object."); | ||||
| this.__mem = m; | this.__mem = m; | ||||
| } | } | ||||
| // TODO: Handle NMI Interrupt. | // TODO: Handle NMI Interrupt. | ||||
| } else if (this.__irq) { | } else if (this.__irq) { | ||||
| this.__irq = false; | this.__irq = false; | ||||
| if (!BIT.isOn(this.__PR, 5)){ | |||||
| if (!BITM.isOn(this.__PR, 5)){ | |||||
| // TODO: Handle IRQ Interrupt. | // TODO: Handle IRQ Interrupt. | ||||
| } | } | ||||
| } else { | } else { |