DSPDisassembler: get rid of double-pass and temp file

This commit is contained in:
Michael Maltese 2017-05-15 17:12:15 -07:00
parent 898bbffaa7
commit 391c7319f5
5 changed files with 25 additions and 64 deletions

View file

@ -56,7 +56,7 @@ bool Disassemble(const std::vector<u16>& code, bool line_numbers, std::string& t
settings.decode_registers = true; settings.decode_registers = true;
DSPDisassembler disasm(settings); DSPDisassembler disasm(settings);
bool success = disasm.Disassemble(0, code, 0x0000, text); bool success = disasm.Disassemble(code, 0x0000, text);
return success; return success;
} }
@ -79,9 +79,9 @@ bool Compare(const std::vector<u16>& code1, const std::vector<u16>& code2)
{ {
std::string line1, line2; std::string line1, line2;
u16 pc = i; u16 pc = i;
disassembler.DisassembleOpcode(&code1[0], 0x0000, 2, &pc, line1); disassembler.DisassembleOpcode(&code1[0], 0x0000, &pc, line1);
pc = i; pc = i;
disassembler.DisassembleOpcode(&code2[0], 0x0000, 2, &pc, line2); disassembler.DisassembleOpcode(&code2[0], 0x0000, &pc, line2);
printf("!! %04x : %04x vs %04x - %s vs %s\n", i, code1[i], code2[i], line1.c_str(), printf("!! %04x : %04x vs %04x - %s vs %s\n", i, code1[i], code2[i], line1.c_str(),
line2.c_str()); line2.c_str());
} }
@ -94,7 +94,7 @@ bool Compare(const std::vector<u16>& code1, const std::vector<u16>& code2)
{ {
u16 pc = i; u16 pc = i;
std::string line; std::string line;
disassembler.DisassembleOpcode(&longest[0], 0x0000, 2, &pc, line); disassembler.DisassembleOpcode(&longest[0], 0x0000, &pc, line);
printf("!! %s\n", line.c_str()); printf("!! %s\n", line.c_str());
} }
} }

View file

@ -55,19 +55,15 @@ DSPDisassembler::~DSPDisassembler()
uo << StringFromFormat("Unknown opcodes count: %d\n", count); uo << StringFromFormat("Unknown opcodes count: %d\n", count);
} }
bool DSPDisassembler::Disassemble(int start_pc, const std::vector<u16>& code, int base_addr, bool DSPDisassembler::Disassemble(const std::vector<u16>& code, int base_addr, std::string& text)
std::string& text)
{ {
const char* tmp1 = "tmp1.bin"; for (u16 pc = 0; pc < code.size();)
// First we have to dump the code to a bin file.
{ {
File::IOFile f(tmp1, "wb"); if (!DisassembleOpcode(code.data(), base_addr, &pc, text))
f.WriteArray(&code[0], code.size()); return false;
text.append("\n");
} }
return true;
// Run the two passes.
return DisassembleFile(tmp1, base_addr, 1, text) && DisassembleFile(tmp1, base_addr, 2, text);
} }
std::string DSPDisassembler::DisassembleParameters(const DSPOPCTemplate& opc, u16 op1, u16 op2) std::string DSPDisassembler::DisassembleParameters(const DSPOPCTemplate& opc, u16 op1, u16 op2)
@ -170,11 +166,9 @@ static std::string MakeLowerCase(std::string in)
return in; return in;
} }
bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, int pass, u16* pc, bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, u16* pc,
std::string& dest) std::string& dest)
{ {
std::string buf(" ");
if ((*pc & 0x7fff) >= 0x1000) if ((*pc & 0x7fff) >= 0x1000)
{ {
++pc; ++pc;
@ -217,7 +211,7 @@ bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, int pa
// printing // printing
if (settings_.show_pc) if (settings_.show_pc)
buf += StringFromFormat("%04x ", *pc); dest += StringFromFormat("%04x ", *pc);
u16 op2; u16 op2;
@ -226,13 +220,13 @@ bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, int pa
{ {
op2 = binbuf[(*pc + 1) & 0x0fff]; op2 = binbuf[(*pc + 1) & 0x0fff];
if (settings_.show_hex) if (settings_.show_hex)
buf += StringFromFormat("%04x %04x ", op1, op2); dest += StringFromFormat("%04x %04x ", op1, op2);
} }
else else
{ {
op2 = 0; op2 = 0;
if (settings_.show_hex) if (settings_.show_hex)
buf += StringFromFormat("%04x ", op1); dest += StringFromFormat("%04x ", op1);
} }
std::string opname = opc->name; std::string opname = opc->name;
@ -248,30 +242,30 @@ bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, int pa
ext_buf = MakeLowerCase(ext_buf); ext_buf = MakeLowerCase(ext_buf);
if (settings_.print_tabs) if (settings_.print_tabs)
buf += StringFromFormat("%s\t", ext_buf.c_str()); dest += StringFromFormat("%s\t", ext_buf.c_str());
else else
buf += StringFromFormat("%-12s", ext_buf.c_str()); dest += StringFromFormat("%-12s", ext_buf.c_str());
if (opc->param_count > 0) if (opc->param_count > 0)
buf += DisassembleParameters(*opc, op1, op2); dest += DisassembleParameters(*opc, op1, op2);
// Handle opcode extension. // Handle opcode extension.
if (is_extended) if (is_extended)
{ {
if (opc->param_count > 0) if (opc->param_count > 0)
buf += " "; dest += " ";
buf += ": "; dest += ": ";
if (opc_ext->param_count > 0) if (opc_ext->param_count > 0)
buf += DisassembleParameters(*opc_ext, op1, op2); dest += DisassembleParameters(*opc_ext, op1, op2);
} }
if (opc->opcode_mask == 0) if (opc->opcode_mask == 0)
{ {
// unknown opcode // unknown opcode
unk_opcodes[op1]++; unk_opcodes[op1]++;
buf += "\t\t; *** UNKNOWN OPCODE ***"; dest += "\t\t; *** UNKNOWN OPCODE ***";
} }
if (is_extended) if (is_extended)
@ -279,35 +273,6 @@ bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, int pa
else else
*pc += opc->size; *pc += opc->size;
if (pass == 2)
dest.append(buf);
return true;
}
bool DSPDisassembler::DisassembleFile(const std::string& name, int base_addr, int pass,
std::string& output)
{
File::IOFile in(name, "rb");
if (!in)
{
printf("gd_dis_file: No input\n");
return false;
}
const int size = ((int)in.GetSize() & ~1) / 2;
std::vector<u16> binbuf(size);
in.ReadArray(binbuf.data(), size);
in.Close();
// Actually do the disassembly.
for (u16 pc = 0; pc < size;)
{
DisassembleOpcode(binbuf.data(), base_addr, pass, &pc, output);
if (pass == 2)
output.append("\n");
}
return true; return true;
} }
} // namespace DSP } // namespace DSP

View file

@ -36,16 +36,12 @@ public:
explicit DSPDisassembler(const AssemblerSettings& settings); explicit DSPDisassembler(const AssemblerSettings& settings);
~DSPDisassembler(); ~DSPDisassembler();
bool Disassemble(int start_pc, const std::vector<u16>& code, int base_addr, std::string& text); bool Disassemble(const std::vector<u16>& code, int base_addr, std::string& text);
// Warning - this one is trickier to use right. // Warning - this one is trickier to use right.
// Use pass == 2 if you're just using it by itself. bool DisassembleOpcode(const u16* binbuf, int base_addr, u16* pc, std::string& dest);
bool DisassembleOpcode(const u16* binbuf, int base_addr, int pass, u16* pc, std::string& dest);
private: private:
// Moves PC forward and writes the result to dest.
bool DisassembleFile(const std::string& name, int base_addr, int pass, std::string& output);
std::string DisassembleParameters(const DSPOPCTemplate& opc, u16 op1, u16 op2); std::string DisassembleParameters(const DSPOPCTemplate& opc, u16 op1, u16 op2);
std::map<u16, int> unk_opcodes; std::map<u16, int> unk_opcodes;

View file

@ -230,7 +230,7 @@ void AutoDisassembly(u16 start_addr, u16 end_addr)
addr_to_line[addr] = line_counter; addr_to_line[addr] = line_counter;
std::string buf; std::string buf;
if (!disasm.DisassembleOpcode(ptr, 0, 2, &addr, buf)) if (!disasm.DisassembleOpcode(ptr, 0, &addr, buf))
{ {
ERROR_LOG(DSPLLE, "disasm failed at %04x", addr); ERROR_LOG(DSPLLE, "disasm failed at %04x", addr);
break; break;

View file

@ -23,7 +23,7 @@ static bool RoundTrippableDissassemble(const std::vector<u16>& code, std::string
settings.show_pc = false; settings.show_pc = false;
DSP::DSPDisassembler disasm(settings); DSP::DSPDisassembler disasm(settings);
return disasm.Disassemble(0x0000, code, 0x0000, text); return disasm.Disassemble(code, 0x0000, text);
} }
// This test goes from text ASM to binary to text ASM and once again back to binary. // This test goes from text ASM to binary to text ASM and once again back to binary.