shithub: psxe

Download patch

ref: 4e7015318dc5c1bbf097783eeba60d0c574bd2fb
parent: f1e75b3463c803c1b8f01a188c0f8a62dc794a34
author: Lycoder <aurealinbox@gmail.com>
date: Thu Jun 15 06:46:02 EDT 2023

Implement PAD stub

--- a/frontend/main.c
+++ b/frontend/main.c
@@ -29,7 +29,7 @@
     signal(SIGINT, sigint_handler);
 
     psx_t* psx = psx_create();
-    psx_init(psx, "SCPH1001.bin");
+    psx_init(psx, "SCPH1001.BIN");
 
     psx_gpu_t* gpu = psx_get_gpu(psx);
 
--- a/psx/bus.c
+++ b/psx/bus.c
@@ -57,6 +57,7 @@
     HANDLE_READ(spu, 32);
     HANDLE_READ(timer, 32);
     HANDLE_READ(cdrom, 32);
+    HANDLE_READ(pad, 32);
 
     log_warn("Unhandled 32-bit read from %08x:%08x", vaddr, addr);
 
@@ -87,6 +88,7 @@
     HANDLE_READ(spu, 16);
     HANDLE_READ(timer, 16);
     HANDLE_READ(cdrom, 16);
+    HANDLE_READ(pad, 16);
 
     log_warn("Unhandled 16-bit read from %08x:%08x", vaddr, addr);
 
@@ -113,6 +115,7 @@
     HANDLE_READ(spu, 8);
     HANDLE_READ(timer, 8);
     HANDLE_READ(cdrom, 8);
+    HANDLE_READ(pad, 8);
 
     log_warn("Unhandled 8-bit read from %08x:%08x", vaddr, addr);
 
@@ -143,6 +146,7 @@
     HANDLE_WRITE(spu, 32);
     HANDLE_WRITE(timer, 32);
     HANDLE_WRITE(cdrom, 32);
+    HANDLE_WRITE(pad, 32);
 
     log_warn("Unhandled 32-bit write to %08x:%08x (%08x)", vaddr, addr, value);
 }
@@ -171,6 +175,7 @@
     HANDLE_WRITE(spu, 16);
     HANDLE_WRITE(timer, 16);
     HANDLE_WRITE(cdrom, 16);
+    HANDLE_WRITE(pad, 16);
 
     log_warn("Unhandled 16-bit write to %08x:%08x (%04x)", vaddr, addr, value);
 }
@@ -195,6 +200,7 @@
     HANDLE_WRITE(spu, 8);
     HANDLE_WRITE(timer, 8);
     HANDLE_WRITE(cdrom, 8);
+    HANDLE_WRITE(pad, 8);
 
     log_warn("Unhandled 8-bit write to %08x:%08x (%02x)", vaddr, addr, value);
 }
@@ -249,6 +255,10 @@
 
 void psx_bus_init_cdrom(psx_bus_t* bus, psx_cdrom_t* cdrom) {
     bus->cdrom = cdrom;
+}
+
+void psx_bus_init_pad(psx_bus_t* bus, psx_pad_t* pad) {
+    bus->pad = pad;
 }
 
 uint32_t psx_bus_get_access_cycles(psx_bus_t* bus) {
--- a/psx/bus_init.h
+++ b/psx/bus_init.h
@@ -14,6 +14,7 @@
 #include "dev/spu.h"
 #include "dev/timer.h"
 #include "dev/cdrom.h"
+#include "dev/pad.h"
 
 struct psx_bus_t {
     psx_bios_t* bios;
@@ -29,6 +30,7 @@
     psx_spu_t* spu;
     psx_timer_t* timer;
     psx_cdrom_t* cdrom;
+    psx_pad_t* pad;
 
     uint32_t access_cycles;
 };
@@ -46,5 +48,6 @@
 void psx_bus_init_spu(psx_bus_t*, psx_spu_t*);
 void psx_bus_init_timer(psx_bus_t*, psx_timer_t*);
 void psx_bus_init_cdrom(psx_bus_t*, psx_cdrom_t*);
+void psx_bus_init_pad(psx_bus_t*, psx_pad_t*);
 
 #endif
\ No newline at end of file
--- a/psx/dev/gpu.c
+++ b/psx/dev/gpu.c
@@ -114,6 +114,36 @@
     }
 }
 
+void gpu_render_textured_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint32_t h, uint32_t tpx, uint32_t tpy) {
+    vertex_t a = v;
+
+    a.x += gpu->off_x;
+    a.y += gpu->off_y;
+
+    int xmin = max(a.x, gpu->draw_x1);
+    int ymin = max(a.y, gpu->draw_y1);
+    int xmax = min(xmin + w, gpu->draw_x2);
+    int ymax = min(ymin + h, gpu->draw_y2);
+
+    uint32_t xc = 0, yc = 0;
+
+    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);
+
+            ++xc;
+
+            if (!color) continue;
+
+            gpu->vram[x + (y * 1024)] = color;
+        }
+
+        xc = 0;
+
+        ++yc;
+    }
+}
+
 void gpu_render_flat_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vertex_t v2, uint32_t color) {
     vertex_t a, b, c;
 
@@ -498,6 +528,49 @@
     }
 }
 
+void gpu_cmd_64(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) {
+                gpu->state = GPU_STATE_RECV_DATA;
+
+                gpu->color = gpu->buf[0] & 0xffffff;
+                gpu->v0.x  = gpu->buf[1] & 0xffff;
+                gpu->v0.y  = gpu->buf[1] >> 16;
+                gpu->v0.tx = gpu->buf[2] & 0xff;
+                gpu->v0.ty = (gpu->buf[2] >> 8) & 0xff;
+                gpu->pal   = gpu->buf[2] >> 16;
+
+                uint32_t w = gpu->buf[3] & 0xffff;
+                uint32_t h = gpu->buf[3] >> 16;
+
+                gpu->clut_x = (gpu->pal & 0x3f) << 4;
+                gpu->clut_y = (gpu->pal >> 6) & 0x1ff;
+
+                uint32_t tpx = gpu->texp_x;
+                uint32_t tpy = gpu->texp_y;
+
+                log_fatal("v0={%u, %u},{%u, %u},{%u, %u},{%u, %u},%06x",
+                    gpu->v0.x, gpu->v0.y,
+                    gpu->v0.tx, gpu->v0.ty,
+                    tpx, tpy,
+                    w, h,
+                    gpu->color
+                );
+
+                gpu_render_textured_rectangle(gpu, gpu->v0, w, h, tpx, tpy);
+
+                gpu->state = GPU_STATE_RECV_CMD;
+            }
+        } break;
+    }
+}
+
 void psx_gpu_update_cmd(psx_gpu_t* gpu) {
     switch (gpu->buf[0] >> 24) {
         case 0x00: /* nop */ break;
@@ -506,6 +579,7 @@
         case 0x2c: gpu_cmd_2c(gpu); break;
         case 0x30: gpu_cmd_30(gpu); break;
         case 0x38: gpu_cmd_38(gpu); break;
+        case 0x64: gpu_cmd_64(gpu); break;
         case 0xa0: gpu_cmd_a0(gpu); break;
         case 0xe1: {
             gpu->gpustat &= 0x7ff;
@@ -535,7 +609,7 @@
         case 0xe6: {
             /* To-do: Implement mask bit thing */
         } break;
-        //default: log_fatal("Unhandled GP0(%02Xh)", gpu->buf[0] >> 24); break;
+        default: log_fatal("Unhandled GP0(%02Xh)", gpu->buf[0] >> 24); break;
     }
 }
 
--- a/psx/dev/mc1.c
+++ b/psx/dev/mc1.c
@@ -181,6 +181,10 @@
     return DEFAULT_DLY;
 }
 
+uint32_t psx_mc1_get_pad_read_delay(psx_mc1_t* mc1) {
+    return DEFAULT_DLY;
+}
+
 uint32_t psx_mc1_get_bios_write_delay(psx_mc1_t* mc1) {
     return DEFAULT_DLY;
 }
@@ -230,6 +234,10 @@
 }
 
 uint32_t psx_mc1_get_cdrom_write_delay(psx_mc1_t* mc1) {
+    return DEFAULT_DLY;
+}
+
+uint32_t psx_mc1_get_pad_write_delay(psx_mc1_t* mc1) {
     return DEFAULT_DLY;
 }
 
--- a/psx/dev/mc1.h
+++ b/psx/dev/mc1.h
@@ -48,6 +48,8 @@
 uint32_t psx_mc1_get_spu_read_delay(psx_mc1_t*);
 uint32_t psx_mc1_get_timer_read_delay(psx_mc1_t*);
 uint32_t psx_mc1_get_cdrom_read_delay(psx_mc1_t*);
+uint32_t psx_mc1_get_pad_read_delay(psx_mc1_t*);
+
 uint32_t psx_mc1_get_bios_write_delay(psx_mc1_t*);
 uint32_t psx_mc1_get_ram_write_delay(psx_mc1_t*);
 uint32_t psx_mc1_get_dma_write_delay(psx_mc1_t*);
@@ -61,5 +63,6 @@
 uint32_t psx_mc1_get_spu_write_delay(psx_mc1_t*);
 uint32_t psx_mc1_get_timer_write_delay(psx_mc1_t*);
 uint32_t psx_mc1_get_cdrom_write_delay(psx_mc1_t*);
+uint32_t psx_mc1_get_pad_write_delay(psx_mc1_t*);
 
 #endif
\ No newline at end of file
--- /dev/null
+++ b/psx/dev/pad.c
@@ -1,0 +1,61 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pad.h"
+#include "../log.h"
+
+psx_pad_t* psx_pad_create() {
+    return (psx_pad_t*)malloc(sizeof(psx_pad_t));
+}
+
+void psx_pad_init(psx_pad_t* pad) {
+    memset(pad, 0, sizeof(psx_pad_t));
+
+    pad->io_base = PSX_PAD_BEGIN;
+    pad->io_size = PSX_PAD_SIZE;
+}
+
+uint32_t psx_pad_read32(psx_pad_t* pad, uint32_t offset) {
+    log_fatal("PAD read32 %u", offset);
+
+    if (offset == 0x4) return 0x00000005;
+
+    log_warn("Unhandled 32-bit PAD read at offset %08x", offset);
+
+    return 0x0;
+}
+
+uint16_t psx_pad_read16(psx_pad_t* pad, uint32_t offset) {
+    log_fatal("PAD read16 %u", offset);
+    if (offset == 0x4) return 0x00000005;
+
+    log_warn("Unhandled 16-bit PAD read at offset %08x", offset);
+
+    return 0x0;
+}
+
+uint8_t psx_pad_read8(psx_pad_t* pad, uint32_t offset) {
+    log_fatal("PAD read8 %u", offset);
+    if (offset == 0x4) return 0x00000005;
+
+    log_warn("Unhandled 8-bit PAD read at offset %08x", offset);
+
+    return 0x0;
+}
+
+void psx_pad_write32(psx_pad_t* pad, uint32_t offset, uint32_t value) {
+    log_warn("Unhandled 32-bit PAD write at offset %08x (%08x)", offset, value);
+}
+
+void psx_pad_write16(psx_pad_t* pad, uint32_t offset, uint16_t value) {
+    log_warn("Unhandled 16-bit PAD write at offset %08x (%04x)", offset, value);
+}
+
+void psx_pad_write8(psx_pad_t* pad, uint32_t offset, uint8_t value) {
+    log_warn("Unhandled 8-bit PAD write at offset %08x (%02x)", offset, value);
+}
+
+void psx_pad_destroy(psx_pad_t* pad) {
+    free(pad);
+}
\ No newline at end of file
--- /dev/null
+++ b/psx/dev/pad.h
@@ -1,0 +1,24 @@
+#ifndef PAD_H
+#define PAD_H
+
+#include <stdint.h>
+
+#define PSX_PAD_BEGIN 0x1f801040
+#define PSX_PAD_SIZE  0x10
+#define PSX_PAD_END   0x1f80104f
+
+typedef struct {
+    uint32_t io_base, io_size;
+} psx_pad_t;
+
+psx_pad_t* psx_pad_create();
+void psx_pad_init(psx_pad_t*);
+uint32_t psx_pad_read32(psx_pad_t*, uint32_t);
+uint16_t psx_pad_read16(psx_pad_t*, uint32_t);
+uint8_t psx_pad_read8(psx_pad_t*, uint32_t);
+void psx_pad_write32(psx_pad_t*, uint32_t, uint32_t);
+void psx_pad_write16(psx_pad_t*, uint32_t, uint16_t);
+void psx_pad_write8(psx_pad_t*, uint32_t, uint8_t);
+void psx_pad_destroy(psx_pad_t*);
+
+#endif
\ No newline at end of file
--- a/psx/psx.c
+++ b/psx/psx.c
@@ -59,6 +59,7 @@
     psx->cpu = psx_cpu_create();
     psx->timer = psx_timer_create();
     psx->cdrom = psx_cdrom_create();
+    psx->pad = psx_pad_create();
 
     psx_bus_init(psx->bus);
 
@@ -75,6 +76,7 @@
     psx_bus_init_spu(psx->bus, psx->spu);
     psx_bus_init_timer(psx->bus, psx->timer);
     psx_bus_init_cdrom(psx->bus, psx->cdrom);
+    psx_bus_init_pad(psx->bus, psx->pad);
 
     // Init devices
     psx_bios_init(psx->bios);
@@ -91,6 +93,7 @@
     psx_cpu_init(psx->cpu, psx->bus);
     psx_timer_init(psx->timer);
     psx_cdrom_init(psx->cdrom, psx->ic);
+    psx_pad_init(psx->pad);
 
     psx_bios_load(psx->bios, bios_path);
 
@@ -130,6 +133,7 @@
     psx_spu_destroy(psx->spu);
     psx_timer_destroy(psx->timer);
     psx_cdrom_destroy(psx->cdrom);
+    psx_pad_destroy(psx->pad);
 
     free(psx);
 }
@@ -188,6 +192,10 @@
 
 psx_cdrom_t* psx_get_cdrom(psx_t* psx) {
     return psx->cdrom;
+}
+
+psx_pad_t* psx_get_pad(psx_t* psx) {
+    return psx->pad;
 }
 
 psx_cpu_t* psx_get_cpu(psx_t* psx) {
--- a/psx/psx.h
+++ b/psx/psx.h
@@ -23,6 +23,7 @@
     psx_cpu_t* cpu;
     psx_timer_t* timer;
     psx_cdrom_t* cdrom;
+    psx_pad_t* pad;
 } psx_t;
 
 psx_t* psx_create();
@@ -50,6 +51,7 @@
 psx_bus_t* psx_get_bus(psx_t*);
 psx_timer_t* psx_get_timer(psx_t*);
 psx_cdrom_t* psx_get_cdrom(psx_t*);
+psx_pad_t* psx_get_pad(psx_t*);
 psx_cpu_t* psx_get_cpu(psx_t*);
 void psx_destroy(psx_t*);
 
--