From 2989bb6ea366123012f68b7d0ba4fed482999d46 Mon Sep 17 00:00:00 2001 From: allkern Date: Mon, 22 Jul 2024 23:41:29 -0300 Subject: [PATCH] Implement IER IRQ blocking Fixes a lot of games (Strider 2, Crash Bash, Tokimeki Memorial 2, Rockman games, and many more) --- frontend/main.c | 3 ++ psx/dev/cdrom/cdrom.c | 79 +++++++++++++++++++++---------------------- psx/dev/cdrom/impl.c | 12 +++---- 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/frontend/main.c b/frontend/main.c index 97ffce2..4c2de72 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -42,6 +42,9 @@ int main(int argc, const char* argv[]) { psx_cdrom_t* cdrom = psx_get_cdrom(psx); + // To-do: Set CDROM firmware version and region based + // on CLI options + if (cfg->cd_path) psx_cdrom_open(cdrom, cfg->cd_path); diff --git a/psx/dev/cdrom/cdrom.c b/psx/dev/cdrom/cdrom.c index 9a616b1..11b4c5b 100644 --- a/psx/dev/cdrom/cdrom.c +++ b/psx/dev/cdrom/cdrom.c @@ -503,55 +503,54 @@ void psx_cdrom_update(psx_cdrom_t* cdrom, int cycles) { return; } - psx_ic_irq(cdrom->ic, IC_CDROM); - - if (cdrom->state == CD_STATE_TX_RESP1) { - cdrom_handle_resp1(cdrom); - - switch (cdrom->pending_command) { - case CDL_READN: - case CDL_READS: - return; - } - - // Switching to read mode after executing a command - // has a 500ms penalty - if (cdrom->state == CD_STATE_READ) { - cdrom_process_setloc(cdrom); + switch (cdrom->state) { + case CD_STATE_TX_RESP1: { + cdrom_handle_resp1(cdrom); + + switch (cdrom->pending_command) { + case CDL_READN: + case CDL_READS: + break; + } - int ts = psx_disc_query(cdrom->disc, cdrom->lba); - - cdrom->state = CD_STATE_READ; - cdrom->prev_state = CD_STATE_READ; - cdrom->delay = CD_DELAY_ONGOING_READ; - } + // Switching to read mode after executing a command + // has a 500ms penalty + if (cdrom->state == CD_STATE_READ) { + cdrom_process_setloc(cdrom); - return; - } + int ts = psx_disc_query(cdrom->disc, cdrom->lba); + + cdrom->state = CD_STATE_READ; + cdrom->prev_state = CD_STATE_READ; + cdrom->delay = CD_DELAY_ONGOING_READ; + } + } break; - if (cdrom->state == CD_STATE_TX_RESP2) { - cdrom_cmd_table[cdrom->pending_command](cdrom); + case CD_STATE_TX_RESP2: { + cdrom_cmd_table[cdrom->pending_command](cdrom); - // Switching to read mode after executing a command - // has a 500ms penalty - if (cdrom->state == CD_STATE_READ) { - cdrom_process_setloc(cdrom); + // Switching to read mode after executing a command + // has a 500ms penalty + if (cdrom->state == CD_STATE_READ) { + cdrom_process_setloc(cdrom); - int ts = psx_disc_query(cdrom->disc, cdrom->lba); - - cdrom->state = CD_STATE_READ; - cdrom->prev_state = CD_STATE_READ; - cdrom->delay = CD_DELAY_ONGOING_READ; - } + int ts = psx_disc_query(cdrom->disc, cdrom->lba); + + cdrom->state = CD_STATE_READ; + cdrom->prev_state = CD_STATE_READ; + cdrom->delay = CD_DELAY_ONGOING_READ; + } + } break; - return; + case CD_STATE_READ: { + cdrom_handle_read(cdrom); + } break; } - if (cdrom->state == CD_STATE_READ) { - cdrom_handle_read(cdrom); - + if ((cdrom->ifr & cdrom->ier) == 0) return; - } + + psx_ic_irq(cdrom->ic, IC_CDROM); } uint8_t cdrom_read_status(psx_cdrom_t* cdrom) { diff --git a/psx/dev/cdrom/impl.c b/psx/dev/cdrom/impl.c index 75186d5..583e6c9 100644 --- a/psx/dev/cdrom/impl.c +++ b/psx/dev/cdrom/impl.c @@ -480,13 +480,11 @@ void cdrom_cmd_gettn(psx_cdrom_t* cdrom) { int tn = psx_disc_get_track_count(cdrom->disc); - printf("getstat=%02x\n", cdrom_get_stat(cdrom)); - queue_push(cdrom->response, cdrom_get_stat(cdrom)); queue_push(cdrom->response, 1); queue_push(cdrom->response, ITOB(tn)); - cdrom_restore_state(cdrom); + cdrom_pause(cdrom); } void cdrom_cmd_gettd(psx_cdrom_t* cdrom) { @@ -721,15 +719,17 @@ void cdrom_cmd_getq(psx_cdrom_t* cdrom) { void cdrom_cmd_readtoc(psx_cdrom_t* cdrom) { if (cdrom->state == CD_STATE_TX_RESP1) { cdrom_set_int(cdrom, 3); + queue_push(cdrom->response, cdrom_get_stat(cdrom)); - cdrom->delay = PSX_CPU_CPS / 2; + cdrom->delay = CD_DELAY_1MS * 500; cdrom->state = CD_STATE_TX_RESP2; } else { cdrom_set_int(cdrom, 2); - queue_push(cdrom->response, cdrom_get_stat(cdrom)); - cdrom_restore_state(cdrom); + queue_push(cdrom->response, CD_STAT_SPINDLE); + + cdrom_pause(cdrom); } }