--- /dev/null
+
+/*
+ * q: Why bother with GPU stuff in a plugin-based emu core?
+ * a: mostly because of busy bits, we have all the needed timing info
+ * that GPU plugin doesn't.
+ */
+
+#define PSXGPU_LCF (1<<31)
+#define PSXGPU_nBUSY (1<<26)
+#define PSXGPU_ILACE (1<<22)
+
+#define HW_GPU_STATUS psxHu32ref(0x1814)
+
+// TODO: handle com too
+#define PSXGPU_TIMING_BITS (PSXGPU_LCF | PSXGPU_nBUSY)
+
+#define gpuSyncPluginSR() { \
+ HW_GPU_STATUS &= PSXGPU_TIMING_BITS; \
+ HW_GPU_STATUS |= GPU_readStatus() & ~PSXGPU_TIMING_BITS; \
+}
#include "../psxhw.h"
#include "../cdrom.h"
#include "../mdec.h"
+#include "../gpu.h"
#include "emu_if.h"
#include "pcsxmem.h"
wfunc(a + 2, value >> 16);
}
+static u32 io_gpu_read_status(void)
+{
+ // meh2, syncing for img bit, might want to avoid it..
+ gpuSyncPluginSR();
+ return HW_GPU_STATUS;
+}
+
+static void io_gpu_write_status(u32 value)
+{
+ GPU_writeStatus(value);
+ gpuSyncPluginSR();
+}
+
static void map_ram_write(void)
{
int i;
map_item(&mem_iortab[IOMEM32(0x1124)], io_rcnt_read_mode2, 1);
map_item(&mem_iortab[IOMEM32(0x1128)], io_rcnt_read_target2, 1);
// map_item(&mem_iortab[IOMEM32(0x1810)], GPU_readData, 1);
-// map_item(&mem_iortab[IOMEM32(0x1814)], GPU_readStatus, 1);
+ map_item(&mem_iortab[IOMEM32(0x1814)], io_gpu_read_status, 1);
map_item(&mem_iortab[IOMEM32(0x1820)], mdecRead0, 1);
map_item(&mem_iortab[IOMEM32(0x1824)], mdecRead1, 1);
map_item(&mem_iowtab[IOMEM32(0x1124)], io_rcnt_write_mode2, 1);
map_item(&mem_iowtab[IOMEM32(0x1128)], io_rcnt_write_target2, 1);
// map_item(&mem_iowtab[IOMEM32(0x1810)], GPU_writeData, 1);
-// map_item(&mem_iowtab[IOMEM32(0x1814)], GPU_writeStatus, 1);
+ map_item(&mem_iowtab[IOMEM32(0x1814)], io_gpu_write_status, 1);
map_item(&mem_iowtab[IOMEM32(0x1820)], mdecWrite0, 1);
map_item(&mem_iowtab[IOMEM32(0x1824)], mdecWrite1, 1);
// plugins might change so update the pointers
map_item(&mem_iortab[IOMEM32(0x1810)], GPU_readData, 1);
- map_item(&mem_iortab[IOMEM32(0x1814)], GPU_readStatus, 1);
for (i = 0x1c00; i < 0x1e00; i += 2)
map_item(&mem_iortab[IOMEM16(i)], SPU_readRegister, 1);
map_item(&mem_iowtab[IOMEM32(0x1810)], GPU_writeData, 1);
- map_item(&mem_iowtab[IOMEM32(0x1814)], GPU_writeStatus, 1);
}
*/
#include "psxcounters.h"
+#include "gpu.h"
#include "debug.h"
/******************************************************************************/
static u32 hsync_steps = 0;
static u32 gpu_wants_hcnt = 0;
static u32 base_cycle = 0;
+static u32 frame_counter = 0;
u32 psxNextCounter = 0, psxNextsCounter = 0;
if( hSyncCount == VBlankStart[Config.PsxType] )
{
GPU_vBlank( 1, &hSyncCount, &gpu_wants_hcnt );
-
+ //if( !(HW_GPU_STATUS & PSXGPU_ILACE) ) // hmh
+ HW_GPU_STATUS |= PSXGPU_LCF;
+
// For the best times. :D
//setIrq( 0x01 );
}
if( hSyncCount >= (Config.VSyncWA ? HSyncTotal[Config.PsxType] / BIAS : HSyncTotal[Config.PsxType]) )
{
hSyncCount = 0;
+ frame_counter++;
GPU_vBlank( 0, &hSyncCount, &gpu_wants_hcnt );
setIrq( 0x01 );
EmuUpdate();
GPU_updateLace();
+
+ HW_GPU_STATUS &= ~PSXGPU_LCF;
+ if( HW_GPU_STATUS & PSXGPU_ILACE )
+ HW_GPU_STATUS |= frame_counter << 31;
}
// Schedule next call, in hsyncs
#include "psxhw.h"
#include "mdec.h"
#include "cdrom.h"
+#include "gpu.h"
//#undef PSXHW_LOG
//#define PSXHW_LOG printf
mdecInit(); // initialize mdec decoder
cdrReset();
psxRcntInit();
+ HW_GPU_STATUS = 0x14802000;
}
u8 psxHwRead8(u32 add) {
#endif
return hard;
case 0x1f801814:
- hard = GPU_readStatus();
+ gpuSyncPluginSR();
+ hard = HW_GPU_STATUS;
#ifdef PSXHW_LOG
PSXHW_LOG("GPU STATUS 32bit read %x\n", hard);
#endif
#ifdef PSXHW_LOG
PSXHW_LOG("GPU STATUS 32bit write %x\n", value);
#endif
- GPU_writeStatus(value); return;
+ GPU_writeStatus(value);
+ gpuSyncPluginSR();
+ return;
case 0x1f801820:
mdecWrite0(value); break;