shithub: psxe

Download patch

ref: 60550f8be5060a38225dd0a2ef0e920e48f249f4
parent: f4eec2ab8a9bcf9c770e9eb471cc5a7efbe40304
author: allkern <lisandroaalarcon@gmail.com>
date: Thu Sep 28 18:29:40 EDT 2023

Work on refactoring the GPU

--- a/psx/dev/gpu.c
+++ b/psx/dev/gpu.c
@@ -26,6 +26,8 @@
 
 // #define BGR555(c) gpu_to_bgr555(c)
 
+#define VRAM(x, y) gpu->vram[(x) + ((y) * 1024)]
+
 int min3(int a, int b, int c) {
     int m = a < b ? a : b;
 
@@ -141,25 +143,23 @@
     switch (depth) {
         // 4-bit
         case 0: {
-            uint16_t texel = gpu->vram[(tpx + (tx >> 2)) + ((tpy + ty) * 1024)];
+            uint16_t texel = VRAM(tpx + (tx >> 2), tpy + ty);
+            uint16_t index = (texel >> ((tx & 0x1) << 3)) & 0xff;
 
-            int index = (texel >> ((tx & 0x3) << 2)) & 0xf;
-
-            return gpu->vram[(clutx + index) + (cluty * 1024)];
+            return VRAM(clutx + index, cluty);
         } break;
 
         // 8-bit
         case 1: {
-            uint16_t texel = gpu->vram[(tpx + (tx >> 1)) + ((tpy + ty) * 1024)];
+            uint16_t texel = VRAM(tpx + (tx >> 1), tpy + ty);
+            uint16_t index = (texel >> ((tx & 0x1) << 3)) & 0xff;
 
-            int index = (texel >> ((tx & 0x1) << 3)) & 0xff;
-
-            return gpu->vram[(clutx + index) + (cluty * 1024)];
+            return VRAM(clutx + index, cluty);
         } break;
 
         // 15-bit
         default: {
-            return gpu->vram[(tpx + tx) + ((tpy + ty) * 1024)];
+            return VRAM(tpx + tx, tpy + ty);
         } break;
     }
 }
@@ -199,10 +199,10 @@
     c.x += gpu->off_x;
     c.y += gpu->off_y;
 
-    int xmin = max(min3(a.x, b.x, c.x), gpu->draw_x1);
-    int ymin = max(min3(a.y, b.y, c.y), gpu->draw_y1);
-    int xmax = min(max3(a.x, b.x, c.x), gpu->draw_x2); 
-    int ymax = min(max3(a.y, b.y, c.y), gpu->draw_y2);
+    int xmin = min3(a.x, b.x, c.x);
+    int ymin = min3(a.y, b.y, c.y);
+    int xmax = max3(a.x, b.x, c.x); 
+    int ymax = max3(a.y, b.y, c.y);
 
     float area = EDGE(a, b, c);
 
@@ -217,6 +217,12 @@
 
             if ((z0 < 0) || (z1 < 0) || (z2 < 0))
                 continue;
+            
+            int bc = (x >= gpu->draw_x1) && (x <= gpu->draw_x2) &&
+                     (y >= gpu->draw_y1) && (y <= gpu->draw_y2);
+            
+            if (!bc)
+                continue;
 
             uint16_t color = 0;
             uint32_t mod   = 0;
@@ -292,13 +298,12 @@
             int cb = ((color >> 10) & 0x1f) << 3;
 
             if (transp) {
-                uint16_t back = gpu->vram[x + (y * 1024)];
+                uint16_t back = VRAM(x, y);
 
                 int br = ((back >> 0 ) & 0x1f) << 3;
                 int bg = ((back >> 5 ) & 0x1f) << 3;
                 int bb = ((back >> 10) & 0x1f) << 3;
 
-                // Do we use transp or gpustat here?
                 switch (transp_mode) {
                     case 0: {
                         cr = (0.5f * br) + (0.5f * cr);
@@ -331,7 +336,7 @@
                 color = BGR555(rgb);
             }
 
-            gpu->vram[x + (y * 1024)] = color;
+            VRAM(x, y) = color;
         }
     }
 }
@@ -413,7 +418,7 @@
             int cb = ((color >> 10) & 0x1f) << 3;
 
             if (transp) {
-                uint16_t back = gpu->vram[x + (y * 1024)];
+                uint16_t back = VRAM(x, y);
 
                 int br = ((back >> 0 ) & 0x1f) << 3;
                 int bg = ((back >> 5 ) & 0x1f) << 3;
@@ -451,7 +456,7 @@
                 color = BGR555(rgb);
             }
 
-            gpu->vram[x + (y * 1024)] = color;
+            VRAM(x, y) = color;
 
             skip:
 
@@ -476,8 +481,8 @@
     int y = y0;
 
     for (int x = x0; x < x1; x++) {
-        if ((x < 1024) && (y < 512) && (x >= 0) && (y >= 0))
-            gpu->vram[x + (y * 1024)] = color;
+        if ((x >= gpu->draw_x1) && (x <= gpu->draw_x2) && (y >= gpu->draw_y1) && (y <= gpu->draw_y2))
+            VRAM(x, y) = color;
 
         if (d > 0) {
             y += yi;
@@ -500,8 +505,9 @@
     int x = x0;
 
     for (int y = y0; y < y1; y++) {
-        if ((x < 1024) && (y < 512))
-            gpu->vram[x + (y * 1024)] = color;
+        if ((x >= gpu->draw_x1) && (x <= gpu->draw_x2) && (y >= gpu->draw_y1) && (y <= gpu->draw_y2))
+            VRAM(x, y) = color;
+
         if (d > 0) {
             x = x + xi;
             d += (2 * (dx - dy));
@@ -542,11 +548,9 @@
     int xmax = min(xmin + w, gpu->draw_x2);
     int ymax = min(ymin + h, gpu->draw_y2);
 
-    for (uint32_t y = ymin; y < ymax; y++) {
-        for (uint32_t x = xmin; x < xmax; x++) {
-            gpu->vram[x + (y * 1024)] = color;
-        }
-    }
+    for (uint32_t y = ymin; y < ymax; y++)
+        for (uint32_t x = xmin; x < xmax; x++)
+            VRAM(x, y) = color;
 }
 
 void gpu_render_textured_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint32_t h, uint16_t clutx, uint16_t cluty, uint32_t color) {
@@ -788,7 +792,7 @@
 
                 if (textured && raw)
                     rect.v0.c = 0x808080;
-
+                
                 gpu_render_rect(gpu, rect);
 
                 gpu->state = GPU_STATE_RECV_CMD;
@@ -810,16 +814,6 @@
             int vertices = 3 + quad;
  
             gpu->cmd_args_remaining = (fields_per_vertex * vertices) - shaded;
-
-            // log_set_quiet(0);
-            // log_fatal("Poly: GP0(%02x) shaded=%u, quad=%u, textured=%u, argc=%u, fpv=%u, vertc=%u",
-            //     gpu->buf[0] >> 24,
-            //     shaded, quad, textured,
-            //     gpu->cmd_args_remaining,
-            //     fields_per_vertex,
-            //     vertices
-            // );
-            // log_set_quiet(1);
         } break;
 
         case GPU_STATE_RECV_ARGS: {
@@ -865,15 +859,6 @@
                     gpu_render_triangle(gpu, poly.v[0], poly.v[1], poly.v[2], poly);
                     gpu_render_triangle(gpu, poly.v[1], poly.v[2], poly.v[3], poly);
                 } else {
-                    // log_set_quiet(0);
-                    // log_fatal("v0=(%3u, %3u, %06x) v1=(%3u, %3u, %06x) v2=(%3u, %3u, %06x) co=%u vo=%u tco=%u tpo=%u",
-                    //     poly.v[0].x, poly.v[0].y, poly.v[0].c,
-                    //     poly.v[1].x, poly.v[1].y, poly.v[1].c,
-                    //     poly.v[2].x, poly.v[2].y, poly.v[2].c,
-                    //     color_offset, vert_offset,
-                    //     texc_offset, texp_offset
-                    // );
-                    // log_set_quiet(1);
                     gpu_render_triangle(gpu, poly.v[0], poly.v[1], poly.v[2], poly);
                 }
 
@@ -883,10 +868,34 @@
     }
 }
 
-void gpu_cmd_a0(psx_gpu_t* gpu) {
+void gpu_copy(psx_gpu_t* gpu) {
     switch (gpu->state) {
         case GPU_STATE_RECV_CMD: {
             gpu->state = GPU_STATE_RECV_ARGS;
+            gpu->cmd_args_remaining = 3;
+        } break;
+
+        case GPU_STATE_RECV_ARGS: {
+            if (!gpu->cmd_args_remaining) {
+                uint32_t srcx = gpu->buf[1] & 0xffff;
+                uint32_t srcy = gpu->buf[1] >> 16;
+                uint32_t dstx = gpu->buf[2] & 0xffff;
+                uint32_t dsty = gpu->buf[2] >> 16;
+                uint32_t xsiz = gpu->buf[3] & 0xffff;
+                uint32_t ysiz = gpu->buf[3] >> 16;
+
+                for (int y = 0; y < ysiz; y++)
+                    for (int x = 0; x < xsiz; x++)
+                        VRAM(dstx + x, dsty + y) = VRAM(srcx + x, srcy + y);
+            }
+        } break;
+    }
+}
+
+void gpu_recv(psx_gpu_t* gpu) {
+    switch (gpu->state) {
+        case GPU_STATE_RECV_CMD: {
+            gpu->state = GPU_STATE_RECV_ARGS;
             gpu->cmd_args_remaining = 2;
         } break;
 
@@ -914,7 +923,7 @@
 
             // To-do: This is segfaulting for some reason
             //        Fix GPU edge cases in general
-            gpu->vram[xpos + (ypos * 1024)] = gpu->recv_data & 0xffff;
+            VRAM(xpos, ypos) = gpu->recv_data & 0xffff;
 
             ++gpu->xcnt;
 
@@ -929,7 +938,7 @@
                 xpos = (gpu->xpos + gpu->xcnt) & 0x3ff;
             }
 
-            gpu->vram[xpos + (ypos * 1024)] = gpu->recv_data >> 16;
+            VRAM(xpos, ypos) = gpu->recv_data & 0xffff;
 
             ++gpu->xcnt;
             
@@ -952,6 +961,34 @@
     }
 }
 
+void gpu_send(psx_gpu_t* gpu) {
+    switch (gpu->state) {
+        case GPU_STATE_RECV_CMD: {
+            gpu->state = GPU_STATE_RECV_ARGS;
+            gpu->cmd_args_remaining = 2;
+        } break;
+
+        case GPU_STATE_RECV_ARGS: {
+            if (!gpu->cmd_args_remaining) {
+                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;
+            }
+        } break;
+    }
+}
+
 // Monochrome Opaque Quadrilateral
 void gpu_cmd_28(psx_gpu_t* gpu) {
     switch (gpu->state) {
@@ -1401,34 +1438,6 @@
     }
 }
 
-void gpu_cmd_c0(psx_gpu_t* gpu) {
-    switch (gpu->state) {
-        case GPU_STATE_RECV_CMD: {
-            gpu->state = GPU_STATE_RECV_ARGS;
-            gpu->cmd_args_remaining = 2;
-        } break;
-
-        case GPU_STATE_RECV_ARGS: {
-            if (!gpu->cmd_args_remaining) {
-                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;
-            }
-        } break;
-    }
-}
-
 void gpu_cmd_02(psx_gpu_t* gpu) {
     switch (gpu->state) {
         case GPU_STATE_RECV_CMD: {
@@ -1455,7 +1464,8 @@
 
                 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++) {
-                        gpu->vram[x + (y * 1024)] = color;
+                        if ((x >= gpu->draw_x1) && (x <= gpu->draw_x2) && (y >= gpu->draw_y1) && (y <= gpu->draw_y2))
+                            VRAM(x, y) = color;
                     }
                 }
 
@@ -1485,7 +1495,8 @@
 
                 for (int y = 0; y < ysiz; y++) {
                     for (int x = 0; x < xsiz; x++) {
-                        gpu->vram[(dstx + x) + (dsty + y) * 1024] = gpu->vram[(srcx + x) + (srcy + y) * 1024];
+                        if ((x >= gpu->draw_x1) && (x <= gpu->draw_x2) && (y >= gpu->draw_y1) && (y <= gpu->draw_y2))
+                            gpu->vram[(dstx + x) + (dsty + y) * 1024] = gpu->vram[(srcx + x) + (srcy + y) * 1024];
                     }
                 }
 
@@ -1510,42 +1521,51 @@
         return;
     }
 
+    switch (type) {
+        case 1: gpu_poly(gpu); break;
+        case 3: gpu_rect(gpu); break;
+        case 4: gpu_copy(gpu); break;
+        case 5: gpu_recv(gpu); break;
+        case 6: gpu_send(gpu); break;
+        default: break;
+    }
+
     switch (gpu->buf[0] >> 24) {
         case 0x00: /* nop */ break;
         case 0x01: /* Cache clear */ break;
         case 0x02: gpu_cmd_02(gpu); break;
-        case 0x24: gpu_cmd_24(gpu); break;
-        case 0x25: gpu_cmd_24(gpu); break;
-        case 0x26: gpu_cmd_24(gpu); break;
-        case 0x27: gpu_cmd_24(gpu); break;
-        case 0x28: gpu_cmd_28(gpu); break;
-        case 0x2a: gpu_cmd_28(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 0x3c: gpu_cmd_3c(gpu); break;
-        case 0x3e: gpu_cmd_3c(gpu); break;
-        case 0x40: gpu_cmd_40(gpu); break;
-        case 0x60: gpu_cmd_60(gpu); break;
-        case 0x62: gpu_cmd_60(gpu); break;
-        case 0x64: gpu_cmd_64(gpu); break;
-        case 0x65: gpu_cmd_64(gpu); break;
-        case 0x66: gpu_cmd_64(gpu); break;
-        case 0x67: gpu_cmd_64(gpu); break;
-        case 0x68: gpu_cmd_68(gpu); break;
-        case 0x74: gpu_cmd_74(gpu); break;
-        case 0x75: gpu_cmd_74(gpu); break;
-        case 0x76: gpu_cmd_74(gpu); break;
-        case 0x77: gpu_cmd_74(gpu); break;
-        case 0x7c: gpu_cmd_7c(gpu); break;
-        case 0x7d: gpu_cmd_7c(gpu); break;
-        case 0x7e: gpu_cmd_7c(gpu); break;
-        case 0x7f: gpu_cmd_7c(gpu); break;
-        case 0x80: gpu_cmd_80(gpu); break;
+        // case 0x24: gpu_cmd_24(gpu); break;
+        // case 0x25: gpu_cmd_24(gpu); break;
+        // case 0x26: gpu_cmd_24(gpu); break;
+        // case 0x27: gpu_cmd_24(gpu); break;
+        // case 0x28: gpu_cmd_28(gpu); break;
+        // case 0x2a: gpu_cmd_28(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 0x3c: gpu_cmd_3c(gpu); break;
+        // case 0x3e: gpu_cmd_3c(gpu); break;
+        // case 0x40: gpu_cmd_40(gpu); break;
+        // case 0x60: gpu_cmd_60(gpu); break;
+        // case 0x62: gpu_cmd_60(gpu); break;
+        // case 0x64: gpu_cmd_64(gpu); break;
+        // case 0x65: gpu_cmd_64(gpu); break;
+        // case 0x66: gpu_cmd_64(gpu); break;
+        // case 0x67: gpu_cmd_64(gpu); break;
+        // case 0x68: gpu_cmd_68(gpu); break;
+        // case 0x74: gpu_cmd_74(gpu); break;
+        // case 0x75: gpu_cmd_74(gpu); break;
+        // case 0x76: gpu_cmd_74(gpu); break;
+        // case 0x77: gpu_cmd_74(gpu); break;
+        // case 0x7c: gpu_cmd_7c(gpu); break;
+        // case 0x7d: gpu_cmd_7c(gpu); break;
+        // case 0x7e: gpu_cmd_7c(gpu); break;
+        // case 0x7f: gpu_cmd_7c(gpu); break;
+        // case 0x80: gpu_cmd_80(gpu); break;
         case 0xa0: gpu_cmd_a0(gpu); break;
         case 0xc0: gpu_cmd_c0(gpu); break;
         case 0xe1: {
--- a/psx/dev/pad.c
+++ b/psx/dev/pad.c
@@ -70,9 +70,9 @@
 }
 
 uint32_t pad_handle_stat_read(psx_pad_t* pad) {
-    log_set_quiet(0);
-    log_fatal("pad stat read");
-    log_set_quiet(1);
+    // log_set_quiet(0);
+    // log_fatal("pad stat read");
+    // log_set_quiet(1);
     return 0x07;
     psx_input_t* joy = pad->joy_slot[(pad->ctrl >> 13) & 1];
 
--