mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-10-04 07:01:32 +02:00
byuu says: Changelog: - int_t<bits> replaced with Integer<bits> - uint_t<bits> replaced with Natural<bits> - fixed "Synchronize Audio" menu option that broke recently - all of sfc/performance ported to "auto function() -> return;" syntax With this WIP, all of higan is finally ported over to the new function declaration syntax. Thank the gods. There's still going to be periodic disruption for diffs from porting over signed->int, unsigned->uint, and whatever we come up with for the new Natural<> and Integer<> classes. But the worst of it's behind us now.
155 lines
4.1 KiB
C++
155 lines
4.1 KiB
C++
#include <nall/file.hpp>
|
|
#include <nall/stdint.hpp>
|
|
#include <nall/string.hpp>
|
|
using namespace nall;
|
|
|
|
static bool cycle_accurate;
|
|
|
|
struct opcode_t {
|
|
string name;
|
|
lstring args;
|
|
uint opcode;
|
|
};
|
|
|
|
auto generate(const char* sourceFilename, const char* targetFilename) -> void {
|
|
file fp;
|
|
fp.open(targetFilename, file::mode::write);
|
|
|
|
string filedata;
|
|
filedata.readfile(sourceFilename);
|
|
filedata.replace("\r", "");
|
|
|
|
lstring block;
|
|
block.split("\n\n", filedata);
|
|
|
|
foreach(data, block) {
|
|
lstring lines;
|
|
lines.split("\n", data);
|
|
|
|
linear_vector<opcode_t> array;
|
|
|
|
uint sourceStart = 0;
|
|
foreach(line, lines, currentLine) {
|
|
line.transform("()", "``");
|
|
lstring part;
|
|
part.split("`", line);
|
|
lstring arguments;
|
|
arguments.split(", ", part[1]);
|
|
|
|
opcode_t opcode;
|
|
opcode.name = part[0];
|
|
opcode.args = arguments;
|
|
opcode.opcode = hex(arguments[0]);
|
|
array.append(opcode);
|
|
|
|
line.rtrim(",", 1L);
|
|
if(line.endswith(" {")) {
|
|
line.rtrim("{ ", 1L);
|
|
sourceStart = currentLine + 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(cycle_accurate == false) {
|
|
foreach(opcode, array) {
|
|
fp.print("case 0x", hex(opcode.opcode, 2L), ": {\n");
|
|
|
|
for(uint n = sourceStart; n < lines.size(); n++) {
|
|
if(lines[n] == "}") break;
|
|
|
|
string output;
|
|
|
|
if(lines[n].beginswith(" ")) {
|
|
output = lines[n];
|
|
} else {
|
|
lstring part;
|
|
part.split<1>(":", lines[n]);
|
|
output = { " ", part[1] };
|
|
}
|
|
|
|
output.replace("$1", opcode.args[1]);
|
|
output.replace("$2", opcode.args[2]);
|
|
output.replace("$3", opcode.args[3]);
|
|
output.replace("$4", opcode.args[4]);
|
|
output.replace("$5", opcode.args[5]);
|
|
output.replace("$6", opcode.args[6]);
|
|
output.replace("$7", opcode.args[7]);
|
|
output.replace("$8", opcode.args[8]);
|
|
output.replace("end;", "break;");
|
|
|
|
fp.print(output, "\n");
|
|
}
|
|
|
|
fp.print(" break;\n");
|
|
fp.print("}\n\n");
|
|
}
|
|
} else {
|
|
foreach(opcode, array) {
|
|
fp.print("case 0x", hex(opcode.opcode, 2L), ": {\n");
|
|
fp.print(" switch(opcode_cycle++) {\n");
|
|
|
|
for(uint n = sourceStart; n < lines.size(); n++) {
|
|
if(lines[n] == "}") break;
|
|
|
|
bool nextLineEndsCycle = false;
|
|
if(lines[n + 1] == "}") nextLineEndsCycle = true;
|
|
if(lines[n + 1].beginswith(" ") == false) nextLineEndsCycle = true;
|
|
|
|
string output;
|
|
|
|
if(lines[n].beginswith(" ")) {
|
|
output = { " ", lines[n] };
|
|
} else {
|
|
lstring part;
|
|
part.split(":", lines[n], 1L);
|
|
fp.print(" case ", (unsigned)decimal(part[0]), ":\n");
|
|
output = { " ", part[1] };
|
|
}
|
|
|
|
output.replace("$1", opcode.args[1]);
|
|
output.replace("$2", opcode.args[2]);
|
|
output.replace("$3", opcode.args[3]);
|
|
output.replace("$4", opcode.args[4]);
|
|
output.replace("$5", opcode.args[5]);
|
|
output.replace("$6", opcode.args[6]);
|
|
output.replace("$7", opcode.args[7]);
|
|
output.replace("$8", opcode.args[8]);
|
|
output.replace("end;", "{ opcode_cycle = 0; break; }");
|
|
|
|
fp.print(output, "\n");
|
|
if(nextLineEndsCycle) {
|
|
if(lines[n + 1].beginswith("}")) {
|
|
fp.print(" opcode_cycle = 0;\n");
|
|
}
|
|
fp.print(" break;\n");
|
|
}
|
|
}
|
|
|
|
fp.print(" }\n");
|
|
fp.print(" break;\n");
|
|
fp.print("}\n\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
fp.close();
|
|
}
|
|
|
|
auto main() -> int {
|
|
cycle_accurate = false;
|
|
generate("op_misc.b", "op_misc.cpp");
|
|
generate("op_mov.b", "op_mov.cpp" );
|
|
generate("op_pc.b", "op_pc.cpp" );
|
|
generate("op_read.b", "op_read.cpp");
|
|
generate("op_rmw.b", "op_rmw.cpp" );
|
|
|
|
cycle_accurate = true;
|
|
generate("op_misc.b", "opcycle_misc.cpp");
|
|
generate("op_mov.b", "opcycle_mov.cpp" );
|
|
generate("op_pc.b", "opcycle_pc.cpp" );
|
|
generate("op_read.b", "opcycle_read.cpp");
|
|
generate("op_rmw.b", "opcycle_rmw.cpp" );
|
|
|
|
return 0;
|
|
}
|