UNPKG

nes-emu

Version:

A NES emulator

63 lines (56 loc) 2.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _constants = _interopRequireDefault(require("../../constants")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** A frequency sweeper. It can progressively increase or decrease pulse channels' notes. */ class FrequencySweeper { constructor() { // input this.startFlag = false; // output this.dividerCount = 0; this.change = 0; this.mute = false; } /** Clocks the sweeper and updates channel's timer frequency. */ clock(channel) { const register = channel.registers.sweep; /** * The sweep unit continuously calculates each channel's target period in this way: * - A barrel shifter shifts the channel's 11-bit raw timer period right by the shift count, producing the change amount. * - If the negate flag is true, the change amount is made negative. * - The target period is the sum of the current period and the change amount. */ if (register.enabledFlag && register.shiftCount > 0 && this.dividerCount === 0 && !this.mute) { const sweepDelta = channel.timer >> register.shiftCount; channel.timer += sweepDelta * (register.negateFlag ? -1 : 1); } if (this.dividerCount === 0 || this.startFlag) { this.dividerCount = register.dividerPeriodMinusOne + 1; this.startFlag = false; } else this.dividerCount--; } muteIfNeeded(channel) { this.mute = channel.timer < _constants.default.APU_MIN_TIMER || channel.timer > _constants.default.APU_MAX_TIMER; } /** Returns a snapshot of the current state. */ getSaveState() { return { startFlag: this.startFlag, dividerCount: this.dividerCount, change: this.change, mute: this.mute }; } /** Restores state from a snapshot. */ setSaveState(saveState) { this.startFlag = saveState.startFlag; this.dividerCount = saveState.dividerCount; this.change = saveState.change; this.mute = saveState.mute; } } exports.default = FrequencySweeper;