nes-emu
Version:
A NES emulator
225 lines (224 loc) • 5.76 kB
JavaScript
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();
;