aboutsummaryrefslogtreecommitdiff
path: root/libpsn00b/psxcd
diff options
context:
space:
mode:
authorJohn Wilbert M. Villamor <lameguy64@gmail.com>2020-09-19 20:43:05 +0800
committerJohn Wilbert M. Villamor <lameguy64@gmail.com>2020-09-19 20:43:05 +0800
commit9f4891f95070c66ea9f1aba99d72724d4ab24e5a (patch)
tree723e3ef2118a3d1a9e6dafa811ed1b8b1bc9196e /libpsn00b/psxcd
parent6762c39551ded059450d17d8bb0cb80642c8aaab (diff)
downloadpsn00bsdk-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.s35
-rw-r--r--libpsn00b/psxcd/cdgetsector.s16
-rw-r--r--libpsn00b/psxcd/isofs.c400
-rw-r--r--libpsn00b/psxcd/isofs.h149
-rw-r--r--libpsn00b/psxcd/makefile34
-rw-r--r--libpsn00b/psxcd/psxcd.c8
-rw-r--r--libpsn00b/psxcd/psxcd_asm.s76
-rw-r--r--libpsn00b/psxcd/readme.txt7
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