nes-emu
Version: 
A NES emulator
113 lines (112 loc) • 4.52 kB
JavaScript
;
var _ = _interopRequireDefault(require(".."));
var _createTestContext = _interopRequireDefault(require("../../../helpers/createTestContext"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const should = require("chai").Should();
describe("addressings", () => {
  let cpu, memory, context;
  beforeEach(() => {
    ({
      cpu,
      memory,
      context
    } = (0, _createTestContext.default)());
  });
  const testExtraCycle = (register, addressing, base1, offset1, base2, offset2) => {
    describe("when the operation can take extra cycles", () => {
      it("adds a cycle if a page-crossed event occurs", () => {
        cpu.registers[register].value = offset1;
        _.default[addressing].getAddress(context, base1, true);
        cpu.extraCycles.should.equal(1);
      });
      it("doesnt add a cycle if no page-crossed event occurs", () => {
        cpu.registers[register].value = offset2;
        _.default[addressing].getAddress(context, base2, true);
        cpu.extraCycles.should.equal(0);
      });
    });
  };
  ["x", "y"].forEach(register => {
    const name = register.toUpperCase();
    describe("indexedAbsolute".concat(name), () => {
      it("returns the address + ".concat(name), () => {
        cpu.registers[register].value = 180;
        _.default["INDEXED_ABSOLUTE_".concat(name)].getAddress(context, 1000).should.equal(1180);
      });
      it("cannot cross the limit of memory", () => {
        cpu.registers[register].value = 2;
        _.default["INDEXED_ABSOLUTE_".concat(name)].getAddress(context, 0xffff).should.equal(0x0001);
      });
      testExtraCycle(register, "INDEXED_ABSOLUTE_".concat(name), 1000, 180, 900, 20);
    });
  });
  ["x", "y"].forEach(register => {
    const name = register.toUpperCase();
    describe("indexedZeroPage".concat(name), () => {
      it("returns the address + ".concat(name), () => {
        cpu.registers[register].value = 20;
        _.default["INDEXED_ZERO_PAGE_".concat(name)].getAddress(context, 130).should.equal(150);
      });
      it("cannot cross the first page", () => {
        cpu.registers[register].value = 200;
        _.default["INDEXED_ZERO_PAGE_".concat(name)].getAddress(context, 130).should.equal(74);
      });
    });
  });
  describe("indexedIndirectX", () => {
    it("dereferences the address + X", () => {
      cpu.registers.x.value = 180;
      memory.writeAt(195, 0x12);
      memory.writeAt(196, 0xfe);
      _.default.INDEXED_INDIRECT_X.getAddress(context, 15).should.equal(0xfe12);
    });
    it("cannot cross the first page", () => {
      cpu.registers.x.value = 255;
      memory.writeAt(0, 0x12);
      memory.writeAt(1, 0xfe);
      _.default.INDEXED_INDIRECT_X.getAddress(context, 1).should.equal(0xfe12);
    });
    it("cannot dereference the address outside the first page", () => {
      cpu.registers.x.value = 254;
      memory.writeAt(255, 0x12);
      memory.writeAt(0, 0xfe);
      _.default.INDEXED_INDIRECT_X.getAddress(context, 1).should.equal(0xfe12);
    });
  });
  describe("indexedIndirectY", () => {
    it("dereferences the address and then adds Y", () => {
      cpu.registers.y.value = 0xb4;
      memory.writeAt(130, 0x12);
      memory.writeAt(131, 0xfe);
      _.default.INDEXED_INDIRECT_Y.getAddress(context, 130).should.equal(0xfec6);
    });
    it("cannot cross the limit of memory", () => {
      cpu.registers.y.value = 3;
      memory.writeAt(130, 0xff);
      memory.writeAt(131, 0xff);
      _.default.INDEXED_INDIRECT_Y.getAddress(context, 130).should.equal(2);
    });
    it("cannot dereference the address outside the first page", () => {
      cpu.registers.y.value = 3;
      memory.writeAt(0xff, 0x12);
      memory.writeAt(0x00, 0xfe);
      _.default.INDEXED_INDIRECT_Y.getAddress(context, 0xff).should.equal(0xfe15);
    });
    describe("when the operation can take extra cycles", () => {
      it("adds a cycle if a page-crossed event occurs", () => {
        cpu.registers.y.value = 0xfc;
        memory.writeAt(130, 0x12);
        memory.writeAt(131, 0xfa);
        _.default.INDEXED_INDIRECT_Y.getAddress(context, 130, true);
        cpu.extraCycles.should.equal(1);
      });
      it("doesnt add a cycle if no page-crossed event occurs", () => {
        cpu.registers.y.value = 0xb4;
        memory.writeAt(130, 0x12);
        memory.writeAt(131, 0xfe);
        _.default.INDEXED_INDIRECT_Y.getAddress(context, 130, true);
        cpu.extraCycles.should.equal(0);
      });
    });
  });
});