ref: 2989bb6ea366123012f68b7d0ba4fed482999d46
parent: 2c6a5a42ab52db675388ed9171015ff1497b8b66
author: allkern <lisandroaalarcon@gmail.com>
date: Mon Jul 22 19:41:29 EDT 2024
Implement IER IRQ blocking Fixes a lot of games (Strider 2, Crash Bash, Tokimeki Memorial 2, Rockman games, and many more)
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -42,6 +42,9 @@
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);
--- a/psx/dev/cdrom/cdrom.c
+++ b/psx/dev/cdrom/cdrom.c
@@ -503,55 +503,54 @@
return;
}
- psx_ic_irq(cdrom->ic, IC_CDROM);
+ switch (cdrom->state) {+ case CD_STATE_TX_RESP1: {+ cdrom_handle_resp1(cdrom);
- if (cdrom->state == CD_STATE_TX_RESP1) {- cdrom_handle_resp1(cdrom);
+ switch (cdrom->pending_command) {+ case CDL_READN:
+ case CDL_READS:
+ break;
+ }
- 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);
- // 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_TX_RESP2: {+ cdrom_cmd_table[cdrom->pending_command](cdrom);
- if (cdrom->state == 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) {--- a/psx/dev/cdrom/impl.c
+++ b/psx/dev/cdrom/impl.c
@@ -480,13 +480,11 @@
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_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);
}
}
--
⑨