UNPKG

nes-emu

Version:

A NES emulator

89 lines (87 loc) 2.98 kB
"use strict"; var _memory = require("../memory"); var _constants = require("./constants"); var _constants2 = _interopRequireDefault(require("../constants")); var _createTestContext = _interopRequireDefault(require("../helpers/createTestContext")); var _helpers = require("../helpers"); var _lodash = _interopRequireDefault(require("lodash")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const should = require("chai").Should(); const registersOf = cpu => _lodash.default.mapValues(cpu.registers, reg => reg.value); describe("CPU", () => { let cpu, memory; beforeEach(() => { ({ cpu, memory } = (0, _createTestContext.default)(context => { // mock the whole memory map const memory = new _memory.MemoryChunk(_constants2.default.CPU_ADDRESSED_MEMORY); _helpers.WithContext.apply(memory); context.cpu.memory = memory; // define sample program: NOP ; LDA #$05 ; STA $0201 memory.write2BytesAt(_constants.interrupts.RESET.vector, 0x1234); [0xea, 0xa9, 0x05, 0x8d, 0x01, 0x02].forEach((byte, i) => memory.writeAt(0x1234 + i, byte)); })); }); it("initializes all variables", () => { cpu.pc.value.should.equal(0x1234); cpu.sp.value.should.equal(0xfd); cpu.flags.should.include({ n: false, v: false, d: false, i: true, z: false, c: false }); cpu.cycle.should.equal(7); registersOf(cpu).should.include({ x: 0, y: 0, a: 0 }); }); it("can run 3 simple operations", () => { let cycles; cycles = cpu.step(); cycles.should.equal(2); cpu.pc.value.should.equal(0x1235); cpu.cycle.should.equal(9); cycles = cpu.step(); cycles.should.equal(2); cpu.pc.value.should.equal(0x1237); cpu.cycle.should.equal(11); cpu.registers.a.value.should.equal(5); cycles = cpu.step(); cycles.should.equal(4); cpu.pc.value.should.equal(0x123a); cpu.cycle.should.equal(15); memory.readAt(0x0201).should.equal(5); }); _lodash.default.values(_constants.interrupts).forEach(interrupt => { it("can handle ".concat(interrupt.id, " interrupts"), () => { cpu.step(); cpu.pc.value.should.equal(0x1235); cpu.flags.i = false; memory.write2BytesAt(interrupt.vector, 0x3125); cpu.interrupt(interrupt); cpu.stack.pop().should.equal(0b00100000); cpu.stack.pop2Bytes().should.equal(0x1235); cpu.cycle.should.equal(16); cpu.flags.i.should.equal(true); cpu.pc.value.should.equal(0x3125); }); }); it("ignores IRQ interrupts when the I flag is set", () => { cpu.step(); cpu.pc.value.should.equal(0x1235); cpu.flags.i = true; memory.write2BytesAt(_constants.interrupts.IRQ.vector, 0x3125); cpu.interrupt(_constants.interrupts.IRQ); cpu.sp.value.should.equal(0xfd); cpu.cycle.should.equal(9); cpu.flags.i.should.equal(true); cpu.pc.value.should.equal(0x1235); }); });