UNPKG

nes-emu

Version:

A NES emulator

225 lines (224 loc) 5.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _helpers = require("../../helpers"); const instructions = () => [ /** * Add with Carry * * Adds the contents of `value` to A together with the carry bit, updating the Z and N flags. * The C and V flags are set in case of unsigned and signed overflow respectively. * Signed overflow occurs when `Positive + Positive = Negative` or `Negative + Negative = Positive`. */ { id: "ADC", needsValue: true, execute: ADC }, /** * Arithmetic Shift Left * * Shifts all the bits of the value held at `address` one bit to the left. * Bit 7 is placed in the C flag and bit 0 is set to 0. * The Z and N flags are updated too. */ { id: "ASL", execute: (_ref, address) => { let { cpu, memoryBus } = _ref; const value = cpu.memory.readAt(address); const result = value << 1; const newValue = _helpers.Byte.force8Bit(result); memoryBus.cpu.writeAt(address, newValue); cpu.flags.updateZeroAndNegative(newValue); cpu.flags.c = _helpers.Byte.hasOverflow(result); } }, /** * Decrement Memory * * Substracts one from the value held at `address`, updating the Z and N flags. */ { id: "DEC", execute: (_ref2, address) => { let { cpu, memoryBus } = _ref2; const value = cpu.memory.readAt(address); const newValue = _helpers.Byte.force8Bit(value - 1); cpu.flags.updateZeroAndNegative(newValue); memoryBus.cpu.writeAt(address, newValue); } }, /** * Decrement X Register * * Substracts one from X, updating the Z and N flags. */ { id: "DEX", execute: DE_("x") }, /** * Decrement Y Register * * Substracts one from Y, updating the Z and N flags. */ { id: "DEY", execute: DE_("y") }, /** * Increment Memory * * Adds one to the value held at `address`, updating the Z and N flags. */ { id: "INC", execute: (_ref3, address) => { let { cpu, memoryBus } = _ref3; const value = cpu.memory.readAt(address); const newValue = _helpers.Byte.force8Bit(value + 1); cpu.flags.updateZeroAndNegative(newValue); memoryBus.cpu.writeAt(address, newValue); } }, /** * Increment X Register * * Adds one to X, updating the Z and N flags. */ { id: "INX", execute: IN_("x") }, /** * Increment Y Register * * Adds one to Y, updating the Z and N flags. */ { id: "INY", execute: IN_("y") }, /** * Logical Shift Right * * Shifts all the bits of the value held at `address` one bit to the right. * Bit 0 is placed in the C flag and bit 7 is set to 0. * The Z and N flags are updated too. */ { id: "LSR", execute: (_ref4, address) => { let { cpu, memoryBus } = _ref4; const value = cpu.memory.readAt(address); const result = value >> 1; const newValue = _helpers.Byte.force8Bit(result); memoryBus.cpu.writeAt(address, newValue); cpu.flags.updateZeroAndNegative(newValue); cpu.flags.c = !!_helpers.Byte.getBit(value, 0); } }, /** * Rotate Left * * Moves all the bits of the value held at `address` one place to the left. * Bit 7 is placed in the C flag and bit 0 is filled with the old value of the C flag. * The Z and N flags are updated too. */ { id: "ROL", execute: (_ref5, address) => { let { cpu, memoryBus } = _ref5; const value = cpu.memory.readAt(address); const result = value << 1 | +cpu.flags.c; const newValue = _helpers.Byte.force8Bit(result); memoryBus.cpu.writeAt(address, newValue); cpu.flags.updateZeroAndNegative(newValue); cpu.flags.c = !!_helpers.Byte.getBit(value, 7); } }, /** * Rotate Right * * Moves all the bits of the value held at `address` one place to the right. * Bit 0 is placed in the C flag and bit 7 is filled with the old value of the C flag. * The Z and N flags are updated too. */ { id: "ROR", execute: (_ref6, address) => { let { cpu, memoryBus } = _ref6; const value = cpu.memory.readAt(address); const result = value >> 1 | +cpu.flags.c << 7; const newValue = _helpers.Byte.force8Bit(result); memoryBus.cpu.writeAt(address, newValue); cpu.flags.updateZeroAndNegative(newValue); cpu.flags.c = !!_helpers.Byte.getBit(value, 0); } }, /** * Subtract with Carry * * Substracts the contents of `value` to A together with the not of the carry bit. * The Z, N, C (set if there was no borrow), and V (set when sign is wrong) flags are updated. * It's implemented as an ADC call with the negative representation of `value` - 1. */ { id: "SBC", needsValue: true, execute: (context, value) => ADC(context, _helpers.Byte.negate(value) - 1) }]; const ADC = (_ref7, value) => { let { cpu } = _ref7; const oldValue = cpu.registers.a.value; const result = oldValue + value + cpu.flags.c; const newValue = _helpers.Byte.force8Bit(result); cpu.registers.a.value = newValue; cpu.flags.updateZeroAndNegative(newValue); cpu.flags.c = _helpers.Byte.hasOverflow(result); cpu.flags.v = _helpers.Byte.isPositive(oldValue) && _helpers.Byte.isPositive(value) && _helpers.Byte.isNegative(newValue) || _helpers.Byte.isNegative(oldValue) && _helpers.Byte.isNegative(value) && _helpers.Byte.isPositive(newValue); }; const DE_ = registerName => { return _ref8 => { let { cpu } = _ref8; const register = cpu.registers[registerName]; register.decrement(); cpu.flags.updateZeroAndNegative(register.value); }; }; const IN_ = registerName => { return _ref9 => { let { cpu } = _ref9; const register = cpu.registers[registerName]; register.increment(); cpu.flags.updateZeroAndNegative(register.value); }; }; var _default = exports.default = instructions();