diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b394342..e567a0f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,7 +50,7 @@ jobs: with: name: build if-no-files-found: error - path: cart-tool-*/** + path: cart-tool-*.zip - name: Publish release if: ${{ github.ref_type == 'tag' }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f85db1..3c0e952 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -218,6 +218,7 @@ function(addBootStub name resourceName) ${name} 80010000 0 src/boot/crt0.s src/boot/main.cpp + src/common/io.cpp src/common/util.cpp ) addBinaryFile( diff --git a/src/boot/main.cpp b/src/boot/main.cpp index 2b1e272..4d6731f 100644 --- a/src/boot/main.cpp +++ b/src/boot/main.cpp @@ -27,7 +27,7 @@ public: }; int main(int argc, const char **argv) { - //io::init(); + io::init(); // Parse the header of the archive's first entry manually. This avoids // pulling in miniz and bloating the binary. diff --git a/src/common/file9660.cpp b/src/common/file9660.cpp index 2515e47..5099f32 100644 --- a/src/common/file9660.cpp +++ b/src/common/file9660.cpp @@ -41,7 +41,14 @@ static size_t _comparePath(const ISORecord &record, const char *path) { auto recordName = record.getName(); auto nameLength = record.nameLength; - for (; nameLength && (*recordName != ';'); nameLength--) { + for (; nameLength; nameLength--) { + // Files with no extension still have a trailing period, which needs to + // be stripped. + if (*recordName == ';') + break; + if ((recordName[0] == '.') && (recordName[1] == ';')) + break; + if (__builtin_toupper(*(recordName++)) != __builtin_toupper(*(ptr++))) return 0; } @@ -60,8 +67,14 @@ static bool _recordToFileInfo(FileInfo &output, const ISORecord &record) { auto outputName = output.name; - for (; nameLength && (*recordName != ';'); nameLength--) + for (; nameLength; nameLength--) { + if (*recordName == ';') + break; + if ((recordName[0] == '.') && (recordName[1] == ';')) + break; + *(outputName++) = *(recordName++); + } *outputName = 0; @@ -93,13 +106,14 @@ bool ISO9660File::_loadSector(uint32_t lba) { } size_t ISO9660File::read(void *output, size_t length) { - auto offset = uint32_t(_offset); + auto offset = uint32_t(_offset); + auto fileSize = size_t(size); // Do not read any data past the end of the file. - if (offset > (size_t(size) - length)) - length = size_t(size) - _offset; - if (!length) + if (!length || (offset >= fileSize)) return 0; + if (offset > (fileSize - length)) + length = fileSize - offset; auto ptr = reinterpret_cast(output); auto remaining = length; @@ -203,7 +217,7 @@ bool ISO9660Provider::_getRecord( return false; if (!(*path)) { - output.copyFrom(&root); + __builtin_memcpy(&output, &root, root.getRecordLength()); return true; } @@ -245,7 +259,7 @@ bool ISO9660Provider::_getRecord( } records.destroy(); - LOG("%s not found", path); + LOG("not found: %s", path); return false; } @@ -285,7 +299,7 @@ bool ISO9660Provider::init(int drive) { type = ISO9660; capacity = uint64_t(pvd.volumeLength.le) * ide::ATAPI_SECTOR_SIZE; - LOG("mounted ISO: %s, drive=%d:", volumeLabel, drive); + LOG("mounted ISO: %d", drive); return true; } @@ -341,7 +355,7 @@ Directory *ISO9660Provider::openDirectory(const char *path) { (record.length.le + ide::ATAPI_SECTOR_SIZE - 1) / ide::ATAPI_SECTOR_SIZE; if (!_readData(dir->_records, record.lba.le, dirLength)) { - LOG("read failed, path=%s", path); + LOG("read failed: %s", path); delete dir; return nullptr; } diff --git a/src/common/file9660.hpp b/src/common/file9660.hpp index a3b0ac4..5311bc9 100644 --- a/src/common/file9660.hpp +++ b/src/common/file9660.hpp @@ -54,14 +54,11 @@ public: return (recordLength + 1) & ~1; } inline const ISOCharD *getName(void) const { - return &(this->recordLength) + sizeof(ISORecord); + return &(this->nameLength) + 1; } inline const uint8_t *getSystemUseData(void) const { return getName() + ((nameLength + 1) & ~1); } - inline void copyFrom(const void *source) { - __builtin_memcpy(this, source, sizeof(ISORecord)); - } }; class [[gnu::packed]] ISORecordBuffer : public ISORecord { diff --git a/src/common/filefat.cpp b/src/common/filefat.cpp index d7f27fa..16fbbb8 100644 --- a/src/common/filefat.cpp +++ b/src/common/filefat.cpp @@ -41,7 +41,7 @@ size_t FATFile::read(void *output, size_t length) { auto error = f_read(&_fd, output, length, &actualLength); if (error) { - LOG("%s, file=0x%08x", _FATFS_ERROR_NAMES[error], this); + LOG("%s", _FATFS_ERROR_NAMES[error]); return 0; } @@ -53,7 +53,7 @@ size_t FATFile::write(const void *input, size_t length) { auto error = f_write(&_fd, input, length, &actualLength); if (error) { - LOG("%s, file=0x%08x", _FATFS_ERROR_NAMES[error], this); + LOG("%s", _FATFS_ERROR_NAMES[error]); return 0; } @@ -64,7 +64,7 @@ uint64_t FATFile::seek(uint64_t offset) { auto error = f_lseek(&_fd, offset); if (error) { - LOG("%s, file=0x%08x", _FATFS_ERROR_NAMES[error], this); + LOG("%s", _FATFS_ERROR_NAMES[error]); return 0; } @@ -109,7 +109,7 @@ bool FATProvider::init(int drive) { auto error = f_mount(&_fs, _drive, 1); if (error) { - LOG("%s, drive=%s", _FATFS_ERROR_NAMES[error], _drive); + LOG("%s: %s", _FATFS_ERROR_NAMES[error], _drive); return false; } @@ -118,7 +118,7 @@ bool FATProvider::init(int drive) { f_getlabel(_drive, volumeLabel, &serialNumber); - LOG("mounted FAT: %s, drive=%s", volumeLabel, _drive); + LOG("mounted FAT: %s", _drive); return true; } @@ -126,14 +126,14 @@ void FATProvider::close(void) { auto error = f_unmount(_drive); if (error) { - LOG("%s, drive=%s", _FATFS_ERROR_NAMES[error], _drive); + LOG("%s: %s", _FATFS_ERROR_NAMES[error], _drive); return; } type = NONE; capacity = 0; - LOG("FAT unmount ok, drive=%s", _drive); + LOG("unmounted FAT: %s", _drive); } uint64_t FATProvider::getFreeSpace(void) { @@ -145,7 +145,7 @@ uint64_t FATProvider::getFreeSpace(void) { auto error = f_getfree(_drive, &count, &dummy); if (error) { - LOG("%s, drive=%s", _FATFS_ERROR_NAMES[error], _drive); + LOG("%s: %s", _FATFS_ERROR_NAMES[error], _drive); return 0; } @@ -169,7 +169,7 @@ bool FATProvider::getFileInfo(FileInfo &output, const char *path) { auto error = f_stat(path, &info); if (error) { - LOG("%s, drive=%s", _FATFS_ERROR_NAMES[error], _drive); + LOG("%s: %s%s", _FATFS_ERROR_NAMES[error], _drive, path); return false; } @@ -211,7 +211,7 @@ bool FATProvider::getFileFragments( _fileError: f_close(&fd); _openError: - LOG("%s, drive=%s", _FATFS_ERROR_NAMES[error], _drive); + LOG("%s, %s%s", _FATFS_ERROR_NAMES[error], _drive, path); return false; } @@ -223,7 +223,7 @@ Directory *FATProvider::openDirectory(const char *path) { auto error = f_opendir(&(dir->_fd), path); if (error) { - LOG("%s, drive=%s", _FATFS_ERROR_NAMES[error], _drive); + LOG("%s: %s%s", _FATFS_ERROR_NAMES[error], _drive, path); delete dir; return nullptr; } @@ -238,7 +238,7 @@ bool FATProvider::createDirectory(const char *path) { auto error = f_mkdir(path); if (error) { - LOG("%s, drive=%s", _FATFS_ERROR_NAMES[error], _drive); + LOG("%s: %s%s", _FATFS_ERROR_NAMES[error], _drive, path); return false; } @@ -253,7 +253,7 @@ File *FATProvider::openFile(const char *path, uint32_t flags) { auto error = f_open(&(_file->_fd), path, uint8_t(flags)); if (error) { - LOG("%s, drive=%s", _FATFS_ERROR_NAMES[error], _drive); + LOG("%s: %s%s", _FATFS_ERROR_NAMES[error], _drive, path); delete _file; return nullptr; } diff --git a/src/common/filemisc.cpp b/src/common/filemisc.cpp index 7881328..d2dedcd 100644 --- a/src/common/filemisc.cpp +++ b/src/common/filemisc.cpp @@ -22,7 +22,7 @@ size_t HostFile::read(void *output, size_t length) { int actualLength = pcdrvRead(_fd, output, length); if (actualLength < 0) { - LOG("PCDRV error, code=%d, file=0x%08x", actualLength, this); + LOG("PCDRV error %d, fd=%d", actualLength, _fd); return 0; } @@ -33,7 +33,7 @@ size_t HostFile::write(const void *input, size_t length) { int actualLength = pcdrvWrite(_fd, input, length); if (actualLength < 0) { - LOG("PCDRV error, code=%d, file=0x%08x", actualLength, this); + LOG("PCDRV error %d, fd=%d", actualLength, _fd); return 0; } @@ -44,7 +44,7 @@ uint64_t HostFile::seek(uint64_t offset) { int actualOffset = pcdrvSeek(_fd, int(offset), PCDRV_SEEK_SET); if (actualOffset < 0) { - LOG("PCDRV error, code=%d, file=0x%08x", actualOffset, this); + LOG("PCDRV error %d, fd=%d", actualOffset, _fd); return 0; } @@ -55,7 +55,7 @@ uint64_t HostFile::tell(void) const { int actualOffset = pcdrvSeek(_fd, 0, PCDRV_SEEK_CUR); if (actualOffset < 0) { - LOG("PCDRV error, code=%d, file=0x%08x", actualOffset, this); + LOG("PCDRV error %d, fd=%d", actualOffset, _fd); return 0; } @@ -84,7 +84,7 @@ bool HostProvider::init(void) { int error = pcdrvInit(); if (error < 0) { - LOG("PCDRV error, code=%d", error); + LOG("PCDRV error %d", error); return false; } @@ -98,7 +98,7 @@ bool HostProvider::getFileInfo(FileInfo &output, const char *path) { int fd = pcdrvFindFirst(path, &entry); if (fd < 0) { - LOG("PCDRV error, code=%d", fd); + LOG("PCDRV error %d: %s", fd, path); return false; } @@ -121,7 +121,7 @@ Directory *HostProvider::openDirectory(const char *path) { int fd = pcdrvFindFirst(pattern, &(dir->_entry)); if (fd < 0) { - LOG("PCDRV error, code=%d", fd); + LOG("PCDRV error %d: %s", fd, path); delete dir; return nullptr; } @@ -133,7 +133,7 @@ bool HostProvider::createDirectory(const char *path) { int error = pcdrvCreateDir(path); if (error < 0) { - LOG("PCDRV error, code=%d", error); + LOG("PCDRV error %d: %s", error, path); return false; } @@ -151,7 +151,7 @@ File *HostProvider::openFile(const char *path, uint32_t flags) { int fd = pcdrvOpen(path, mode); if (fd < 0) { - LOG("PCDRV error, code=%d", fd); + LOG("PCDRV error %d: %s", fd, path); return nullptr; } @@ -173,27 +173,27 @@ VFSMountPoint *VFSProvider::_getMounted(const char *path) { return ∓ } + LOG("unknown device: %s", path); return nullptr; } bool VFSProvider::mount(const char *prefix, Provider *provider, bool force) { + auto hash = util::hash(prefix, VFS_PREFIX_SEPARATOR); + for (auto &mp : _mountPoints) { if (force) { - if (mp.provider && (mp.provider != provider)) + if (mp.prefix && (mp.prefix != hash)) continue; } else { - if (mp.provider) + if (mp.prefix) continue; } - mp.prefix = util::hash(prefix, VFS_PREFIX_SEPARATOR); - mp.pathOffset = 0; + mp.prefix = hash; + mp.pathOffset = __builtin_strlen(prefix); mp.provider = provider; - while (prefix[mp.pathOffset] != VFS_PREFIX_SEPARATOR) - mp.pathOffset++; - - mp.pathOffset++; + LOG("mapped %s, dev=0x%08x", prefix, provider); return true; } @@ -210,6 +210,8 @@ bool VFSProvider::unmount(const char *prefix) { mp.prefix = 0; mp.pathOffset = 0; mp.provider = nullptr; + + LOG("unmapped %s", prefix); return true; } diff --git a/src/common/filezip.cpp b/src/common/filezip.cpp index 18a00d4..e9df935 100644 --- a/src/common/filezip.cpp +++ b/src/common/filezip.cpp @@ -116,14 +116,14 @@ bool ZIPProvider::init(File *file) { if (!mz_zip_reader_init(&_zip, file->size, _ZIP_FLAGS)) { auto error = mz_zip_get_last_error(&_zip); - LOG("%s, file=0x%08x", _MINIZ_ZIP_ERROR_NAMES[error], file); + LOG("%s", _MINIZ_ZIP_ERROR_NAMES[error]); return false; } type = ZIP_FILE; capacity = _zip.m_archive_size; - LOG("mounted ZIP, file=0x%08x", file); + LOG("mounted ZIP file"); return true; } @@ -134,14 +134,14 @@ bool ZIPProvider::init(const void *zipData, size_t length) { if (!mz_zip_reader_init_mem(&_zip, zipData, length, _ZIP_FLAGS)) { auto error = mz_zip_get_last_error(&_zip); - LOG("%s, ptr=0x%08x", _MINIZ_ZIP_ERROR_NAMES[error], zipData); + LOG("%s: 0x%08x", _MINIZ_ZIP_ERROR_NAMES[error], zipData); return false; } type = ZIP_MEMORY; capacity = _zip.m_archive_size; - LOG("mounted ZIP, ptr=0x%08x", zipData); + LOG("mounted ZIP: 0x%08x", zipData); return true; } @@ -200,7 +200,7 @@ size_t ZIPProvider::loadData(util::Data &output, const char *path) { if (!output.ptr) { auto error = mz_zip_get_last_error(&_zip); - LOG("%s, zip=0x%08x", _MINIZ_ZIP_ERROR_NAMES[error], this); + LOG("%s: %s", _MINIZ_ZIP_ERROR_NAMES[error], path); return 0; } @@ -214,7 +214,7 @@ size_t ZIPProvider::loadData(void *output, size_t length, const char *path) { if (!mz_zip_reader_extract_file_to_mem(&_zip, path, output, length, 0)) { auto error = mz_zip_get_last_error(&_zip); - LOG("%s, zip=0x%08x", _MINIZ_ZIP_ERROR_NAMES[error], this); + LOG("%s: %s", _MINIZ_ZIP_ERROR_NAMES[error], path); return 0; } diff --git a/src/common/ide.cpp b/src/common/ide.cpp index 683db07..d3473d3 100644 --- a/src/common/ide.cpp +++ b/src/common/ide.cpp @@ -22,7 +22,7 @@ namespace ide { -static constexpr int _STATUS_TIMEOUT = 30000000; +static constexpr int _WAIT_TIMEOUT = 30000000; static constexpr int _DETECT_TIMEOUT = 500000; static constexpr int _DMA_TIMEOUT = 10000; static constexpr int _SRST_DELAY = 5000; @@ -144,14 +144,16 @@ void Device::_setLBA(uint64_t lba, size_t count) { _write(CS0_CYLINDER_H, (lba >> 16) & 0xff); } -DeviceError Device::_waitForStatus(uint8_t mask, uint8_t value, int timeout) { +DeviceError Device::_waitForStatus( + uint8_t mask, uint8_t value, int timeout, bool ignoreErrors +) { if (!timeout) - timeout = _STATUS_TIMEOUT; + timeout = _WAIT_TIMEOUT; for (; timeout > 0; timeout -= 10) { uint8_t status = _read(CS0_STATUS); - if (status & CS0_STATUS_ERR) { + if (!ignoreErrors && (status & CS0_STATUS_ERR)) { LOG( "IDE error, stat=0x%02x, err=0x%02x", _read(CS0_STATUS), _read(CS0_ERROR) @@ -160,6 +162,7 @@ DeviceError Device::_waitForStatus(uint8_t mask, uint8_t value, int timeout) { _write(CS0_COMMAND, ATA_DEVICE_RESET); return DRIVE_ERROR; } + if ((status & mask) == value) return NO_ERROR; @@ -178,8 +181,12 @@ DeviceError Device::_waitForStatus(uint8_t mask, uint8_t value, int timeout) { return STATUS_TIMEOUT; } -DeviceError Device::_command(uint8_t cmd, uint8_t status, int timeout) { - auto error = _waitForStatus(CS0_STATUS_BSY | status, status, timeout); +DeviceError Device::_command( + uint8_t cmd, uint8_t status, int timeout, bool ignoreErrors +) { + auto error = _waitForStatus( + CS0_STATUS_BSY | status, status, timeout, ignoreErrors + ); if (error) return error; @@ -479,41 +486,47 @@ DeviceError Device::atapiPacket(const Packet &packet, size_t transferLength) { auto error = _command(ATA_PACKET, 0); - if (error) - return error; + if (!error) + error = _writePIO(&packet, (flags & DEVICE_HAS_PACKET16) ? 16 : 12); + if (!error) + return _waitForStatus(CS0_STATUS_BSY, 0); - error = _writePIO(&packet, (flags & DEVICE_HAS_PACKET16) ? 16 : 12); - - if (error) - return error; - - return _waitForStatus(CS0_STATUS_BSY, 0); + return atapiPoll(); } DeviceError Device::atapiPoll(void) { - Packet packet; - int senseKey = -1; + Packet packet; + SenseData data; packet.setRequestSense(); - if (!atapiPacket(packet)) { - SenseData data; + // If an error occurs, the error flag in the status register will be set but + // the drive will still accept a request sense command. + auto error = _command(ATA_PACKET, 0, 0, true); - if (!_readPIO(&data, sizeof(data))) { - senseKey = data.senseKey & 15; - LOG( - "key=0x%02x, asc=0x%02x, ascq=0x%02x", data.senseKey, data.asc, - data.ascQualifier - ); - } + if (!error) + error = _writePIO(&packet, (flags & DEVICE_HAS_PACKET16) ? 16 : 12); + if (!error) + error = _waitForStatus(CS0_STATUS_BSY, 0); + if (!error) + error = _readPIO(&data, sizeof(data)); + + int senseKey; + + if (error) { + // If the request sense command fails, fall back to reading the sense + // key from the IDE error register. + senseKey = (_read(CS0_ERROR) >> 4) & 15; + LOG("request sense failed"); + } else { + senseKey = data.senseKey & 15; + LOG( + "key=0x%02x, asc=0x%02x, ascq=0x%02x", data.senseKey, data.asc, + data.ascQualifier + ); } - // If the request sense command fails, fall back to reading the sense key - // from the IDE error register. - if (senseKey < 0) - senseKey = (_read(CS0_ERROR) >> 4) & 15; - - LOG("%s, key=%d", _SENSE_KEY_NAMES[senseKey], senseKey); + LOG("%s (%d)", _SENSE_KEY_NAMES[senseKey], senseKey); switch (senseKey) { case SENSE_KEY_NO_SENSE: diff --git a/src/common/ide.hpp b/src/common/ide.hpp index 686df4b..3edc896 100644 --- a/src/common/ide.hpp +++ b/src/common/ide.hpp @@ -378,8 +378,12 @@ private: } void _setLBA(uint64_t lba, size_t count); - DeviceError _waitForStatus(uint8_t mask, uint8_t value, int timeout = 0); - DeviceError _command(uint8_t cmd, uint8_t status, int timeout = 0); + DeviceError _waitForStatus( + uint8_t mask, uint8_t value, int timeout = 0, bool ignoreErrors = false + ); + DeviceError _command( + uint8_t cmd, uint8_t status, int timeout = 0, bool ignoreErrors = false + ); DeviceError _detectDrive(void); DeviceError _readPIO(void *data, size_t length, int timeout = 0); diff --git a/src/common/io.cpp b/src/common/io.cpp index 0717329..3d7af18 100644 --- a/src/common/io.cpp +++ b/src/common/io.cpp @@ -12,14 +12,6 @@ namespace io { uint16_t _bankSwitchReg, _cartOutputReg, _miscOutputReg; void init(void) { - _bankSwitchReg = 0; - _cartOutputReg = 0; - _miscOutputReg = 0 - | SYS573_MISC_OUT_ADC_MOSI - | SYS573_MISC_OUT_ADC_CS - | SYS573_MISC_OUT_ADC_SCK - | SYS573_MISC_OUT_JVS_RESET; - // Remapping the base address is required in order for IDE DMA to work // properly, as the BIU will output it over the address lines during a DMA // transfer. It does not affect non-DMA access since the BIU will replace @@ -39,11 +31,29 @@ void init(void) { | ( 4 << 24) // DMA read/write delay | BIU_CTRL_DMA_DELAY; - SYS573_WATCHDOG = 0; + // Revision D of the main board has footprints for either eight 8-bit RAM + // chips wired as two 32-bit banks, or two 16-bit chips wired as a single + // bank. Normally the kernel takes care of setting up the memory controller + // appropriately, but this makes sure the configuration is correct if e.g. + // the tool is booted through OpenBIOS instead. + DRAM_CTRL = isDualBankRAM() ? 0x0c80 : 0x4788; + + _bankSwitchReg = 0; + _cartOutputReg = 0; + _miscOutputReg = 0 + | SYS573_MISC_OUT_ADC_MOSI + | SYS573_MISC_OUT_ADC_CS + | SYS573_MISC_OUT_ADC_SCK + | SYS573_MISC_OUT_JVS_RESET; + SYS573_BANK_CTRL = _bankSwitchReg; SYS573_CART_OUT = _cartOutputReg; SYS573_MISC_OUT = _miscOutputReg; + clearWatchdog(); +} + +void initIOBoard(void) { // Some of the digital I/O board's light outputs are controlled by the FPGA // and cannot be turned off until the FPGA is initialized. if (isDigitalIOPresent()) { diff --git a/src/common/io.hpp b/src/common/io.hpp index e091af4..d8ea135 100644 --- a/src/common/io.hpp +++ b/src/common/io.hpp @@ -40,7 +40,7 @@ enum JAMMAInput : uint32_t { // SYS573_JAMMA_EXT2 JAMMA_P2_BUTTON4 = 1 << 20, JAMMA_P2_BUTTON5 = 1 << 21, - JAMMA_UNKNOWN = 1 << 22, + JAMMA_RAM_LAYOUT = 1 << 22, JAMMA_P2_BUTTON6 = 1 << 23, // SYS573_MISC_IN @@ -72,7 +72,7 @@ enum MiscOutputPin { MISC_AMP_ENABLE = 5, MISC_CDDA_ENABLE = 6, MISC_SPU_ENABLE = 7, - MISC_JVS_STAT = 8 + MISC_JVS_RESET = 8 }; /* Inputs */ @@ -81,6 +81,10 @@ static inline void clearWatchdog(void) { SYS573_WATCHDOG = 0; } +static inline bool isDualBankRAM(void) { + return (SYS573_JAMMA_EXT2 >> 10) & 1; +} + static inline bool getDIPSwitch(int bit) { return !((SYS573_DIP_CART >> bit) & 1); } @@ -159,6 +163,7 @@ static inline void setDIO1Wire(bool value) { /* Other APIs */ void init(void); +void initIOBoard(void); uint32_t getJAMMAInputs(void); void getRTCTime(util::Date &output); void setRTCTime(const util::Date &value, bool stop = false); diff --git a/src/main/app/miscworkers.cpp b/src/main/app/miscworkers.cpp index dbb9124..31fb737 100644 --- a/src/main/app/miscworkers.cpp +++ b/src/main/app/miscworkers.cpp @@ -10,13 +10,13 @@ #include "ps1/system.h" static const char *const _AUTOBOOT_PATHS[][2]{ - { "hdd:/noboot.txt", "hdd:/psx.exe" }, { "cdrom:/noboot.txt", "cdrom:/psx.exe" }, { "cdrom:/noboot.txt", "cdrom:/qsy.dxd" }, { "cdrom:/noboot.txt", "cdrom:/ssw.bxf" }, { "cdrom:/noboot.txt", "cdrom:/tsv.axg" }, { "cdrom:/noboot.txt", "cdrom:/gse.nxx" }, - { "cdrom:/noboot.txt", "cdrom:/nse.gxx" } + { "cdrom:/noboot.txt", "cdrom:/nse.gxx" }, + { "hdd:/noboot.txt", "hdd:/psx.exe" } }; bool App::_ideInitWorker(void) { diff --git a/src/main/app/romactions.cpp b/src/main/app/romactions.cpp index 4732be4..200ae83 100644 --- a/src/main/app/romactions.cpp +++ b/src/main/app/romactions.cpp @@ -185,6 +185,7 @@ static const Action _ACTIONS[]{ .prompt = "StorageActionsScreen.resetFlashHeader.prompt"_h, .region = rom::flash, .target = &StorageActionsScreen::resetFlashHeader +#if 0 }, { .name = "StorageActionsScreen.matchFlashHeader.name"_h, .prompt = "StorageActionsScreen.matchFlashHeader.prompt"_h, @@ -195,6 +196,7 @@ static const Action _ACTIONS[]{ .prompt = "StorageActionsScreen.editFlashHeader.prompt"_h, .region = rom::flash, .target = &StorageActionsScreen::editFlashHeader +#endif } }; diff --git a/src/main/main.cpp b/src/main/main.cpp index 0622d97..b465706 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -14,6 +14,7 @@ int main(int argc, const char **argv) { gpu::init(); spu::init(); io::init(); + io::initIOBoard(); util::initZipCRC32(); args::MainArgs args;