shithub: psxe

Download patch

ref: 72ac93b384c6e6996085db4c80a70421c30ada41
parent: 510b4f0733d2546184643d362235db145c963d16
author: allkern <lisandroaalarcon@gmail.com>
date: Sun Oct 8 21:23:04 EDT 2023

Implemented CDDA features

Implemented basic CDDA Report IRQ support
Implemented CdlPlay auto track seeking

--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -195,25 +195,30 @@
 
     switch (cdrom->state) {
         case CD_STATE_RECV_CMD: {
-            // Ignore parameters
-            cdrom->pfifo_index = 0;
+            int track = 0;
 
-            // if (cdrom->pfifo_index) {
-            //     log_fatal("CdlGetStat: Expected exactly 0 parameters");
+            // Optional track number parameter
+            if (cdrom->pfifo_index)
+                track = PFIFO_POP;
 
-            //     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->state = CD_STATE_SEND_RESP1;
             cdrom->delayed_command = CDL_PLAY;
 
+            if (track) {
+
+                psx_disc_get_track_addr(cdrom->disc, &cdrom->cdda_msf, track);
+
+                msf_to_bcd(&cdrom->cdda_msf);
+
+                cdrom->cdda_track = track;
+                cdrom->seek_mm = cdrom->cdda_msf.m;
+                cdrom->seek_ss = cdrom->cdda_msf.s;
+                cdrom->seek_ff = cdrom->cdda_msf.f;
+    
+                cdrom->seek_pending = 1;
+            }
+
             if (cdrom->seek_pending) {
                 cdrom->seek_pending = 0;
 
@@ -1505,9 +1510,33 @@
     msf_from_bcd(&msf);
 
     // Seek to that address and read sector
-    psx_disc_seek(cdrom->disc, msf);
+    if (psx_disc_seek(cdrom->disc, msf)) {
+        cdrom->cdda_playing = 0;
+    }
+
     psx_disc_read_sector(cdrom->disc, cdrom->cdda_buf);
 
+    ++cdrom->cdda_sectors_played;
+
+    if (cdrom->cdda_sectors_played == CD_SECTORS_PS) {
+        if (cdrom->mode & MODE_REPORT) {
+            SET_BITS(ifr, IFR_INT, 1);
+
+            RESP_PUSH(0);
+            RESP_PUSH(0);
+            RESP_PUSH(cdrom->cdda_msf.f);
+            RESP_PUSH(cdrom->cdda_msf.s | 0x80);
+            RESP_PUSH(cdrom->cdda_msf.m);
+            RESP_PUSH(0);
+            RESP_PUSH(cdrom->cdda_track);
+            RESP_PUSH(GETSTAT_PLAY);
+
+            psx_ic_irq(cdrom->ic, IC_CDROM);
+        }
+
+        cdrom->cdda_sectors_played = 0;
+    }
+
     // Increment sector
     msf_add_f(&msf, 1);
     msf_to_bcd(&msf);
@@ -1515,68 +1544,7 @@
     // Assign to CDDA MSF
     cdrom->cdda_msf = msf;
 
-    /*
-    start = offset
-    end = offset + request
-
-    start = 0
-    end = 10
-    
-    */
-
-    // int req_start = cdrom->cdda_sector_offset;
-    // int req_end = req_start + size;
-
-    // if (req_end > CD_SECTOR_SIZE) {
-    //     int unbuffered = req_end - CD_SECTOR_SIZE;
-    //     //int buffered = 
-    // }
-
-    // // We need a new sector
-    // if (cdrom->cdda_sector_offset >= CD_SECTOR_SIZE) {
-    //     cdrom->cdda_sector_offset -= CD_SECTOR_SIZE;
-
-    //     // Convert seek to I
-    //     msf_t msf = cdrom->cdda_msf;
-        
-    //     msf_from_bcd(&msf);
-
-    //     // Seek to that address and read sector
-    //     psx_disc_seek(cdrom->disc, msf);
-    //     psx_disc_read_sector(cdrom->disc, cdrom->cdda_buf);
-
-    //     // Increment sector
-    //     msf_add_f(&msf, 1);
-    //     msf_to_bcd(&msf);
-
-    //     // Assign to CDDA MSF
-    //     cdrom->cdda_msf = msf;
-    // }
-
     memcpy(buf, cdrom->cdda_buf, size);
-
-    // cdrom->cdda_sector_offset += size;
-
-    // // We need a new sector
-    // if (cdrom->cdda_sector_offset >= CD_SECTOR_SIZE) {
-    //     cdrom->cdda_sector_offset -= CD_SECTOR_SIZE;
-
-    //     // Convert seek to I
-    //     msf_t msf = cdrom->cdda_msf;
-        
-    //     msf_from_bcd(&msf);
-
-    //     // Seek to that address and read sector
-    //     psx_disc_seek(cdrom->disc, msf);
-    //     psx_disc_read_sector(cdrom->disc, cdrom->cdda_buf);
-
-    //     // Increment sector
-    //     msf_add_f(&msf, 1);
-    //     msf_to_bcd(&msf);
-
-    //     // Assign to CDDA MSF
-    //     cdrom->cdda_msf = msf;
-    // }
 }
 
 void psx_cdrom_destroy(psx_cdrom_t* cdrom) {
--- a/psx/dev/cdrom.h
+++ b/psx/dev/cdrom.h
@@ -197,6 +197,8 @@
     int cdda_sector_offset;
     msf_t cdda_msf;
     int cdda_playing;
+    int cdda_sectors_played;
+    int cdda_track;
 
     const char* path;
     psx_disc_t* disc;
--