UNPKG

broken-neees

Version:

A really broken NEEES emulator that introduces glitches and random bugs on purpose!

99 lines (97 loc) 4.45 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _byte = _interopRequireDefault(require("./lib/byte")); 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); } } 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 _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } 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); } var KB = 1024; var HEADER_SIZE = 16; var PRG_PAGE_SIZE = 16 * KB; var CHR_PAGE_SIZE = 8 * KB; var Cartridge = /*#__PURE__*/function () { function Cartridge(bytes) { _classCallCheck(this, Cartridge); this.bytes = bytes; this._checkMagicConstant(); this.header = this._buildHeader(); } // [!!!] _createClass(Cartridge, [{ key: "isBroken", get: function get() { return !this.unbroken; } }, { key: "prg", value: function prg() { return this.bytes.slice(this._prgOffset(), this._prgOffset() + this._prgSize()); } }, { key: "chr", value: function chr() { if (this.header.usesChrRam) return new Uint8Array(CHR_PAGE_SIZE); if (this.unbroken) { return this.bytes.slice(this._chrOffset(), this._chrOffset() + this._chrSize()); } else { // [!!!] var size = this._chrSize(); var bytes = new Uint8Array(size + 3); bytes.set(this.bytes.slice(this._chrOffset(), this._chrOffset() + size), 3); return bytes; } } }, { key: "_prgOffset", value: function _prgOffset() { return HEADER_SIZE + (this.header.has512BytePadding ? 512 : 0); } }, { key: "_prgSize", value: function _prgSize() { return this.header.prgRomPages * PRG_PAGE_SIZE; } }, { key: "_chrOffset", value: function _chrOffset() { return this._prgOffset() + this._prgSize(); } }, { key: "_chrSize", value: function _chrSize() { return this.header.chrRomPages * CHR_PAGE_SIZE; } }, { key: "_buildHeader", value: function _buildHeader() { var prgRomPages = this.bytes[4]; var chrRomPages = this.bytes[5]; var flags6 = this.bytes[6]; var flags7 = this.bytes[7]; return { prgRomPages: prgRomPages, chrRomPages: chrRomPages, usesChrRam: chrRomPages === 0, has512BytePadding: _byte.default.getFlag(flags6, 2), hasPrgRam: _byte.default.getFlag(flags6, 1), mirroringId: _byte.default.getFlag(flags6, 3) ? "FOUR_SCREEN" : _byte.default.getFlag(flags6, 0) ? "VERTICAL" : "HORIZONTAL", mapperId: _byte.default.buildU8(_byte.default.highNybbleOf(flags7), _byte.default.highNybbleOf(flags6)) }; } }, { key: "_checkMagicConstant", value: function _checkMagicConstant() { if (this.bytes[0] !== 0x4e || this.bytes[1] !== 0x45 || this.bytes[2] !== 0x53 || this.bytes[3] !== 0x1a) { throw new Error("Invalid ROM."); } } }]); return Cartridge; }(); exports.default = Cartridge;