broken-neees
Version:
A really broken NEEES emulator that introduces glitches and random bugs on purpose!
120 lines (119 loc) • 4.09 kB
JavaScript
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;
;