ref: 41fb845c7cc25d7508851aeced8114fd8c0f4c8d
parent: 59dc0947be593d508695aa81c11b5ce477c27129
author: allkern <lisandroaalarcon@gmail.com>
date: Wed May 8 20:43:29 EDT 2024
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
--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -304,6 +304,7 @@
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 @@
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 @@
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 @@
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_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_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;
--- a/psx/dev/dma.c
+++ b/psx/dev/dma.c
@@ -239,7 +239,9 @@
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;
--- a/psx/dev/mcd.c
+++ b/psx/dev/mcd.c
@@ -12,6 +12,7 @@
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 @@
}
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 @@
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 @@
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 @@
// log_fatal("mcd read %02x", 'G');
// log_set_quiet(1);
+ // printf("mcd read %02x\n", 'G');
+
return 'G';
} break;
@@ -110,6 +115,8 @@
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 @@
// log_fatal("mcd read %02x", 'G');
// log_set_quiet(1);
+ // printf("mcd read %02x\n", 'G');
+
return 'G';
} break;
}
@@ -138,15 +147,17 @@
// 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;
--- a/psx/dev/pad.c
+++ b/psx/dev/pad.c
@@ -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 @@
} break;
case DEST_MCD: {
- pad->dest[slot] = 0;
-
- return 0xff;
-
if (!mcd) {
pad->dest[slot] = 0;
@@ -58,7 +56,6 @@
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 @@
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 @@
} break;
case DEST_MCD: {
- pad->dest[slot] = 0;
-
- return;
-
if (!mcd) {
pad->dest[slot] = 0;
@@ -114,34 +105,34 @@
} 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;
+ }
}
psx_pad_t* psx_pad_create() {
@@ -155,31 +146,40 @@
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;
@@ -186,17 +186,25 @@
}
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_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_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);
@@ -294,6 +314,11 @@
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;
}
--- a/psx/dev/pad.h
+++ b/psx/dev/pad.h
@@ -115,6 +115,7 @@
int cycles_until_irq;
int cycle_counter;
int dest[2];
+ int irq_bit;
uint16_t mode, ctrl, baud, stat;
} psx_pad_t;
--- a/psx/input/sda.c
+++ b/psx/input/sda.c
@@ -23,7 +23,7 @@
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 @@
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 @@
sda->state = SDA_STATE_TX_HIZ;
}
}
-
- return;
}
void psxi_sda_on_button_press(void* udata, uint32_t data) {
--
⑨