DSP: Give the assembler and disassembler saner public APIs. Fix bug in fileutil ReadFileToString. More cleanup.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2970 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2009-04-14 22:30:31 +00:00
parent f9903f2054
commit d973a9e001
15 changed files with 193 additions and 288 deletions

View File

@ -626,7 +626,7 @@ bool ReadFileToString(bool text_file, const char *filename, std::string *str)
fseek(f, 0, SEEK_SET);
char *buf = new char[len + 1];
buf[fread(buf, 1, len, f)] = 0;
*str = std::string(buf);
*str = std::string(buf, len);
fclose(f);
delete [] buf;
return true;

View File

@ -26,7 +26,6 @@
bool Assemble(const char *text, std::vector<u16> *code)
{
const char *fname = "tmp.asm";
AssemblerSettings settings;
settings.pc = 0;
// settings.decode_registers = false;
@ -34,22 +33,11 @@ bool Assemble(const char *text, std::vector<u16> *code)
settings.print_tabs = false;
settings.ext_separator = '\'';
if (!File::WriteStringToFile(true, text, fname))
return false;
// TODO: fix the terrible api of the assembler.
DSPAssembler assembler(settings);
assembler.gd_ass_init_pass(1);
if (!assembler.gd_ass_file(fname, 1))
return false;
assembler.gd_ass_init_pass(2);
if (!assembler.gd_ass_file(fname, 2))
return false;
if (!assembler.Assemble(text, code))
printf("%s", assembler.GetErrorString().c_str());
code->resize(assembler.gdg_buffer_size);
for (int i = 0; i < assembler.gdg_buffer_size; i++) {
(*code)[i] = *(u16 *)(assembler.gdg_buffer + i * 2);
}
return true;
}
@ -57,34 +45,19 @@ bool Disassemble(const std::vector<u16> &code, bool line_numbers, std::string *t
{
if (code.empty())
return false;
const char *tmp1 = "tmp1.bin";
const char *tmp2 = "tmp.txt";
// First we have to dump the code to a bin file.
FILE *f = fopen(tmp1, "wb");
fwrite(&code[0], 1, code.size() * 2, f);
fclose(f);
AssemblerSettings settings;
FILE* t = fopen(tmp2, "w");
if (t != NULL)
{
AssemblerSettings settings;
// These two prevent roundtripping.
settings.show_hex = false;
settings.show_pc = line_numbers;
settings.ext_separator = '\'';
settings.decode_names = false;
settings.decode_registers = true;
// These two prevent roundtripping.
settings.show_hex = false;
settings.show_pc = line_numbers;
settings.ext_separator = '\'';
settings.decode_names = false;
settings.decode_registers = true;
DSPDisassembler disasm(settings);
bool success = disasm.gd_dis_file(tmp1, t);
fclose(t);
File::ReadFileToString(true, tmp2, text);
return success;
}
return false;
DSPDisassembler disasm(settings);
bool success = disasm.Disassemble(0, code, text);
return success;
}
bool Compare(const std::vector<u16> &code1, const std::vector<u16> &code2)
@ -92,7 +65,7 @@ bool Compare(const std::vector<u16> &code1, const std::vector<u16> &code2)
if (code1.size() != code2.size())
printf("Size difference! 1=%i 2=%i\n", (int)code1.size(), (int)code2.size());
int count_equal = 0;
const int min_size = std::min(code1.size(), code2.size());
const int min_size = (int)std::min(code1.size(), code2.size());
for (int i = 0; i < min_size; i++)
{
if (code1[i] == code2[i])
@ -150,7 +123,7 @@ void BinaryStringBEToCode(const std::string &str, std::vector<u16> *code)
code->resize(str.size() / 2);
for (int i = 0; i < code->size(); i++)
{
(*code)[i] = (str[i * 2 + 0] << 8) | (str[i * 2 + 1]);
(*code)[i] = ((u16)(u8)str[i * 2 + 0] << 8) | ((u16)(u8)str[i * 2 + 1]);
}
}
@ -159,6 +132,7 @@ bool LoadBinary(const char *filename, std::vector<u16> *code)
std::string buffer;
if (!File::ReadFileToString(false, filename, &buffer))
return false;
BinaryStringBEToCode(buffer, code);
return true;
}

View File

@ -352,8 +352,8 @@ const DSPOPCTemplate opcodes_ext[] =
{"XXX", 0x0000, 0x0000, nop, nop, 1, 1, {{P_VAL, 1, 0, 0, 0x00ff}}, NULL, NULL,},
};
const u32 opcodes_size = sizeof(opcodes) / sizeof(DSPOPCTemplate);
const u32 opcodes_ext_size = sizeof(opcodes_ext) / sizeof(DSPOPCTemplate);
const int opcodes_size = sizeof(opcodes) / sizeof(DSPOPCTemplate);
const int opcodes_ext_size = sizeof(opcodes_ext) / sizeof(DSPOPCTemplate);
const pdlabel_t pdlabels[] =
{

View File

@ -120,9 +120,9 @@ typedef DSPOPCTemplate opc_t;
// Opcodes
extern const DSPOPCTemplate opcodes[];
extern const u32 opcodes_size;
extern const int opcodes_size;
extern const DSPOPCTemplate opcodes_ext[];
extern const u32 opcodes_ext_size;
extern const int opcodes_ext_size;
extern u8 opSize[OPTABLE_SIZE];
extern const DSPOPCTemplate cw;

View File

@ -44,6 +44,7 @@ Initial import
#include <map>
#include "Common.h"
#include "FileUtil.h"
#include "DSPInterpreter.h"
#include "DSPTables.h"
#include "disassemble.h"
@ -80,38 +81,60 @@ DSPAssembler::DSPAssembler(const AssemblerSettings &settings)
: current_param(0),
cur_addr(0),
cur_pass(0),
settings_(settings)
settings_(settings)
{
gdg_buffer = NULL;
}
DSPAssembler::~DSPAssembler()
{
}
bool DSPAssembler::Assemble(const char *text, std::vector<u16> *code, std::vector<int> *line_numbers)
{
if (line_numbers)
line_numbers->clear();
const char *fname = "tmp.asm";
if (!File::WriteStringToFile(true, text, fname))
return false;
InitPass(1);
if (!AssembleFile(fname, 1))
return false;
InitPass(2);
if (!AssembleFile(fname, 2))
return false;
code->resize(gdg_buffer_size);
for (int i = 0; i < gdg_buffer_size; i++) {
(*code)[i] = *(u16 *)(gdg_buffer + i * 2);
}
last_error_str = "(no errors)";
last_error = ERR_OK;
return true;
}
void DSPAssembler::parse_error(err_t err_code, const char *extra_info)
{
fprintf(stderr, "%i : %s\n", code_line, cur_line);
failed = true;
char error_buffer[1024];
char *buf_ptr = error_buffer;
buf_ptr += sprintf(buf_ptr, "%i : %s\n", code_line, cur_line);
if (!extra_info)
extra_info = "-";
if (fsrc)
fclose(fsrc);
else
{
fprintf(stderr, "ERROR: %s : %s\n", err_string[err_code], extra_info);
}
// modified by Hermes
buf_ptr += sprintf(buf_ptr, "ERROR: %s : %s\n", err_string[err_code], extra_info);
if (current_param == 0)
fprintf(stderr, "ERROR: %s Line: %d : %s\n", err_string[err_code], code_line, extra_info);
buf_ptr += sprintf(buf_ptr, "ERROR: %s Line: %d : %s\n", err_string[err_code], code_line, extra_info);
else
fprintf(stderr, "ERROR: %s Line: %d Param: %d : %s\n",
err_string[err_code], code_line, current_param, extra_info);
buf_ptr += sprintf(buf_ptr, "ERROR: %s Line: %d Param: %d : %s\n",
err_string[err_code], code_line, current_param, extra_info);
last_error_str = error_buffer;
last_error = err_code;
}
char *skip_spaces(char *ptr)
@ -692,7 +715,7 @@ void DSPAssembler::build_code(const opc_t *opc, param_t *par, u32 par_count, u16
}
}
void DSPAssembler::gd_ass_init_pass(int pass)
void DSPAssembler::InitPass(int pass)
{
failed = false;
if (pass == 1)
@ -719,7 +742,7 @@ void DSPAssembler::gd_ass_init_pass(int pass)
segment_addr[SEGMENT_OVERLAY] = 0;
}
bool DSPAssembler::gd_ass_file(const char *fname, int pass)
bool DSPAssembler::AssembleFile(const char *fname, int pass)
{
int disable_text = 0; // modified by Hermes
@ -892,7 +915,7 @@ bool DSPAssembler::gd_ass_file(const char *fname, int pass)
tmpstr = (char *)malloc(strlen(params[0].str) + 1);
strcpy(tmpstr, params[0].str);
}
gd_ass_file(tmpstr, pass);
AssembleFile(tmpstr, pass);
free(tmpstr);
}
else

View File

@ -67,8 +67,16 @@ public:
DSPAssembler(const AssemblerSettings &settings);
~DSPAssembler();
void Assemble(const char *text, std::vector<u16> *code);
// line_numbers is optional (and not yet implemented). It'll receieve a list of ints,
// one for each word of code, indicating the source assembler code line number it came from.
// If returns false, call GetErrorString to get some text to present to the user.
bool Assemble(const char *text, std::vector<u16> *code, std::vector<int> *line_numbers = NULL);
std::string GetErrorString() const { return last_error_str; }
err_t GetError() const { return last_error; }
private:
struct label_t
{
label_t(const char *lbl, s32 address) : label(lbl), addr(address) {}
@ -90,13 +98,13 @@ public:
SEGMENT_OVERLAY,
SEGMENT_MAX
};
void gd_ass_init_pass(int pass);
bool gd_ass_file(const char *fname, int pass);
void InitPass(int pass);
bool AssembleFile(const char *fname, int pass);
char *gdg_buffer;
int gdg_buffer_size;
private:
void parse_error(err_t err_code, const char *extra_info = NULL);
void gd_ass_register_label(const char *label, u16 lval);
void gd_ass_clear_labels();
@ -119,6 +127,8 @@ private:
FILE *fsrc;
u32 code_line;
bool failed;
std::string last_error_str;
err_t last_error;
typedef std::map<std::string, std::string> AliasMap;
AliasMap aliases;

View File

@ -27,6 +27,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "FileUtil.h"
#include "disassemble.h"
#include "DSPTables.h"
@ -39,31 +40,81 @@ extern void nop(const UDSPInstruction& opc);
DSPDisassembler::DSPDisassembler(const AssemblerSettings &settings)
: settings_(settings)
{
memset(unk_opcodes, 0, sizeof(unk_opcodes));
}
char *DSPDisassembler::gd_dis_params(const DSPOPCTemplate* opc, u16 op1, u16 op2, char *strbuf)
DSPDisassembler::~DSPDisassembler()
{
// Some old code for logging unknown ops.
char filename[MAX_PATH];
sprintf(filename, "%sUnkOps.txt", FULL_DSP_DUMP_DIR);
FILE *uo = fopen(filename, "w");
if (!uo)
return;
int count = 0;
for (std::map<u16, int>::const_iterator iter = unk_opcodes.begin();
iter != unk_opcodes.end(); ++iter)
{
if (iter->second > 0)
{
count++;
fprintf(uo, "OP%04x\t%d", iter->first, iter->second);
for (int j = 15; j >= 0; j--) // print op bits
{
if ((j & 0x3) == 3)
fprintf(uo, "\tb");
fprintf(uo, "%d", (iter->first >> j) & 0x1);
}
fprintf(uo, "\n");
}
}
fprintf(uo, "Unknown opcodes count: %d\n", count);
fclose(uo);
}
bool DSPDisassembler::Disassemble(int start_pc, const std::vector<u16> &code, std::string *text)
{
const char *tmp1 = "tmp1.bin";
const char *tmp2 = "tmp.txt";
// First we have to dump the code to a bin file.
FILE *f = fopen(tmp1, "wb");
fwrite(&code[0], 1, code.size() * 2, f);
fclose(f);
FILE* t = fopen(tmp2, "w");
if (!t)
return false;
bool success = DisFile(tmp1, t);
fclose(t);
File::ReadFileToString(true, tmp2, text);
return success;
}
char *DSPDisassembler::DisParams(const DSPOPCTemplate& opc, u16 op1, u16 op2, char *strbuf)
{
char *buf = strbuf;
for (int j = 0; j < opc->param_count; j++)
for (int j = 0; j < opc.param_count; j++)
{
if (j > 0)
buf += sprintf(buf, ", ");
u32 val;
if (opc->params[j].loc >= 1)
if (opc.params[j].loc >= 1)
val = op2;
else
val = op1;
val &= opc->params[j].mask;
val &= opc.params[j].mask;
if (opc->params[j].lshift < 0)
val = val << (-opc->params[j].lshift);
if (opc.params[j].lshift < 0)
val = val << (-opc.params[j].lshift);
else
val = val >> opc->params[j].lshift;
val = val >> opc.params[j].lshift;
u32 type = opc->params[j].type;
u32 type = opc.params[j].type;
if ((type & 0xff) == 0x10)
type &= 0xff00;
@ -102,9 +153,9 @@ char *DSPDisassembler::gd_dis_params(const DSPOPCTemplate* opc, u16 op1, u16 op2
break;
case P_IMM:
if (opc->params[j].size != 2)
if (opc.params[j].size != 2)
{
if (opc->params[j].mask == 0x003f) // LSL, LSR, ASL, ASR
if (opc.params[j].mask == 0x003f) // LSL, LSR, ASL, ASR
sprintf(buf, "#%d", (val & 0x20) ? (val | 0xFFFFFFC0) : val);
else
sprintf(buf, "#0x%02x", val);
@ -114,7 +165,7 @@ char *DSPDisassembler::gd_dis_params(const DSPOPCTemplate* opc, u16 op1, u16 op2
break;
case P_MEM:
if (opc->params[j].size != 2)
if (opc.params[j].size != 2)
val = (u16)(s8)val;
if (settings_.decode_names)
@ -124,7 +175,7 @@ char *DSPDisassembler::gd_dis_params(const DSPOPCTemplate* opc, u16 op1, u16 op2
break;
default:
ERROR_LOG(DSPLLE, "Unknown parameter type: %x", opc->params[j].type);
ERROR_LOG(DSPLLE, "Unknown parameter type: %x", opc.params[j].type);
break;
}
@ -134,70 +185,7 @@ char *DSPDisassembler::gd_dis_params(const DSPOPCTemplate* opc, u16 op1, u16 op2
return strbuf;
}
#if 0
u16 gd_dis_get_opcode_size(gd_globals_t* gdg)
{
const DSPOPCTemplate* opc = 0;
const DSPOPCTemplate* opc_ext = 0;
bool extended;
// Undefined memory.
if ((gdg->pc & 0x7fff) >= 0x1000)
return 1;
u32 op1 = gdg->binbuf[gdg->pc & 0x0fff];
for (u32 j = 0; j < opcodes_size; j++)
{
u16 mask;
if (opcodes[j].size & P_EXT)
mask = opcodes[j].opcode_mask & 0xff00;
else
mask = opcodes[j].opcode_mask;
if ((op1 & mask) == opcodes[j].opcode)
{
opc = &opcodes[j];
break;
}
}
if (!opc)
{
ERROR_LOG(DSPLLE, "get_opcode_size ARGH");
}
if (opc->size & P_EXT && op1 & 0x00ff)
extended = true;
else
extended = false;
if (extended)
{
// opcode has an extension
// find opcode
for (u32 j = 0; j < opcodes_ext_size; j++)
{
if ((op1 & opcodes_ext[j].opcode_mask) == opcodes_ext[j].opcode)
{
opc_ext = &opcodes_ext[j];
break;
}
}
if (!opc_ext)
{
ERROR_LOG(DSPLLE, "get_opcode_size ext ARGH");
}
return opc_ext->size;
}
return opc->size & ~P_EXT;
}
#endif
void DSPDisassembler::gd_dis_opcode(const u16 *binbuf, u16 *pc, std::string *dest)
void DSPDisassembler::DisOpcode(const u16 *binbuf, u16 *pc, std::string *dest)
{
u32 op2;
char buffer[256];
@ -297,22 +285,19 @@ void DSPDisassembler::gd_dis_opcode(const u16 *binbuf, u16 *pc, std::string *des
buf += strlen(buf);
if (opc->param_count > 0)
gd_dis_params(opc, op1, op2, buf);
DisParams(*opc, op1, op2, buf);
buf += strlen(buf);
if (extended)
{
if (opc->param_count > 0)
sprintf(buf, " ");
buf += sprintf(buf, " ");
buf += strlen(buf);
sprintf(buf, ": ");
buf += strlen(buf);
buf += sprintf(buf, ": ");
if (opc_ext->param_count > 0)
gd_dis_params(opc_ext, op1, op2, buf);
DisParams(*opc_ext, op1, op2, buf);
buf += strlen(buf);
}
@ -332,10 +317,8 @@ void DSPDisassembler::gd_dis_opcode(const u16 *binbuf, u16 *pc, std::string *des
dest->append(buffer);
}
bool DSPDisassembler::gd_dis_file(const char* name, FILE* output)
bool DSPDisassembler::DisFile(const char* name, FILE* output)
{
gd_dis_open_unkop();
FILE* in;
u32 size;
@ -346,95 +329,24 @@ bool DSPDisassembler::gd_dis_file(const char* name, FILE* output)
}
fseek(in, 0, SEEK_END);
size = (int)ftell(in);
size = (int)ftell(in) & ~1;
fseek(in, 0, SEEK_SET);
u16 *binbuf = (u16*)malloc(size);
u16 *binbuf = new u16[size / 2];
fread(binbuf, 1, size, in);
for (u16 pc = 0; pc < (size / 2);)
{
std::string str;
gd_dis_opcode(binbuf, &pc, &str);
DisOpcode(binbuf, &pc, &str);
fprintf(output, "%s\n", str.c_str());
}
fclose(in);
free(binbuf);
gd_dis_close_unkop();
delete [] binbuf;
return true;
}
void DSPDisassembler::gd_dis_close_unkop()
{
FILE* uo;
int i, j;
u32 count = 0;
char filename[MAX_PATH];
sprintf(filename, "%sUnkOps.bin", FULL_DSP_DUMP_DIR);
uo = fopen(filename, "wb");
if (uo)
{
fwrite(unk_opcodes, 1, sizeof(unk_opcodes), uo);
fclose(uo);
}
sprintf(filename, "%sUnkOps.txt", FULL_DSP_DUMP_DIR);
uo = fopen(filename, "w");
if (uo)
{
for (i = 0; i < 0x10000; i++)
{
if (unk_opcodes[i])
{
count++;
fprintf(uo, "OP%04x\t%d", i, unk_opcodes[i]);
for (j = 15; j >= 0; j--)
{
if ((j & 0x3) == 3)
fprintf(uo, "\tb");
fprintf(uo, "%d", (i >> j) & 0x1);
}
fprintf(uo, "\n");
}
}
fprintf(uo, "Unknown opcodes count: %d\n", count);
fclose(uo);
}
}
void DSPDisassembler::gd_dis_open_unkop()
{
FILE* uo;
char filename[MAX_PATH];
sprintf(filename, "%sUnkOps.bin", FULL_DSP_DUMP_DIR);
uo = fopen(filename, "rb");
if (uo)
{
fread(unk_opcodes, 1, sizeof(unk_opcodes), uo);
fclose(uo);
}
else
{
for (int i = 0; i < 0x10000; i++)
{
unk_opcodes[i] = 0;
}
}
}
const char *gd_get_reg_name(u16 reg)
{
return regnames[reg].name;

View File

@ -25,6 +25,9 @@
#ifndef _DSP_DISASSEMBLE_H
#define _DSP_DISASSEMBLE_H
#include <map>
#include <vector>
#include "Common.h"
#include "DSPTables.h"
@ -55,25 +58,24 @@ class DSPDisassembler
{
public:
DSPDisassembler(const AssemblerSettings &settings);
~DSPDisassembler() {}
~DSPDisassembler();
// Moves PC forward and writes the result to dest.
void gd_dis_opcode(const u16 *binbuf, u16 *pc, std::string *dest);
bool gd_dis_file(const char* name, FILE *output);
bool Disassemble(int start_pc, const std::vector<u16> &code, std::string *text);
void gd_dis_close_unkop();
void gd_dis_open_unkop();
const char* gd_dis_get_reg_name(u16 reg);
// Warning - this one is trickier to use right.
void DisOpcode(const u16 *binbuf, u16 *pc, std::string *dest);
private:
char* gd_dis_params(const DSPOPCTemplate* opc, u16 op1, u16 op2, char* strbuf);
u32 unk_opcodes[0x10000];
// Moves PC forward and writes the result to dest.
bool DisFile(const char* name, FILE *output);
char* DisParams(const DSPOPCTemplate& opc, u16 op1, u16 op2, char* strbuf);
std::map<u16, int> unk_opcodes;
const AssemblerSettings settings_;
};
const char *gd_get_reg_name(u16 reg);
//u16 gd_dis_get_opcode_size(gd_globals_t* gdg);
#endif // _DSP_DISASSEMBLE_H

View File

@ -44,6 +44,7 @@ volatile u32 gdsp_running;
static bool cr_halt = true;
static bool cr_external_int = false;
void UpdateCachedCR()
{
cr_halt = (g_dsp.cr & 0x4) != 0;

View File

@ -116,12 +116,7 @@ void gdsp_run_cycles(int cycles);
void gdsp_stop();
void gdsp_write_cr(u16 val);
u16 gdsp_read_cr(void);
u16* gdsp_get_iram(void);
u16* gdsp_get_irom(void);
u16* gdsp_get_dram(void);
u16* gdsp_get_drom(void);
u16 gdsp_read_cr();
// sets a flag in the pending exception register.
void gdsp_generate_exception(u8 level);

View File

@ -120,15 +120,15 @@ void RunAsmTests()
// Let's get brutal. We generate random code bytes and make sure that they can
// be roundtripped. We don't expect it to always succeed but it'll be sure to generate
// interesting test cases.
/*
puts("Insane Random Code Test\n");
std::vector<u16> rand_code;
GenRandomCode(31, &rand_code);
GenRandomCode(30, &rand_code);
std::string rand_code_text;
Disassemble(rand_code, true, &rand_code_text);
printf("%s", rand_code_text.c_str());
RoundTrip(rand_code);
*/
std::string dsp_test;
if (File::ReadFileToString(true, "C:/devkitPro/examples/wii/asndlib/dsptest/dsp_test.ds", &dsp_test))

View File

@ -45,7 +45,6 @@ bool DSPHost_Running()
u32 DSPHost_CodeLoaded(const u8 *ptr, int size)
{
u32 crc = GenerateCRC(ptr, size);
DumpDSPCode(ptr, size, crc);
return crc;
}

View File

@ -221,7 +221,7 @@ void DSPDebuggerLLE::RebuildDisAsmListView()
AssemblerSettings settings;
DSPDisassembler disasm(settings);
std::string op_str;
disasm.gd_dis_opcode(binbuf,&settings.pc, &op_str);
disasm.DisOpcode(binbuf, &settings.pc, &op_str);
const char* pParameter = NULL;
const char* pExtension = NULL;

View File

@ -21,58 +21,48 @@
#include "Common.h"
#include "Globals.h"
#include "FileUtil.h"
#include "DSPCodeUtil.h"
#include "Tools.h"
#include "disassemble.h"
#include "gdsp_interpreter.h"
bool DumpDSPCode(const u8 *data, u32 _Length, u32 crc)
{
char szFilename[MAX_PATH];
sprintf(szFilename, "%sDSP_UC_%08X.bin", FULL_DSP_DUMP_DIR, crc);
FILE* pFile = fopen(szFilename, "wb");
if (pFile)
{
fwrite(data, _Length, 1, pFile);
fclose(pFile);
}
else
{
PanicAlert("Cant open file (%s) to dump UCode!!", szFilename);
return false;
}
if (!DisasmUCodeDump(crc))
{
PanicAlert("Failed to disasm UCode!!", szFilename);
return false;
}
return true;
}
bool DisasmUCodeDump(u32 crc)
bool DumpDSPCode(const u8 *code_be, int size_in_bytes, u32 crc)
{
char binFile[MAX_PATH];
char txtFile[MAX_PATH];
sprintf(binFile, "%sDSP_UC_%08X.bin", FULL_DSP_DUMP_DIR, crc);
sprintf(txtFile, "%sDSP_UC_%08X.txt", FULL_DSP_DUMP_DIR, crc);
FILE* t = fopen(txtFile, "wb");
if (t != NULL)
FILE* pFile = fopen(binFile, "wb");
if (pFile)
{
AssemblerSettings settings;
settings.show_hex = true;
settings.show_pc = true;
settings.ext_separator = '\t';
settings.decode_names = true;
settings.decode_registers = true;
DSPDisassembler disasm(settings);
disasm.gd_dis_file(binFile, t);
fclose(t);
return true;
fwrite(code_be, size_in_bytes, 1, pFile);
fclose(pFile);
}
else
{
PanicAlert("Cant open file (%s) to dump UCode!!", binFile);
return false;
}
// Load the binary back in.
std::vector<u16> code;
LoadBinary(binFile, &code);
AssemblerSettings settings;
settings.show_hex = true;
settings.show_pc = true;
settings.ext_separator = '\t';
settings.decode_names = true;
settings.decode_registers = true;
std::string text;
DSPDisassembler disasm(settings);
if (!disasm.Disassemble(0, code, &text))
return false;
return File::WriteStringToFile(true, text, txtFile);
}
u32 GenerateCRC(const unsigned char* _pBuffer, int _pLength)

View File

@ -18,8 +18,7 @@
#ifndef _DSPLLE_TOOLS_H
#define _DSPLLE_TOOLS_H
bool DumpDSPCode(const u8 *data, u32 _Length, u32 crc);
bool DisasmUCodeDump(u32 crc);
bool DumpDSPCode(const u8 *code_be, int size_in_bytes, u32 crc);
u32 GenerateCRC(const unsigned char* _pBuffer, int _pLength);
bool DumpCWCode(u32 _Address, u32 _Length);