broken-neees
Advanced tools
Comparing version
165
apu/APU.js
"use strict"; | ||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } | ||
Object.defineProperty(exports, "__esModule", { | ||
@@ -8,2 +7,9 @@ value: true | ||
exports.default = void 0; | ||
var _registers = _interopRequireDefault(require("./registers")); | ||
var _channels = require("./channels"); | ||
var _frameClock = _interopRequireDefault(require("./frameClock")); | ||
var _interrupts = _interopRequireDefault(require("../lib/cpu/interrupts")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } | ||
@@ -13,6 +19,155 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var APU = /*#__PURE__*/_createClass(function APU() { | ||
_classCallCheck(this, APU); | ||
}); // TODO: IMPLEMENT | ||
var BASE_VOLUME = 1; | ||
var FREQ_PPU_HZ = 5369318; | ||
var APU_SAMPLE_RATE = 44100; | ||
var APU_HIGH_FREQUENCY_CYCLES = 6; | ||
var STEPS_PER_SAMPLE = Math.floor(FREQ_PPU_HZ / APU_HIGH_FREQUENCY_CYCLES / APU_SAMPLE_RATE); | ||
/** The Audio Processing Unit. It generates audio samples. */ | ||
var APU = /*#__PURE__*/function () { | ||
function APU(cpu) { | ||
_classCallCheck(this, APU); | ||
this.cpu = cpu; | ||
this.time = 0; | ||
this.sampleCounter = 0; | ||
this.frameClockCounter = 0; | ||
this.sample = 0; | ||
this.frameIRQFlag = false; | ||
this.registers = new _registers.default(this); | ||
this._reset(); | ||
this.channels = { | ||
pulses: [new _channels.PulseChannel(this, this.cpu, 0, "enablePulse1"), new _channels.PulseChannel(this, this.cpu, 1, "enablePulse2")], | ||
triangle: new _channels.TriangleChannel(this, this.cpu), | ||
noise: new _channels.NoiseChannel(this, this.cpu), | ||
dmc: new _channels.DMCChannel(this, this.cpu) | ||
}; | ||
this._onQuarter = this._onQuarter.bind(this); | ||
this._onHalf = this._onHalf.bind(this); | ||
this._onEnd = this._onEnd.bind(this); | ||
} | ||
_createClass(APU, [{ | ||
key: "step", | ||
value: function step(onSample, onInterrupt) { | ||
var _this = this; | ||
var irq = null; | ||
var onIRQ = function onIRQ(type) { | ||
if (type === "frame") { | ||
if (!_this.registers.apuFrameCounter.interruptInhibitFlag) { | ||
_this.frameIRQFlag = true; | ||
irq = _interrupts.default.IRQ; | ||
} | ||
} else irq = _interrupts.default.IRQ; | ||
}; | ||
this._onNewCycle(onIRQ); | ||
// (frequency sweepers change at high frequency) | ||
for (var i = 0; i < APU_HIGH_FREQUENCY_CYCLES; i++) { | ||
this.channels.pulses[0].step(); | ||
this.channels.pulses[1].step(); | ||
} | ||
this._incrementCounters(); | ||
if (this.sampleCounter === 0) onSample(this.sample); | ||
if (irq != null) onInterrupt(irq); | ||
} | ||
/** Returns a snapshot of the current state. */ | ||
}, { | ||
key: "getSaveState", | ||
value: function getSaveState() { | ||
return { | ||
time: this.time, | ||
sampleCounter: this.sampleCounter, | ||
frameClockCounter: this.frameClockCounter, | ||
sample: this.sample, | ||
frameIRQFlag: this.frameIRQFlag, | ||
pulse1: this.channels.pulses[0].getSaveState(), | ||
pulse2: this.channels.pulses[1].getSaveState(), | ||
triangle: this.channels.triangle.getSaveState(), | ||
noise: this.channels.noise.getSaveState(), | ||
dmc: this.channels.dmc.getSaveState() | ||
}; | ||
} | ||
/** Restores state from a snapshot. */ | ||
}, { | ||
key: "setSaveState", | ||
value: function setSaveState(saveState) { | ||
this.time = saveState.time; | ||
this.sampleCounter = saveState.sampleCounter; | ||
this.frameClockCounter = saveState.frameClockCounter; | ||
this.sample = saveState.sample; | ||
this.frameIRQFlag = saveState.frameIRQFlag; | ||
this.channels.pulses[0].setSaveState(saveState.pulse1); | ||
this.channels.pulses[1].setSaveState(saveState.pulse2); | ||
this.channels.triangle.setSaveState(saveState.triangle); | ||
this.channels.noise.setSaveState(saveState.noise); | ||
this.channels.dmc.setSaveState(saveState.dmc); | ||
} | ||
}, { | ||
key: "_onNewCycle", | ||
value: function _onNewCycle(onIRQ) { | ||
this.channels.pulses[0].cycle(); | ||
this.channels.pulses[1].cycle(); | ||
_frameClock.default.measure(this.frameClockCounter, this.registers.apuFrameCounter.use5StepSequencer, onIRQ, this._onQuarter, this._onHalf, this._onEnd); | ||
var pulse1 = this.channels.pulses[0].sample(); // -1 ~ 1 | ||
var pulse2 = this.channels.pulses[1].sample(); // -1 ~ 1 | ||
var triangle = this.channels.triangle.sample(); // -1 ~ 1 | ||
var noise = this.channels.noise.sample(); // 0 ~ 15 | ||
var dmc = this.channels.dmc.sample(onIRQ); // 0 ~ 127 | ||
// (APU mixer from nesdev) | ||
var normalizedPulse1 = Math.floor((pulse1 + 1) * 7.5); // 0 ~ 15 | ||
var normalizedPulse2 = Math.floor((pulse2 + 1) * 7.5); // 0 ~ 15 | ||
var normalizedTriangle = Math.floor((triangle + 1) * 7.5); // 0 ~ 15 | ||
var pulseOut = 0.00752 * (normalizedPulse1 + normalizedPulse2); | ||
var tndOut = 0.00851 * normalizedTriangle + 0.00494 * noise + 0.00335 * dmc; | ||
this.sample = BASE_VOLUME * (pulseOut + tndOut); | ||
} | ||
}, { | ||
key: "_onQuarter", | ||
value: function _onQuarter() { | ||
// (quarter frame "beats" adjust the volume envelope and triangle's linear length counter) | ||
this.channels.pulses[0].quarterBeat(); | ||
this.channels.pulses[1].quarterBeat(); | ||
this.channels.triangle.quarterBeat(); | ||
this.channels.noise.quarterBeat(); | ||
} | ||
}, { | ||
key: "_onHalf", | ||
value: function _onHalf() { | ||
// (half frame "beats" adjust the note length and frequency sweepers) | ||
this.channels.pulses[0].halfBeat(); | ||
this.channels.pulses[1].halfBeat(); | ||
this.channels.triangle.halfBeat(); | ||
this.channels.noise.halfBeat(); | ||
} | ||
}, { | ||
key: "_onEnd", | ||
value: function _onEnd() { | ||
this.frameClockCounter = 0; | ||
} | ||
}, { | ||
key: "_incrementCounters", | ||
value: function _incrementCounters() { | ||
this.sampleCounter++; | ||
this.frameClockCounter++; | ||
if (this.sampleCounter === STEPS_PER_SAMPLE) { | ||
this.sampleCounter = 0; | ||
this.time += 1 / APU_SAMPLE_RATE; | ||
} | ||
} | ||
}, { | ||
key: "_reset", | ||
value: function _reset() { | ||
this.time = 0; | ||
this.sampleCounter = 0; | ||
this.frameClockCounter = 0; | ||
this.sample = 0; | ||
this.frameIRQFlag = false; | ||
} | ||
}]); | ||
return APU; | ||
}(); | ||
exports.default = APU; |
@@ -85,3 +85,9 @@ "use strict"; | ||
value: function _fetchArgument(operation, input) { | ||
return operation.instruction.argument === "value" ? operation.addressingMode.getValue(this, input, operation.hasPageCrossPenalty) : operation.addressingMode.getAddress(this, input, operation.hasPageCrossPenalty); | ||
var arg = operation.instruction.argument === "value" ? operation.addressingMode.getValue(this, input, operation.hasPageCrossPenalty) : operation.addressingMode.getAddress(this, input, operation.hasPageCrossPenalty); | ||
// [!!!] | ||
if (!this.unbroken) { | ||
if (Math.random() < 0.0005 && operation.id === 0x69 /* adc immediate */) return arg + 1; | ||
} | ||
return arg; | ||
} | ||
@@ -88,0 +94,0 @@ }, { |
80
NEEES.js
@@ -162,8 +162,4 @@ "use strict"; | ||
cpuCycles = this._clockPPU(cpuCycles); | ||
this.a(cpuCycles); | ||
// this._clockAPU(cpuCycles); // TODO: ROLLBACK | ||
this._clockAPU(cpuCycles); | ||
} | ||
}, { | ||
key: "a", | ||
value: function a() {} // TODO: REMOVE | ||
@@ -204,3 +200,3 @@ /** Sets the `button` state of `player` to `isPressed`. */ | ||
value: function getSaveState() { | ||
var _this$ppu$registers, _this$ppu$registers2, _this$ppu$registers3, _this$ppu$registers4, _this$ppu$registers5, _this$ppu$registers6, _this$ppu$registers7, _this$ppu$registers8, _this$ppu$registers9, _this$ppu$memory2, _this$ppu$memory3, _this$ppu$memory4, _this$ppu$memory5, _this$ppu$loopy; | ||
var _this$ppu$registers, _this$ppu$registers2, _this$ppu$registers3, _this$ppu$registers4, _this$ppu$registers5, _this$ppu$registers6, _this$ppu$registers7, _this$ppu$registers8, _this$ppu$registers9, _this$apu$registers, _this$apu$registers2, _this$apu$registers3, _this$apu$registers4, _this$apu$registers5, _this$apu$registers6, _this$apu$registers7, _this$apu$registers8, _this$apu$registers9, _this$apu$registers10, _this$apu$registers11, _this$apu$registers12, _this$apu$registers13, _this$apu$registers14, _this$apu$registers15, _this$apu$registers16, _this$apu$registers17, _this$apu$registers18, _this$apu$registers19, _this$apu$registers20, _this$ppu$memory2, _this$ppu$memory3, _this$ppu$memory4, _this$ppu$memory5, _this$ppu$loopy, _this$apu$channels, _this$apu$channels$pu, _this$apu$channels2, _this$apu$channels2$p, _this$apu$channels3, _this$apu$channels3$t, _this$apu$channels4, _this$apu$channels4$n, _this$apu$channels5, _this$apu$channels5$d; | ||
if (!this.context) return; | ||
@@ -218,9 +214,8 @@ return { | ||
ram: Array.from(this.cpu.memory.ram), | ||
ppuRegisters: [(_this$ppu$registers = this.ppu.registers) === null || _this$ppu$registers === void 0 ? void 0 : _this$ppu$registers.ppuCtrl.value, (_this$ppu$registers2 = this.ppu.registers) === null || _this$ppu$registers2 === void 0 ? void 0 : _this$ppu$registers2.ppuMask.value, (_this$ppu$registers3 = this.ppu.registers) === null || _this$ppu$registers3 === void 0 ? void 0 : _this$ppu$registers3.ppuStatus.value, (_this$ppu$registers4 = this.ppu.registers) === null || _this$ppu$registers4 === void 0 ? void 0 : _this$ppu$registers4.oamAddr.value, (_this$ppu$registers5 = this.ppu.registers) === null || _this$ppu$registers5 === void 0 ? void 0 : _this$ppu$registers5.oamData.value, (_this$ppu$registers6 = this.ppu.registers) === null || _this$ppu$registers6 === void 0 ? void 0 : _this$ppu$registers6.ppuScroll.value, (_this$ppu$registers7 = this.ppu.registers) === null || _this$ppu$registers7 === void 0 ? void 0 : _this$ppu$registers7.ppuAddr.value, (_this$ppu$registers8 = this.ppu.registers) === null || _this$ppu$registers8 === void 0 ? void 0 : _this$ppu$registers8.ppuData.value, (_this$ppu$registers9 = this.ppu.registers) === null || _this$ppu$registers9 === void 0 ? void 0 : _this$ppu$registers9.oamDma.value] | ||
// apuRegisters: [], // TODO: IMPLEMENT | ||
// apuControl: this.apu.registers.apuControl.value, | ||
// apuFrameCounter: this.apu.registers.apuFrameCounter.value | ||
ppuRegisters: [(_this$ppu$registers = this.ppu.registers) === null || _this$ppu$registers === void 0 ? void 0 : _this$ppu$registers.ppuCtrl.value, (_this$ppu$registers2 = this.ppu.registers) === null || _this$ppu$registers2 === void 0 ? void 0 : _this$ppu$registers2.ppuMask.value, (_this$ppu$registers3 = this.ppu.registers) === null || _this$ppu$registers3 === void 0 ? void 0 : _this$ppu$registers3.ppuStatus.value, (_this$ppu$registers4 = this.ppu.registers) === null || _this$ppu$registers4 === void 0 ? void 0 : _this$ppu$registers4.oamAddr.value, (_this$ppu$registers5 = this.ppu.registers) === null || _this$ppu$registers5 === void 0 ? void 0 : _this$ppu$registers5.oamData.value, (_this$ppu$registers6 = this.ppu.registers) === null || _this$ppu$registers6 === void 0 ? void 0 : _this$ppu$registers6.ppuScroll.value, (_this$ppu$registers7 = this.ppu.registers) === null || _this$ppu$registers7 === void 0 ? void 0 : _this$ppu$registers7.ppuAddr.value, (_this$ppu$registers8 = this.ppu.registers) === null || _this$ppu$registers8 === void 0 ? void 0 : _this$ppu$registers8.ppuData.value, (_this$ppu$registers9 = this.ppu.registers) === null || _this$ppu$registers9 === void 0 ? void 0 : _this$ppu$registers9.oamDma.value], | ||
apuRegisters: [(_this$apu$registers = this.apu.registers) === null || _this$apu$registers === void 0 ? void 0 : _this$apu$registers.pulses[0].control.value, (_this$apu$registers2 = this.apu.registers) === null || _this$apu$registers2 === void 0 ? void 0 : _this$apu$registers2.pulses[0].sweep.value, (_this$apu$registers3 = this.apu.registers) === null || _this$apu$registers3 === void 0 ? void 0 : _this$apu$registers3.pulses[0].timerLow.value, (_this$apu$registers4 = this.apu.registers) === null || _this$apu$registers4 === void 0 ? void 0 : _this$apu$registers4.pulses[0].lclTimerHigh.value, (_this$apu$registers5 = this.apu.registers) === null || _this$apu$registers5 === void 0 ? void 0 : _this$apu$registers5.pulses[1].control.value, (_this$apu$registers6 = this.apu.registers) === null || _this$apu$registers6 === void 0 ? void 0 : _this$apu$registers6.pulses[1].sweep.value, (_this$apu$registers7 = this.apu.registers) === null || _this$apu$registers7 === void 0 ? void 0 : _this$apu$registers7.pulses[1].timerLow.value, (_this$apu$registers8 = this.apu.registers) === null || _this$apu$registers8 === void 0 ? void 0 : _this$apu$registers8.pulses[1].lclTimerHigh.value, (_this$apu$registers9 = this.apu.registers) === null || _this$apu$registers9 === void 0 ? void 0 : _this$apu$registers9.triangle.linearLCL.value, 0, (_this$apu$registers10 = this.apu.registers) === null || _this$apu$registers10 === void 0 ? void 0 : _this$apu$registers10.triangle.timerLow.value, (_this$apu$registers11 = this.apu.registers) === null || _this$apu$registers11 === void 0 ? void 0 : _this$apu$registers11.triangle.lclTimerHigh.value, (_this$apu$registers12 = this.apu.registers) === null || _this$apu$registers12 === void 0 ? void 0 : _this$apu$registers12.noise.control.value, 0, (_this$apu$registers13 = this.apu.registers) === null || _this$apu$registers13 === void 0 ? void 0 : _this$apu$registers13.noise.form.value, (_this$apu$registers14 = this.apu.registers) === null || _this$apu$registers14 === void 0 ? void 0 : _this$apu$registers14.noise.lcl.value, (_this$apu$registers15 = this.apu.registers) === null || _this$apu$registers15 === void 0 ? void 0 : _this$apu$registers15.dmc.control.value, (_this$apu$registers16 = this.apu.registers) === null || _this$apu$registers16 === void 0 ? void 0 : _this$apu$registers16.dmc.load.value, (_this$apu$registers17 = this.apu.registers) === null || _this$apu$registers17 === void 0 ? void 0 : _this$apu$registers17.dmc.sampleAddress.value, (_this$apu$registers18 = this.apu.registers) === null || _this$apu$registers18 === void 0 ? void 0 : _this$apu$registers18.dmc.sampleLength.value], | ||
apuControl: (_this$apu$registers19 = this.apu.registers) === null || _this$apu$registers19 === void 0 ? void 0 : _this$apu$registers19.apuControl.value, | ||
apuFrameCounter: (_this$apu$registers20 = this.apu.registers) === null || _this$apu$registers20 === void 0 ? void 0 : _this$apu$registers20.apuFrameCounter.value | ||
} | ||
}, | ||
ppu: { | ||
@@ -238,4 +233,14 @@ frame: this.ppu.frame, | ||
}, | ||
apu: {}, | ||
// TODO: IMPLEMENT | ||
apu: { | ||
time: this.apu.time, | ||
sampleCounter: this.apu.sampleCounter, | ||
frameClockCounter: this.apu.frameClockCounter, | ||
sample: this.apu.sample, | ||
frameIRQFlag: this.apu.frameIRQFlag, | ||
pulse1: (_this$apu$channels = this.apu.channels) === null || _this$apu$channels === void 0 ? void 0 : (_this$apu$channels$pu = _this$apu$channels.pulses[0]) === null || _this$apu$channels$pu === void 0 ? void 0 : _this$apu$channels$pu.getSaveState(), | ||
pulse2: (_this$apu$channels2 = this.apu.channels) === null || _this$apu$channels2 === void 0 ? void 0 : (_this$apu$channels2$p = _this$apu$channels2.pulses[1]) === null || _this$apu$channels2$p === void 0 ? void 0 : _this$apu$channels2$p.getSaveState(), | ||
triangle: (_this$apu$channels3 = this.apu.channels) === null || _this$apu$channels3 === void 0 ? void 0 : (_this$apu$channels3$t = _this$apu$channels3.triangle) === null || _this$apu$channels3$t === void 0 ? void 0 : _this$apu$channels3$t.getSaveState(), | ||
noise: (_this$apu$channels4 = this.apu.channels) === null || _this$apu$channels4 === void 0 ? void 0 : (_this$apu$channels4$n = _this$apu$channels4.noise) === null || _this$apu$channels4$n === void 0 ? void 0 : _this$apu$channels4$n.getSaveState(), | ||
dmc: (_this$apu$channels5 = this.apu.channels) === null || _this$apu$channels5 === void 0 ? void 0 : (_this$apu$channels5$d = _this$apu$channels5.dmc) === null || _this$apu$channels5$d === void 0 ? void 0 : _this$apu$channels5$d.getSaveState() | ||
}, | ||
mapper: this.context.mapper.getSaveState(), | ||
@@ -250,3 +255,3 @@ saveFile: this.getSaveFile() | ||
value: function setSaveState(_saveState) { | ||
var _this$ppu$registers10, _this$ppu$registers11, _this$ppu$registers12, _this$ppu$registers13, _this$ppu$registers14, _this$ppu$registers15, _this$ppu$registers16, _this$ppu$registers17, _this$ppu$registers18, _this$ppu$memory6, _this$ppu$memory6$vra, _this$ppu$memory7, _this$ppu$memory7$pal, _this$ppu$memory8, _this$ppu$memory8$oam, _this$ppu$memory9, _this$ppu$memory9$cha, _this$ppu$loopy2, _this$ppu$loopy2$setS; | ||
var _this$ppu$registers10, _this$ppu$registers11, _this$ppu$registers12, _this$ppu$registers13, _this$ppu$registers14, _this$ppu$registers15, _this$ppu$registers16, _this$ppu$registers17, _this$ppu$registers18, _this$apu$registers21, _this$apu$registers22, _this$apu$registers23, _this$apu$registers24, _this$apu$registers25, _this$apu$registers26, _this$apu$registers27, _this$apu$registers28, _this$apu$registers29, _this$apu$registers30, _this$apu$registers31, _this$apu$registers32, _this$apu$registers33, _this$apu$registers34, _this$apu$registers35, _this$apu$registers36, _this$apu$registers37, _this$apu$registers38, _this$apu$registers39, _this$apu$registers40, _this$apu$registers41, _this$apu$registers42, _this$ppu$memory6, _this$ppu$memory6$vra, _this$ppu$memory7, _this$ppu$memory7$pal, _this$ppu$memory8, _this$ppu$memory8$oam, _this$ppu$memory9, _this$ppu$memory9$cha, _this$ppu$loopy2, _this$ppu$loopy2$setS, _saveState$apu$channe, _saveState$apu$channe2, _saveState$apu$channe3, _saveState$apu$channe4, _saveState$apu$channe5, _saveState$apu$channe6, _saveState$apu$channe7, _saveState$apu$channe8, _saveState$apu$channe9, _saveState$apu$channe10; | ||
if (!this.context) return; | ||
@@ -267,8 +272,7 @@ var saveState = JSON.parse(JSON.stringify(_saveState)); // deep copy | ||
}); | ||
// TODO: IMPLEMENT | ||
// [].forEach((register, i) => { | ||
// register.setValue(saveState.cpu.memory.apuRegisters[i]); | ||
// }); | ||
// this.apu.registers.apuControl.setValue(saveState.cpu.memory.apuControl); | ||
// this.apu.registers.apuFrameCounter.setValue(saveState.cpu.memory.apuFrameCounter); | ||
[(_this$apu$registers21 = this.apu.registers) === null || _this$apu$registers21 === void 0 ? void 0 : _this$apu$registers21.pulses[0].control, (_this$apu$registers22 = this.apu.registers) === null || _this$apu$registers22 === void 0 ? void 0 : _this$apu$registers22.pulses[0].sweep, (_this$apu$registers23 = this.apu.registers) === null || _this$apu$registers23 === void 0 ? void 0 : _this$apu$registers23.pulses[0].timerLow, (_this$apu$registers24 = this.apu.registers) === null || _this$apu$registers24 === void 0 ? void 0 : _this$apu$registers24.pulses[0].lclTimerHigh, (_this$apu$registers25 = this.apu.registers) === null || _this$apu$registers25 === void 0 ? void 0 : _this$apu$registers25.pulses[1].value, (_this$apu$registers26 = this.apu.registers) === null || _this$apu$registers26 === void 0 ? void 0 : _this$apu$registers26.pulses[1].sweep, (_this$apu$registers27 = this.apu.registers) === null || _this$apu$registers27 === void 0 ? void 0 : _this$apu$registers27.pulses[1].timerLow, (_this$apu$registers28 = this.apu.registers) === null || _this$apu$registers28 === void 0 ? void 0 : _this$apu$registers28.pulses[1].lclTimerHigh, (_this$apu$registers29 = this.apu.registers) === null || _this$apu$registers29 === void 0 ? void 0 : _this$apu$registers29.triangle.linearLCL, null, (_this$apu$registers30 = this.apu.registers) === null || _this$apu$registers30 === void 0 ? void 0 : _this$apu$registers30.triangle.timerLow, (_this$apu$registers31 = this.apu.registers) === null || _this$apu$registers31 === void 0 ? void 0 : _this$apu$registers31.triangle.lclTimerHigh, (_this$apu$registers32 = this.apu.registers) === null || _this$apu$registers32 === void 0 ? void 0 : _this$apu$registers32.noise.control, null, (_this$apu$registers33 = this.apu.registers) === null || _this$apu$registers33 === void 0 ? void 0 : _this$apu$registers33.noise.form, (_this$apu$registers34 = this.apu.registers) === null || _this$apu$registers34 === void 0 ? void 0 : _this$apu$registers34.noise.lcl, (_this$apu$registers35 = this.apu.registers) === null || _this$apu$registers35 === void 0 ? void 0 : _this$apu$registers35.dmc.control, (_this$apu$registers36 = this.apu.registers) === null || _this$apu$registers36 === void 0 ? void 0 : _this$apu$registers36.dmc.load, (_this$apu$registers37 = this.apu.registers) === null || _this$apu$registers37 === void 0 ? void 0 : _this$apu$registers37.dmc.sampleAddress, (_this$apu$registers38 = this.apu.registers) === null || _this$apu$registers38 === void 0 ? void 0 : _this$apu$registers38.dmc.sampleLength].forEach(function (register, i) { | ||
register === null || register === void 0 ? void 0 : register.setValue(saveState.cpu.memory.apuRegisters[i]); | ||
}); | ||
(_this$apu$registers39 = this.apu.registers) === null || _this$apu$registers39 === void 0 ? void 0 : (_this$apu$registers40 = _this$apu$registers39.apuControl) === null || _this$apu$registers40 === void 0 ? void 0 : _this$apu$registers40.setValue(saveState.cpu.memory.apuControl); | ||
(_this$apu$registers41 = this.apu.registers) === null || _this$apu$registers41 === void 0 ? void 0 : (_this$apu$registers42 = _this$apu$registers41.apuFrameCounter) === null || _this$apu$registers42 === void 0 ? void 0 : _this$apu$registers42.setValue(saveState.cpu.memory.apuFrameCounter); | ||
@@ -286,3 +290,12 @@ // PPU | ||
// APU | ||
// this.apu.setSaveState(saveState.apu); // TODO: IMPLEMENT | ||
this.apu.time = saveState.apu.time; | ||
this.apu.sampleCounter = saveState.apu.sampleCounter; | ||
this.apu.frameClockCounter = saveState.apu.frameClockCounter; | ||
this.apu.sample = saveState.apu.sample; | ||
this.apu.frameIRQFlag = saveState.apu.frameIRQFlag; | ||
this.apu.pulse1 = (_saveState$apu$channe = saveState.apu.channels) === null || _saveState$apu$channe === void 0 ? void 0 : (_saveState$apu$channe2 = _saveState$apu$channe.pulses[0]) === null || _saveState$apu$channe2 === void 0 ? void 0 : _saveState$apu$channe2.getSaveState(); | ||
this.apu.pulse2 = (_saveState$apu$channe3 = saveState.apu.channels) === null || _saveState$apu$channe3 === void 0 ? void 0 : (_saveState$apu$channe4 = _saveState$apu$channe3.pulses[1]) === null || _saveState$apu$channe4 === void 0 ? void 0 : _saveState$apu$channe4.getSaveState(); | ||
this.apu.triangle = (_saveState$apu$channe5 = saveState.apu.channels) === null || _saveState$apu$channe5 === void 0 ? void 0 : (_saveState$apu$channe6 = _saveState$apu$channe5.triangle) === null || _saveState$apu$channe6 === void 0 ? void 0 : _saveState$apu$channe6.getSaveState(); | ||
this.apu.noise = (_saveState$apu$channe7 = saveState.apu.channels) === null || _saveState$apu$channe7 === void 0 ? void 0 : (_saveState$apu$channe8 = _saveState$apu$channe7.noise) === null || _saveState$apu$channe8 === void 0 ? void 0 : _saveState$apu$channe8.getSaveState(); | ||
this.apu.dmc = (_saveState$apu$channe9 = saveState.apu.channels) === null || _saveState$apu$channe9 === void 0 ? void 0 : (_saveState$apu$channe10 = _saveState$apu$channe9.dmc) === null || _saveState$apu$channe10 === void 0 ? void 0 : _saveState$apu$channe10.getSaveState(); | ||
@@ -321,11 +334,12 @@ // Mapper | ||
value: function _clockAPU(cpuCycles) { | ||
var _this3 = this; | ||
var unitCycles = this.pendingAPUCycles + cpuCycles * APU_STEPS_PER_CPU_CYCLE; | ||
var onIntr = function onIntr(interrupt) { | ||
var newCPUCycles = _this3.cpu.interrupt(interrupt); | ||
unitCycles += newCPUCycles * APU_STEPS_PER_CPU_CYCLE; | ||
_this3.pendingPPUCycles += newCPUCycles * PPU_STEPS_PER_CPU_CYCLE; | ||
}; | ||
while (unitCycles >= 1) { | ||
var interrupt = this.apu.step(this.onSample); | ||
this.apu.step(this.onSample, onIntr); | ||
unitCycles--; | ||
if (interrupt != null) { | ||
var newCPUCycles = this.cpu.interrupt(interrupt); | ||
unitCycles += newCPUCycles * APU_STEPS_PER_CPU_CYCLE; | ||
this.pendingPPUCycles += newCPUCycles * PPU_STEPS_PER_CPU_CYCLE; | ||
} | ||
} | ||
@@ -364,5 +378,4 @@ this.pendingAPUCycles = unitCycles; | ||
if (!components.APU) { | ||
if (address >= 0x4000 && address <= 0x4013) return 0; | ||
// TODO: this.apuRegisters.readAt(address - 0x4000); | ||
else if (address === 0x4015) return 0; // TODO: this.apu.registers.apuMain.readAt(0); | ||
var _this$apu$registers$r, _this$apu$registers43, _this$apu$registers44; | ||
if (address >= 0x4000 && address <= 0x4013 || address === 0x4015) return (_this$apu$registers$r = (_this$apu$registers43 = this.apu.registers) === null || _this$apu$registers43 === void 0 ? void 0 : (_this$apu$registers44 = _this$apu$registers43.read) === null || _this$apu$registers44 === void 0 ? void 0 : _this$apu$registers44.call(_this$apu$registers43, address)) !== null && _this$apu$registers$r !== void 0 ? _this$apu$registers$r : 0; | ||
} | ||
@@ -403,7 +416,4 @@ | ||
if (!components.APU) { | ||
if (address >= 0x4000 && address <= 0x4013) return 0; | ||
// TODO this.apuRegisters.writeAt(address - 0x4000, value); | ||
else if (address === 0x4015) return; | ||
// TODO this.apu.registers.apuMain.writeAt(0, value); | ||
else if (address === 0x4017) return; // TODO this.apu.registers.apuFrameCounter.writeAt(0, value); | ||
var _this$apu$registers45, _this$apu$registers46; | ||
if (address >= 0x4000 && address <= 0x4013 || address === 0x4015 || address === 0x4017) return (_this$apu$registers45 = this.apu.registers) === null || _this$apu$registers45 === void 0 ? void 0 : (_this$apu$registers46 = _this$apu$registers45.write) === null || _this$apu$registers46 === void 0 ? void 0 : _this$apu$registers46.call(_this$apu$registers45, address, value); | ||
} | ||
@@ -410,0 +420,0 @@ |
{ | ||
"name": "broken-neees", | ||
"version": "1.0.21", | ||
"version": "1.0.22", | ||
"main": "index.js", | ||
@@ -5,0 +5,0 @@ "description": "A really broken NEEES emulator that introduces glitches and random bugs on purpose!", |
# broken-neees | ||
A really broken NEEES emulator that introduces glitches and random bugs on purpose! |
385869
64.48%71
97.22%7302
41.65%