1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-05-28 08:41:30 +00:00
8bitworkshop/gen/chunk-4MHYRQST.js.map

8 lines
13 KiB
Plaintext

{
"version": 3,
"sources": ["../src/common/analysis.ts"],
"sourcesContent": ["\nimport { hex, byte2signed } from \"./util\";\nimport { Platform } from \"./baseplatform\";\n\nconst debug = false;\n\nexport interface CodeAnalyzer {\n showLoopTimingForPC(pc:number);\n pc2clockrange : {[key:number]:ClockRange};\n MAX_CLOCKS : number;\n}\n\n/// VCS TIMING ANALYSIS\n\n// [taken, not taken]\nconst BRANCH_CONSTRAINTS = [\n [{N:0},{N:1}],\n [{N:1},{N:0}],\n [{V:0},{V:1}],\n [{V:1},{V:0}],\n [{C:0},{C:1}],\n [{C:1},{C:0}],\n [{Z:0},{Z:1}],\n [{Z:1},{Z:0}]\n];\n\nfunction constraintEquals(a,b) {\n if (a == null || b == null)\n return null;\n for (var n in a) {\n if (b[n] !== 'undefined')\n return a[n] == b[n];\n }\n for (var n in b) {\n if (a[n] !== 'undefined')\n return a[n] == b[n];\n }\n return null;\n}\n\ninterface ClockRange {\n minclocks: number;\n maxclocks: number;\n}\n\nabstract class CodeAnalyzer6502 implements CodeAnalyzer {\n pc2clockrange : {[key:number]:ClockRange} = {};\n jsrresult : {[key:number]:ClockRange} = {};\n START_CLOCKS : number;\n MAX_CLOCKS : number;\n WRAP_CLOCKS : boolean;\n platform : Platform;\n MAX_CYCLES : number = 2000;\n \n constructor(platform : Platform) {\n this.platform = platform;\n }\n\n getClockCountsAtPC(pc) {\n var opcode = this.platform.readAddress(pc);\n var meta = this.platform.getOpcodeMetadata(opcode, pc);\n return meta; // minCycles, maxCycles\n }\n\n traceInstructions(pc:number, minclocks:number, maxclocks:number, subaddr:number, constraints) {\n if (debug) console.log(\"trace\", hex(pc), minclocks, maxclocks);\n if (!constraints) constraints = {};\n var modified = true;\n var abort = false;\n for (let i=0; modified && !abort; i++) {\n if (i >= this.MAX_CYCLES) {\n console.log(\"too many cycles @\", hex(pc), \"routine\", hex(subaddr));\n break;\n }\n modified = false;\n if (this.WRAP_CLOCKS) {\n // wrap clocks\n minclocks = minclocks % this.MAX_CLOCKS;\n maxclocks = maxclocks % this.MAX_CLOCKS;\n if (maxclocks == minclocks-1) {\n if (debug) console.log(\"0-75\", hex(pc), minclocks, maxclocks);\n minclocks = 0;\n maxclocks = this.MAX_CLOCKS-1;\n }\n } else {\n // truncate clocks\n minclocks = Math.min(this.MAX_CLOCKS, minclocks);\n maxclocks = Math.min(this.MAX_CLOCKS, maxclocks);\n }\n let meta = this.getClockCountsAtPC(pc);\n let lob = this.platform.readAddress(pc+1);\n let hib = this.platform.readAddress(pc+2);\n let addr = lob + (hib << 8);\n let pc0 = pc;\n let pcrange = this.pc2clockrange[pc0];\n if (pcrange == null) {\n this.pc2clockrange[pc0] = pcrange = {minclocks:minclocks, maxclocks:maxclocks};\n if (debug) console.log(\"new\", hex(pc), hex(pc0), hex(subaddr), minclocks, maxclocks);\n modified = true;\n }\n //console.log(hex(pc),minclocks,maxclocks, pcrange);\n if (pcrange.minclocks != minclocks || pcrange.maxclocks != maxclocks) {\n if (this.WRAP_CLOCKS && (minclocks <= maxclocks) != (pcrange.minclocks <= pcrange.maxclocks)) {\n if (debug) console.log(\"wrap\", hex(pc), hex(pc0), hex(subaddr), minclocks, maxclocks, pcrange);\n pcrange.minclocks = minclocks = 0;\n pcrange.maxclocks = maxclocks = this.MAX_CLOCKS-1;\n modified = true;\n }\n if (minclocks < pcrange.minclocks) {\n if (debug) console.log(\"min\", hex(pc), hex(pc0), hex(subaddr), minclocks, maxclocks, pcrange);\n pcrange.minclocks = minclocks;\n modified = true;\n }\n if (maxclocks > pcrange.maxclocks) {\n if (debug) console.log(\"max\", hex(pc), hex(pc0), hex(subaddr), minclocks, maxclocks, pcrange);\n pcrange.maxclocks = maxclocks;\n modified = true;\n }\n }\n if (!meta.insnlength) {\n console.log(\"Illegal instruction!\", hex(pc), hex(meta.opcode), meta);\n break;\n }\n pc += meta.insnlength;\n var oldconstraints = constraints;\n constraints = null;\n // TODO: if jump to zero-page, maybe assume RTS?\n switch (meta.opcode) {\n case 0x19: case 0x1d:\n case 0x39: case 0x3d:\n case 0x59: case 0x5d:\n case 0x79: case 0x7d:\n case 0xb9: case 0xbb:\n case 0xbc: case 0xbd: case 0xbe: case 0xbf:\n case 0xd9: case 0xdd:\n case 0xf9: case 0xfd:\n if (lob == 0) meta.maxCycles -= 1; // no page boundary crossed\n break;\n // TODO: only VCS\n case 0x85:\n if (lob == 0x2) { // STA WSYNC\n minclocks = maxclocks = 0;\n meta.minCycles = meta.maxCycles = 0;\n }\n break;\n // TODO: only NES (sprite 0 poll)\n case 0x2c:\n if (lob == 0x02 && hib == 0x20) { // BIT $2002\n minclocks = 0;\n maxclocks = 4; // uncertainty b/c of assumed branch poll\n meta.minCycles = meta.maxCycles = 0;\n }\n break;\n // TODO: only Apple2 (vapor lock)\n /*\n case 0xad:\n if (lob == 0x61 && hib == 0xc0) { // LDA $C061\n minclocks = 0;\n maxclocks = 4; // uncertainty?\n meta.minCycles = meta.maxCycles = 0;\n }\n break;\n */\n case 0x20: // JSR\n // TODO: handle bare RTS case\n minclocks += meta.minCycles;\n maxclocks += meta.maxCycles;\n this.traceInstructions(addr, minclocks, maxclocks, addr, constraints);\n var result = this.jsrresult[addr];\n if (result) {\n minclocks = result.minclocks;\n maxclocks = result.maxclocks;\n } else {\n console.log(\"No JSR result!\", hex(pc), hex(addr));\n minclocks = maxclocks;\n //return;\n }\n break;\n case 0x4c: // JMP\n pc = addr; // TODO: make sure in ROM space\n break;\n case 0x40: // RTI\n abort = true;\n break;\n case 0x60: // RTS\n if (subaddr) { // TODO: 0 doesn't work\n // TODO: combine with previous result\n var result = this.jsrresult[subaddr];\n if (!result) {\n result = {minclocks:minclocks, maxclocks:maxclocks};\n } else {\n result = {\n minclocks:Math.min(minclocks,result.minclocks),\n maxclocks:Math.max(maxclocks,result.maxclocks)\n }\n }\n this.jsrresult[subaddr] = result;\n console.log(\"RTS\", hex(pc), hex(subaddr), this.jsrresult[subaddr]);\n }\n return;\n case 0x10: case 0x30: // branch\n case 0x50: case 0x70:\n case 0x90: case 0xB0:\n case 0xD0: case 0xF0:\n var newpc = pc + byte2signed(lob);\n var crosspage = (pc>>8) != (newpc>>8);\n if (!crosspage) meta.maxCycles--;\n // TODO: other instructions might modify flags too\n var cons = BRANCH_CONSTRAINTS[Math.floor((meta.opcode-0x10)/0x20)];\n var cons0 = constraintEquals(oldconstraints, cons[0]);\n var cons1 = constraintEquals(oldconstraints, cons[1]);\n // recursively trace the taken branch\n if (true || cons0 !== false) { // TODO?\n this.traceInstructions(newpc, minclocks+meta.maxCycles, maxclocks+meta.maxCycles, subaddr, cons[0]);\n }\n // abort if we will always take the branch\n if (cons1 === false) {\n console.log(\"branch always taken\", hex(pc), oldconstraints, cons[1]);\n abort = true;\n }\n constraints = cons[1]; // not taken\n meta.maxCycles = meta.minCycles; // branch not taken, no extra clock(s)\n break;\n case 0x6c:\n console.log(\"Instruction not supported!\", hex(pc), hex(meta.opcode), meta); // TODO\n return;\n }\n // add min/max instruction time to min/max clocks bound\n if (debug) console.log(\"add\", hex(pc), meta.minCycles, meta.maxCycles);\n minclocks += meta.minCycles;\n maxclocks += meta.maxCycles;\n }\n }\n\n showLoopTimingForPC(pc:number) {\n this.pc2clockrange = {};\n this.jsrresult = {};\n // recurse through all traces\n this.traceInstructions(pc | this.platform.getOriginPC(), this.START_CLOCKS, this.MAX_CLOCKS, 0, {});\n }\n}\n\n// 76 cycles\nexport class CodeAnalyzer_vcs extends CodeAnalyzer6502 {\n constructor(platform : Platform) {\n super(platform);\n this.MAX_CLOCKS = 76; // 1 scanline\n this.START_CLOCKS = 0; // TODO?\n this.WRAP_CLOCKS = true;\n }\n}\n\n// https://wiki.nesdev.com/w/index.php/PPU_rendering#Line-by-line_timing\n// TODO: sprite 0 hit, CPU stalls\nexport class CodeAnalyzer_nes extends CodeAnalyzer6502 {\n constructor(platform : Platform) {\n super(platform);\n this.MAX_CLOCKS = 114; // 341 clocks for 3 scanlines\n this.START_CLOCKS = 0;\n this.WRAP_CLOCKS = true;\n }\n}\n\nexport class CodeAnalyzer_apple2 extends CodeAnalyzer6502 {\n constructor(platform : Platform) {\n super(platform);\n this.MAX_CLOCKS = 65;\n this.START_CLOCKS = 0;\n this.WRAP_CLOCKS = true;\n }\n}\n\n"],
"mappings": "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",
"names": []
}