UNPKG

uae-dap

Version:

Debug Adapter Protocol for Amiga development with FS-UAE or WinUAE

151 lines 5.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CopperSkip = exports.CopperWait = exports.CopperCondition = exports.CopperMove = exports.CopperInstruction = exports.disassembleCopper = exports.CopperInstructionType = void 0; const hardware_1 = require("../hardware"); /** Type of copper instruction */ var CopperInstructionType; (function (CopperInstructionType) { CopperInstructionType[CopperInstructionType["MOVE"] = 0] = "MOVE"; CopperInstructionType[CopperInstructionType["WAIT"] = 1] = "WAIT"; CopperInstructionType[CopperInstructionType["SKIP"] = 2] = "SKIP"; })(CopperInstructionType = exports.CopperInstructionType || (exports.CopperInstructionType = {})); /** * Disassemble memory into copper instructions */ function disassembleCopper(memory) { if (memory.length < 8) { throw new Error("Memory block too short to parse (8 characters minimum)"); } const copperList = []; // Split the string in blocs of 8 characters for (let i = 8; i <= memory.length; i += 8) { const instruction = CopperInstruction.parse(memory.substring(i - 8, i)); copperList.push(instruction); if (instruction instanceof CopperWait && instruction.isEnd()) { break; } } return copperList; } exports.disassembleCopper = disassembleCopper; /** * Copper instruction */ class CopperInstruction { constructor(instructionType, first, second) { this.instructionType = instructionType; this.first = first; this.second = second; } static parse(instructionString) { // Split in two parts const firstStr = instructionString.substring(0, 4); const secondStr = instructionString.substring(4); const first = parseInt(firstStr, 16); const second = parseInt(secondStr, 16); if (first & 0x0001) { // This is a wait or skip if (second & 0x0001) { return new CopperSkip(first, second); } else { return new CopperWait(first, second); } } else { return new CopperMove(first, second); } } getAsmInstruction() { return `dc.w $${this.format(this.first)},$${this.format(this.second)}`; } getInstructionBytes() { const f = this.format(this.first); const s = this.format(this.second); return `${f.substring(0, 2)} ${f.substring(2)} ${s.substring(0, 2)} ${s.substring(2)}`; } getPaddedAsmInstruction() { const inst = this.getAsmInstruction(); const pad = " ".repeat(20 - inst.length); return inst + pad; } format(value) { return value.toString(16).padStart(4, "0"); } } exports.CopperInstruction = CopperInstruction; class CopperMove extends CopperInstruction { constructor(first, second) { super(CopperInstructionType.MOVE, first, second); this.DA = first & 0x01fe; this.RD = second; const address = hardware_1.CUSTOM_BASE + this.DA; this.label = hardware_1.customRegisterNames[address]; } toString() { let l; if (this.label) { l = this.label; } else { l = `$${this.format(this.DA)}`; } const inst = this.getPaddedAsmInstruction(); const value = `$${this.format(this.RD)}`; return `${inst}; ${l} := ${value}`; } } exports.CopperMove = CopperMove; class CopperCondition extends CopperInstruction { constructor(instructionType, first, second) { super(instructionType, first, second); this.VP = first >> 8; this.HP = first & 0x00fe; this.BFD = (second & 0x8000) >> 15; this.VE = (second | 0x8000) >> 8; this.HE = second & 0x00fe; this.vertical = this.VP & this.VE; this.horizontal = this.HP & this.HE; } } exports.CopperCondition = CopperCondition; class CopperWait extends CopperCondition { constructor(first, second) { super(CopperInstructionType.WAIT, first, second); } toString() { const inst = this.getPaddedAsmInstruction(); if (this.isEnd()) { return `${inst}; End of CopperList`; } else { const str = `${inst}; Wait for `; const wait = []; if (this.vertical) { wait.push(`vpos >= 0x${this.vertical.toString(16)}`); } if (this.horizontal) { wait.push(`hpos >= 0x${this.horizontal.toString(16)}`); } if (this.BFD === 0) { wait.push(`blitter finished`); } return str + wait.join(" and "); } } isEnd() { return this.first === 0xffff && this.second === 0xfffe; } } exports.CopperWait = CopperWait; class CopperSkip extends CopperCondition { constructor(first, second) { super(CopperInstructionType.SKIP, first, second); } toString() { const inst = this.getPaddedAsmInstruction(); return `${inst}; Skip if vpos >= 0x${this.vertical.toString(16)} and hpos >= 0x${this.horizontal.toString(16)}`; } } exports.CopperSkip = CopperSkip; //# sourceMappingURL=copperDisassembler.js.map