Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
emoon committed Mar 31, 2024
1 parent ee5fcf8 commit 217602d
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 24 deletions.
137 changes: 119 additions & 18 deletions external/capstone/arch/M68K/M68KInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <stdio.h> // DEBUG
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#include "M68KInstPrinter.h"

Expand Down Expand Up @@ -104,7 +105,7 @@ static void printRegbitsRange(char* buffer, uint32_t data, const char* prefix)
}
}

static void registerBits(SStream* O, const cs_m68k_op* op)
static void registerBits(cs_detail* detail, SStream* O, const cs_m68k_op* op, bool write_reg)
{
char buffer[128];
unsigned int data = op->register_bits;
Expand All @@ -120,41 +121,114 @@ static void registerBits(SStream* O, const cs_m68k_op* op)
printRegbitsRange(buffer, (data >> 8) & 0xff, "a");
printRegbitsRange(buffer, (data >> 16) & 0xff, "fp");

RegisterStringInfo* info = NULL;

if (write_reg) {
int i = detail->regs_write_string_count++;
info = &detail->regs_write_string_info[i];
} else {
int i = detail->regs_read_string_count++;
info = &detail->regs_read_string_info[i];
}

info->type = REGISTER_STRING_INFO_REG_BITS;
info->length = strlen(buffer);
info->offset = O->index;

SStream_concat(O, "%s", buffer);
}

static void addStringInfo(cs_detail* detail, SStream* O, int adjust_offset, bool is_write, uint8_t length)
{
RegisterStringInfo* info = NULL;

if (is_write) {
int i = detail->regs_write_string_count++;
info = &detail->regs_write_string_info[i];
} else {
int i = detail->regs_read_string_count++;
info = &detail->regs_read_string_info[i];
}

info->type = REGISTER_STRING_INFO_REGISTER;
info->length = length;
info->offset = O->index + adjust_offset;
}

static void registerPair(SStream* O, const cs_m68k_op* op)
{
SStream_concat(O, "%s:%s", s_reg_names[op->reg_pair.reg_0],
s_reg_names[op->reg_pair.reg_1]);
SStream_concat(O, "%s:%s", s_reg_names[op->reg_pair.reg_0], s_reg_names[op->reg_pair.reg_1]);
}

static void printAddressingMode(SStream* O, unsigned int pc, const cs_m68k* inst, const cs_m68k_op* op)
static void printAddressingMode(cs_detail* detail, SStream* O, unsigned int pc, const cs_m68k* inst, const cs_m68k_op* op, bool is_write)
{
switch (op->address_mode) {
case M68K_AM_NONE:
switch (op->type) {
case M68K_OP_REG_BITS:
registerBits(O, op);
registerBits(detail, O, op, is_write);
break;
case M68K_OP_REG_PAIR:
//registerPair(detail, O, op, is_write);
registerPair(O, op);
break;
case M68K_OP_REG:
SStream_concat(O, "%s", s_reg_names[op->reg]);
addStringInfo(detail, O, 0, is_write, strlen(s_reg_names[op->reg]));
break;
default:
break;
}
break;

case M68K_AM_REG_DIRECT_DATA: SStream_concat(O, "d%d", (op->reg - M68K_REG_D0)); break;
case M68K_AM_REG_DIRECT_ADDR: SStream_concat(O, "a%d", (op->reg - M68K_REG_A0)); break;
case M68K_AM_REGI_ADDR: SStream_concat(O, "(a%d)", (op->reg - M68K_REG_A0)); break;
case M68K_AM_REGI_ADDR_POST_INC: SStream_concat(O, "(a%d)+", (op->reg - M68K_REG_A0)); break;
case M68K_AM_REGI_ADDR_PRE_DEC: SStream_concat(O, "-(a%d)", (op->reg - M68K_REG_A0)); break;
case M68K_AM_REGI_ADDR_DISP: SStream_concat(O, "%s$%x(a%d)", op->mem.disp < 0 ? "-" : "", abs(op->mem.disp), (op->mem.base_reg - M68K_REG_A0)); break;
case M68K_AM_PCI_DISP: SStream_concat(O, "$%x(pc)", pc + 2 + op->mem.disp); break;
case M68K_AM_REG_DIRECT_DATA:
{
addStringInfo(detail, O, 0, is_write, 2);
SStream_concat(O, "d%d", (op->reg - M68K_REG_D0));
break;
}

case M68K_AM_REG_DIRECT_ADDR:
{
addStringInfo(detail, O, 0, is_write, 2);
SStream_concat(O, "a%d", (op->reg - M68K_REG_A0));
break;
}

case M68K_AM_REGI_ADDR:
{
addStringInfo(detail, O, 1, is_write, 2);
SStream_concat(O, "(a%d)", (op->reg - M68K_REG_A0));
break;
}

case M68K_AM_REGI_ADDR_POST_INC:
{
addStringInfo(detail, O, 1, true, 2);
SStream_concat(O, "(a%d)+", (op->reg - M68K_REG_A0));
break;
}

case M68K_AM_REGI_ADDR_PRE_DEC:
{
addStringInfo(detail, O, 2, true, 2);
SStream_concat(O, "-(a%d)", (op->reg - M68K_REG_A0));
break;
}

case M68K_AM_REGI_ADDR_DISP:
{
SStream_concat(O, "%s$%x(a%d)", op->mem.disp < 0 ? "-" : "", abs(op->mem.disp), (op->mem.base_reg - M68K_REG_A0));
addStringInfo(detail, O, -2, false, 2);
break;
}

case M68K_AM_PCI_DISP:
{
SStream_concat(O, "$%x(pc)", pc + 2 + op->mem.disp);
break;
}

case M68K_AM_ABSOLUTE_DATA_SHORT: SStream_concat(O, "$%x.w", op->imm); break;
case M68K_AM_ABSOLUTE_DATA_LONG: SStream_concat(O, "$%x.l", op->imm); break;
case M68K_AM_IMMEDIATE:
Expand All @@ -176,11 +250,26 @@ static void printAddressingMode(SStream* O, unsigned int pc, const cs_m68k* inst
SStream_concat(O, "#$%x", op->imm);
break;
case M68K_AM_PCI_INDEX_8_BIT_DISP:
SStream_concat(O, "$%x(pc,%s%s.%c)", pc + 2 + op->mem.disp, s_spacing, getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
{
SStream_concat(O, "$%x(pc,%s.%c)",
pc + 2 + op->mem.disp,
getRegName(op->mem.index_reg),
op->mem.index_size ? 'l' : 'w');
addStringInfo(detail, O, -3, false, 2);
break;
}
case M68K_AM_AREGI_INDEX_8_BIT_DISP:
SStream_concat(O, "%s$%x(%s,%s%s.%c)", op->mem.disp < 0 ? "-" : "", abs(op->mem.disp), getRegName(op->mem.base_reg), s_spacing, getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
{
SStream_concat(O, "%s$%x(%s,%s.%c)",
op->mem.disp < 0 ? "-" : "",
abs(op->mem.disp),
getRegName(op->mem.base_reg),
getRegName(op->mem.index_reg),
op->mem.index_size ? 'l' : 'w');
addStringInfo(detail, O, -5, false, 2);
addStringInfo(detail, O, -3, false, 2);
break;
}
case M68K_AM_PCI_INDEX_BASE_DISP:
case M68K_AM_AREGI_INDEX_BASE_DISP:

Expand All @@ -197,7 +286,12 @@ static void printAddressingMode(SStream* O, unsigned int pc, const cs_m68k* inst
SStream_concat(O, "pc,%s.%c", getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
} else {
if (op->mem.base_reg != M68K_REG_INVALID)
{
addStringInfo(detail, O, 0, false, 2);
SStream_concat(O, "a%d,%s", op->mem.base_reg - M68K_REG_A0, s_spacing);
}

addStringInfo(detail, O, 0, false, 2);
SStream_concat(O, "%s.%c", getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
}

Expand All @@ -224,9 +318,15 @@ static void printAddressingMode(SStream* O, unsigned int pc, const cs_m68k* inst

if (op->mem.base_reg != M68K_REG_INVALID) {
if (op->mem.in_disp > 0)
SStream_concat(O, ",%s%s", s_spacing, getRegName(op->mem.base_reg));
{
addStringInfo(detail, O, 1, false, 2);
SStream_concat(O, ",%s", getRegName(op->mem.base_reg));
}
else
{
addStringInfo(detail, O, 0, false, 2);
SStream_concat(O, "%s", getRegName(op->mem.base_reg));
}
}

if (op->address_mode == M68K_AM_MEMI_POST_INDEX || op->address_mode == M68K_AM_PC_MEMI_POST_INDEX)
Expand Down Expand Up @@ -325,16 +425,17 @@ void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)

if (MI->Opcode == M68K_INS_CAS2) {
int reg_value_0, reg_value_1;
printAddressingMode(O, info->pc, ext, &ext->operands[0]); SStream_concat0(O, ",");
printAddressingMode(O, info->pc, ext, &ext->operands[1]); SStream_concat0(O, ",");
printAddressingMode(detail, O, info->pc, ext, &ext->operands[0], false); SStream_concat0(O, ",");
printAddressingMode(detail, O, info->pc, ext, &ext->operands[1], true); SStream_concat0(O, ",");
reg_value_0 = ext->operands[2].register_bits >> 4;
reg_value_1 = ext->operands[2].register_bits & 0xf;
SStream_concat(O, "(%s):(%s)", s_reg_names[M68K_REG_D0 + reg_value_0], s_reg_names[M68K_REG_D0 + reg_value_1]);
return;
}

for (i = 0; i < ext->op_count; ++i) {
printAddressingMode(O, info->pc, ext, &ext->operands[i]);
bool is_write = i == ext->op_count - 1;
printAddressingMode(detail, O, info->pc, ext, &ext->operands[i], is_write);
if ((i + 1) != ext->op_count)
SStream_concat(O, ",%s", s_spacing);
}
Expand Down
23 changes: 18 additions & 5 deletions external/capstone/include/capstone/capstone.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,18 +377,31 @@ typedef struct cs_opt_skipdata {
#define MAX_IMPL_R_REGS 20
#define MAX_NUM_GROUPS 8

#define REGISTER_STRING_INFO_REGISTER 0
#define REGISTER_STRING_INFO_REG_BITS 1

typedef struct RegisterStringInfo {
uint16_t offset;
uint8_t length;
uint8_t type;
} RegisterStringInfo;

/// NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON
/// Initialized as memset(., 0, offsetof(cs_detail, ARCH)+sizeof(cs_ARCH))
/// by ARCH_getInstruction in arch/ARCH/ARCHDisassembler.c
/// if cs_detail changes, in particular if a field is added after the union,
/// then update arch/ARCH/ARCHDisassembler.c accordingly
typedef struct cs_detail {
uint16_t regs_read
[MAX_IMPL_R_REGS]; ///< list of implicit registers read by this insn
uint8_t regs_read_count; ///< number of implicit registers read by this insn
RegisterStringInfo regs_read_string_info[MAX_IMPL_R_REGS];
uint8_t regs_read_string_count;

uint16_t regs_write
[MAX_IMPL_W_REGS]; ///< list of implicit registers modified by this insn
RegisterStringInfo regs_write_string_info[MAX_IMPL_W_REGS];
uint8_t regs_write_string_count;

uint16_t regs_read[MAX_IMPL_R_REGS]; ///< list of implicit registers read by this insn
uint8_t regs_read_count; ///< number of implicit registers read by this insn

uint16_t regs_write[MAX_IMPL_W_REGS]; ///< list of implicit registers modified by this insn
uint8_t regs_write_count; ///< number of implicit registers modified by this insn

uint8_t groups[MAX_NUM_GROUPS]; ///< list of group this instruction belong to
Expand Down
38 changes: 38 additions & 0 deletions src/debugger/disassembly_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,44 @@ static void draw_disassembly(DisassemblyView* self) {
cs_insn* insn = nullptr;
size_t count = cs_disasm(self->capstone, pc_addr - offset, count_bytes, start_disasm, 0, &insn);

for (size_t j = 0; j < count; j++) {
cs_detail* detail = insn[j].detail;

printf("--------------------------------------------------------\n");

printf("%08llxx %s %s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
printf(" read offsets registers: ");

for (int i = 0; i < detail->regs_read_string_count; i++) {
RegisterStringInfo* reg = &detail->regs_read_string_info[i];
printf(" %d %d %d |", reg->offset, reg->length, reg->type);
}

printf("\n");
printf(" write offsets registers:");

for (int i = 0; i < detail->regs_write_string_count; i++) {
RegisterStringInfo* reg = &detail->regs_write_string_info[i];
printf(" %d %d %d | \n", reg->offset, reg->length, reg->type);
}

printf("\n");
printf(" read registers: ");

for (int i = 0; i < detail->regs_read_count; i++) {
printf(" %d |", detail->regs_read[i]);
}

printf("\n");
printf(" write registers: ");

for (int i = 0; i < detail->regs_write_count; i++) {
printf(" %d |", detail->regs_write[i]);
}

printf("\n");
}

int max_instruction_width = 20;

ImGuiTableFlags flags = ImGuiTableFlags_Resizable
Expand Down
3 changes: 2 additions & 1 deletion src/quaesar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ int main(int argc, char** argv) {
currprefs.cpu_cycle_exact = 1;
currprefs.cpu_memory_cycle_exact = 1;
currprefs.blitter_cycle_exact = 1;
currprefs.turbo_emulation = 0;
currprefs.turbo_emulation = 1;
currprefs.sound_stereo_separation = 0;
currprefs.uaeboard = 1;

strcpy(currprefs.romfile, options.kickstart.c_str());

Expand Down

0 comments on commit 217602d

Please sign in to comment.