Input fixes

Fixes Silent Hill, Harvest Moon, Chrono Cross, Capcom vs. SNK, US Racer, Army Men - Air Attack, Alone in the Dark - The New Nightmare, and more
This commit is contained in:
allkern
2024-05-09 00:43:29 -03:00
parent 59dc0947be
commit 41fb845c7c
6 changed files with 132 additions and 96 deletions
+36 -32
View File
@@ -304,6 +304,7 @@ void cdrom_cmd_setloc(psx_cdrom_t* cdrom) {
int m = PFIFO_POP;
if (!(VALID_BCD(m) && VALID_BCD(s) && VALID_BCD(f) && (f < 0x75))) {
printf("setloc: invalid msf\n");
cdrom->irq_delay = DELAY_1MS;
cdrom->delayed_command = CDL_ERROR;
cdrom->state = CD_STATE_ERROR;
@@ -323,11 +324,11 @@ void cdrom_cmd_setloc(psx_cdrom_t* cdrom) {
cdrom->seek_pending = 1;
log_fatal("setloc: %02x:%02x:%02x",
cdrom->seek_msf.m,
cdrom->seek_msf.s,
cdrom->seek_msf.f
);
// printf("setloc: %02x:%02x:%02x\n",
// cdrom->seek_msf.m,
// cdrom->seek_msf.s,
// cdrom->seek_msf.f
// );
cdrom->irq_delay = DELAY_1MS;
cdrom->delayed_command = CDL_SETLOC;
@@ -336,7 +337,7 @@ void cdrom_cmd_setloc(psx_cdrom_t* cdrom) {
case CD_STATE_SEND_RESP1: {
SET_BITS(ifr, IFR_INT, IFR_INT3);
RESP_PUSH(GETSTAT_MOTOR);
RESP_PUSH(GETSTAT_MOTOR | GETSTAT_SEEK);
if (cdrom->ongoing_read_command) {
// printf("command=%02x\n", cdrom->ongoing_read_command);
@@ -881,24 +882,24 @@ void cdrom_cmd_getlocl(psx_cdrom_t* cdrom) {
case CD_STATE_SEND_RESP1: {
SET_BITS(ifr, IFR_INT, IFR_INT3);
RESP_PUSH(cdrom->dfifo[0x13]);
RESP_PUSH(cdrom->dfifo[0x12]);
RESP_PUSH(cdrom->dfifo[0x11]);
RESP_PUSH(cdrom->dfifo[0x10]);
RESP_PUSH(cdrom->dfifo[0x0f]);
RESP_PUSH(cdrom->dfifo[0x0e]);
RESP_PUSH(cdrom->dfifo[0x0d]);
RESP_PUSH(cdrom->dfifo[0x0c]);
RESP_PUSH(cdrom->xa_sector_buf[0x13]);
RESP_PUSH(cdrom->xa_sector_buf[0x12]);
RESP_PUSH(cdrom->xa_sector_buf[0x11]);
RESP_PUSH(cdrom->xa_sector_buf[0x10]);
RESP_PUSH(cdrom->xa_sector_buf[0x0f]);
RESP_PUSH(cdrom->xa_sector_buf[0x0e]);
RESP_PUSH(cdrom->xa_sector_buf[0x0d]);
RESP_PUSH(cdrom->xa_sector_buf[0x0c]);
// if (cdrom->ongoing_read_command) {
// // printf("command=%02x\n", cdrom->ongoing_read_command);
// cdrom->state = CD_STATE_SEND_RESP2;
// cdrom->delayed_command = cdrom->ongoing_read_command;
// cdrom->irq_delay = DELAY_1MS;
// } else {
if (cdrom->ongoing_read_command) {
// printf("command=%02x\n", cdrom->ongoing_read_command);
cdrom->state = CD_STATE_SEND_RESP2;
cdrom->delayed_command = cdrom->ongoing_read_command;
cdrom->irq_delay = DELAY_1MS;
} else {
cdrom->delayed_command = CDL_NONE;
cdrom->state = CD_STATE_RECV_CMD;
// }
}
} break;
}
}
@@ -1564,6 +1565,9 @@ uint8_t cdrom_read_status(psx_cdrom_t* cdrom) {
}
uint8_t cdrom_read_rfifo(psx_cdrom_t* cdrom) {
if (cdrom->rfifo_index < 0)
return 0;
uint8_t data = cdrom->rfifo[--cdrom->rfifo_index];
if (cdrom->rfifo_index == 0)
@@ -1608,17 +1612,17 @@ void cdrom_write_status(psx_cdrom_t* cdrom, uint8_t value) {
}
void cdrom_write_cmd(psx_cdrom_t* cdrom, uint8_t value) {
// printf("%s(%02x) %u params=[%02x, %02x, %02x, %02x, %02x, %02x]\n",
// g_psx_cdrom_command_names[value],
// value,
// cdrom->pfifo_index,
// cdrom->pfifo[0],
// cdrom->pfifo[1],
// cdrom->pfifo[2],
// cdrom->pfifo[3],
// cdrom->pfifo[4],
// cdrom->pfifo[5]
// );
printf("%s(%02x) %u params=[%02x, %02x, %02x, %02x, %02x, %02x]\n",
g_psx_cdrom_command_names[value],
value,
cdrom->pfifo_index,
cdrom->pfifo[0],
cdrom->pfifo[1],
cdrom->pfifo[2],
cdrom->pfifo[3],
cdrom->pfifo[4],
cdrom->pfifo[5]
);
cdrom->command = value;
cdrom->state = CD_STATE_RECV_CMD;
+3 -1
View File
@@ -239,7 +239,9 @@ void psx_dma_do_gpu_linked(psx_dma_t* dma) {
uint32_t size = hdr >> 24;
uint32_t addr = dma->gpu.madr;
while (true) {
int timeout = 16384;
while (timeout--) {
while (size--) {
addr = (addr + (CHCR_STEP(gpu) ? -4 : 4)) & 0x1ffffc;
+15 -4
View File
@@ -12,6 +12,7 @@ void psx_mcd_init(psx_mcd_t* mcd, const char* path) {
mcd->flag = 0x08;
mcd->path = path;
mcd->buf = malloc(MCD_MEMORY_SIZE);
mcd->tx_data_ready = 0;
memset(mcd->buf, 0, MCD_MEMORY_SIZE);
@@ -33,8 +34,6 @@ void psx_mcd_init(psx_mcd_t* mcd, const char* path) {
}
uint8_t psx_mcd_read(psx_mcd_t* mcd) {
return 0xff;
switch (mcd->state) {
case MCD_STATE_TX_HIZ: mcd->tx_data = 0xff; break;
case MCD_STATE_TX_FLG: mcd->tx_data = mcd->flag; mcd->flag = 0x00; break;
@@ -49,6 +48,8 @@ uint8_t psx_mcd_read(psx_mcd_t* mcd) {
case 'S': mcd->state = MCD_S_STATE_TX_ACK1; break;
}
// printf("mcd read %02x\n", mcd->tx_data);
// log_set_quiet(0);
// log_fatal("mcd read %02x", mcd->tx_data);
// log_set_quiet(1);
@@ -77,6 +78,8 @@ uint8_t psx_mcd_read(psx_mcd_t* mcd) {
break;
}
// printf("mcd read %02x\n", data);
// log_set_quiet(0);
// log_fatal("mcd read %02x", data);
// log_set_quiet(1);
@@ -92,6 +95,8 @@ uint8_t psx_mcd_read(psx_mcd_t* mcd) {
// log_fatal("mcd read %02x", 'G');
// log_set_quiet(1);
// printf("mcd read %02x\n", 'G');
return 'G';
} break;
@@ -110,6 +115,8 @@ uint8_t psx_mcd_read(psx_mcd_t* mcd) {
break;
}
// printf("mcd read %02x\n", mcd->rx_data);
// log_set_quiet(0);
// log_fatal("mcd read %02x", mcd->rx_data);
// log_set_quiet(1);
@@ -127,6 +134,8 @@ uint8_t psx_mcd_read(psx_mcd_t* mcd) {
// log_fatal("mcd read %02x", 'G');
// log_set_quiet(1);
// printf("mcd read %02x\n", 'G');
return 'G';
} break;
}
@@ -138,16 +147,18 @@ uint8_t psx_mcd_read(psx_mcd_t* mcd) {
// log_fatal("mcd read %02x", mcd->tx_data);
// log_set_quiet(1);
// printf("mcd read %02x\n", mcd->tx_data);
return mcd->tx_data;
}
void psx_mcd_write(psx_mcd_t* mcd, uint8_t data) {
return;
// log_set_quiet(0);
// log_fatal("mcd write %02x", data);
// log_set_quiet(1);
// printf("mcd write %02x\n", data);
switch (mcd->state) {
case MCD_STATE_TX_FLG: mcd->mode = data; break;
case MCD_R_STATE_RX_MSB: mcd->msb = data; break;
+76 -51
View File
@@ -5,6 +5,8 @@
#include "pad.h"
#include "../log.h"
#define JOY_IRQ_DELAY 512
uint32_t pad_read_rx(psx_pad_t* pad) {
int slot = (pad->ctrl >> 13) & 1;
@@ -34,10 +36,6 @@ uint32_t pad_read_rx(psx_pad_t* pad) {
} break;
case DEST_MCD: {
pad->dest[slot] = 0;
return 0xff;
if (!mcd) {
pad->dest[slot] = 0;
@@ -58,7 +56,6 @@ uint32_t pad_read_rx(psx_pad_t* pad) {
void pad_write_tx(psx_pad_t* pad, uint16_t data) {
int slot = (pad->ctrl >> 13) & 1;
// printf("slot=%u dest=%02x write tx data=%02x ", slot, pad->dest[slot], data);
psx_input_t* joy = pad->joy_slot[slot];
psx_mcd_t* mcd = pad->mcd_slot[slot];
@@ -66,20 +63,18 @@ void pad_write_tx(psx_pad_t* pad, uint16_t data) {
if (!(pad->ctrl & CTRL_TXEN))
return;
// if (slot == 0)
// printf("slot %u (%02x) write %08x\n", slot, pad->dest[slot], data);
if (!pad->dest[slot]) {
if ((data == DEST_JOY) || (data == DEST_MCD)) {
pad->dest[slot] = data;
// printf(" slot=%u dest=%02x\n", slot, data);
if ((data == DEST_JOY) && !joy)
return;
// if (slot == 0)
// printf("dest=%02x\n", data);
if ((data == DEST_MCD) && !mcd)
return;
if (pad->ctrl & CTRL_ACIE)
pad->cycles_until_irq = 1500;
pad->cycles_until_irq = JOY_IRQ_DELAY;
}
} else {
switch (pad->dest[slot]) {
@@ -97,10 +92,6 @@ void pad_write_tx(psx_pad_t* pad, uint16_t data) {
} break;
case DEST_MCD: {
pad->dest[slot] = 0;
return;
if (!mcd) {
pad->dest[slot] = 0;
@@ -114,33 +105,33 @@ void pad_write_tx(psx_pad_t* pad, uint16_t data) {
} break;
}
if (pad->ctrl & CTRL_ACIE)
pad->cycles_until_irq = 1500;
if (pad->ctrl & CTRL_ACIE) {
pad->irq_bit = 1;
pad->cycles_until_irq = JOY_IRQ_DELAY;
}
}
}
uint32_t pad_handle_stat_read(psx_pad_t* pad) {
// // log_set_quiet(0);
// printf("pad stat read\n");
// // log_set_quiet(1);
// return 0x07;
psx_input_t* joy = pad->joy_slot[(pad->ctrl >> 13) & 1];
if (!joy)
return 0xff;
return 0x7;
return pad->stat | 7;
}
void pad_handle_ctrl_write(psx_pad_t* pad, uint32_t value) {
int slot = pad->ctrl & CTRL_SLOT;
pad->ctrl = value;
if (!(pad->ctrl & CTRL_JOUT)) {
// pad->dest[0] = 0;
// pad->dest[1] = 0;
pad->ctrl &= ~CTRL_SLOT;
psx_mcd_reset(pad->mcd_slot[(pad->ctrl >> 13) & 1]);
if (pad->mcd_slot[slot >> 13])
psx_mcd_reset(pad->mcd_slot[slot >> 13]);
}
// Reset STAT bits 3, 4, 5, 9
if (pad->ctrl & CTRL_ACKN) {
pad->stat &= 0xfdc7;
pad->ctrl &= ~CTRL_ACKN;
}
}
@@ -155,48 +146,65 @@ void psx_pad_init(psx_pad_t* pad, psx_ic_t* ic) {
pad->io_base = PSX_PAD_BEGIN;
pad->io_size = PSX_PAD_SIZE;
pad->joy_slot[0] = NULL;
pad->joy_slot[1] = NULL;
pad->mcd_slot[0] = NULL;
pad->mcd_slot[1] = NULL;
}
uint32_t psx_pad_read32(psx_pad_t* pad, uint32_t offset) {
uint32_t v = 0;
switch (offset) {
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;
case 0: v = pad_read_rx(pad); break;
case 4: v = pad_handle_stat_read(pad); break;
case 8: v = pad->mode; break;
case 10: v = pad->ctrl; break;
case 14: v = pad->baud; break;
}
printf("Unhandled 32-bit PAD read at offset %08x", offset);
return 0x0;
return v;
}
uint16_t psx_pad_read16(psx_pad_t* pad, uint32_t offset) {
uint32_t v = 0;
switch (offset) {
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;
case 0: v = pad_read_rx(pad) & 0xffff; break;
case 4: v = pad_handle_stat_read(pad) & 0xffff; break;
case 8: v = pad->mode; break;
case 10: v = pad->ctrl & 0xffff; break;
case 14: v = pad->baud; break;
}
return v;
printf("Unhandled 16-bit PAD read at offset %08x", offset);
return 0x0;
}
uint8_t psx_pad_read8(psx_pad_t* pad, uint32_t offset) {
uint32_t v = 0;
switch (offset) {
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;
case 0: v = pad_read_rx(pad) & 0xff; break;
case 4: v = pad_handle_stat_read(pad) & 0xff; break;
case 8: v = pad->mode; break;
case 10: v = pad->ctrl & 0xff; break;
case 14: v = pad->baud; break;
}
printf("Unhandled 8-bit PAD read at offset %08x", offset);
// if (offset <= 0xa)
// printf("slot=%d dest=%02x pad_read8(%02x) -> %02x\n",
// (pad->ctrl & CTRL_SLOT) >> 13,
// pad->dest[(pad->ctrl & CTRL_SLOT) >> 13],
// offset,
// v
// );
return 0x0;
return v;
}
void psx_pad_write32(psx_pad_t* pad, uint32_t offset, uint32_t value) {
@@ -222,6 +230,14 @@ void psx_pad_write16(psx_pad_t* pad, uint32_t offset, uint16_t value) {
}
void psx_pad_write8(psx_pad_t* pad, uint32_t offset, uint8_t value) {
// if (offset <= 0xa)
// printf("slot=%d dest=%02x pad_write8(%02x) -> %02x\n",
// (pad->ctrl & CTRL_SLOT) >> 13,
// pad->dest[(pad->ctrl & CTRL_SLOT) >> 13],
// offset,
// value
// );
switch (offset) {
case 0: pad_write_tx(pad, value); return;
case 8: pad->mode = value; return;
@@ -270,6 +286,10 @@ void psx_pad_detach_joy(psx_pad_t* pad, int slot) {
}
void psx_pad_attach_mcd(psx_pad_t* pad, int slot, const char* path) {
printf("Memory Card support is disabled\n");
return;
if (pad->mcd_slot[slot])
psx_pad_detach_mcd(pad, slot);
@@ -295,6 +315,11 @@ void psx_pad_update(psx_pad_t* pad, int cyc) {
if (pad->cycles_until_irq <= 0) {
psx_ic_irq(pad->ic, IC_JOY);
if (pad->irq_bit) {
pad->stat |= STAT_IRQ7;
pad->irq_bit = 0;
}
pad->cycles_until_irq = 0;
}
}
+1
View File
@@ -115,6 +115,7 @@ typedef struct {
int cycles_until_irq;
int cycle_counter;
int dest[2];
int irq_bit;
uint16_t mode, ctrl, baud, stat;
} psx_pad_t;
+1 -8
View File
@@ -23,7 +23,7 @@ void psxi_sda_init(psxi_sda_t* sda, uint16_t model) {
sda->model = model;
sda->state = SDA_STATE_TX_HIZ;
sda->sw = 0xffff;
sda->sa_mode = 0;
sda->sa_mode = SA_MODE_DIGITAL;
sda->adc0 = 0x80;
sda->adc1 = 0x80;
sda->adc2 = 0x80;
@@ -81,11 +81,6 @@ void psxi_sda_write(void* udata, uint16_t data) {
psxi_sda_t* sda = (psxi_sda_t*)udata;
// To-do: Handle TAP and MOT bytes here
if (data == 0x01) {
sda->tx_data = 0xff;
sda->tx_data_ready = 1;
sda->state = SDA_STATE_TX_HIZ;
}
if (data == 0x43) {
if (sda->sa_mode == SA_MODE_ANALOG) {
@@ -97,8 +92,6 @@ void psxi_sda_write(void* udata, uint16_t data) {
sda->state = SDA_STATE_TX_HIZ;
}
}
return;
}
void psxi_sda_on_button_press(void* udata, uint32_t data) {