ref: 54de596c313e459573724c1b580c763b52c5f6d7
parent: 61f58168b98ed956dc1adde1272fae68e9c63aa3
author: allkern <lisandroaalarcon@gmail.com>
date: Sun Apr 28 21:26:19 EDT 2024
Overall improvements
--- a/frontend/screen.c
+++ b/frontend/screen.c
@@ -133,29 +133,24 @@
// int frame = 0;
void psxe_screen_update(psxe_screen_t* screen) {
- // void* vram = psx_get_vram(screen->psx);
-
- // if (screen->field & 2) {
- // for (int y = screen->field & 1; y < 512; y += 2) {
- // memcpy(
- // ((uint8_t*)screen->buf) + (y * PSX_GPU_FB_STRIDE),
- // ((uint8_t*)vram) + (y * PSX_GPU_FB_STRIDE),
- // PSX_GPU_FB_STRIDE
- // );
- // }
- // }
-
- // screen->field += 1;
- // screen->field &= 3;
-
void* display_buf = screen->debug_mode ?
psx_get_vram(screen->psx) : psx_get_display_buffer(screen->psx);
- // if (screen->texture_height == 240) {
- // display_buf = screen->psx->gpu->vram + (screen->psx->gpu->disp_x + ((frame * 256) * 1024));
-
- // frame ^= 1;
- // }
+ // printf("res=(%u,%u) off=(%u,%u) disp=(%u,%u-%u,%u) draw=(%u,%u-%u,%u) vres=%u\n",
+ // screen->texture_width,
+ // screen->texture_height,
+ // screen->psx->gpu->disp_x,
+ // screen->psx->gpu->disp_y,
+ // screen->psx->gpu->disp_x1,
+ // screen->psx->gpu->disp_y1,
+ // screen->psx->gpu->disp_x2,
+ // screen->psx->gpu->disp_y2,
+ // screen->psx->gpu->draw_x1,
+ // screen->psx->gpu->draw_y1,
+ // screen->psx->gpu->draw_x2,
+ // screen->psx->gpu->draw_y2,
+ // screen->psx->gpu->disp_y2 - screen->psx->gpu->disp_y1
+ // );
SDL_UpdateTexture(screen->texture, NULL, display_buf, PSX_GPU_FB_STRIDE);
SDL_RenderClear(screen->renderer);
--- a/psx/cpu.c
+++ b/psx/cpu.c
@@ -633,7 +633,7 @@
uint32_t s = cpu->r[S];
uint32_t t = cpu->r[rt];
- DO_PENDING_LOAD;
+ uint32_t tp = t;
uint32_t addr = s + IMM16S;
uint32_t load = psx_bus_read32(cpu->bus, addr & 0xfffffffc);
@@ -641,6 +641,8 @@
if (rt == cpu->load_d)
t = cpu->load_v;
+ DO_PENDING_LOAD;
+
int shift = (int)((addr & 0x3) << 3);
uint32_t mask = (uint32_t)0x00FFFFFF >> shift;
uint32_t value = (t & mask) | (load << (24 - shift));
@@ -647,6 +649,10 @@
cpu->load_d = rt;
cpu->load_v = value;
+
+ // printf("lwl rt=%u s=%08x t=%08x addr=%08x load=%08x (%08x) tp=%08x shift=%u mask=%08x value=%08x\n",
+ // rt, s, t, addr, load, addr & 0xfffffffc, tp, shift, mask, value
+ // );
}
void psx_cpu_i_lw(psx_cpu_t* cpu) {
@@ -699,8 +705,6 @@
uint32_t s = cpu->r[S];
uint32_t t = cpu->r[rt];
- DO_PENDING_LOAD;
-
uint32_t addr = s + IMM16S;
uint32_t load = psx_bus_read32(cpu->bus, addr & 0xfffffffc);
@@ -707,6 +711,8 @@
if (rt == cpu->load_d)
t = cpu->load_v;
+ DO_PENDING_LOAD;
+
int shift = (int)((addr & 0x3) << 3);
uint32_t mask = 0xFFFFFF00 << (24 - shift);
uint32_t value = (t & mask) | (load >> shift);
@@ -713,6 +719,10 @@
cpu->load_d = rt;
cpu->load_v = value;
+
+ // printf("lwl rt=%u s=%08x t=%08x addr=%08x load=%08x (%08x) tp=%08x shift=%u mask=%08x value=%08x\n",
+ // rt, s, t, addr, load, addr & 0xfffffffc, tp, shift, mask, value
+ // );
}
void psx_cpu_i_sb(psx_cpu_t* cpu) {
@@ -1855,6 +1865,24 @@
R_GC2 = gte_clamp_rgb(cpu, 2, R_MAC2 >> 4); \
R_BC2 = gte_clamp_rgb(cpu, 3, R_MAC3 >> 4); }
+void gte_interpolate_color(psx_cpu_t* cpu, uint64_t mac1, uint64_t mac2, uint64_t mac3) {
+ R_MAC1 = (int)(gte_clamp_mac(cpu, 1, ((long)R_RFC << 12) - mac1));
+ R_MAC2 = (int)(gte_clamp_mac(cpu, 2, ((long)R_GFC << 12) - mac2));
+ R_MAC3 = (int)(gte_clamp_mac(cpu, 3, ((long)R_BFC << 12) - mac3));
+
+ R_IR1 = gte_clamp_ir(cpu, 1, R_MAC1, cpu->gte_lm);
+ R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm);
+ R_IR3 = gte_clamp_ir_z(cpu, cpu->s_mac3, cpu->gte_sf, cpu->gte_lm);
+
+ R_MAC1 = (int)(gte_clamp_mac(cpu, 1, ((long)R_IR1 * R_IR0) + mac1));
+ R_MAC2 = (int)(gte_clamp_mac(cpu, 2, ((long)R_IR2 * R_IR0) + mac2));
+ R_MAC3 = (int)(gte_clamp_mac(cpu, 3, ((long)R_IR3 * R_IR0) + mac3));
+
+ R_IR1 = gte_clamp_ir(cpu, 1, R_MAC1, cpu->gte_lm);
+ R_IR2 = gte_clamp_ir(cpu, 2, R_MAC2, cpu->gte_lm);
+ R_IR3 = gte_clamp_ir_z(cpu, cpu->s_mac3, cpu->gte_sf, cpu->gte_lm);
+}
+
void psx_gte_i_rtps(psx_cpu_t* cpu) {
GTE_RTP_DQ(0);
}
@@ -2088,7 +2116,18 @@
}
void psx_gte_i_dcpl(psx_cpu_t* cpu) {
- printf("dpcl: Unimplemented GTE instruction\n");
+ R_MAC1 = (int)(gte_clamp_mac(cpu, 1, R_RC * R_IR1) << 4);
+ R_MAC2 = (int)(gte_clamp_mac(cpu, 2, R_GC * R_IR2) << 4);
+ R_MAC3 = (int)(gte_clamp_mac(cpu, 3, R_BC * R_IR3) << 4);
+
+ gte_interpolate_color(cpu, R_MAC1, R_MAC2, R_MAC3);
+
+ R_RGB0 = R_RGB1;
+ R_RGB1 = R_RGB2;
+ R_CD2 = R_CODE;
+ R_RC2 = gte_clamp_rgb(cpu, 1, R_MAC1 >> 4);
+ R_GC2 = gte_clamp_rgb(cpu, 2, R_MAC2 >> 4);
+ R_BC2 = gte_clamp_rgb(cpu, 3, R_MAC3 >> 4);
}
void psx_gte_i_dpct(psx_cpu_t* cpu) {
--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -263,7 +263,7 @@
RESP_PUSH(
GETSTAT_MOTOR |
(cdrom->cdda_playing ? GETSTAT_PLAY : 0) |
- // (cdrom->ongoing_read_command ? GETSTAT_READ : 0) |
+ (cdrom->ongoing_read_command ? GETSTAT_READ : 0) |
(cdrom->disc ? 0 : GETSTAT_TRAYOPEN)
);
@@ -685,6 +685,43 @@
} break;
}
}
+void cdrom_cmd_mute(psx_cdrom_t* cdrom) {
+ cdrom->delayed_command = CDL_NONE;
+
+ switch (cdrom->state) {
+ case CD_STATE_RECV_CMD: {
+ if (cdrom->pfifo_index) {
+ log_fatal("CdlMute: Expected exactly 0 parameters");
+
+ cdrom->irq_delay = DELAY_1MS;
+ cdrom->delayed_command = CDL_ERROR;
+ cdrom->state = CD_STATE_ERROR;
+ cdrom->error = ERR_PCOUNT;
+ cdrom->error_flags = GETSTAT_ERROR;
+
+ return;
+ }
+
+ cdrom->irq_delay = DELAY_1MS;
+ cdrom->delayed_command = CDL_MUTE;
+ cdrom->state = CD_STATE_SEND_RESP1;
+ } break;
+
+ case CD_STATE_SEND_RESP1: {
+ SET_BITS(ifr, IFR_INT, IFR_INT3);
+ RESP_PUSH(cdrom->stat);
+
+ if (cdrom->ongoing_read_command) {
+ cdrom->state = CD_STATE_SEND_RESP2;
+ cdrom->delayed_command = cdrom->ongoing_read_command;
+ cdrom->irq_delay = DELAY_1MS;
+ } else {
+ cdrom->delayed_command = CDL_NONE;
+ cdrom->state = CD_STATE_RECV_CMD;
+ }
+ } break;
+ }
+}
void cdrom_cmd_unmute(psx_cdrom_t* cdrom) {
cdrom->delayed_command = CDL_NONE;
@@ -1455,7 +1492,7 @@
"CdlStop",
"CdlPause",
"CdlInit",
- "CdlUnimplemented",
+ "CdlMute",
"CdlUnmute",
"CdlSetfilter",
"CdlSetmode",
@@ -1490,7 +1527,7 @@
cdrom_cmd_stop,
cdrom_cmd_pause,
cdrom_cmd_init,
- cdrom_cmd_unmute,
+ cdrom_cmd_mute,
cdrom_cmd_unmute,
cdrom_cmd_setfilter,
cdrom_cmd_setmode,
--- a/psx/dev/cdrom.h
+++ b/psx/dev/cdrom.h
@@ -307,6 +307,7 @@
void cdrom_cmd_stop(psx_cdrom_t*);
void cdrom_cmd_pause(psx_cdrom_t*);
void cdrom_cmd_init(psx_cdrom_t*);
+void cdrom_cmd_mute(psx_cdrom_t*);
void cdrom_cmd_unmute(psx_cdrom_t*);
void cdrom_cmd_setfilter(psx_cdrom_t*);
void cdrom_cmd_setmode(psx_cdrom_t*);
--- a/psx/dev/gpu.c
+++ b/psx/dev/gpu.c
@@ -221,6 +221,12 @@
for (int y = ymin; y < ymax; y++) {
for (int x = xmin; x < xmax; x++) {
+ int bc = (x >= gpu->draw_x1) && (x <= gpu->draw_x2) &&
+ (y >= gpu->draw_y1) && (y <= gpu->draw_y2);
+
+ if (!bc)
+ continue;
+
p.x = x;
p.y = y;
@@ -501,7 +507,10 @@
int y = y0;
for (int x = x0; x < x1; x++) {
- if ((x < 1024) && (y < 512) && (x >= 0) && (y >= 0))
+ int bc = (x >= gpu->draw_x1) && (x <= gpu->draw_x2) &&
+ (y >= gpu->draw_y1) && (y <= gpu->draw_y2);
+
+ if ((x < 1024) && (y < 512) && (x >= 0) && (y >= 0) && bc)
gpu->vram[x + (y * 1024)] = color;
if (d > 0) {
@@ -525,8 +534,12 @@
int x = x0;
for (int y = y0; y < y1; y++) {
- if ((x < 1024) && (y < 512) && (x >= 0) && (y >= 0))
+ int bc = (x >= gpu->draw_x1) && (x <= gpu->draw_x2) &&
+ (y >= gpu->draw_y1) && (y <= gpu->draw_y2);
+
+ if ((x < 1024) && (y < 512) && (x >= 0) && (y >= 0) && bc)
gpu->vram[x + (y * 1024)] = color;
+
if (d > 0) {
x = x + xi;
d += (2 * (dx - dy));
@@ -574,6 +587,12 @@
for (uint32_t y = ymin; y < ymax; y++) {
for (uint32_t x = xmin; x < xmax; x++) {
+ int bc = (x >= gpu->draw_x1) && (x <= gpu->draw_x2) &&
+ (y >= gpu->draw_y1) && (y <= gpu->draw_y2);
+
+ if (!bc)
+ continue;
+
gpu->vram[x + (y * 1024)] = color;
}
}
@@ -1466,6 +1485,12 @@
for (uint32_t y = gpu->v0.y; y < (gpu->v0.y + gpu->ysiz); y++) {
for (uint32_t x = gpu->v0.x; x < (gpu->v0.x + gpu->xsiz); x++) {
+ int bc = (x >= gpu->draw_x1) && (x <= gpu->draw_x2) &&
+ (y >= gpu->draw_y1) && (y <= gpu->draw_y2);
+
+ if (!bc)
+ continue;
+
if ((x < 1024) && (y < 512) && (x >= 0) && (y >= 0))
gpu->vram[x + (y * 1024)] = color;
}
@@ -1645,6 +1670,10 @@
case 0x06: {
gpu->disp_x1 = value & 0xfff;
gpu->disp_x2 = (value >> 12) & 0xfff;
+ } break;
+ case 0x07: {
+ gpu->disp_y1 = value & 0x1ff;
+ gpu->disp_y2 = (value >> 10) & 0x1ff;
} break;
case 0x08:
gpu->display_mode = value & 0xffffff;
--- a/psx/dev/gpu.h
+++ b/psx/dev/gpu.h
@@ -17,6 +17,7 @@
// Use this when updating your texture
#define PSX_GPU_FB_STRIDE 2048
+// 0x100000 * 2
#define PSX_GPU_VRAM_SIZE (0x100000)
#define PSX_GPU_CLOCK_NTSC 53693175 // 53.693175 MHz
--- a/psx/psx.c
+++ b/psx/psx.c
@@ -90,7 +90,15 @@
}
uint32_t psx_get_dmode_height(psx_t* psx) {
- return (psx->gpu->display_mode & 0x4) ? 480 : 240;
+ if (psx->gpu->display_mode & 0x4)
+ return 480;
+
+ int disp = psx->gpu->disp_y2 - psx->gpu->disp_y1;
+
+ if (disp < (255-16))
+ return disp;
+
+ return 240;
}
double psx_get_display_aspect(psx_t* psx) {
--
⑨