shithub: psxe

Download patch

ref: c9a8620e9e0dbba505b609a2027e51ce6f320a15
parent: 662bb5f225dd1cf6b189f045651618c584d6224e
author: allkern <lisandroaalarcon@gmail.com>
date: Mon Jul 31 15:47:49 EDT 2023

Improve CD error handling

--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -60,9 +60,10 @@
 
 void cdrom_cmd_error(psx_cdrom_t* cdrom) {
     SET_BITS(ifr, IFR_INT, IFR_INT5);
-    RESP_PUSH(cdrom->stat);
-    RESP_PUSH(0x20);
+    RESP_PUSH(cdrom->error);
+    RESP_PUSH(GETSTAT_MOTOR | cdrom->error_flags);
 
+    cdrom->pfifo_index = 0;
     cdrom->delayed_command = CDL_NONE;
     cdrom->state = CD_STATE_RECV_CMD;
 }
@@ -77,6 +78,12 @@
             if (cdrom->pfifo_index) {
                 log_fatal("CdlGetStat: Expected exactly 0 parameters");
 
+                cdrom->irq_delay = DELAY_1MS;
+                cdrom->delayed_command = CDL_ERROR;
+                cdrom->state = CD_STATE_ERROR;
+                cdrom->error = ERR_PCOUNT;
+                cdrom->error_flags = GETSTAT_ERROR;
+
                 return;
             }
 
@@ -103,6 +110,12 @@
                     cdrom->pfifo_index
                 );
 
+                cdrom->irq_delay = DELAY_1MS;
+                cdrom->delayed_command = CDL_ERROR;
+                cdrom->state = CD_STATE_ERROR;
+                cdrom->error = ERR_PCOUNT;
+                cdrom->error_flags = GETSTAT_ERROR;
+
                 return;
             }
 
@@ -249,8 +262,14 @@
     switch (cdrom->state) {
         case CD_STATE_RECV_CMD: {
             if (cdrom->pfifo_index) {
-                log_fatal("CdlGetStat: Expected exactly 0 parameters");
+                log_fatal("CdlUnmute: Expected exactly 0 parameters");
 
+                cdrom->irq_delay = DELAY_1MS;
+                cdrom->delayed_command = CDL_ERROR;
+                cdrom->state = CD_STATE_ERROR;
+                cdrom->error = ERR_PCOUNT;
+                cdrom->error_flags = GETSTAT_ERROR;
+
                 return;
             }
 
@@ -278,6 +297,8 @@
                 cdrom->irq_delay = DELAY_1MS;
                 cdrom->delayed_command = CDL_ERROR;
                 cdrom->state = CD_STATE_ERROR;
+                cdrom->error = ERR_PCOUNT;
+                cdrom->error_flags = GETSTAT_ERROR;
 
                 return;
             }
@@ -312,6 +333,12 @@
             if (cdrom->pfifo_index) {
                 log_fatal("CdlGetTN: Expected exactly 0 parameters");
 
+                cdrom->irq_delay = DELAY_1MS;
+                cdrom->delayed_command = CDL_ERROR;
+                cdrom->state = CD_STATE_ERROR;
+                cdrom->error = ERR_PCOUNT;
+                cdrom->error_flags = GETSTAT_ERROR;
+
                 return;
             }
 
@@ -337,6 +364,12 @@
             if (cdrom->pfifo_index != 1) {
                 log_fatal("CdlGetTD: Expected exactly 0 parameters");
 
+                cdrom->irq_delay = DELAY_1MS;
+                cdrom->delayed_command = CDL_ERROR;
+                cdrom->state = CD_STATE_ERROR;
+                cdrom->error = ERR_PCOUNT;
+                cdrom->error_flags = GETSTAT_ERROR;
+
                 return;
             }
 
@@ -395,6 +428,12 @@
             if (cdrom->pfifo_index != 1) {
                 log_fatal("CdlTest: Expected exactly 1 parameter");
 
+                cdrom->irq_delay = DELAY_1MS;
+                cdrom->delayed_command = CDL_ERROR;
+                cdrom->state = CD_STATE_ERROR;
+                cdrom->error = ERR_PCOUNT;
+                cdrom->error_flags = GETSTAT_ERROR;
+
                 return;
             }
 
@@ -401,6 +440,11 @@
             if (PFIFO_POP != 0x20) {
                 log_fatal("CdlTest: Unhandled subcommand");
 
+                cdrom->irq_delay = DELAY_1MS;
+                cdrom->delayed_command = CDL_ERROR;
+                cdrom->state = CD_STATE_ERROR;
+                cdrom->error = ERR_INVSUBF;
+
                 return;
             }
 
@@ -431,6 +475,8 @@
                 cdrom->irq_delay = DELAY_1MS;
                 cdrom->delayed_command = CDL_ERROR;
                 cdrom->state = CD_STATE_ERROR;
+                cdrom->error = ERR_PCOUNT;
+                cdrom->error_flags = GETSTAT_ERROR;
 
                 return;
             }
@@ -720,13 +766,6 @@
             (STAT_PRMEMPT_MASK | STAT_PRMWRDY_MASK)
         );
     }
-
-    // Clear Response FIFO
-    // if (value & 0x7) {
-    //     cdrom->rfifo_index = 0;
-
-    //     SET_BITS(status, STAT_RSLRRDY_MASK, 0);
-    // }
 }
 
 void cdrom_write_sminfo(psx_cdrom_t* cdrom, uint8_t value) {
--- a/psx/dev/cdrom.h
+++ b/psx/dev/cdrom.h
@@ -119,6 +119,27 @@
 #define REQ_BFWR 0x40
 #define REQ_BFRD 0x80
 
+/*
+  ___These values appear in the FIRST response; with stat.bit0 set___
+  10h - Invalid Sub_function (for command 19h), or invalid parameter value
+  20h - Wrong number of parameters
+  40h - Invalid command
+  80h - Cannot respond yet (eg. required info was not yet read from disk yet)
+           (namely, TOC not-yet-read or so)
+           (also appears if no disk inserted at all)
+  ___These values appear in the SECOND response; with stat.bit2 set___
+  04h - Seek failed (when trying to use SeekL on Audio CDs)
+  ___These values appear even if no command was sent; with stat.bit2 set___
+  08h - Drive door became opened
+*/
+
+#define ERR_INVSUBF 0x10
+#define ERR_PCOUNT  0x20
+#define ERR_INVALID 0x40
+#define ERR_BUSY    0x80
+#define ERR_SEEK    0x04
+#define ERR_LIDOPEN 0x08
+
 typedef struct {
     uint32_t io_base, io_size;
 
@@ -159,6 +180,8 @@
     int state;
     int delayed_response;
     int spin_delay;
+    uint8_t error;
+    uint8_t error_flags;
 
     const char* path;
     FILE* disc;
--