diff options
| author | John Wilbert M. Villamor <lameguy64@gmail.com> | 2020-09-19 20:43:05 +0800 |
|---|---|---|
| committer | John Wilbert M. Villamor <lameguy64@gmail.com> | 2020-09-19 20:43:05 +0800 |
| commit | 9f4891f95070c66ea9f1aba99d72724d4ab24e5a (patch) | |
| tree | 723e3ef2118a3d1a9e6dafa811ed1b8b1bc9196e /libpsn00b/psxcd | |
| parent | 6762c39551ded059450d17d8bb0cb80642c8aaab (diff) | |
| download | psn00bsdk-9f4891f95070c66ea9f1aba99d72724d4ab24e5a.tar.gz | |
Revised makefiles, added strtok(), command line arguments, SetHeapSize(), moved ISR and callback system to psxetc, moved debug font to psxgpu, fixed CD-ROM library crashing on PSIO, fixed interrupt callback setup to fix crashing on ResetGraph()
Diffstat (limited to 'libpsn00b/psxcd')
| -rw-r--r-- | libpsn00b/psxcd/_cd_control.s | 35 | ||||
| -rw-r--r-- | libpsn00b/psxcd/cdgetsector.s | 16 | ||||
| -rw-r--r-- | libpsn00b/psxcd/isofs.c | 400 | ||||
| -rw-r--r-- | libpsn00b/psxcd/isofs.h | 149 | ||||
| -rw-r--r-- | libpsn00b/psxcd/makefile | 34 | ||||
| -rw-r--r-- | libpsn00b/psxcd/psxcd.c | 8 | ||||
| -rw-r--r-- | libpsn00b/psxcd/psxcd_asm.s | 76 | ||||
| -rw-r--r-- | libpsn00b/psxcd/readme.txt | 7 |
8 files changed, 480 insertions, 245 deletions
diff --git a/libpsn00b/psxcd/_cd_control.s b/libpsn00b/psxcd/_cd_control.s index 7f69266..c4153ff 100644 --- a/libpsn00b/psxcd/_cd_control.s +++ b/libpsn00b/psxcd/_cd_control.s @@ -15,6 +15,24 @@ _cd_control: # a1 - pointer to parameters # a2 - length of parameters + addiu $sp, -16 + sw $ra, 0($sp) + sw $a0, 4($sp) + sw $a1, 8($sp) + sw $a2, 12($sp) + +# move $a3, $a2 # Debug +# move $a2, $a1 +# move $a1, $a0 +# la $a0, _cd_control_msg +# jal printf +# addiu $sp, -16 +# addiu $sp, 16 + + lw $a0, 4($sp) + lw $a1, 8($sp) + lw $a2, 12($sp) + li $v0, 1 # Set acknowledge wait flag la $v1, _cd_ack_wait sb $v0, 0($v1) @@ -80,6 +98,15 @@ _cd_control: li $v0, 0x40 sb $v0, CD_REG3($v1) +#.Lflush_response: # Flush response FIFO +# lbu $v0, CD_REG1($v1) +# nop +# lbu $v0, CD_REG0($v1) +# nop +# andi $v0, 0x20 +# beqz $v0, .Lflush_response +# nop + .Lcmd_wait: # Wait for CD to become ready for commands lbu $v0, CD_REG0($v1) nop @@ -104,6 +131,14 @@ _cd_control: sb $0 , CD_REG0($v1) # Feed command value sb $a0, CD_REG1($v1) + lw $ra, 0($sp) + addiu $sp, 16 jr $ra nop + + +#.section .data + +#_cd_control_msg: +# .asciiz "CdControl(%d, %x, %d)\n"
\ No newline at end of file diff --git a/libpsn00b/psxcd/cdgetsector.s b/libpsn00b/psxcd/cdgetsector.s index 70039bf..9af3543 100644 --- a/libpsn00b/psxcd/cdgetsector.s +++ b/libpsn00b/psxcd/cdgetsector.s @@ -10,12 +10,12 @@ CdGetSector: lui $a2, IOBASE -.Lwait_fifo: - lbu $v0, CD_REG0($a2) - nop - andi $v0, 0x40 - beqz $v0, .Lwait_fifo - nop +#.Lwait_fifo: # Probably redundant as the BIOS CD-ROM +# lbu $v0, CD_REG0($a2) # routines do not not wait for this +# nop +# andi $v0, 0x40 +# beqz $v0, .Lwait_fifo +# nop lui $v0, 0x1 srl $a1, 2 @@ -27,11 +27,13 @@ CdGetSector: sw $v0, D3_CHCR($a2) nop nop -.Ldma_wait: + +.Ldma_wait: # Ensure DMA transfer has completed lw $v0, D3_CHCR($a2) nop srl $v0, 24 andi $v0, 0x1 + bnez $v0, .Ldma_wait nop diff --git a/libpsn00b/psxcd/isofs.c b/libpsn00b/psxcd/isofs.c index 149f746..11dba6c 100644 --- a/libpsn00b/psxcd/isofs.c +++ b/libpsn00b/psxcd/isofs.c @@ -4,152 +4,11 @@ #include <psxgpu.h> #include <psxsio.h> #include "psxcd.h" +#include "isofs.h" // Uncommend to enable debug output //#define DEBUG -#pragma pack(push, 1) - -/// Structure of a double-endian unsigned short word -typedef struct ISO_USHORT_PAIR -{ - unsigned short lsb; /// LSB format 16-bit word - unsigned short msb; /// MSB format 16-bit word -} ISO_USHORT_PAIR; - -/// Structure of a double-endian unsigned int word -typedef struct ISO_UINT_PAIR -{ - unsigned int lsb; /// LSB format 32-bit word - unsigned int msb; /// MSB format 32-bit word -} ISO_UINT_PAIR; - -/// ISO descriptor header structure -typedef struct ISO_DESCRIPTOR_HEADER -{ - unsigned char type; /// Volume descriptor type (1 is descriptor, 255 is descriptor terminator) - char id[5]; /// Volume descriptor ID (always CD001) - unsigned short version; /// Volume descriptor version (always 0x01) -} ISO_DESCRIPTOR_HEADER; - -/// Structure of a date stamp for ISO_DIR_ENTRY structure -typedef struct ISO_DATESTAMP -{ - unsigned char year; /// number of years since 1900 - unsigned char month; /// month, where 1=January, 2=February, etc. - unsigned char day; /// day of month, in the range from 1 to 31 - unsigned char hour; /// hour, in the range from 0 to 23 - unsigned char minute; /// minute, in the range from 0 to 59 - unsigned char second; /// Second, in the range from 0 to 59 - unsigned char GMToffs; /// Greenwich Mean Time offset -} ISO_DATESTAMP; - -/// Structure of an ISO path table entry (specifically for the cd::IsoReader class) -typedef struct ISO_PATHTABLE_ENTRY -{ - unsigned char nameLength; /// Name length (or 1 for the root directory) - unsigned char extLength; /// Number of sectors in extended attribute record - unsigned int dirOffs; /// Number of the first sector in the directory, as a double word - unsigned short dirLevel; /// Index of the directory record's parent directory - /// If nameLength is odd numbered, a padding byte will be present after the identifier text. -} ISO_PATHTABLE_ENTRY; - -typedef struct ISO_DIR_ENTRY -{ - unsigned char entryLength; // Directory entry length (variable, use for parsing through entries) - unsigned char extLength; // Extended entry data length (always 0) - ISO_UINT_PAIR entryOffs; // Points to the LBA of the file/directory entry - ISO_UINT_PAIR entrySize; // Size of the file/directory entry - ISO_DATESTAMP entryDate; // Date & time stamp of entry - unsigned char flags; // File flags (0x02 for directories, 0x00 for files) - unsigned char fileUnitSize; // Unit size (usually 0 even with Form 2 files such as STR/XA) - unsigned char interleaveGapSize; // Interleave gap size (usually 0 even with Form 2 files such as STR/XA) - ISO_USHORT_PAIR volSeqNum; // Volume sequence number (always 1) - unsigned char identifierLen; // Identifier (file/directory name) length in bytes -} ISO_DIR_ENTRY; - -typedef struct ISO_ROOTDIR_HEADER -{ - unsigned char entryLength; // Always 34 bytes - unsigned char extLength; // Always 0 - ISO_UINT_PAIR entryOffs; // Should point to LBA 22 - ISO_UINT_PAIR entrySize; // Size of entry extent - ISO_DATESTAMP entryDate; // Record date and time - unsigned char flags; // File flags - unsigned char fileUnitSize; - unsigned char interleaveGapSize; - ISO_USHORT_PAIR volSeqNum; - unsigned char identifierLen; // 0x01 - unsigned char identifier; // 0x00 -} ISO_ROOTDIR_HEADER; - -// ISO descriptor structure -typedef struct ISO_DESCRIPTOR -{ - - // ISO descriptor header - ISO_DESCRIPTOR_HEADER header; - // System ID (always PLAYSTATION) - char systemID[32]; - // Volume ID (or label, can be blank or anything) - char volumeID[32]; - // Unused null bytes - unsigned char pad2[8]; - // Size of volume in sector units - ISO_UINT_PAIR volumeSize; - // Unused null bytes - unsigned char pad3[32]; - // Number of discs in this volume set (always 1 for single volume) - ISO_USHORT_PAIR volumeSetSize; - // Number of this disc in volume set (always 1 for single volume) - ISO_USHORT_PAIR volumeSeqNumber; - // Size of sector in bytes (always 2048 bytes) - ISO_USHORT_PAIR sectorSize; - // Path table size in bytes (applies to all the path tables) - ISO_UINT_PAIR pathTableSize; - // LBA to Type-L path table - unsigned int pathTable1Offs; - // LBA to optional Type-L path table (usually a copy of the primary path table) - unsigned int pathTable2Offs; - // LBA to Type-L path table but with MSB format values - unsigned int pathTable1MSBoffs; - // LBA to optional Type-L path table but with MSB format values (usually a copy of the main path table) - unsigned int pathTable2MSBoffs; - // Directory entry for the root directory (similar to a directory entry) - ISO_ROOTDIR_HEADER rootDirRecord; - // Volume set identifier (can be blank or anything) - char volumeSetIdentifier[128]; - // Publisher identifier (can be blank or anything) - char publisherIdentifier[128]; - // Data preparer identifier (can be blank or anything) - char dataPreparerIdentifier[128]; - // Application identifier (always PLAYSTATION) - char applicationIdentifier[128]; - // Copyright file in the file system identifier (can be blank or anything) - char copyrightFileIdentifier[37]; - // Abstract file in the file system identifier (can be blank or anything) - char abstractFileIdentifier[37]; - // Bibliographical file identifier in the file system (can be blank or anything) - char bibliographicFilelIdentifier[37]; - // Volume create date (in text format YYYYMMDDHHMMSSMMGG) - char volumeCreateDate[17]; - // Volume modify date (in text format YYYYMMDDHHMMSSMMGG) - char volumeModifyDate[17]; - // Volume expiry date (in text format YYYYMMDDHHMMSSMMGG) - char volumeExpiryDate[17]; - // Volume effective date (in text format YYYYMMDDHHMMSSMMGG) - char volumeEffeciveDate[17]; - // File structure version (always 1) - unsigned char fileStructVersion; - // Padding - unsigned char dummy0; - // Application specific data (says CD-XA001 at [141], the rest are null bytes) - unsigned char appData[512]; - // Padding - unsigned char pad4[653]; - -} ISO_DESCRIPTOR; - typedef struct _CdlDIR_INT { u_int _pos; @@ -157,10 +16,7 @@ typedef struct _CdlDIR_INT u_char* _dir; } CdlDIR_INT; -// Leave non-aligned structure packing -#pragma pack(pop) - -extern char _cd_media_changed; +extern int _cd_media_changed; static int _cd_iso_last_dir_lba; @@ -176,7 +32,37 @@ static int _CdReadIsoDescriptor(int session_offs) CdlLOC loc; ISO_DESCRIPTOR *descriptor; - // Seek to volume descriptor location + // Check if the lid had been opened + if( !_cd_media_changed ) + { + CdControl(CdlNop, 0, 0); + if( (CdStatus()&0x10) ) + { + // Check if lid is still open + CdControl(CdlNop, 0, 0); + if( (CdStatus()&0x10) ) + { +#ifdef DEBUG + printf("psxcd: Lid is still open.\n"); +#endif + _cd_iso_error = CdlIsoLidOpen; + return -1; + } + // Reparse the file system + _cd_media_changed = 1; + } + } + + if( !_cd_media_changed ) + { + return 0; + } + +#ifdef DEBUG + printf("psxcd: Parsing ISO file system.\n"); +#endif + + // Seek to volume descriptor CdIntToPos(16+session_offs, &loc); if( !CdControl(CdlSetloc, (u_char*)&loc, 0) ) { @@ -186,9 +72,17 @@ static int _CdReadIsoDescriptor(int session_offs) _cd_iso_error = CdlIsoSeekError; return -1; } + +#ifdef DEBUG + printf("psxcd: Set seek target.\n"); +#endif +#ifdef DEBUG + printf("psxcd: Read sectors.\n"); +#endif // Read volume descriptor CdRead(1, (u_int*)_cd_iso_descriptor_buff, CdlModeSpeed); + if( CdReadSync(0, 0) ) { #ifdef DEBUG @@ -198,13 +92,16 @@ static int _CdReadIsoDescriptor(int session_offs) return -1; } +#ifdef DEBUG + printf("psxcd: Read complete.\n"); +#endif // Verify if volume descriptor is present descriptor = (ISO_DESCRIPTOR*)_cd_iso_descriptor_buff; if( strncmp("CD001", descriptor->header.id, 5) ) { #ifdef DEBUG - printf("psxcd: Disc does not have a ISO9660 file system.\n"); + printf("psxcd: Disc does not contain a ISO9660 file system.\n"); #endif _cd_iso_error = CdlIsoInvalidFs; return -1; @@ -240,8 +137,10 @@ static int _CdReadIsoDescriptor(int session_offs) return -1; } - _cd_iso_last_dir_lba = 0; - _cd_iso_error = CdlIsoOkay; + _cd_iso_last_dir_lba = 0; + _cd_iso_error = CdlIsoOkay; + + _cd_media_changed = 0; return 0; } @@ -572,21 +471,21 @@ CdlFILE *CdSearchFile(CdlFILE *fp, const char *filename) ISO_DIR_ENTRY dir_entry; // Read ISO descriptor if changed flag is set - if( _cd_media_changed ) - { + //if( _cd_media_changed ) + //{ // Read ISO descriptor and path table - if( _CdReadIsoDescriptor(0) ) - { + if( _CdReadIsoDescriptor(0) ) + { #ifdef DEBUG - printf("psxcd: Could not read ISO file system.\n"); + printf("psxcd: Could not read ISO file system.\n"); #endif - return NULL; - } + return NULL; + } #ifdef DEBUG - printf("psxcd: ISO file system cache updated.\n"); + // printf("psxcd: ISO file system cache updated.\n"); #endif - _cd_media_changed = 0; - } + // _cd_media_changed = 0; + //} // Get number of directories in path table num_dirs = get_pathtable_entry(0, NULL, NULL); @@ -692,21 +591,21 @@ CdlDIR *CdOpenDir(const char* path) ISO_PATHTABLE_ENTRY tbl_entry; // Read ISO descriptor if changed flag is set - if( _cd_media_changed ) +// if( _cd_media_changed ) +// { + // Read ISO descriptor and path table + if( _CdReadIsoDescriptor( 0 ) ) { - // Read ISO descriptor and path table - if( _CdReadIsoDescriptor( 0 ) ) - { #ifdef DEBUG - printf( "psxcd: Could not read ISO file system.\n" ); + printf( "psxcd: Could not read ISO file system.\n" ); #endif - return NULL; - } + return NULL; + } #ifdef DEBUG - printf( "psxcd: ISO file system cache updated.\n" ); +// printf( "psxcd: ISO file system cache updated.\n" ); #endif - _cd_media_changed = 0; - } +// _cd_media_changed = 0; +// } num_dirs = get_pathtable_entry( 0, NULL, NULL ); @@ -775,10 +674,17 @@ int CdReadDir(CdlDIR *dir, CdlFILE* file) CdlDIR_INT* d_dir; ISO_DIR_ENTRY* dir_entry; + // Locks up in an infinite loop if directory record size is 6144 bytes + d_dir = (CdlDIR_INT*)dir; if( d_dir->_pos >= _cd_iso_directory_len ) return 0; + + // Some generated file systems have a premature NULL entry, consider this + // the end of the directory record + if( d_dir->_dir[d_dir->_pos] == 0 ) + return 0; dir_entry = (ISO_DIR_ENTRY*)(d_dir->_dir+d_dir->_pos); @@ -800,9 +706,17 @@ int CdReadDir(CdlDIR *dir, CdlFILE* file) CdIntToPos( dir_entry->entryOffs.lsb, &file->pos ); file->size = dir_entry->entrySize.lsb; + +#ifdef DEBUG + printf("dir_entry->entryLength = %d, ", dir_entry->entryLength); +#endif d_dir->_pos += dir_entry->entryLength; +#ifdef DEBUG + printf("d_dir->_pos = %d\n", d_dir->_pos); +#endif + // Check if padding is reached (end of record sector) if( d_dir->_dir[d_dir->_pos] == 0 ) { @@ -849,4 +763,148 @@ int CdGetVolumeLabel(char* label) label[i] = 0x00; return 0; -}
\ No newline at end of file +} + + +// Session load routine + +void _cd_control(unsigned char com, unsigned char *param, int plen); + +static volatile unsigned int _ready_oldcb; + +static volatile int _ses_scanfound; +static volatile int _ses_scancount; +static volatile int _ses_scancomplete; +//static volatile char _ses_scan_resultbuff[8]; +static volatile char *_ses_scanbuff; + +static void _scan_callback(int status, unsigned char *result) +{ + if( status == CdlDataReady ) + { + CdGetSector((void*)_ses_scanbuff, 2048); + + if( _ses_scanbuff[0] == 0x1 ) + { + if( strncmp((const char*)_ses_scanbuff+1, "CD001", 5) == 0 ) + { + _cd_control(CdlPause, 0, 0); + _ses_scancomplete = 1; + _ses_scanfound = 1; + return; + } + } + _ses_scancount++; + if( _ses_scancount >= 512 ) + { + _cd_control(CdlPause, 0, 0); + _ses_scancomplete = 1; + return; + } + } + + if( status == CdlDiskError ) + { + _cd_control(CdlPause, 0, 0); + _ses_scancomplete = 1; + } +} + +int CdLoadSession(int session) +{ + CdlLOC *loc; + unsigned int ready_oldcb; + char scanbuff[2048]; + char resultbuff[16]; + int i; + + // Seek to specified session +#ifdef DEBUG + printf("psxcd: CdLoadSession(): Seeking to session %d...\n", session); +#endif + CdControl(CdlSetsession, (unsigned char*)&session, + (unsigned char*)&resultbuff); + + if( CdSync(0, 0) == CdlDiskError ) + { +#ifdef DEBUG + printf("psxcd: CdLoadSession(): Session seek failed, " + "session does not exist.\n"); + printf("psxcd: CdLoadSession(): Restarting CD-ROM...\n"); +#endif + + // Restart CD-ROM on session seek failure + CdControl(CdlNop, 0, 0); + CdControl(CdlInit, 0, 0); + CdSync(0, 0); + + return -1; + } + + // Set search routine callback + ready_oldcb = CdReadyCallback(_scan_callback); + + _ses_scanfound = 0; + _ses_scancount = 0; + _ses_scancomplete = 0; + _ses_scanbuff = scanbuff; + + // Begin scan for an ISO volume descriptor +#ifdef DEBUG + printf("psxcd: CdLoadSession(): Scanning for ISO9660 volume descriptor.\n"); +#endif + i = CdlModeSpeed; + CdControl(CdlSetmode, (unsigned char*)&i, 0); + CdControl(CdlReadN, 0, (unsigned char*)resultbuff); + + // Wait until scan complete + while(!_ses_scancomplete); + + CdReadyCallback((void*)_ready_oldcb); + + if( !_ses_scanfound ) + { +#ifdef DEBUG + printf("psxcd: CdLoadSession(): Did not find volume descriptor.\n"); +#endif + _cd_iso_error = CdlIsoInvalidFs; + CdReadyCallback((CdlCB)ready_oldcb); + return -1; + } + + // Restore old callback if any + CdReadyCallback((CdlCB)ready_oldcb); + + // Wait until CD-ROM has completely stopped reading, to get a consistent + // fix of the CD-ROM pickup's current location + do + { + VSync(2); + CdControl(CdlNop, 0, 0); + } while(CdStatus()&0xE0); + + // Get location of volume descriptor + CdControl(CdlGetlocL, 0, (unsigned char*)resultbuff); + CdSync(0, 0); + + loc = (CdlLOC*)resultbuff; + +#ifdef DEBUG + printf("psxcd: CdLoadSession(): Session found in %02d:%02d:%02d (LBA=%d)\n", + btoi(loc->minute), btoi(loc->second), btoi(loc->sector), CdPosToInt(loc)); +#endif + + i = CdPosToInt(loc)-17; +#ifdef DEBUG + printf("psxcd: CdLoadSession(): Session starting at LBA=%d\n", i); +#endif + + _cd_media_changed = 1; + + if( _CdReadIsoDescriptor(i) ) + { + return -1; + } + + return 0; +} diff --git a/libpsn00b/psxcd/isofs.h b/libpsn00b/psxcd/isofs.h new file mode 100644 index 0000000..5c5bf36 --- /dev/null +++ b/libpsn00b/psxcd/isofs.h @@ -0,0 +1,149 @@ +#ifndef _ISOFS_H +#define _ISOFS_H + +#pragma pack(push, 1) + +/// Structure of a double-endian unsigned short word +typedef struct ISO_USHORT_PAIR +{ + unsigned short lsb; /// LSB format 16-bit word + unsigned short msb; /// MSB format 16-bit word +} ISO_USHORT_PAIR; + +/// Structure of a double-endian unsigned int word +typedef struct ISO_UINT_PAIR +{ + unsigned int lsb; /// LSB format 32-bit word + unsigned int msb; /// MSB format 32-bit word +} ISO_UINT_PAIR; + +/// ISO descriptor header structure +typedef struct ISO_DESCRIPTOR_HEADER +{ + unsigned char type; /// Volume descriptor type (1 is descriptor, 255 is descriptor terminator) + char id[5]; /// Volume descriptor ID (always CD001) + unsigned short version; /// Volume descriptor version (always 0x01) +} ISO_DESCRIPTOR_HEADER; + +/// Structure of a date stamp for ISO_DIR_ENTRY structure +typedef struct ISO_DATESTAMP +{ + unsigned char year; /// number of years since 1900 + unsigned char month; /// month, where 1=January, 2=February, etc. + unsigned char day; /// day of month, in the range from 1 to 31 + unsigned char hour; /// hour, in the range from 0 to 23 + unsigned char minute; /// minute, in the range from 0 to 59 + unsigned char second; /// Second, in the range from 0 to 59 + unsigned char GMToffs; /// Greenwich Mean Time offset +} ISO_DATESTAMP; + +/// Structure of an ISO path table entry (specifically for the cd::IsoReader class) +typedef struct ISO_PATHTABLE_ENTRY +{ + unsigned char nameLength; /// Name length (or 1 for the root directory) + unsigned char extLength; /// Number of sectors in extended attribute record + unsigned int dirOffs; /// Number of the first sector in the directory, as a double word + unsigned short dirLevel; /// Index of the directory record's parent directory + /// If nameLength is odd numbered, a padding byte will be present after the identifier text. +} ISO_PATHTABLE_ENTRY; + +typedef struct ISO_DIR_ENTRY +{ + unsigned char entryLength; // Directory entry length (variable, use for parsing through entries) + unsigned char extLength; // Extended entry data length (always 0) + ISO_UINT_PAIR entryOffs; // Points to the LBA of the file/directory entry + ISO_UINT_PAIR entrySize; // Size of the file/directory entry + ISO_DATESTAMP entryDate; // Date & time stamp of entry + unsigned char flags; // File flags (0x02 for directories, 0x00 for files) + unsigned char fileUnitSize; // Unit size (usually 0 even with Form 2 files such as STR/XA) + unsigned char interleaveGapSize; // Interleave gap size (usually 0 even with Form 2 files such as STR/XA) + ISO_USHORT_PAIR volSeqNum; // Volume sequence number (always 1) + unsigned char identifierLen; // Identifier (file/directory name) length in bytes +} ISO_DIR_ENTRY; + +typedef struct ISO_ROOTDIR_HEADER +{ + unsigned char entryLength; // Always 34 bytes + unsigned char extLength; // Always 0 + ISO_UINT_PAIR entryOffs; // Should point to LBA 22 + ISO_UINT_PAIR entrySize; // Size of entry extent + ISO_DATESTAMP entryDate; // Record date and time + unsigned char flags; // File flags + unsigned char fileUnitSize; + unsigned char interleaveGapSize; + ISO_USHORT_PAIR volSeqNum; + unsigned char identifierLen; // 0x01 + unsigned char identifier; // 0x00 +} ISO_ROOTDIR_HEADER; + +// ISO descriptor structure +typedef struct ISO_DESCRIPTOR +{ + + // ISO descriptor header + ISO_DESCRIPTOR_HEADER header; + // System ID (always PLAYSTATION) + char systemID[32]; + // Volume ID (or label, can be blank or anything) + char volumeID[32]; + // Unused null bytes + unsigned char pad2[8]; + // Size of volume in sector units + ISO_UINT_PAIR volumeSize; + // Unused null bytes + unsigned char pad3[32]; + // Number of discs in this volume set (always 1 for single volume) + ISO_USHORT_PAIR volumeSetSize; + // Number of this disc in volume set (always 1 for single volume) + ISO_USHORT_PAIR volumeSeqNumber; + // Size of sector in bytes (always 2048 bytes) + ISO_USHORT_PAIR sectorSize; + // Path table size in bytes (applies to all the path tables) + ISO_UINT_PAIR pathTableSize; + // LBA to Type-L path table + unsigned int pathTable1Offs; + // LBA to optional Type-L path table (usually a copy of the primary path table) + unsigned int pathTable2Offs; + // LBA to Type-L path table but with MSB format values + unsigned int pathTable1MSBoffs; + // LBA to optional Type-L path table but with MSB format values (usually a copy of the main path table) + unsigned int pathTable2MSBoffs; + // Directory entry for the root directory (similar to a directory entry) + ISO_ROOTDIR_HEADER rootDirRecord; + // Volume set identifier (can be blank or anything) + char volumeSetIdentifier[128]; + // Publisher identifier (can be blank or anything) + char publisherIdentifier[128]; + // Data preparer identifier (can be blank or anything) + char dataPreparerIdentifier[128]; + // Application identifier (always PLAYSTATION) + char applicationIdentifier[128]; + // Copyright file in the file system identifier (can be blank or anything) + char copyrightFileIdentifier[37]; + // Abstract file in the file system identifier (can be blank or anything) + char abstractFileIdentifier[37]; + // Bibliographical file identifier in the file system (can be blank or anything) + char bibliographicFilelIdentifier[37]; + // Volume create date (in text format YYYYMMDDHHMMSSMMGG) + char volumeCreateDate[17]; + // Volume modify date (in text format YYYYMMDDHHMMSSMMGG) + char volumeModifyDate[17]; + // Volume expiry date (in text format YYYYMMDDHHMMSSMMGG) + char volumeExpiryDate[17]; + // Volume effective date (in text format YYYYMMDDHHMMSSMMGG) + char volumeEffeciveDate[17]; + // File structure version (always 1) + unsigned char fileStructVersion; + // Padding + unsigned char dummy0; + // Application specific data (says CD-XA001 at [141], the rest are null bytes) + unsigned char appData[512]; + // Padding + unsigned char pad4[653]; + +} ISO_DESCRIPTOR; + +// Leave non-aligned structure packing +#pragma pack(pop) + +#endif /* _ISOFS_H */
\ No newline at end of file diff --git a/libpsn00b/psxcd/makefile b/libpsn00b/psxcd/makefile index 87466b3..1886ace 100644 --- a/libpsn00b/psxcd/makefile +++ b/libpsn00b/psxcd/makefile @@ -1,24 +1,26 @@ # Run using make (Linux) or gmake (BSD) # Part of the PSn00bSDK Project -# 2019 Lameguy64 / Meido-Tek Productions +# 2019 - 2020 Lameguy64 / Meido-Tek Productions -include ../common.mk +include ../../psn00bsdk-setup.mk -TARGET = ../libpsxcd.a +TARGET = libpsxcd.a -CFILES = $(notdir $(wildcard ./*.c)) -AFILES = $(notdir $(wildcard ./*.s)) -OFILES = $(addprefix build/,$(CFILES:.c=.o) $(AFILES:.s=.o)) +INCLUDE = -I../include -INCLUDE = -I../include +CFILES = $(notdir $(wildcard ./*.c)) +AFILES = $(notdir $(wildcard ./*.s)) +OFILES = $(addprefix build/,$(CFILES:.c=.o) $(AFILES:.s=.o)) -CFLAGS = -g -msoft-float -fno-builtin -fdata-sections -ffunction-sections -Wa,--strip-local-absolute -AFLAGS = -g -msoft-float -Wa,--strip-local-absolute +CFLAGS = -g -msoft-float -fno-builtin -fdata-sections \ + -ffunction-sections -Wa,--strip-local-absolute +AFLAGS = -g -msoft-float -Wa,--strip-local-absolute -CC = $(PREFIX)gcc -AS = $(PREFIX)as -AR = $(PREFIX)ar -RANLIB = $(PREFIX)ranlib +ifndef PSN00BSDK_LIBS + +PSN00BSDK_LIBS = .. + +endif all: $(TARGET) @@ -34,5 +36,11 @@ build/%.o: %.s @mkdir -p $(dir $@) $(CC) $(AFLAGS) $(INCLUDE) -c $< -o $@ +install: +ifneq ($(PSN00BSDK_LIBS), "..") + @mkdir -p $(PSN00BSDK_LIBS) +endif + cp $(TARGET) $(PSN00BSDK_LIBS)/$(TARGET) + clean: rm -Rf build $(TARGET) diff --git a/libpsn00b/psxcd/psxcd.c b/libpsn00b/psxcd/psxcd.c index 76b6c08..76a8eba 100644 --- a/libpsn00b/psxcd/psxcd.c +++ b/libpsn00b/psxcd/psxcd.c @@ -17,7 +17,7 @@ volatile CdlLOC _cd_last_setloc; volatile unsigned int *_cd_last_read_addr; volatile int _cd_last_sector_count; -extern volatile char _cd_media_changed; +int _cd_media_changed; void _cd_init(void); void _cd_control(unsigned char com, unsigned char *param, int plen); @@ -62,6 +62,12 @@ int CdControl(unsigned char com, unsigned char *param, unsigned char *result) CdControlF(com, param); _cd_wait_ack(); + // Set media changed flag if lid had been opened + if( (CdStatus()&0x10) ) + { + _cd_media_changed = 1; + } + return 1; } diff --git a/libpsn00b/psxcd/psxcd_asm.s b/libpsn00b/psxcd/psxcd_asm.s index 0bfe5ca..1dbf542 100644 --- a/libpsn00b/psxcd/psxcd_asm.s +++ b/libpsn00b/psxcd/psxcd_asm.s @@ -15,6 +15,12 @@ _cd_init: nop lui $a3, IOBASE # Acknowledge all CD IRQs + + li $v0, 0x20943 # Set CD-ROM Delay/Size and common delay + sw $v0, SBUS_5($a3) + li $v0, 0x1325 + sw $v0, COM_DELAY($a3) + li $v0, 1 sb $v0, CD_REG0($a3) li $v0, 0x1f @@ -24,9 +30,6 @@ _cd_init: sb $0 , CD_REG0($a3) sb $0 , CD_REG3($a3) - li $v0, 0x1325 - sw $v0, COM_DELAY($a3) - la $a1, _cd_handler jal InterruptCallback li $a0, 2 @@ -76,29 +79,6 @@ _cd_init: jal ExitCriticalSection nop - #li $a0, 0x01 # GetStat - #jal _cd_control - #move $a2, $0 - #jal _cd_wait - #nop - - #li $a0, 0x0a # Init - #jal _cd_control - #move $a2, $0 - #jal _cd_wait - #nop - - #li $a0, 0x0c # Demute - #jal _cd_control - #move $a2, $0 - #jal _cd_wait - #nop - - #la $a0, _cd_init_msg - #jal printf - #addiu $sp, -16 - #addiu $sp, 16 - lw $ra, 0($sp) addiu $sp, 4 jr $ra @@ -153,7 +133,7 @@ _cd_handler: addiu $sp, -4 sw $ra, 0($sp) - lui $a3, IOBASE # Print out IRQ number + lui $a3, IOBASE # Get IRQ number li $v0, 1 sb $v0, CD_REG0($a3) @@ -167,6 +147,11 @@ _cd_handler: bne $v0, 0x1, .Lno_data nop + sb $0 , CD_REG0($a3) + lbu $v1, CD_REG0($a3) + sb $0 , CD_REG3($a3) + lbu $v1, CD_REG3($a3) + sb $0 , CD_REG0($a3) # Load data FIFO on INT1 li $v1, 0x80 sb $v1, CD_REG3($a3) @@ -189,6 +174,9 @@ _cd_handler: li $v1, 3 sw $v1, 0($0) + la $v1, _cd_last_int + lbu $v0, 0($v1) + beq $v0, 0x1, .Lirq_1 # Data ready nop beq $v0, 0x2, .Lirq_2 # Command finish @@ -371,17 +359,6 @@ _cd_fetch_result: .Lwrite_status: - andi $v1, $v0, 0x10 - - beqz $v1, .Lno_disc_change - nop - - la $v1, _cd_media_changed - addiu $a1, $0 , 1 - sw $a1, 0($v1) - -.Lno_disc_change: - sb $v0, 0($a0) .Lskip_status: @@ -394,23 +371,32 @@ _cd_fetch_result: sb $v0, 0($a0) addiu $a0, 1 + move $a1, $0 .Lread_futher_result: lbu $v0, CD_REG0($a3) nop andi $v0, 0x20 beqz $v0, .Lno_result + addu $a1, 1 + bge $a1, 7, .Lno_result # timeout (locks up here on PSIO) nop - lbu $v0, CD_REG1($a3) lbu $v1, CD_REG0($a3) sb $v0, 0($a0) - andi $v1, 0x20 + + andi $v1, 0x20 # when performing a CD-ROM read bnez $v1, .Lread_futher_result addiu $a0, 1 .Lno_result: +# lbu $v0, CD_REG0($a3) # Flush response FIFO +# nop +# andi $v0, 0x20 +# bnez $v0, .Lno_result +# lbu $v0, CD_REG1($a3) + jr $ra nop @@ -509,11 +495,7 @@ CdSyncCallback: .type psxcd_credits, @object psxgpu_credits: .ascii "psxcd library programs by Lameguy64\n" - .asciiz "2019 PSn00bSDK Project / Meido-Tek Productions\n" - -_cd_init_msg: -.asciiz "psxcd: Init OK\n" -.align 4 + .asciiz "2020 PSn00bSDK Project / Meido-Tek Productions\n" .comm _cd_last_cmd, 1, 1 .comm _cd_last_mode, 1, 1 @@ -523,9 +505,7 @@ _cd_init_msg: .comm _cd_status, 1, 1 .comm _cd_last_int, 1, 1 -.comm _cd_media_changed, 1, 1 - # Callback hooks .comm _cd_callback_int1_data, 4, 4 # Data IRQ callback -.comm _cd_callback_int4, 4, 4 # Autopause callback +.comm _cd_callback_int4, 4, 4 # Autopause callback .comm _cd_sync_cb, 4, 4 diff --git a/libpsn00b/psxcd/readme.txt b/libpsn00b/psxcd/readme.txt index a85fab5..64643ed 100644 --- a/libpsn00b/psxcd/readme.txt +++ b/libpsn00b/psxcd/readme.txt @@ -1,5 +1,5 @@ PSX CD-ROM library, part of PSn00bSDK -2019 Lameguy64 / Meido-Tek Productions +2020 Lameguy64 / Meido-Tek Productions Licensed under Mozilla Public License @@ -42,7 +42,4 @@ Todo list: * Data streaming functions (prefixed with St*) not yet implemented. Would require devising a PSn00bSDK equivalent of the STR file - format. - - * Original functions for querying directory contents in the file - system not yet implemented.
\ No newline at end of file + format.
\ No newline at end of file |
