mirror of
https://github.com/spicyjpeg/573in1.git
synced 2025-01-22 19:52:05 +01:00
Fix BIOS ROM crash and ATAPI error polling
This commit is contained in:
parent
7702ef2258
commit
818ef7bdf1
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -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' }}
|
||||
|
@ -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(
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
@ -94,12 +107,13 @@ bool ISO9660File::_loadSector(uint32_t lba) {
|
||||
|
||||
size_t ISO9660File::read(void *output, size_t length) {
|
||||
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<uintptr_t>(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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 error;
|
||||
|
||||
if (!error)
|
||||
return _waitForStatus(CS0_STATUS_BSY, 0);
|
||||
|
||||
return atapiPoll();
|
||||
}
|
||||
|
||||
DeviceError Device::atapiPoll(void) {
|
||||
Packet packet;
|
||||
int senseKey = -1;
|
||||
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))) {
|
||||
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:
|
||||
|
@ -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);
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -14,6 +14,7 @@ int main(int argc, const char **argv) {
|
||||
gpu::init();
|
||||
spu::init();
|
||||
io::init();
|
||||
io::initIOBoard();
|
||||
util::initZipCRC32();
|
||||
|
||||
args::MainArgs args;
|
||||
|
Loading…
x
Reference in New Issue
Block a user