PS1: Manually handle resetting GPU and VSync

This commit is contained in:
UnknownShadow200 2025-03-13 07:40:57 +11:00
parent 7f383f9caa
commit 576faba9a6
4 changed files with 66 additions and 10 deletions

View File

@ -41,6 +41,7 @@ enum gp0_rectcmd_flags {
};
enum gp1_cmd_type {
GP1_CMD_RESET_GPU = 0x00000000,
GP1_CMD_DISPLAY_ACTIVE = 0x03000000,
GP1_CMD_DMA_MODE = 0x04000000,
GP1_CMD_DISPLAY_ADDRESS = 0x05000000,

View File

@ -14,7 +14,52 @@
#include "../misc/ps1/ps1defs.h"
// Based off https://github.com/Lameguy64/PSn00bSDK/blob/master/examples/beginner/hello/main.c
#define wait_while(cond) while (cond) { __asm__ volatile(""); }
/*########################################################################################################################*
*------------------------------------------------------GPU management-----------------------------------------------------*
*#########################################################################################################################*/
static volatile cc_uint32 vblank_count;
static void vblank_handler(void) { vblank_count++; }
#define DMA_IDX_GPU (DMA_GPU * 4)
#define DMA_IDX_OTC (DMA_OTC * 4)
void Gfx_ResetGPU(void) {
int needs_exit = EnterCriticalSection();
InterruptCallback(IRQ_VBLANK, &vblank_handler);
if (needs_exit) ExitCriticalSection();
GPU_GP1 = GP1_CMD_RESET_GPU;
ChangeClearPAD(0);
// Enable GPU and OTC DMA channels at priority 3
DMA_DPCR |= (0xB << DMA_IDX_GPU) | (0xB << DMA_IDX_OTC);
// Stop pending DMA
DMA_CHCR(DMA_GPU) = CHRC_MODE_SLICE | CHRC_FROM_RAM;
DMA_CHCR(DMA_OTC) = CHRC_MODE_SLICE;
}
void Gfx_VSync(void) {
cc_uint32 counter = vblank_count;
for (int i = 0; i < 0x100000; i++)
{
if (counter != vblank_count) return;
}
// VSync IRQ may be swallowed by BIOS, try to undo that
Platform_LogConst("VSync timed out");
ChangeClearPAD(0);
}
/*########################################################################################################################*
*------------------------------------------------------Render buffers-----------------------------------------------------*
*#########################################################################################################################*/
// Length of the ordering table, i.e. the range Z coordinates can have, 0-15 in
// this case. Larger values will allow for more granularity with depth (useful
// when drawing a complex 3D scene) at the expense of RAM usage and performance.
@ -24,8 +69,6 @@
// crashes due to too many primitives being drawn, increase this value.
#define BUFFER_LENGTH 32768
#define wait_while(cond) while (cond) { __asm__ volatile(""); }
struct EnvPrimities {
uint32_t tag;
uint32_t tpage_code[1];
@ -51,7 +94,6 @@ static uint8_t* next_packet_end;
static int active_buffer;
static RenderBuffer* cur_buffer;
static void* lastPoly;
static cc_bool cullingEnabled, noMemWarned;
static void BuildContext(RenderBuffer* buf) {
struct EnvPrimities* prim = &buf->env;
@ -105,7 +147,13 @@ static void SetupContexts(int w, int h) {
OnBufferUpdated();
}
/*########################################################################################################################*
*----------------------------------------------------------General--------------------------------------------------------*
*#########################################################################################################################*/
static GfxResourceID white_square;
static cc_bool cullingEnabled;
void Gfx_RestoreState(void) {
InitDefaultResources();
@ -907,7 +955,7 @@ void Gfx_EndFrame(void) {
Platform_LogConst("OUT OF VERTEX RAM");
}
WaitUntilFinished();
VSync(0);
Gfx_VSync();
RenderBuffer* draw_buffer = &buffers[active_buffer];
RenderBuffer* disp_buffer = &buffers[active_buffer ^ 1];

View File

@ -246,8 +246,11 @@ cc_result Socket_CheckWritable(cc_socket s, cc_bool* writable) {
/*########################################################################################################################*
*--------------------------------------------------------Platform---------------------------------------------------------*
*#########################################################################################################################*/
extern void Gfx_ResetGPU(void);
void Platform_Init(void) {
ResetGraph(0);
ResetCallback();
Gfx_ResetGPU();
Stopwatch_Init();
}

View File

@ -24,9 +24,12 @@
static cc_bool launcherMode;
struct _DisplayData DisplayInfo;
struct cc_window WindowInfo;
static DISPENV disp;
static int gpu_video_mode;
void Window_PreInit(void) {
gpu_video_mode = (GPU_GP1 >> 20) & 1;
}
void Window_PreInit(void) { }
void Window_Init(void) {
DisplayInfo.Width = SCREEN_XRES;
DisplayInfo.Height = SCREEN_YRES;
@ -49,7 +52,7 @@ void Window_Init(void) {
void Window_Free(void) { }
static void InitScreen(void) {
int vid = GetVideoMode();
int vid = gpu_video_mode;
int mode = (vid << 3) | GP1_HOR_RES_320 | GP1_VER_RES_240;
int yMid = vid ? 0xA3 : 0x88; // PAL has more vertical lines
@ -82,9 +85,10 @@ static void ClearScreen(void)
GPU_GP0 = GP0_CMD_FILL_XY(0, 0);
GPU_GP0 = GP0_CMD_FILL_WH(320, 200);
}
extern void Gfx_ResetGPU(void);
void Window_Create2D(int width, int height) {
ResetGraph(0);
Gfx_ResetGPU();
launcherMode = true;
InitScreen();
@ -92,7 +96,7 @@ void Window_Create2D(int width, int height) {
}
void Window_Create3D(int width, int height) {
ResetGraph(0);
Gfx_ResetGPU();
launcherMode = false;
InitScreen();