Fix IDE and file closing bugs

This commit is contained in:
spicyjpeg 2024-04-11 07:59:47 +02:00
parent e836f665f4
commit 80be8fdd0e
No known key found for this signature in database
GPG Key ID: 5CC87404C01DF393
10 changed files with 143 additions and 97 deletions

View File

@ -206,49 +206,50 @@ Provider::~Provider(void) {
} }
size_t Provider::loadData(util::Data &output, const char *path) { size_t Provider::loadData(util::Data &output, const char *path) {
auto file = openFile(path, READ); auto _file = openFile(path, READ);
if (!file) if (!_file)
return 0; return 0;
//assert(file->length <= SIZE_MAX); //assert(file->length <= SIZE_MAX);
if (!output.allocate(size_t(file->length))) { if (!output.allocate(size_t(_file->length))) {
delete file; _file->close();
delete _file;
return 0; return 0;
} }
size_t actualLength = file->read(output.ptr, output.length); size_t actualLength = _file->read(output.ptr, output.length);
file->close();
delete file; _file->close();
delete _file;
return actualLength; return actualLength;
} }
size_t Provider::loadData(void *output, size_t length, const char *path) { size_t Provider::loadData(void *output, size_t length, const char *path) {
auto file = openFile(path, READ); auto _file = openFile(path, READ);
if (!file) if (!_file)
return 0; return 0;
//assert(file->length >= length); //assert(file->length >= length);
size_t actualLength = file->read(output, length); size_t actualLength = _file->read(output, length);
file->close();
delete file; _file->close();
delete _file;
return actualLength; return actualLength;
} }
size_t Provider::saveData(const void *input, size_t length, const char *path) { size_t Provider::saveData(const void *input, size_t length, const char *path) {
#ifdef ENABLE_FILE_WRITING #ifdef ENABLE_FILE_WRITING
auto file = openFile(path, WRITE | ALLOW_CREATE); auto _file = openFile(path, WRITE | ALLOW_CREATE);
if (!file) if (!_file)
return 0; return 0;
size_t actualLength = file->write(input, length); size_t actualLength = _file->write(input, length);
file->close();
delete file; _file->close();
delete _file;
return actualLength; return actualLength;
#else #else
return 0; return 0;
@ -511,17 +512,17 @@ File *FATProvider::openFile(const char *path, uint32_t flags) {
if (!_selectDrive()) if (!_selectDrive())
return nullptr; return nullptr;
auto file = new FATFile(); auto _file = new FATFile();
auto error = f_open(&(file->_fd), path, uint8_t(flags)); auto error = f_open(&(_file->_fd), path, uint8_t(flags));
if (error) { if (error) {
LOG("%s, drive=%s", _FATFS_ERROR_NAMES[error], _drive); LOG("%s, drive=%s", _FATFS_ERROR_NAMES[error], _drive);
delete file; delete _file;
return nullptr; return nullptr;
} }
file->length = f_size(&(file->_fd)); _file->length = f_size(&(_file->_fd));
return file; return _file;
} }
static constexpr uint32_t _ZIP_FLAGS = 0 static constexpr uint32_t _ZIP_FLAGS = 0

View File

@ -45,6 +45,7 @@ static void _copyString(char *output, const uint16_t *input, size_t length) {
output += length; output += length;
input += length / 2; input += length / 2;
*output = 0;
for (; length; length -= 2) { for (; length; length -= 2) {
uint16_t packed = *(--input); uint16_t packed = *(--input);
@ -264,9 +265,9 @@ DeviceError Device::enumerate(void) {
flags |= DEVICE_HAS_FLUSH; flags |= DEVICE_HAS_FLUSH;
} }
_copyString(model, block.model, sizeof(model)); _copyString(model, block.model, sizeof(block.model));
_copyString(revision, block.revision, sizeof(revision)); _copyString(revision, block.revision, sizeof(block.revision));
_copyString(serialNumber, block.serialNumber, sizeof(serialNumber)); _copyString(serialNumber, block.serialNumber, sizeof(block.serialNumber));
LOG("drive %d: %s", (flags / DEVICE_SECONDARY) & 1, model); LOG("drive %d: %s", (flags / DEVICE_SECONDARY) & 1, model);

View File

@ -331,7 +331,7 @@ private:
public: public:
uint32_t flags; uint32_t flags;
char model[40], revision[8], serialNumber[20]; char model[41], revision[9], serialNumber[21];
uint64_t capacity; uint64_t capacity;
inline Device(uint32_t flags) inline Device(uint32_t flags)

View File

@ -177,25 +177,24 @@ enum JEDECCommand : uint16_t {
_JEDEC_ERASE_SECTOR = 0x3030 _JEDEC_ERASE_SECTOR = 0x3030
}; };
enum SharpCommand : uint16_t { enum IntelCommand : uint16_t {
_SHARP_RESET = 0xffff, _INTEL_RESET = 0xffff,
_SHARP_GET_ID = 0x9090, _INTEL_GET_ID = 0x9090,
_SHARP_WRITE_BYTE = 0x4040, _INTEL_WRITE_BYTE = 0x4040,
_SHARP_ERASE_SECTOR1 = 0x2020, _INTEL_ERASE_SECTOR1 = 0x2020,
_SHARP_ERASE_SECTOR2 = 0xd0d0, _INTEL_ERASE_SECTOR2 = 0xd0d0,
_SHARP_GET_STATUS = 0x7070, _INTEL_GET_STATUS = 0x7070,
_SHARP_CLEAR_STATUS = 0x5050, _INTEL_CLEAR_STATUS = 0x5050,
_SHARP_SUSPEND = 0xb0b0, _INTEL_SUSPEND = 0xb0b0,
_SHARP_RESUME = 0xd0d0 _INTEL_RESUME = 0xd0d0
}; };
enum FlashIdentifier : uint16_t { enum FlashIdentifier : uint16_t {
// NOTE: the MBM29F017A datasheet incorrectly lists the device ID as 0xad in _ID_MBM29F016A = 0x04 | (0xad << 8),
// some places. The chip behaves pretty much identically to the MBM29F016A. _ID_MBM29F017A = 0x04 | (0x3d << 8),
_ID_MBM29F016A = 0x04 | (0xad << 8), _ID_MBM29F040A = 0x04 | (0xa4 << 8),
_ID_MBM29F017A = 0x04 | (0x3d << 8), _ID_28F016S5 = 0x89 | (0xaa << 8),
_ID_FUJITSU_UNKNOWN = 0x04 | (0xa4 << 8), _ID_28F640J5 = 0x89 | (0x15 << 8)
_ID_LH28F016S = 0x89 | (0xaa << 8)
}; };
bool FlashRegion::hasBootExecutable(void) const { bool FlashRegion::hasBootExecutable(void) const {
@ -234,11 +233,11 @@ uint32_t FlashRegion::getJEDECID(void) const {
auto _ptr = reinterpret_cast<volatile uint16_t *>(ptr); auto _ptr = reinterpret_cast<volatile uint16_t *>(ptr);
_ptr[0x000] = _SHARP_RESET; _ptr[0x000] = _INTEL_RESET;
_ptr[0x000] = _SHARP_RESET; _ptr[0x000] = _INTEL_RESET;
_ptr[0x555] = _JEDEC_HANDSHAKE1; _ptr[0x555] = _JEDEC_HANDSHAKE1;
_ptr[0x2aa] = _JEDEC_HANDSHAKE2; _ptr[0x2aa] = _JEDEC_HANDSHAKE2;
_ptr[0x555] = _JEDEC_GET_ID; // Same as _SHARP_GET_ID _ptr[0x555] = _JEDEC_GET_ID; // Same as _INTEL_GET_ID
return _ptr[0] | (_ptr[1] << 16); return _ptr[0] | (_ptr[1] << 16);
} }
@ -254,25 +253,36 @@ Driver *FlashRegion::newDriver(void) const {
uint16_t high = ((id >> 8) & 0xff) | ((id >> 16) & 0xff00); uint16_t high = ((id >> 8) & 0xff) | ((id >> 16) & 0xff00);
LOG("low=0x%04x, high=0x%04x", low, high); LOG("low=0x%04x, high=0x%04x", low, high);
if (low != high) { if (low == high) {
// TODO: implement single-chip (16-bit) flash support // Two 8-bit chips for each bank
return new Driver(*this);
} else {
switch (low) { switch (low) {
case _ID_MBM29F016A: case _ID_MBM29F016A:
case _ID_MBM29F017A: case _ID_MBM29F017A:
// The MBM29F017A datasheet incorrectly lists the device ID as
// 0xad rather than 0x3d in some places. The chip behaves pretty
// much identically to the MBM29F016A.
return new MBM29F016ADriver(*this); return new MBM29F016ADriver(*this);
case _ID_FUJITSU_UNKNOWN: case _ID_MBM29F040A:
return new FujitsuUnknownDriver(*this); return new MBM29F040ADriver(*this);
case _ID_LH28F016S: case _ID_28F016S5:
return new LH28F016SDriver(*this); // The chip used by Konami is actually the Sharp LH28F016S,
// which uses the same ID and command set as the Intel 28F016S5.
default: return new Intel28F016S5Driver(*this);
return new Driver(*this); }
//} else if (!high || (high == 0xff)) {
} else {
// Single 16-bit chip for each bank
switch (low) {
case _ID_28F640J5:
// Found in "Centennial" branded flash cards. Not supported by
// Konami's drivers.
return new Intel28F640J5Driver(*this);
} }
} }
return new Driver(*this);
} }
const BIOSRegion bios; const BIOSRegion bios;
@ -350,7 +360,7 @@ const ChipSize &RTCDriver::getChipSize(void) const {
return _RTC_CHIP_SIZE; return _RTC_CHIP_SIZE;
} }
/* Fujitsu MBM29F016A driver */ /* Fujitsu MBM29F016A/017A driver */
enum FujitsuStatusFlag : uint16_t { enum FujitsuStatusFlag : uint16_t {
_FUJITSU_STATUS_ERASE_TOGGLE = 0x101 << 2, _FUJITSU_STATUS_ERASE_TOGGLE = 0x101 << 2,
@ -440,13 +450,12 @@ const ChipSize &MBM29F016ADriver::getChipSize(void) const {
return _STANDARD_CHIP_SIZE; return _STANDARD_CHIP_SIZE;
} }
/* Unknown Fujitsu chip driver */ /* Fujitsu MBM29F040A driver */
// Konami's drivers handle this chip pretty much identically to the MBM29F016A, // Konami's drivers handle this chip pretty much identically to the MBM29F016A,
// but using 0x5555/0x2aaa as command addresses instead of 0x555/0x2aa. This // but using 0x5555/0x2aaa as command addresses instead of 0x555/0x2aa.
// could actually be a >2 MB chip.
void FujitsuUnknownDriver::write(uint32_t offset, uint16_t value) { void MBM29F040ADriver::write(uint32_t offset, uint16_t value) {
volatile uint16_t *ptr = _region.getRawPtr(offset, true); volatile uint16_t *ptr = _region.getRawPtr(offset, true);
offset = (offset % FLASH_BANK_LENGTH) / 2; offset = (offset % FLASH_BANK_LENGTH) / 2;
@ -457,7 +466,7 @@ void FujitsuUnknownDriver::write(uint32_t offset, uint16_t value) {
ptr[offset] = value; ptr[offset] = value;
} }
void FujitsuUnknownDriver::eraseSector(uint32_t offset) { void MBM29F040ADriver::eraseSector(uint32_t offset) {
volatile uint16_t *ptr = _region.getRawPtr(offset, true); volatile uint16_t *ptr = _region.getRawPtr(offset, true);
offset = (offset % FLASH_BANK_LENGTH) / 2; offset = (offset % FLASH_BANK_LENGTH) / 2;
@ -470,7 +479,7 @@ void FujitsuUnknownDriver::eraseSector(uint32_t offset) {
ptr[offset] = _JEDEC_ERASE_SECTOR; ptr[offset] = _JEDEC_ERASE_SECTOR;
} }
void FujitsuUnknownDriver::eraseChip(uint32_t offset) { void MBM29F040ADriver::eraseChip(uint32_t offset) {
volatile uint16_t *ptr = _region.getRawPtr(offset, true); volatile uint16_t *ptr = _region.getRawPtr(offset, true);
ptr[0x0005] = _JEDEC_RESET; ptr[0x0005] = _JEDEC_RESET;
@ -482,42 +491,42 @@ void FujitsuUnknownDriver::eraseChip(uint32_t offset) {
ptr[0x5555] = _JEDEC_ERASE_CHIP; ptr[0x5555] = _JEDEC_ERASE_CHIP;
} }
/* Sharp LH28F016S driver */ /* Intel 28F016S5 (Sharp LH28F016S) driver */
enum SharpStatusFlag : uint16_t { enum IntelStatusFlag : uint16_t {
_SHARP_STATUS_DPS = 0x101 << 1, _INTEL_STATUS_DPS = 0x101 << 1,
_SHARP_STATUS_BWSS = 0x101 << 2, _INTEL_STATUS_BWSS = 0x101 << 2,
_SHARP_STATUS_VPPS = 0x101 << 3, _INTEL_STATUS_VPPS = 0x101 << 3,
_SHARP_STATUS_BWSLBS = 0x101 << 4, _INTEL_STATUS_BWSLBS = 0x101 << 4,
_SHARP_STATUS_ECLBS = 0x101 << 5, _INTEL_STATUS_ECLBS = 0x101 << 5,
_SHARP_STATUS_ESS = 0x101 << 6, _INTEL_STATUS_ESS = 0x101 << 6,
_SHARP_STATUS_WSMS = 0x101 << 7 _INTEL_STATUS_WSMS = 0x101 << 7
}; };
DriverError LH28F016SDriver::_flush(uint32_t offset, int timeout) { DriverError Intel28F016S5Driver::_flush(uint32_t offset, int timeout) {
volatile uint16_t *ptr = _region.getRawPtr(offset); volatile uint16_t *ptr = _region.getRawPtr(offset);
// Not required as all write/erase commands already put the chip into status // Not required as all write/erase commands already put the chip into status
// reading mode. // reading mode.
//*ptr = _SHARP_GET_STATUS; //*ptr = _INTEL_GET_STATUS;
for (; timeout > 0; timeout--) { for (; timeout > 0; timeout--) {
auto status = *ptr; auto status = *ptr;
if (status & (_SHARP_STATUS_DPS | _SHARP_STATUS_VPPS)) { if (status & (_INTEL_STATUS_DPS | _INTEL_STATUS_VPPS)) {
*ptr = _SHARP_CLEAR_STATUS; *ptr = _INTEL_CLEAR_STATUS;
LOG("locked @ 0x%08x, stat=0x%04x", offset, status); LOG("locked @ 0x%08x, stat=0x%04x", offset, status);
return WRITE_PROTECTED; return WRITE_PROTECTED;
} }
if (status & (_SHARP_STATUS_BWSLBS | _SHARP_STATUS_ECLBS)) { if (status & (_INTEL_STATUS_BWSLBS | _INTEL_STATUS_ECLBS)) {
*ptr = _SHARP_CLEAR_STATUS; *ptr = _INTEL_CLEAR_STATUS;
LOG("error @ 0x%08x, stat=0x%04x", offset, status); LOG("error @ 0x%08x, stat=0x%04x", offset, status);
return CHIP_ERROR; return CHIP_ERROR;
} }
if (status & _SHARP_STATUS_WSMS) if (status & _INTEL_STATUS_WSMS)
return NO_ERROR; return NO_ERROR;
delayMicroseconds(1); delayMicroseconds(1);
@ -527,37 +536,48 @@ DriverError LH28F016SDriver::_flush(uint32_t offset, int timeout) {
return CHIP_TIMEOUT; return CHIP_TIMEOUT;
} }
void LH28F016SDriver::write(uint32_t offset, uint16_t value) { void Intel28F016S5Driver::write(uint32_t offset, uint16_t value) {
volatile uint16_t *ptr = _region.getRawPtr(offset); volatile uint16_t *ptr = _region.getRawPtr(offset);
*ptr = _SHARP_RESET; *ptr = _INTEL_RESET;
*ptr = _SHARP_CLEAR_STATUS; *ptr = _INTEL_CLEAR_STATUS;
*ptr = _SHARP_WRITE_BYTE; *ptr = _INTEL_WRITE_BYTE;
*ptr = value; *ptr = value;
} }
void LH28F016SDriver::eraseSector(uint32_t offset) { void Intel28F016S5Driver::eraseSector(uint32_t offset) {
volatile uint16_t *ptr = _region.getRawPtr(offset); volatile uint16_t *ptr = _region.getRawPtr(offset);
*ptr = _SHARP_RESET; *ptr = _INTEL_RESET;
*ptr = _SHARP_ERASE_SECTOR1; *ptr = _INTEL_ERASE_SECTOR1;
*ptr = _SHARP_ERASE_SECTOR2; *ptr = _INTEL_ERASE_SECTOR2;
} }
DriverError LH28F016SDriver::flushWrite( DriverError Intel28F016S5Driver::flushWrite(
uint32_t offset, uint16_t value uint32_t offset, uint16_t value
) { ) {
return _flush(offset, _FLASH_WRITE_TIMEOUT); return _flush(offset, _FLASH_WRITE_TIMEOUT);
} }
DriverError LH28F016SDriver::flushErase(uint32_t offset) { DriverError Intel28F016S5Driver::flushErase(uint32_t offset) {
return _flush(offset, _FLASH_ERASE_TIMEOUT); return _flush(offset, _FLASH_ERASE_TIMEOUT);
} }
const ChipSize &LH28F016SDriver::getChipSize(void) const { const ChipSize &Intel28F016S5Driver::getChipSize(void) const {
return _STANDARD_CHIP_SIZE; return _STANDARD_CHIP_SIZE;
} }
/* Intel 28F640J5 driver */
static const ChipSize _28F640J5_CHIP_SIZE{
.chipLength = 0x800000,
.eraseSectorLength = 0x20000
};
const ChipSize &Intel28F640J5Driver::getChipSize(void) const {
return _28F640J5_CHIP_SIZE;
}
/* BIOS ROM headers */ /* BIOS ROM headers */
static const ShellInfo _SHELL_VERSIONS[]{ static const ShellInfo _SHELL_VERSIONS[]{

View File

@ -144,9 +144,9 @@ public:
const ChipSize &getChipSize(void) const; const ChipSize &getChipSize(void) const;
}; };
class FujitsuUnknownDriver : public MBM29F016ADriver { class MBM29F040ADriver : public MBM29F016ADriver {
public: public:
inline FujitsuUnknownDriver(const FlashRegion &region) inline MBM29F040ADriver(const FlashRegion &region)
: MBM29F016ADriver(region) {} : MBM29F016ADriver(region) {}
void write(uint32_t offset, uint16_t value); void write(uint32_t offset, uint16_t value);
@ -154,12 +154,12 @@ public:
void eraseChip(uint32_t offset); void eraseChip(uint32_t offset);
}; };
class LH28F016SDriver : public Driver { class Intel28F016S5Driver : public Driver {
private: private:
DriverError _flush(uint32_t offset, int timeout); DriverError _flush(uint32_t offset, int timeout);
public: public:
inline LH28F016SDriver(const FlashRegion &region) inline Intel28F016S5Driver(const FlashRegion &region)
: Driver(region) {} : Driver(region) {}
void write(uint32_t offset, uint16_t value); void write(uint32_t offset, uint16_t value);
@ -169,6 +169,14 @@ public:
const ChipSize &getChipSize(void) const; const ChipSize &getChipSize(void) const;
}; };
class Intel28F640J5Driver : public Intel28F016S5Driver {
public:
inline Intel28F640J5Driver(const FlashRegion &region)
: Intel28F016S5Driver(region) {}
const ChipSize &getChipSize(void) const;
};
extern const char *const DRIVER_ERROR_NAMES[]; extern const char *const DRIVER_ERROR_NAMES[];
static inline const char *getErrorString(DriverError error) { static inline const char *getErrorString(DriverError error) {

View File

@ -73,8 +73,10 @@ App::~App(void) {
_unloadCartData(); _unloadCartData();
//_resourceProvider.close(); //_resourceProvider.close();
if (_resourceFile) if (_resourceFile) {
_resourceFile->close();
delete _resourceFile; delete _resourceFile;
}
//_fileProvider.close(); //_fileProvider.close();

View File

@ -291,6 +291,7 @@ bool App::_cartRestoreWorker(void) {
if (length != newDump.getDumpLength()) if (length != newDump.getDumpLength())
goto _fileError; goto _fileError;
_file->close();
delete _file; delete _file;
if (_dump.chipType != newDump.chipType) { if (_dump.chipType != newDump.chipType) {
@ -336,6 +337,7 @@ bool App::_cartRestoreWorker(void) {
return _cartUnlockWorker(); return _cartUnlockWorker();
_fileError: _fileError:
_file->close();
delete _file; delete _file;
_fileOpenError: _fileOpenError:

View File

@ -106,6 +106,7 @@ bool App::_executableWorker(void) {
goto _validFile; goto _validFile;
} }
_file->close();
delete _file; delete _file;
_fileOpenError: _fileOpenError:
@ -117,6 +118,7 @@ _fileOpenError:
return false; return false;
_validFile: _validFile:
_file->close();
delete _file; delete _file;
uintptr_t executableEnd, stackTop; uintptr_t executableEnd, stackTop;
@ -169,8 +171,10 @@ _validFile:
_unloadCartData(); _unloadCartData();
_resourceProvider.close(); _resourceProvider.close();
if (_resourceFile) if (_resourceFile) {
_resourceFile->close();
delete _resourceFile; delete _resourceFile;
}
_fileProvider.close(); _fileProvider.close();
@ -240,8 +244,10 @@ bool App::_rebootWorker(void) {
_unloadCartData(); _unloadCartData();
_resourceProvider.close(); _resourceProvider.close();
if (_resourceFile) if (_resourceFile) {
_resourceFile->close();
delete _resourceFile; delete _resourceFile;
}
_fileProvider.close(); _fileProvider.close();
_workerStatus.setStatus(WORKER_REBOOT); _workerStatus.setStatus(WORKER_REBOOT);

View File

@ -206,6 +206,7 @@ int FilePickerScreen::loadDirectory(ui::Context &ctx, const char *path) {
_numFiles++; _numFiles++;
} }
directory->close();
delete directory; delete directory;
_activeItem = 0; _activeItem = 0;
@ -236,6 +237,7 @@ int FilePickerScreen::loadDirectory(ui::Context &ctx, const char *path) {
__builtin_memcpy(ptr, &info, sizeof(file::FileInfo)); __builtin_memcpy(ptr, &info, sizeof(file::FileInfo));
} }
directory->close();
delete directory; delete directory;
__builtin_strncpy(_currentPath, path, sizeof(_currentPath)); __builtin_strncpy(_currentPath, path, sizeof(_currentPath));

View File

@ -113,6 +113,7 @@ bool App::_romDumpWorker(void) {
entry.region.read(buffer, offset, chunkLength); entry.region.read(buffer, offset, chunkLength);
if (_file->write(buffer, chunkLength) < chunkLength) { if (_file->write(buffer, chunkLength) < chunkLength) {
_file->close();
delete _file; delete _file;
delete[] buffer; delete[] buffer;
@ -122,6 +123,7 @@ bool App::_romDumpWorker(void) {
offset += chunkLength; offset += chunkLength;
} }
_file->close();
delete _file; delete _file;
delete[] buffer; delete[] buffer;
@ -209,6 +211,7 @@ bool App::_romRestoreWorker(void) {
} }
} }
_file->close();
delete _file; delete _file;
delete[] buffer; delete[] buffer;
delete driver; delete driver;
@ -234,6 +237,7 @@ _fileError:
return false; return false;
_flashError: _flashError:
_file->close();
delete _file; delete _file;
delete[] buffer; delete[] buffer;
delete driver; delete driver;