broken-neees
Version:
A really broken NEEES emulator that introduces glitches and random bugs on purpose!
72 lines (70 loc) • 2.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _byte = _interopRequireDefault(require("./lib/byte"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const KB = 1024;
const HEADER_SIZE = 16;
const PRG_PAGE_SIZE = 16 * KB;
const CHR_PAGE_SIZE = 8 * KB;
class Cartridge {
constructor(bytes) {
this.bytes = bytes;
this._checkMagicConstant();
this.header = this._buildHeader();
}
// [!!!]
get isBroken() {
return !this.unbroken;
}
prg() {
return this.bytes.slice(this._prgOffset(), this._prgOffset() + this._prgSize());
}
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 {
// [!!!]
const size = this._chrSize();
const bytes = new Uint8Array(size + 3);
bytes.set(this.bytes.slice(this._chrOffset(), this._chrOffset() + size), 3);
return bytes;
}
}
_prgOffset() {
return HEADER_SIZE + (this.header.has512BytePadding ? 512 : 0);
}
_prgSize() {
return this.header.prgRomPages * PRG_PAGE_SIZE;
}
_chrOffset() {
return this._prgOffset() + this._prgSize();
}
_chrSize() {
return this.header.chrRomPages * CHR_PAGE_SIZE;
}
_buildHeader() {
const prgRomPages = this.bytes[4];
const chrRomPages = this.bytes[5];
const flags6 = this.bytes[6];
const flags7 = this.bytes[7];
return {
prgRomPages,
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))
};
}
_checkMagicConstant() {
if (this.bytes[0] !== 0x4e || this.bytes[1] !== 0x45 || this.bytes[2] !== 0x53 || this.bytes[3] !== 0x1a) {
throw new Error("Invalid ROM.");
}
}
}
exports.default = Cartridge;