mirror of
https://github.com/spicyjpeg/573in1.git
synced 2025-01-22 19:52:05 +01:00
Bump to 0.4.2, parallelize flash writing, minor tweaks
This commit is contained in:
parent
d85582d9b5
commit
1e79613029
@ -6,7 +6,7 @@ set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/cmake/toolchain.cmake")
|
||||
project(
|
||||
cart_tool_private
|
||||
LANGUAGES C CXX ASM
|
||||
VERSION 0.4.1
|
||||
VERSION 0.4.2
|
||||
DESCRIPTION "Konami System 573 security cartridge tool"
|
||||
)
|
||||
|
||||
|
@ -354,7 +354,7 @@ size_t Provider::saveVRAMBMP(gpu::RectWH &rect, const char *path) {
|
||||
size_t length = _file->write(&header, sizeof(header));
|
||||
util::Data buffer;
|
||||
|
||||
if (buffer.allocate(rect.w * 2 + 32)) {
|
||||
if (buffer.allocate<uint16_t>(rect.w + 32)) {
|
||||
// Read the image from VRAM one line at a time from the bottom up, as
|
||||
// the BMP format stores lines in reversed order.
|
||||
gpu::RectWH slice;
|
||||
|
@ -18,7 +18,7 @@ void init(void) {
|
||||
| SYS573_MISC_OUT_ADC_MOSI
|
||||
| SYS573_MISC_OUT_ADC_CS
|
||||
| SYS573_MISC_OUT_ADC_SCK
|
||||
| SYS573_MISC_OUT_JVS_STAT;
|
||||
| SYS573_MISC_OUT_JVS_RESET;
|
||||
|
||||
BIU_DEV0_ADDR = DEV0_BASE & 0x1fffffff;
|
||||
BIU_DEV0_CTRL = 0
|
||||
@ -204,13 +204,15 @@ bool loadRawBitstream(const uint8_t *data, size_t length) {
|
||||
for (int i = 3; i; i--) {
|
||||
SYS573D_CPLD_UNK_RESET = 0;
|
||||
|
||||
SYS573D_CPLD_CTRL = SYS573D_CPLD_CTRL_UNK4;
|
||||
SYS573D_CPLD_CTRL = SYS573D_CPLD_CTRL_UNK3 | SYS573D_CPLD_CTRL_UNK4;
|
||||
SYS573D_CPLD_CTRL = SYS573D_CPLD_CTRL_UNKNOWN;
|
||||
SYS573D_CPLD_CTRL = 0
|
||||
| SYS573D_CPLD_CTRL_UNK1
|
||||
| SYS573D_CPLD_CTRL_UNK2
|
||||
| SYS573D_CPLD_CTRL_UNK3
|
||||
| SYS573D_CPLD_CTRL_UNK4;
|
||||
| SYS573D_CPLD_CTRL_PROGRAM
|
||||
| SYS573D_CPLD_CTRL_UNKNOWN;
|
||||
SYS573D_CPLD_CTRL = 0
|
||||
| SYS573D_CPLD_CTRL_INIT
|
||||
| SYS573D_CPLD_CTRL_DONE
|
||||
| SYS573D_CPLD_CTRL_PROGRAM
|
||||
| SYS573D_CPLD_CTRL_UNKNOWN;
|
||||
delayMicroseconds(5000);
|
||||
|
||||
if (!(SYS573D_CPLD_STAT & SYS573D_CPLD_STAT_INIT))
|
||||
|
@ -141,11 +141,10 @@ static inline void setMiscOutput(MiscOutputPin pin, bool value) {
|
||||
|
||||
/* Digital I/O board driver */
|
||||
|
||||
// TODO: these do not seem to actually be LDC and HDC...
|
||||
static inline bool isDigitalIOPresent(void) {
|
||||
return (
|
||||
(SYS573D_CPLD_STAT & (SYS573D_CPLD_STAT_LDC | SYS573D_CPLD_STAT_HDC))
|
||||
== SYS573D_CPLD_STAT_HDC
|
||||
(SYS573D_CPLD_STAT & (SYS573D_CPLD_STAT_ID1 | SYS573D_CPLD_STAT_ID2)) ==
|
||||
SYS573D_CPLD_STAT_ID1
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,26 @@ Hash hash(const uint8_t *data, size_t length) {
|
||||
|
||||
/* Date and time class */
|
||||
|
||||
bool Date::isValid(void) const {
|
||||
if ((hour > 23) || (minute > 59) || (second > 59))
|
||||
return false;
|
||||
if ((month < 1) || (month > 12))
|
||||
return false;
|
||||
if ((day < 1) || (day > getMonthDayCount()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Date::isLeapYear(void) const {
|
||||
if (year % 4)
|
||||
return false;
|
||||
if (!(year % 100) && (year % 400))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int Date::getDayOfWeek(void) const {
|
||||
// See https://datatracker.ietf.org/doc/html/rfc3339#appendix-B
|
||||
int _year = year, _month = month - 2;
|
||||
|
@ -103,6 +103,9 @@ public:
|
||||
template<typename T> inline const T *as(void) const {
|
||||
return reinterpret_cast<const T *>(ptr);
|
||||
}
|
||||
template<typename T> inline T *allocate(size_t count = 1) {
|
||||
return reinterpret_cast<T *>(allocate(sizeof(T) * count));
|
||||
}
|
||||
|
||||
inline void *allocate(size_t _length) {
|
||||
if (ptr)
|
||||
@ -170,15 +173,8 @@ public:
|
||||
uint8_t month, day;
|
||||
uint8_t hour, minute, second;
|
||||
|
||||
inline bool isLeapYear(void) const {
|
||||
if (year % 4)
|
||||
return false;
|
||||
if (!(year % 100) && (year % 400))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValid(void) const;
|
||||
bool isLeapYear(void) const;
|
||||
int getDayOfWeek(void) const;
|
||||
int getMonthDayCount(void) const;
|
||||
uint32_t toDOSTime(void) const;
|
||||
|
@ -1,4 +1,6 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include "common/defs.hpp"
|
||||
#include "common/file.hpp"
|
||||
#include "common/gpu.hpp"
|
||||
@ -154,27 +156,47 @@ void App::_loadResources(void) {
|
||||
_resourceProvider.loadVAG(_ctx.sounds[i], _UI_SOUND_PATHS[i]);
|
||||
}
|
||||
|
||||
bool App::_takeScreenshot(void) {
|
||||
bool App::_createDataDirectory(void) {
|
||||
file::FileInfo info;
|
||||
|
||||
if (!_fileProvider.getFileInfo(info, EXTERNAL_DATA_DIR))
|
||||
return _fileProvider.createDirectory(EXTERNAL_DATA_DIR);
|
||||
if (info.attributes & file::DIRECTORY)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool App::_getNumberedPath(char *output, size_t length, const char *path) {
|
||||
file::FileInfo info;
|
||||
char path[32];
|
||||
int index = 0;
|
||||
|
||||
do {
|
||||
index++;
|
||||
snprintf(path, sizeof(path), EXTERNAL_DATA_DIR "/shot%04d.bmp", index);
|
||||
} while (_fileProvider.getFileInfo(info, path));
|
||||
if (++index > 9999)
|
||||
return false;
|
||||
|
||||
snprintf(output, length, path, index);
|
||||
} while (_fileProvider.getFileInfo(info, output));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool App::_takeScreenshot(void) {
|
||||
char path[32];
|
||||
|
||||
if (!_createDataDirectory())
|
||||
return false;
|
||||
if (!_getNumberedPath(path, sizeof(path), EXTERNAL_DATA_DIR "/shot%04d.bmp"))
|
||||
return false;
|
||||
|
||||
gpu::RectWH clip;
|
||||
|
||||
_ctx.gpuCtx.getVRAMClipRect(clip);
|
||||
|
||||
if (_fileProvider.saveVRAMBMP(clip, path)) {
|
||||
LOG("%s saved", path);
|
||||
return true;
|
||||
} else {
|
||||
LOG("%s saving failed", path);
|
||||
if (!_fileProvider.saveVRAMBMP(clip, path))
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG("%s saved", path);
|
||||
return true;
|
||||
}
|
||||
|
||||
void App::_worker(void) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include "common/file.hpp"
|
||||
#include "main/app/cartactions.hpp"
|
||||
#include "main/app/cartunlock.hpp"
|
||||
@ -131,6 +132,8 @@ private:
|
||||
void _setupWorker(bool (App::*func)(void));
|
||||
void _setupInterrupts(void);
|
||||
void _loadResources(void);
|
||||
bool _createDataDirectory(void);
|
||||
bool _getNumberedPath(char *output, size_t length, const char *path);
|
||||
bool _takeScreenshot(void);
|
||||
|
||||
// cartworkers.cpp
|
||||
|
@ -202,20 +202,11 @@ bool App::_qrCodeWorker(void) {
|
||||
bool App::_cartDumpWorker(void) {
|
||||
_workerStatus.update(0, 1, WSTR("App.cartDumpWorker.save"));
|
||||
|
||||
file::FileInfo info;
|
||||
char path[32];
|
||||
char path[32], code[8], region[8];
|
||||
size_t length = _cartDump.getDumpLength();
|
||||
|
||||
__builtin_strcpy(path, EXTERNAL_DATA_DIR);
|
||||
|
||||
if (!_fileProvider.getFileInfo(info, path)) {
|
||||
if (!_fileProvider.createDirectory(path))
|
||||
goto _error;
|
||||
}
|
||||
|
||||
char code[8], region[8];
|
||||
size_t length;
|
||||
|
||||
length = _cartDump.getDumpLength();
|
||||
if (!_createDataDirectory())
|
||||
goto _error;
|
||||
|
||||
if (
|
||||
_identified && _cartParser->getCode(code) &&
|
||||
@ -225,14 +216,10 @@ bool App::_cartDumpWorker(void) {
|
||||
path, sizeof(path), EXTERNAL_DATA_DIR "/%s%s.573", code, region
|
||||
);
|
||||
} else {
|
||||
int index = 0;
|
||||
|
||||
do {
|
||||
index++;
|
||||
snprintf(
|
||||
path, sizeof(path), EXTERNAL_DATA_DIR "/cart%04d.573", index
|
||||
);
|
||||
} while (_fileProvider.getFileInfo(info, path));
|
||||
if (!_getNumberedPath(
|
||||
path, sizeof(path), EXTERNAL_DATA_DIR "/cart%04d.573"
|
||||
))
|
||||
goto _error;
|
||||
}
|
||||
|
||||
LOG("saving %s, length=%d", path, length);
|
||||
|
@ -34,7 +34,10 @@ void WarningScreen::update(ui::Context &ctx) {
|
||||
if (_locked) {
|
||||
time = (time / ctx.gpuCtx.refreshRate) + 1;
|
||||
|
||||
sprintf(_buttonText, STR("WarningScreen.cooldown"), time);
|
||||
snprintf(
|
||||
_buttonText, sizeof(_buttonText), STR("WarningScreen.cooldown"),
|
||||
time
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -217,13 +217,12 @@ int FilePickerScreen::loadDirectory(ui::Context &ctx, const char *path) {
|
||||
LOG("path: %s", path);
|
||||
LOG("files=%d, dirs=%d", _numFiles, _numDirectories);
|
||||
|
||||
if (_numFiles)
|
||||
_files.allocate(sizeof(file::FileInfo) * _numFiles);
|
||||
if (_numDirectories)
|
||||
_directories.allocate(sizeof(file::FileInfo) * _numDirectories);
|
||||
file::FileInfo *files, *directories;
|
||||
|
||||
auto files = _files.as<file::FileInfo>();
|
||||
auto directories = _directories.as<file::FileInfo>();
|
||||
if (_numFiles)
|
||||
files = _files.allocate<file::FileInfo>(_numFiles);
|
||||
if (_numDirectories)
|
||||
directories = _directories.allocate<file::FileInfo>(_numDirectories);
|
||||
|
||||
// Iterate over all entries again to populate the newly allocated arrays.
|
||||
directory = APP->_fileProvider.openDirectory(path);
|
||||
|
@ -326,10 +326,10 @@ void StorageActionsScreen::update(ui::Context &ctx) {
|
||||
void CardSizeScreen::show(ui::Context &ctx, bool goBack) {
|
||||
_title = STR("CardSizeScreen.title");
|
||||
_body = STR("CardSizeScreen.body");
|
||||
_buttons[0] = STR("CardSizeScreen.16");
|
||||
_buttons[1] = STR("CardSizeScreen.32");
|
||||
_buttons[2] = STR("CardSizeScreen.64");
|
||||
_buttons[3] = STR("CardSizeScreen.cancel");
|
||||
_buttons[0] = STR("CardSizeScreen.cancel");
|
||||
_buttons[1] = STR("CardSizeScreen.16");
|
||||
_buttons[2] = STR("CardSizeScreen.32");
|
||||
_buttons[3] = STR("CardSizeScreen.64");
|
||||
|
||||
_numButtons = 4;
|
||||
|
||||
@ -340,11 +340,11 @@ void CardSizeScreen::update(ui::Context &ctx) {
|
||||
MessageBoxScreen::update(ctx);
|
||||
|
||||
if (ctx.buttons.pressed(ui::BTN_START)) {
|
||||
if (_activeButton == 3) {
|
||||
ctx.show(APP->_storageActionsScreen, true, true);
|
||||
} else {
|
||||
selectedLength = 0x1000000 << _activeButton;
|
||||
if (_activeButton) {
|
||||
selectedLength = 0x800000 << _activeButton;
|
||||
(APP->_storageActionsScreen.*callback)(ctx);
|
||||
} else {
|
||||
ctx.show(APP->_storageActionsScreen, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,33 +98,21 @@ bool App::_romChecksumWorker(void) {
|
||||
bool App::_romDumpWorker(void) {
|
||||
_workerStatus.update(0, 1, WSTR("App.romDumpWorker.init"));
|
||||
|
||||
// Store all dumps in a subdirectory named "dumpN" within the main data
|
||||
// Store all dumps in a subdirectory named "dumpNNNN" within the main data
|
||||
// folder.
|
||||
file::FileInfo info;
|
||||
char dirPath[32];
|
||||
|
||||
__builtin_strcpy(dirPath, EXTERNAL_DATA_DIR);
|
||||
|
||||
if (!_fileProvider.getFileInfo(info, dirPath)) {
|
||||
if (!_fileProvider.createDirectory(dirPath))
|
||||
goto _initError;
|
||||
}
|
||||
|
||||
int index;
|
||||
char filePath[32];
|
||||
|
||||
index = 0;
|
||||
|
||||
do {
|
||||
index++;
|
||||
snprintf(dirPath, sizeof(dirPath), EXTERNAL_DATA_DIR "/dump%04d", index);
|
||||
} while (_fileProvider.getFileInfo(info, dirPath));
|
||||
|
||||
LOG("saving dumps to %s", dirPath);
|
||||
char dirPath[32], filePath[32];
|
||||
|
||||
if (!_createDataDirectory())
|
||||
goto _initError;
|
||||
if (!_getNumberedPath(
|
||||
dirPath, sizeof(dirPath), EXTERNAL_DATA_DIR "/dump%04d"
|
||||
))
|
||||
goto _initError;
|
||||
if (!_fileProvider.createDirectory(dirPath))
|
||||
goto _initError;
|
||||
|
||||
LOG("saving dumps to %s", dirPath);
|
||||
|
||||
for (auto &entry : _REGION_INFO) {
|
||||
if (!entry.region.isPresent())
|
||||
continue;
|
||||
@ -142,19 +130,19 @@ bool App::_romDumpWorker(void) {
|
||||
if (!_file)
|
||||
goto _fileError;
|
||||
|
||||
auto buffer = new uint8_t[chunkLength];
|
||||
uint32_t offset = 0;
|
||||
util::Data buffer;
|
||||
uint32_t offset = 0;
|
||||
|
||||
//assert(buffer);
|
||||
buffer.allocate(chunkLength);
|
||||
|
||||
for (size_t i = 0; i < numChunks; i++) {
|
||||
_workerStatus.update(i, numChunks, WSTRH(entry.dumpPrompt));
|
||||
entry.region.read(buffer, offset, chunkLength);
|
||||
entry.region.read(buffer.ptr, offset, chunkLength);
|
||||
|
||||
if (_file->write(buffer, chunkLength) < chunkLength) {
|
||||
if (_file->write(buffer.ptr, chunkLength) < chunkLength) {
|
||||
buffer.destroy();
|
||||
_file->close();
|
||||
delete _file;
|
||||
delete[] buffer;
|
||||
delete _file;
|
||||
|
||||
goto _fileError;
|
||||
}
|
||||
@ -162,9 +150,9 @@ bool App::_romDumpWorker(void) {
|
||||
offset += chunkLength;
|
||||
}
|
||||
|
||||
buffer.destroy();
|
||||
_file->close();
|
||||
delete _file;
|
||||
delete[] buffer;
|
||||
delete _file;
|
||||
|
||||
LOG("%s saved", filePath);
|
||||
}
|
||||
@ -202,67 +190,117 @@ bool App::_romRestoreWorker(void) {
|
||||
auto region = _storageActionsScreen.selectedRegion;
|
||||
auto regionLength = _cardSizeScreen.selectedLength;
|
||||
|
||||
size_t bytesWritten = 0;
|
||||
|
||||
util::Data buffers, chunkLengths;
|
||||
|
||||
if (!_file)
|
||||
goto _fileError;
|
||||
if (!_romEraseWorker())
|
||||
return false;
|
||||
|
||||
size_t fileLength, dataLength;
|
||||
|
||||
fileLength = size_t(_file->length);
|
||||
dataLength = util::min(fileLength, regionLength);
|
||||
|
||||
rom::Driver *driver;
|
||||
size_t sectorLength, numSectors;
|
||||
size_t chipLength, numChips, maxChunkLength;
|
||||
|
||||
driver = region->newDriver();
|
||||
sectorLength = driver->getChipSize().eraseSectorLength;
|
||||
numSectors = (dataLength + sectorLength - 1) / sectorLength;
|
||||
driver = region->newDriver();
|
||||
chipLength = driver->getChipSize().chipLength;
|
||||
numChips = (regionLength + chipLength - 1) / chipLength;
|
||||
maxChunkLength = util::min(regionLength, _DUMP_CHUNK_LENGTH / numChips);
|
||||
|
||||
LOG("%d chips, buf=%d", numChips, maxChunkLength);
|
||||
|
||||
rom::DriverError error;
|
||||
uint8_t *buffer;
|
||||
uint32_t offset;
|
||||
|
||||
buffer = new uint8_t[sectorLength];
|
||||
offset = 0;
|
||||
buffers.allocate(maxChunkLength * numChips);
|
||||
chunkLengths.allocate<size_t>(numChips);
|
||||
|
||||
//assert(buffer);
|
||||
// Parallelize writing by buffering a chunk for each chip into RAM, then
|
||||
// writing all chunks to the respective chips at the same time.
|
||||
for (size_t i = 0; i < chipLength; i += maxChunkLength) {
|
||||
_workerStatus.update(i, chipLength, WSTR("App.romRestoreWorker.write"));
|
||||
|
||||
for (size_t i = 0; i < numSectors; i++) {
|
||||
_workerStatus.update(i, numSectors, WSTR("App.romRestoreWorker.write"));
|
||||
auto bufferPtr = buffers.as<uint8_t>();
|
||||
auto lengthPtr = chunkLengths.as<size_t>();
|
||||
size_t offset = i;
|
||||
size_t totalLength = 0;
|
||||
|
||||
auto length = _file->read(buffer, sectorLength);
|
||||
auto ptr = reinterpret_cast<const uint16_t *>(buffer);
|
||||
for (
|
||||
size_t j = numChips; j > 0; j--, bufferPtr += maxChunkLength,
|
||||
offset += chipLength
|
||||
) {
|
||||
_file->seek(offset);
|
||||
auto length = _file->read(bufferPtr, maxChunkLength);
|
||||
|
||||
// Data is written 16 bits at a time, so the buffer must be padded to an
|
||||
// even number of bytes.
|
||||
if (length % 2)
|
||||
buffer[length++] = 0xff;
|
||||
// Data is written 16 bits at a time, so the chunk must be padded to
|
||||
// an even number of bytes.
|
||||
if (length % 2)
|
||||
bufferPtr[length++] = 0xff;
|
||||
|
||||
for (uint32_t end = offset + length; offset < end; offset += 2) {
|
||||
auto value = *(ptr++);
|
||||
*(lengthPtr++) = length;
|
||||
totalLength += length;
|
||||
}
|
||||
|
||||
driver->write(offset, value);
|
||||
error = driver->flushWrite(offset, value);
|
||||
// Stop once there is no more data to write.
|
||||
if (!totalLength)
|
||||
break;
|
||||
|
||||
if (error)
|
||||
goto _flashError;
|
||||
bufferPtr = buffers.as<uint8_t>();
|
||||
offset = i;
|
||||
|
||||
for (
|
||||
size_t j = 0; j < maxChunkLength; j += 2, bufferPtr += 2,
|
||||
offset += 2
|
||||
) {
|
||||
auto chunkOffset = offset;
|
||||
auto chunkPtr = bufferPtr;
|
||||
lengthPtr = chunkLengths.as<size_t>();
|
||||
|
||||
for (
|
||||
size_t k = numChips; k > 0;
|
||||
k--, chunkPtr += maxChunkLength, chunkOffset += chipLength
|
||||
) {
|
||||
if (j >= *(lengthPtr++))
|
||||
continue;
|
||||
|
||||
auto value = *reinterpret_cast<const uint16_t *>(chunkPtr);
|
||||
|
||||
driver->write(chunkOffset, value);
|
||||
}
|
||||
|
||||
chunkOffset = offset;
|
||||
chunkPtr = bufferPtr;
|
||||
lengthPtr = chunkLengths.as<size_t>();
|
||||
|
||||
for (
|
||||
size_t k = numChips; k > 0; k--, chunkPtr += maxChunkLength,
|
||||
chunkOffset += chipLength, bytesWritten += 2
|
||||
) {
|
||||
if (j >= *(lengthPtr++))
|
||||
continue;
|
||||
|
||||
auto value = *reinterpret_cast<const uint16_t *>(chunkPtr);
|
||||
error = driver->flushWrite(chunkOffset, value);
|
||||
|
||||
if (error)
|
||||
goto _flashError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_file->close();
|
||||
delete _file;
|
||||
delete[] buffer;
|
||||
delete driver;
|
||||
|
||||
util::Hash message;
|
||||
|
||||
message = (fileLength > dataLength)
|
||||
message = (_file->length > regionLength)
|
||||
? "App.romRestoreWorker.overflow"_h
|
||||
: "App.romRestoreWorker.success"_h;
|
||||
|
||||
buffers.destroy();
|
||||
chunkLengths.destroy();
|
||||
_file->close();
|
||||
delete _file;
|
||||
delete driver;
|
||||
|
||||
_messageScreen.setMessage(
|
||||
MESSAGE_SUCCESS, _storageInfoScreen, WSTRH(message), offset
|
||||
MESSAGE_SUCCESS, _storageInfoScreen, WSTRH(message), bytesWritten
|
||||
);
|
||||
_workerStatus.setNextScreen(_messageScreen);
|
||||
return true;
|
||||
@ -276,15 +314,16 @@ _fileError:
|
||||
return false;
|
||||
|
||||
_flashError:
|
||||
buffers.destroy();
|
||||
chunkLengths.destroy();
|
||||
_file->close();
|
||||
delete _file;
|
||||
delete[] buffer;
|
||||
delete driver;
|
||||
delete _file;
|
||||
delete driver;
|
||||
|
||||
_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, _storageInfoScreen,
|
||||
WSTR("App.romRestoreWorker.flashError"), rom::getErrorString(error),
|
||||
offset
|
||||
bytesWritten
|
||||
);
|
||||
_workerStatus.setNextScreen(_messageScreen);
|
||||
return false;
|
||||
@ -293,10 +332,12 @@ _flashError:
|
||||
bool App::_romEraseWorker(void) {
|
||||
auto region = _storageActionsScreen.selectedRegion;
|
||||
auto regionLength = _cardSizeScreen.selectedLength;
|
||||
auto driver = region->newDriver();
|
||||
|
||||
size_t chipLength = driver->getChipSize().chipLength;
|
||||
size_t sectorLength = driver->getChipSize().eraseSectorLength;
|
||||
auto driver = region->newDriver();
|
||||
size_t chipLength = driver->getChipSize().chipLength;
|
||||
size_t sectorLength = driver->getChipSize().eraseSectorLength;
|
||||
//size_t numChips = (regionLength + chipLength - 1) / chipLength;
|
||||
|
||||
size_t sectorsErased = 0;
|
||||
|
||||
if (!chipLength)
|
||||
@ -306,7 +347,8 @@ bool App::_romEraseWorker(void) {
|
||||
|
||||
_checksumScreen.valid = false;
|
||||
|
||||
// Erase one sector at a time on each chip.
|
||||
// Parallelize erasing by sending the same sector erase command to all chips
|
||||
// at the same time.
|
||||
for (size_t i = 0; i < chipLength; i += sectorLength) {
|
||||
_workerStatus.update(i, chipLength, WSTR("App.romEraseWorker.erase"));
|
||||
|
||||
@ -356,6 +398,8 @@ bool App::_flashHeaderWriteWorker(void) {
|
||||
auto driver = rom::flash.newDriver();
|
||||
size_t sectorLength = driver->getChipSize().eraseSectorLength;
|
||||
|
||||
util::Data buffer;
|
||||
|
||||
// This should never happen since the flash chips are soldered to the 573,
|
||||
// but whatever.
|
||||
if (!sectorLength)
|
||||
@ -367,14 +411,10 @@ bool App::_flashHeaderWriteWorker(void) {
|
||||
// The flash can only be erased with sector granularity, so all data in the
|
||||
// first sector other than the header must be backed up and rewritten.
|
||||
rom::DriverError error;
|
||||
uint8_t *buffer;
|
||||
const uint16_t *ptr;
|
||||
|
||||
buffer = new uint8_t[sectorLength];
|
||||
|
||||
//assert(buffer);
|
||||
|
||||
rom::flash.read(buffer, 0, sectorLength);
|
||||
buffer.allocate(sectorLength);
|
||||
rom::flash.read(buffer.ptr, 0, sectorLength);
|
||||
|
||||
driver->eraseSector(0);
|
||||
error = driver->flushErase(0);
|
||||
@ -403,7 +443,7 @@ bool App::_flashHeaderWriteWorker(void) {
|
||||
}
|
||||
|
||||
// Restore the rest of the sector that was erased.
|
||||
ptr = reinterpret_cast<const uint16_t *>(&buffer[rom::FLASH_CRC_OFFSET]);
|
||||
ptr = &buffer.as<const uint16_t>()[rom::FLASH_CRC_OFFSET / 2];
|
||||
|
||||
for (
|
||||
uint32_t offset = rom::FLASH_CRC_OFFSET; offset < sectorLength;
|
||||
@ -418,15 +458,15 @@ bool App::_flashHeaderWriteWorker(void) {
|
||||
goto _flashError;
|
||||
}
|
||||
|
||||
delete[] buffer;
|
||||
delete driver;
|
||||
buffer.destroy();
|
||||
delete driver;
|
||||
|
||||
_workerStatus.setNextScreen(_storageInfoScreen);
|
||||
return true;
|
||||
|
||||
_flashError:
|
||||
delete[] buffer;
|
||||
delete driver;
|
||||
buffer.destroy();
|
||||
delete driver;
|
||||
|
||||
_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, _storageInfoScreen,
|
||||
|
@ -29,7 +29,7 @@ typedef enum {
|
||||
SYS573_MISC_OUT_AMP_ENABLE = 1 << 5,
|
||||
SYS573_MISC_OUT_CDDA_ENABLE = 1 << 6,
|
||||
SYS573_MISC_OUT_SPU_ENABLE = 1 << 7,
|
||||
SYS573_MISC_OUT_JVS_STAT = 1 << 8
|
||||
SYS573_MISC_OUT_JVS_RESET = 1 << 8
|
||||
} Sys573MiscOutputFlag;
|
||||
|
||||
typedef enum {
|
||||
@ -37,10 +37,10 @@ typedef enum {
|
||||
SYS573_MISC_IN_ADC_SARS = 1 << 1,
|
||||
SYS573_MISC_IN_CART_SDA = 1 << 2,
|
||||
SYS573_MISC_IN_JVS_SENSE = 1 << 3,
|
||||
SYS573_MISC_IN_JVS_AVAIL = 1 << 4,
|
||||
SYS573_MISC_IN_JVS_UNK = 1 << 5,
|
||||
SYS573_MISC_IN_CART_ISIG = 1 << 6,
|
||||
SYS573_MISC_IN_CART_DSIG = 1 << 7,
|
||||
SYS573_MISC_IN_JVS_IRDY = 1 << 4,
|
||||
SYS573_MISC_IN_JVS_DRDY = 1 << 5,
|
||||
SYS573_MISC_IN_CART_IRDY = 1 << 6,
|
||||
SYS573_MISC_IN_CART_DRDY = 1 << 7,
|
||||
SYS573_MISC_IN_COIN1 = 1 << 8,
|
||||
SYS573_MISC_IN_COIN2 = 1 << 9,
|
||||
SYS573_MISC_IN_PCMCIA_CD1 = 1 << 10,
|
||||
@ -126,17 +126,18 @@ typedef enum {
|
||||
typedef enum {
|
||||
SYS573D_CPLD_STAT_INIT = 1 << 12,
|
||||
SYS573D_CPLD_STAT_DONE = 1 << 13,
|
||||
SYS573D_CPLD_STAT_LDC = 1 << 14,
|
||||
SYS573D_CPLD_STAT_HDC = 1 << 15
|
||||
SYS573D_CPLD_STAT_ID1 = 1 << 14,
|
||||
SYS573D_CPLD_STAT_ID2 = 1 << 15
|
||||
} Sys573DCPLDStatusFlag;
|
||||
|
||||
typedef enum {
|
||||
SYS573D_CPLD_CTRL_UNK1 = 1 << 12,
|
||||
SYS573D_CPLD_CTRL_UNK2 = 1 << 13,
|
||||
SYS573D_CPLD_CTRL_UNK3 = 1 << 14,
|
||||
SYS573D_CPLD_CTRL_UNK4 = 1 << 15
|
||||
SYS573D_CPLD_CTRL_INIT = 1 << 12,
|
||||
SYS573D_CPLD_CTRL_DONE = 1 << 13,
|
||||
SYS573D_CPLD_CTRL_PROGRAM = 1 << 14,
|
||||
SYS573D_CPLD_CTRL_UNKNOWN = 1 << 15
|
||||
} Sys573DCPLDControlFlag;
|
||||
|
||||
#define SYS573D_FPGA_MAGIC _MMIO16(DEV0_BASE | 0x640080)
|
||||
#define SYS573D_FPGA_LIGHTS_A1 _MMIO16(DEV0_BASE | 0x6400e0)
|
||||
#define SYS573D_FPGA_LIGHTS_A0 _MMIO16(DEV0_BASE | 0x6400e2)
|
||||
#define SYS573D_FPGA_LIGHTS_B1 _MMIO16(DEV0_BASE | 0x6400e4)
|
||||
|
Loading…
x
Reference in New Issue
Block a user