UNPKG

snes-disassembler

Version:

A Super Nintendo (SNES) ROM disassembler for 65816 assembly

371 lines 12.2 kB
"use strict"; /** * SNES Cartridge Types and Memory Mapping System * Based on research from SNES MCP servers and hardware documentation */ Object.defineProperty(exports, "__esModule", { value: true }); exports.MemorySpeed = exports.CartridgeType = void 0; exports.detectCartridgeType = detectCartridgeType; exports.getMemorySpeed = getMemorySpeed; exports.hasBatteryBackup = hasBatteryBackup; exports.getSRAMSize = getSRAMSize; exports.createMemoryLayout = createMemoryLayout; var CartridgeType; (function (CartridgeType) { // Basic mapping modes CartridgeType["LoROM"] = "LoROM"; CartridgeType["HiROM"] = "HiROM"; // Extended mapping modes CartridgeType["ExLoROM"] = "ExLoROM"; CartridgeType["ExHiROM"] = "ExHiROM"; // Special chip cartridges CartridgeType["SA1"] = "SA-1"; CartridgeType["SuperFX"] = "SuperFX"; CartridgeType["DSP1"] = "DSP-1"; CartridgeType["DSP2"] = "DSP-2"; CartridgeType["DSP3"] = "DSP-3"; CartridgeType["DSP4"] = "DSP-4"; CartridgeType["CX4"] = "CX4"; CartridgeType["ST010"] = "ST010"; CartridgeType["ST011"] = "ST011"; CartridgeType["SPC7110"] = "SPC7110"; CartridgeType["SDD1"] = "S-DD1"; CartridgeType["SRTC"] = "S-RTC"; CartridgeType["OBC1"] = "OBC-1"; // Special formats CartridgeType["BSX"] = "BSX"; CartridgeType["MSU1"] = "MSU-1"; // Unknown/custom CartridgeType["Unknown"] = "Unknown"; })(CartridgeType || (exports.CartridgeType = CartridgeType = {})); var MemorySpeed; (function (MemorySpeed) { MemorySpeed["SlowROM"] = "SlowROM"; MemorySpeed["FastROM"] = "FastROM"; // 3.58 MHz (200ns) })(MemorySpeed || (exports.MemorySpeed = MemorySpeed = {})); /** * Detect cartridge type from ROM header information */ function detectCartridgeType(mapMode, cartridgeType) { // Map mode byte format: xSSSpppp // x = unused, SSS = speed (0=SlowROM, 1=FastROM), pppp = map mode const mapType = mapMode & 0x0F; const romSpeed = (mapMode & 0x30) >> 4; // Check for special chips first (based on cartridge type byte) switch (cartridgeType) { case 0x03: return CartridgeType.DSP1; case 0x05: return CartridgeType.DSP2; case 0x06: return CartridgeType.DSP3; case 0x0A: return CartridgeType.DSP4; case 0x13: case 0x14: case 0x15: case 0x1A: return CartridgeType.SuperFX; case 0x34: case 0x35: return CartridgeType.SA1; case 0x43: case 0x45: return CartridgeType.SDD1; case 0x55: return CartridgeType.SRTC; case 0xE3: return CartridgeType.BSX; // BSX satellaview case 0xE5: return CartridgeType.BSX; // BSX satellaview with memory pack case 0xF3: return CartridgeType.CX4; case 0xF5: return CartridgeType.ST010; case 0xF6: return CartridgeType.ST011; case 0xF9: return CartridgeType.SPC7110; case 0xFE: return CartridgeType.MSU1; // MSU-1 audio enhancement } // Standard mapping modes switch (mapType) { case 0x0: return CartridgeType.LoROM; case 0x1: return CartridgeType.HiROM; case 0x2: return CartridgeType.LoROM; // LoROM + S-DD1 case 0x3: return CartridgeType.LoROM; // LoROM + SA-1 case 0x4: return CartridgeType.ExLoROM; // Extended LoROM case 0x5: return CartridgeType.ExHiROM; // Extended HiROM case 0xA: return CartridgeType.HiROM; // HiROM + FastROM default: return CartridgeType.Unknown; } } /** * Get memory speed from map mode */ function getMemorySpeed(mapMode) { const speed = (mapMode & 0x30) >> 4; return speed === 1 ? MemorySpeed.FastROM : MemorySpeed.SlowROM; } /** * Check if cartridge has battery-backed SRAM */ function hasBatteryBackup(cartridgeType) { // Cartridge type values that indicate battery backup const batteryTypes = [0x02, 0x05, 0x06, 0x09, 0x0A, 0x13, 0x14, 0x15, 0x1A, 0x35, 0x45, 0x55]; return batteryTypes.includes(cartridgeType); } /** * Get SRAM size from ROM header */ function getSRAMSize(ramSize) { if (ramSize === 0) return 0; return 1024 << ramSize; // 2^ramSize KB } /** * Create memory region layout for cartridge type */ function createMemoryLayout(cartridgeInfo) { const regions = []; switch (cartridgeInfo.type) { case CartridgeType.LoROM: regions.push(...createLoROMLayout(cartridgeInfo)); break; case CartridgeType.HiROM: regions.push(...createHiROMLayout(cartridgeInfo)); break; case CartridgeType.ExLoROM: regions.push(...createExLoROMLayout(cartridgeInfo)); break; case CartridgeType.ExHiROM: regions.push(...createExHiROMLayout(cartridgeInfo)); break; case CartridgeType.SA1: regions.push(...createSA1Layout(cartridgeInfo)); break; case CartridgeType.SuperFX: regions.push(...createSuperFXLayout(cartridgeInfo)); break; case CartridgeType.BSX: regions.push(...createBSXLayout(cartridgeInfo)); break; case CartridgeType.MSU1: regions.push(...createMSU1Layout(cartridgeInfo)); break; default: // Default to LoROM layout for unknown types regions.push(...createLoROMLayout(cartridgeInfo)); break; } return regions; } function createLoROMLayout(info) { const regions = []; // Banks 00-7F: ROM at $8000-$FFFF (32KB per bank) for (let bank = 0x00; bank <= 0x7F; bank++) { regions.push({ start: (bank << 16) | 0x8000, end: (bank << 16) | 0xFFFF, type: 'ROM', readable: true, writable: false, size: 0x8000, speed: info.speed, description: `Bank ${bank.toString(16).toUpperCase()} ROM` }); } // Banks 80-FF: Mirror of banks 00-7F for (let bank = 0x80; bank <= 0xFF; bank++) { regions.push({ start: (bank << 16) | 0x8000, end: (bank << 16) | 0xFFFF, type: 'ROM', readable: true, writable: false, size: 0x8000, speed: MemorySpeed.FastROM, // FastROM region description: `Bank ${bank.toString(16).toUpperCase()} ROM (FastROM mirror)` }); } // SRAM if present if (info.ramSize > 0) { regions.push({ start: 0x700000, end: 0x7FFFFF, type: 'SRAM', readable: true, writable: true, size: info.ramSize * 1024, speed: MemorySpeed.SlowROM, description: 'SRAM' }); } return regions; } function createHiROMLayout(info) { const regions = []; // Banks 00-3F: ROM at $8000-$FFFF (32KB per bank) for (let bank = 0x00; bank <= 0x3F; bank++) { regions.push({ start: (bank << 16) | 0x8000, end: (bank << 16) | 0xFFFF, type: 'ROM', readable: true, writable: false, size: 0x8000, speed: info.speed, description: `Bank ${bank.toString(16).toUpperCase()} ROM` }); } // Banks 40-7F: ROM (64KB per bank) for (let bank = 0x40; bank <= 0x7F; bank++) { regions.push({ start: (bank << 16), end: (bank << 16) | 0xFFFF, type: 'ROM', readable: true, writable: false, size: 0x10000, speed: info.speed, description: `Bank ${bank.toString(16).toUpperCase()} ROM` }); } // Banks 80-BF: Mirror of banks 00-3F for (let bank = 0x80; bank <= 0xBF; bank++) { regions.push({ start: (bank << 16) | 0x8000, end: (bank << 16) | 0xFFFF, type: 'ROM', readable: true, writable: false, size: 0x8000, speed: MemorySpeed.FastROM, description: `Bank ${bank.toString(16).toUpperCase()} ROM (FastROM mirror)` }); } // Banks C0-FF: Mirror of banks 40-7F for (let bank = 0xC0; bank <= 0xFF; bank++) { regions.push({ start: (bank << 16), end: (bank << 16) | 0xFFFF, type: 'ROM', readable: true, writable: false, size: 0x10000, speed: MemorySpeed.FastROM, description: `Bank ${bank.toString(16).toUpperCase()} ROM (FastROM mirror)` }); } // SRAM if present (banks 20-3F at $6000-$7FFF) if (info.ramSize > 0) { for (let bank = 0x20; bank <= 0x3F; bank++) { regions.push({ start: (bank << 16) | 0x6000, end: (bank << 16) | 0x7FFF, type: 'SRAM', readable: true, writable: true, size: 0x2000, speed: MemorySpeed.SlowROM, description: `Bank ${bank.toString(16).toUpperCase()} SRAM` }); } } return regions; } function createExLoROMLayout(info) { // Extended LoROM - supports up to 32MB // Similar to LoROM but with additional bank mappings return createLoROMLayout(info); // Simplified for now } function createExHiROMLayout(info) { // Extended HiROM - supports up to 64MB // Similar to HiROM but with additional bank mappings return createHiROMLayout(info); // Simplified for now } function createSA1Layout(info) { const regions = []; // SA-1 has complex memory mapping with BW-RAM and I-RAM // Based on SA-1 documentation from SNES MCP server // I-RAM (Internal RAM) - 2KB regions.push({ start: 0x003000, end: 0x0037FF, type: 'RAM', readable: true, writable: true, size: 0x800, speed: MemorySpeed.FastROM, description: 'SA-1 I-RAM' }); // BW-RAM (Backup Work RAM) regions.push({ start: 0x006000, end: 0x007FFF, type: 'RAM', readable: true, writable: true, size: 0x2000, speed: MemorySpeed.SlowROM, description: 'SA-1 BW-RAM' }); // ROM mapping (similar to LoROM) regions.push(...createLoROMLayout(info)); return regions; } function createSuperFXLayout(info) { const regions = []; // SuperFX GSU memory layout // Based on SuperFX documentation from SNES MCP server // GSU RAM/Cache regions.push({ start: 0x706000, end: 0x707FFF, type: 'RAM', readable: true, writable: true, size: 0x2000, speed: MemorySpeed.FastROM, description: 'SuperFX GSU RAM' }); // ROM mapping (similar to LoROM) regions.push(...createLoROMLayout(info)); return regions; } function createBSXLayout(info) { const regions = []; // BSX Satellaview memory layout // Based on BSX documentation and SNES MCP server research // BSX Memory Pack area regions.push({ start: 0x005000, end: 0x005FFF, type: 'RAM', readable: true, writable: true, size: 0x1000, speed: MemorySpeed.SlowROM, description: 'BSX Memory Pack' }); // BSX registers regions.push({ start: 0x002188, end: 0x00218F, type: 'IO', readable: true, writable: true, size: 0x8, speed: MemorySpeed.SlowROM, description: 'BSX Registers' }); // ROM mapping (uses LoROM-style) regions.push(...createLoROMLayout(info)); return regions; } function createMSU1Layout(info) { const regions = []; // MSU-1 audio enhancement layout // Based on MSU-1 specification // MSU-1 registers regions.push({ start: 0x002000, end: 0x002007, type: 'IO', readable: true, writable: true, size: 0x8, speed: MemorySpeed.SlowROM, description: 'MSU-1 Audio Registers' }); // Standard ROM mapping (typically LoROM) regions.push(...createLoROMLayout(info)); return regions; } //# sourceMappingURL=cartridge-types.js.map