summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorLioncash <mathew1800@gmail.com>2018-06-17 18:05:58 -0400
committerLioncash <mathew1800@gmail.com>2018-06-17 18:21:33 -0400
commit78eba289752d22ed86304320a95ce4dfd3e7260f (patch)
tree46ee0a0cdad8d3ad60184b003c7eb7bc289193a5 /Source
parent6bfbc1988ee059205f276af3228085394c950031 (diff)
DSPTool: Factor out behavior from main()
Keeps all behavior localized in their own functions, making it a tiny bit nicer to read.
Diffstat (limited to 'Source')
-rw-r--r--Source/DSPTool/DSPTool.cpp439
1 files changed, 234 insertions, 205 deletions
diff --git a/Source/DSPTool/DSPTool.cpp b/Source/DSPTool/DSPTool.cpp
index 93bd019623..bd100e6d83 100644
--- a/Source/DSPTool/DSPTool.cpp
+++ b/Source/DSPTool/DSPTool.cpp
@@ -112,6 +112,236 @@ static void CodesToHeader(const std::vector<u16>* codes, const std::vector<std::
header.append("};\n");
}
+static void PerformBinaryComparison(const std::string& lhs, const std::string& rhs)
+{
+ std::string binary_code;
+
+ File::ReadFileToString(lhs, binary_code);
+ const std::vector<u16> code1 = DSP::BinaryStringBEToCode(binary_code);
+
+ File::ReadFileToString(rhs, binary_code);
+ const std::vector<u16> code2 = DSP::BinaryStringBEToCode(binary_code);
+
+ DSP::Compare(code1, code2);
+}
+
+static void PrintResults(const std::string& input_name, const std::string& output_name,
+ bool print_results_srhack, bool print_results_prodhack)
+{
+ std::string dumpfile;
+
+ File::ReadFileToString(input_name, dumpfile);
+ const std::vector<u16> reg_vector = DSP::BinaryStringBEToCode(dumpfile);
+
+ std::string results("Start:\n");
+ for (int initial_reg = 0; initial_reg < 32; initial_reg++)
+ {
+ results.append(StringFromFormat("%02x %04x ", initial_reg, reg_vector.at(initial_reg)));
+ if ((initial_reg + 1) % 8 == 0)
+ results.append("\n");
+ }
+
+ results.append("\n");
+ results.append("Step [number]:\n[Reg] [last value] [current value]\n\n");
+
+ for (unsigned int step = 1; step < reg_vector.size() / 32; step++)
+ {
+ bool changed = false;
+ u16 current_reg;
+ u16 last_reg;
+ u32 htemp;
+ // results.append(StringFromFormat("Step %3d: (CW 0x%04x) UC:%03d\n", step, 0x8fff+step,
+ // (step-1)/32));
+ results.append(StringFromFormat("Step %3d:\n", step));
+ for (int reg = 0; reg < 32; reg++)
+ {
+ if (reg >= 0x0c && reg <= 0x0f)
+ continue;
+ if (print_results_srhack && reg == 0x13)
+ continue;
+
+ if (print_results_prodhack && reg >= 0x15 && reg <= 0x17)
+ {
+ switch (reg)
+ {
+ case 0x15: // DSP_REG_PRODM
+ last_reg =
+ reg_vector.at((step * 32 - 32) + reg) + reg_vector.at((step * 32 - 32) + reg + 2);
+ current_reg = reg_vector.at(step * 32 + reg) + reg_vector.at(step * 32 + reg + 2);
+ break;
+ case 0x16: // DSP_REG_PRODH
+ htemp = ((reg_vector.at(step * 32 + reg - 1) + reg_vector.at(step * 32 + reg + 1)) &
+ ~0xffff) >>
+ 16;
+ current_reg = (u8)(reg_vector.at(step * 32 + reg) + htemp);
+ htemp =
+ ((reg_vector.at(step * 32 - 32 + reg - 1) + reg_vector.at(step * 32 - 32 + reg + 1)) &
+ ~0xffff) >>
+ 16;
+ last_reg = (u8)(reg_vector.at(step * 32 - 32 + reg) + htemp);
+ break;
+ case 0x17: // DSP_REG_PRODM2
+ default:
+ current_reg = 0;
+ last_reg = 0;
+ break;
+ }
+ }
+ else
+ {
+ current_reg = reg_vector.at(step * 32 + reg);
+ last_reg = reg_vector.at((step * 32 - 32) + reg);
+ }
+ if (last_reg != current_reg)
+ {
+ results.append(StringFromFormat("%02x %-7s: %04x %04x\n", reg, DSP::pdregname(reg),
+ last_reg, current_reg));
+ changed = true;
+ }
+ }
+
+ if (changed)
+ results.append("\n");
+ else
+ results.append("No Change\n\n");
+ }
+
+ if (output_name.empty())
+ printf("%s", results.c_str());
+ else
+ File::WriteStringToFile(results, output_name.c_str());
+}
+
+static bool PerformDisassembly(const std::string& input_name, const std::string& output_name)
+{
+ if (input_name.empty())
+ {
+ printf("Disassemble: Must specify input.\n");
+ return false;
+ }
+
+ std::string binary_code;
+ File::ReadFileToString(input_name, binary_code);
+ const std::vector<u16> code = DSP::BinaryStringBEToCode(binary_code);
+ std::string text;
+ DSP::Disassemble(code, true, text);
+
+ if (output_name.empty())
+ printf("%s", text.c_str());
+ else
+ File::WriteStringToFile(text, output_name);
+
+ printf("Disassembly completed successfully!\n");
+ return true;
+}
+
+static bool PerformAssembly(const std::string& input_name, const std::string& output_name,
+ const std::string& output_header_name, bool multiple, bool force,
+ bool output_size)
+{
+ if (input_name.empty())
+ {
+ printf("Assemble: Must specify input.\n");
+ return false;
+ }
+
+ std::string source;
+ if (File::ReadFileToString(input_name.c_str(), source))
+ {
+ if (multiple)
+ {
+ // When specifying a list of files we must compile a header
+ // (we can't assemble multiple files to one binary)
+ // since we checked it before, we assume output_header_name isn't empty
+ int lines;
+ std::vector<u16>* codes;
+ std::vector<std::string> files;
+ std::string header, currentSource;
+ size_t lastPos = 0, pos = 0;
+
+ source.append("\n");
+
+ while ((pos = source.find('\n', lastPos)) != std::string::npos)
+ {
+ std::string temp = source.substr(lastPos, pos - lastPos);
+ if (!temp.empty())
+ files.push_back(temp);
+ lastPos = pos + 1;
+ }
+
+ lines = (int)files.size();
+
+ if (lines == 0)
+ {
+ printf("ERROR: Must specify at least one file\n");
+ return false;
+ }
+
+ codes = new std::vector<u16>[lines];
+
+ for (int i = 0; i < lines; i++)
+ {
+ if (!File::ReadFileToString(files[i].c_str(), currentSource))
+ {
+ printf("ERROR reading %s, skipping...\n", files[i].c_str());
+ lines--;
+ }
+ else
+ {
+ if (!DSP::Assemble(currentSource, codes[i], force))
+ {
+ printf("Assemble: Assembly of %s failed due to errors\n", files[i].c_str());
+ lines--;
+ }
+ if (output_size)
+ {
+ printf("%s: %d\n", files[i].c_str(), (int)codes[i].size());
+ }
+ }
+ }
+
+ CodesToHeader(codes, &files, lines, output_header_name.c_str(), header);
+ File::WriteStringToFile(header, output_header_name + ".h");
+
+ delete[] codes;
+ }
+ else
+ {
+ std::vector<u16> code;
+
+ if (!DSP::Assemble(source, code, force))
+ {
+ printf("Assemble: Assembly failed due to errors\n");
+ return false;
+ }
+
+ if (output_size)
+ {
+ printf("%s: %d\n", input_name.c_str(), (int)code.size());
+ }
+
+ if (!output_name.empty())
+ {
+ const std::string binary_code = DSP::CodeToBinaryStringBE(code);
+ File::WriteStringToFile(binary_code, output_name);
+ }
+ if (!output_header_name.empty())
+ {
+ std::string header;
+ CodeToHeader(code, input_name, output_header_name.c_str(), header);
+ File::WriteStringToFile(header, output_header_name + ".h");
+ }
+ }
+ }
+
+ source.clear();
+
+ if (!output_size)
+ printf("Assembly completed successfully!\n");
+
+ return true;
+}
+
// Usage:
// Disassemble a file:
// dsptool -d -o asdf.txt asdf.bin
@@ -210,226 +440,25 @@ int main(int argc, const char* argv[])
if (compare)
{
- // Two binary inputs, let's diff.
- std::string binary_code;
-
- File::ReadFileToString(input_name, binary_code);
- const std::vector<u16> code1 = DSP::BinaryStringBEToCode(binary_code);
-
- File::ReadFileToString(output_name, binary_code);
- const std::vector<u16> code2 = DSP::BinaryStringBEToCode(binary_code);
-
- DSP::Compare(code1, code2);
+ PerformBinaryComparison(input_name, output_name);
return 0;
}
if (print_results)
{
- std::string dumpfile;
-
- File::ReadFileToString(input_name, dumpfile);
- const std::vector<u16> reg_vector = DSP::BinaryStringBEToCode(dumpfile);
-
- std::string results("Start:\n");
- for (int initial_reg = 0; initial_reg < 32; initial_reg++)
- {
- results.append(StringFromFormat("%02x %04x ", initial_reg, reg_vector.at(initial_reg)));
- if ((initial_reg + 1) % 8 == 0)
- results.append("\n");
- }
- results.append("\n");
- results.append("Step [number]:\n[Reg] [last value] [current value]\n\n");
- for (unsigned int step = 1; step < reg_vector.size() / 32; step++)
- {
- bool changed = false;
- u16 current_reg;
- u16 last_reg;
- u32 htemp;
- // results.append(StringFromFormat("Step %3d: (CW 0x%04x) UC:%03d\n", step, 0x8fff+step,
- // (step-1)/32));
- results.append(StringFromFormat("Step %3d:\n", step));
- for (int reg = 0; reg < 32; reg++)
- {
- if ((reg >= 0x0c) && (reg <= 0x0f))
- continue;
- if (print_results_srhack && (reg == 0x13))
- continue;
-
- if ((print_results_prodhack) && (reg >= 0x15) && (reg <= 0x17))
- {
- switch (reg)
- {
- case 0x15: // DSP_REG_PRODM
- last_reg =
- reg_vector.at((step * 32 - 32) + reg) + reg_vector.at((step * 32 - 32) + reg + 2);
- current_reg = reg_vector.at(step * 32 + reg) + reg_vector.at(step * 32 + reg + 2);
- break;
- case 0x16: // DSP_REG_PRODH
- htemp = ((reg_vector.at(step * 32 + reg - 1) + reg_vector.at(step * 32 + reg + 1)) &
- ~0xffff) >>
- 16;
- current_reg = (u8)(reg_vector.at(step * 32 + reg) + htemp);
- htemp = ((reg_vector.at(step * 32 - 32 + reg - 1) +
- reg_vector.at(step * 32 - 32 + reg + 1)) &
- ~0xffff) >>
- 16;
- last_reg = (u8)(reg_vector.at(step * 32 - 32 + reg) + htemp);
- break;
- case 0x17: // DSP_REG_PRODM2
- default:
- current_reg = 0;
- last_reg = 0;
- break;
- }
- }
- else
- {
- current_reg = reg_vector.at(step * 32 + reg);
- last_reg = reg_vector.at((step * 32 - 32) + reg);
- }
- if (last_reg != current_reg)
- {
- results.append(StringFromFormat("%02x %-7s: %04x %04x\n", reg, DSP::pdregname(reg),
- last_reg, current_reg));
- changed = true;
- }
- }
- if (!changed)
- results.append("No Change\n\n");
- else
- results.append("\n");
- }
-
- if (!output_name.empty())
- File::WriteStringToFile(results, output_name.c_str());
- else
- printf("%s", results.c_str());
+ PrintResults(input_name, output_name, print_results_srhack, print_results_prodhack);
return 0;
}
if (disassemble)
{
- if (input_name.empty())
- {
- printf("Disassemble: Must specify input.\n");
+ if (!PerformDisassembly(input_name, output_name))
return 1;
- }
- std::string binary_code;
- File::ReadFileToString(input_name, binary_code);
- const std::vector<u16> code = DSP::BinaryStringBEToCode(binary_code);
- std::string text;
- DSP::Disassemble(code, true, text);
- if (!output_name.empty())
- File::WriteStringToFile(text, output_name);
- else
- printf("%s", text.c_str());
}
else
{
- if (input_name.empty())
- {
- printf("Assemble: Must specify input.\n");
+ if (!PerformAssembly(input_name, output_name, output_header_name, multiple, force, outputSize))
return 1;
- }
- std::string source;
- if (File::ReadFileToString(input_name.c_str(), source))
- {
- if (multiple)
- {
- // When specifying a list of files we must compile a header
- // (we can't assemble multiple files to one binary)
- // since we checked it before, we assume output_header_name isn't empty
- int lines;
- std::vector<u16>* codes;
- std::vector<std::string> files;
- std::string header, currentSource;
- size_t lastPos = 0, pos = 0;
-
- source.append("\n");
-
- while ((pos = source.find('\n', lastPos)) != std::string::npos)
- {
- std::string temp = source.substr(lastPos, pos - lastPos);
- if (!temp.empty())
- files.push_back(temp);
- lastPos = pos + 1;
- }
-
- lines = (int)files.size();
-
- if (lines == 0)
- {
- printf("ERROR: Must specify at least one file\n");
- return 1;
- }
-
- codes = new std::vector<u16>[lines];
-
- for (int i = 0; i < lines; i++)
- {
- if (!File::ReadFileToString(files[i].c_str(), currentSource))
- {
- printf("ERROR reading %s, skipping...\n", files[i].c_str());
- lines--;
- }
- else
- {
- if (!DSP::Assemble(currentSource, codes[i], force))
- {
- printf("Assemble: Assembly of %s failed due to errors\n", files[i].c_str());
- lines--;
- }
- if (outputSize)
- {
- printf("%s: %d\n", files[i].c_str(), (int)codes[i].size());
- }
- }
- }
-
- CodesToHeader(codes, &files, lines, output_header_name.c_str(), header);
- File::WriteStringToFile(header, output_header_name + ".h");
-
- delete[] codes;
- }
- else
- {
- std::vector<u16> code;
-
- if (!DSP::Assemble(source, code, force))
- {
- printf("Assemble: Assembly failed due to errors\n");
- return 1;
- }
-
- if (outputSize)
- {
- printf("%s: %d\n", input_name.c_str(), (int)code.size());
- }
-
- if (!output_name.empty())
- {
- const std::string binary_code = DSP::CodeToBinaryStringBE(code);
- File::WriteStringToFile(binary_code, output_name);
- }
- if (!output_header_name.empty())
- {
- std::string header;
- CodeToHeader(code, input_name, output_header_name.c_str(), header);
- File::WriteStringToFile(header, output_header_name + ".h");
- }
- }
- }
- source.clear();
- }
-
- if (disassemble)
- {
- printf("Disassembly completed successfully!\n");
- }
- else
- {
- if (!outputSize)
- printf("Assembly completed successfully!\n");
}
return 0;