uae-dap
Version:
Debug Adapter Protocol for Amiga development with FS-UAE or WinUAE
151 lines • 5.28 kB
JavaScript
"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