UNPKG

broken-neees

Version:

A really broken NEEES emulator that introduces glitches and random bugs on purpose!

120 lines (119 loc) 4.09 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _byte = _interopRequireDefault(require("../lib/byte")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const unsupported = () => { throw new Error("Unsupported."); }; function read(cpu, argument, hasPageCrossPenalty) { return cpu.memory.read(this.getAddress(cpu, argument, hasPageCrossPenalty)); } const addressingModes = { IMPLICIT: { inputSize: 0, getAddress: () => null, getValue: unsupported }, IMMEDIATE: { inputSize: 1, getAddress: unsupported, getValue: (cpu, value) => value }, ABSOLUTE: { inputSize: 2, getAddress: (cpu, address) => address, getValue: read }, ZERO_PAGE: { inputSize: 1, getAddress: (cpu, zeroPageAddress) => zeroPageAddress, getValue: read }, RELATIVE: { inputSize: 1, getAddress: (cpu, offset, hasPageCrossPenalty) => { const address = cpu.pc.getValue(); const newAddress = address + _byte.default.toS8(offset); const pageCrossed = _byte.default.highByteOf(address) !== _byte.default.highByteOf(newAddress); if (pageCrossed && hasPageCrossPenalty) cpu.extraCycles += 2; return _byte.default.toU16(newAddress); }, getValue: unsupported }, INDIRECT: { inputSize: 2, getAddress: (cpu, absoluteAddress) => { const msb = _byte.default.highByteOf(absoluteAddress); const lsb = _byte.default.lowByteOf(absoluteAddress); const low = cpu.memory.read(absoluteAddress); const high = cpu.memory.read(lsb === 0xff ? _byte.default.buildU16(msb, 0x00) : absoluteAddress + 1); return _byte.default.buildU16(high, low); }, getValue: unsupported }, INDEXED_ZERO_PAGE_X: { inputSize: 1, getAddress: (cpu, zeroPageAddress) => { return _byte.default.toU8(zeroPageAddress + cpu.x.getValue()); }, getValue: read }, INDEXED_ZERO_PAGE_Y: { inputSize: 1, getAddress: (cpu, zeroPageAddress) => { return _byte.default.toU8(zeroPageAddress + cpu.y.getValue()); }, getValue: read }, INDEXED_ABSOLUTE_X: { inputSize: 2, getAddress: (cpu, absoluteAddress, hasPageCrossPenalty) => { const address = absoluteAddress; const newAddress = address + cpu.x.getValue(); const pageCrossed = _byte.default.highByteOf(address) !== _byte.default.highByteOf(newAddress); if (pageCrossed && hasPageCrossPenalty) cpu.extraCycles += 1; return _byte.default.toU16(newAddress); }, getValue: read }, INDEXED_ABSOLUTE_Y: { inputSize: 2, getAddress: (cpu, absoluteAddress, hasPageCrossPenalty) => { const address = absoluteAddress; const newAddress = address + cpu.y.getValue(); const pageCrossed = _byte.default.highByteOf(address) !== _byte.default.highByteOf(newAddress); if (pageCrossed && hasPageCrossPenalty) cpu.extraCycles += 1; return _byte.default.toU16(newAddress); }, getValue: read }, INDEXED_INDIRECT: { inputSize: 1, getAddress: (cpu, zeroPageAddress) => { const start = _byte.default.toU8(zeroPageAddress + cpu.x.getValue()); const end = _byte.default.toU8(start + 1); return _byte.default.buildU16(cpu.memory.read(end), cpu.memory.read(start)); }, getValue: read }, INDIRECT_INDEXED: { inputSize: 1, getAddress: (cpu, zeroPageAddress, hasPageCrossPenalty) => { const start = _byte.default.toU8(zeroPageAddress); const end = _byte.default.toU8(start + 1); const address = _byte.default.buildU16(cpu.memory.read(end), cpu.memory.read(start)); const newAddress = address + cpu.y.getValue(); const pageCrossed = _byte.default.highByteOf(address) !== _byte.default.highByteOf(newAddress); if (pageCrossed && hasPageCrossPenalty) cpu.extraCycles += 1; return _byte.default.toU16(newAddress); }, getValue: read } }; for (let key in addressingModes) { addressingModes[key].id = key; } var _default = exports.default = addressingModes;