ref: 92c0706c0003ee1684ed83472e2ef1377fe6ea4c
parent: c84d48a6abd8f595a1d3b9780bd73c5983502c02
author: allkern <lisandroaalarcon@gmail.com>
date: Sun Jul 2 13:40:51 EDT 2023
Implement very basic input support
--- a/frontend/screen.c
+++ b/frontend/screen.c
@@ -1,5 +1,20 @@
#include "screen.h"
+uint16_t screen_get_button(SDL_Keycode k) {+ if (k == SDLK_x ) return PSXI_SW_SDA_CROSS;
+ if (k == SDLK_a ) return PSXI_SW_SDA_SQUARE;
+ if (k == SDLK_w ) return PSXI_SW_SDA_TRIANGLE;
+ if (k == SDLK_d ) return PSXI_SW_SDA_CIRCLE;
+ if (k == SDLK_RETURN) return PSXI_SW_SDA_START;
+ if (k == SDLK_q ) return PSXI_SW_SDA_SELECT;
+ if (k == SDLK_UP ) return PSXI_SW_SDA_PAD_UP;
+ if (k == SDLK_DOWN ) return PSXI_SW_SDA_PAD_DOWN;
+ if (k == SDLK_LEFT ) return PSXI_SW_SDA_PAD_LEFT;
+ if (k == SDLK_RIGHT ) return PSXI_SW_SDA_PAD_RIGHT;
+
+ return 0;
+}
+
psxe_screen_t* psxe_screen_create() {return (psxe_screen_t*)malloc(sizeof(psxe_screen_t));
}
@@ -19,6 +34,7 @@
screen->open = 1;
screen->format = SDL_PIXELFORMAT_BGR555;
screen->psx = psx;
+ screen->pad = psx_get_pad(psx);
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
@@ -97,8 +113,20 @@
switch (event.key.keysym.sym) { case SDLK_F1: {psxe_screen_toggle_debug_mode(screen);
+
+ return;
} break;
}
+
+ uint16_t mask = screen_get_button(event.key.keysym.sym);
+
+ psx_pad_button_press(screen->pad, mask);
+ } break;
+
+ case SDL_KEYUP: {+ uint16_t mask = screen_get_button(event.key.keysym.sym);
+
+ psx_pad_button_release(screen->pad, mask);
} break;
}
}
--- a/frontend/screen.h
+++ b/frontend/screen.h
@@ -14,6 +14,7 @@
SDL_Texture* texture;
psx_t* psx;
+ psx_pad_t* pad;
unsigned int saved_scale;
unsigned int width, height, scale;
--- a/psx/dev/ic.c
+++ b/psx/dev/ic.c
@@ -53,7 +53,7 @@
void psx_ic_write32(psx_ic_t* ic, uint32_t offset, uint32_t value) { switch (offset) {case 0x00: ic->stat &= value; break;
- case 0x04: ic->mask = value; break;
+ case 0x04: log_fatal("32 IMASK write %08x", value); ic->mask = value; break; default: { log_warn("Unhandled 32-bit IC write at offset %08x (%08x)", offset, value);@@ -69,7 +69,7 @@
void psx_ic_write16(psx_ic_t* ic, uint32_t offset, uint16_t value) { switch (offset) {case 0x00: ic->stat &= value; break;
- case 0x04: ic->mask = value; break;
+ case 0x04: log_fatal("16 IMASK write %04x", value); ic->mask = value; break; default: { log_warn("Unhandled 16-bit IC write at offset %08x (%08x)", offset, value);--- a/psx/dev/pad.c
+++ b/psx/dev/pad.c
@@ -9,23 +9,32 @@
return (psx_pad_t*)malloc(sizeof(psx_pad_t));
}
-void psx_pad_init(psx_pad_t* pad) {+void psx_pad_init(psx_pad_t* pad, psx_ic_t* ic) {memset(pad, 0, sizeof(psx_pad_t));
+ pad->ic = ic;
+
pad->io_base = PSX_PAD_BEGIN;
pad->io_size = PSX_PAD_SIZE;
+
+ pad->rx_buf[0] = 0xff;
+ pad->rx_buf[1] = 0xff;
+ pad->rx_buf[2] = 0x41;
+ pad->rx_buf[3] = 0x5a;
+ pad->rx_buf[4] = 0xff;
+ pad->rx_buf[5] = 0xff;
}
uint32_t psx_pad_read32(psx_pad_t* pad, uint32_t offset) {- switch (offset) {- case 0: return 0x00;
- case 4: return 0x03;
- case 8: return pad->mode;
- case 10: return pad->ctrl;
- case 14: return pad->baud;
- }
+ // switch (offset) {+ // case 0: return 0x00;
+ // case 4: return 0x01;
+ // case 8: return pad->mode;
+ // case 10: return pad->ctrl;
+ // case 14: return pad->baud;
+ // }
- log_warn("Unhandled 32-bit PAD read at offset %08x", offset);+ log_fatal("Unhandled 32-bit PAD read at offset %08x", offset);return 0x0;
}
@@ -32,14 +41,14 @@
uint16_t psx_pad_read16(psx_pad_t* pad, uint32_t offset) { switch (offset) {- case 0: return 0x00;
- case 4: return 0x03;
- case 8: return pad->mode;
+ // case 0: return 0x00;
+ // case 4: return 0x03;
+ // case 8: return pad->mode;
case 10: return pad->ctrl;
- case 14: return pad->baud;
+ // case 14: return pad->baud;
}
- log_warn("Unhandled 16-bit PAD read at offset %08x", offset);+ log_fatal("Unhandled 16-bit PAD read at offset %08x", offset);return 0x0;
}
@@ -46,7 +55,7 @@
uint8_t psx_pad_read8(psx_pad_t* pad, uint32_t offset) { switch (offset) {- case 0: return 0x00;
+ case 0: return pad->rx_buf[(pad->rx_index++) % 6];
case 4: return 0x03;
case 8: return pad->mode;
case 10: return pad->ctrl;
@@ -53,38 +62,38 @@
case 14: return pad->baud;
}
- log_warn("Unhandled 8-bit PAD read at offset %08x", offset);+ log_fatal("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) {- switch (offset) {- case 0: break;
- case 4: break;
- case 8: pad->mode = value & 0xffff; return;
- case 10: pad->ctrl = value & 0xffff; return;
- case 14: pad->baud = value & 0xffff; return;
- }
+ // switch (offset) {+ // case 0: log_fatal("PAD write %08x", value); break;+ // case 4: break;
+ // case 8: pad->mode = value & 0xffff; return;
+ // case 10: pad->ctrl = value & 0xffff; return;
+ // case 14: pad->baud = value & 0xffff; return;
+ // }
- log_warn("Unhandled 32-bit PAD write at offset %08x (%08x)", offset, value);+ log_fatal("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) { switch (offset) {- case 0: break;
- case 4: break;
- case 8: pad->mode = value; return;
+ // case 0: break;
+ // case 4: break;
+ // case 8: pad->mode = value; return;
case 10: pad->ctrl = value; return;
- case 14: pad->baud = value; return;
+ // case 14: pad->baud = value; return;
}
- log_warn("Unhandled 16-bit PAD write at offset %08x (%04x)", offset, value);+ log_fatal("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) { switch (offset) {- case 0: break;
+ case 0: return; break;
case 4: break;
case 8: pad->mode = value; return;
case 10: pad->ctrl = value; return;
@@ -91,7 +100,15 @@
case 14: pad->baud = value; return;
}
- log_warn("Unhandled 8-bit PAD write at offset %08x (%02x)", offset, value);+ log_fatal("Unhandled 8-bit PAD write at offset %08x (%02x)", offset, value);+}
+
+void psx_pad_button_press(psx_pad_t* pad, uint16_t data) {+ *((uint16_t*)(&pad->rx_buf[4])) &= ~data;
+}
+
+void psx_pad_button_release(psx_pad_t* pad, uint16_t data) {+ *((uint16_t*)(&pad->rx_buf[4])) |= data;
}
void psx_pad_destroy(psx_pad_t* pad) {--- a/psx/dev/pad.h
+++ b/psx/dev/pad.h
@@ -3,18 +3,65 @@
#include <stdint.h>
+#include "ic.h"
+
#define PSX_PAD_BEGIN 0x1f801040
#define PSX_PAD_SIZE 0x10
#define PSX_PAD_END 0x1f80104f
+// Controller/Input IDs
+#define PSXI_ID_SD 0x5a41
+#define PSXI_ID_SA_PAD 0x5a73
+#define PSXI_ID_SA_STICK 0x5a53
+
+#define PSXI_SW_SDA_SELECT 0x0001
+#define PSXI_SW_SDA_L3 0x0002
+#define PSXI_SW_SDA_R3 0x0004
+#define PSXI_SW_SDA_START 0x0008
+#define PSXI_SW_SDA_PAD_UP 0x0010
+#define PSXI_SW_SDA_PAD_RIGHT 0x0020
+#define PSXI_SW_SDA_PAD_DOWN 0x0040
+#define PSXI_SW_SDA_PAD_LEFT 0x0080
+#define PSXI_SW_SDA_L2 0x0100
+#define PSXI_SW_SDA_R2 0x0200
+#define PSXI_SW_SDA_L1 0x0400
+#define PSXI_SW_SDA_R1 0x0800
+#define PSXI_SW_SDA_TRIANGLE 0x1000
+#define PSXI_SW_SDA_CIRCLE 0x2000
+#define PSXI_SW_SDA_CROSS 0x4000
+#define PSXI_SW_SDA_SQUARE 0x8000
+
+/*
+ To-do: Design API to interface any type of controller.
+
+ Possible names:
+ - psx_im (Input Method)
+ - psx_controller
+ - psx_input
+
+ Private API should contain a way to get the ID of
+ this controller, public API should contain the following
+ functions: (WIP)
+ - _write(data)
+ - _read()
+ _ _on_button_press(id)
+ - _on_button_release(id)
+ - _on_analog_change(id)
+*/
+
typedef struct {uint32_t io_base, io_size;
+ psx_ic_t* ic;
+
+ uint8_t rx_buf[6];
+ int rx_index;
+
uint16_t mode, ctrl, baud;
} psx_pad_t;
psx_pad_t* psx_pad_create();
-void psx_pad_init(psx_pad_t*);
+void psx_pad_init(psx_pad_t*, psx_ic_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);
@@ -22,5 +69,7 @@
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*);
+void psx_pad_button_press(psx_pad_t*, uint16_t);
+void psx_pad_button_release(psx_pad_t*, uint16_t);
#endif
\ No newline at end of file
--- a/psx/psx.c
+++ b/psx/psx.c
@@ -113,7 +113,7 @@
psx_spu_init(psx->spu);
psx_timer_init(psx->timer);
psx_cdrom_init(psx->cdrom, psx->ic);
- psx_pad_init(psx->pad);
+ psx_pad_init(psx->pad, psx->ic);
psx_bios_load(psx->bios, bios_path);
psx_cpu_init(psx->cpu, psx->bus);
}
--
⑨