shithub: psxe

Download patch

ref: b12a6380928caa21ca2feca485a9adaa096008a0
parent: 2bd54ea370da6e37c742923ad96dd6b3b5838e00
author: Lycoder <aurealinbox@gmail.com>
date: Mon Sep 25 12:28:10 EDT 2023

Implement CdlMotoron

--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -343,6 +343,39 @@
         } break;
     }
 }
+void cdrom_cmd_motoron(psx_cdrom_t* cdrom) {
+    cdrom->delayed_command = CDL_NONE;
+
+    switch (cdrom->state) {
+        case CD_STATE_RECV_CMD: {
+            cdrom->read_ongoing = 0;
+            cdrom->cdda_playing = 0;
+
+            cdrom->irq_delay = DELAY_1MS;
+            cdrom->state = CD_STATE_SEND_RESP1;
+            cdrom->delayed_command = CDL_MOTORON;
+        } break;
+
+        case CD_STATE_SEND_RESP1: {
+            SET_BITS(ifr, IFR_INT, 3);
+            RESP_PUSH(GETSTAT_MOTOR | GETSTAT_READ);
+
+            int double_speed = cdrom->mode & MODE_SPEED;
+
+            cdrom->irq_delay = DELAY_1MS * (double_speed ? 70 : 65);
+            cdrom->state = CD_STATE_SEND_RESP2;
+            cdrom->delayed_command = CDL_MOTORON;
+        } break;
+
+        case CD_STATE_SEND_RESP2: {
+            SET_BITS(ifr, IFR_INT, 2);
+            RESP_PUSH(GETSTAT_MOTOR);
+
+            cdrom->state = CD_STATE_RECV_CMD;
+            cdrom->delayed_command = CDL_NONE;
+        } break;
+    }
+}
 void cdrom_cmd_stop(psx_cdrom_t* cdrom) {
     cdrom->delayed_command = CDL_NONE;
 
@@ -557,7 +590,30 @@
     }
 }
 void cdrom_cmd_getlocl(psx_cdrom_t* cdrom) { log_fatal("getlocl: Unimplemented"); exit(1); }
-void cdrom_cmd_getlocp(psx_cdrom_t* cdrom) { log_fatal("getlocp: Unimplemented"); exit(1); }
+void cdrom_cmd_getlocp(psx_cdrom_t* cdrom) {
+    switch (cdrom->state) {
+        case CD_STATE_RECV_CMD: {
+            cdrom->irq_delay = DELAY_1MS;
+            cdrom->delayed_command = CDL_GETLOCP;
+            cdrom->state = CD_STATE_SEND_RESP1;
+        } break;
+
+        case CD_STATE_SEND_RESP1: {
+            SET_BITS(ifr, IFR_INT, IFR_INT3);
+            RESP_PUSH(0x00);
+            RESP_PUSH(0x00);
+            RESP_PUSH(0x00);
+            RESP_PUSH(0x00);
+            RESP_PUSH(0x00);
+            RESP_PUSH(0x00);
+            RESP_PUSH(0x01);
+            RESP_PUSH(0xff);
+
+            cdrom->delayed_command = CDL_NONE;
+            cdrom->state = CD_STATE_RECV_CMD;
+        } break;
+    }
+}
 void cdrom_cmd_gettn(psx_cdrom_t* cdrom) {
     cdrom->delayed_command = CDL_NONE;
 
@@ -614,6 +670,18 @@
 
             cdrom->gettd_track = PFIFO_POP;
 
+            int err = psx_disc_get_track_addr(cdrom->disc, NULL, cdrom->gettd_track);
+
+            if (err) {
+                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;
+            }
+
             cdrom->irq_delay = DELAY_1MS;
             cdrom->delayed_command = CDL_GETTD;
             cdrom->state = CD_STATE_SEND_RESP1;
@@ -624,10 +692,6 @@
 
             psx_disc_get_track_addr(cdrom->disc, &td, cdrom->gettd_track);
 
-            log_fatal("@@@@@@@@@@@@@@@@ GetTD track=%u, addr=%02u:%02u", cdrom->gettd_track, td.m, td.s);
-
-            // To-do: Handle OOB tracks
-
             SET_BITS(ifr, IFR_INT, IFR_INT3);
             RESP_PUSH(ITOB(td.s));
             RESP_PUSH(ITOB(td.m));
@@ -815,24 +879,24 @@
                 SET_BITS(ifr, IFR_INT, 2);
 
                 // Unlicensed:Mode1
-                RESP_PUSH(0x00);
-                RESP_PUSH(0x00);
-                RESP_PUSH(0x00);
-                RESP_PUSH(0x00);
-                RESP_PUSH(0x00);
-                RESP_PUSH(0x00);
-                RESP_PUSH(0x80);
-                RESP_PUSH(0x0a);
-
-                // Licensed:Mode2
-                // RESP_PUSH(0x41);
-                // RESP_PUSH(0x45);
-                // RESP_PUSH(0x43);
-                // RESP_PUSH(0x53);
                 // RESP_PUSH(0x00);
-                // RESP_PUSH(0x20);
                 // RESP_PUSH(0x00);
-                // RESP_PUSH(0x02);
+                // RESP_PUSH(0x00);
+                // RESP_PUSH(0x00);
+                // RESP_PUSH(0x00);
+                // RESP_PUSH(0x00);
+                // RESP_PUSH(0x80);
+                // RESP_PUSH(0x0a);
+
+                // Licensed:Mode2
+                RESP_PUSH(0x41);
+                RESP_PUSH(0x45);
+                RESP_PUSH(0x43);
+                RESP_PUSH(0x53);
+                RESP_PUSH(0x00);
+                RESP_PUSH(0x20);
+                RESP_PUSH(0x00);
+                RESP_PUSH(0x02);
             } else {
                 SET_BITS(ifr, IFR_INT, 5);
 
@@ -990,7 +1054,7 @@
     "CdlUnimplemented",
     "CdlUnimplemented",
     "CdlReadn",
-    "CdlUnimplemented",
+    "CdlMotoron",
     "CdlStop",
     "CdlPause",
     "CdlInit",
@@ -1025,7 +1089,7 @@
     cdrom_cmd_unimplemented,
     cdrom_cmd_unimplemented,
     cdrom_cmd_readn,
-    cdrom_cmd_unimplemented,
+    cdrom_cmd_motoron,
     cdrom_cmd_stop,
     cdrom_cmd_pause,
     cdrom_cmd_init,
--- a/psx/dev/cdrom.h
+++ b/psx/dev/cdrom.h
@@ -261,6 +261,7 @@
 void cdrom_cmd_setloc(psx_cdrom_t*);
 void cdrom_cmd_play(psx_cdrom_t*);
 void cdrom_cmd_readn(psx_cdrom_t*);
+void cdrom_cmd_motoron(psx_cdrom_t*);
 void cdrom_cmd_stop(psx_cdrom_t*);
 void cdrom_cmd_pause(psx_cdrom_t*);
 void cdrom_cmd_init(psx_cdrom_t*);
--- a/psx/disc/cue.c
+++ b/psx/disc/cue.c
@@ -91,7 +91,7 @@
     const char* token = g_psxd_cue_tokens[i];
 
     while (token) {
-        if (strcmp(token, cue->buf) == 1) {
+        if (!strcmp(token, cue->buf)) {
             return i;
         } else {
             token = g_psxd_cue_tokens[++i];
@@ -424,6 +424,9 @@
     psxd_cue_t* cue = udata;
 
     if (!track) {
+        if (!msf)
+            return 0;
+
         msf->m = cue->end.m;
         msf->s = cue->end.s;
 
@@ -432,6 +435,9 @@
 
     if (track > cue->num_tracks)
         return DISC_ERR_TRACK_OUT_OF_BOUNDS;
+
+    if (!msf)
+        return 0;
     
     msf->m = cue->track[track - 1]->disc_offset.m;
     msf->s = cue->track[track - 1]->disc_offset.s;
--- a/psx/disc/cue.h
+++ b/psx/disc/cue.h
@@ -24,8 +24,8 @@
 };
 
 enum {
-    CUE_NONE,
-    CUE_4CH,
+    CUE_NONE = 255,
+    CUE_4CH = 0,
     CUE_AIFF,
     CUE_AUDIO,
     CUE_BINARY,
--