Skip to content

Commit 85c9ed7

Browse files
authored
Merge pull request #210 from nicolasnoble/binary-loader
Adding support for minipsf.
2 parents 9f9d036 + 5ca27cf commit 85c9ed7

4 files changed

Lines changed: 111 additions & 35 deletions

File tree

src/core/binloader.cc

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,13 @@
2222
#include <stdint.h>
2323
#include <zlib.h>
2424

25+
#include <filesystem>
26+
#include <string>
27+
#include <vector>
28+
2529
#include "core/psxemulator.h"
2630
#include "core/r3000a.h"
31+
#include "fmt/format.h"
2732
#include "support/file.h"
2833

2934
namespace PCSX {
@@ -143,7 +148,8 @@ bool loadPSEXE(File& file) {
143148
return true;
144149
}
145150

146-
bool loadPSF(File& file) {
151+
bool loadPSF(File& file, bool seenRefresh = false, unsigned depth = 0) {
152+
if (depth >= 10) return false;
147153
file.seek(0, SEEK_SET);
148154
uint32_t magic = file.read<uint32_t>();
149155
if (magic != 0x1465350) return false;
@@ -153,7 +159,53 @@ bool loadPSF(File& file) {
153159
file.seek(R, SEEK_CUR);
154160
uint8_t* buffer = (uint8_t*)malloc(N);
155161
file.read(buffer, N);
156-
162+
char tagtag[6];
163+
file.read(tagtag, 5);
164+
tagtag[5] = 0;
165+
166+
std::map<std::string, std::string> pairs;
167+
168+
if (strcmp(tagtag, "[TAG]") == 0) {
169+
char* tags;
170+
auto current = file.tell();
171+
file.seek(0, SEEK_END);
172+
size_t tagsSize = file.tell() - current;
173+
file.seek(current, SEEK_SET);
174+
tags = (char*)malloc(tagsSize + 1);
175+
176+
file.read(tags, tagsSize);
177+
tags[tagsSize] = 0;
178+
char* cr;
179+
180+
while ((cr = strchr(tags, '\r'))) *cr = '\n';
181+
182+
auto lines = Misc::split(tags, "\n");
183+
184+
free(tags);
185+
186+
for (auto& line : lines) {
187+
auto e = line.find('=', 0);
188+
if (e == std::string::npos) continue;
189+
pairs[line.substr(0, e)] = line.substr(e + 1);
190+
}
191+
}
192+
193+
if (!seenRefresh && pairs.find("refresh") != pairs.end()) {
194+
const auto& refresh = pairs["refresh"];
195+
if (refresh == "50") {
196+
g_emulator->settings.get<Emulator::SettingVideo>() = Emulator::PSX_TYPE_PAL;
197+
} else if (refresh == "60") {
198+
g_emulator->settings.get<Emulator::SettingVideo>() = Emulator::PSX_TYPE_NTSC;
199+
}
200+
seenRefresh = true;
201+
}
202+
203+
if (pairs.find("_lib") != pairs.end()) {
204+
std::filesystem::path subFilePath(file.filename());
205+
File subFile(subFilePath.parent_path() / pairs["_lib"]);
206+
if (!subFile.failed()) loadPSF(subFile, seenRefresh, depth++);
207+
}
208+
157209
{
158210
static constexpr unsigned TWOM = 2 * 1024 * 1024;
159211
uint8_t* psexe = (uint8_t*)malloc(TWOM); // and no fucks were given today.
@@ -177,6 +229,18 @@ bool loadPSF(File& file) {
177229
free(psexe);
178230
}
179231
free(buffer);
232+
233+
unsigned libNum = 2;
234+
235+
while (true) {
236+
std::string libName = fmt::format("_lib{}", libNum++);
237+
if (pairs.find(libName) == pairs.end()) break;
238+
std::filesystem::path subFilePath(file.filename());
239+
File subFile(subFilePath.parent_path() / pairs[libName]);
240+
if (!subFile.failed()) loadPSF(subFile, seenRefresh, depth++);
241+
}
242+
243+
return true;
180244
}
181245

182246
} // namespace

src/core/gdb-server.cc

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <uv.h>
2424

2525
#include "core/debug.h"
26+
#include "core/misc.h"
2627
#include "core/psxemulator.h"
2728
#include "core/psxmem.h"
2829
#include "core/r3000a.h"
@@ -184,21 +185,6 @@ void PCSX::GdbClient::processData(const Slice& slice) {
184185
}
185186
}
186187

187-
static std::vector<std::string> split(const std::string& str, const std::string& delim) {
188-
std::vector<std::string> tokens;
189-
size_t prev = 0, pos = 0;
190-
do {
191-
pos = str.find(delim, prev);
192-
if (pos == std::string::npos) pos = str.length();
193-
std::string token = str.substr(prev, pos - prev);
194-
if (!token.empty()) tokens.push_back(token);
195-
prev = pos + delim.length();
196-
} while (pos < str.length() && prev < str.length());
197-
return std::move(tokens);
198-
}
199-
200-
static bool startsWith(const std::string& s1, const std::string& s2) { return s1.rfind(s2, 0) == 0; }
201-
202188
static std::pair<uint32_t, bool> parseHexNumber(const char* str) {
203189
uint64_t value = 0;
204190
char c;
@@ -322,7 +308,7 @@ static const std::string targetXML = R"(<?xml version="1.0"?>
322308
)";
323309

324310
std::pair<uint64_t, uint64_t> PCSX::GdbClient::parseCursor(const std::string& cursorStr) {
325-
auto cursorStrs = split(cursorStr, ",");
311+
auto cursorStrs = Misc::split(cursorStr, ",");
326312
uint64_t off = 0;
327313
uint64_t len = 0;
328314
if (cursorStrs.size() == 2) {
@@ -436,7 +422,7 @@ void PCSX::GdbClient::processCommand() {
436422
m_waitingForTrap = true;
437423
} else if (m_cmd[0] == 'M') {
438424
// write memory
439-
auto elements = split(m_cmd, ":");
425+
auto elements = Misc::split(m_cmd, ":");
440426
auto [off, len] = parseCursor(elements[0].substr(1));
441427
size_t i = 0;
442428
while (len--) {
@@ -480,7 +466,7 @@ void PCSX::GdbClient::processCommand() {
480466
write("");
481467
return;
482468
}
483-
auto breakpointData = split(m_cmd.substr(1), ",");
469+
auto breakpointData = Misc::split(m_cmd.substr(1), ",");
484470
if (breakpointData.size() != 3) {
485471
// wrong number of arguments
486472
write("");
@@ -540,22 +526,22 @@ void PCSX::GdbClient::processCommand() {
540526
write("OK");
541527
} else if (m_cmd == "Hg0") {
542528
write("OK");
543-
} else if (startsWith(m_cmd, "vKill;")) {
529+
} else if (Misc::startsWith(m_cmd, "vKill;")) {
544530
write("OK");
545-
} else if (startsWith(m_cmd, qSupported)) {
531+
} else if (Misc::startsWith(m_cmd, qSupported)) {
546532
// do we care about any features gdb supports?
547533
// auto elements = split(m_cmd.substr(qSupported.length()), ";");
548534
write("PacketSize=4000;qXfer:features:read+;qXfer:threads:read+;QStartNoAckMode+");
549-
} else if (startsWith(m_cmd, "QStartNoAckMode")) {
535+
} else if (Misc::startsWith(m_cmd, "QStartNoAckMode")) {
550536
m_ackEnabled = false;
551537
write("OK");
552-
} else if (startsWith(m_cmd, qSymbol)) {
538+
} else if (Misc::startsWith(m_cmd, qSymbol)) {
553539
// It looks like extended-remote doesn't even offer to give us the
554540
// location of the start address...? Why? That's a terrible design.
555541
// We'll have to basically rely on our wits and monitor commands
556542
// tricks to get us to load an arbitrary file properly. We'll only
557543
// make this work if the symbols _start or _reset are defined.
558-
auto elements = split(m_cmd.substr(qSymbol.length()), ":");
544+
auto elements = Misc::split(m_cmd.substr(qSymbol.length()), ":");
559545
switch (m_qsymbolState) {
560546
case QSYMBOL_IDLE:
561547
// gdb is offering symbols. Let's start by trying _start's location.
@@ -586,7 +572,7 @@ void PCSX::GdbClient::processCommand() {
586572
write("OK");
587573
break;
588574
}
589-
} else if (startsWith(m_cmd, "qRcmd,")) {
575+
} else if (Misc::startsWith(m_cmd, "qRcmd,")) {
590576
// this is the "monitor" command
591577
size_t len = m_cmd.length() - 6;
592578
std::string monitor;
@@ -598,11 +584,11 @@ void PCSX::GdbClient::processCommand() {
598584
monitor += c;
599585
}
600586
processMonitorCommand(monitor);
601-
} else if (startsWith(m_cmd, qXferMemMap)) {
587+
} else if (Misc::startsWith(m_cmd, qXferMemMap)) {
602588
writePaged(memoryMap, m_cmd.substr(qXferMemMap.length()));
603-
} else if (startsWith(m_cmd, qXferFeatures)) {
589+
} else if (Misc::startsWith(m_cmd, qXferFeatures)) {
604590
writePaged(targetXML, m_cmd.substr(qXferFeatures.length()));
605-
} else if (startsWith(m_cmd, qXferThreads)) {
591+
} else if (Misc::startsWith(m_cmd, qXferThreads)) {
606592
writePaged("<?xml version=\"1.0\"?><threads></threads>", m_cmd.substr(qXferThreads.length()));
607593
} else {
608594
g_system->printf("Unknown GDB command: %s\n", m_cmd.c_str());
@@ -619,10 +605,10 @@ void PCSX::GdbClient::processMonitorCommand(const std::string& cmd) {
619605
writeEscaped("");
620606
m_sentBanner = true;
621607
}
622-
if (startsWith(cmd, "reset")) {
608+
if (Misc::startsWith(cmd, "reset")) {
623609
g_emulator->m_psxCpu->psxReset();
624610
writeEscaped("Emulation reset\n");
625-
auto words = split(cmd, " ");
611+
auto words = Misc::split(cmd, " ");
626612
if (words.size() == 2) {
627613
if (words[1] == "halt") {
628614
writeEscaped("Emulation paused\n");

src/core/misc.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121

2222
#include "core/coff.h"
2323

24+
#include <string>
25+
#include <vector>
26+
2427
#undef s_addr
2528

2629
typedef struct {
@@ -54,3 +57,26 @@ int RecvPcsxInfo();
5457

5558
void trim(char *str);
5659
uint16_t calcCrc(uint8_t *d, int len);
60+
61+
namespace PCSX {
62+
63+
namespace Misc {
64+
65+
static inline std::vector<std::string> split(const std::string &str, const std::string &delim) {
66+
std::vector<std::string> tokens;
67+
size_t prev = 0, pos = 0;
68+
do {
69+
pos = str.find(delim, prev);
70+
if (pos == std::string::npos) pos = str.length();
71+
std::string token = str.substr(prev, pos - prev);
72+
if (!token.empty()) tokens.push_back(token);
73+
prev = pos + delim.length();
74+
} while (pos < str.length() && prev < str.length());
75+
return std::move(tokens);
76+
}
77+
78+
static inline bool startsWith(const std::string &s1, const std::string &s2) { return s1.rfind(s2, 0) == 0; }
79+
80+
} // namespace Misc
81+
82+
} // namespace PCSX

vsprojects/core/core.vcxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
<ConformanceMode>true</ConformanceMode>
9494
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
9595
<LanguageStandard>stdcpp17</LanguageStandard>
96-
<AdditionalIncludeDirectories>..\..\third_party\libelfin;..\..\third_party\libuv\include</AdditionalIncludeDirectories>
96+
<AdditionalIncludeDirectories>..\..\third_party\libelfin;..\..\third_party\libuv\include;..\..\third_party\fmt\include</AdditionalIncludeDirectories>
9797
</ClCompile>
9898
</ItemDefinitionGroup>
9999
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -104,7 +104,7 @@
104104
<ConformanceMode>true</ConformanceMode>
105105
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
106106
<LanguageStandard>stdcpp17</LanguageStandard>
107-
<AdditionalIncludeDirectories>..\..\third_party\libelfin;..\..\third_party\libuv\include</AdditionalIncludeDirectories>
107+
<AdditionalIncludeDirectories>..\..\third_party\libelfin;..\..\third_party\libuv\include;..\..\third_party\fmt\include</AdditionalIncludeDirectories>
108108
</ClCompile>
109109
</ItemDefinitionGroup>
110110
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -117,7 +117,7 @@
117117
<ConformanceMode>true</ConformanceMode>
118118
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
119119
<LanguageStandard>stdcpp17</LanguageStandard>
120-
<AdditionalIncludeDirectories>..\..\third_party\libelfin;..\..\third_party\libuv\include</AdditionalIncludeDirectories>
120+
<AdditionalIncludeDirectories>..\..\third_party\libelfin;..\..\third_party\libuv\include;..\..\third_party\fmt\include</AdditionalIncludeDirectories>
121121
</ClCompile>
122122
<Link>
123123
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -134,7 +134,7 @@
134134
<ConformanceMode>true</ConformanceMode>
135135
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
136136
<LanguageStandard>stdcpp17</LanguageStandard>
137-
<AdditionalIncludeDirectories>..\..\third_party\libelfin;..\..\third_party\libuv\include</AdditionalIncludeDirectories>
137+
<AdditionalIncludeDirectories>..\..\third_party\libelfin;..\..\third_party\libuv\include;..\..\third_party\fmt\include</AdditionalIncludeDirectories>
138138
</ClCompile>
139139
<Link>
140140
<EnableCOMDATFolding>true</EnableCOMDATFolding>

0 commit comments

Comments
 (0)