aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspicyjpeg <88942473+spicyjpeg@users.noreply.github.com>2022-06-29 12:40:46 +0200
committerspicyjpeg <88942473+spicyjpeg@users.noreply.github.com>2022-06-29 12:40:46 +0200
commit6120304537470e7e5ff94b3bf19a33787ca69083 (patch)
treef489c6dceae0846184dddd38444ef8519f799f7b
parent578181ace1374e72cb93d69d2c201ce7a0a2300c (diff)
downloadpsn00bsdk-6120304537470e7e5ff94b3bf19a33787ca69083.tar.gz
Refactor libpsxgpu in C, add OT drawing queue
-rw-r--r--examples/demos/n00bdemo/disp.c2
-rw-r--r--examples/sound/vagsample/main.c2
-rw-r--r--libpsn00b/CMakeLists.txt2
-rw-r--r--libpsn00b/include/psxgpu.h69
-rw-r--r--libpsn00b/psxgpu/addprim.s26
-rw-r--r--libpsn00b/psxgpu/clearotagr.s21
-rw-r--r--libpsn00b/psxgpu/common.c293
-rw-r--r--libpsn00b/psxgpu/dbugfont.c144
-rw-r--r--libpsn00b/psxgpu/drawotag.s38
-rw-r--r--libpsn00b/psxgpu/drawprim.s41
-rw-r--r--libpsn00b/psxgpu/drawsync.s67
-rw-r--r--libpsn00b/psxgpu/drawsynccallback.s105
-rw-r--r--libpsn00b/psxgpu/env.c213
-rw-r--r--libpsn00b/psxgpu/fntsort.c48
-rw-r--r--libpsn00b/psxgpu/font.c47
-rw-r--r--libpsn00b/psxgpu/getode.s20
-rw-r--r--libpsn00b/psxgpu/gettimimage.c40
-rw-r--r--libpsn00b/psxgpu/getvideomode.s14
-rw-r--r--libpsn00b/psxgpu/image.c116
-rw-r--r--libpsn00b/psxgpu/loadimage.s70
-rw-r--r--libpsn00b/psxgpu/putdispenv.s174
-rw-r--r--libpsn00b/psxgpu/putdispenvraw.s71
-rw-r--r--libpsn00b/psxgpu/putdrawenv.s142
-rw-r--r--libpsn00b/psxgpu/readgpustat.s14
-rw-r--r--libpsn00b/psxgpu/readme.txt22
-rw-r--r--libpsn00b/psxgpu/resetgraph.s363
-rw-r--r--libpsn00b/psxgpu/setdefdispenv.c22
-rw-r--r--libpsn00b/psxgpu/setdefdrawenv.c27
-rw-r--r--libpsn00b/psxgpu/setdispmask.s19
-rw-r--r--libpsn00b/psxgpu/setvideomode.s50
-rw-r--r--libpsn00b/psxgpu/storeimage.s76
-rw-r--r--libpsn00b/psxgpu/vsynccallback.s25
32 files changed, 722 insertions, 1661 deletions
diff --git a/examples/demos/n00bdemo/disp.c b/examples/demos/n00bdemo/disp.c
index c134163..d8d2bbf 100644
--- a/examples/demos/n00bdemo/disp.c
+++ b/examples/demos/n00bdemo/disp.c
@@ -19,7 +19,7 @@ MATRIX mtx;
void initDisplay() {
- ResetGraph( 3 );
+ ResetGraph( 0 );
if( GetVideoMode() == MODE_NTSC ) {
SetDefDispEnv( &disp, 0, 0, 640, 480 );
diff --git a/examples/sound/vagsample/main.c b/examples/sound/vagsample/main.c
index 2b04c34..5764541 100644
--- a/examples/sound/vagsample/main.c
+++ b/examples/sound/vagsample/main.c
@@ -127,7 +127,7 @@ void init(void)
// Begin pad polling
InitPAD( pad_buff[0], 34, pad_buff[1], 34 );
StartPAD();
-
+ ChangeClearPAD(0);
} /* init */
// Display function
diff --git a/libpsn00b/CMakeLists.txt b/libpsn00b/CMakeLists.txt
index f9c4f9d..a662448 100644
--- a/libpsn00b/CMakeLists.txt
+++ b/libpsn00b/CMakeLists.txt
@@ -40,6 +40,8 @@ foreach(_library IN LISTS PSN00BSDK_LIBRARIES)
psn00bsdk_add_library(${_library} STATIC ${_sources})
endforeach()
+psn00bsdk_target_incbin(psxgpu PRIVATE _gpu_debug_font psxgpu/dbugfont.tim)
+
# Extract libgcc's contents and merge them into libc after building.
# Unfortunately glob expressions won't work on Windows, so we have to manually
# enumerate the contents of libgcc and save the list to a temporary file (as it
diff --git a/libpsn00b/include/psxgpu.h b/libpsn00b/include/psxgpu.h
index f061219..53a24c9 100644
--- a/libpsn00b/include/psxgpu.h
+++ b/libpsn00b/include/psxgpu.h
@@ -1,6 +1,7 @@
#ifndef __PSXGPU_H
#define __PSXGPU_H
+#include <stddef.h>
#include <sys/types.h>
// Low-level display parameters for DISPENV_RAW. A leftover from prototyping
@@ -17,10 +18,11 @@
#define DISP_MODE_NTSC 0
#define DISP_MODE_PAL 8
-
-#define MODE_NTSC 0
-#define MODE_PAL 1
-
+typedef enum _VIDEO_MODE
+{
+ MODE_NTSC = 0,
+ MODE_PAL = 1
+} VIDEO_MODE;
// Vector macros
@@ -89,6 +91,12 @@
#define setWH( p, _w, _h ) \
(p)->w = _w, (p)->h = _h
+#define setXYWH( p, _x0, _y0, _w, _h ) \
+ (p)->x0 = _x0, (p)->y0 = _y0, \
+ (p)->x1 = _x0+(_w), (p)->y1 = _y0, \
+ (p)->x2 = _x0, (p)->y2 = _y0+(_h), \
+ (p)->x3 = _x0+(_w), (p)->y3 = _y0+(_h)
+
/*
* Set texture coordinates
*/
@@ -569,50 +577,61 @@ typedef struct _TIM_IMAGE
u_long *paddr;
} TIM_IMAGE;
+typedef struct _GsIMAGE
+{
+ u_long pmode;
+ short px, py, pw, ph;
+ u_long *pixel;
+ short cx, cy, cw, ch;
+ u_long *clut;
+} GsIMAGE;
#ifdef __cplusplus
extern "C" {
#endif
-// Function definitions (asm)
+// Function definitions
void ResetGraph(int mode);
-int GetVideoMode(void);
-void SetVideoMode(int mode);
+VIDEO_MODE GetVideoMode(void);
+void SetVideoMode(VIDEO_MODE mode);
int GetODE(void);
-void PutDispEnvRaw(DISPENV_RAW *disp); /* obsolete */
-void PutDispEnv(DISPENV *disp);
-void PutDrawEnv(DRAWENV *draw);
+void PutDispEnvRaw(const DISPENV_RAW *env); /* obsolete */
+void PutDispEnv(const DISPENV *env);
+void PutDrawEnv(DRAWENV *env);
+void PutDrawEnvFast(DRAWENV *env);
void SetDispMask(int mask);
-int VSync(int m);
-int DrawSync(int m);
-void WaitGPUcmd(void);
-void WaitGPUdma(void);
+int VSync(int mode);
+int DrawSync(int mode);
+//void WaitGPUcmd(void);
+//void WaitGPUdma(void);
// Callback hook functions
void *VSyncCallback(void (*func)(void));
void *DrawSyncCallback(void (*func)(void));
-void LoadImage(RECT *rect, u_long *data);
-void StoreImage(RECT *rect, u_long *data);
-
-void ClearOTagR(u_long* ot, int n);
-void DrawOTag(u_long* ot);
-void DrawPrim(void *pri);
+void LoadImage(const RECT *rect, const u_long *data);
+void StoreImage(const RECT *rect, u_long *data);
-void AddPrim(u_long* ot, void* pri);
+void ClearOTagR(u_long *ot, size_t length);
+void ClearOTag(u_long *ot, size_t length);
+void DrawOTag(const u_long *ot);
+void DrawOTag2(const u_long *ot);
+void DrawOTagEnv(const u_long *ot, DRAWENV *env);
+void DrawPrim(const u_long *pri);
-// Function definitions (C)
+void AddPrim(u_long *ot, const void *pri);
-int GetTimInfo(const u_long *tim, TIM_IMAGE *timimg); /* ORIGINAL */
+int GsGetTimInfo(const u_long *tim, GsIMAGE *info);
+int GetTimInfo(const u_long *tim, TIM_IMAGE *info); /* deprecated */
-DISPENV *SetDefDispEnv(DISPENV *disp, int x, int y, int w, int h);
-DRAWENV *SetDefDrawEnv(DRAWENV *draw, int x, int y, int w, int h);
+DISPENV *SetDefDispEnv(DISPENV *env, int x, int y, int w, int h);
+DRAWENV *SetDefDrawEnv(DRAWENV *env, int x, int y, int w, int h);
// Debug font functions
diff --git a/libpsn00b/psxgpu/addprim.s b/libpsn00b/psxgpu/addprim.s
deleted file mode 100644
index 1b66274..0000000
--- a/libpsn00b/psxgpu/addprim.s
+++ /dev/null
@@ -1,26 +0,0 @@
-.set noreorder
-.set noat
-
-.section .text
-
-
-.global AddPrim
-.type AddPrim, @function
-AddPrim:
-
- lw $v0, 0($a0) # Load OT entry
- lw $v1, 0($a1) # Set packet length value (in words)
- lui $at, 0x00ff
- or $at, 0xffff
- and $v0, $at # Mask off the upper 8 bits of OT entry
- or $v1, $v0 # OR values together
- sw $v1, 0($a1) # Store new address to primitive tag
- lw $v0, 0($a0) # Load OT entry
- and $a1, $at # Mask off the upper 8 bits of primitive tag
- lui $at, 0xff00
- and $v0, $at # Mask off the first 24 bits of OT entry
- or $v0, $a1 # OR values together
-
- jr $ra
- sw $v0, 0($a0) # Store result to OT
-
diff --git a/libpsn00b/psxgpu/clearotagr.s b/libpsn00b/psxgpu/clearotagr.s
deleted file mode 100644
index 562cad4..0000000
--- a/libpsn00b/psxgpu/clearotagr.s
+++ /dev/null
@@ -1,21 +0,0 @@
-.set noreorder
-
-.include "hwregs_a.h"
-
-.section .text
-
-
-.global ClearOTagR
-.type ClearOTagR, @function
-ClearOTagR:
- lui $a2, IOBASE
- addi $v0, $a1, -1
- sll $v0, 2
- addu $a0, $v0
- sw $a0, DMA6_MADR($a2)
- andi $a1, 0xffff
- sw $a1, DMA6_BCR($a2)
- lui $v0, 0x1100
- addiu $v0, 2
- jr $ra
- sw $v0, DMA6_CHCR($a2)
diff --git a/libpsn00b/psxgpu/common.c b/libpsn00b/psxgpu/common.c
new file mode 100644
index 0000000..ee90225
--- /dev/null
+++ b/libpsn00b/psxgpu/common.c
@@ -0,0 +1,293 @@
+/*
+ * PSn00bSDK GPU library (common functions)
+ * (C) 2022 spicyjpeg - MPL licensed
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <psxetc.h>
+#include <psxapi.h>
+#include <psxgpu.h>
+#include <hwregs_c.h>
+
+#define QUEUE_LENGTH 8
+#define DMA_CHUNK_LENGTH 8
+#define VSYNC_TIMEOUT 0x100000
+
+/* Internal globals */
+
+VIDEO_MODE _gpu_video_mode;
+
+static void (*_vsync_callback)(void);
+static void (*_drawsync_callback)(void);
+
+static const u_long *volatile _draw_queue[QUEUE_LENGTH];
+static volatile uint8_t _queue_head, _queue_tail, _queue_length;
+static volatile uint32_t _vblank_counter, _last_hblank;
+
+/* Interrupt handlers */
+
+static void _vblank_handler(void) {
+ _vblank_counter++;
+
+ if (_vsync_callback)
+ _vsync_callback();
+}
+
+static void _gpu_dma_handler(void) {
+ //while (DMA_CHCR(2) & (1 << 24))
+ //__asm__ volatile("");
+ while (!(GPU_GP1 & (1 << 28)))
+ __asm__ volatile("");
+
+ if (_queue_length) {
+ DrawOTag2(_draw_queue[_queue_head++]);
+
+ _queue_length--;
+ _queue_head %= QUEUE_LENGTH;
+ } else {
+ GPU_GP1 = 0x04000000; // Disable DMA request
+
+ if (_drawsync_callback)
+ _drawsync_callback();
+ }
+}
+
+/* GPU reset and system initialization */
+
+void ResetGraph(int mode) {
+ // Perform some basic system initialization when ResetGraph() is called for
+ // the first time.
+ static int setup_done = 0;
+ if (!setup_done) {
+ EnterCriticalSection();
+
+ DMA_DPCR = 0x03333333;
+ DMA_DICR = 0;
+ IRQ_MASK = 0;
+
+ InterruptCallback(0, &_vblank_handler);
+ DMACallback(2, &_gpu_dma_handler);
+ RestartCallback();
+ _96_remove();
+
+ _gpu_video_mode = (GPU_GP1 >> 20) & 1;
+ setup_done = 1;
+
+ ExitCriticalSection();
+ printf("psxgpu: setup done, default mode is %s\n", _gpu_video_mode ? "PAL" : "NTSC");
+ }
+
+ if (mode == 3) {
+ GPU_GP1 = 0x01000000; // Reset command buffer
+ return;
+ }
+
+ DMA_DPCR |= 0x0b000b00; // Enable DMA2 and DMA6
+ DMA_CHCR(2) = 0x00000201; // Stop DMA2
+ DMA_CHCR(6) = 0x00000200; // Stop DMA6
+
+ if (mode == 1) {
+ GPU_GP1 = 0x01000000; // Reset command buffer
+ return;
+ }
+
+ GPU_GP1 = 0x00000000; // Reset GPU
+ TIMER_CTRL(0) = 0x0500;
+ TIMER_CTRL(1) = 0x0500;
+
+ _queue_head = 0;
+ _queue_tail = 0;
+ _queue_length = 0;
+ _vblank_counter = 0;
+ _last_hblank = 0;
+}
+
+/* Syncing API */
+
+// TODO: add support for no$psx's "halt" register
+static void _vsync_halt(void) {
+ int counter = _vblank_counter;
+
+ for (int i = VSYNC_TIMEOUT; i; i--) {
+ if (counter != _vblank_counter)
+ return;
+ }
+
+ printf("psxgpu: VSync() timeout\n");
+ ChangeClearPAD(0);
+ ChangeClearRCnt(3, 0);
+ return;
+}
+
+int VSync(int mode) {
+ if (mode < 0)
+ return _vblank_counter;
+
+ uint32_t status = GPU_GP1;
+
+ // If mode = 0, wait for one vertical blank event to occur. If mode = 1, do
+ // not wait.
+ for (int i = ((mode < 2) ? (mode ^ 1) : mode); i; i--) {
+ _vsync_halt();
+
+ // If interlaced mode is enabled, wait until the GPU starts displaying
+ // the next field.
+ if (status & (1 << 22)) {
+ while (!((GPU_GP1 ^ status) & (1 << 31)))
+ __asm__ volatile("");
+ }
+ }
+
+ // Update the horizontal blank counter and return the time elapsed since
+ // the last time it was updated.
+ uint16_t counter = TIMER_VALUE(1);
+ uint16_t delta = counter - _last_hblank;
+
+ _last_hblank = counter;
+ return delta;
+}
+
+int DrawSync(int mode) {
+ if (mode)
+ return (DMA_BCR(2) >> 16);
+
+ // Wait for the queue to become empty, to make sure no .
+ // TODO: add a timeout
+ while (_queue_length)
+ __asm__ volatile("");
+
+ // Wait for any DMA transfer to finish if DMA is enabled.
+ if (GPU_GP1 & (3 << 29)) {
+ while (DMA_CHCR(2) & (1 << 24))
+ __asm__ volatile("");
+ while (!(GPU_GP1 & (1 << 28)))
+ __asm__ volatile("");
+ }
+
+ while (!(GPU_GP1 & (1 << 26)))
+ __asm__ volatile("");
+
+ return 0;
+}
+
+void *VSyncCallback(void (*func)(void)) {
+ EnterCriticalSection();
+
+ void *old_callback = _vsync_callback;
+ _vsync_callback = func;
+
+ ExitCriticalSection();
+ return old_callback;
+}
+
+void *DrawSyncCallback(void (*func)(void)) {
+ EnterCriticalSection();
+
+ void *old_callback = _drawsync_callback;
+ _drawsync_callback = func;
+
+ ExitCriticalSection();
+ return old_callback;
+}
+
+/* OT and primitive drawing API */
+
+void ClearOTagR(u_long *ot, size_t length) {
+ DMA_MADR(6) = (uint32_t) &ot[length - 1];
+ DMA_BCR(6) = length & 0xffff;
+ DMA_CHCR(6) = 0x11000002;
+
+ //while (DMA_CHCR(6) & (1 << 24))
+ //__asm__ volatile("");
+}
+
+void ClearOTag(u_long *ot, size_t length) {
+ // DMA6 only supports writing to RAM in reverse order (last to first), so
+ // the OT has to be cleared in software here. This function is thus much
+ // slower than ClearOTagR().
+ // https://problemkaputt.de/psx-spx.htm#dmachannels
+ for (int i = 0; i < (length - 1); i++)
+ ot[i] = (u_long) &ot[i + 1] & 0x00ffffff;
+
+ ot[length - 1] = 0x00ffffff;
+}
+
+void DrawOTag(const u_long *ot) {
+ // If GPU DMA is currently busy, append the OT to the queue instead of
+ // drawing it immediately.
+ if (DMA_CHCR(2) & (1 << 24)) {
+ if (_queue_length >= QUEUE_LENGTH) {
+ printf("psxgpu: DrawOTag() failed, draw queue full\n");
+ return;
+ }
+
+ _draw_queue[_queue_tail++] = ot;
+ _queue_length++;
+ _queue_tail %= QUEUE_LENGTH;
+ return;
+ }
+
+ DrawOTag2(ot);
+}
+
+void DrawOTag2(const u_long *ot) {
+ GPU_GP1 = 0x04000002;
+
+ while (!(GPU_GP1 & (1 << 26)))
+ __asm__ volatile("");
+
+ DMA_MADR(2) = (uint32_t) ot;
+ DMA_BCR(2) = 0;
+ DMA_CHCR(2) = 0x01000401;
+}
+
+void DrawPrim(const u_long *pri) {
+ size_t length = getlen(pri);
+
+ DrawSync(0);
+ GPU_GP1 = 0x04000002;
+
+ // NOTE: if length >= DMA_CHUNK_LENGTH then it also has to be a multiple of
+ // DMA_CHUNK_LENGTH, otherwise the DMA channel will get stuck waiting for
+ // more data indefinitely.
+ DMA_MADR(2) = (uint32_t) &pri[1];
+ if (length < DMA_CHUNK_LENGTH)
+ DMA_BCR(2) = 0x00010000 | length;
+ else
+ DMA_BCR(2) = DMA_CHUNK_LENGTH | ((length / DMA_CHUNK_LENGTH) << 16);
+
+ DMA_CHCR(2) = 0x01000201;
+}
+
+void AddPrim(u_long *ot, const void *pri) {
+ addPrim(ot, pri);
+}
+
+/* Misc. functions */
+
+VIDEO_MODE GetVideoMode(void) {
+ return _gpu_video_mode;
+}
+
+void SetVideoMode(VIDEO_MODE mode) {
+ uint32_t _mode, stat = GPU_GP1;
+
+ _gpu_video_mode = mode & 1;
+
+ _mode = (mode & 1) << 3;
+ _mode |= (stat >> 17) & 0x37; // GPUSTAT 17-22 -> cmd bits 0-5
+ _mode |= (stat >> 10) & 0x40; // GPUSTAT bit 16 -> cmd bit 6
+ _mode |= (stat >> 7) & 0x80; // GPUSTAT bit 14 -> cmd bit 7
+
+ GPU_GP1 = 0x08000000 | mode;
+}
+
+int GetODE(void) {
+ return (GPU_GP1 >> 31);
+}
+
+void SetDispMask(int mask) {
+ GPU_GP1 = 0x03000000 | (mask ? 0 : 1);
+}
diff --git a/libpsn00b/psxgpu/dbugfont.c b/libpsn00b/psxgpu/dbugfont.c
deleted file mode 100644
index ff21d84..0000000
--- a/libpsn00b/psxgpu/dbugfont.c
+++ /dev/null
@@ -1,144 +0,0 @@
-unsigned int dbugfont_size=2112;
-unsigned char dbugfont[] = {
-0x10,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x00,0xe0,
-0x01,0x10,0x00,0x01,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x08,0x00,0x00,0x80,0x02,0x00,0x00,
-0x20,0x00,0x20,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,
-0x00,0x10,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x11,
-0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x11,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,
-0x00,0x00,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
-0x01,0x00,0x00,0x11,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
-0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x01,0x00,
-0x00,0x00,0x00,0x00,0x00,0x10,0x11,0x11,0x00,0x01,0x01,0x00,0x00,0x11,0x01,
-0x01,0x00,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x10,0x00,0x00,0x00,0x00,
-0x10,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x10,0x00,0x11,
-0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x10,0x11,
-0x00,0x00,0x10,0x10,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x10,
-0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x11,0x00,0x00,0x11,0x11,0x01,0x00,
-0x00,0x00,0x00,0x00,0x11,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,
-0x00,0x10,0x10,0x10,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x11,
-0x11,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x01,0x10,0x01,0x00,0x00,
-0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x01,0x01,0x01,0x00,
-0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x01,0x00,0x00,0x10,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x10,0x10,0x11,0x00,0x01,
-0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,
-0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x11,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x01,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x10,0x11,0x00,0x00,0x01,
-0x00,0x01,0x00,0x10,0x01,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,
-0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x11,
-0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x11,0x01,0x00,0x00,
-0x11,0x01,0x00,0x00,0x10,0x01,0x00,0x10,0x11,0x11,0x00,0x00,0x10,0x01,0x00,
-0x10,0x11,0x11,0x00,0x00,0x11,0x01,0x00,0x00,0x11,0x01,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x10,0x00,
-0x00,0x00,0x00,0x11,0x01,0x00,0x00,0x11,0x11,0x00,0x00,0x11,0x00,0x00,0x10,
-0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x01,0x01,0x00,0x10,0x00,0x00,0x00,
-0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,
-0x00,0x00,0x11,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x01,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x01,0x10,
-0x10,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x01,0x00,
-0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,
-0x00,0x10,0x00,0x10,0x00,0x00,0x11,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x01,
-0x00,0x00,0x10,0x11,0x11,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x00,0x10,
-0x10,0x01,0x01,0x00,0x10,0x00,0x00,0x00,0x10,0x01,0x00,0x00,0x10,0x01,0x00,
-0x10,0x11,0x11,0x00,0x10,0x11,0x01,0x00,0x10,0x11,0x01,0x00,0x00,0x00,0x01,
-0x00,0x00,0x11,0x01,0x00,0x00,0x11,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
-0x00,0x01,0x00,0x10,0x10,0x01,0x01,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x00,
-0x00,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,
-0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x10,0x11,0x11,0x00,0x00,
-0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x10,0x11,0x00,0x00,0x10,0x00,0x00,
-0x10,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x10,
-0x00,0x10,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x00,
-0x01,0x00,0x00,0x11,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
-0x10,0x11,0x11,0x00,0x10,0x11,0x11,0x00,0x00,0x11,0x01,0x00,0x00,0x00,0x01,
-0x00,0x10,0x11,0x01,0x00,0x00,0x11,0x01,0x00,0x00,0x10,0x00,0x00,0x00,0x11,
-0x01,0x00,0x00,0x11,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x11,0x00,0x00,0x00,
-0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x00,0x00,
-0x00,0x11,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,
-0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x11,0x01,
-0x00,0x00,0x11,0x01,0x00,0x10,0x11,0x01,0x00,0x10,0x11,0x11,0x00,0x10,0x11,
-0x11,0x00,0x00,0x11,0x11,0x00,0x10,0x00,0x10,0x00,0x10,0x11,0x11,0x00,0x00,
-0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x10,0x00,
-0x10,0x00,0x10,0x00,0x00,0x11,0x01,0x00,0x10,0x11,0x01,0x00,0x00,0x01,0x01,
-0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
-0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,
-0x10,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,
-0x10,0x01,0x11,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,
-0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x10,0x00,
-0x10,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,
-0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x01,0x00,
-0x10,0x00,0x00,0x00,0x10,0x10,0x10,0x00,0x10,0x01,0x10,0x00,0x10,0x00,0x10,
-0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x11,0x01,0x00,0x10,0x00,
-0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x11,0x00,0x00,0x10,0x11,0x00,0x00,0x10,
-0x10,0x11,0x00,0x10,0x11,0x11,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x00,
-0x10,0x11,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x10,0x10,
-0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x11,0x11,0x00,0x10,0x00,
-0x10,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x10,
-0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x10,0x00,0x00,
-0x10,0x00,0x10,0x00,0x10,0x00,0x01,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x10,
-0x00,0x10,0x00,0x11,0x00,0x10,0x00,0x10,0x00,0x10,0x11,0x01,0x00,0x10,0x00,
-0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,
-0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
-0x00,0x10,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,
-0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
-0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x11,0x01,0x00,0x00,0x11,0x01,0x00,0x10,
-0x11,0x01,0x00,0x10,0x11,0x11,0x00,0x10,0x00,0x00,0x00,0x00,0x11,0x01,0x00,
-0x10,0x00,0x10,0x00,0x10,0x11,0x11,0x00,0x00,0x11,0x01,0x00,0x10,0x00,0x10,
-0x00,0x10,0x11,0x11,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x11,
-0x01,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x01,0x00,0x10,
-0x11,0x01,0x00,0x00,0x11,0x01,0x00,0x10,0x11,0x11,0x00,0x10,0x00,0x10,0x00,
-0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,
-0x00,0x10,0x11,0x11,0x00,0x00,0x11,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x11,
-0x01,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x10,
-0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x10,0x00,0x00,
-0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,
-0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x01,0x00,0x00,0x10,0x00,
-0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
-0x11,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,
-0x00,0x10,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,
-0x00,0x00,0x01,0x01,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x01,
-0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x10,0x01,0x11,0x00,0x00,
-0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x11,0x01,0x00,
-0x00,0x11,0x01,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,
-0x00,0x10,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x10,
-0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x00,
-0x10,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x10,
-0x00,0x10,0x00,0x10,0x00,0x10,0x10,0x10,0x00,0x00,0x01,0x01,0x00,0x00,0x10,
-0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
-0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x10,0x00,0x01,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x10,0x00,
-0x00,0x10,0x00,0x10,0x00,0x00,0x01,0x01,0x00,0x10,0x01,0x11,0x00,0x10,0x00,
-0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
-0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x11,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x11,0x01,
-0x00,0x00,0x10,0x00,0x00,0x00,0x11,0x01,0x00,0x00,0x10,0x00,0x00,0x10,0x00,
-0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x11,0x11,0x00,0x00,
-0x11,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x11,0x01,0x00,0x00,0x00,0x00,0x00,
-0x11,0x11,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-};
diff --git a/libpsn00b/psxgpu/drawotag.s b/libpsn00b/psxgpu/drawotag.s
deleted file mode 100644
index 3cb0db0..0000000
--- a/libpsn00b/psxgpu/drawotag.s
+++ /dev/null
@@ -1,38 +0,0 @@
-.set noreorder
-
-.include "hwregs_a.h"
-
-.section .text
-
-
-.global DrawOTag
-.type DrawOTag, @function
-DrawOTag:
- addiu $sp, -4
- sw $ra, 0($sp)
-
- lui $a3, IOBASE # I/O segment base
-
- lui $v0, 0x0400 # Set DMA direction to CPUtoGPU
- ori $v0, 0x2
- sw $v0, GPU_GP1($a3)
-
-.Lgpu_wait: # Wait for GPU to be ready for commands & DMA
- jal ReadGPUstat
- nop
- srl $v0, 26
- andi $v0, 1
- beqz $v0, .Lgpu_wait
- nop
-
- sw $a0, DMA2_MADR($a3) # Set DMA base address to specified OT
- sw $0 , DMA2_BCR($a3)
-
- lui $v0, 0x0100 # Begin OT transfer!
- ori $v0, 0x0401
- sw $v0, DMA2_CHCR($a3)
-
- lw $ra, 0($sp)
- addiu $sp, 4
- jr $ra
- nop
diff --git a/libpsn00b/psxgpu/drawprim.s b/libpsn00b/psxgpu/drawprim.s
deleted file mode 100644
index d62c202..0000000
--- a/libpsn00b/psxgpu/drawprim.s
+++ /dev/null
@@ -1,41 +0,0 @@
-.set noreorder
-
-.include "hwregs_a.h"
-
-.text
-
-.global DrawPrim
-.type DrawPrim, @function
-DrawPrim:
-
- addiu $sp, -8
- sw $ra, 0($sp)
- sw $s0, 4($sp)
-
- move $s0, $a0 # Wait for GPU to complete
- jal DrawSync
- move $a0, $0
-
- lui $a3, IOBASE
- lui $v0, 0x0400 # Set transfer direction to off
- sw $v0, GPU_GP1($a3)
-
- move $a0, $s0
- lbu $a1, 3($a0) # Get length of primitive packet
- addiu $a0, 4
- addiu $a1, -1
-
-.Ltransfer_loop:
- lw $v0, 0($a0)
- addiu $a0, 4
- sw $v0, GPU_GP0($a3)
- bgtz $a1, .Ltransfer_loop
- addiu $a1, -1
-
- jal DrawSync
- move $a0, $0
-
- lw $ra, 0($sp)
- lw $s0, 4($sp)
- jr $ra
- addiu $sp, 8 \ No newline at end of file
diff --git a/libpsn00b/psxgpu/drawsync.s b/libpsn00b/psxgpu/drawsync.s
deleted file mode 100644
index b671b03..0000000
--- a/libpsn00b/psxgpu/drawsync.s
+++ /dev/null
@@ -1,67 +0,0 @@
-.set noreorder
-
-.include "hwregs_a.h"
-
-.section .text
-
-
-.global DrawSync
-.type DrawSync, @function
-DrawSync:
-
- bnez $a0, .Lgetwords
- lui $a0, IOBASE
-
- addiu $sp, -4
- sw $ra, 0($sp)
-
- jal ReadGPUstat # Check if DMA enabled
- nop
- srl $v0, 29
- andi $v0, 0x3
-
- beqz $v0, .Lsimple_wait
- nop
-
-.Ldma_wait:
- lw $v0, DMA2_CHCR($a0)
- nop
- srl $v0, 24
- andi $v0, 0x1
- bnez $v0, .Ldma_wait
- nop
-
-.Lgpu_wait:
- jal ReadGPUstat
- nop
- srl $v0, 26
- andi $v0, 0x5
- bne $v0, 5, .Lgpu_wait
- nop
-
- b .Lexit
- nop
-
-.Lsimple_wait: # Wait for GPU to be ready for next DMA
- jal ReadGPUstat
- nop
- srl $v0, 28
- andi $v0, 0x1
- beqz $v0, .Lsimple_wait
- nop
-
-.Lexit:
-
- lw $ra, 0($sp)
- addiu $sp, 4
- jr $ra
- nop
-
-.Lgetwords:
-
- lw $v0, DMA2_BCR($a0)
- nop
-
- jr $ra
- srl $v0, 16
-
diff --git a/libpsn00b/psxgpu/drawsynccallback.s b/libpsn00b/psxgpu/drawsynccallback.s
deleted file mode 100644
index 22cfb7d..0000000
--- a/libpsn00b/psxgpu/drawsynccallback.s
+++ /dev/null
@@ -1,105 +0,0 @@
-.set noreorder
-
-.include "hwregs_a.h"
-
-.text
-
-.global DrawSyncCallback
-.type DrawSyncCallback, @function
-DrawSyncCallback:
-
- addiu $sp, -8
- sw $ra, 0($sp)
- sw $a0, 4($sp)
-
- jal EnterCriticalSection
- nop
-
- beqz $a0, .Luninstall
- nop
-
- la $a1, _drawsync_handler
- lw $a1, 4($sp)
- jal DMACallback
- li $a0, 2
-
- b .Lcontinue
- nop
-
-.Luninstall:
-
- move $a1, $0
- jal DMACallback
- li $a0, 2
-
-.Lcontinue:
-
- lw $a0, 4($sp)
- la $v1, _drawsync_func
- lw $v0, 0($v1)
- sw $a0, 0($v1)
- sw $v0, 4($sp)
-
-.Lexit:
-
- jal ExitCriticalSection
- nop
-
- lw $ra, 0($sp)
- lw $v0, 4($sp)
- jr $ra
- addiu $sp, 8
-
-
-.type _drawsync_handler, @function
-_drawsync_handler:
-
-.Ldma_wait:
- la $v0, _drawsync_func
- lw $v0, 0($v0)
- nop
- beqz $v0, .Lskip
- nop
-
- addiu $sp, -4
- sw $ra, 0($sp)
-
- lw $v0, DMA2_CHCR($a0)
- nop
- srl $v0, 24
- andi $v0, 0x1
-
- bnez $v0, .Ldma_wait
- nop
-
-.Lgpu_wait:
- jal ReadGPUstat
- nop
- srl $v0, 28
- andi $v0, 0x1
- beqz $v0, .Lgpu_wait
- nop
-
- la $v1, _drawsync_func
- lw $v1, 0($v1)
-
- lui $v0, 0x0400 # Set DMA direction to off
- sw $v0, GPU_GP1($a0)
-
- jalr $v1
- nop
-
- lw $ra, 0($sp)
- addiu $sp, 4
-
-.Lskip:
-
- jr $ra
- nop
-
-
-.data
-
-_drawsync_func:
- .word 0
- \ No newline at end of file
diff --git a/libpsn00b/psxgpu/env.c b/libpsn00b/psxgpu/env.c
new file mode 100644
index 0000000..8a74b7e
--- /dev/null
+++ b/libpsn00b/psxgpu/env.c
@@ -0,0 +1,213 @@
+/*
+ * PSn00bSDK GPU library (DRAWENV/DISPENV functions)
+ * (C) 2022 spicyjpeg - MPL licensed
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <psxgpu.h>
+#include <hwregs_c.h>
+
+#define _min(x, y) (((x) < (y)) ? (x) : (y))
+
+extern VIDEO_MODE _gpu_video_mode;
+
+/* Drawing API */
+
+DRAWENV *SetDefDrawEnv(DRAWENV *env, int x, int y, int w, int h) {
+ env->clip.x = x;
+ env->clip.y = y;
+ env->clip.w = w;
+ env->clip.h = h;
+
+ env->ofs[0] = 0;
+ env->ofs[1] = 0;
+
+ env->tw.x = 0;
+ env->tw.y = 0;
+ env->tw.w = 0;
+ env->tw.h = 0;
+
+ env->tpage = 0x0a;
+ env->dtd = 1;
+ env->dfe = 0;
+ env->isbg = 0;
+ setRGB0(env, 0, 0, 0);
+
+ env->dr_env.tag = 0;
+ return env;
+}
+
+void DrawOTagEnv(const u_long *ot, DRAWENV *env) {
+ DR_ENV *prim = &(env->dr_env);
+
+ // All commands are grouped into a single display list packet for
+ // performance reasons (keep in mind that the GPU doesn't care about this
+ // as the display list is parsed by the DMA unit in the CPU and only the
+ // payload is sent to the GPU).
+ setaddr(prim, ot);
+ setlen(prim, 4);
+
+ // Set drawing area top left
+ prim->code[0] = 0xe3000000;
+ prim->code[0] |= env->clip.x & 0x3ff;
+ prim->code[0] |= (env->clip.y & 0x3ff) << 10;
+
+ // Set drawing area bottom right
+ prim->code[1] = 0xe4000000;
+ prim->code[1] |= (env->clip.x + (env->clip.w - 1)) & 0x3ff;
+ prim->code[1] |= ((env->clip.y + (env->clip.h - 1)) & 0x3ff) << 10;
+
+ // Set drawing offset
+ prim->code[2] = 0xe5000000;
+ prim->code[2] |= (env->clip.x + env->ofs[0]) & 0x7ff;
+ prim->code[2] |= ((env->clip.y + env->ofs[1]) & 0x7ff) << 11;
+
+ // Texture page (reset active page and set dither/mask bits)
+ prim->code[3] = 0xe1000000;
+ prim->code[3] |= (env->dtd & 1) << 9;
+ prim->code[3] |= (env->dfe & 1) << 10;
+
+ if (env->isbg) {
+ setlen(prim, 7);
+
+ // Rectangle fill
+ // FIXME: reportedly this command doesn't accept height values >511...
+ prim->code[4] = 0x02000000;
+ //prim->code[4] |= env->r0 | (env->g0 << 8) | (env->b0 << 16);
+ prim->code[4] |= *((const uint32_t *) &(env->isbg)) >> 8;
+ //prim->code[5] = env->clip.x;
+ //prim->code[5] |= env->clip.y << 16;
+ prim->code[5] = *((const uint32_t *) &(env->clip.x));
+ prim->code[6] = env->clip.w;
+ prim->code[6] |= _min(env->clip.h, 0x1ff) << 16;
+ }
+
+ //while (!(GPU_GP1 & (1 << 26)))
+ //__asm__ volatile("");
+
+ DrawOTag(prim);
+}
+
+void PutDrawEnv(DRAWENV *env) {
+ DrawOTagEnv((const u_long *) 0x00ffffff, env);
+}
+
+// This function skips rebuilding the cached packet whenever possible and is
+// useful if the DRAWENV structure is never modified (which is the case most of
+// the time).
+void PutDrawEnvFast(DRAWENV *env) {
+ if (!(env->dr_env.tag)) {
+ DrawOTagEnv((const u_long *) 0x00ffffff, env);
+ return;
+ }
+
+ DrawOTag(&(env->dr_env));
+}
+
+/* Display API */
+
+DISPENV *SetDefDispEnv(DISPENV *env, int x, int y, int w, int h) {
+ env->disp.x = x;
+ env->disp.y = y;
+ env->disp.w = w;
+ env->disp.h = h;
+
+ env->screen.x = 0;
+ env->screen.y = 0;
+ env->screen.w = 0;
+ env->screen.h = 0;
+
+ env->isinter = 0;
+ env->isrgb24 = 0;
+ env->reverse = 0;
+
+ return env;
+}
+
+void PutDispEnv(const DISPENV *env) {
+ uint32_t h_range, v_range, mode, fb_pos;
+
+ mode = _gpu_video_mode << 3;
+ mode |= (env->isrgb24 & 1) << 4;
+ mode |= (env->isinter & 1) << 5;
+ mode |= (env->reverse & 1) << 7;
+
+ if (env->disp.h >= 256)
+ mode |= 1 << 2;
+
+ // Calculate the horizontal display range values. The original code was
+ // this bad; in actual fact it was even worse due to being written in
+ // assembly and using slow multiplication even when not necessary.
+ int offset, span, default_span = 2560;
+
+ if (env->disp.w > 560) {
+ // 640 pixels
+ mode |= 3;
+ offset = 620;
+ span = env->screen.w * 4;
+ } else if (env->disp.w > 400) {
+ // 512 pixels
+ mode |= 2;
+ offset = 615;
+ span = env->screen.w * 4 + env->screen.w;
+ } else if (env->disp.w > 352) {
+ // 384 pixels (this mode is weird)
+ mode |= 1 << 6;
+ offset = 539;
+ span = env->screen.w * 8 - env->screen.w;
+ default_span = 2688;
+ } else if (env->disp.w > 280) {
+ // 320 pixels
+ mode |= 1;
+ offset = 600;
+ span = env->screen.w * 8;
+ } else {
+ // 256 pixels
+ offset = 590;
+ span = env->screen.w * 8 + env->screen.w * 2;
+ }
+
+ offset += env->screen.x * 4;
+ if (!span)
+ span = default_span;
+
+ h_range = offset & 0xfff;
+ h_range |= ((offset + span) & 0xfff) << 12;
+
+ // Calculate the vertical display range values.
+ offset = 16 + env->screen.y;
+ span = env->screen.h ? env->screen.h : 240;
+
+ v_range = offset & 0x3ff;
+ v_range |= ((offset + span) & 0x3ff) << 10;
+
+ fb_pos = env->disp.x & 0x3ff;
+ fb_pos |= (env->disp.y & 0x1ff) << 10;
+
+ GPU_GP1 = 0x06000000 | h_range; // Set horizontal display range
+ GPU_GP1 = 0x07000000 | v_range; // Set vertical display range
+ GPU_GP1 = 0x08000000 | mode; // Set video mode
+ GPU_GP1 = 0x05000000 | fb_pos; // Set VRAM location to display
+}
+
+/* Deprecated "raw" display API */
+
+void PutDispEnvRaw(const DISPENV_RAW *env) {
+ uint32_t h_range, v_range, fb_pos;
+
+ h_range = 608 + env->vid_xpos;
+ h_range |= (3168 + env->vid_xpos) << 12;
+
+ // FIXME: these hardcoded values are for NTSC displays.
+ v_range = (136 - 120 + env->vid_ypos) & 0x3ff;
+ v_range |= ((136 + 120 + env->vid_ypos) & 0x3ff) << 12;
+
+ fb_pos = env->fb_x & 0x3ff;
+ fb_pos |= (env->fb_y & 0x1ff) << 10;
+
+ GPU_GP1 = 0x06000000 | h_range; // Set horizontal display range
+ GPU_GP1 = 0x07000000 | v_range; // Set vertical display range
+ GPU_GP1 = 0x08000000 | env->vid_mode; // Set video mode
+ GPU_GP1 = 0x05000000 | fb_pos; // Set VRAM location to display
+}
diff --git a/libpsn00b/psxgpu/fntsort.c b/libpsn00b/psxgpu/fntsort.c
deleted file mode 100644
index 9358793..0000000
--- a/libpsn00b/psxgpu/fntsort.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <sys/types.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <psxgpu.h>
-
-extern unsigned short _font_tpage;
-extern unsigned short _font_clut;
-
-char *FntSort(u_long *ot, char *pri, int x, int y, const char *text) {
-
- DR_TPAGE *tpage;
- SPRT_8 *sprt = (SPRT_8*)pri;
- int i;
-
- while( *text != 0 ) {
-
- i = toupper( *text )-32;
-
- if( i > 0 ) {
-
- i--;
- setSprt8( sprt );
- setRGB0( sprt, 128, 128, 128 );
- setXY0( sprt, x, y );
- setUV0( sprt, (i%16)<<3, (i>>4)<<3 );
- sprt->clut = _font_clut;
- addPrim( ot, sprt );
- sprt++;
-
- }
-
- x += 8;
- text++;
-
- }
-
- pri = (char*)sprt;
-
- tpage = (DR_TPAGE*)pri;
- tpage->code[0] = _font_tpage;
- setlen( tpage, 1 );
- setcode( tpage, 0xe1 );
- addPrim( ot, pri );
- pri += sizeof(DR_TPAGE);
-
- return pri;
-
-} \ No newline at end of file
diff --git a/libpsn00b/psxgpu/font.c b/libpsn00b/psxgpu/font.c
index 4c715a9..7a8137c 100644
--- a/libpsn00b/psxgpu/font.c
+++ b/libpsn00b/psxgpu/font.c
@@ -21,14 +21,14 @@ static int _nstreams = 0;
u_short _font_tpage;
u_short _font_clut;
-extern u_char dbugfont[];
+extern u_char _gpu_debug_font[];
void FntLoad(int x, int y) {
RECT pos;
TIM_IMAGE tim;
- GetTimInfo( (u_long*)dbugfont, &tim );
+ GetTimInfo( (const u_long *) _gpu_debug_font, &tim );
// Load font image
pos = *tim.prect;
@@ -223,4 +223,45 @@ char *FntFlush(int id) {
return _stream[id].pribuff;
-} \ No newline at end of file
+}
+
+char *FntSort(u_long *ot, char *pri, int x, int y, const char *text) {
+
+ DR_TPAGE *tpage;
+ SPRT_8 *sprt = (SPRT_8*)pri;
+ int i;
+
+ while( *text != 0 ) {
+
+ i = toupper( *text )-32;
+
+ if( i > 0 ) {
+
+ i--;
+ setSprt8( sprt );
+ setRGB0( sprt, 128, 128, 128 );
+ setXY0( sprt, x, y );
+ setUV0( sprt, (i%16)<<3, (i>>4)<<3 );
+ sprt->clut = _font_clut;
+ addPrim( ot, sprt );
+ sprt++;
+
+ }
+
+ x += 8;
+ text++;
+
+ }
+
+ pri = (char*)sprt;
+
+ tpage = (DR_TPAGE*)pri;
+ tpage->code[0] = _font_tpage;
+ setlen( tpage, 1 );
+ setcode( tpage, 0xe1 );
+ addPrim( ot, pri );
+ pri += sizeof(DR_TPAGE);
+
+ return pri;
+
+}
diff --git a/libpsn00b/psxgpu/getode.s b/libpsn00b/psxgpu/getode.s
deleted file mode 100644
index 5dc1e70..0000000
--- a/libpsn00b/psxgpu/getode.s
+++ /dev/null
@@ -1,20 +0,0 @@
-.set noreorder
-
-.include "hwregs_a.h"
-
-.section .text
-
-
-.global GetODE
-.type GetODE, @function
-GetODE:
- addiu $sp, -4
- sw $ra, 0($sp)
- jal ReadGPUstat
- nop
- srl $v0, 31
- andi $v0, 1
- lw $ra, 0($sp)
- addiu $sp, 4
- jr $ra
- nop
diff --git a/libpsn00b/psxgpu/gettimimage.c b/libpsn00b/psxgpu/gettimimage.c
deleted file mode 100644
index 5598e07..0000000
--- a/libpsn00b/psxgpu/gettimimage.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include <sys/types.h>
-#include <psxgpu.h>
-
-int GetTimInfo(const u_long *tim, TIM_IMAGE *timimg) {
-
- u_long *rtim;
-
- // Check ID
- if( ( tim[0]&0xff ) != 0x10 ) {
- return 1;
- }
-
- // Check version
- if( ( (tim[0]>>8)&0xff ) != 0x0 ) {
- return 2;
- }
-
- timimg->mode = tim[1];
- rtim = tim+2;
-
- // Clut present?
- if( timimg->mode & 0x8 ) {
-
- timimg->crect = (RECT*)(rtim+1);
- timimg->caddr = (u_long*)(rtim+3);
-
- rtim += rtim[0]>>2;
-
- } else {
-
- timimg->caddr = 0;
-
- }
-
- timimg->prect = (RECT*)(rtim+1);
- timimg->paddr = (u_long*)(rtim+3);
-
- return 0;
-
-}
diff --git a/libpsn00b/psxgpu/getvideomode.s b/libpsn00b/psxgpu/getvideomode.s
deleted file mode 100644
index 6f1613c..0000000
--- a/libpsn00b/psxgpu/getvideomode.s
+++ /dev/null
@@ -1,14 +0,0 @@
-.set noreorder
-
-
-.section .text
-
-.global GetVideoMode
-.type GetVideoMode, @function
-GetVideoMode:
-
- la $v0, _gpu_standard
- lw $v0, 0($v0)
-
- jr $ra
- nop
diff --git a/libpsn00b/psxgpu/image.c b/libpsn00b/psxgpu/image.c
new file mode 100644
index 0000000..3633c7c
--- /dev/null
+++ b/libpsn00b/psxgpu/image.c
@@ -0,0 +1,116 @@
+/*
+ * PSn00bSDK GPU library (image and VRAM transfer functions)
+ * (C) 2022 spicyjpeg - MPL licensed
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <psxgpu.h>
+#include <hwregs_c.h>
+
+#define DMA_CHUNK_LENGTH 8
+
+/* Common internal load/store function */
+
+static void _load_store_image(
+ uint32_t command,
+ int mode,
+ const RECT *rect,
+ uint32_t *data
+) {
+ size_t length = rect->w * rect->h;
+ if (length % 2)
+ printf("psxgpu: can't transfer an odd number of pixels\n");
+
+ length /= 2;
+ if ((length >= DMA_CHUNK_LENGTH) && (length % DMA_CHUNK_LENGTH))
+ printf("psxgpu: transfer data length (%d) is not a multiple of %d\n", length, DMA_CHUNK_LENGTH);
+
+ DrawSync(0);
+ GPU_GP1 = 0x04000000; // Disable DMA request
+ GPU_GP0 = 0x01000000; // Flush cache
+
+ GPU_GP0 = command;
+ //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));
+
+ // Enable DMA request, route to GP0 (2) or from GPU_READ (3)
+ GPU_GP1 = 0x04000000 | mode;
+
+ DMA_MADR(2) = (uint32_t) data;
+ if (length < DMA_CHUNK_LENGTH)
+ DMA_BCR(2) = 0x00010000 | length;
+ else
+ DMA_BCR(2) = DMA_CHUNK_LENGTH | ((length / DMA_CHUNK_LENGTH) << 16);
+
+ DMA_CHCR(2) = 0x01000200 | !(mode & 1);
+}
+
+/* Public VRAM API */
+
+void LoadImage(const RECT *rect, const u_long *data) {
+ _load_store_image(0xa0000000, 2, rect, (uint32_t *) data);
+}
+
+void StoreImage(const RECT *rect, u_long *data) {
+ _load_store_image(0xc0000000, 3, rect, (uint32_t *) data);
+}
+
+/* .TIM image parsers */
+
+// This is the only libgs function PSn00bSDK is ever going to implement. The
+// difference from GetTimInfo() is that it copies RECTs rather than merely
+// returning pointers to them, which become useless once the .TIM file is
+// unloaded from main RAM.
+int GsGetTimInfo(const u_long *tim, GsIMAGE *info) {
+ if ((*(tim++) & 0xffff) != 0x0010)
+ return 1;
+
+ info->pmode = *(tim++);
+ if (info->pmode & 8) {
+ const u_long *palette_end = tim;
+ palette_end += *(tim++) / 4;
+
+ *((u_long *) &(info->cx)) = *(tim++);
+ *((u_long *) &(info->cw)) = *(tim++);
+ info->clut = (u_long *) tim;
+
+ tim = palette_end;
+ } else {
+ info->clut = 0;
+ }
+
+ tim++;
+ *((u_long *) &(info->px)) = *(tim++);
+ *((u_long *) &(info->pw)) = *(tim++);
+ info->pixel = (u_long *) tim;
+
+ return 0;
+}
+
+int GetTimInfo(const u_long *tim, TIM_IMAGE *info) {
+ if ((*(tim++) & 0xffff) != 0x0010)
+ return 1;
+
+ info->mode = *(tim++);
+ if (info->mode & 8) {
+ const u_long *palette_end = tim;
+ palette_end += *(tim++) / 4;
+
+ info->crect = (RECT *) tim;
+ info->caddr = (u_long *) &tim[2];
+
+ tim = palette_end;
+ } else {
+ info->caddr = 0;
+ }
+
+ tim++;
+ info->prect = (RECT *) tim;
+ info->paddr = (u_long *) &tim[2];
+
+ return 0;
+}
diff --git a/libpsn00b/psxgpu/loadimage.s b/libpsn00b/psxgpu/loadimage.s
deleted file mode 100644
index 45f152f..0000000
--- a/libpsn00b/psxgpu/loadimage.s
+++ /dev/null
@@ -1,70 +0,0 @@
-.set noreorder
-
-.include "hwregs_a.h"
-
-.set RECT_x, 0
-.set RECT_y, 2
-.set RECT_w, 4
-.set RECT_h, 6
-
-.section .text
-
-
-.global LoadImage
-.type LoadImage, @function
-LoadImage:
- addiu $sp, -8
- sw $ra, 0($sp)
- sw $s0, 4($sp)
-
- lui $s0, IOBASE # Set I/O segment base address
-
-.Lgpu_wait: # Wait for GPU to be ready for commands and DMA
- jal ReadGPUstat
- nop
- srl $v0, 0x1a
- andi $v0, 0x5
- li $v1, 5
- #srl $v0, 28
- #andi $v0, 1
- bne $v0, $v1, .Lgpu_wait
- nop
-
- lui $v0, 0x400 # Set DMA direction to off
- sw $v0, GPU_GP1($s0)
-
- lui $v0, 0x0100 # Clear GPU cache
- sw $v0, GPU_GP0($s0)
-
- lui $v1, 0xa000 # Load image to VRAM
- sw $v1, GPU_GP0($s0)
- lw $v0, RECT_x($a0) # Set XY and dimensions of image
- lw $v1, RECT_w($a0)
- sw $v0, GPU_GP0($s0)
- sw $v1, GPU_GP0($s0)
-
- lui $v0, 0x400 # Set DMA direction to CPUtoVRAM
- ori $v0, 0x2
- sw $v0, GPU_GP1($s0)
-
- lhu $v0, RECT_w($a0) # Get rectangle size
- lhu $v1, RECT_h($a0)
- nop
- mult $v0, $v1 # Calculate BCR value
- mflo $v1
- srl $v1, 0x4
- sll $v1, 0x10
- ori $v1, 0x8
-
- sw $a1, DMA2_MADR($s0) # Set DMA base address and transfer length
- sw $v1, DMA2_BCR($s0)
-
- lui $v0, 0x100 # Start DMA transfer
- ori $v0, 0x201
- sw $v0, DMA2_CHCR($s0)
-
- lw $ra, 0($sp)
- lw $s0, 4($sp)
- jr $ra
- addiu $sp, 8
-
diff --git a/libpsn00b/psxgpu/putdispenv.s b/libpsn00b/psxgpu/putdispenv.s
deleted file mode 100644
index fc09454..0000000
--- a/libpsn00b/psxgpu/putdispenv.s
+++ /dev/null
@@ -1,174 +0,0 @@
-.set noreorder
-
-.include "hwregs_a.h"
-
-.set DISP_dx, 0
-.set DISP_dy, 2
-.set DISP_dw, 4
-.set DISP_dh, 6
-.set DISP_sx, 8
-.set DISP_sy, 10
-.set DISP_sw, 12
-.set DISP_sh, 14
-.set DISP_inter, 16
-.set DISP_isrgb24, 17
-.set DISP_reverse, 18
-
-.section .text
-
-
-.global PutDispEnv
-.type PutDispEnv, @function
-PutDispEnv:
-
- lui $a3, IOBASE
-
- # Horizontal resolution stuff
-
- lh $a2, DISP_dw($a0) # Get X resolution
-
- lh $v0, DISP_sx($a0)
- lh $v1, DISP_sw($a0) # Get X screen width
-
- move $a1, $0 # To use as mode value
-
- bgt $a2, 560, .Lmode_640
- nop
- bgt $a2, 400, .Lmode_512
- nop
- bgt $a2, 352, .Lmode_384
- nop
- bgt $a2, 280, .Lmode_320
- nop
-
- .set noat
-
-.Lmode_256:
- li $at, 10
- mult $at, $v1
- li $a2, 0x24e
- sll $v0, 2
- add $a2, $v0
- b .Lmode_end
- li $v1, 0xa00
-.Lmode_320:
- li $at, 8
- mult $at, $v1
- li $a2, 0x258
- ori $a1, 0x01
- sll $v0, 2
- add $a2, $v0
- b .Lmode_end
- li $v1, 0xa00
-.Lmode_384:
- li $at, 7
- mult $at, $v1
- li $a2, 0x21b
- ori $a1, 0x64
- sll $v0, 2
- add $a2, $v0
- b .Lmode_end
- li $v1, 0xa80
-.Lmode_512:
- li $at, 5
- mult $at, $v1
- li $a2, 0x267
- ori $a1, 0x02
- sll $v0, 2
- add $a2, $v0
- b .Lmode_end
- li $v1, 0xa00
-.Lmode_640:
- li $at, 4
- mult $at, $v1
- li $a2, 0x26c
- ori $a1, 0x03
- sll $v0, 2
- add $a2, $v0
- li $v1, 0xa00
-.Lmode_end:
-
- .set at
-
- mflo $v0
- bnez $v0, .Lno_default # Check if screen with is non zero
- nop
- move $v0, $v1 # Use default if screen width is 0
-.Lno_default:
-
- addu $v0, $a2 # Apply horizontal display coordinates
- sll $v0, 12
- andi $a2, 0xfff
- or $a2, $v0
- lui $v0, 0x0600
- or $v0, $a2
- sw $v0, GPU_GP1($a3)
-
- # Vertical resolution
-
- lh $v0, DISP_dh($a0)
- li $a2, 0x10
- ble $v0, 256, .Lmode_low
- nop
-
-.Lmode_high:
- ori $a1, 0x04
-.Lmode_low:
- lh $v0, DISP_sy($a0)
- lh $v1, DISP_sh($a0)
- add $a2, $v0
- bnez $v1, .Lno_default_vert
- nop
- li $v1, 0xf0
-.Lno_default_vert:
- add $v1, $a2
- and $a2, 0x3ff
- sll $v1, 10
- or $v1, $a2
- lui $v0, 0x0700
- or $v1, $v0
- sw $v1, GPU_GP1($a3)
-
- # Video mode
-
- la $v0, _gpu_standard
- lbu $v0, 0($v0)
- nop
- beqz $v0, .Lconfig_ntsc
- nop
-.Lconfig_pal:
- ori $a1, 0x08
-.Lconfig_ntsc:
-
- lbu $v0, DISP_inter($a0)
- lbu $v1, DISP_isrgb24($a0)
- beqz $v0, .Lno_inter
- nop
- or $a1, 0x20
-.Lno_inter:
- beqz $v1, .Lno_rgb24
- nop
- or $a1, 0x10
-.Lno_rgb24:
- lbu $v0, DISP_inter($a0)
- nop
- beqz $v0, .Lno_reverse
- nop
- or $a1, 0x80
-.Lno_reverse:
-
- lui $v0, 0x800 # Apply mode
- or $a1, $v0
- sw $a1, GPU_GP1($a3)
-
- lhu $v0, DISP_dx($a0) # Set VRAM XY offset
- lhu $v1, DISP_dy($a0)
- andi $v0, 0x3ff
- andi $v1, 0x1ff
- sll $v1, 10
- or $v0, $v1
- lui $v1, 0x500
- or $v0, $v1
-
- jr $ra
- sw $v0, GPU_GP1($a3)
diff --git a/libpsn00b/psxgpu/putdispenvraw.s b/libpsn00b/psxgpu/putdispenvraw.s
deleted file mode 100644
index 747796f..0000000
--- a/libpsn00b/psxgpu/putdispenvraw.s
+++ /dev/null
@@ -1,71 +0,0 @@
-.set noreorder
-.set noat
-
-.include "hwregs_a.h"
-
-.set DISP_mode, 0
-.set DISP_vxpos, 4
-.set DISP_vypos, 6
-.set DISP_fbx, 8
-.set DISP_fby, 10
-
-.section .text
-
-
-.global PutDispEnvRaw
-.type PutDispEnvRaw, @function
-PutDispEnvRaw:
- addiu $sp, -8
- sw $ra, 0($sp)
- sw $s0, 4($sp)
-
- lui $s0, IOBASE
-
- lh $at, DISP_vxpos($a0) # Set horizontal display range
- li $v0, 608
- add $v0, $at
- li $v1, 3168
- add $v1, $at
- sll $v1, 12
- or $v0, $v1
- lui $v1, 0x600
- or $v1, $v0
- sw $v1, GPU_GP1($s0)
-
- lh $at, DISP_vypos($a0) # Set vertical display range (for NTSC)
- li $v1, 120 # (values differet for PAL modes)
- sub $v1, $at
- li $v0, 136
- sub $v0, $v1
- andi $v0, 0x1ff
- li $v1, 120
- add $v1, $at
- li $at, 136
- add $at, $v1
- andi $at, 0x1ff
- sll $at, 10
- or $v0, $at
- lui $at, 0x700
- or $v0, $at
- sw $v0, GPU_GP1($s0)
-
- lw $v0, DISP_mode($a0) # Set video mode
- lui $at, 0x800
- or $v0, $at
- sw $v0, GPU_GP1($s0)
-
- lhu $v0, DISP_fbx($a0) # Set VRAM XY offset
- lhu $v1, DISP_fby($a0)
- andi $v0, 0x3ff
- andi $v1, 0x1ff
- sll $v1, 10
- or $v0, $v1
- lui $v1, 0x500
- or $v0, $v1
- sw $v0, GPU_GP1($s0)
-
- lw $ra, 0($sp)
- lw $s0, 4($sp)
- jr $ra
- addiu $sp, 8
-
diff --git a/libpsn00b/psxgpu/putdrawenv.s b/libpsn00b/psxgpu/putdrawenv.s
deleted file mode 100644
index c0d5676..0000000
--- a/libpsn00b/psxgpu/putdrawenv.s
+++ /dev/null
@@ -1,142 +0,0 @@
-.set noreorder
-.set noat
-
-.include "hwregs_a.h"
-
-.set DRAW_x, 0 # Drawing area
-.set DRAW_y, 2
-.set DRAW_w, 4
-.set DRAW_h, 6
-.set DRAW_ofx, 8 # Draw offset
-.set DRAW_ofy, 10
-.set DRAW_tx, 12 # Texture window
-.set DRAW_ty, 14
-.set DRAW_tw, 16
-.set DRAW_th, 18
-.set DRAW_tpage, 20 # TPage values
-.set DRAW_dtd, 22
-.set DRAW_dfe, 23
-.set DRAW_isbg, 24 # Clear draw area
-.set DRAW_r0, 25
-.set DRAW_g0, 26
-.set DRAW_b0, 27
-.set DRAW_env, 28
-
-
-.section .text
-
-.global PutDrawEnv
-.type PutDrawEnv, @function
-PutDrawEnv:
- addiu $sp, -4
- sw $ra, 0($sp)
-
- addiu $a1, $a0, DRAW_env
-
- li $v0, 0x04ffffff # Packet header (length+terminator)
- sw $v0, 0($a1)
-
- lhu $v0, DRAW_x($a0) # Set draw area top-left
- lhu $v1, DRAW_y($a0)
- andi $v0, 0x3ff
- andi $v1, 0x1ff
- sll $v1, 10
- or $v0, $v1
- lui $v1, 0xe300
- or $v0, $v1
- sw $v0, 4($a1) # 1
-
- .set noat
-
- lhu $v0, DRAW_w($a0) # Set draw area bottom-right
- lhu $at, DRAW_x($a0)
- addiu $v0, -1
- addu $at, $v0
- andi $at, 0x3ff
- lhu $v1, DRAW_h($a0)
- lhu $v0, DRAW_y($a0)
- addiu $v1, -1
- addu $v0, $v1
- andi $v0, 0x1ff
- sll $v0, 10
- or $at, $v0
- lui $v0, 0xe400
- or $at, $v0
- sw $at, 8($a1) # 2
-
- lhu $v0, DRAW_x($a0) # Set drawing offset
- lhu $v1, DRAW_ofx($a0)
- nop
- add $v0, $v1
- andi $at, $v0, 0x7ff
- lhu $v0, DRAW_y($a0)
- lhu $v1, DRAW_ofy($a0)
- nop
- add $v0, $v1
- andi $v0, 0x7ff
- sll $v0, 11
- or $at, $v0
- lui $v0, 0xe500
- or $at, $v0
- sw $at, 12($a1) # 3
-
- lhu $at, DRAW_tpage($a0) # Set tpage
- lbu $v0, DRAW_dtd($a0)
- lbu $v1, DRAW_dfe($a0)
- andi $v0, 1
- and $v1, 1
- sll $v0, 9
- sll $v1, 10
- or $at, $v0
- or $at, $v1
- lui $v0, 0xe100
- or $at, $v0
- sw $at, 16($a1) # 4
-
- .set at
-
- lbu $v0, DRAW_isbg($a0)
- nop
- beqz $v0, .Lno_fillVRAM
- nop
-
- lw $v0, DRAW_isbg($a0) # FillVRAM
- lui $v1, 0x0200
- srl $v0, 8
- or $v0, $v1
- sw $v0, 20($a1) # 5
- lw $v0, DRAW_x($a0)
- lw $v1, DRAW_w($a0)
- sw $v0, 24($a1) # 6
-
- srl $v0, $v1, 16 # Workaround as rectangle primitives
- blt $v0, 511, .Lno_overflow # don't accept a height of 512
- nop
-
- li $v0, 511
- sll $v0, 16
- andi $v1, 0xffff
- or $v1, $v0
-
-.Lno_overflow:
- sw $v1, 28($a1) # 7
- li $v0, 0x07ffffff # Packet header (length+terminator)
- sw $v0, 0($a1)
-
-.Lno_fillVRAM:
-
-.Lgpu_wait: # Wait for GPU to become ready for commands and DMA
- jal ReadGPUstat
- nop
- srl $v0, 26
- andi $v0, 1
- beqz $v0, .Lgpu_wait
- nop
-
- jal DrawOTag
- move $a0, $a1
-
- lw $ra, 0($sp)
- addiu $sp, 4
- jr $ra
- nop
diff --git a/libpsn00b/psxgpu/readgpustat.s b/libpsn00b/psxgpu/readgpustat.s
deleted file mode 100644
index ffff4d7..0000000
--- a/libpsn00b/psxgpu/readgpustat.s
+++ /dev/null
@@ -1,14 +0,0 @@
-.set noreorder
-
-.include "hwregs_a.h"
-
-.section .text
-
-
-.global ReadGPUstat
-.type ReadGPUstat, @function
-ReadGPUstat:
- lui $v0, IOBASE
- lw $v0, GPU_GP1($v0)
- jr $ra
- nop
diff --git a/libpsn00b/psxgpu/readme.txt b/libpsn00b/psxgpu/readme.txt
index b626e1d..2963b6a 100644
--- a/libpsn00b/psxgpu/readme.txt
+++ b/libpsn00b/psxgpu/readme.txt
@@ -3,25 +3,19 @@ PSX GPU library, part of PSn00bSDK
Licensed under Mozilla Public License
- Open source implementation of the GPU library written mostly in MIPS
-assembly. Supports DMA transfers for ordering table draw and transferring
-image data to and from VRAM. The syntax is intentionally made to closely
-resemble Sony's syntax for familiarity and to make porting homebrew made
-using the official SDK to PSn00bSDK a little easier.
-
+Open source implementation of the GPU library written entirely in C. Supports
+DMA transfers for drawing OTs (with an internal queue so DrawOTag() can be
+called even when another OT is being drawn) and transferring image data to and
+from VRAM. The syntax is intentionally made to closely resemble Sony's syntax
+for familiarity and to make porting homebrew made using the official SDK to
+PSn00bSDK a little easier.
Library developer(s):
- Lameguy64
-
+ Lameguy64 (initial implementation in assembly, debug font API)
+ spicyjpeg
Library header(s):
hwregs_a.h (GNU assembler port defs)
psxgpu.h
-
-
-Todo list:
-
- * ClearOTag() function (non reverse version of ClearOTagR()) yet to be
- implemented (but should be trivial).
diff --git a/libpsn00b/psxgpu/resetgraph.s b/libpsn00b/psxgpu/resetgraph.s
deleted file mode 100644
index 6327f02..0000000
--- a/libpsn00b/psxgpu/resetgraph.s
+++ /dev/null
@@ -1,363 +0,0 @@
-.set noreorder
-
-.include "hwregs_a.h"
-
-.section .text
-
-.set ISR_STACK_SIZE, 4096
-
-.global ResetGraph # Resets the GPU and installs a
-.type ResetGraph, @function # VSync event handler
-ResetGraph:
- addiu $sp, -8 # C style stack allocation (required if
- sw $ra, 0($sp) # you call BIOS functions from asm)
- sw $a0, 4($sp)
-
- la $a0, resetgraph_msg
- move $a1, $0
- move $a2, $0
- la $a1, _irq_func_table
- la $a2, _custom_exit
- jal printf
- addiu $sp, -16
- addiu $sp, 16
-
- la $a0, sr_msg
- mfc0 $a1, $12
- jal printf
- addiu $sp, -16
- addiu $sp, 16
-
- la $v0, _hooks_installed # Skip installing hooks if this function
- lbu $v0, 0($v0) # has already been called before once
- nop
- bnez $v0, .Lskip_hook_init
- nop
-
- jal EnterCriticalSection # Disable interrupts as LoadExec() keeps
- nop # interrupts enabled when transferring
- # execution to the loaded program
-
- lui $a3, IOBASE # Base address for I/O
-
- lui $v0, 0x3b33 # Enables DMA channel 6 (for ClearOTag)
- ori $v0, 0x3b33 # Enables DMA channel 2
- sw $v0, DMA_DPCR($a3)
- sw $0 , DMA_DICR($a3) # Clear DICR (not needed)
-
- sw $0 , IRQ_MASK($a3) # Clear IRQ settings
-
- la $v0, _hooks_installed # Set installed flag
- li $v1, 0x1
- sb $v1, 0($v0)
-
- la $v0, _vsync_cb_func # Clear VSync callback function
- sw $0 , 0($v0)
-
- la $a1, _vsync_irq_callback # Install VSync interrupt callback
- jal InterruptCallback
- li $a0, 0
-
- jal RestartCallback
- nop
-
- la $a0, cbhooks_msg
- jal printf
- addiu $sp, -16
- addiu $sp, 16
-
- jal _96_remove # Remove CD handling left by the BIOS
- nop
-
- la $a0, abouttoen_msg
- jal printf
- addiu $sp, -16
- addiu $sp, 16
-
- jal ExitCriticalSection # Re-enable interrupts
- nop
-
- la $a0, enableint_msg
- jal printf
- addiu $sp, -16
- addiu $sp, 16
-
-.Lskip_hook_init:
-
- lui $a3, IOBASE
-
- lw $v0, GPU_GP1($a3) # Get video standard
- lui $v1, 0x0010
- and $v0, $v1
- la $v1, _gpu_standard
- beqz $v0, .Lnot_pal
- sw $0 , 0($v1)
- li $v0, 1
- sw $v0, 0($v1)
-.Lnot_pal:
-
- lw $a0, 4($sp) # Get argument value
-
- lui $a3, IOBASE # Set base I/O again (likely destroyed
- # by previous calls)
-
- li $v0, 0x1d00 # Configure timer 1 as Hblank counter
- sw $v0, TIMER1_CTRL($a3) # Set timer 1 value
-
- beq $a0, 1, .Lgpu_init_1
- nop
- beq $a0, 3, .Lgpu_init_3
- nop
-
- sw $0 , GPU_GP1($a3) # Reset the GPU
-
- b .Linit_done
- nop
-
-.Lgpu_init_1:
-
- sw $0 , DMA2_CHCR($a3) # Stop any DMA
-
-.Lgpu_init_3:
-
- li $v0, 0x1 # Reset the command buffer
- sw $v0, GPU_GP1($a3)
-
-.Linit_done:
-
- lw $ra, 0($sp)
- lw $a0, 4($sp) # Return
- jr $ra
- addiu $sp, 8
-
-
-.global VSync # VSync function
-.type VSync, @function
-VSync:
-
- addiu $sp, -12
- sw $ra, 0($sp)
- sw $s0, 4($sp)
-
- lui $a3, IOBASE # Get GPU status (for interlace sync)
- lw $s0, GPU_GP1($a3)
-
-.Lhwait_loop: # Get Hblank time
- lw $v0, TIMER1_VALUE($a3)
- nop
- lw $v1, TIMER1_VALUE($a3)
- nop
- bne $v0, $v1, .Lhwait_loop
- nop
-
- la $a3, _vsync_lasthblank # Calculate Hblank time since last
- lw $v1, 0($a3)
- nop
- subu $v0, $v1
- andi $v0, 0xffff
-
- beq $a0, 1, .Lhblank_exit # Return Hblank time only, no VSync
- sw $v0, 8($sp) # Stored as return value
-
- bgez $a0, .Lvsync # Vsync if argument is 0 and up
- nop
-
- la $v0, _vsync_rcnt # Return VSync count only
- lw $v0, 0($v0)
- nop
- b .Lvsync_exit
- sw $v0, 8($sp)
-
-.Lvsync:
-
- bnez $a0, .Lnot_zero
- nop
- li $a0, 1
-
-.Lnot_zero:
-
- la $v0, _vsync_rcnt # Call vsync sub function (with timeout)
- lw $v0, 0($v0)
- addiu $a1, $a0, 1
- jal _vsync_sub
- addu $a0, $v0, $a0
-
- lui $v0, 0x40
- and $v0, $s0, $v0
- beqz $v0, .Lhblank_exit
- nop
-
- lui $a3, IOBASE # Interlace wait logic
-
- lw $v0, GPU_GP1($a3)
- nop
- xor $v0, $s0, $v0
- bltz $v0, .Lhblank_exit
- lui $a0, 0x8000
-
-.Linterlace_wait:
- lw $v0, GPU_GP1($a3)
- nop
- xor $v0, $s0, $v0
- and $v0, $a0
- beqz $v0, .Linterlace_wait
- nop
-
-.Lhblank_exit: # Set current Hblank as last value
-
- la $a2, _vsync_lasthblank
-
-.Lhwait2_loop:
- lw $v0, TIMER1_VALUE($a3)
- nop
- lw $v1, TIMER1_VALUE($a3)
- sw $v0, 0($a2)
- bne $v0, $v1, .Lhwait2_loop
- nop
-
-.Lvsync_exit:
-
- lw $ra, 0($sp)
- lw $s0, 4($sp)
- lw $v0, 8($sp)
- jr $ra
- addiu $sp, 12
-
-
-.type _vsync_sub, @function
-_vsync_sub:
-
- # a0 - VSync destination count
- # a1 - Timeout ratio (number of vsyncs to wait relative to vsync count)
-
- addiu $sp, -4
- sw $ra, 0($sp)
-
- sll $a1, 15 # Timeout counter
-
- la $v0, _vsync_rcnt
- lw $v0, 0($v0)
- nop
- bge $v0, $a0, .Lvsync_sub_exit
- nop
-
-.Lvsync_wait:
-
- addiu $a1, -1
-
- la $v1, 0xffffffff
- bne $a1, $v1, .Lnot_timeout
- nop
-
- la $a0, vsynctimeout_msg
- jal puts
- addiu $sp, -8
-
- jal ChangeClearPAD
- move $a0, $0
-
- li $a0, 3
- jal ChangeClearRCnt
- move $a1, $0
-
- addiu $sp, 8
- b .Lvsync_sub_exit
- li $v0, -1
-
-.Lnot_timeout:
-
- la $v0, _vsync_rcnt
- lw $v0, 0($v0)
- nop
- blt $v0, $a0, .Lvsync_wait
- nop
-
-.Lvsync_sub_exit:
-
- lw $ra, 0($sp)
- addiu $sp, 4
- jr $ra
- move $v0, $0
-
-
-
-.type _vsync_irq_callback, @function
-_vsync_irq_callback:
-
- lui $a0, IOBASE
-
- la $v1, _vsync_rcnt # Increment VSync root counter
- lw $v0, 0($v1)
- nop
- addiu $v0, 1
- sw $v0, 0($v1)
-
- la $v0, _vsync_cb_func # Check if a callback function is set
- lw $v0, 0($v0)
- nop
- beqz $v0, .Lno_callback
- nop
-
- addiu $sp, -4 # Save return address
- sw $ra, 0($sp)
- jalr $v0 # Execute user callback function
- nop
- lw $ra, 0($sp) # Restore previous return address
- addiu $sp, 4
-
- lui $a0, IOBASE
-
-.Lno_callback:
-
- jr $ra
- nop
-
-
-.section .data
-
-# VSync root counter
-.type _vsync_rcnt, @object
-_vsync_rcnt:
- .word 0
-
-.type _vsync_lasthblank, @object
-_vsync_lasthblank:
- .word 0
-
-.comm _vsync_cb_func, 4, 4
-
-.comm _gpu_standard, 4, 4
-.comm _gpu_current_field, 4, 4
-.comm _hooks_installed, 4, 4
-
-
-.type vsynctimeout_msg, @object
-vsynctimeout_msg:
- .asciiz "VSync: timeout\n"
-
-.type resetgraph_msg, @object
-resetgraph_msg:
- .asciiz "ResetGraph:itb=%08x,ehk=%08x\n"
-
-.type enableint_msg, @object
-enableint_msg:
- .asciiz "ResetGraph:Interrupts enabled!\n"
-
-.type cbhooks_msg, @object
-cbhooks_msg:
- .asciiz "ResetGraph:Interrupt hooks enabled.\n"
-
-.type abouttoen_msg, @object
-abouttoen_msg:
- .asciiz "ResetGraph:About to init interrupts.\n"
-
-.type sr_msg, @object
-sr_msg:
- .asciiz "ResetGraph:SR=%x\n"
-
-.global psxgpu_credits
-.type psxgpu_credits, @object
-psxgpu_credits:
- .ascii "psxgpu programs by Lameguy64\n"
- .asciiz "2020 PSn00bSDK Project / Meido-Tek Productions\n"
- \ No newline at end of file
diff --git a/libpsn00b/psxgpu/setdefdispenv.c b/libpsn00b/psxgpu/setdefdispenv.c
deleted file mode 100644
index 2d7b2b4..0000000
--- a/libpsn00b/psxgpu/setdefdispenv.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <sys/types.h>
-#include <psxgpu.h>
-
-DISPENV *SetDefDispEnv(DISPENV *disp, int x, int y, int w, int h) {
-
- disp->disp.x = x;
- disp->disp.y = y;
- disp->disp.w = w;
- disp->disp.h = h;
-
- disp->screen.x = 0;
- disp->screen.y = 0;
- disp->screen.w = 0;
- disp->screen.h = 0;
-
- disp->isinter = 0;
- disp->isrgb24 = 0;
- disp->reverse = 0;
-
- return disp;
-
-}
diff --git a/libpsn00b/psxgpu/setdefdrawenv.c b/libpsn00b/psxgpu/setdefdrawenv.c
deleted file mode 100644
index 6fd6086..0000000
--- a/libpsn00b/psxgpu/setdefdrawenv.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <sys/types.h>
-#include <psxgpu.h>
-
-DRAWENV *SetDefDrawEnv(DRAWENV *draw, int x, int y, int w, int h) {
-
- draw->clip.x = x;
- draw->clip.y = y;
- draw->clip.w = w;
- draw->clip.h = h;
-
- draw->ofs[0] = 0;
- draw->ofs[1] = 0;
-
- draw->tw.x = 0;
- draw->tw.y = 0;
- draw->tw.w = 0;
- draw->tw.h = 0;
-
- draw->tpage = 0x0a;
- draw->dtd = 1;
- draw->dfe = 0;
- draw->isbg = 0;
- setRGB0( draw, 0, 0, 0 );
-
- return draw;
-
-}
diff --git a/libpsn00b/psxgpu/setdispmask.s b/libpsn00b/psxgpu/setdispmask.s
deleted file mode 100644
index d79006c..0000000
--- a/libpsn00b/psxgpu/setdispmask.s
+++ /dev/null
@@ -1,19 +0,0 @@
-.set noreorder
-
-.include "hwregs_a.h"
-
-.section .text
-
-
-.global SetDispMask
-.type SetDispMask, @function
-SetDispMask:
- lui $v1, IOBASE
- andi $a0, 0x1
- lui $v0, 0x300
- ori $v0, 0x1
- sub $v0, $a0
- sw $v0, GPU_GP1($v1)
- jr $ra
- nop
-
diff --git a/libpsn00b/psxgpu/setvideomode.s b/libpsn00b/psxgpu/setvideomode.s
deleted file mode 100644
index b89b285..0000000
--- a/libpsn00b/psxgpu/setvideomode.s
+++ /dev/null
@@ -1,50 +0,0 @@
-.set noreorder
-
-.include "hwregs_a.h"
-
-
-.section .text
-
-.global SetVideoMode
-.type SetVideoMode, @function
-SetVideoMode:
- addiu $sp, -4
- sw $ra, 0($sp)
-
- jal ReadGPUstat
- nop
-
- srl $a1, $v0, 17
- andi $a1, 0x1f
-
- srl $v1, $v0, 14 # Reverse flag
- andi $v1, 1
- sll $v1, 6
- or $a1, $v1
-
- srl $v1, $v0, 16 # Horizontal resolution 2
- andi $v1, 1
- sll $v1, 6
- or $a1, $v1
-
- andi $a1, 0xf7 # Mask off PAL bit
-
- la $v0, _gpu_standard
- beqz $a0, .Lset_done
- sw $0 , 0($v0)
- li $v1, 1
- sw $v1, 0($v0)
- b .Lset_done
- or $a1, 0x8
-.Lset_done:
-
- lui $v0, 0x800 # Apply new mode
- or $a1, $v0
- lui $v0, IOBASE
- sw $a1, GPU_GP1($v0)
-
- lw $ra, 0($sp)
- addiu $sp, 4
- jr $ra
- nop
-
diff --git a/libpsn00b/psxgpu/storeimage.s b/libpsn00b/psxgpu/storeimage.s
deleted file mode 100644
index 554e83c..0000000
--- a/libpsn00b/psxgpu/storeimage.s
+++ /dev/null
@@ -1,76 +0,0 @@
-.set noreorder
-
-.include "hwregs_a.h"
-
-.set RECT_x, 0
-.set RECT_y, 2
-.set RECT_w, 4
-.set RECT_h, 6
-
-.section .text
-
-
-.global StoreImage
-.type StoreImage, @function
-StoreImage:
- addiu $sp, -8
- sw $ra, 0($sp)
- sw $s0, 4($sp)
-
- lui $s0, IOBASE # Set I/O segment base address
-
-.Lgpu_wait: # Wait for GPU to be ready for commands and DMA
- jal ReadGPUstat
- nop
- srl $v0, 0x1a
- andi $v0, 0x5
- li $v1, 5
- bne $v0, $v1, .Lgpu_wait
- nop
-
- lui $v0, 0x400 # Set DMA direction to off
- sw $v0, GPU_GP1($s0)
-
- lui $v0, 0x0100 # Clear GPU cache
- sw $v0, GPU_GP0($s0)
-
- lui $v1, 0xc000 # Store image from VRAM
- sw $v1, GPU_GP0($s0)
- lw $v0, RECT_x($a0) # Set XY and dimensions of image
- lw $v1, RECT_w($a0)
- sw $v0, GPU_GP0($s0)
- sw $v1, GPU_GP0($s0)
-
- lui $v0, 0x400 # Set DMA direction to VRAMtoCPU
- ori $v0, 0x3
- sw $v0, GPU_GP1($s0)
-
- lhu $v0, RECT_w($a0) # Get rectangle size
- lhu $v1, RECT_h($a0)
- nop
- mult $v0, $v1 # Calculate BCR value
- mflo $v1
- srl $v1, 0x4
- sll $v1, 0x10
- ori $v1, 0x8
-
- sw $a1, DMA2_MADR($s0) # Set DMA base address and transfer length
- sw $v1, DMA2_BCR($s0)
-
-.Lgpu_wait_2: # Wait for GPU to be ready for commands and DMA
- jal ReadGPUstat
- nop
- srl $v0, 27
- andi $v0, 0x1
- beqz $v0, .Lgpu_wait_2
- nop
-
- lui $v0, 0x100 # Start DMA transfer
- ori $v0, 0x200
- sw $v0, DMA2_CHCR($s0)
-
- lw $ra, 0($sp)
- lw $s0, 4($sp)
- jr $ra
- addiu $sp, 8
-
diff --git a/libpsn00b/psxgpu/vsynccallback.s b/libpsn00b/psxgpu/vsynccallback.s
deleted file mode 100644
index 4be29c8..0000000
--- a/libpsn00b/psxgpu/vsynccallback.s
+++ /dev/null
@@ -1,25 +0,0 @@
-.set noreorder
-
-.section .text
-
-.global VSyncCallback
-.type VSyncCallback, @function
-VSyncCallback:
- addiu $sp, -8
- sw $ra, 0($sp)
-
- jal EnterCriticalSection
- sw $a0, 4($sp)
-
- lw $a0, 4($sp)
- la $v0, _vsync_cb_func
- sw $a0, 0($v0)
-
- jal ExitCriticalSection
- nop
-
- lw $ra, 0($sp)
- addiu $sp, 8
- jr $ra
- nop
-