ref: 45886e067d78fddee5a84a28f4ee44e8b4a3af6a
parent: 3a9d344655a77e3eb6453fb7e0905afafd9bf969
author: allkern <lisandroaalarcon@gmail.com>
date: Sat Jul 1 19:42:46 EDT 2023
Tidy up, Improve CDROM IRQ timings
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -3,28 +3,8 @@
#include "screen.h"
#include "config.h"
-#include <signal.h>
-
#undef main
-psx_cpu_t* g_cpu;
-
-void sigint_handler(int sig) {- log_set_quiet(0);
-
- log_fatal("r0=%08x at=%08x v0=%08x v1=%08x", g_cpu->r[0] , g_cpu->r[1] , g_cpu->r[2] , g_cpu->r[3] );- log_fatal("a0=%08x a1=%08x a2=%08x a3=%08x", g_cpu->r[4] , g_cpu->r[5] , g_cpu->r[6] , g_cpu->r[7] );- log_fatal("t0=%08x t1=%08x t2=%08x t3=%08x", g_cpu->r[8] , g_cpu->r[9] , g_cpu->r[10], g_cpu->r[11]);- log_fatal("t4=%08x t5=%08x t6=%08x t7=%08x", g_cpu->r[12], g_cpu->r[13], g_cpu->r[14], g_cpu->r[15]);- log_fatal("s0=%08x s1=%08x s2=%08x s3=%08x", g_cpu->r[16], g_cpu->r[17], g_cpu->r[18], g_cpu->r[19]);- log_fatal("s4=%08x s5=%08x s6=%08x s7=%08x", g_cpu->r[20], g_cpu->r[21], g_cpu->r[22], g_cpu->r[23]);- log_fatal("t8=%08x t9=%08x k0=%08x k1=%08x", g_cpu->r[24], g_cpu->r[25], g_cpu->r[26], g_cpu->r[27]);- log_fatal("gp=%08x sp=%08x fp=%08x ra=%08x", g_cpu->r[28], g_cpu->r[29], g_cpu->r[30], g_cpu->r[31]);- log_fatal("pc=%08x hi=%08x lo=%08x epc=%08x", g_cpu->pc, g_cpu->hi, g_cpu->lo, g_cpu->cop0_epc);-
- exit(1);
-}
-
int main(int argc, const char* argv[]) {psxe_config_t* cfg = psxe_cfg_create();
@@ -34,15 +14,11 @@
log_set_level(cfg->log_level);
- signal(SIGINT, sigint_handler);
-
psx_t* psx = psx_create();
psx_init(psx, cfg->bios);
psx_gpu_t* gpu = psx_get_gpu(psx);
- g_cpu = psx_get_cpu(psx);
-
psxe_screen_t* screen = psxe_screen_create();
psxe_screen_init(screen, psx);
psxe_screen_set_scale(screen, 2);
@@ -52,7 +28,7 @@
psx_gpu_set_udata(gpu, 0, screen);
if (cfg->exe) {- while (psx->cpu->pc != 0xBFC06FF0) {+ while (psx->cpu->pc != 0x80030000) {psx_update(psx);
}
@@ -77,7 +53,7 @@
log_fatal("s4=%08x s5=%08x s6=%08x s7=%08x", cpu->r[20], cpu->r[21], cpu->r[22], cpu->r[23]); log_fatal("t8=%08x t9=%08x k0=%08x k1=%08x", cpu->r[24], cpu->r[25], cpu->r[26], cpu->r[27]); log_fatal("gp=%08x sp=%08x fp=%08x ra=%08x", cpu->r[28], cpu->r[29], cpu->r[30], cpu->r[31]);- log_fatal("pc=%08x hi=%08x lo=%08x ep=%08x", cpu->pc, cpu->hi, cpu->lo, cpu->cop0_epc);+ log_fatal("pc=%08x hi=%08x lo=%08x ep=%08x", cpu->pc, cpu->hi, cpu->lo, cpu->cop0_r[COP0_EPC]);psx_destroy(psx);
psxe_screen_destroy(screen);
--- a/frontend/screen.c
+++ b/frontend/screen.c
@@ -17,6 +17,7 @@
screen->scale = 1;
screen->open = 1;
+ screen->format = SDL_PIXELFORMAT_BGR555;
screen->psx = psx;
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
@@ -47,7 +48,7 @@
screen->texture = SDL_CreateTexture(
screen->renderer,
- SDL_PIXELFORMAT_BGR555,
+ screen->format,
SDL_TEXTUREACCESS_STREAMING,
PSX_GPU_FB_WIDTH, PSX_GPU_FB_HEIGHT
);
@@ -74,7 +75,7 @@
void psxe_screen_toggle_debug_mode(psxe_screen_t* screen) {screen->debug_mode = !screen->debug_mode;
- psxe_screen_reload(screen);
+ psxe_gpu_dmode_event_cb(screen->psx->gpu);
}
void psxe_screen_update(psxe_screen_t* screen) {@@ -91,6 +92,14 @@
case SDL_QUIT: {screen->open = 0;
} break;
+
+ case SDL_KEYDOWN: {+ switch (event.key.keysym.sym) {+ case SDLK_F1: {+ psxe_screen_toggle_debug_mode(screen);
+ } break;
+ }
+ } break;
}
}
}
@@ -98,7 +107,6 @@
void psxe_screen_set_scale(psxe_screen_t* screen, unsigned int scale) { if (screen->debug_mode) {screen->scale = 1;
- screen->saved_scale = 1;
} else {screen->scale = scale;
screen->saved_scale = scale;
@@ -117,6 +125,9 @@
void psxe_gpu_dmode_event_cb(psx_gpu_t* gpu) {psxe_screen_t* screen = gpu->udata[0];
+
+ screen->format = psx_get_display_format(screen->psx) ?
+ SDL_PIXELFORMAT_BGR555 : SDL_PIXELFORMAT_RGB888;
if (screen->debug_mode) {screen->width = PSX_GPU_FB_WIDTH;
--- a/frontend/screen.h
+++ b/frontend/screen.h
@@ -17,6 +17,7 @@
unsigned int saved_scale;
unsigned int width, height, scale;
+ unsigned int format;
int debug_mode;
int open;
--- a/psx/cpu.c
+++ b/psx/cpu.c
@@ -5,73 +5,6 @@
#include <stdlib.h>
#include <string.h>
-#define R_R0 (cpu->r[0])
-#define R_AT (cpu->r[1])
-#define R_V0 (cpu->r[2])
-#define R_V1 (cpu->r[3])
-#define R_A0 (cpu->r[4])
-#define R_A1 (cpu->r[5])
-#define R_A2 (cpu->r[6])
-#define R_A3 (cpu->r[7])
-#define R_T0 (cpu->r[8])
-#define R_T1 (cpu->r[9])
-#define R_T2 (cpu->r[10])
-#define R_T3 (cpu->r[11])
-#define R_T4 (cpu->r[12])
-#define R_T5 (cpu->r[13])
-#define R_T6 (cpu->r[14])
-#define R_T7 (cpu->r[15])
-#define R_S0 (cpu->r[16])
-#define R_S1 (cpu->r[17])
-#define R_S2 (cpu->r[18])
-#define R_S3 (cpu->r[19])
-#define R_S4 (cpu->r[20])
-#define R_S5 (cpu->r[21])
-#define R_S6 (cpu->r[22])
-#define R_S7 (cpu->r[23])
-#define R_T8 (cpu->r[24])
-#define R_T9 (cpu->r[25])
-#define R_K0 (cpu->r[26])
-#define R_K1 (cpu->r[27])
-#define R_GP (cpu->r[28])
-#define R_SP (cpu->r[29])
-#define R_FP (cpu->r[30])
-#define R_RA (cpu->r[31])
-
-psx_cpu_t* psx_cpu_create() {- return (psx_cpu_t*)malloc(sizeof(psx_cpu_t));
-}
-
-void cpu_a_kcall_hook(psx_cpu_t*);
-void cpu_b_kcall_hook(psx_cpu_t*);
-
-void psx_cpu_fetch(psx_cpu_t* cpu) {- cpu->buf[0] = psx_bus_read32(cpu->bus, cpu->pc);
- cpu->pc += 4;
-
- // Discard fetch cycles
- psx_bus_get_access_cycles(cpu->bus);
-}
-
-void psx_cpu_init(psx_cpu_t* cpu, psx_bus_t* bus) {- memset(cpu, 0, sizeof(psx_cpu_t));
-
- psx_cpu_set_a_kcall_hook(cpu, cpu_a_kcall_hook);
- psx_cpu_set_b_kcall_hook(cpu, cpu_b_kcall_hook);
-
- cpu->bus = bus;
- cpu->pc = 0xbfc00000;
-
- cpu->cop0_sr = 0x10900000;
- cpu->cop0_prid = 0x00000002;
-
- psx_cpu_fetch(cpu);
-}
-
-void psx_cpu_destroy(psx_cpu_t* cpu) {- free(cpu);
-}
-
psx_cpu_instruction_t g_psx_cpu_secondary_table[] = {psx_cpu_i_sll , psx_cpu_i_invalid, psx_cpu_i_srl , psx_cpu_i_sra ,
psx_cpu_i_sllv , psx_cpu_i_invalid, psx_cpu_i_srlv , psx_cpu_i_srav ,
@@ -143,6 +76,39 @@
#define IMM16 (cpu->buf[1] & 0xffff)
#define IMM16S ((int32_t)((int16_t)IMM16))
+#define R_R0 (cpu->r[0])
+#define R_AT (cpu->r[1])
+#define R_V0 (cpu->r[2])
+#define R_V1 (cpu->r[3])
+#define R_A0 (cpu->r[4])
+#define R_A1 (cpu->r[5])
+#define R_A2 (cpu->r[6])
+#define R_A3 (cpu->r[7])
+#define R_T0 (cpu->r[8])
+#define R_T1 (cpu->r[9])
+#define R_T2 (cpu->r[10])
+#define R_T3 (cpu->r[11])
+#define R_T4 (cpu->r[12])
+#define R_T5 (cpu->r[13])
+#define R_T6 (cpu->r[14])
+#define R_T7 (cpu->r[15])
+#define R_S0 (cpu->r[16])
+#define R_S1 (cpu->r[17])
+#define R_S2 (cpu->r[18])
+#define R_S3 (cpu->r[19])
+#define R_S4 (cpu->r[20])
+#define R_S5 (cpu->r[21])
+#define R_S6 (cpu->r[22])
+#define R_S7 (cpu->r[23])
+#define R_T8 (cpu->r[24])
+#define R_T9 (cpu->r[25])
+#define R_K0 (cpu->r[26])
+#define R_K1 (cpu->r[27])
+#define R_GP (cpu->r[28])
+#define R_SP (cpu->r[29])
+#define R_FP (cpu->r[30])
+#define R_RA (cpu->r[31])
+
// #define CPU_TRACE
#ifdef CPU_TRACE
@@ -295,6 +261,40 @@
}
}
+psx_cpu_t* psx_cpu_create() {+ return (psx_cpu_t*)malloc(sizeof(psx_cpu_t));
+}
+
+void cpu_a_kcall_hook(psx_cpu_t*);
+void cpu_b_kcall_hook(psx_cpu_t*);
+
+void psx_cpu_fetch(psx_cpu_t* cpu) {+ cpu->buf[0] = psx_bus_read32(cpu->bus, cpu->pc);
+ cpu->pc += 4;
+
+ // Discard fetch cycles
+ psx_bus_get_access_cycles(cpu->bus);
+}
+
+void psx_cpu_init(psx_cpu_t* cpu, psx_bus_t* bus) {+ memset(cpu, 0, sizeof(psx_cpu_t));
+
+ psx_cpu_set_a_kcall_hook(cpu, cpu_a_kcall_hook);
+ psx_cpu_set_b_kcall_hook(cpu, cpu_b_kcall_hook);
+
+ cpu->bus = bus;
+ cpu->pc = 0xbfc00000;
+
+ cpu->cop0_r[COP0_SR] = 0x10900000;
+ cpu->cop0_r[COP0_PRID] = 0x00000002;
+
+ psx_cpu_fetch(cpu);
+}
+
+void psx_cpu_destroy(psx_cpu_t* cpu) {+ free(cpu);
+}
+
void psx_cpu_set_a_kcall_hook(psx_cpu_t* cpu, psx_cpu_kcall_hook_t hook) {cpu->a_function_hook = hook;
}
@@ -333,7 +333,7 @@
g_psx_cpu_primary_table[OP](cpu);
- if ((cpu->cop0_sr & SR_IEC) && (cpu->cop0_cause & cpu->cop0_sr & SR_IM2)) {+ if ((cpu->cop0_r[COP0_SR] & SR_IEC) && (cpu->cop0_r[COP0_CAUSE] & cpu->cop0_r[COP0_SR] & SR_IM2)) {psx_cpu_exception(cpu, CAUSE_INT);
}
@@ -342,36 +342,59 @@
cpu->r[0] = 0;
}
+void psx_cpu_check_irq(psx_cpu_t* cpu) {+ if ((cpu->cop0_r[COP0_SR] & SR_IEC) && (cpu->cop0_r[COP0_CAUSE] & cpu->cop0_r[COP0_SR] & SR_IM2)) {+ // log_fatal("(before) IRQ pc=%08x, epc=%08x, cause=%08x, sr=%08x, tc=%u (%08x), istat=%08x, imask=%08x, [0]=%08x, [1]=%08x",+ // cpu->pc,
+ // cpu->cop0_r[COP0_EPC],
+ // cpu->cop0_r[COP0_CAUSE],
+ // cpu->cop0_r[COP0_SR],
+ // cpu->total_cycles,
+ // cpu->total_cycles,
+ // psx_bus_read32(cpu->bus, 0x1F801070),
+ // psx_bus_read32(cpu->bus, 0x1F801074),
+ // cpu->buf[0],
+ // cpu->buf[1]
+ // );
+
+ psx_cpu_exception(cpu, CAUSE_INT);
+ }
+}
+
void psx_cpu_exception(psx_cpu_t* cpu, uint32_t cause) {- cpu->cop0_cause = cause << 2;
+ // Set excode and clear 3 LSBs
+ cpu->cop0_r[COP0_CAUSE] &= 0xffffff80;
+ cpu->cop0_r[COP0_CAUSE] |= cause;
// If we're in a delay slot, set delay slot bit
// on CAUSE
if (cpu->delay_slot) {- cpu->cop0_epc = cpu->pc - 12;
- cpu->cop0_cause |= 0x80000000;
+ cpu->cop0_r[COP0_EPC] = cpu->pc - 12;
+ cpu->cop0_r[COP0_CAUSE] |= 0x80000000;
} else {- cpu->cop0_epc = cpu->pc - 8;
- cpu->cop0_cause &= 0x7fffffff;
+ cpu->cop0_r[COP0_EPC] = cpu->pc - 8;
+ cpu->cop0_r[COP0_CAUSE] &= 0x7fffffff;
}
// Do exception stack push
- uint32_t mode = cpu->cop0_sr & 0x3f;
+ uint32_t mode = cpu->cop0_r[COP0_SR] & 0x3f;
- cpu->cop0_sr &= 0xffffffc0;
- cpu->cop0_sr |= (mode << 2) & 0x3f;
+ cpu->cop0_r[COP0_SR] &= 0xffffffc0;
+ cpu->cop0_r[COP0_SR] |= (mode << 2) & 0x3f;
// Set PC to the vector selected on BEV
- cpu->pc = (cpu->cop0_sr & SR_BEV) ? 0xbfc00180 : 0x80000080;
+ cpu->pc = (cpu->cop0_r[COP0_SR] & SR_BEV) ? 0xbfc00180 : 0x80000080;
// Simulate pipeline flush
psx_cpu_fetch(cpu);
+
+ cpu->buf[1] = cpu->buf[0];
}
void psx_cpu_irq(psx_cpu_t* cpu, uint32_t irq) {// Set interrupt pending field
- cpu->cop0_cause &= ~SR_IM2;
- cpu->cop0_cause |= irq ? SR_IM2 : 0;
+ cpu->cop0_r[COP0_CAUSE] &= ~SR_IM2;
+ cpu->cop0_r[COP0_CAUSE] |= irq ? SR_IM2 : 0;
}
void psx_cpu_i_invalid(psx_cpu_t* cpu) {@@ -758,7 +781,7 @@
DO_PENDING_LOAD;
// Cache isolated
- if (cpu->cop0_sr & SR_ISC) {+ if (cpu->cop0_r[COP0_SR] & SR_ISC) { log_debug("Ignoring write while cache is isolated");return;
@@ -777,7 +800,7 @@
DO_PENDING_LOAD;
// Cache isolated
- if (cpu->cop0_sr & SR_ISC) {+ if (cpu->cop0_r[COP0_SR] & SR_ISC) { log_debug("Ignoring write while cache is isolated");return;
@@ -821,7 +844,7 @@
DO_PENDING_LOAD;
// Cache isolated
- if (cpu->cop0_sr & SR_ISC) {+ if (cpu->cop0_r[COP0_SR] & SR_ISC) { log_debug("Ignoring write while cache is isolated");return;
@@ -1226,20 +1249,7 @@
DO_PENDING_LOAD;
- switch (D) {- case 3: cpu->load_v = cpu->cop0_bpc; break;
- case 5: cpu->load_v = cpu->cop0_bda; break;
- case 6: cpu->load_v = cpu->cop0_jumpdest; break;
- case 7: cpu->load_v = cpu->cop0_dcic; break;
- case 8: cpu->load_v = cpu->cop0_badvaddr; break;
- case 9: cpu->load_v = cpu->cop0_bdam; break;
- case 11: cpu->load_v = cpu->cop0_bpcm; break;
- case 12: cpu->load_v = cpu->cop0_sr; break;
- case 13: cpu->load_v = cpu->cop0_cause; break;
- case 14: cpu->load_v = cpu->cop0_epc; break;
- case 15: cpu->load_v = cpu->cop0_prid; break;
- }
-
+ cpu->load_v = cpu->cop0_r[D];
cpu->load_d = T;
}
@@ -1256,18 +1266,7 @@
DO_PENDING_LOAD;
- switch (D) {- case 3: cpu->cop0_bpc = t; break;
- case 5: cpu->cop0_bda = t; break;
- case 7: cpu->cop0_dcic = t; break;
- case 9: cpu->cop0_bdam = t; break;
- case 11: cpu->cop0_bpcm = t; break;
- case 12: cpu->cop0_sr = t; break;
- }
-
- if ((cpu->cop0_sr & SR_IEC) && (cpu->cop0_cause & cpu->cop0_sr & SR_IM2)) {- psx_cpu_exception(cpu, CAUSE_INT);
- }
+ cpu->cop0_r[D] = t;
}
void psx_cpu_i_ctc0(psx_cpu_t* cpu) {@@ -1288,10 +1287,10 @@
DO_PENDING_LOAD;
- uint32_t mode = cpu->cop0_sr & 0x3f;
+ uint32_t mode = cpu->cop0_r[COP0_SR] & 0x3f;
- cpu->cop0_sr &= 0xfffffff0;
- cpu->cop0_sr |= mode >> 2;
+ cpu->cop0_r[COP0_SR] &= 0xfffffff0;
+ cpu->cop0_r[COP0_SR] |= mode >> 2;
}
#undef R_R0
--- a/psx/cpu.h
+++ b/psx/cpu.h
@@ -52,6 +52,18 @@
cop0r15 - PRID - Processor ID (R)
*/
+#define COP0_BPC 3
+#define COP0_BDA 5
+#define COP0_JUMPDEST 6
+#define COP0_DCIC 7
+#define COP0_BADVADDR 8
+#define COP0_BDAM 9
+#define COP0_BPCM 11
+#define COP0_SR 12
+#define COP0_CAUSE 13
+#define COP0_EPC 14
+#define COP0_PRID 15
+
struct psx_cpu_t {uint32_t r[32];
uint32_t buf[2];
@@ -59,19 +71,10 @@
uint32_t hi, lo;
uint32_t load_d, load_v;
uint32_t last_cycles;
+ uint32_t total_cycles;
int branch, delay_slot;
- uint32_t cop0_bpc;
- uint32_t cop0_bda;
- uint32_t cop0_jumpdest;
- uint32_t cop0_dcic;
- uint32_t cop0_badvaddr;
- uint32_t cop0_bdam;
- uint32_t cop0_bpcm;
- uint32_t cop0_sr;
- uint32_t cop0_cause;
- uint32_t cop0_epc;
- uint32_t cop0_prid;
+ uint32_t cop0_r[16];
psx_bus_t* bus;
@@ -158,6 +161,7 @@
void psx_cpu_fetch(psx_cpu_t*);
void psx_cpu_set_a_kcall_hook(psx_cpu_t*, psx_cpu_kcall_hook_t);
void psx_cpu_set_b_kcall_hook(psx_cpu_t*, psx_cpu_kcall_hook_t);
+void psx_cpu_check_irq(psx_cpu_t*);
/*
00h INT Interrupt
@@ -178,19 +182,19 @@
0Ch Ov Arithmetic overflow
*/
-#define CAUSE_INT 0x00
-#define CAUSE_MOD 0x01
-#define CAUSE_TLBL 0x02
-#define CAUSE_TLBS 0x03
-#define CAUSE_ADEL 0x04
-#define CAUSE_ADES 0x05
-#define CAUSE_IBE 0x06
-#define CAUSE_DBE 0x07
-#define CAUSE_SYSCALL 0x08
-#define CAUSE_BP 0x09
-#define CAUSE_RI 0x0a
-#define CAUSE_CPU 0x0b
-#define CAUSE_OV 0x0c
+#define CAUSE_INT (0x00 << 2)
+#define CAUSE_MOD (0x01 << 2)
+#define CAUSE_TLBL (0x02 << 2)
+#define CAUSE_TLBS (0x03 << 2)
+#define CAUSE_ADEL (0x04 << 2)
+#define CAUSE_ADES (0x05 << 2)
+#define CAUSE_IBE (0x06 << 2)
+#define CAUSE_DBE (0x07 << 2)
+#define CAUSE_SYSCALL (0x08 << 2)
+#define CAUSE_BP (0x09 << 2)
+#define CAUSE_RI (0x0a << 2)
+#define CAUSE_CPU (0x0b << 2)
+#define CAUSE_OV (0x0c << 2)
void psx_cpu_i_invalid(psx_cpu_t*);
--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -239,8 +239,11 @@
if (cdrom->irq_delay) {cdrom->irq_delay -= 2;
- if (!cdrom->irq_delay)
+ if (cdrom->irq_delay <= 0) {psx_ic_irq(cdrom->ic, IC_CDROM);
+
+ cdrom->irq_delay = 0;
+ }
}
}
--- a/psx/dev/gpu.c
+++ b/psx/dev/gpu.c
@@ -596,8 +596,14 @@
gpu->v0.x = gpu->buf[1] & 0xffff;
gpu->v0.y = gpu->buf[1] >> 16;
- gpu_render_flat_rectangle(gpu, gpu->v0, 1, 1, gpu->color);
+ gpu->v0.x += gpu->off_x;
+ gpu->v0.y += gpu->off_y;
+ gpu->vram[gpu->v0.x + (gpu->v0.y * 1024)] = gpu_to_bgr555(gpu->color);
+
+ // Optimize pixel plotting
+ // gpu_render_flat_rectangle(gpu, gpu->v0, 1, 1, gpu->color);
+
gpu->state = GPU_STATE_RECV_CMD;
}
} break;
@@ -752,7 +758,8 @@
if (gpu->line == GPU_SCANS_PER_VDRAW_NTSC) {// Disable Vblank for now
- // psx_ic_irq(gpu->ic, IC_VBLANK);
+ // log_fatal("Vblank");+ psx_ic_irq(gpu->ic, IC_VBLANK);
} else if (gpu->line == GPU_SCANS_PER_FRAME_NTSC) {gpu->line = 0;
}
@@ -760,13 +767,20 @@
void psx_gpu_update(psx_gpu_t* gpu, int cyc) {// Convert CPU (~33.8 MHz) cycles to GPU (~53.7 MHz) cycles
- gpu->cycles += ((float)cyc) * (PSX_GPU_CLOCK_FREQ_PAL / PSX_CPU_CLOCK_FREQ);
+ gpu->cycles += (float)cyc * (PSX_GPU_CLOCK_FREQ_NTSC / PSX_CPU_CLOCK_FREQ);
+ //gpu->cycles += (float)cyc;
- //if (gpu->cycles >= (float)GPU_CYCLES_PER_HDRAW_NTSC) {- // Tick Hblank timer
+ // if (gpu->cycles >= ((float)PSX_CPU_CLOCK / 60.0f)) {+ // psx_ic_irq(gpu->ic, IC_VBLANK);
+ // gpu->cycles -= (float)PSX_CPU_CLOCK / 60.0f;
+ // }
+
+ // if (gpu->cycles >= (float)GPU_CYCLES_PER_HDRAW_NTSC) {+ // Tick Hblank timer
+
if (gpu->cycles >= (float)GPU_CYCLES_PER_SCANL_NTSC) {- gpu->cycles -= (float)GPU_CYCLES_PER_SCANL_NTSC;
+ gpu->cycles = 0;
gpu_scanline_event(gpu);
}
--- a/psx/dev/ic.c
+++ b/psx/dev/ic.c
@@ -59,16 +59,26 @@
log_warn("Unhandled 32-bit IC write at offset %08x (%08x)", offset, value);} break;
}
+
+ // Emulate acknowledge
+ if (!(ic->stat & ic->mask)) {+ ic->cpu->cop0_r[COP0_CAUSE] &= ~SR_IM2;
+ }
}
void psx_ic_write16(psx_ic_t* ic, uint32_t offset, uint16_t value) { switch (offset) {- case 0x00: ic->stat = value; break;
+ case 0x00: ic->stat &= value; break;
case 0x04: ic->mask = value; break;
default: { log_warn("Unhandled 16-bit IC write at offset %08x (%08x)", offset, value);} break;
+ }
+
+ // Emulate acknowledge
+ if (!(ic->stat & ic->mask)) {+ ic->cpu->cop0_r[COP0_CAUSE] &= ~SR_IM2;
}
}
--- a/psx/dev/timer.c
+++ b/psx/dev/timer.c
@@ -38,16 +38,16 @@
return 0x000016b0;
}
- int t = (offset >> 4) & 0x3;
- int r = offset & 0xf;
+ // int t = (offset >> 4) & 0x3;
+ // int r = offset & 0xf;
- if (r == 0) {- switch (t) {- case 0: return timer->t0_stub++;
- case 1: return timer->t1_stub++;
- case 2: return timer->t2_stub++;
- }
- }
+ // if (r == 0) {+ // switch (t) {+ // case 0: return timer->t0_stub++;
+ // case 1: return timer->t1_stub++;
+ // case 2: return timer->t2_stub++;
+ // }
+ // }
log_fatal("Unhandled 16-bit TIMER read at offset %08x", offset);--- a/psx/psx.c
+++ b/psx/psx.c
@@ -28,6 +28,7 @@
psx_cpu_cycle(psx->cpu);
psx_cdrom_update(psx->cdrom);
psx_gpu_update(psx->gpu, psx->cpu->last_cycles);
+ psx_cpu_check_irq(psx->cpu);
}
void psx_run_frame(psx_t* psx) {@@ -55,6 +56,10 @@
uint32_t psx_get_display_height(psx_t* psx) {return (psx->gpu->display_mode & 0x4) ? 480 : 240;
+}
+
+uint32_t psx_get_display_format(psx_t* psx) {+ return (psx->gpu->display_mode >> 4) & 1;
}
void psx_init(psx_t* psx, const char* bios_path) {--- a/psx/psx.h
+++ b/psx/psx.h
@@ -39,6 +39,7 @@
void* psx_get_display_buffer(psx_t*);
uint32_t psx_get_display_width(psx_t*);
uint32_t psx_get_display_height(psx_t*);
+uint32_t psx_get_display_format(psx_t*);
uint32_t* psx_take_screenshot(psx_t*);
psx_bios_t* psx_get_bios(psx_t*);
psx_ram_t* psx_get_ram(psx_t*);
--
⑨