nes-emu
Version:
A NES emulator
70 lines (64 loc) • 2.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _mappers = _interopRequireDefault(require("./mappers"));
var _constants = _interopRequireDefault(require("../constants"));
var _helpers = require("../helpers");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** The game cartridge (a file in iNES format). */
class Cartridge {
constructor(bytes) {
this.bytes = bytes;
if (this.magicNumber !== _constants.default.ROM_MAGIC_NUMBER) throw new Error("Invalid ROM format.");
}
/** Returns a new instance of the right mapper. */
createMapper() {
const mapperId = this.header.mapperId;
const Mapper = _mappers.default[mapperId];
if (!Mapper) throw new Error("Unknown mapper: ".concat(mapperId, "."));
return new Mapper();
}
/** Returns the PRG ROM, which contains the game's code. */
get prgRom() {
return this._getBytes(this._programOffset, this._programSize);
}
/** Returns the CHR ROM buffer (which contains static tilesets) or a CHR RAM buffer. */
get chrRom() {
const offset = this._programOffset + this._programSize;
const size = this.header.chrRomPages * _constants.default.CHR_ROM_PAGE_SIZE;
return !this.header.usesChrRam ? this._getBytes(offset, size) : new Uint8Array(_constants.default.CHR_RAM_PAGES * _constants.default.CHR_ROM_PAGE_SIZE);
}
/** Returns the header data. */
get header() {
if (this.__header) return this.__header;
const flags6 = this.bytes[6];
const flags7 = this.bytes[7];
const prgRomPages = this.bytes[4];
const chrRomPages = this.bytes[5];
if (prgRomPages === 0) throw new Error("Invalid header: No PRG ROM pages!");
return this.__header = {
prgRomPages,
chrRomPages: chrRomPages || _constants.default.CHR_RAM_PAGES,
usesChrRam: chrRomPages === 0,
mirroring: _helpers.Byte.getBit(flags6, 3) === 1 ? "FOUR_SCREENS" : _helpers.Byte.getBit(flags6, 0) === 1 ? "VERTICAL" : "HORIZONTAL",
hasTrainerBeforeProgram: !!_helpers.Byte.getBit(flags6, 2),
mapperId: _helpers.Byte.setBits(_helpers.Byte.getBits(flags6, 4, 4), 4, 4, _helpers.Byte.getBits(flags7, 4, 4))
};
}
/** Returns the first 3 ASCII bytes of the header. It should return "NES". */
get magicNumber() {
return Array.from(this._getBytes(0, 3)).map(char => String.fromCharCode(char)).join("");
}
_getBytes(offset, size) {
return this.bytes.slice(offset, offset + size);
}
get _programOffset() {
return _constants.default.ROM_HEADER_SIZE + (this.header.hasTrainerBeforeProgram ? _constants.default.ROM_TRAINER_SIZE : 0);
}
get _programSize() {
return this.header.prgRomPages * _constants.default.PRG_ROM_PAGE_SIZE;
}
}
exports.default = Cartridge;