Skip to content

Commit

Permalink
Fix bugs in libc, psxgpu, psxpress, clean up headers
Browse files Browse the repository at this point in the history
  • Loading branch information
spicyjpeg committed Jan 8, 2024
1 parent 06e65be commit dd85f9f
Show file tree
Hide file tree
Showing 11 changed files with 311 additions and 231 deletions.
6 changes: 3 additions & 3 deletions libpsn00b/include/hwregs_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@

/* Timers */

#define TIMER_VALUE(N) _MMIO32((IOBASE | 0x1100) + (16 * (N)))
#define TIMER_CTRL(N) _MMIO32((IOBASE | 0x1104) + (16 * (N)))
#define TIMER_RELOAD(N) _MMIO32((IOBASE | 0x1108) + (16 * (N)))
#define TIMER_VALUE(N) _MMIO16((IOBASE | 0x1100) + (16 * (N)))
#define TIMER_CTRL(N) _MMIO16((IOBASE | 0x1104) + (16 * (N)))
#define TIMER_RELOAD(N) _MMIO16((IOBASE | 0x1108) + (16 * (N)))

/* Memory/bus control */

Expand Down
387 changes: 230 additions & 157 deletions libpsn00b/include/psxcd.h

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions libpsn00b/include/psxgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

/* Definitions */

typedef enum _GPU_DispFlags {
typedef enum {
DISP_WIDTH_256 = 0,
DISP_WIDTH_320 = 1,
DISP_WIDTH_512 = 2,
Expand All @@ -39,12 +39,12 @@ typedef enum _GPU_DispFlags {
DISP_WIDTH_384 = 1 << 6
} GPU_DispFlags;

typedef enum _GPU_VideoMode {
typedef enum {
MODE_NTSC = 0,
MODE_PAL = 1
} GPU_VideoMode;

typedef enum _GPU_DrawOpType {
typedef enum {
DRAWOP_TYPE_DMA = 1,
DRAWOP_TYPE_GPU_IRQ = 2
} GPU_DrawOpType;
Expand Down Expand Up @@ -273,31 +273,31 @@ typedef enum _GPU_DrawOpType {

/* Primitive structure definitions */

typedef struct _P_TAG_T {
typedef struct {
uint32_t color:24;
uint32_t code:8;
} P_TAG_T;

typedef struct _P_TAG {
typedef struct {
uint32_t addr:24;
uint32_t len:8;
uint32_t color:24;
uint32_t code:8;
} P_TAG;

typedef struct _P_COLOR {
typedef struct {
uint32_t color:24;
uint32_t pad:8;
} P_COLOR;

// These macros are used to define two variants of each primitive, a regular one
// and a "tagless" one (_T suffix) without the OT/display list header.
#define _DEF_PRIM(name, ...) \
typedef struct _##name##_T { __VA_ARGS__ } name##_T; \
typedef struct _##name { uint32_t tag; __VA_ARGS__ } name;
typedef struct { __VA_ARGS__ } name##_T; \
typedef struct { uint32_t tag; __VA_ARGS__ } name;
#define _DEF_ALIAS(name, target) \
typedef struct _##target##_T name##_T; \
typedef struct _##target name;
typedef target##_T name##_T; \
typedef target name;

_DEF_PRIM(POLY_F3,
uint8_t r0, g0, b0, code;
Expand Down Expand Up @@ -524,23 +524,23 @@ _DEF_PRIM(DR_ENV,

/* Structure definitions */

typedef struct _RECT {
typedef struct {
int16_t x, y, w, h;
} RECT;

typedef struct _DISPENV_RAW {
typedef struct {
uint32_t vid_mode;
int16_t vid_xpos, vid_ypos;
int16_t fb_x, fb_y;
} DISPENV_RAW;

typedef struct _DISPENV {
typedef struct {
RECT disp, screen;
uint8_t isinter, isrgb24, reverse;
uint8_t _reserved;
} DISPENV;

typedef struct _DRAWENV {
typedef struct {
RECT clip; // Drawing area
int16_t ofs[2]; // GPU draw offset (relative to draw area)
RECT tw; // Texture window
Expand All @@ -552,15 +552,15 @@ typedef struct _DRAWENV {
DR_ENV dr_env; // GPU primitive cache area (used internally)
} DRAWENV;

typedef struct _TIM_IMAGE {
typedef struct {
uint32_t mode;
RECT *crect;
uint32_t *caddr;
RECT *prect;
uint32_t *paddr;
} TIM_IMAGE;

typedef struct _GsIMAGE {
typedef struct {
uint32_t pmode;
int16_t px, py, pw, ph;
uint32_t *pixel;
Expand Down Expand Up @@ -615,7 +615,7 @@ int DrawBuffer(const uint32_t *buf, size_t length);
int DrawBufferIRQ(const uint32_t *buf, size_t length);
void DrawBuffer2(const uint32_t *buf, size_t length);
void DrawBufferIRQ2(const uint32_t *buf, size_t length);
void DrawPrim(const uint32_t *pri);
void DrawPrim(const void *pri);

void AddPrim(uint32_t *ot, const void *pri);

Expand Down
33 changes: 15 additions & 18 deletions libpsn00b/include/psxpress.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@

/* Structure definitions */

typedef struct _DECDCTENV {
typedef struct {
uint8_t iq_y[64]; // Luma quantization table, stored in zigzag order
uint8_t iq_c[64]; // Chroma quantization table, stored in zigzag order
int16_t dct[64]; // Inverse DCT matrix (2.14 fixed-point)
} DECDCTENV;

typedef struct _VLC_TableV2 {
typedef struct {
uint16_t ac0[2];
uint32_t ac2[8], ac3[64];
uint16_t ac4[8], ac5[8], ac7[16], ac8[32];
uint16_t ac9[32], ac10[32], ac11[32], ac12[32];
} VLC_TableV2;

typedef struct _VLC_TableV3 {
typedef struct {
uint16_t ac0[2];
uint32_t ac2[8], ac3[64];
uint16_t ac4[8], ac5[8], ac7[16], ac8[32];
Expand All @@ -51,29 +51,25 @@ typedef struct _VLC_TableV3 {
uint8_t _reserved[3];
} VLC_TableV3;

typedef struct _DECDCTTAB {
typedef struct {
uint32_t ac[8192], ac00[512];
} DECDCTTAB;

typedef enum _DECDCTMODE {
typedef enum {
DECDCT_MODE_24BPP = 1,
DECDCT_MODE_16BPP = 0,
DECDCT_MODE_16BPP_BIT15 = 2,
DECDCT_MODE_RAW = -1
} DECDCTMODE;

typedef struct _VLC_Context {
typedef struct {
const uint32_t *input;
uint32_t window, next_window, remaining;
int8_t is_v3, bit_offset, block_index, coeff_index;
uint16_t quant_scale;
int16_t last_y, last_cr, last_cb;
} VLC_Context;

// Despite what some docs claim, the "number of 32-byte blocks" and "always
// 0x3800" fields are actually a single 32-bit field which is copied over to
// the output buffer, then parsed by DecDCTin() and written to the MDEC0
// register.
typedef struct {
uint32_t mdec0_header;
uint16_t quant_scale;
Expand Down Expand Up @@ -179,10 +175,10 @@ void DecDCTinRaw(const uint32_t *data, size_t length);
* 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
* no callback is registered to set up further transfers. DecDCTinSync(0) shall
* only be used alongside DMACallback(1) or if the entirety of the decoded
* stream (usually a whole frame) is being written to main RAM.
* output decoded data, e.g. if the length passed to DecDCTout() was too small
* and no callback is registered to set up further transfers. DecDCTinSync(0)
* shall only be used alongside DMACallback(1) or if the entirety of the
* decoded stream (usually a whole frame) is being written to main RAM.
*
* @param mode
* @return 0 or -1 in case of a timeout (mode = 0), MDEC busy flag (mode = 1)
Expand Down Expand Up @@ -219,7 +215,8 @@ void DecDCTout(uint32_t *data, size_t length);
* 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.
* If the input stream isn't contiguous in memory, DMACallback(0) shall be used
* to register a callback that calls DecDCTin() to feed the MDEC.
* to register a callback that calls DecDCTin() or DecDCTinRaw() to feed the
* MDEC.
*
* @param mode
* @return 0 or -1 in case of a timeout (mode = 0), DMA busy flag (mode = 1)
Expand Down Expand Up @@ -249,7 +246,7 @@ int DecDCToutSync(int mode);
* first time. Attempting to call this function with the GTE disabled will
* result in a crash.
*
* @param ctx Pointer to VLC_Context structure (which will be initialized)
* @param ctx Pointer to new VLC_Context structure
* @param buf
* @param max_size Maximum number of 32-bit words to output
* @param bs
Expand Down Expand Up @@ -456,8 +453,8 @@ int DecDCTvlcContinue2(VLC_Context *ctx, uint32_t *buf, size_t max_size);
* additionally, the maximum output buffer size is not passed as an argument
* but is instead set by calling DecDCTvlcSize2().
*
* This function behaves identically to DecDCTvlcContinue() if bs = 0 and
* DecDCTvlcStart() otherwise. The table argument can optionally be passed to
* This function behaves identically to DecDCTvlcContinue2() if bs = 0 and
* DecDCTvlcStart2() otherwise. The table argument can optionally be passed to
* use a custom lookup table. If zero, the last pointer passed to
* DecDCTvlcBuild() will be used.
*
Expand Down
13 changes: 9 additions & 4 deletions libpsn00b/include/psxsn.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,29 @@
* write access to a directory on the host's filesystem when the executable is
* running on an emulator or through a debugger that supports the PCDRV
* protocol, such as Unirom or pcsx-redux. These functions are completely
* separate and independent from the BIOS file API and do not register any
* device drivers.
* separate and independent from the file APIs provided by the BIOS and do not
* register any device drivers.
*
* Note that in the official SDK these functions are provided by libsn, while
* in PSn00bSDK they are part of libpsxapi.
*
* IMPORTANT: as these function rely on break instructions internally, calling
* them on real hardware without a PCDRV handler installed or on an emulator
* that does not support the API will result in an uncaught break exception,
* which will cause the BIOS to get stuck in an infinite loop.
*/

#pragma once

#include <stddef.h>

typedef enum _PCDRV_OpenMode {
typedef enum {
PCDRV_MODE_READ = 0,
PCDRV_MODE_WRITE = 1,
PCDRV_MODE_READ_WRITE = 2
} PCDRV_OpenMode;

typedef enum _PCDRV_SeekMode {
typedef enum {
PCDRV_SEEK_SET = 0,
PCDRV_SEEK_CUR = 1,
PCDRV_SEEK_END = 2
Expand Down
2 changes: 1 addition & 1 deletion libpsn00b/libc/malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ __attribute__((weak)) void *realloc(void *ptr, size_t size) {
}

// No luck.
void *new = malloc(_size);
void *new = malloc(size);
if (!new)
return 0;

Expand Down
17 changes: 7 additions & 10 deletions libpsn00b/libc/start.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,13 @@ extern uint8_t _end[];
extern void (*__CTOR_LIST__[])(void);
extern void (*__DTOR_LIST__[])(void);

extern int main(int argc, const char* argv[]);
extern int main(int argc, const char **argv);

// Even though _start() usually takes no arguments, this implementation allows
// parent executables to pass args directly to child executables without having
// to overwrite the arg strings in kernel RAM.
void _start_inner(int argc, const char **argv) {
//__asm__ volatile("la $gp, _gp;");

// BSS is always aligned to 4 bytes by the linker script.
for (uint32_t *i = (uint32_t *) __bss_start; i < (uint32_t *) _end; i++)
*i = 0;
int _start_inner(int argc, const char **argv) {
__builtin_memset(__bss_start, 0, (void *) _end - (void *) __bss_start);

// Initialize the heap and place it after the executable, assuming 2 MB of
// RAM. Note that InitHeap() can be called again in main().
Expand All @@ -91,11 +87,12 @@ void _start_inner(int argc, const char **argv) {
for (int i = (int) __CTOR_LIST__[0]; i >= 1; i--)
__CTOR_LIST__[i]();

// Store main()'s return value into the kernel return value area (for child
// executables).
*KERNEL_RETURN_VALUE = main(__argc, __argv);
int value = main(argc, argv);

// Call global destructors (in forward order).
for (int i = 0; i < (int) __DTOR_LIST__[0]; i++)
__DTOR_LIST__[i + 1]();

//*KERNEL_RETURN_VALUE = value;
return value;
}
14 changes: 7 additions & 7 deletions libpsn00b/psxcd/isofs.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ typedef struct _CdlDIR_INT
extern volatile int _cd_media_changed;


static int _cd_iso_last_dir_lba;
static uint8_t _cd_iso_descriptor_buff[2048];
static uint8_t *_cd_iso_pathtable_buff=NULL;
static uint8_t *_cd_iso_directory_buff=NULL;
static int _cd_iso_directory_len;
static int _cd_iso_error=0;
static int _cd_iso_last_dir_lba;
static uint8_t _cd_iso_descriptor_buff[2048];
static uint8_t *_cd_iso_pathtable_buff=NULL;
static uint8_t *_cd_iso_directory_buff=NULL;
static int _cd_iso_directory_len;
static CdlIsoError _cd_iso_error=CdlIsoOkay;

static int _CdReadIsoDescriptor(int session_offs)
{
Expand Down Expand Up @@ -721,7 +721,7 @@ void CdCloseDir(CdlDIR *dir)
free( d_dir );
}

int CdIsoError()
CdlIsoError CdIsoError()
{
return _cd_iso_error;
}
Expand Down
4 changes: 2 additions & 2 deletions libpsn00b/psxgpu/drawing.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ void DrawBufferIRQ2(const uint32_t *buf, size_t length) {
_send_buffer(DRAWOP_TYPE_GPU_IRQ, buf, length);
}

void DrawPrim(const uint32_t *pri) {
void DrawPrim(const void *pri) {
_sdk_validate_args_void(pri);

DrawSync(0);
DrawBuffer2(&pri[1], getlen(pri));
DrawBuffer2(((const uint32_t *) pri) + 1, getlen(pri));
}

/* Helper functions */
Expand Down
18 changes: 13 additions & 5 deletions libpsn00b/psxgpu/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,24 @@ static void _dma_transfer(const RECT *rect, uint32_t *data, int write) {
GPU_GP1 = 0x04000000; // Disable DMA request
GPU_GP0 = 0x01000000; // Flush cache

GPU_GP0 = write ? 0xa0000000 : 0xc0000000;
uint32_t dreq_mode, status_mask;
if (write) {
GPU_GP0 = 0xa0000000; // Begin VRAM write
dreq_mode = 0x04000002; // Enable DMA request, route to GP0
status_mask = 1 << 28;
} else {
GPU_GP0 = 0xc0000000; // Begin VRAM read
dreq_mode = 0x04000003; // Enable DMA request, route to GPU_READ
status_mask = 1 << 27;
}

//GPU_GP0 = rect->x | (rect->y << 16);
GPU_GP0 = *((const uint32_t *) &(rect->x));
//GPU_GP0 = rect->w | (rect->h << 16);
GPU_GP0 = *((const uint32_t *) &(rect->w));
GPU_GP1 = dreq_mode;

// Enable DMA request, route to GP0 (2) or from GPU_READ (3)
GPU_GP1 = 0x04000002 | (write ^ 1);

while ((DMA_CHCR(DMA_GPU) & (1 << 24)) || !(GPU_GP1 & (1 << 28)))
while ((DMA_CHCR(DMA_GPU) & (1 << 24)) || !(GPU_GP1 & status_mask))
__asm__ volatile("");

DMA_MADR(DMA_GPU) = (uint32_t) data;
Expand Down
Loading

0 comments on commit dd85f9f

Please sign in to comment.