UNPKG

snes-disassembler

Version:

A Super Nintendo (SNES) ROM disassembler for 65816 assembly

103 lines 3.37 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createCycleInfo = createCycleInfo; const types_1 = require("./types"); const cartridge_types_1 = require("./cartridge-types"); /** * Calculate the actual cycle count for an instruction based on processor state and memory timing */ function calculateCycles(instruction, context) { const cycles = instruction.cycles; // If it's a simple number, return it as-is (legacy support) if (typeof cycles === 'number') { return cycles; } // If no timing context provided, return base cycles if (!context) { return cycles.base; } let totalCycles = cycles.base; // Add cycles for 16-bit accumulator operations (M flag = 0) if (cycles.m16 && !context.flags.m) { totalCycles += cycles.m16; } // Add cycles for 16-bit index operations (X flag = 0) if (cycles.x16 && !context.flags.x) { totalCycles += cycles.x16; } // Add cycles for page boundary crossing if (cycles.pageBoundary && context.operandAddress) { if (crossesPageBoundary(context.address, context.operandAddress, instruction.addressingMode)) { totalCycles += cycles.pageBoundary; } } // Add cycles for memory access timing (FastROM vs SlowROM) if (cycles.memoryAccess) { if (!context.fastROM) { totalCycles += cycles.memoryAccess; } } return totalCycles; } /** * Check if an instruction crosses a page boundary */ function crossesPageBoundary(instructionAddress, operandAddress, mode) { switch (mode) { case types_1.AddressingMode.AbsoluteX: case types_1.AddressingMode.AbsoluteY: case types_1.AddressingMode.DirectIndirectY: // These modes can cross page boundaries const page1 = (operandAddress & 0xFF00); const page2 = ((operandAddress + getIndexOffset(mode)) & 0xFF00); return page1 !== page2; default: return false; } } /** * Get the index offset for addressing modes that use index registers */ function getIndexOffset(mode) { // This would need to be calculated based on actual register values // For now, return 1 as a conservative estimate return 1; } /** * Determine if an address is in FastROM region */ function isFastROM(address, cartridgeSpeed) { // If cartridge doesn't support FastROM, return false if (cartridgeSpeed === cartridge_types_1.MemorySpeed.SlowROM) { return false; } // FastROM regions (when supported): // LoROM: Banks $80-$FF at $8000-$FFFF // HiROM: Banks $80-$FF (all addresses) const bank = (address >> 16) & 0xFF; const offset = address & 0xFFFF; // FastROM mirror regions if (bank >= 0x80) { return true; // FastROM mirror banks } return false; // SlowROM regions } /** * Get memory access timing based on address and cartridge type */ function getMemoryTiming(address, cartridgeSpeed) { if (isFastROM(address, cartridgeSpeed)) { return cartridge_types_1.MemorySpeed.FastROM; } return cartridge_types_1.MemorySpeed.SlowROM; } /** * Update an instruction with dynamic cycle information */ function createCycleInfo(base, options = {}) { return { base, ...options }; } //# sourceMappingURL=timing.js.map