ref: bd3e55548dafd97ce02401010f0308d437889dae
parent: 4787a909b713b7f655172177fc8ea509cc1b2f17
author: allkern <lisandroaalarcon@gmail.com>
date: Thu Jul 6 19:56:38 EDT 2023
Fix GPU commands
--- a/psx/dev/gpu.c
+++ b/psx/dev/gpu.c
@@ -40,16 +40,26 @@
case 0x00: {uint32_t data = 0x0;
- if (gpu->c0_ysiz) {- data = *((uint32_t*)(&gpu->vram[gpu->c0_xpos + (gpu->c0_ypos * 1024)]));
+ if (gpu->c0_tsiz) {+ data |= gpu->vram[gpu->c0_addr + (gpu->c0_xcnt + (gpu->c0_ycnt * 1024))];
- gpu->c0_xsiz -= 2;
- gpu->c0_xpos += 2;
+ gpu->c0_xcnt += 1;
- if (gpu->c0_xsiz <= 0) {- gpu->c0_ypos += 1;
- gpu->c0_ysiz -= 1;
+ if (gpu->c0_xcnt == gpu->c0_xsiz) {+ gpu->c0_ycnt += 1;
+ gpu->c0_xcnt = 0;
}
+
+ data |= gpu->vram[gpu->c0_addr + (gpu->c0_xcnt + (gpu->c0_ycnt * 1024))] << 16;
+
+ gpu->c0_xcnt += 1;
+
+ if (gpu->c0_xcnt == gpu->c0_xsiz) {+ gpu->c0_ycnt += 1;
+ gpu->c0_xcnt = 0;
+ }
+
+ gpu->c0_tsiz -= 2;
}
return data;
@@ -94,11 +104,11 @@
#define EDGE(a, b, c) ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x))
-uint16_t gpu_fetch_texel(psx_gpu_t* gpu, uint16_t tx, uint16_t ty, uint32_t tpx, uint32_t tpy) {+uint16_t gpu_fetch_texel(psx_gpu_t* gpu, uint16_t tx, uint16_t ty, uint32_t tpx, uint32_t tpy, int depth) {tx = (tx & ~gpu->texw_mx) | (gpu->texw_ox & gpu->texw_mx);
ty = (ty & ~gpu->texw_my) | (gpu->texw_oy & gpu->texw_my);
- switch (gpu->texp_d) {+ switch (depth) {// 4-bit
case 0: {uint16_t texel = gpu->vram[(tpx + (tx >> 2)) + ((tpy + ty) * 1024)];
@@ -124,20 +134,82 @@
}
}
-void gpu_render_flat_line(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, uint32_t color) {- double l = 640.0;
+void plotLineLow(psx_gpu_t* gpu, int x0, int y0, int x1, int y1, uint16_t color) {+ int dx = x1 - x0;
+ int dy = y1 - y0;
+ int yi = 1;
+ if (dy < 0) {+ yi = -1;
+ dy = -dy;
+ }
+ int d = (2 * dy) - dx;
+ int y = y0;
- for (double p = 0.0; p < 1.0; p += 1.0 / l) {- unsigned int ax = (v0.x * p) + (v1.x * (1.0f - p));
- unsigned int ay = (v0.y * p) + (v1.y * (1.0f - p));
+ for (int x = x0; x < x1; x++) {+ gpu->vram[x + (y * 1024)] = color;
- if ((ax > 1024) || (ay > 512))
- continue;
+ if (d > 0) {+ y += yi;
+ d += (2 * (dy - dx));
+ } else {+ d += 2*dy;
+ }
+ }
+}
- gpu->vram[ax + (ay * 1024)] = color;
+void plotLineHigh(psx_gpu_t* gpu, int x0, int y0, int x1, int y1, uint16_t color) {+ int dx = x1 - x0;
+ int dy = y1 - y0;
+ int xi = 1;
+ if (dx < 0) {+ xi = -1;
+ dx = -dx;
}
+ int d = (2 * dx) - dy;
+ int x = x0;
+
+ for (int y = y0; y < y1; y++) {+ gpu->vram[x + (y * 1024)] = color;
+ if (d > 0) {+ x = x + xi;
+ d += (2 * (dx - dy));
+ } else {+ d += 2*dx;
+ }
+ }
}
+void plotLine(psx_gpu_t* gpu, int x0, int y0, int x1, int y1, uint16_t color) {+ if (abs(y1 - y0) < abs(x1 - x0)) {+ if (x0 > x1) {+ plotLineLow(gpu, x1, y1, x0, y0, color);
+ } else {+ plotLineLow(gpu, x0, y0, x1, y1, color);
+ }
+ } else {+ if (y0 > y1) {+ plotLineHigh(gpu, x1, y1, x0, y0, color);
+ } else {+ plotLineHigh(gpu, x0, y0, x1, y1, color);
+ }
+ }
+}
+
+void gpu_render_flat_line(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, uint32_t color) {+ plotLine(gpu, v0.x, v0.y, v1.x, v1.y, color);
+ // double l = 640.0;
+
+ // for (double p = 0.0; p < 1.0; p += 1.0 / l) {+ // unsigned int ax = (v0.x * p) + (v1.x * (1.0f - p));
+ // unsigned int ay = (v0.y * p) + (v1.y * (1.0f - p));
+
+ // if ((ax > 1024) || (ay > 512))
+ // continue;
+
+ // gpu->vram[ax + (ay * 1024)] = color;
+ // }
+}
+
void gpu_render_flat_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint32_t h, uint32_t color) {/* Offset coordinates */
v.x += gpu->off_x;
@@ -171,7 +243,7 @@
for (int y = ymin; y < ymax; y++) { for (int x = xmin; x < xmax; x++) {- uint16_t color = gpu_fetch_texel(gpu, a.tx + xc, a.ty + yc, tpx, tpy);
+ uint16_t color = gpu_fetch_texel(gpu, a.tx + xc, a.ty + yc, tpx, tpy, gpu->texp_d);
++xc;
@@ -298,7 +370,7 @@
}
}
-void gpu_render_textured_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vertex_t v2, uint32_t tpx, uint32_t tpy) {+void gpu_render_textured_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vertex_t v2, uint32_t tpx, uint32_t tpy, int depth) {vertex_t a, b, c;
a = v0;
@@ -341,7 +413,7 @@
uint32_t tx = ((z0 * a.tx) + (z1 * b.tx) + (z2 * c.tx)) / area;
uint32_t ty = ((z0 * a.ty) + (z1 * b.ty) + (z2 * c.ty)) / area;
- uint16_t color = gpu_fetch_texel(gpu, tx, ty, tpx, tpy);
+ uint16_t color = gpu_fetch_texel(gpu, tx, ty, tpx, tpy, depth);
if (!color) continue;
@@ -511,9 +583,9 @@
if (!gpu->cmd_args_remaining) {gpu->state = GPU_STATE_RECV_DATA;
+ uint32_t texp = gpu->buf[4] >> 16;
gpu->color = gpu->buf[0] & 0xffffff;
gpu->pal = gpu->buf[2] >> 16;
- gpu->texp = gpu->buf[4] >> 16;
gpu->v0.tx = gpu->buf[2] & 0xff;
gpu->v0.ty = (gpu->buf[2] >> 8) & 0xff;
gpu->v1.tx = gpu->buf[4] & 0xff;
@@ -534,11 +606,12 @@
gpu->clut_x = (gpu->pal & 0x3f) << 4;
gpu->clut_y = (gpu->pal >> 6) & 0x1ff;
- uint32_t tpx = (gpu->texp & 0xf) << 6;
- uint32_t tpy = (gpu->texp & 0x10) << 4;
+ uint32_t tpx = (texp & 0xf) << 6;
+ uint32_t tpy = (texp & 0x10) << 4;
+ uint32_t depth = (texp >> 7) & 0x3;
- gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy);
- gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy);
+ gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy, depth);
+ gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy, depth);
gpu->state = GPU_STATE_RECV_CMD;
}
@@ -558,9 +631,9 @@
if (!gpu->cmd_args_remaining) {gpu->state = GPU_STATE_RECV_DATA;
+ uint32_t texp = gpu->buf[4] >> 16;
gpu->color = gpu->buf[0] & 0xffffff;
gpu->pal = gpu->buf[2] >> 16;
- gpu->texp = gpu->buf[4] >> 16;
gpu->v0.tx = gpu->buf[2] & 0xff;
gpu->v0.ty = (gpu->buf[2] >> 8) & 0xff;
gpu->v1.tx = gpu->buf[4] & 0xff;
@@ -581,11 +654,12 @@
gpu->clut_x = (gpu->pal & 0x3f) << 4;
gpu->clut_y = (gpu->pal >> 6) & 0x1ff;
- uint32_t tpx = (gpu->texp & 0xf) << 6;
- uint32_t tpy = (gpu->texp & 0x10) << 4;
+ uint32_t tpx = (texp & 0xf) << 6;
+ uint32_t tpy = (texp & 0x10) << 4;
+ int depth = (texp >> 7) & 0x3;
- gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy);
- gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy);
+ gpu_render_textured_triangle(gpu, gpu->v0, gpu->v1, gpu->v2, tpx, tpy, depth);
+ gpu_render_textured_triangle(gpu, gpu->v1, gpu->v2, gpu->v3, tpx, tpy, depth);
gpu->state = GPU_STATE_RECV_CMD;
}
@@ -687,10 +761,18 @@
case GPU_STATE_RECV_ARGS: { if (!gpu->cmd_args_remaining) {- gpu->c0_xpos = gpu->buf[1] & 0xffff;
- gpu->c0_ypos = gpu->buf[1] >> 16;
+ gpu->c0_xcnt = 0;
+ gpu->c0_ycnt = 0;
+ uint32_t c0_xpos = gpu->buf[1] & 0xffff;
+ uint32_t c0_ypos = gpu->buf[1] >> 16;
gpu->c0_xsiz = gpu->buf[2] & 0xffff;
gpu->c0_ysiz = gpu->buf[2] >> 16;
+ c0_xpos = c0_xpos & 0x3ff;
+ c0_ypos = c0_ypos & 0x1ff;
+ gpu->c0_xsiz = ((gpu->c0_xsiz - 1) & 0x3ff) + 1;
+ gpu->c0_ysiz = ((gpu->c0_ysiz - 1) & 0x1ff) + 1;
+ gpu->c0_tsiz = ((gpu->c0_xsiz * gpu->c0_ysiz) + 1) & 0xfffffffe;
+ gpu->c0_addr = c0_xpos + (c0_ypos * 1024);
gpu->state = GPU_STATE_RECV_CMD;
}
@@ -720,12 +802,6 @@
gpu->xsiz = (((gpu->xsiz & 0x3ff) + 0x0f) & 0xfffffff0);
gpu->ysiz = gpu->ysiz & 0x1ff;
- log_fatal("Render flat rectangle pos=(%u, %u) siz=(%u, %u), color=%02x",- gpu->v0.x, gpu->v0.y,
- gpu->xsiz, gpu->ysiz,
- gpu->color
- );
-
gpu->v0.x += gpu->off_x;
gpu->v0.y += gpu->off_y;
@@ -743,9 +819,12 @@
case 0x01: /* Cache clear */ break;
case 0x02: gpu_cmd_02(gpu); break;
case 0x28: gpu_cmd_28(gpu); break;
- case 0x2c: gpu_cmd_2c(gpu); break;
+ case 0x2c: gpu_cmd_2d(gpu); break;
case 0x2d: gpu_cmd_2d(gpu); break;
+ case 0x2e: gpu_cmd_2d(gpu); break;
+ case 0x2f: gpu_cmd_2d(gpu); break;
case 0x30: gpu_cmd_30(gpu); break;
+ case 0x32: gpu_cmd_30(gpu); break;
case 0x38: gpu_cmd_38(gpu); break;
case 0x40: gpu_cmd_40(gpu); break;
case 0x64: gpu_cmd_64(gpu); break;
--- a/psx/dev/gpu.h
+++ b/psx/dev/gpu.h
@@ -70,8 +70,10 @@
uint32_t xcnt, ycnt;
vertex_t v0, v1, v2, v3;
uint32_t pal, texp;
- uint32_t c0_xpos, c0_ypos;
+ uint32_t c0_xcnt, c0_ycnt;
+ uint32_t c0_addr;
int c0_xsiz, c0_ysiz;
+ int c0_tsiz;
// GPU state
uint32_t state;
--- a/psx/dev/pad.c
+++ b/psx/dev/pad.c
@@ -69,11 +69,11 @@
uint32_t psx_pad_read32(psx_pad_t* pad, uint32_t offset) { switch (offset) {- case 0: log_fatal("RX read 32"); return pad_read_rx(pad);- case 4: log_fatal("ST read 32"); return pad_handle_stat_read(pad);- case 8: log_fatal("MD read 32"); return pad->mode;- case 10: log_fatal("CT read 32"); return pad->ctrl;- case 14: log_fatal("BD read 32"); return pad->baud;+ case 0: return pad_read_rx(pad);
+ case 4: return pad_handle_stat_read(pad);
+ case 8: return pad->mode;
+ case 10: return pad->ctrl;
+ case 14: return pad->baud;
}
log_fatal("Unhandled 32-bit PAD read at offset %08x", offset);@@ -83,11 +83,11 @@
uint16_t psx_pad_read16(psx_pad_t* pad, uint32_t offset) { switch (offset) {- case 0: log_fatal("RX read 16"); return pad_read_rx(pad) & 0xffff;- case 4: log_fatal("ST read 16 %04x", pad_handle_stat_read(pad) & 0xffff); return pad_handle_stat_read(pad) & 0xffff;- case 8: log_fatal("MD read 16"); return pad->mode;- case 10: log_fatal("CT read 16 %04x", pad->ctrl & 0xffff); return pad->ctrl & 0xffff;- case 14: log_fatal("BD read 16"); return pad->baud;+ case 0: return pad_read_rx(pad) & 0xffff;
+ case 4: return pad_handle_stat_read(pad) & 0xffff;
+ case 8: return pad->mode;
+ case 10: return pad->ctrl & 0xffff;
+ case 14: return pad->baud;
}
log_fatal("Unhandled 16-bit PAD read at offset %08x", offset);@@ -97,11 +97,11 @@
uint8_t psx_pad_read8(psx_pad_t* pad, uint32_t offset) { switch (offset) {- case 0: log_fatal("RX read 8 %02x", pad_read_rx(pad) & 0xff); return pad_read_rx(pad) & 0xff;- case 4: log_fatal("ST read 8"); return pad_handle_stat_read(pad) & 0xff;- case 8: log_fatal("MD read 8"); return pad->mode & 0xff;- case 10: log_fatal("CT read 8"); return pad->ctrl & 0xff;- case 14: log_fatal("BD read 8"); return pad->baud & 0xff;+ case 0: return pad_read_rx(pad) & 0xff;
+ case 4: return pad_handle_stat_read(pad) & 0xff;
+ case 8: return pad->mode & 0xff;
+ case 10: return pad->ctrl & 0xff;
+ case 14: return pad->baud & 0xff;
}
log_fatal("Unhandled 8-bit PAD read at offset %08x", offset);@@ -111,10 +111,10 @@
void psx_pad_write32(psx_pad_t* pad, uint32_t offset, uint32_t value) { switch (offset) {- case 0: log_fatal("TX write 32 %08x", value); pad_write_tx(pad, value); return;- case 8: log_fatal("MD write 32 %08x", value); pad->mode = value & 0xffff; return;- case 10: log_fatal("CT write 32 %08x", value); pad_handle_ctrl_write(pad, value); return;- case 14: log_fatal("BD write 32 %08x", value); pad->baud = value & 0xffff; return;+ case 0: pad_write_tx(pad, value); return;
+ case 8: pad->mode = value & 0xffff; return;
+ case 10: pad_handle_ctrl_write(pad, value); return;
+ case 14: pad->baud = value & 0xffff; return;
}
log_fatal("Unhandled 32-bit PAD write at offset %08x (%08x)", offset, value);@@ -122,10 +122,10 @@
void psx_pad_write16(psx_pad_t* pad, uint32_t offset, uint16_t value) { switch (offset) {- case 0: log_fatal("TX write 16 %04x", value); pad_write_tx(pad, value); return;- case 8: log_fatal("MD write 16 %04x", value); pad->mode = value; return;- case 10: log_fatal("CT write 16 %04x", value); pad_handle_ctrl_write(pad, value); return;- case 14: log_fatal("BD write 16 %04x", value); pad->baud = value; return;+ case 0: pad_write_tx(pad, value); return;
+ case 8: pad->mode = value; return;
+ case 10: pad_handle_ctrl_write(pad, value); return;
+ case 14: pad->baud = value; return;
}
log_fatal("Unhandled 16-bit PAD write at offset %08x (%04x)", offset, value);@@ -133,10 +133,10 @@
void psx_pad_write8(psx_pad_t* pad, uint32_t offset, uint8_t value) { switch (offset) {- case 0: log_fatal("TX write 8 %02x", value); pad_write_tx(pad, value); return;- case 8: log_fatal("MD write 8 %02x", value); pad->mode = value; return;- case 10: log_fatal("CT write 8 %02x", value); pad_handle_ctrl_write(pad, value); return;- case 14: log_fatal("BD write 8 %02x", value); pad->baud = value; return;+ case 0: pad_write_tx(pad, value); return;
+ case 8: pad->mode = value; return;
+ case 10: pad_handle_ctrl_write(pad, value); return;
+ case 14: pad->baud = value; return;
}
log_fatal("Unhandled 8-bit PAD write at offset %08x (%02x)", offset, value);@@ -166,8 +166,6 @@
if (pad->cycles_until_irq <= 0) {psx_ic_irq(pad->ic, IC_JOY);
-
- log_fatal("PAD IRQ");pad->cycles_until_irq = 0;
}
--
⑨