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*);
--
⑨