aboutsummaryrefslogtreecommitdiff
path: root/libpsn00b/include
diff options
context:
space:
mode:
authorspicyjpeg <thatspicyjpeg@gmail.com>2022-10-30 17:19:56 +0100
committerspicyjpeg <thatspicyjpeg@gmail.com>2022-10-30 17:19:56 +0100
commit37d963f724113e45d15aa9b8ee86baa9c4362b8f (patch)
treed4d3374afd5e36e8580cc424ab2c63ee9e7d357c /libpsn00b/include
parent68daf6d338aba6e32e687d4151eaddc8735227b3 (diff)
downloadpsn00bsdk-37d963f724113e45d15aa9b8ee86baa9c4362b8f.tar.gz
Add inline docs to psxcd.h, psxetc.h, psxgte.h
Diffstat (limited to 'libpsn00b/include')
-rw-r--r--libpsn00b/include/inline_c.h173
-rw-r--r--libpsn00b/include/psxcd.h824
-rw-r--r--libpsn00b/include/psxetc.h152
-rw-r--r--libpsn00b/include/psxgte.h205
-rw-r--r--libpsn00b/include/psxpress.h158
-rw-r--r--libpsn00b/include/psxsio.h99
6 files changed, 1432 insertions, 179 deletions
diff --git a/libpsn00b/include/inline_c.h b/libpsn00b/include/inline_c.h
index c5eaa59..5facc1c 100644
--- a/libpsn00b/include/inline_c.h
+++ b/libpsn00b/include/inline_c.h
@@ -3,9 +3,17 @@
* (C) 2019 Lameguy64
* (C) 2021-2022 Soapy (tweaked by spicyjpeg)
*
- * This header is basically identical to Nugget's inline_n.h. All GTE commands
- * can be used right away without having to run DMPSX or any other tool on
- * object files.
+ * This header is basically identical to Nugget's inline_n.h.
+ */
+
+/**
+ * @file inline_c.h
+ * @brief Inline GTE macro header
+ *
+ * @details This header provides a set of macros for making use of GTE commands
+ * and registers from C or C++ code. Unlike the official SDK, all commands can
+ * be used right away without having to run any other post-processing tool on
+ * compiled object files.
*/
#ifndef _INLINE_C_H
@@ -13,7 +21,11 @@
/* GTE load macros */
-/* Load a SVECTOR (passed as a pointer) to GTE V0
+/**
+ * @brief Loads a single SVECTOR to GTE vector register V0
+ *
+ * @details Loads values from an SVECTOR struct to GTE data registers C2_VXY0
+ * and C2_VZ0.
*/
#define gte_ldv0( r0 ) __asm__ volatile ( \
"lwc2 $0, 0( %0 );" \
@@ -22,7 +34,11 @@
: "r"( r0 ) \
: "$t0" )
-/* Load a SVECTOR (passed as a pointer) to GTE V1
+/**
+ * @brief Loads a single SVECTOR to GTE vector register V1
+ *
+ * @details Loads values from an SVECTOR struct to GTE data registers C2_VXY1
+ * and C2_VZ1.
*/
#define gte_ldv1( r0 ) __asm__ volatile ( \
"lwc2 $2, 0( %0 );" \
@@ -31,7 +47,11 @@
: "r"( r0 ) \
: "$t0" )
-/* Load a SVECTOR (passed as a pointer) to GTE V2
+/**
+ * @brief Loads a single SVECTOR to GTE vector register V2
+ *
+ * @details Loads values from an SVECTOR struct to GTE data registers C2_VXY2
+ * and C2_VZ2.
*/
#define gte_ldv2( r0 ) __asm__ volatile ( \
"lwc2 $4, 0( %0 );" \
@@ -40,7 +60,11 @@
: "r"( r0 ) \
: "$t0" )
-/* Load three SVECTORs (passed as a pointer) to the GTE at once
+/**
+ * @brief Load three SVECTORs to GTE vector registers at once
+ *
+ * @details Loads values from three SVECTOR structs to GTE data registers
+ * C2_VXY0 and C2_VZ0, C2_VXY1 and C2_VZ1, C2_VXY2 and C2_VZ2 at once.
*/
#define gte_ldv3( r0, r1, r2 ) __asm__ volatile ( \
"lwc2 $0, 0( %0 );" \
@@ -88,6 +112,14 @@
: \
: "r"( r0 ) )
+/**
+ * @brief Load a CVECTOR to GTE register C2_RGBC
+ *
+ * @details Loads a CVECTOR value to GTE data register C2_RGBC. The primitive
+ * code (the last byte of a CVECTOR) is passed to the color FIFO registers when
+ * performing lighting compute operations, so it can be stored to the RGBC
+ * field of a primitive directly without any additional operation required.
+ */
#define gte_ldrgb( r0 ) __asm__ volatile ( \
"lwc2 $6 , 0( %0 );" \
: \
@@ -224,6 +256,12 @@
: "r"( r0 ) \
: "$12", "$13", "$14" )
+/**
+ * @brief Loads values to GTE registers C2_IR1-3
+ *
+ * @details Loads three 32-bit values to GTE data registers C2_IR1, C2_IR2 and
+ * C2_IR3.
+ */
#define gte_ldopv2( r0 ) __asm__ volatile ( \
"lwc2 $11, 8( %0 );" \
"lwc2 $9 , 0( %0 );" \
@@ -253,6 +291,14 @@
: \
: "r"( r0 ), "r"( r1 ), "r"( r2 ) )
+/**
+ * @brief Sets an RGB color value to the GTE
+ *
+ * @details Sets the specified RGB value to GTE control registers C2_RBK,
+ * C2_GBK and C2_BBK. This specifies the color value to use when a normal faces
+ * away from the direction of the light source. This can be considered as the
+ * ambient light color.
+ */
#define gte_SetBackColor( r0, r1, r2 ) __asm__ volatile ( \
"sll $t0, %0, 4;" \
"sll $t1, %1, 4;" \
@@ -282,6 +328,13 @@
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
: "$12", "$13", "$14" )
+/**
+ * @brief Sets the GTE screen offset
+ *
+ * @details Sets the values of the GTE screen offset which is applied to 2D
+ * projected coordinates when performing perspective transformation. The values
+ * are set to GTE control registers C2_OFX and C2_OFY.
+ */
#define gte_SetGeomOffset( r0, r1 ) __asm__ volatile ( \
"sll $t0, %0, 16;" \
"sll $t1, %1, 16;" \
@@ -291,6 +344,13 @@
: "r"( r0 ), "r"( r1 ) \
: "$t0", "$t1" )
+/**
+ * @brief Sets the distance of the projection plane
+ *
+ * @details Sets the specified value to GTE control register C2_H which
+ * determines the projection plane distance, otherwise known as the field of
+ * view.
+ */
#define gte_SetGeomScreen( r0 ) __asm__ volatile ( \
"ctc2 %0, $26;" \
: \
@@ -305,6 +365,12 @@
: "r"( r0 ) \
: "$12", "$13" )
+/**
+ * @brief Sets a 3x3 rotation matrix portion from a MATRIX to the GTE
+ *
+ * @details Sets the 3x3 rotation matrix coordinates from a MATRIX struct to
+ * GTE control registers C2_R11R12, C2_R13R21, C2_R22R23, C2_R31R32 and C2_R33.
+ */
#define gte_SetRotMatrix( r0 ) __asm__ volatile ( \
"lw $t0, 0( %0 );" \
"lw $t1, 4( %0 );" \
@@ -329,6 +395,17 @@
: "r"( r0 ) \
: "$12", "$13" )
+/**
+ * @brief Sets a 3x3 lighting matrix from a MATRIX to the GTE
+ *
+ * @details Sets the 3x3 lighting matrix coordinates from a MATRIX struct to
+ * GTE control registers C2_L11L12, C2_L13L21, C2_L22L23, C2_L31L32 and C2_L33.
+ *
+ * The lighting matrix is essentially a triplet of three light direction
+ * vectors. L11, L12 and L13 represents the X, Y and Z coordinates of light
+ * source 0 for example. Coordinates must be normalized to ensure correct
+ * results.
+ */
#define gte_SetLightMatrix( r0 ) __asm__ volatile ( \
"lw $t0, 0( %0 );" \
"lw $t1, 4( %0 );" \
@@ -353,6 +430,17 @@
: "r"( r0 ) \
: "$12", "$13" )
+/**
+ * @brief Sets a 3x3 color matrix from a MATRIX to the GTE
+ *
+ * @details Sets the 3x3 color matrix values from a MATRIX struct to GTE
+ * control registers C2_LR1LR2, C2_LR3LG1, C2_LG2LG3, C2_LB1LB2 and C2_LB3.
+ *
+ * The light color matrix is essentially a triplet of three RGB colors for each
+ * of the three light sources. LR1, LG1 and LB1 represents the R, G and B color
+ * values for light source 0 for example. Values are of range 0 to 4095, higher
+ * values will be saturated.
+ */
#define gte_SetColorMatrix( r0 ) __asm__ volatile ( \
"lw $t0, 0( %0 );" \
"lw $t1, 4( %0 );" \
@@ -368,6 +456,12 @@
: "r"( r0 ) \
: "$t2" )
+/**
+ * @brief Sets the translation portion of a MATRIX to the GTE
+ *
+ * @details Sets the translation coordinates from a MATRIX struct to GTE
+ * control registers C2_TRX, C2_TRY and C2_TRZ respectively.
+ */
#define gte_SetTransMatrix( r0 ) __asm__ volatile ( \
"lw $t0, 20( %0 );" \
"lw $t1, 24( %0 );" \
@@ -1044,11 +1138,39 @@
/* GTE operation macros */
+/**
+ * @brief Rotate, Translate and Perspective Single (15 cycles)
+ *
+ * @details Performs rotation, translation and perspective calculation of a
+ * single vertex. Divide overflows are simply saturated allowing for crude Z
+ * clipping. Check C2_FLAG to determine which overflow error has occurred
+ * during calculation.
+ *
+ * The following equation is performed when executing this GTE command:
+ *
+ * IR1 = MAC1 = (TRX*4096 + R11*VX0 + R12*VY0 + R13*VZ0) / 4096
+ * IR2 = MAC2 = (TRY*4096 + R21*VX0 + R22*VY0 + R23*VZ0) / 4096
+ * IR3 = MAC3 = (TRZ*4096 + R31*VX0 + R32*VY0 + R33*VZ0) / 4096
+ * SZ3 = MAC3
+ *
+ * MAC0 = (((H*131072/SZ3)+1)/2) * IR1 + OFX, SX2 = MAC0 / 65536
+ * MAC0 = (((H*131072/SZ3)+1)/2) * IR2 + OFY, SY2 = MAC0 / 65536
+ * MAC0 = (((H*131072/SZ3)+1)/2) * DQA + DQB, IR0 = MAC0 / 4096
+ */
#define gte_rtps() __asm__ volatile ( \
"nop;" \
"nop;" \
"cop2 0x0180001;" )
+/**
+ * @brief Rotate, Translate and Perspective Triple (23 cycles)
+ *
+ * @details Performs rotation, translation and perspective calculation of three
+ * vertices at once. The equation performed is the same as gte_rtps() only
+ * repeated three times for each vertex. The result of the first vertex is
+ * stored in GTE data register C2_SXY0, the second vector in C2_SXY1 then
+ * C2_SXY2.
+ */
#define gte_rtpt() __asm__ volatile ( \
"nop;" \
"nop;" \
@@ -1325,16 +1447,53 @@
"nop;" \
"cop2 0x0138041C;" )
+/**
+ * @brief Normal clipping (8 cycles)
+ *
+ * @details Computes the sign of three screen coordinates (C2_SXY0-3) used for
+ * backface culling. If the value of C2_MAC0 is negative, the coordinates are
+ * inverted and thus the triangle is back facing.
+ *
+ * The following equation is performed when executing this GTE command:
+ *
+ * MAC0 = SX0*SY1 + SX1*SY2 + SX2*SY0 - SX0*SY2 - SX1*SY0 - SX2*SY1
+ */
#define gte_nclip() __asm__ volatile ( \
"nop;" \
"nop;" \
"cop2 0x01400006;" )
+/**
+ * @brief Average screen Z result (5 cycles)
+ *
+ * @details Averages the values of GTE registers C2_SZ1, C2_SZ2 and C2_SZ3,
+ * multiplies it by C2_ZSF3 and divides the result by 0x1000 before storing to
+ * C2_OTZ. Used to compute the ordering table depth level for a three-vertex
+ * primitive.
+ *
+ * The following equation is performed when executing this GTE command:
+ *
+ * MAC0 = ZSF3 * (SZ1+SZ2+SZ3)
+ * OTZ = MAC0 / 4096
+ */
#define gte_avsz3() __asm__ volatile ( \
"nop;" \
"nop;" \
"cop2 0x0158002D;" )
+/**
+ * @brief Average screen Z result (6 cycles)
+ *
+ * @details Averages the values of GTE registers C2_SZ1, C2_SZ2, C2_SZ3 and
+ * C2_SZ4, multiplies it by C2_ZSF4 and divides the result by 0x1000 before
+ * storing to C2_OTZ. Used to compute the ordering table depth level for a
+ * four-vertex primitive.
+ *
+ * The following equation is performed when executing this GTE command:
+ *
+ * MAC0 = ZSF4 * (SZ1+SZ2+SZ3+SZ4)
+ * OTZ = MAC0 / 4096
+ */
#define gte_avsz4() __asm__ volatile ( \
"nop;" \
"nop;" \
diff --git a/libpsn00b/include/psxcd.h b/libpsn00b/include/psxcd.h
index bd89f53..8150703 100644
--- a/libpsn00b/include/psxcd.h
+++ b/libpsn00b/include/psxcd.h
@@ -3,174 +3,792 @@
* (C) 2019-2022 Lameguy64, spicyjpeg - MPL licensed
*/
+/**
+ * @file psxcd.h
+ * @brief CD-ROM library header
+ *
+ * @details The PSn00bSDK CD-ROM library provides facilities for using the
+ * CD-ROM hardware of the PS1. Unlike the CD-ROM library of the official SDK,
+ * psxcd is immune to the 30 file and directory limit and is capable of parsing
+ * directories containing as many files as the ISO9660 file system can support,
+ * unless the records are too large to be loaded into memory. However, to
+ * maintain compatibility with the PS1 BIOS, the root directory must not exceed
+ * the 30 file limit and the entire disc should contain no more than 45
+ * directories total.
+ *
+ * Whilst psxcd is not constrained by the 30 file per directory limit, it does
+ * not support Joliet CD-ROM extensions to support long file names. However, a
+ * library extension is considered for future development.
+ */
+
#ifndef __PSXCD_H
#define __PSXCD_H
#include <stdint.h>
-/*
- * CD-ROM control commands
- */
-#define CdlNop 0x01 /* a.k.a. Getstat */
-#define CdlSetloc 0x02
-#define CdlPlay 0x03
-#define CdlForward 0x04
-#define CdlBackward 0x05
-#define CdlReadN 0x06
-#define CdlStandby 0x07 /* a.k.a. MotorOn */
-#define CdlStop 0x08
-#define CdlPause 0x09
-#define CdlInit 0x0A
-#define CdlMute 0x0B
-#define CdlDemute 0x0C
-#define CdlSetfilter 0x0D
-#define CdlSetmode 0x0E
-#define CdlGetparam 0x0F
-#define CdlGetlocL 0x10
-#define CdlGetlocP 0x11
-#define CdlSetsession 0x12 /* ORIGINAL CODE */
-#define CdlGetTN 0x13
-#define CdlGetTD 0x14
-#define CdlSeekL 0x15
-#define CdlSeekP 0x16
-#define CdlTest 0x19 /* ORIGINAL CODE */
-#define CdlReadS 0x1B
+/* Enum definitions */
-/*
- * CD-ROM status bits
- */
-#define CdlStatError 0x01
-#define CdlStatStandby 0x02
-#define CdlStatSeekError 0x04
-#define CdlStatIdError 0x08 /* ORIGINAL CODE */
-#define CdlStatShellOpen 0x10
-#define CdlStatRead 0x20
-#define CdlStatSeek 0x40
-#define CdlStatPlay 0x80
+typedef enum _CdlCommand {
+ CdlNop = 0x01,
+ CdlSetloc = 0x02,
+ CdlPlay = 0x03,
+ CdlForward = 0x04,
+ CdlBackward = 0x05,
+ CdlReadN = 0x06,
+ CdlStandby = 0x07,
+ CdlStop = 0x08,
+ CdlPause = 0x09,
+ CdlInit = 0x0a,
+ CdlMute = 0x0b,
+ CdlDemute = 0x0c,
+ CdlSetfilter = 0x0d,
+ CdlSetmode = 0x0e,
+ CdlGetparam = 0x0f,
+ CdlGetlocL = 0x10,
+ CdlGetlocP = 0x11,
+ CdlSetsession = 0x12,
+ CdlGetTN = 0x13,
+ CdlGetTD = 0x14,
+ CdlSeekL = 0x15,
+ CdlSeekP = 0x16,
+ CdlTest = 0x19,
+ CdlGetID = 0x1a,
+ CdlReadS = 0x1b,
+ CdlReset = 0x1c
+} CdlCommand;
-/*
- * CD-ROM mode bits
- */
-#define CdlModeDA 0x01
-#define CdlModeAP 0x02
-#define CdlModeRept 0x04
-#define CdlModeSF 0x08
-//#define CdlModeSize0 0x10
-//#define CdlModeSize1 0x20
-#define CdlModeIgnore 0x10
-#define CdlModeSize 0x20
-#define CdlModeRT 0x40
-#define CdlModeSpeed 0x80
+typedef enum _CdlStatFlag {
+ CdlStatError = 1 << 0,
+ CdlStatStandby = 1 << 1,
+ CdlStatSeekError = 1 << 2,
+ CdlStatIdError = 1 << 3,
+ CdlStatShellOpen = 1 << 4,
+ CdlStatRead = 1 << 5,
+ CdlStatSeek = 1 << 6,
+ CdlStatPlay = 1 << 7
+} CdlStatFlag;
-/*
- * CD-ROM interrupt result values
+typedef enum _CdlModeFlag {
+ CdlModeDA = 1 << 0,
+ CdlModeAP = 1 << 1,
+ CdlModeRept = 1 << 2,
+ CdlModeSF = 1 << 3,
+ //CdlModeSize0 = 1 << 4,
+ //CdlModeSize1 = 1 << 5,
+ CdlModeIgnore = 1 << 4,
+ CdlModeSize = 1 << 5,
+ CdlModeRT = 1 << 6,
+ CdlModeSpeed = 1 << 7
+} CdlModeFlag;
+
+typedef enum _CdlIntrResult {
+ CdlNoIntr = 0,
+ CdlDataReady = 1,
+ CdlComplete = 2,
+ CdlAcknowledge = 3,
+ CdlDataEnd = 4,
+ CdlDiskError = 5
+} CdlIntrResult;
+
+typedef enum _CdlIsoError {
+ CdlIsoOkay = 0,
+ CdlIsoSeekError = 1,
+ CdlIsoReadError = 2,
+ CdlIsoInvalidFs = 3,
+ CdlIsoLidOpen = 4
+} CdlIsoError;
+
+/**
+ * @brief Translates a BCD format value to decimal
+ *
+ * @details Translates a specified value in BCD format (ie. 32/0x20 = 20) into
+ * a decimal integer, as the CD-ROM controller returns integer values only in
+ * BCD format.
*/
-#define CdlNoIntr 0x00
-#define CdlDataReady 0x01
-#define CdlComplete 0x02
-#define CdlAcknowledge 0x03
-#define CdlDataEnd 0x04
-#define CdlDiskError 0x05
+#define btoi(b) ((b)/16*10+(b)%16)
-/*
- * CD-ROM file system error codes (original)
+/**
+ * @brief Translates a decimal value to BCD
+ *
+ * @details Translates a decimal integer into a BCD format value (ie.
+ * 20 = 32/0x20), as the CD-ROM controller only accepts values in BCD format.
*/
-#define CdlIsoOkay 0x00
-#define CdlIsoSeekError 0x01
-#define CdlIsoReadError 0x02
-#define CdlIsoInvalidFs 0x03
-#define CdlIsoLidOpen 0x04
+#define itob(i) ((i)/10*16+(i)%10)
-#define btoi(b) ((b)/16*10+(b)%16) /* Convert BCD value to integer */
-#define itob(i) ((i)/10*16+(i)%10) /* Convert integer to BCD value */
+/* Structure and type definitions */
-/*
- * CD-ROM disc location struct
- */
-typedef struct _CdlLOC
-{
- uint8_t minute;
- uint8_t second;
- uint8_t sector;
- uint8_t track;
+/**
+ * @brief CD-ROM positional coordinates
+ *
+ * @details This structure is used to specify CD-ROM positional coordinates for
+ * CdlSetloc, CdlReadN and CdlReadS CD-ROM commands. Use CdIntToPos() to set
+ * parameters from a logical sector number.
+ *
+ * @see CdIntToPos(), CdControl()
+ */
+typedef struct _CdlLOC {
+ uint8_t minute; // Minutes (BCD)
+ uint8_t second; // Seconds (BCD)
+ uint8_t sector; // Sector or frame (BCD)
+ uint8_t track; // Track number (not used)
} CdlLOC;
-/*
- * CD-ROM audio attenuation struct (volume)
- */
-typedef struct _CdlATV
-{
- uint8_t val0; /* L -> SPU L */
- uint8_t val1; /* L -> SPU R */
- uint8_t val2; /* R -> SPU R */
- uint8_t val3; /* R -> SPU L */
+/**
+ * @brief CD-ROM attenuation parameters
+ *
+ * @details This structure specifies parameters for the CD-ROM attenuation.
+ * Values must be of range 0 to 127.
+ *
+ * The CD-ROM attenuation can be used to set the CD-ROM audio output to mono
+ * (0x40, 0x40, 0x40, 0x40) or reversed stereo (0x00, 0x80, 0x00, 0x80). It can
+ * also be used to play one of two stereo channels to both speakers.
+ *
+ * The CD-ROM attenuation affects CD-DA and CD-XA audio.
+ *
+ * @see CdMix()
+ */
+typedef struct _CdlATV {
+ uint8_t val0; // CD to SPU L-to-L volume
+ uint8_t val1; // CD to SPU L-to-R volume
+ uint8_t val2; // CD to SPU R-to-R volume
+ uint8_t val3; // CD to SPU R-to-L volume
} CdlATV;
-/*
- * CD-ROM file information struct
+/**
+ * @brief File entry structure
+ *
+ * @details Used to store basic information of a file such as logical block
+ * location and size. Currently, CdSearchFile() is the only function that uses
+ * this struct but it will be used in directory listing functions that may be
+ * implemented in the future.
+ *
+ * @see CdSearchFile()
*/
-typedef struct _CdlFILE
-{
- CdlLOC pos;
- uint32_t size;
- char name[16];
+typedef struct _CdlFILE {
+ CdlLOC pos; // CD-ROM position coordinates of file
+ uint32_t size; // Size of file in bytes
+ char name[16]; // File name
} CdlFILE;
-typedef struct _CdlFILTER
-{
- uint8_t file;
- uint8_t chan;
- uint16_t pad;
+/**
+ * @brief Structure used to set CD-ROM XA filter
+ *
+ * @details This structure is used to specify stream filter parameters for
+ * CD-ROM XA audio streaming using the CdlSetfilter command. This only affects
+ * CD-ROM XA audio streaming.
+ *
+ * CD-ROM XA audio is normally comprised of up to 8 or more ADPCM compressed
+ * audio streams interleaved into one continuous stream of data. The data
+ * stream is normally read at 2x speed but only one of eight XA audio streams
+ * can be played at a time. The XA stream to play is specified by the
+ * CdlSetfilter command and this struct.
+ *
+ * The CD-ROM XA filter can be changed during CD-ROM XA audio playback with
+ * zero audio interruption. This can be used to achieve dynamic music effects
+ * by switching to alternate versions of a theme to fit specific scenes
+ * seamlessly.
+ *
+ * @see CdControl()
+ */
+typedef struct _CdlFILTER {
+ uint8_t file; // File number to fetch (usually 1)
+ uint8_t chan; // Channel number (0 through 7)
+ uint16_t pad; // Padding
} CdlFILTER;
-/* Directory query context */
-typedef void* CdlDIR;
+/**
+ * @brief CD-ROM directory query context handle
+ *
+ * @details Used to store a directory context created by CdOpenDir(). An open
+ * context can then be used with CdReadDir() and closed with CdCloseDir().
+ *
+ * @see CdOpenDir()
+ */
+typedef void *CdlDIR;
-/* Data callback */
typedef void (*CdlCB)(int, uint8_t *);
+/* Public API */
+
#ifdef __cplusplus
extern "C" {
#endif
+/**
+ * @brief Initializes the CD-ROM library
+ *
+ * @details Initializes the CD-ROM subsystem which includes hooking the
+ * required IRQ handler, sets up internal variables of the CD-ROM library and
+ * attempts to initialize the CD-ROM controller. The mode parameter does
+ * nothing but may be used in future updates of this library.
+ *
+ * This function must be called after ResetGraph and before any other CD-ROM
+ * library function that interfaces with the CD-ROM controller. This function
+ * may not be called twice as it may cause instability or would just crash.
+ *
+ * @return Always 1. May change in the future.
+ */
int CdInit(void);
+/**
+ * @brief Translates a logical sector number to CD-ROM positional coordinates
+ *
+ * @details This function translates the logical sector number from i to CD-ROM
+ * positional coordinates stored to a CdlLOC struct specified by p. The
+ * translation takes the lead-in offset into account so the first logical
+ * sector begins at 0 and the result will be offset by 150 sectors.
+ *
+ * @param i Logical sector number
+ * @param p Pointer to a CdlLOC structure
+ * @return Pointer to the specified CdlLOC struct plus 150 sectors.
+ */
CdlLOC* CdIntToPos(int i, CdlLOC *p);
+
+/**
+ * @brief Translates CD-ROM positional coordinates to a logical sector number
+ *
+ * @details Translates the CD-ROM position parameters from a CdlLOC struct
+ * specified by p to a logical sector number. The translation takes the lead-in
+ * offset of 150 sectors into account so the logical sector number returned
+ * would begin at zero.
+ *
+ * @param p Pointer to a CdlLOC struct
+ * @return Logical sector number minus the 150 sector lead-in.
+ */
int CdPosToInt(const CdlLOC *p);
+
+/**
+ * @brief Gets CD-ROM TOC information
+ *
+ * @details Retrieves the track entries from a CD's table of contents (TOC). The
+ * function can return up to 99 track entries, which is the maximum number of
+ * audio tracks the CD standard supports.
+ *
+ * This function only retrieve the minutes and seconds of an audio track's
+ * position as the CD-ROM controller only returns the minutes and seconds of a
+ * track, which may result in the end of the previous track being played
+ * instead of the intended track to be played. This can be remedied by having a
+ * 2 second pregap on each audio track on your disc.
+ *
+ * @param toc Pointer to an array of CdlLOC entries
+ * @return Number of tracks on the disc, zero on error.
+ *
+ * @see CdControl()
+ */
int CdGetToc(CdlLOC *toc);
+/**
+ * @brief Issues a control command to the CD-ROM controller
+ *
+ * @details Sends a CD-ROM command specified by com to the CD-ROM controller,
+ * waits for an acknowledge interrupt (very fast) then returns. It will also
+ * issue parameters from param to the CD-ROM controller if the command accepts
+ * parameters. Response data from the CD-ROM controller is stored to result on
+ * commands that produce response data.
+ *
+ * Because this function waits for an acknowledge interrupt from the CD-ROM
+ * controller, this function should not be used in a callback. Instead, use
+ * CdControlF().
+ *
+ * Commands that are blocking require the use of CdSync() to wait for the
+ * command to fully complete.
+ *
+ * CD-ROM control commands:
+ *
+ * | Command | Value | Parameter | Blocking | Description |
+ * | :------------ | ----: | :-------- | :------- | :----------------------------------------------------------------------------------------------------------------- |
+ * | CdlNop | 0x01 | | No | Also known as Getstat. Normally used to query the CD-ROM status, which is retrieved using CdStatus(). |
+ * | CdlSetloc | 0x02 | CdlLOC | No | Sets the seek target location, but does not seek. Actual seeking begins upon issuing a seek or read command. |
+ * | CdlPlay | 0x03 | uint8_t | No | Begins CD Audio playback. Parameter specifies an optional track number to play (some emulators do not support it). |
+ * | CdlForward | 0x04 | | No | Fast forward (CD Audio only), issue CdlPlay to stop fast forward. |
+ * | CdlBackward | 0x05 | | No | Rewind (CD Audio only), issue CdlPlay to stop rewind. |
+ * | CdlReadN | 0x06 | CdlLOC | No | Begin reading data sectors. Used in conjunction with CdReadCallback(). |
+ * | CdlStandby | 0x07 | | Yes | Also known as MotorOn, starts CD motor and remains idle. |
+ * | CdlStop | 0x08 | | Yes | Stops playback and the disc itself. |
+ * | CdlPause | 0x09 | | Yes | Stops playback or data reading, but leaves the disc on standby. |
+ * | CdlInit | 0x0A | | Yes | Initialize the CD-ROM controller. |
+ * | CdlMute | 0x0B | | No | Mutes CD audio (both DA and XA). |
+ * | CdlDemute | 0x0C | | No | Unmutes CD audio (both DA and XA). |
+ * | CdlSetfilter | 0x0D | CdlFILTER | No | Set XA audio filter. |
+ * | CdlSetmode | 0x0E | uint8_t | No | Set CD-ROM mode. |
+ * | CdlGetparam | 0x0F | | No | Returns current CD-ROM mode and file/channel filter settings. |
+ * | CdlGetlocL | 0x10 | | No | Returns current logical CD position, mode and XA filter parameters. |
+ * | CdlGetlocP | 0x11 | | No | Returns current physical CD position (using SubQ location data). |
+ * | CdlSetsession | 0x12 | uint8_t | Yes | Seek to specified session on a multi-session disc. |
+ * | CdlGetTN | 0x13 | | No | Get CD-ROM track count. |
+ * | CdlGetTD | 0x14 | uint8_t | No | Get specified track position. |
+ * | CdlSeekL | 0x15 | | Yes | Logical seek to target position, set by last CdlSetloc command. |
+ * | CdlSeekP | 0x16 | | Yes | Physical seek to target position, set by last CdlSetloc command. |
+ * | CdlTest | 0x19 | (varies) | Yes | Special test command not disclosed to official developers (see nocash documents for more info). |
+ * | CdlReadS | 0x1B | CdlLOC | No | Begin reading data sectors without pausing for error correction. |
+ *
+ * CD-ROM return values:
+ *
+ * | Command | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+ * | :---------- | :---- | :---- | :----- | :--- | :------ | :------ | :--- | :----- |
+ * | CdlGetparam | stat | mode | 0 | file | channel | | | |
+ * | CdlGetlocL | amin | asec | aframe | mode | file | channel | sm | ci |
+ * | CdlGetlocP | track | index | min | sec | frame | amin | asec | aframe |
+ * | CdlGetTN | stat | first | last | | | | | |
+ * | CdlGetTD | stat | min | sec | | | | | |
+ *
+ * NOTE: Values are in BCD format.
+ *
+ * @param com Command value
+ * @param param Command parameters
+ * @param result Pointer of buffer to store result
+ * @return 1 if the command was issued successfully. Otherwise 0 if a
+ * previously issued command has not yet finished processing.
+ *
+ * @see CdSync(), CdControlF()
+ */
int CdControl(uint8_t com, const void *param, uint8_t *result);
+
+/**
+ * @brief Issues a CD-ROM command to the CD-ROM controller (blocking)
+ *
+ * @details This function works just like CdControl(), but blocks on blocking
+ * commands until said blocking command has completed.
+ *
+ * Because this function waits for an acknowledge interrupt from the CD-ROM
+ * controller, this function should not be used in a callback. Use CdControlF()
+ * instead.
+ *
+ * @param com Command value
+ * @param param Command parameters
+ * @param result Pointer of buffer to store result
+ * @return 1 if the command was issued successfully. Otherwise 0 if a
+ * previously issued command has not yet finished processing.
+ *
+ * @see CdControl(), CdControlF()
+ */
int CdControlB(uint8_t com, const void *param, uint8_t *result);
+
+/**
+ * @brief Issues a CD-ROM command to the CD-ROM controller (does not block)
+ *
+ * @details This function works more or less the same as CdControl() but it
+ * does not block even for the acknowledge interrupt from the CD-ROM
+ * controller. Since this function is non-blocking it can be used in a callback
+ * function.
+ *
+ * When using this function in a callback, a maximum of two commands can be
+ * issued at once and only the first command can have parameters. This is
+ * because the CD-ROM controller can only queue up to two commands and the
+ * parameter FIFO is not cleared until the last command is acknowledged. But
+ * waiting for acknowledgment in a callback is not possible.
+ *
+ * @param com Command value
+ * @param param Command parameters
+ * @return 1 if the command was issued successfully. Otherwise 0 if a
+ * previously issued command has not yet finished processing.
+ *
+ * @see CdControl()
+ */
int CdControlF(uint8_t com, const void *param);
+
+/**
+ * @brief Waits for blocking command or blocking status
+ *
+ * @details If mode is zero the function blocks if a blocking command was
+ * issued earlier until the command has finished. If mode is non-zero the
+ * function returns a command status value.
+ *
+ * A buffer specified by result will be set with the most recent CD-ROM status
+ * value from the last command issued.
+ *
+ * @param mode Mode
+ * @param result Pointer to store most recent CD-ROM status
+ * @return Command status is returned as one of the following definitions:
+ *
+ * | Definition | Description |
+ * | :----------- | :-------------------------- |
+ * | CdlComplete | Command completed. |
+ * | CdlNoIntr | No interrupt, command busy. |
+ * | CdlDiskError | CD-ROM error occurred. |
+ *
+ * @see CdControl()
+ */
int CdSync(int mode, uint8_t *result);
+
+/**
+ * @brief Sets a callback function
+ *
+ * @details Sets a callback with the specified function func. The callback is
+ * executed whenever a blocking command has completed.
+ *
+ * status is the CD-ROM status from the command that has completed processing.
+ * *result corresponds to the *result parameter on CdControl()/CdControlB() and
+ * returns the pointer to the buffer last set with that function.
+ *
+ * @param func Callback function
+ * @return Pointer to last callback function set, or NULL if none was set.
+ *
+ * @see CdControl, CdControlB, CdSync
+ */
uint32_t CdSyncCallback(CdlCB func);
+/**
+ * @brief Sets a callback function
+ *
+ * @details Sets a callback with the specified function func. The callback is
+ * executed whenever there's an incoming data sector from the CD-ROM controller
+ * during CdlReadN or CdlReadS. The pending sector data can be retrieved using
+ * CdGetSector().
+ *
+ * status is the CD-ROM status code from the last CD command that has finished
+ * processing. *result corresponds to the result pointer that was passed by the
+ * last CdControl()/CdControlB() call.
+ *
+ * This callback cannot be used in conjunction with CdRead() because it also
+ * uses this callback hook for its own internal use. The previously set
+ * callback is restored after read completion however.
+ *
+ * @param func Callback function
+ * @return Pointer to last callback function set, or NULL if none was set.
+ *
+ * @see CdControl(), CdControlB(), CdGetSector()
+ */
int CdReadyCallback(CdlCB func);
+
+/**
+ * @brief Gets data from the CD-ROM sector buffered
+ *
+ * @details Reads sector data that is pending in the CD-ROM sector buffer and
+ * stores it to *madr. Uses DMA to transfer the sector data and blocks very
+ * briefly until said transfer completes.
+ *
+ * This function is intended to be called within a callback routine set using
+ * CdReadyCallback() to fetch read data sectors from the CD-ROM sector buffer.
+ *
+ * @param madr Pointer to memory buffer to store sector data
+ * @param size Number of 32-bit words to retrieve
+ * @return Always 1.
+ *
+ * @see CdReadyCallback()
+ */
int CdGetSector(void *madr, int size);
+
+/**
+ * @brief Gets data from the CD-ROM sector buffered (non-blocking)
+ *
+ * @details Reads sector data that is pending in the CD-ROM sector buffer and
+ * stores it to *madr. Uses DMA to transfer the sector data in the background
+ * while keeping the CPU running (one word is transferred every 16 CPU cycles).
+ * Note this is much slower than the blocking transfer performed by
+ * CdGetSector().
+ *
+ * This function is intended to be called within a callback routine set using
+ * CdReadyCallback() to fetch read data sectors from the CD-ROM sector buffer.
+ * Since the transfer is asynchronous, CdDataSync() should be used to wait
+ * until the whole sector has been read.
+ *
+ * @param madr Pointer to memory buffer to store sector data
+ * @param size Number of 32-bit words to retrieve
+ * @return Always 1.
+ *
+ * @see CdReadyCallback(), CdDataSync()
+ */
int CdGetSector2(void *madr, int size);
+
+/**
+ * @brief Waits for sector transfer to finish
+ *
+ * @details If mode is zero the function blocks until any sector DMA transfer
+ * initiated by calling CdGetSector2() has finished. If mode is non-zero the
+ * function returns a boolean value representing whether a transfer is
+ * currently in progress.
+ *
+ * @param mode Mode
+ * @return 0 if the transfer has finished, 1 if it is still in progress or -1
+ * in case of a timeout.
+ *
+ * @see CdGetSector2()
+ */
int CdDataSync(int mode);
+/**
+ * @brief Locates a file in the CD-ROM file system
+ *
+ * @details Searches a file specified by filename by path and name in the
+ * CD-ROM file system and returns information of the file if found. The file
+ * information acquired will be stored to loc.
+ *
+ * Directories can be separated with slashes (/) or backslashes (\), a leading
+ * slash or backslash is optional but paths must be absolute. File version
+ * identifier (;1) at the end of the file name is also optional. File and
+ * directory names are case insensitive.
+ *
+ * The ISO9660 file system routines of libpsxcd do not support long file names
+ * currently. Only MS-DOS style 8.3 file names are supported; extensions such
+ * as Joliet and Rock Ridge are ignored.
+ *
+ * Upon calling this function for the first time, the ISO descriptor of the
+ * disc is read and the whole path table is cached into memory. Next the
+ * directory descriptor of the particular directory specified is loaded and
+ * cached to locate the file specified. The directory descriptor is kept in
+ * memory as long as the consecutive files to be searched are stored in the
+ * same directory until a file in another directory is to be searched. On which
+ * the directory descriptor is unloaded and a new directory descriptor is read
+ * from the disc and cached. Therefore, locating files in the same directory is
+ * faster as the relevant directory descriptor is already in memory and no disc
+ * reads are issued.
+ *
+ * As of Revision 66 of PSn00bSDK, media change is detected by checking the
+ * CD-ROM lid open status bit and attempting to acknowledge it with a CdlNop
+ * command, to discriminate the status from an open lid or changed disc.
+ *
+ * @param loc Pointer to a CdlFILE struct to store file information
+ * @param filename Path and name of file to locate
+ * @return Pointer to the specified CdlFILE struct. Otherwise NULL is returned
+ * when the file is not found.
+ */
CdlFILE* CdSearchFile(CdlFILE *loc, const char *filename);
+/**
+ * @brief Reads sectors from the CD-ROM
+ *
+ * @details Reads a number sectors specified by sectors from the location set
+ * by the last CdlSetloc command, the read sectors are then stored to a buffer
+ * specified by buf. mode specifies the CD-ROM mode to use for the read
+ * operation.
+ *
+ * The size of the sector varies depending on the sector read mode specified by
+ * mode. For standard data sectors it is multiples of 2048 bytes. If
+ * CdlModeSize0 is specified the sector size is 2328 bytes which includes the
+ * whole sector minus sync, adress, mode and sub header bytes. CdlModeSize1
+ * makes the sector size 2340 which is the entire sector minus sync bytes.
+ * Ideally, CdlModeSpeed must be specified to read data sectors at double
+ * CD-ROM speed.
+ *
+ * This function blocks very briefly to issue the necessary commands to start
+ * CD-ROM reading. To determine if reading has completed use CdReadSync or
+ * CdReadCallback.
+ *
+ * @param sectors Number of sectors to read
+ * @param buf Pointer to buffer to store sectors read
+ * @param mode CD-ROM mode for reading
+ * @return Always returns 0 even on errors. This may change in future versions.
+ *
+ * @see CdReadSync(), CdReadCallback()
+ */
int CdRead(int sectors, uint32_t *buf, int mode);
+
+/**
+ * @brief Waits for CD-ROM read completion or returns read status
+ *
+ * @details This function works more or less like CdSync() but for CdRead(). If
+ * mode is zero the function blocks if CdRead() was issued earlier until
+ * reading has completed. If mode is non-zero the function completes
+ * immediately and returns number of sectors remaining.
+ *
+ * A buffer specified by result will be set with the most recent CD-ROM status
+ * value from the last read issued.
+ *
+ * @param mode Mode
+ * @param result Pointer to store most recent CD-ROM status
+ * @return Number of sectors remaining. If reading is completed, 0 is returned.
+ * On error, -1 is returned.
+ *
+ * @see CdRead()
+ */
int CdReadSync(int mode, uint8_t *result);
+
+/**
+ * @brief Sets a callback function for read completion
+ *
+ * @details Works much the same as CdSyncCallback() but for CdRead(). Sets a
+ * callback with the specified function func. The callback is executed whenever
+ * a read operation initiated by CdRead() has completed.
+ *
+ * status is the CD-ROM status from the command that has completed processing.
+ * *result points to a read result buffer.
+ *
+ * @param func Callback function
+ * @return Pointer to last callback function set, or NULL if none was set.
+ *
+ * @see CdRead()
+ */
uint32_t CdReadCallback(CdlCB func);
+/**
+ * @brief Gets the most recent CD-ROM status
+ *
+ * @details Returns the CD-ROM status since the last command issued. The status
+ * value is updated by most CD-ROM commands.
+ *
+ * To get the current CD-ROM status you can issue CdlNop commands at regular
+ * intervals to update the CD-ROM status this function returns.
+ *
+ * @return CD-ROM status from last comand issued.
+ *
+ * @see CdControl()
+ */
int CdStatus(void);
+
+/**
+ * @brief Gets the last CD-ROM mode
+ *
+ * @details Returns the CD-ROM mode last set when issuing a CdlSetmode command.
+ * The function returns instantly as it merely returns a value stored in an
+ * internal variable.
+ *
+ * Since the value is simply a copy of what was specified from the last
+ * CdlSetmode command, the mode value may become inaccurate if CdlInit or other
+ * commands that affect the CD-ROM mode have been issued previously.
+ *
+ * @return Last CD-ROM mode value.
+ */
int CdMode(void);
+/**
+ * @brief Sets CD-ROM mixer or attenuation
+ *
+ * @details Sets the CD-ROM attenuation parameters from a CdlATV struct
+ * specified by vol. The CD-ROM attenuation settings are different from the SPU
+ * CD-ROM volume.
+ *
+ * Normally used to configure CD and XA audio playback for mono or reverse
+ * stereo output, though this was rarely used in practice.
+ *
+ * @param vol CD-ROM attenuation parameters
+ * @return Always 1.
+ */
int CdMix(const CdlATV *vol);
-/* ORIGINAL CODE */
+/**
+ * @brief Opens a directory on the CD-ROM file system
+ *
+ * @details Opens a directory on the CD-ROM file system to read the contents of
+ * a directory.
+ *
+ * A path name can use a slash (/) or backslash character (\) as the directory
+ * name separator. The path must be absolute and should begin with a slash or
+ * backslash. It should also not be prefixed with a device name (ie.
+ * \MYDIR1\MYDIR2 will work but not cdrom:\MYDIR1\MYDIR2). The file system
+ * routines in libpsxcd can query directory paths of up to 128 characters.
+ *
+ * The ISO9660 file system routines of libpsxcd do not support long file names
+ * currently. Only MS-DOS style 8.3 file names are supported; extensions such
+ * as Joliet and Rock Ridge are ignored.
+ *
+ * @param path Directory path to open
+ * @return Pointer of a CdlDIR context, NULL if an error occurred.
+ *
+ * @see CdReadDir(), CdCloseDir()
+ */
CdlDIR* CdOpenDir(const char* path);
+
+/**
+ * @brief Reads a directory entry from an open directory context
+ *
+ * @details Retrieves a file entry from an open directory context and stores it
+ * to a CdlFILE struct specified by file. Repeated calls of this function
+ * retrieves the next directory entry available until there are no more
+ * directory entries that follow.
+ *
+ * @param dir Open directory context (from CdOpenDir())
+ * @param file Pointer to a CdlFILE struct
+ * @return 1 if there are proceeding directory entries that follow, otherwise 0.
+ *
+ * @see CdOpenDir()
+ */
int CdReadDir(CdlDIR* dir, CdlFILE* file);
+
+/**
+ * @brief Closes a directory context created by CdOpenDir()
+ *
+ * @details Closes a directory query context created by CdOpenDir(). Behavior
+ * is undefined when closing a previously closed directory context.
+ *
+ * @param dir Directory context
+ *
+ * @see CdOpenDir()
+ */
void CdCloseDir(CdlDIR* dir);
int CdGetVolumeLabel(char* label);
+/**
+ * @brief Sets a callback function for auto pause
+ *
+ * @details The callback function specified in *func is executed when an auto
+ * pause interrupt occurs when the current CD-ROM mode is set with CdlModeAP.
+ * Auto pause interrupt occurs when CD Audio playback reaches the end of the
+ * audio track. Specifying 0 disables the callback.
+ *
+ * This can be used to easily loop CD audio automatically without requiring any
+ * intervention in your software loop.
+ *
+ * @param func Callback function
+ * @return Pointer to the last callback function set. Zero if no callback was
+ * set previously.
+ *
+ * @see CdControl()
+ */
int* CdAutoPauseCallback(void(*func)());
-int CdIsoError();
+/**
+ * @brief Retrieves CD-ROM ISO9660 parser status
+ *
+ * @details Returns the status of the file system parser from the last call of
+ * a file system related function, such as CdSearchFile(), CdGetVolumeLabel()
+ * and CdOpenDir(). Use this function to retrieve the exact error occurred when
+ * either of those functions fail.
+ *
+ * @return CD-ROM ISO9660 parser error code, as listed below:
+ *
+ * | Value | Description |
+ * | :-------------- | :-------------------------------------------------------------------------------------------------- |
+ * | CdlIsoOkay | File system parser okay. |
+ * | CdlIsoSeekError | Logical seek error occurred. May occur when attempting to query the filesystem on an audio-only CD. |
+ * | CdlIsoReadError | Read error occurred while reading the CD-ROM file system descriptor. |
+ * | CdlIsoInvalidFs | Disc does not contain a standard ISO9660 file system. |
+ * | CdlIsoLidOpen | Lid is open when attempting to parse the CD-ROM file system. |
+ */
+int CdIsoError(void);
+
+/**
+ * @brief Locates and parses the specified disc session
+ *
+ * @details Loads a session specified by session on a multi-session disc. Uses
+ * CdlSetsession to seek to the specified disc session, then scans the
+ * following 512 sectors for an ISO volume descriptor. If a volume descriptor
+ * is found the file system of that session is parsed and files inside the new
+ * session can be accessed using regular CD-ROM file and directory querying
+ * functions (CdSearchFile(), CdOpenDir(), CdReadDir(), CdCloseDir()). No
+ * special consideration is required when reading files from a new session.
+ *
+ * Loading a session takes 5-10 seconds to complete depending on the distance
+ * between the beginning of the disc and the start of the specified session. If
+ * the session specified does not exist, the disc will stop and would take
+ * 15-20 seconds to restart. The function does not support loading the most
+ * recent session of a disc automatically due to limitations of the CD-ROM
+ * hardware, so the user must be prompted to specify which session to load and
+ * to keep a record of the number of sessions that have been written to the
+ * disc.
+ *
+ * This function can also be used to update the Table of Contents (TOC) and
+ * reparse the file system regardless of the media change status by simply
+ * loading the first session. This is most useful for accessing files or audio
+ * tracks on a disc that was inserted using the swap trick method (it is
+ * recommended to stop the disc using CdlStop then restart it with CdlStandby
+ * after a button prompt for convenience, if you wish to implement this
+ * capability). Seeking to sessions other than the first session does not work
+ * with the swap trick however, so a chipped or unlockable console is desired
+ * for reading multi-session discs.
+ *
+ * NOTE: When the lid has been opened, the current CD-ROM session is reset to
+ * the first session on the disc. The console may produce an audible click
+ * sound when executing this function. This is normal, and the click sound is
+ * no different to the click heard on disc spin-up in older models of the
+ * console.
+ *
+ * @param session Session number (1 = first session)
+ * @return 0 on success. On failure due to open lid, bad session number or no
+ * volume descriptor found in specified session, returns -1 and return value of
+ * CdIsoError() is updated.
+ */
int CdLoadSession(int session);
#ifdef __cplusplus
diff --git a/libpsn00b/include/psxetc.h b/libpsn00b/include/psxetc.h
index 3b18784..ae4611e 100644
--- a/libpsn00b/include/psxetc.h
+++ b/libpsn00b/include/psxetc.h
@@ -3,6 +3,16 @@
* (C) 2019-2022 Lameguy64, spicyjpeg - MPL licensed
*/
+/**
+ * @file psxetc.h
+ * @brief Interrupt management library header
+ *
+ * @details This library provides basic facilities (such as interrupt handling)
+ * used by all other PSn00bSDK libraries, as well as some additional
+ * functionality including a dynamic linker (whose API is however defined in a
+ * separate header).
+ */
+
#ifndef __PSXETC_H
#define __PSXETC_H
@@ -39,13 +49,155 @@ typedef enum _DMA_Channel {
extern "C" {
#endif
+/**
+ * @brief Sets a callback for an interrupt.
+ *
+ * @details Registers a function to be called whenever the specified interrupt
+ * is fired. A previously registered callback can be removed by passing a null
+ * pointer instead. The IRQ controller is automatically configured to only
+ * enable interrupts for which a callback is registered.
+ *
+ * The callback will run in the exception handler's context, so it should be as
+ * fast as possible and shall not call any function that relies on interrupts
+ * being enabled. Each interrupt is acknowledged automatically before the
+ * callback is invoked.
+ *
+ * The following interrupt channels are available (the ones already used
+ * internally by libraries shall not be overridden to avoid conflicts):
+ *
+ * | ID | Channel | Used by |
+ * | --: | :--------------- | :-------------------------------------- |
+ * | 0 | IRQ_VBLANK | psxgpu (use VSyncCallback() instead) |
+ * | 1 | IRQ_GPU | |
+ * | 2 | IRQ_CD | psxcd (use CdReadyCallback() instead) |
+ * | 3 | IRQ_DMA | psxetc (use DMACallback() instead) |
+ * | 4 | IRQ_TIMER0 | |
+ * | 5 | IRQ_TIMER1 | |
+ * | 6 | IRQ_TIMER2 | |
+ * | 7 | IRQ_SIO0 | |
+ * | 8 | IRQ_SIO1 | psxsio (use SIO_ReadCallback() instead) |
+ * | 9 | IRQ_SPU | |
+ * | 10 | IRQ_GUN, IRQ_PIO | |
+ *
+ * WARNING: even though interrupts are acknowledged automatically at the IRQ
+ * controller side, most IRQ channels (1, 2, 3, 7, 8, 9) additionally require
+ * acknowledging at the device side, which must be done by the callback. The
+ * exact way to acknowledge interrupts varies for each device, however it
+ * usually involves setting or clearing a bit in a register. See the nocash
+ * documentation for more details.
+ *
+ * @param irq
+ * @param func
+ * @return Previously set callback for the channel or NULL
+ */
void *InterruptCallback(IRQ_Channel irq, void (*func)(void));
+
+/**
+ * @brief Gets the callback for an interrupt.
+ *
+ * @details Returns a pointer to the callback currently registered to handle
+ * the specified interrupt, or a null pointer if none is set.
+ *
+ * @param irq
+ * @return Currently set callback for the channel or NULL
+ *
+ * @see InterruptCallback()
+ */
void *GetInterruptCallback(IRQ_Channel irq);
+
+/**
+ * @brief Sets a callback for a DMA interrupt.
+ *
+ * @details Registers a function to be called whenever the specified DMA
+ * channel goes from busy to idle, i.e. when a transfer is completed. A
+ * previously registered callback can be removed by passing a null pointer
+ * instead. The DMA controller is automatically configured to only enable DMA
+ * interrupts for which a callback is registered.
+ *
+ * This function uses InterruptCallback() to register a "master handler" for
+ * DMA interrupts, which then dispatches the IRQ to depending on the channel
+ * that triggered it.
+ *
+ * The callback will run in the exception handler's context, so it should be as
+ * fast as possible and shall not call any function that relies on interrupts
+ * being enabled. Each interrupt is acknowledged automatically before the
+ * callback is invoked.
+ *
+ * The following DMA channels are available (the ones already used internally
+ * by libraries shall not be overridden to avoid conflicts):
+ *
+ * | ID | Channel | Used by |
+ * | --: | :----------- | :-------------------------------------- |
+ * | 0 | DMA_MDEC_IN | |
+ * | 1 | DMA_MDEC_OUT | |
+ * | 2 | DMA_GPU | psxgpu (use DrawSyncCallback() instead) |
+ * | 3 | DMA_CD | |
+ * | 4 | DMA_SPU | |
+ * | 5 | DMA_PIO | |
+ * | 6 | DMA_OTC | |
+ *
+ * @param dma
+ * @param func
+ * @return Previously set callback for the channel or NULL
+ */
void *DMACallback(DMA_Channel dma, void (*func)(void));
+
+/**
+ * @brief Gets the callback for a DMA interrupt.
+ *
+ * @details Returns a pointer to the callback currently registered to handle
+ * the specified DMA interrupt, or a null pointer if none is set.
+ *
+ * @param dma
+ * @return Currently set callback for the channel or NULL
+ *
+ * @see DMACallback()
+ */
void *GetDMACallback(DMA_Channel dma);
+/**
+ * @brief Initializes the interrupt dispatcher.
+ *
+ * @details Sets up the interrupt handling system, hooks the BIOS to dispatch
+ * interrupts to the library and clears all registered callbacks. This function
+ * must be called once at the beginning of the program, prior to registering
+ * any IRQ or DMA callbacks.
+ *
+ * ResetCallback() is called by psxgpu's ResetGraph(), so invoking it manually
+ * is usually not required. Calling ResetCallback() after ResetGraph() will
+ * actually result in improper initialization, as ResetGraph() registers
+ * several callbacks used internally by psxgpu.
+ *
+ * @return 0 or -1 if the was already initialized
+ */
int ResetCallback(void);
+
+/**
+ * @brief Restores the interrupt dispatcher.
+ *
+ * @details Restores the IRQ and DMA controller state saved by StopCallback()
+ * and reinstalls BIOS hooks for interrupt dispatching. All callbacks
+ * previously set before StopCallback() was called are preserved.
+ *
+ * @see StopCallback()
+ */
void RestartCallback(void);
+
+/**
+ * @brief Temporarily disables the interrupt dispatcher.
+ *
+ * @details Saves the state of the IRQ and DMA controllers, then disables them
+ * and removes BIOS hooks. This function must be called prior to launching a
+ * new executable or DLL that calls ResetCallback() or ResetGraph(), or an
+ * executable not built with PSn00bSDK that uses its own interrupt handling
+ * subsystem (such as a retail game). The saved state can be restored after the
+ * executable returns using RestartCallback().
+ *
+ * Note that interrupts are (obviously) disabled until RestartCallback() is
+ * called.
+ *
+ * @see RestartCallback()
+ */
void StopCallback(void);
#ifdef __cplusplus
diff --git a/libpsn00b/include/psxgte.h b/libpsn00b/include/psxgte.h
index ddc988d..3c1d5a4 100644
--- a/libpsn00b/include/psxgte.h
+++ b/libpsn00b/include/psxgte.h
@@ -3,6 +3,17 @@
* (C) 2019-2022 Lameguy64 - MPL licensed
*/
+/**
+ * @file psxgte.h
+ * @brief GTE library header
+ *
+ * @details The Geometry Transformation Engine, often referred to as the GTE,
+ * is most responsible for providing 3D capabilities to the PS1. This is
+ * effectively an all-integer math co-processor connected directly to the CPU,
+ * as it is accessed using COP2 and related MIPS instructions to access
+ * registers and issue commands to the GTE.
+ */
+
#ifndef __PSXGTE_H
#define __PSXGTE_H
@@ -35,50 +46,216 @@ typedef struct _DVECTOR {
/* Public API */
+#define csin(a) isin(a)
+#define ccos(a) icos(a)
+#define rsin(a) isin(a)
+#define rcos(a) icos(a)
+
#ifdef __cplusplus
extern "C" {
#endif
-void InitGeom(void);
-
-// Integer SIN/COS functions (4096 = 360 degrees)
-// Does not use tables!
+/**
+ * @brief Gets sine of angle (fixed-point, high precision version)
+ *
+ * @details Returns the sine of angle a.
+ *
+ * @param a Angle in fixed-point format (131072 = 360 degrees)
+ * @return Sine value in 20.12 fixed-point format (4096 = 1.0).
+ */
int isin(int a);
+
+/**
+ * @brief Gets cosine of angle (fixed-point, high precision version)
+ *
+ * @details Returns the cosine of angle a.
+ *
+ * @param a Angle in fixed-point format (131072 = 360 degrees)
+ * @return Cosine value in 20.12 fixed-point format (4096 = 1.0).
+ */
int icos(int a);
-// Higher precision integer sin/cos functions (131072 = 360 degrees)
-// Does not use tables!
+/**
+ * @brief Gets sine of angle (fixed-point)
+ *
+ * @details Returns the sine of angle a.
+ *
+ * @param a Angle in fixed-point format (131072 = 360 degrees)
+ * @return Sine value in 20.12 fixed-point format (4096 = 1.0).
+ */
int hisin(int a);
+
+/**
+ * @brief Gets cosine of angle (fixed-point)
+ *
+ * @details Returns the cosine of angle a.
+ *
+ * @param a Angle in fixed-point format (131072 = 360 degrees)
+ * @return Cosine value in 20.12 fixed-point format (4096 = 1.0).
+ */
int hicos(int a);
+/**
+ * @brief Initializes the GTE
+ *
+ * @details Resets, enables and initializes the GTE. Must be called prior to
+ * using any GTE function or macro.
+ */
+void InitGeom(void);
+
+/**
+ * @brief Gets square root (fixed-point)
+ *
+ * @details Returns the square root of value v.
+ *
+ * @param v Value in 20.12 fixed-point format (4096 = 1.0)
+ * @return Square root in 20.12 fixed-point format (4096 = 1.0).
+ */
+int SquareRoot12(int v);
+
+/**
+ * @brief Gets square root (integer)
+ *
+ * @details Returns the square root of value v.
+ *
+ * @param v Value in integer format
+ * @return Square root in integer format.
+ */
+int SquareRoot0(int v);
+
+/**
+ * @brief Pushes the current GTE matrix to the matrix stack
+ *
+ * @details Pushes the current GTE rotation matrix and translation vector to
+ * the internal matrix stack. Only one matrix stack level is currently
+ * supported.
+ */
void PushMatrix(void);
+
+/**
+ * @brief Pops the last matrix pushed into the matrix stack back to the GTE
+ *
+ * @details Pops the last inserted matrix in the internal matrix stack back to
+ * the GTE. Only one matrix stack level is currently supported.
+ */
void PopMatrix(void);
+/**
+ * @brief Defines the rotation matrix of a MATRIX
+ *
+ * @details Defines the rotation matrix of m from rotation coordinates of r.
+ * The matrix is computed as follows:
+ *
+ * [ 1 0 0 ] [ cy 0 sy] [ cz -sz 0 ]
+ * [ 0 cx -sx] * [ 0 1 0 ] * [ sz cz 0 ]
+ * [ 0 sx cx] [-sy 0 cy] [ 0 0 1 ]
+ *
+ * where:
+ *
+ * sx = sin(r.x) sy = sin(r.y) sz = sin(r.z)
+ * cx = cos(r.x) cy = cos(r.y) cz = cos(r.z)
+ *
+ * @param r Rotation vector (input)
+ * @param m Matrix (output)
+ * @return Pointer to m.
+ *
+ * @see TransMatrix(), CompMatrixLV()
+ */
MATRIX *RotMatrix(SVECTOR *r, MATRIX *m);
+
+/**
+ * @brief Defines the rotation matrix of a MATRIX (high precision version)
+ *
+ * @details Defines the rotation matrix of m from rotation coordinates of r.
+ * This function is a variant of RotMatrix() that uses hisin()/hicos() instead
+ * of isin()/icos().
+ *
+ * See RotMatrix() for more details.
+ *
+ * @param r Rotation vector (input)
+ * @param m Matrix (output)
+ * @return Pointer to m.
+ *
+ * @see RotMatrix()
+ */
MATRIX *HiRotMatrix(VECTOR *r, MATRIX *m);
+/**
+ * @brief Defines the translation vector of a MATRIX
+ *
+ * @details Simply sets the translation vector of MATRIX m. To perform
+ * accumulative translation operations, see CompMatrixLV().
+ *
+ * @param m Translation vector (input)
+ * @param r Matrix (output)
+ * @return Pointer to m.
+ *
+ * @see RotMatrix(), CompMatrixLV()
+ */
MATRIX *TransMatrix(MATRIX *m, VECTOR *r);
+
MATRIX *ScaleMatrix(MATRIX *m, VECTOR *s);
MATRIX *ScaleMatrixL(MATRIX *m, VECTOR *s);
MATRIX *MulMatrix(MATRIX *m0, MATRIX *m1);
MATRIX *MulMatrix0(MATRIX *m0, MATRIX *m1, MATRIX *m2);
+/**
+ * @brief Composite coordinate matrix transform
+ *
+ * @details Performs vector multiply by matrix with vector addition from v0 to
+ * the translation vector of v1. Then, multiples the rotation matrix of v0 by
+ * the rotation matrix of v1. The result of both operations is then stored in
+ * v2. Replaces the current GTE rotation matrix and translation vector with v0.
+ *
+ * Often used to adjust the matrix (includes rotation and translation) of an
+ * object relative to a world matrix, so the object would render relative to
+ * the world matrix.
+ *
+ * @param v0 Input matrix A
+ * @param v1 Input matrix B
+ * @param v2 Output matrix
+ * @return Pointer to v2.
+ */
MATRIX *CompMatrixLV(MATRIX *v0, MATRIX *v1, MATRIX *v2);
+
+/**
+ * @brief Multiplies a vector by a matrix
+ *
+ * @details Multiplies vector v0 with matrix m, result is stored to v1.
+ * Replaces the current GTE rotation matrix and translation vector with m.
+ *
+ * Often used to calculate a translation vector in relation to the rotation
+ * matrix for first person or vector camera perspectives.
+ *
+ * @param m Input matrix
+ * @param v0 Input vector
+ * @param v1 Output vector
+ * @return Pointer to v1.
+ */
VECTOR *ApplyMatrixLV(MATRIX *m, VECTOR *v0, VECTOR *v1);
+/**
+ * @brief Normalizes a VECTOR into SVECTOR format
+ *
+ * Normalizes a 32-bit vector into a 16-bit vector in 4.12 fixed-point format
+ * (4096 = 1.0, 2048 = 0.5).
+ *
+ * @param v0 Input (raw) 32-bit vector
+ * @param v1 Output (normalized) 16-bit vector
+ */
void VectorNormalS(VECTOR *v0, SVECTOR *v1);
+/**
+ * @brief Calculates the square of a VECTOR
+ *
+ * @details Calculates the square of vector v0 and stores the result to v1.
+ *
+ * @param v0 Input vector
+ * @param v1 Output vector
+ */
void Square0(VECTOR *v0, VECTOR *v1);
-int SquareRoot12(int v);
-int SquareRoot0(int v);
-
-#define csin(a) isin(a)
-#define ccos(a) icos(a)
-#define rsin(a) isin(a)
-#define rcos(a) icos(a)
-
#ifdef __cplusplus
}
#endif
diff --git a/libpsn00b/include/psxpress.h b/libpsn00b/include/psxpress.h
index 2106a53..dc1d52c 100644
--- a/libpsn00b/include/psxpress.h
+++ b/libpsn00b/include/psxpress.h
@@ -3,6 +3,23 @@
* (C) 2022 spicyjpeg - MPL licensed
*/
+/**
+ * @file psxpress.h
+ * @brief MDEC library header
+ *
+ * @details This is a fully original reimplementation of the official SDK's
+ * "data compression" library. This library is made up of two parts, the MDEC
+ * API and functions to decompress Huffman-encoded bitstreams (.BS files, or
+ * frames in .STR files) into data to be fed to the MDEC. Two different
+ * implementations of the latter are provided, one using the GTE and scratchpad
+ * region and an older one using a large lookup table in main RAM.
+ *
+ * FMV playback is not part of this library per se, but can implemented using
+ * the APIs defined here alongside some code to stream data from the CD drive.
+ *
+ * Currently only version 1 and 2 .BS files are supported.
+ */
+
#ifndef __PSXPRESS_H
#define __PSXPRESS_H
@@ -70,7 +87,9 @@ extern "C" {
#endif
/**
- * @brief Resets the MDEC and aborts any MDEC DMA transfers. If mode = 0, the
+ * @brief Resets and optionally initializes the MDEC.
+ *
+ * @details Resets the MDEC and aborts any MDEC DMA transfers. If mode = 0, the
* default IDCT matrix and quantization tables are also loaded and the MDEC is
* put into color output mode, discarding any custom environment previously set
* with DecDCTPutEnv().
@@ -78,15 +97,19 @@ extern "C" {
* DecDCTReset(0) must be called at least once prior to using the MDEC.
*
* @param mode
+ *
+ * @see DecDCTPutEnv()
*/
void DecDCTReset(int mode);
/**
- * @brief Uploads the specified decoding environment's quantization tables and
- * IDCT matrix to the MDEC, or restores the default tables if a null pointer is
- * passed. Calling this function is normally not required as DecDCTReset(0)
- * initializes the MDEC with the default tables, but it may be useful for e.g.
- * decoding JPEG or a format with custom quantization tables.
+ * @brief Loads default or custom quantization and IDCT tables into the MDEC.
+ *
+ * @details Uploads the specified decoding environment's quantization tables
+ * and IDCT matrix to the MDEC, or restores the default tables if a null
+ * pointer is passed. Calling this function is normally not required as
+ * DecDCTReset(0) initializes the MDEC with the default tables, but it may be
+ * useful for e.g. decoding JPEG or a format with custom quantization tables.
*
* The second argument, not present in the official SDK, specifies whether the
* MDEC shall be put into color (0) or monochrome (1) output mode. In
@@ -103,12 +126,16 @@ void DecDCTReset(int mode);
void DecDCTPutEnv(const DECDCTENV *env, int mono);
/**
- * @brief Sets up the MDEC to start fetching and decoding the given buffer.
- * This function is meant to be used with buffers generated by DecDCTvlc(): the
- * first 32-bit word of the buffer is initially copied to the MDEC0 register,
- * then all subsequent data is read in 128-byte (32-word) chunks. The length of
- * the stream (in 32-bit units, minus the first word) is encoded by DecDCTvlc()
- * in the lower 16 bits of the first word.
+ * @brief Feeds the MDEC with a run-length code buffer from the specified
+ * location.
+ *
+ * @details Sets up the MDEC to start fetching and decoding the given buffer.
+ * This function is meant to be used with buffers generated by DecDCTvlc(),
+ * DecDCTvlc2() or their variants: the first 32-bit word of the buffer is
+ * initially copied to the MDEC0 register, then all subsequent data is read in
+ * 128-byte (32-word) chunks. The length of the stream (in 32-bit units, minus
+ * the first word) is encoded by DecDCTvlc() in the lower 16 bits of the first
+ * word.
*
* The mode argument optionally specifies the output color depth (0 for 16bpp,
* 1 for 24bpp) if not already set in the first word. Passing -1 will result in
@@ -117,11 +144,15 @@ void DecDCTPutEnv(const DECDCTENV *env, int mono);
*
* @param data
* @param mode DECDCT_MODE_* or -1
+ *
+ * @see DecDCTinRaw(), DecDCTinSync()
*/
void DecDCTin(const uint32_t *data, int mode);
/**
- * @brief Configures the MDEC to automatically fetch data (the input stream,
+ * @brief Feeds the MDEC with raw data from the specified location.
+ *
+ * @details Configures the MDEC to automatically fetch data (the input stream,
* IDCT matrix or quantization tables) in 128-byte (32-word) chunks from the
* specified address in main RAM. The transfer is stopped, and any callback
* registered with DMACallback(0) is fired, once a certain number of 32-bit
@@ -135,13 +166,17 @@ void DecDCTin(const uint32_t *data, int mode);
*
* @param data
* @param length Number of 32-bit words to read (must be multiple of 32)
+ *
+ * @see DecDCTin(), DecDCTinSync()
*/
void DecDCTinRaw(const uint32_t *data, size_t length);
/**
- * @brief Waits for the MDEC to finish decoding the input stream (if mode = 0)
- * or returns whether it is busy (if mode = 1). MDEC commands can be issued
- * only when the MDEC isn't busy.
+ * @brief Waits for an MDEC input transfer to finish or returns its status.
+ *
+ * @details Waits for the MDEC to finish decoding the input stream (if
+ * mode = 0) or returns whether it is busy (if mode = 1). MDEC commands can be
+ * issued only when the MDEC isn't busy.
*
* WARNING: DecDCTinSync(0) might time out and return -1 if the MDEC can't
* output decoded data, e.g. if the length passed DecDCTout() was too small and
@@ -155,7 +190,9 @@ void DecDCTinRaw(const uint32_t *data, size_t length);
int DecDCTinSync(int mode);
/**
- * @brief Configures the MDEC to automatically transfer decoded image data in
+ * @brief Writes image data decoded by the MDEC to the specified location.
+ *
+ * @details Configures the MDEC to automatically transfer decoded image data in
* 128-byte (32-word) chunks to the specified address in main RAM. MDEC
* operation is paused once a certain number of 32-bit words have been output
* and can be resumed by calling DecDCTout() again: the MDEC will continue
@@ -168,12 +205,16 @@ int DecDCTinSync(int mode);
*
* @param data
* @param length Number of 32-bit words to output (must be multiple of 32)
+ *
+ * @see DecDCToutSync()
*/
void DecDCTout(uint32_t *data, size_t length);
/**
- * @brief Waits until the transfer set up by DecDCTout() finishes (if mode = 0)
- * or returns whether it is still in progress (if mode = 1).
+ * @brief Waits for an MDEC output transfer to finish or returns its status.
+ *
+ * @details Waits until the transfer set up by DecDCTout() finishes (if
+ * mode = 0) or returns whether it is still in progress (if mode = 1).
*
* WARNING: DecDCToutSync(0) might time out and return -1 if the MDEC is unable
* to consume enough input data in order to produce the desired amount of data.
@@ -186,7 +227,9 @@ void DecDCTout(uint32_t *data, size_t length);
int DecDCToutSync(int mode);
/**
- * @brief Begins decompressing the contents of a .BS file (or of a single .STR
+ * @brief Decompresses or begins decompressing a .BS file into MDEC codes.
+ *
+ * @details Begins decompressing the contents of a .BS file (or of a single STR
* frame) into a buffer that can be passed to DecDCTin(). This function uses a
* small (<1 KB) lookup table combined with the GTE to accelerate the process;
* performance is roughly on par with DecDCTvlcStart2() if the lookup table
@@ -212,11 +255,15 @@ int DecDCToutSync(int mode);
* @param max_size Maximum number of 32-bit words to output
* @param bs
* @return 0, 1 if more data needs to be output or -1 in case of failure
+ *
+ * @see DecDCTvlcContinue(), DecDCTvlcCopyTable()
*/
int DecDCTvlcStart(VLC_Context *ctx, uint32_t *buf, size_t max_size, const uint32_t *bs);
/**
- * @brief Resumes the decompression process started by DecDCTvlcStart(). The
+ * @brief Resumes or finishes decompressing a .BS file into MDEC codes.
+ *
+ * @details Resumes the decompression process started by DecDCTvlcStart(). The
* state of the decompressor is contained entirely in the VLC_Context structure
* so an arbitrary number of bitstreams can be decoded concurrently (although
* the limited CPU power makes it impractical to do so) by keeping a separate
@@ -236,14 +283,18 @@ int DecDCTvlcStart(VLC_Context *ctx, uint32_t *buf, size_t max_size, const uint3
* @param buf
* @param max_size Maximum number of 32-bit words to output
* @return 0, 1 if more data needs to be output or -1 in case of failure
+ *
+ * @see DecDCTvlcStart()
*/
int DecDCTvlcContinue(VLC_Context *ctx, uint32_t *buf, size_t max_size);
/**
- * A wrapper around DecDCTvlcStart() and DecDCTvlcContinue() for compatibility
- * with the official SDK. This function uses an internal context; additionally,
- * the maximum output buffer size is not passed as an argument but is instead
- * set by calling DecDCTvlcSize().
+ * @brief Decompresses a .BS file into MDEC codes.
+ *
+ * @details A wrapper around DecDCTvlcStart() and DecDCTvlcContinue() for
+ * compatibility with the official SDK. This function uses an internal context;
+ * additionally, the maximum output buffer size is not passed as an argument
+ * but is instead set by calling DecDCTvlcSize().
*
* This function behaves identically to DecDCTvlcContinue() if bs = 0 and
* DecDCTvlcStart() otherwise.
@@ -257,21 +308,34 @@ int DecDCTvlcContinue(VLC_Context *ctx, uint32_t *buf, size_t max_size);
* @param bs Pointer to bitstream data or 0 to resume decoding
* @param buf
* @return 0, 1 if more data needs to be output or -1 in case of failure
+ *
+ * @see DecDCTvlcSize(), DecDCTvlcCopyTable()
*/
int DecDCTvlc(const uint32_t *bs, uint32_t *buf);
/**
- * @brief Sets the maximum number of 32-bit words that a single call to
+ * @brief Sets the maximum amount of data to be decompressed.
+ *
+ * @details Sets the maximum number of 32-bit words that a single call to
* DecDCTvlc() will output. If size = 0, the entire frame will always be
* decoded in one shot.
*
+ * Note that DecDCTvlcStart() and DecDCTvlcContinue() do not use the value set
+ * by this function and instead expect the maximum size to be passed as an
+ * argument.
+ *
* @param size Maximum number of 32-bit words to output
- * @return Previously set value
+ * @return Previously set value
+ *
+ * @see DecDCTvlc()
*/
size_t DecDCTvlcSize(size_t size);
/**
- * @brief Copies the small (<1 KB) lookup table used by DecDCTvlcContinue(),
+ * @brief Moves the lookup table used by the .BS decompressor to the scratchpad
+ * region.
+ *
+ * @details Copies the small (<1 KB) lookup table used by DecDCTvlcContinue(),
* DecDCTvlcStart() and DecDCTvlc() (a DECDCTTAB structure) to the specified
* address. A copy of this table is always present in main RAM, however this
* function can be used to copy it to the scratchpad region to boost
@@ -287,7 +351,10 @@ size_t DecDCTvlcSize(size_t size);
void DecDCTvlcCopyTable(DECDCTTAB *addr);
/**
- * @brief Begins decompressing the contents of a .BS file (or of a single .STR
+ * @brief Decompresses or begins decompressing a .BS file into MDEC codes
+ * (alternate implementation).
+ *
+ * @details Begins decompressing the contents of a .BS file (or of a single STR
* frame) into a buffer that can be passed to DecDCTin(). This function uses a
* large (34 KB) lookup table that must be loaded into main RAM beforehand by
* calling DecDCTvlcBuild(), but does not use the GTE nor the scratchpad.
@@ -311,11 +378,16 @@ void DecDCTvlcCopyTable(DECDCTTAB *addr);
* @param max_size Maximum number of 32-bit words to output
* @param bs
* @return 0, 1 if more data needs to be output or -1 in case of failure
+ *
+ * @see DecDCTvlcContinue2(), DecDCTvlcBuild()
*/
int DecDCTvlcStart2(VLC_Context *ctx, uint32_t *buf, size_t max_size, const uint32_t *bs);
/**
- * @brief Resumes the decompression process started by DecDCTvlcStart2(). The
+ * @brief Resumes or finishes decompressing a .BS file into MDEC codes
+ * (alternate implementation).
+ *
+ * @details Resumes the decompression process started by DecDCTvlcStart2(). The
* state of the decompressor is contained entirely in the VLC_Context structure
* so an arbitrary number of bitstreams can be decoded concurrently (although
* the limited CPU power makes it impractical to do so) by keeping a separate
@@ -333,11 +405,15 @@ int DecDCTvlcStart2(VLC_Context *ctx, uint32_t *buf, size_t max_size, const uint
* @param buf
* @param max_size Maximum number of 32-bit words to output
* @return 0, 1 if more data needs to be output or -1 in case of failure
+ *
+ * @see DecDCTvlcStart2()
*/
int DecDCTvlcContinue2(VLC_Context *ctx, uint32_t *buf, size_t max_size);
/**
- * A wrapper around DecDCTvlcStart2() and DecDCTvlcContinue2() for
+ * @brief Decompresses a .BS file into MDEC codes (alternate implementation).
+ *
+ * @details A wrapper around DecDCTvlcStart2() and DecDCTvlcContinue2() for
* compatibility with the official SDK. This function uses an internal context;
* additionally, the maximum output buffer size is not passed as an argument
* but is instead set by calling DecDCTvlcSize2().
@@ -353,21 +429,35 @@ int DecDCTvlcContinue2(VLC_Context *ctx, uint32_t *buf, size_t max_size);
* @param buf
* @param table Pointer to decompressed table or 0 to use last table used
* @return 0, 1 if more data needs to be output or -1 in case of failure
+ *
+ * @see DecDCTvlcSize2(), DecDCTvlcBuild()
*/
int DecDCTvlc2(const uint32_t *bs, uint32_t *buf, DECDCTTAB2 *table);
/**
- * @brief Sets the maximum number of 32-bit words that a single call to
+ * @brief Sets the maximum amount of data to be decompressed (alternate
+ * implementation).
+ *
+ * @details Sets the maximum number of 32-bit words that a single call to
* DecDCTvlc2() will output. If size = 0, the entire frame will always be
* decoded in one shot.
*
+ * Note that DecDCTvlcStart2() and DecDCTvlcContinue2() do not use the value
+ * set by this function and instead expect the maximum size to be passed as an
+ * argument.
+ *
* @param size Maximum number of 32-bit words to output
- * @return Previously set value
+ * @return Previously set value
+ *
+ * @see DecDCTvlc2()
*/
size_t DecDCTvlcSize2(size_t size);
/**
- * @brief Generates the lookup table required by DecDCTvlcStart2(),
+ * @brief Generates the lookup table used by the alternate implementation of
+ * the .BS decompressor.
+ *
+ * @details Generates the lookup table required by DecDCTvlcStart2(),
* DecDCTvlcContinue2() and DecDCTvlc2() (a DECDCTTAB2 structure) into the
* specified buffer. Since the table is relatively large (34 KB), it is
* recommended to only generate it in a dynamically-allocated buffer when
diff --git a/libpsn00b/include/psxsio.h b/libpsn00b/include/psxsio.h
index d5f7d9a..449e43a 100644
--- a/libpsn00b/include/psxsio.h
+++ b/libpsn00b/include/psxsio.h
@@ -3,12 +3,27 @@
* (C) 2019-2022 Lameguy64, spicyjpeg - MPL licensed
*/
+/**
+ * @file psxsio.h
+ * @brief Serial port library header
+ *
+ * @details This library provides a custom API to access the PS1's serial port.
+ * Sending and receiving data is done fully asynchronously using a pair of
+ * 128-byte FIFOs kept in main RAM, with optional hardware flow control. More
+ * advanced use cases such as custom callbacks for each byte received are also
+ * supported.
+ *
+ * A BIOS TTY driver to redirect stdin/stdout (including BIOS messages as well
+ * as PSn00bSDK's own debug logging) to the serial port is also provided for
+ * debugging purposes.
+ */
+
#ifndef __PSXSIO_H
#define __PSXSIO_H
#include <stdint.h>
-/* Register definitions (used internally) */
+/* Enum and register definitions */
typedef enum _SIO_StatusRegFlag {
SR_TXRDY = 1 << 0,
@@ -67,7 +82,9 @@ extern "C" {
#endif
/**
- * @brief Resets the serial port, initializes the library's internal ring
+ * @brief Initializes the serial port driver.
+ *
+ * @details Resets the serial port, initializes the library's internal ring
* buffers and installs a serial IRQ handler. The given mode value (normally
* MR_CHLEN_8|MR_SB_01 for 8 data bits, 1 stop bit and no parity) is copied to
* the SIO_MODE register. Flow control is disabled by default (see
@@ -79,18 +96,28 @@ extern "C" {
*
* @param baud Baud rate in bits per second
* @param mode Binary OR of SIO_ModeRegFlag enum members
+ *
+ * @see SIO_Quit()
*/
void SIO_Init(int baud, uint16_t mode);
/**
- * @brief Resets the serial port and removes the IRQ callback added by
- * SIO_Init(), restoring any previously installed handler.
+ * @brief Uninstalls the serial port driver.
+ *
+ * @details Resets the serial port and removes the IRQ callback added by
+ * SIO_Init(), restoring any previously installed handler if any. If SIO_Init()
+ * was previously invoked, calling SIO_Quit() before accessing serial port
+ * registers manually is highly recommended.
+ *
+ * @see SIO_Init()
*/
void SIO_Quit(void);
/**
- * @brief Changes the serial port's flow control mode. The following modes are
- * available:
+ * @brief Sets the flow control mode.
+ *
+ * @details Changes the serial port's flow control mode. The following modes
+ * are available:
*
* - SIO_FC_NONE (default): do not assert RTS or DTR automatically and ignore
* DSR. Note that the hardware will still wait for CTS to be asserted before
@@ -106,7 +133,9 @@ void SIO_Quit(void);
void SIO_SetFlowControl(SIO_FlowControl mode);
/**
- * @brief Reads a byte from the RX buffer. If the buffer is empty, blocks
+ * @brief Reads a byte from the RX buffer (blocking).
+ *
+ * @details Reads a byte from the RX buffer. If the buffer is empty, blocks
* indefinitely until a byte is received.
*
* WARNING: this function shall not be used in a critical section or IRQ
@@ -115,21 +144,29 @@ void SIO_SetFlowControl(SIO_FlowControl mode);
* or SIO_ReadSync(1) and implementing a timeout instead.
*
* @return Received byte
+ *
+ * @see SIO_ReadByte2(), SIO_ReadSync()
*/
int SIO_ReadByte(void);
/**
- * @brief Non-blocking variant of SIO_ReadByte(). Reads a byte from the RX
+ * @brief Reads a byte from the RX buffer (non-blocking).
+ *
+ * @details Non-blocking variant of SIO_ReadByte(). Reads a byte from the RX
* buffer or returns -1 if the buffer is empty. Unlike SIO_ReadByte() this
* function is safe to use in a critical section (although no data will be
* received while interrupts are disabled).
*
* @return Received byte, -1 if no data is available
+ *
+ * @see SIO_ReadByte()
*/
int SIO_ReadByte2(void);
/**
- * @brief Waits for at least one byte to be available in the RX buffer (if
+ * @brief Waits for a byte to be received or returns the RX buffer's length.
+ *
+ * @details Waits for at least one byte to be available in the RX buffer (if
* mode = 0) or returns the length of the RX buffer (if mode = 1).
*
* WARNING: this function shall not be used in a critical section or IRQ
@@ -144,7 +181,9 @@ int SIO_ReadByte2(void);
int SIO_ReadSync(int mode);
/**
- * @brief Registers a function to be called whenever a byte is received. The
+ * @brief Sets a callback for received bytes.
+ *
+ * @details Registers a function to be called whenever a byte is received. The
* received byte is passed as an argument to the callback, which shall then
* return a zero value to also store the byte in the RX buffer or a non-zero
* value to drop it. This can be used to e.g. filter or validate incoming data,
@@ -160,7 +199,9 @@ int SIO_ReadSync(int mode);
void *SIO_ReadCallback(int (*func)(uint8_t));
/**
- * @brief Sends the given byte, or appends it to the TX buffer if the serial
+ * @brief Writes a byte to the TX buffer (blocking).
+ *
+ * @details Sends the given byte, or appends it to the TX buffer if the serial
* port is busy. If the buffer is full, blocks until the byte can be stored in
* the buffer (with a timeout).
*
@@ -169,11 +210,15 @@ void *SIO_ReadCallback(int (*func)(uint8_t));
*
* @param value
* @return Number of TX bytes previously pending, -1 in case of a timeout
+ *
+ * @see SIO_WriteByte2(), SIO_WriteSync()
*/
int SIO_WriteByte(uint8_t value);
/**
- * @brief Non-blocking variant of SIO_WriteByte(). Sends the given byte, or
+ * @brief Writes a byte to the TX buffer (non-blocking).
+ *
+ * @details Non-blocking variant of SIO_WriteByte(). Sends the given byte, or
* appends it to the TX buffer if the serial port is busy. If the buffer is
* full, returns -1 without actually sending the byte. Unlike SIO_WriteByte()
* this function is safe to use in a critical section (although no data will be
@@ -181,12 +226,16 @@ int SIO_WriteByte(uint8_t value);
*
* @param value
* @return Number of TX bytes previously pending, -1 in case of failure
+ *
+ * @see SIO_WriteByte()
*/
int SIO_WriteByte2(uint8_t value);
/**
- * @brief Waits for all bytes pending in the TX buffer to be sent (if mode = 0)
- * or returns the length of the TX buffer (if mode = 1).
+ * @brief Waits for all bytes to be sent or returns the TX buffer's length.
+ *
+ * @details Waits for all bytes pending in the TX buffer to be sent (if
+ * mode = 0) or returns the length of the TX buffer (if mode = 1).
*
* WARNING: this function shall not be used in a critical section or IRQ
* callback as no data is sent or received while interrupts are disabled.
@@ -197,10 +246,11 @@ int SIO_WriteByte2(uint8_t value);
int SIO_WriteSync(int mode);
/**
- * @brief Installs a BIOS file driver to redirect TTY stdin/stdout (including
- * BIOS messages as well as PSn00bSDK's own debug logging) to the serial port.
- * Uses SIO_Init() internally. The port is configured for 8 data bits, 1 stop
- * bit and no parity.
+ * @brief Installs the serial port TTY driver.
+ *
+ * @details Installs a BIOS file driver to redirect TTY stdin/stdout to the
+ * serial port. Uses SIO_Init() internally. The port is configured for 8 data
+ * bits, 1 stop bit and no parity.
*
* This function shall only be used for debugging purposes. Picking a high baud
* rate is recommended as all TTY writes are blocking and bypass the TX buffer.
@@ -210,13 +260,20 @@ int SIO_WriteSync(int mode);
* built-in TTY functionality of these loaders.
*
* @param baud Baud rate in bits per second
+ *
+ * @see DelSIO()
*/
void AddSIO(int baud);
/**
- * @brief Uninstalls the BIOS driver installed by AddSIO() and attempts to
- * restore a "dummy" TTY driver. Calling this function is not recommended as
- * any further TTY usage may crash the system.
+ * @brief Removes the serial port TTY driver.
+ *
+ * @details Uninstalls the BIOS driver installed by AddSIO() and attempts to
+ * restore the default "dummy" TTY driver. Uses SIO_Quit() internally. Calling
+ * this function is not recommended as any further TTY usage may crash the
+ * system.
+ *
+ * @see AddSIO()
*/
void DelSIO(void);