Skip to content

Commit ecc7583

Browse files
committed
Adding -data to exe2iso, and various small improvements.
1 parent 366a4dd commit ecc7583

File tree

1 file changed

+64
-39
lines changed

1 file changed

+64
-39
lines changed

tools/exe2iso/exe2iso.cc

Lines changed: 64 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ static void storeU32(uint32_t value, uint8_t* buffer) {
3232
buffer[3] = (value >> 24) & 0xff;
3333
}
3434

35-
// make sure to call this with a sector that's memset to 0
36-
static void getSector(uint8_t data[2048], uint32_t lba, uint32_t exeSize, uint32_t exeOffset = 19) {
35+
// make sure to call this with a sector that's memset to 0, as it relies on zeros being
36+
// in the right place.
37+
static void getSectorMinimal(uint8_t data[2048], uint32_t lba, uint32_t exeSize, uint32_t exeOffset = 19) {
3738
switch (lba) {
39+
// Minimal PVD
3840
case 16:
3941
data[0] = 1;
4042
data[1] = 'C';
@@ -46,11 +48,13 @@ static void getSector(uint8_t data[2048], uint32_t lba, uint32_t exeSize, uint32
4648
storeU32(17, data + 140);
4749
storeU32(18, data + 158);
4850
break;
51+
// Minimal path table
4952
case 17:
5053
data[0] = 1;
5154
data[2] = 18;
5255
data[6] = 1;
5356
break;
57+
// Minimal root directory
5458
case 18:
5559
data[0] = 42;
5660
storeU32(exeOffset, data + 2);
@@ -69,16 +73,20 @@ static void getSector(uint8_t data[2048], uint32_t lba, uint32_t exeSize, uint32
6973
}
7074
}
7175

72-
// make sure to call this with a sector that's memset to 0, as it relies on zeros being
73-
// in the right place.
74-
static void makeHeader(uint8_t sector[2352], uint32_t lba) {
75-
PCSX::IEC60908b::MSF time(lba + 150);
76+
// Call this once on a sector that's been memset to 0,
77+
// in order to set all of the immutable data.
78+
static void makeHeaderOnce(uint8_t sector[2352]) {
7679
memset(sector + 1, 0xff, 10);
77-
time.toBCD(sector + 12);
7880
sector[15] = 2;
7981
sector[18] = sector[22] = 8;
8082
}
8183

84+
// This function sets the LBA in the header of the sector.
85+
static void makeHeader(uint8_t sector[2352], uint32_t lba) {
86+
PCSX::IEC60908b::MSF time(lba + 150);
87+
time.toBCD(sector + 12);
88+
}
89+
8290
int main(int argc, char** argv) {
8391
CommandLine::args args(argc, argv);
8492

@@ -96,12 +104,14 @@ exe2iso by Nicolas "Pixel" Noble
96104
const bool pad = args.get<bool>("pad").value_or(false);
97105
const bool regen = args.get<bool>("regen").value_or(false);
98106
const auto license = args.get<std::string>("license");
107+
const auto data = args.get<std::string>("data");
99108
if (asksForHelp || !oneInput || !hasOutput) {
100109
fmt::print(R"(
101110
Usage: {} input.ps-exe [-offset value] [-pad] [-regen] [-license file] -o output.bin
102111
input.ps-exe mandatory: specify the input ps-exe file.
103112
-o output.bin mandatory: name of the output file.
104113
-offset value optional: move the exe data by value sectors.
114+
-data filename optional: insert this file into the iso after the exe.
105115
-pad optional: pads the iso with 150 blank sectors.
106116
-regen optional: generates proper ECC/EDC.
107117
-license file optional: use this license file.
@@ -114,17 +124,29 @@ Usage: {} input.ps-exe [-offset value] [-pad] [-regen] [-license file] -o output
114124
auto& input = inputs[0];
115125
PCSX::IO<PCSX::File> file(new PCSX::PosixFile(input));
116126
if (file->failed()) {
117-
fmt::print("Unable to open file: {}\n", input);
127+
fmt::print("Error opening input file {}\n", input);
118128
return -1;
119129
}
120130
PCSX::IO<PCSX::File> licenseFile(new PCSX::FailedFile);
131+
PCSX::IO<PCSX::File> dataFile(new PCSX::FailedFile);
121132
PCSX::IO<PCSX::File> out(new PCSX::PosixFile(output.value(), PCSX::FileOps::TRUNCATE));
122133
if (out->failed()) {
123134
fmt::print("Error opening output file {}\n", output.value());
124135
return -1;
125136
}
126137
if (license.has_value()) {
127138
licenseFile.setFile(new PCSX::PosixFile(license.value()));
139+
if (licenseFile->failed()) {
140+
fmt::print("Error opening license file {}\n", license.value());
141+
return -1;
142+
}
143+
}
144+
if (data.has_value()) {
145+
dataFile.setFile(new PCSX::PosixFile(data.value()));
146+
if (dataFile->failed()) {
147+
fmt::print("Error opening data file {}\n", data.value());
148+
return -1;
149+
}
128150
}
129151

130152
uint32_t exeSize = file->size();
@@ -134,77 +156,80 @@ Usage: {} input.ps-exe [-offset value] [-pad] [-regen] [-license file] -o output
134156
uint32_t exeOffset = 19 + offset;
135157

136158
uint8_t sector[2352];
159+
memset(sector, 0, sizeof(sector));
160+
makeHeaderOnce(sector);
137161
bool wroteLicense = false;
162+
unsigned LBA = 0;
163+
auto writeSector = [&]() {
164+
makeHeader(sector, LBA++);
165+
if (regen) compute_edcecc(sector);
166+
out->write(sector, sizeof(sector));
167+
};
138168
// Sectors 0-15 are the license. We can keep it to zeroes and it'll work most everywhere.
139169
if (licenseFile && !licenseFile->failed()) {
140170
uint8_t licenseData[2352 * 16];
141171
memset(licenseData, 0, sizeof(licenseData));
142172
licenseFile->read(licenseData, sizeof(licenseData));
143-
if (licenseData[0x2492] == 'L') {
173+
if ((licenseFile->size() == 2336 * 16) && (licenseData[0x2492] == 'L')) {
144174
// official license file from the sdk, in 2336 bytes per sector.
145175
for (unsigned i = 0; i < 16; i++) {
146-
memset(sector, 0, sizeof(sector));
147176
memcpy(sector + 16, licenseData + 2336 * i, 2336);
148-
makeHeader(sector, i);
149-
if (regen) compute_edcecc(sector);
150-
out->write(sector, sizeof(sector));
177+
writeSector();
151178
}
152179
wroteLicense = true;
153180
} else if (licenseData[0x24e2] == 'L') {
154181
// looks like an iso file itself
155182
for (unsigned i = 0; i < 16; i++) {
156183
memcpy(sector, licenseData + 2352 * i, 2352);
157-
makeHeader(sector, i);
158-
if (regen) compute_edcecc(sector);
159-
out->write(sector, sizeof(sector));
184+
makeHeaderOnce(sector);
185+
writeSector();
160186
}
161187
wroteLicense = true;
162188
} else {
163189
fmt::print("Unrecognized LICENSE file format {}\n", output.value());
164190
}
165191
}
166192
if (!wroteLicense) {
193+
memset(sector, 0, sizeof(sector));
167194
for (unsigned i = 0; i < 16; i++) {
168-
memset(sector, 0, sizeof(sector));
169-
makeHeader(sector, i);
170-
if (regen) compute_edcecc(sector);
171-
out->write(sector, sizeof(sector));
195+
writeSector();
172196
}
173197
}
174198
// The actual structure of the iso. We're only generating 3 sectors,
175199
// from 16 to 18, as it's the only things necessary for the PS1 bios.
176-
for (unsigned i = 16; i < 19; i++) {
200+
for (unsigned i = 0; i < 3; i++) {
177201
memset(sector, 0, sizeof(sector));
178-
makeHeader(sector, i);
202+
makeHeaderOnce(sector);
179203
// This function will fill the sector with the right data, as
180204
// necessary for the PS1 bios.
181-
getSector(sector + 24, i, exeSize, exeOffset);
182-
if (regen) compute_edcecc(sector);
183-
out->write(sector, sizeof(sector));
205+
getSectorMinimal(sector + 24, LBA, exeSize, exeOffset);
206+
writeSector();
184207
}
185208
// Potential padding before the start of the exe.
186-
for (unsigned i = 19; i < exeOffset; i++) {
187-
memset(sector, 0, sizeof(sector));
188-
makeHeader(sector, i);
189-
if (regen) compute_edcecc(sector);
190-
out->write(sector, sizeof(sector));
209+
memset(sector, 0, sizeof(sector));
210+
makeHeaderOnce(sector);
211+
for (unsigned i = 0; i < offset; i++) {
212+
writeSector();
191213
}
192-
unsigned LBA = exeOffset;
193214
// The actual exe.
194215
for (unsigned i = 0; i < exeSize; i += 2048) {
195-
memset(sector, 0, sizeof(sector));
196-
makeHeader(sector, LBA++);
197216
file->read(sector + 24, 2048);
198-
if (regen) compute_edcecc(sector);
199-
out->write(sector, sizeof(sector));
217+
writeSector();
218+
}
219+
if (dataFile && !dataFile->failed()) {
220+
// The additional data file.
221+
unsigned sectors = (dataFile->size() + 2047) / 2048;
222+
for (unsigned i = 0; i < sectors; i++) {
223+
dataFile->read(sector + 24, 2048);
224+
writeSector();
225+
}
200226
}
227+
memset(sector, 0, sizeof(sector));
228+
makeHeaderOnce(sector);
201229
if (pad) {
202230
// 150 sectors padding.
203231
for (unsigned i = 0; i < 150; i++) {
204-
memset(sector, 0, sizeof(sector));
205-
makeHeader(sector, LBA++);
206-
if (regen) compute_edcecc(sector);
207-
out->write(sector, sizeof(sector));
232+
writeSector();
208233
}
209234
}
210235
fmt::print("Done.");

0 commit comments

Comments
 (0)