]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
stuff
authorToni Wilen <twilen@winuae.net>
Wed, 21 Jul 2010 09:33:48 +0000 (12:33 +0300)
committerToni Wilen <twilen@winuae.net>
Wed, 21 Jul 2010 09:33:48 +0000 (12:33 +0300)
19 files changed:
akiko.cpp
blkdev.cpp
blkdev_cdimage.cpp
cd32_fmv.cpp
cdtv.cpp
cfgfile.cpp
custom.cpp
include/blkdev.h
include/options.h
od-win32/blkdev_win32_aspi.cpp
od-win32/blkdev_win32_ioctl.cpp
od-win32/blkdev_win32_spti.cpp
od-win32/rp.cpp
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32gui.cpp
savestate.cpp
scsiemul.cpp
zfile_archive.cpp

index 22f752921076c6c913004c85c67308ccc63be831..82a448a035e59fa891f80e4dcb9c54a31feac237 100644 (file)
--- a/akiko.cpp
+++ b/akiko.cpp
@@ -420,7 +420,6 @@ static uae_u8 *sector_buffer_info_1, *sector_buffer_info_2;
 
 static int unitnum = -1;
 static int cdromok = 0;
-static int cd_hunt;
 static bool akiko_inited;
 static volatile int mediachanged, mediacheckcounter;
 static volatile int frame2counter;
@@ -660,77 +659,10 @@ static int get_cdrom_toc (void)
 /* open device */
 static int sys_cddev_open (void)
 {
-       int first = -1;
-       struct device_info di1, *di2;
-       int cd32unit = -1;
-       int audiounit = -1;
-       int opened[MAX_TOTAL_SCSI_DEVICES];
-       int i;
-
-       for (unitnum = 0; unitnum < MAX_TOTAL_SCSI_DEVICES; unitnum++) {
-               opened[unitnum] = 0;
-               if (sys_command_open (unitnum)) {
-                       opened[unitnum] = 1;
-                       di2 = sys_command_info (unitnum, &di1, 0);
-                       if (di2 && di2->type == INQ_ROMD) {
-                               write_log (L"%s: ", di2->label);
-                               if (first < 0)
-                                       first = unitnum;
-                               if (!get_cdrom_toc ()) {
-                                       if (cdrom_data_end > 0) {
-                                               uae_u8 buffer[2048];
-                                               if (sys_command_cd_read (unitnum, buffer, 16, 1)) {
-                                                       uae_u8 *p = buffer;
-                                                       if (!memcmp (p + 8, "CDTV", 4) || !memcmp (p + 8, "CD32", 4)) {
-                                                               uae_u32 crc;
-                                                               write_log (L"CD32 or CDTV");
-                                                               if (cd32unit < 0)
-                                                                       cd32unit = unitnum;
-                                                               if (sys_command_cd_read (unitnum, buffer, 21, 1)) {
-                                                                       crc = get_crc32 (buffer, 2048);
-                                                                       if (crc == 0xe56c340f)
-                                                                               write_log (L" [CD32.TM]");
-                                                                       write_log (L"\n");
-                                                               }
-                                                       } else {
-                                                               write_log (L"non CD32/CDTV data CD\n");
-                                                       }
-                                               } else {
-                                                       write_log (L"read error\n");
-                                               }
-                                       } else {
-                                               write_log (L"Audio CD\n");
-                                               if (audiounit < 0)
-                                                       audiounit = unitnum;
-                                       }
-                               } else {
-                                       write_log (L"can't read TOC\n");
-                               }
-                       }
-               }
-       }
-       unitnum = audiounit;
-       if (cd32unit >= 0)
-               unitnum = cd32unit;
-       if (unitnum < 0)
-               unitnum = first;
-       if (unitnum >= 0)
-               opened[unitnum] = 0;
-       for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-               if (opened[i])
-                       sys_command_close (i);
-       }
-       if (unitnum < 0)
-               return 1;
-       di2 = sys_command_info (unitnum, &di1, 0);
-       if (!di2) {
-               write_log (L"unit %d info failed\n", unitnum);
-               sys_command_close (unitnum);
-               return 1;
-       }
-       if (sys_command_ismedia (unitnum, 0) <= 0)
-               cd_hunt = 1;
-       write_log (L"using drive %s (unit %d, media %d)\n", di2->label, unitnum, di2->media_inserted);
+       struct device_info di;
+       unitnum = get_standard_cd_unit (CD_STANDARD_UNIT_CD32);
+       sys_command_info (unitnum, &di, 0);
+       write_log (L"using drive %s (unit %d, media %d)\n", di.label, unitnum, di.media_inserted);
        /* make sure CD audio is not playing */
        cdaudiostop_do ();
        return 0;
@@ -803,11 +735,7 @@ static int cdrom_command_led (void)
 static int cdrom_command_media_status (void)
 {
        cdrom_result_buffer[0] = 0x0a;
-       if (cd_hunt) {
-               cdrom_result_buffer[1] = 0x80;
-       } else {
-               cdrom_result_buffer[1] = sys_command_ismedia (unitnum, 0) > 0 ? 0x83: 0x80;
-       }
+       cdrom_result_buffer[1] = sys_command_ismedia (unitnum, 0) > 0 ? 0x83: 0x80;
        return 2;
 }
 
@@ -1013,7 +941,10 @@ static void cdrom_run_command (void)
                        cdrom_command_buffer[i] = get_byte (cdtx_address + ((cdcomtxinx + i) & 0xff));
                        checksum += cdrom_command_buffer[i];
 #if AKIKO_DEBUG_IO_CMD
-                       write_log (L"%02X ", cdrom_command_buffer[i]);
+                       if (i == cmd_len)
+                               write_log (L"(%02X) ", cdrom_command_buffer[i]); // checksum
+                       else
+                               write_log (L"%02X ", cdrom_command_buffer[i]);
 #endif
                }
                if (checksum != 0xff) {
@@ -1073,8 +1004,6 @@ static void cdrom_run_command_run (void)
        cdrom_start_return_data (len);
 }
 
-extern void encode_l2 (uae_u8 *p, int address);
-
 /* DMA transfer one CD sector */
 static void cdrom_run_read (void)
 {
@@ -1108,8 +1037,7 @@ static void cdrom_run_read (void)
                if (sector_buffer_info_1[sec] != 0xff && sector_buffer_info_1[sec] != 0) {
                        uae_u8 buf[2352];
 
-                       memcpy (buf + 16, sector_buffer_1 + sec * 2048, 2048);
-                       encode_l2 (buf, sector + 150);
+                       memcpy (buf, sector_buffer_1 + sec * 2352, 2352);
                        buf[0] = 0;
                        buf[1] = 0;
                        buf[2] = 0;
@@ -1186,52 +1114,11 @@ static void akiko_internal (void)
        }
 }
 
-static void do_hunt (void)
-{
-       int i;
-       for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-               if (sys_command_ismedia (i, 1) > 0)
-                       break;
-       }
-       if (i == MAX_TOTAL_SCSI_DEVICES) {
-               if (unitnum >= 0 && sys_command_ismedia (unitnum, 1) >= 0)
-                       return;
-               for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-                       if (sys_command_ismedia (i, 1) >= 0)
-                               break;
-               }
-               if (i == MAX_TOTAL_SCSI_DEVICES)
-                       return;
-       }
-       if (unitnum >= 0) {
-               int ou = unitnum;
-               unitnum = -1;
-               sys_command_close (ou);
-       }
-       if (sys_command_open (i) > 0) {
-               struct device_info di = { 0 };
-               sys_command_info (i, &di, 0);
-               unitnum = i;
-               cd_hunt = 0;
-               lastmediastate = -1;
-               write_log (L"CD32: autodetected unit %d ('%s')\n", unitnum, di.label);
-       }
-}
-
 void AKIKO_hsync_handler (void)
 {
        if (!currprefs.cs_cd32cd || !akiko_inited)
                return;
 
-       if (cd_hunt) {
-               static int huntcnt;
-               if (huntcnt <= 0 && (!mediachanged || unitnum < 0)) {
-                       do_hunt ();
-                       huntcnt = 312 * 50 * 2;
-               }
-               huntcnt--;
-       }
-
        framecounter--;
        if (framecounter <= 0) {
                if (cdrom_led) {
@@ -1344,15 +1231,12 @@ static void *akiko_thread (void *null)
                        mediacheckcounter = 312 * 50 * 2;
                        int media = sys_command_ismedia (unitnum, 1);
                        if (media < 0) {
-                               if (!cd_hunt) {
-                                       write_log (L"CD32: device unit %d lost\n", unitnum);
-                                       media = lastmediastate = cdrom_disk = 0;
-                                       mediachanged = 1;
-                                       cdaudiostop_do ();
-                                       cd_hunt = 1;
-                               }
+                               write_log (L"CD32: device unit %d lost\n", unitnum);
+                               media = lastmediastate = cdrom_disk = 0;
+                               mediachanged = 1;
+                               cdaudiostop_do ();
                        } else if (media != lastmediastate) {
-                               write_log (L"CD32: media changed = %d (hunt=%d)\n", media, cd_hunt);
+                               write_log (L"CD32: media changed = %d\n", media);
                                lastmediastate = cdrom_disk = media;
                                mediachanged = 1;
                                cdaudiostop_do ();
@@ -1376,7 +1260,7 @@ static void *akiko_thread (void *null)
                                while (offset < SECTOR_BUFFER_SIZE) {
                                        int ok = 0;
                                        if (sector < cdrom_data_end)
-                                               ok = sys_command_cd_read (unitnum, sector_buffer_2 + offset * 2048, sector, 1);
+                                               ok = sys_command_cd_rawread (unitnum, sector_buffer_2 + offset * 2352, sector, 1, 2352);
                                        sector_buffer_info_2[offset] = ok ? 3 : 0;
                                        offset++;
                                        sector++;
@@ -1764,14 +1648,10 @@ int akiko_init (void)
 {
        if (currprefs.cs_cd32cd && cdromok == 0) {
                unitnum = -1;
-               if (!device_func_init (0)) {
-                       write_log (L"no CDROM support\n");
-                       return 0;
-               }
                if (!sys_cddev_open ()) {
                        cdromok = 1;
-                       sector_buffer_1 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE * 2048);
-                       sector_buffer_2 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE * 2048);
+                       sector_buffer_1 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE * 2352);
+                       sector_buffer_2 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE * 2352);
                        sector_buffer_info_1 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE);
                        sector_buffer_info_2 = xmalloc (uae_u8, SECTOR_BUFFER_SIZE);
                        sector_buffer_sector_1 = -1;
index 1b34842e7392a64bf53f9e6fa7576caae199fb9d..ac47acbd8958425aae596743161a5865cbd74d0b 100644 (file)
@@ -1,7 +1,9 @@
 /*
 * UAE - The Un*x Amiga Emulator
 *
-* lowlevel device glue
+* lowlevel cd device glue, scsi emulator
+*
+* Copyright 2009-2010 Toni Wilen
 *
 */
 
@@ -13,6 +15,7 @@
 #include "blkdev.h"
 #include "scsidev.h"
 #include "savestate.h"
+#include "crc32.h"
 #ifdef RETROPLATFORM
 #include "rp.h"
 #endif
@@ -112,27 +115,36 @@ static void install_driver (int flags)
        for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
                scsiemu[i] = false;
                device_func[i] = NULL;
-               switch (cdscsidevicetype[i])
-               {
-                       case SCSI_UNIT_IMAGE:
-                       device_func[i] = devicetable[SCSI_UNIT_IMAGE];
-                       scsiemu[i] = true;
-                       break;
-                       case SCSI_UNIT_IOCTL:
-                       device_func[i] = devicetable[SCSI_UNIT_IOCTL];
-                       scsiemu[i] = true;
-                       break;
-                       case SCSI_UNIT_SPTI:
-                       if (currprefs.win32_uaescsimode == UAESCSI_CDEMU) {
+       }
+       if (flags > 0) {
+               device_func[0] = devicetable[flags];
+               scsiemu[0] = true;
+       } else {
+               for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
+                       scsiemu[i] = false;
+                       device_func[i] = NULL;
+                       switch (cdscsidevicetype[i])
+                       {
+                               case SCSI_UNIT_IMAGE:
+                               device_func[i] = devicetable[SCSI_UNIT_IMAGE];
+                               scsiemu[i] = true;
+                               break;
+                               case SCSI_UNIT_IOCTL:
                                device_func[i] = devicetable[SCSI_UNIT_IOCTL];
                                scsiemu[i] = true;
-                       } else {
-                               device_func[i] = devicetable[SCSI_UNIT_SPTI];
+                               break;
+                               case SCSI_UNIT_SPTI:
+                               if (currprefs.win32_uaescsimode == UAESCSI_CDEMU) {
+                                       device_func[i] = devicetable[SCSI_UNIT_IOCTL];
+                                       scsiemu[i] = true;
+                               } else {
+                                       device_func[i] = devicetable[SCSI_UNIT_SPTI];
+                               }
+                               break;
+                               case SCSI_UNIT_ASPI:
+                               device_func[i] = devicetable[SCSI_UNIT_ASPI];
+                               break;
                        }
-                       break;
-                       case SCSI_UNIT_ASPI:
-                       device_func[i] = devicetable[SCSI_UNIT_ASPI];
-                       break;
                }
        }
 
@@ -155,30 +167,35 @@ static void install_driver (int flags)
 void blkdev_default_prefs (struct uae_prefs *p)
 {
        for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-               p->cdimagefile[i][0] = 0;
-               p->cdimagefileuse[i] = false;
-               p->cdscsidevicetype[i] = SCSI_UNIT_NONE;
-               cdscsidevicetype[i] = SCSI_UNIT_NONE;
+               p->cdslots[i].name[0] = 0;
+               p->cdslots[i].inuse = false;
+               p->cdslots[i].type = SCSI_UNIT_DEFAULT;
+               cdscsidevicetype[i] = SCSI_UNIT_DEFAULT;
        }
 }
 
 void blkdev_fix_prefs (struct uae_prefs *p)
 {
-       for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++)
-               cdscsidevicetype[i] = p->cdscsidevicetype[i];
+       for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
+               cdscsidevicetype[i] = p->cdslots[i].type;
+               if (p->cdslots[i].inuse == false && p->cdslots[i].name[0] && p->cdslots[i].type != SCSI_UNIT_DISABLED)
+                       p->cdslots[i].inuse = true;
+       }
 
        // blkdev_win32_aspi.cpp does not support multi units
        if (currprefs.win32_uaescsimode >= UAESCSI_ASPI_FIRST) {
-               for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++)
-                       cdscsidevicetype[i] = SCSI_UNIT_ASPI;
+               for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
+                       if (cdscsidevicetype[i] != SCSI_UNIT_DISABLED)
+                               cdscsidevicetype[i] = SCSI_UNIT_ASPI;
+               }
                return;
        }
 
        for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-               if (cdscsidevicetype[i] != SCSI_UNIT_NONE)
+               if (cdscsidevicetype[i] != SCSI_UNIT_DEFAULT)
                        continue;
-               if (p->cdimagefileuse[i] || p->cdimagefile[i][0]) {
-                       TCHAR *name = p->cdimagefile[i];
+               if (p->cdslots[i].inuse || p->cdslots[i].name[0]) {
+                       TCHAR *name = p->cdslots[i].name;
                        if (_tcslen (name) == 3 && name[1] == ':' && name[2] == '\\') {
                                if (currprefs.scsi && (currprefs.win32_uaescsimode == UAESCSI_SPTI || currprefs.win32_uaescsimode == UAESCSI_SPTISCAN))
                                        cdscsidevicetype[i] = SCSI_UNIT_SPTI;
@@ -201,25 +218,108 @@ void blkdev_fix_prefs (struct uae_prefs *p)
 
 }
 
-
-int sys_command_isopen (int unitnum)
-{
-       return openlist[unitnum];
-}
-
-int sys_command_open (int unitnum)
+static int sys_command_open_internal (int unitnum, const TCHAR *ident)
 {
        int ret = 0;
        if (openlist[unitnum])
                write_log (L"BUG unit %d open: opencnt=%d!\n", unitnum, openlist[unitnum]);
        if (device_func[unitnum]) {
-               ret = device_func[unitnum]->opendev (unitnum, currprefs.cdimagefile[unitnum][0] ? currprefs.cdimagefile[unitnum] : NULL);
+               ret = device_func[unitnum]->opendev (unitnum, ident);
                if (ret)
                        openlist[unitnum]++;
        }
        return ret;
 }
 
+int get_standard_cd_unit (enum cd_standard_unit csu)
+{
+       int unitnum = 0;
+       if (currprefs.cdslots[unitnum].name[0] || currprefs.cdslots[unitnum].inuse) {
+               device_func_init (SCSI_UNIT_IOCTL);
+               if (!sys_command_open_internal (unitnum, currprefs.cdslots[unitnum].name)) {
+                       device_func_init (SCSI_UNIT_IMAGE);
+                       if (!sys_command_open_internal (unitnum, currprefs.cdslots[unitnum].name))
+                               goto fallback;
+               }
+               return unitnum;
+       }
+       int isaudio = 0;
+       device_func_init (SCSI_UNIT_IOCTL);
+       for (int drive = 'C'; drive <= 'Z'; ++drive) {
+               TCHAR vol[100];
+               _stprintf (vol, L"%c:\\", drive);
+               int drivetype = GetDriveType (vol);
+               if (drivetype == DRIVE_CDROM) {
+                       if (sys_command_open_internal (unitnum, vol)) {
+                               struct device_info di;
+                               write_log (L"Scanning drive %s: ", vol);
+                               if (sys_command_info (unitnum, &di, 0)) {
+                                       if (di.media_inserted) {
+                                               if (isaudiotrack (&di.toc, 0)) {
+                                                       if (isaudio == 0)
+                                                               isaudio = drive;
+                                                       write_log (L"CDA");
+                                               }
+                                               uae_u8 buffer[2048];
+                                               if (sys_command_cd_read (unitnum, buffer, 16, 1)) {
+                                                       if (!memcmp (buffer + 8, "CDTV", 4) || !memcmp (buffer + 8, "CD32", 4)) {
+                                                               uae_u32 crc;
+                                                               write_log (L"CD32 or CDTV");
+                                                               if (sys_command_cd_read (unitnum, buffer, 21, 1)) {
+                                                                       crc = get_crc32 (buffer, sizeof buffer);
+                                                                       if (crc == 0xe56c340f) {
+                                                                               write_log (L" [CD32.TM]");
+                                                                               if (csu == CD_STANDARD_UNIT_CD32) {
+                                                                                       write_log (L"\n");
+                                                                                       return unitnum;
+                                                                               }
+                                                                       }
+                                                               }
+                                                               if (csu == CD_STANDARD_UNIT_CDTV || csu == CD_STANDARD_UNIT_CD32) {
+                                                                       write_log (L"\n");
+                                                                       return unitnum;
+                                                               }
+                                                       }
+                                               }
+                                       } else {
+                                               write_log (L"no media");
+                                       }
+                               }
+                               write_log (L"\n");
+                       }
+                       sys_command_close (unitnum);
+               }
+       }
+       if (isaudio) {
+               TCHAR vol[100];
+               _stprintf (vol, L"%c:\\", isaudio);
+               if (sys_command_open_internal (unitnum, vol)) 
+                       return unitnum;
+       }
+fallback:
+       device_func_init (SCSI_UNIT_IMAGE);
+       if (!sys_command_open_internal (unitnum, L"")) {
+               write_log (L"image mounter failed to open as empty!?\n");
+               return -1;
+       }
+       return unitnum;
+}
+void close_standard_cd_unit (int unitnum)
+{
+       sys_command_close (unitnum);
+}
+
+int sys_command_isopen (int unitnum)
+{
+       return openlist[unitnum];
+}
+
+int sys_command_open (int unitnum)
+{
+       return sys_command_open_internal (unitnum, currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : NULL);
+}
+
+
 void sys_command_close (int unitnum)
 {
        if (openlist[unitnum] <= 0)
@@ -231,6 +331,16 @@ void sys_command_close (int unitnum)
        }
 }
 
+void blkdev_cd_change (int unitnum, const TCHAR *name)
+{
+       struct device_info di;
+       sys_command_info (unitnum, &di, 1);
+#ifdef RETROPLATFORM
+       rp_cd_change (unitnum, di.media_inserted);
+       rp_cd_image_change (unitnum, name);
+#endif
+}
+
 void device_func_reset (void)
 {
 }
@@ -251,16 +361,16 @@ static void check_changes (int unitnum)
 {
        bool changed = false;
 
-       if (_tcscmp (changed_prefs.cdimagefile[unitnum], currprefs.cdimagefile[unitnum]) != 0)
+       if (_tcscmp (changed_prefs.cdslots[unitnum].name, currprefs.cdslots[unitnum].name) != 0)
                changed = true;
-       if (!changed && changed_prefs.cdimagefile[unitnum][0] == 0 && changed_prefs.cdimagefileuse[unitnum] != currprefs.cdimagefileuse[unitnum])
+       if (!changed && changed_prefs.cdslots[unitnum].name[0] == 0 && changed_prefs.cdslots[unitnum].inuse != currprefs.cdslots[unitnum].inuse)
                changed = true;
 
        if (changed) {
-               cdimagefileinuse[unitnum] = changed_prefs.cdimagefileuse[unitnum];
-               _tcscpy (newimagefiles[unitnum], changed_prefs.cdimagefile[unitnum]);
-               changed_prefs.cdimagefile[unitnum][0] = currprefs.cdimagefile[unitnum][0] = 0;
-               currprefs.cdimagefileuse[unitnum] = changed_prefs.cdimagefileuse[unitnum];
+               cdimagefileinuse[unitnum] = changed_prefs.cdslots[unitnum].inuse;
+               _tcscpy (newimagefiles[unitnum], changed_prefs.cdslots[unitnum].name);
+               changed_prefs.cdslots[unitnum].name[0] = currprefs.cdslots[unitnum].name[0] = 0;
+               currprefs.cdslots[unitnum].inuse = changed_prefs.cdslots[unitnum].inuse;
                int pollmode = 0;
                imagechangetime[unitnum] = 3 * 50;
                struct device_info di;
@@ -284,14 +394,14 @@ static void check_changes (int unitnum)
        imagechangetime[unitnum]--;
        if (imagechangetime[unitnum] > 0)
                return;
-       _tcscpy (currprefs.cdimagefile[unitnum], newimagefiles[unitnum]);
-       _tcscpy (changed_prefs.cdimagefile[unitnum], newimagefiles[unitnum]);
-       currprefs.cdimagefileuse[unitnum] = changed_prefs.cdimagefileuse[unitnum] = cdimagefileinuse[unitnum];
+       _tcscpy (currprefs.cdslots[unitnum].name, newimagefiles[unitnum]);
+       _tcscpy (changed_prefs.cdslots[unitnum].name, newimagefiles[unitnum]);
+       currprefs.cdslots[unitnum].inuse = changed_prefs.cdslots[unitnum].inuse = cdimagefileinuse[unitnum];
        newimagefiles[unitnum][0] = 0;
-       write_log (L"CD: delayed insert '%s'\n", currprefs.cdimagefile[unitnum][0] ? currprefs.cdimagefile[unitnum] : L"<EMPTY>");
+       write_log (L"CD: delayed insert '%s'\n", currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : L"<EMPTY>");
        device_func_init (0);
        if (wasopen[unitnum]) {
-               if (!device_func[unitnum]->opendev (unitnum, currprefs.cdimagefile[unitnum])) {
+               if (!device_func[unitnum]->opendev (unitnum, currprefs.cdslots[unitnum].name)) {
                        write_log (L"-> device open failed\n");
                }
        }
@@ -303,7 +413,7 @@ static void check_changes (int unitnum)
                scsi_do_disk_change (unitnum, 1, &pollmode);
        }
 #ifdef RETROPLATFORM
-       rp_cd_image_change (unitnum, currprefs.cdimagefile[unitnum]);
+       rp_cd_image_change (unitnum, currprefs.cdslots[unitnum].name);
 #endif
        config_changed = 1;
 
@@ -493,9 +603,9 @@ int sys_command_cd_rawread (int unitnum, uae_u8 *data, int block, int size, int
                uae_u8 cmd[12] = { 0xbe, 0, block >> 24, block >> 16, block >> 8, block >> 0, size >> 16, size >> 8, size >> 0, 0x10, 0, 0 };
                return do_scsi (unitnum, cmd, sizeof cmd, data, size * sectorsize);
        }
-       return device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, 0xffff);
+       return device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, 0xffffffff);
 }
-int sys_command_cd_rawread (int unitnum, uae_u8 *data, int block, int size, int sectorsize, uae_u8 scsicmd9, uae_u8 subs)
+int sys_command_cd_rawread (int unitnum, uae_u8 *data, int block, int size, int sectorsize, uae_u8 sectortype, uae_u8 scsicmd9, uae_u8 subs)
 {
        if (failunit (unitnum))
                return -1;
@@ -503,7 +613,7 @@ int sys_command_cd_rawread (int unitnum, uae_u8 *data, int block, int size, int
                uae_u8 cmd[12] = { 0xbe, 0, block >> 24, block >> 16, block >> 8, block >> 0, size >> 16, size >> 8, size >> 0, 0x10, 0, 0 };
                return do_scsi (unitnum, cmd, sizeof cmd, data, size * sectorsize);
        }
-       return device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, (scsicmd9 << 8) | subs);
+       return device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, (sectortype << 16) | (scsicmd9 << 8) | subs);
 }
 
 /* read block */
@@ -671,39 +781,6 @@ void scsi_log_after (uae_u8 *data, int datalen, uae_u8 *sense, int senselen)
        }
 }
 
-uae_u8 *save_cd (int num, int *len)
-{
-       uae_u8 *dstbak, *dst;
-
-       if (num != 0)
-               return NULL;
-       if (!currprefs.cdimagefile[0])
-               return NULL;
-
-       dstbak = dst = xmalloc (uae_u8, 4 + 256);
-       save_u32 (4);
-       for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-               save_string (currprefs.cdimagefile[i]);
-               save_u32 (currprefs.cdscsidevicetype[i]);
-       }
-       *len = dst - dstbak;
-       return dstbak;
-}
-
-uae_u8 *restore_cd (int unit, uae_u8 *src)
-{
-       uae_u32 flags;
-       TCHAR *s;
-
-       flags = restore_u32 ();
-       s = restore_string ();
-       if ((flags & 4) && unit == 0) {
-               _tcscpy (changed_prefs.cdimagefile[0], s);
-               _tcscpy (currprefs.cdimagefile[0], s);
-       }
-       return src;
-}
-
 static bool nodisk (struct device_info *di)
 {
        return di->media_inserted == 0;
@@ -791,7 +868,7 @@ static int scsi_read_cd (int unitnum, uae_u8 *cmd, uae_u8 *data, struct device_i
        int subs = cmd[10] & 7;
        if (len == 0)
                return 0;
-       return sys_command_cd_rawread (unitnum, data, start, len, 0, cmd[9], subs);
+       return sys_command_cd_rawread (unitnum, data, start, len, 0, (cmd[1] >> 2) & 7, cmd[9], subs);
 }
 
 static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
@@ -802,6 +879,7 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
        int scsi_len = -1;
        int status = 0;
        struct device_info di;
+       uae_u8 cmd = cmdbuf[0];
 
        *reply_len = *sense_len = 0;
        memset (r, 0, 256);
@@ -1157,6 +1235,10 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                        sys_command_cd_stop (unitnum);
                        scsi_len = 0;
                break;
+               case 0x1e: // PREVENT/ALLOW MEDIA REMOVAL
+                       // do nothing
+                       scsi_len = 0;
+               break;
                case 0x4e: // STOP PLAY/SCAN
                        if (nodisk (&di))
                                goto nodisk;
@@ -1209,6 +1291,28 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                        scsi_len = 0;
                }
                break;
+               case 0x49: // PLAY AUDIO TRACK RELATIVE (10)
+               case 0xa9: // PLAY AUDIO TRACK RELATIVE (12)
+               {
+                       if (nodisk (&di))
+                               goto nodisk;
+                       int len = cmd == 0xa9 ? rl (cmdbuf + 6) : rw (cmdbuf + 7);
+                       int track = cmd == 0xa9 ? cmdbuf[10] : cmdbuf[6];
+                       if (track < di.toc.first_track || track > di.toc.last_track)
+                               goto errreq;
+                       int start = di.toc.toc[di.toc.first_track_offset + track - 1].paddress;
+                       int rel = rl (cmdbuf + 2);
+                       start += rel;
+                       int end = start + len;
+                       if (end > di.toc.lastaddress)
+                               end = di.toc.lastaddress;
+                       if (len > 0) {
+                               if (!sys_command_cd_play (unitnum, start, start + len, 0, NULL))
+                                       goto notdatatrack;
+                       }
+                       scsi_len = 0;
+               }
+               break;
                case 0x47: // PLAY AUDIO MSF
                {
                        if (nodisk (&di))
@@ -1220,27 +1324,39 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                                start = fromlongbcd (buf + 4 + 7);
                        }
                        int end = msf2lsn (rl (cmdbuf + 5) & 0x00ffffff);
+                       if (end > di.toc.lastaddress)
+                               end = di.toc.lastaddress;
                        start = msf2lsn (start);
                        if (start > end)
                                goto errreq;
                        if (start < end)
-                               sys_command_cd_play (unitnum, start, end, 0, NULL);
+                               if (!sys_command_cd_play (unitnum, start, end, 0, NULL))
+                                       goto notdatatrack;
                        scsi_len = 0;
                }
                break;
-               case 0x45: // PLAY AUDIO
+               case 0x45: // PLAY AUDIO (10)
+               case 0xa5: // PLAY AUDIO (12)
                {
                        if (nodisk (&di))
                                goto nodisk;
                        int start = rl (cmdbuf + 2);
-                       int len = rw (cmdbuf + 7);
+                       int len;
+                       if (cmd= 0xa5)
+                               len = rl (cmdbuf + 6);
+                       else
+                               len = rw (cmdbuf + 7);
                        if (len > 0) {
                                if (start == -1) {
                                        uae_u8 buf[SUBQ_SIZE] = { 0 };
                                        sys_command_cd_qcode (unitnum, buf);
                                        start = msf2lsn (fromlongbcd (buf + 4 + 7));
                                }
-                               sys_command_cd_play (unitnum, start, start + len, 0, NULL);
+                               int end = start + len;
+                               if (end > di.toc.lastaddress)
+                                       end = di.toc.lastaddress;
+                               if (!sys_command_cd_play (unitnum, start, end, 0, NULL))
+                                       goto notdatatrack;
                        }
                        scsi_len = 0;
                }
@@ -1258,10 +1374,14 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                                start = rl (cmdbuf + 2);
                                end = start + rl (cmdbuf + 6);
                        }
+                       if (end > di.toc.lastaddress)
+                               end = di.toc.lastaddress;
                        if (start > end)
                                goto errreq;
-                       if (start < end)
-                               sys_command_cd_play (unitnum, start, end, 0, NULL);
+                       if (start < end) {
+                               if (!sys_command_cd_play (unitnum, start, end, 0, NULL))
+                                       goto notdatatrack;
+                       }
                }
                break;
                case 0x4b: // PAUSE/RESUME
@@ -1426,3 +1546,41 @@ int sys_command_scsi_direct (int unitnum, uaecptr acmd)
 
        return ret;
 }
+
+#ifdef SAVESTATE
+
+uae_u8 *save_cd (int num, int *len)
+{
+       uae_u8 *dstbak, *dst;
+
+       if (!currprefs.cdslots[num].inuse || num >= MAX_TOTAL_SCSI_DEVICES)
+               return NULL;
+       dstbak = dst = xmalloc (uae_u8, 4 + 256 + 4 + 4);
+       save_u32 (4);
+       save_string (currprefs.cdslots[num].name);
+       save_u32 (currprefs.cdslots[num].type);
+       save_u32 (0);
+       *len = dst - dstbak;
+       return dstbak;
+}
+
+uae_u8 *restore_cd (int num, uae_u8 *src)
+{
+       uae_u32 flags;
+       TCHAR *s;
+
+       if (num >= MAX_TOTAL_SCSI_DEVICES)
+               return NULL;
+       flags = restore_u32 ();
+       s = restore_string ();
+       int type = restore_u32 ();
+       restore_u32 ();
+       if (flags & 4) {
+               _tcscpy (changed_prefs.cdslots[num].name, s);
+               _tcscpy (currprefs.cdslots[num].name, s);
+               changed_prefs.cdslots[num].type = currprefs.cdslots[num].type = type;
+       }
+       return src;
+}
+
+#endif
index 8679a0443e1ee570149f3180c35bf20118d11548..7fd7127216fe3964516e8a3628f0c8f7e4dd6fbc 100644 (file)
@@ -1,7 +1,11 @@
 /*
 * UAE
 *
-* CD32/CDTV image file support
+* CD image file support
+*
+* - iso (2048/2352 block size)
+* - cue/bin, cue/bin/wav, cue/bin/mp3
+* - ccd/img and ccd/img/sub
 *
 * Copyright 2010 Toni Wilen
 *
 #include "fsdb.h"
 #include "threaddep/thread.h"
 #include "scsidev.h"
-#include <mp3decoder.h>
-#include <memory.h>
+#include "mp3decoder.h"
+#include "memory.h"
 #ifdef RETROPLATFORM
 #include "rp.h"
 #endif
 
 #define scsi_log write_log
 
-#define USE 1
-
 #define CDDA_BUFFERS 6
 
 #define AUDIO_STATUS_NOT_SUPPORTED  0x00
@@ -50,6 +52,7 @@ struct cdtoc
        uae_u8 adr, ctrl;
        int track;
        int size;
+       int skipsize; // bytes to skip after each block
        int mp3;
        int subcode;
 };
@@ -144,13 +147,46 @@ static int cdda_openwav (void)
        return 1;
 }
 
+static void sub_to_interleaved (const uae_u8 *s, uae_u8 *d)
+{
+       for (int i = 0; i < 8 * 12; i ++) {
+               int dmask = 0x80;
+               int smask = 1 << (7 - (i & 7));
+               (*d) = 0;
+               for (int j = 0; j < 8; j++) {
+                       (*d) |= (s[(i / 8) + j * 12] & smask) ? dmask : 0;
+                       dmask >>= 1;
+               }
+               d++;
+       }
+}
+static void sub_to_deinterleaved (const uae_u8 *s, uae_u8 *d)
+{
+       for (int i = 0; i < 8 * 12; i ++) {
+               int dmask = 0x80;
+               int smask = 1 << (7 - (i / 12));
+               (*d) = 0;
+               for (int j = 0; j < 8; j++) {
+                       (*d) |= (s[(i % 12) * 8 + j] & smask) ? dmask : 0;
+                       dmask >>= 1;
+               }
+               d++;
+       }
+}
+
 static int getsub (uae_u8 *dst, struct cdunit *cdu, struct cdtoc *t, int sector)
 {
        int ret = 0;
        uae_sem_wait (&cdu->sub_sem);
        if (t->subcode) {
                if (t->subhandle) {
-                       zfile_fseek (t->subhandle, sector * SUB_CHANNEL_SIZE + t->suboffset, SEEK_SET);
+                       int offset = 0;
+                       int totalsize = SUB_CHANNEL_SIZE;
+                       if (t->skipsize) {
+                               totalsize += t->size;
+                               offset = t->size;
+                       }
+                       zfile_fseek (t->subhandle, sector * totalsize + t->suboffset + offset, SEEK_SET);
                        if (zfile_fread (dst, SUB_CHANNEL_SIZE, 1, t->subhandle) > 0)
                                ret = t->subcode;
                } else {
@@ -171,37 +207,16 @@ static int getsub (uae_u8 *dst, struct cdunit *cdu, struct cdtoc *t, int sector)
                tolongbcd (s + 3, msf);
                ret = 2;
        }
+       if (ret == 1) {
+               uae_u8 tmp[SUB_CHANNEL_SIZE];
+               memcpy (tmp, dst, SUB_CHANNEL_SIZE);
+               sub_to_deinterleaved (tmp, dst);
+               ret = 2;
+       }
        uae_sem_post (&cdu->sub_sem);
        return ret;
 }
 
-static void sub_to_interleaved (const uae_u8 *s, uae_u8 *d)
-{
-       for (int i = 0; i < 8 * 12; i ++) {
-               int dmask = 0x80;
-               int smask = 1 << (7 - (i & 7));
-               (*d) = 0;
-               for (int j = 0; j < 8; j++) {
-                       (*d) |= (s[(i / 8) + j * 12] & smask) ? dmask : 0;
-                       dmask >>= 1;
-               }
-               d++;
-       }
-}
-static void sub_to_deinterleaved (const uae_u8 *s, uae_u8 *d)
-{
-       for (int i = 0; i < 8 * 12; i ++) {
-               int dmask = 0x80;
-               int smask = 1 << (7 - (i / 12));
-               (*d) = 0;
-               for (int j = 0; j < 8; j++) {
-                       (*d) |= (s[(i % 12) * 8 + j] & smask) ? dmask : 0;
-                       dmask >>= 1;
-               }
-               d++;
-       }
-}
-
 static void dosub (struct cdunit *cdu, struct cdtoc *t, int sector)
 {
        uae_u8 *d;
@@ -271,7 +286,7 @@ static void *cdda_play_func (void *v)
                        whdr[i].lpData = (LPSTR)px[i];
                        mmr = waveOutPrepareHeader (cdda_wavehandle, &whdr[i], sizeof (WAVEHDR));
                        if (mmr != MMSYSERR_NOERROR) {
-                               write_log (L"CDDA: waveOutPrepareHeader %d:%d\n", i, mmr);
+                               write_log (L"IMAGE CDDA: waveOutPrepareHeader %d:%d\n", i, mmr);
                                goto end;
                        }
                        whdr[i].dwFlags |= WHDR_DONE;
@@ -289,9 +304,9 @@ static void *cdda_play_func (void *v)
                                sector = cdu->cdda_start;
                                t = findtoc (cdu, &sector);
                                if (!t) {
-                                       write_log (L"CDDA: illegal sector number %d\n", cdu->cdda_start);
+                                       write_log (L"IMAGE CDDA: illegal sector number %d\n", cdu->cdda_start);
                                } else {
-                                       write_log (L"CDDA: playing from %d to %d, track %d ('%s', offset %d, secoffset %d)\n",
+                                       write_log (L"IMAGE CDDA: playing from %d to %d, track %d ('%s', offset %d, secoffset %d)\n",
                                                cdu->cdda_start, cdu->cdda_end, t->track, t->fname, t->offset, sector);
                                        if (t->mp3 && !t->data) {
                                                if (!mp3dec) {
@@ -350,11 +365,12 @@ static void *cdda_play_func (void *v)
                                                if (t) {
                                                        if (t->handle && !(t->ctrl & 4)) {
                                                                uae_u8 *dst = px[bufnum] + cnt * t->size;
+                                                               int totalsize = t->size + t->skipsize;
                                                                if (t->mp3 && t->data) {
-                                                                       memcpy (dst, t->data + sector * t->size + t->offset, t->size);
+                                                                       memcpy (dst, t->data + sector * totalsize + t->offset, t->size);
                                                                } else if (!t->mp3) {
-                                                                       if (sector * t->size + t->offset + t->size < t->filesize) {
-                                                                               zfile_fseek (t->handle, sector * t->size + t->offset, SEEK_SET);
+                                                                       if (sector * totalsize + t->offset + totalsize < t->filesize) {
+                                                                               zfile_fseek (t->handle, sector * totalsize + t->offset, SEEK_SET);
                                                                                zfile_fread (dst, t->size, 1, t->handle);
                                                                        }
                                                                }
@@ -384,7 +400,7 @@ static void *cdda_play_func (void *v)
                                bufon[bufnum] = 1;
                                mmr = waveOutWrite (cdda_wavehandle, &whdr[bufnum], sizeof (WAVEHDR));
                                if (mmr != MMSYSERR_NOERROR) {
-                                       write_log (L"CDDA: waveOutWrite %d\n", mmr);
+                                       write_log (L"IMAGE CDDA: waveOutWrite %d\n", mmr);
                                        break;
                                }
 
@@ -421,7 +437,7 @@ end:
        xfree (p);
        delete mp3dec;
        cdu->cdda_play = 0;
-       write_log (L"CDDA: thread killed\n");
+       write_log (L"IMAGE CDDA: thread killed\n");
        return NULL;
 }
 
@@ -473,7 +489,7 @@ static int command_play (int unitnum, int startlsn, int endlsn, int scan, play_s
        cdu->cdda_subfunc = subfunc;
        cdu->cdda_scan = scan > 0 ? 10 : (scan < 0 ? 10 : 0);
        if (!cdu->cdda_play)
-               uae_start_thread (L"cdda_play", cdda_play_func, cdu, NULL);
+               uae_start_thread (L"cdimage_cdda_play", cdda_play_func, cdu, NULL);
        cdu->cdda_play++;
        return 1;
 }
@@ -542,7 +558,9 @@ static uae_u32 command_volume (int unitnum, uae_u16 volume_left, uae_u16 volume_
        return old;
 }
 
-static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int sectorsize, uae_u16 extra)
+extern void encode_l2 (uae_u8 *p, int address);
+
+static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int sectorsize, uae_u32 extra)
 {
        int ret = 0;
        struct cdunit *cdu = unitisopen (unitnum);
@@ -555,16 +573,30 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int
                return 0;
        cdda_stop (cdu);
        if (sectorsize > 0) {
-               if (sectorsize > t->size)
-                       return 0;
                offset = 0;
-               if (sectorsize == 2336 && t->size == 2352)
+               if (sectorsize == 2352 && t->size == 2048) {
+                       // 2048 -> 2352
+                       memset (data, 0, 16);
+                       zfile_fseek (t->handle, t->offset + sector * t->size, SEEK_SET);
+                       zfile_fread (data + 16, t->size, size, t->handle);
+                       encode_l2 (data, sector + 150);
+               } else if (sectorsize == 2336 && t->size == 2352) {
+                       // 2352 -> 2336
                        offset = 16;
-               zfile_fseek (t->handle, t->offset + sector * t->size + offset, SEEK_SET);
-               zfile_fread (data, sectorsize, size, t->handle);
+                       memset (data, 0, offset);
+                       zfile_fseek (t->handle, t->offset + sector * t->size + offset, SEEK_SET);
+                       zfile_fread (data, sectorsize, size, t->handle);
+               } else if (sectorsize == t->size) {
+                       // no change
+                       zfile_fseek (t->handle, t->offset + sector * t->size, SEEK_SET);
+                       zfile_fread (data, sectorsize, size, t->handle);
+               }
                cdu->cd_last_pos = sector;
                ret = sectorsize * size;
+
+
        } else {
+               uae_u8 sectortype = extra >> 16;
                uae_u8 cmd9 = extra >> 8;
                int sync = (cmd9 >> 7) & 1;
                int headercodes = (cmd9 >> 5) & 3;
@@ -576,8 +608,10 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int
                        return -1;
 
                if (isaudiotrack (&cdu->di.toc, sector)) {
-                       if (t->size != 2352)
+                       if (sectortype != 0 && sectortype != 1)
                                return -2;
+                       if (t->size != 2352)
+                               return -1;
                        for (int i = 0; i < size; i++) {
                                zfile_fseek (t->handle, t->offset + sector * t->size, SEEK_SET);
                                zfile_fread (data, t->size, 1, t->handle);
@@ -719,6 +753,182 @@ static int readval (const TCHAR *s)
        return _tcstol (s, &endptr, base);
 }
 
+#define MEDIA_DESCRIPTOR "MEDIA DESCRIPTOR"
+
+/* MDS spec structures from cdemu */
+
+#define MDS_MEDIUM_CD           0x00 /* CD-ROM */
+#define MDS_MEDIUM_CD_R         0x01 /* CD-R */
+#define MDS_MEDIUM_CD_RW        0x02 /* CD-RW */
+#define MDS_MEDIUM_DVD          0x10 /* DVD-ROM */
+#define MDS_MEDIUM_DVD_MINUS_R  0x12 /* DVD-R */
+#define MDS_TRACKMODE_UNKNOWN       0x00
+#define MDS_TRACKMODE_AUDIO         0xA9 /* sector size = 2352 */
+#define MDS_TRACKMODE_MODE1         0xAA /* sector size = 2048 */
+#define MDS_TRACKMODE_MODE2         0xAB /* sector size = 2336 */
+#define MDS_TRACKMODE_MODE2_FORM1   0xAC /* sector size = 2048 */
+#define MDS_TRACKMODE_MODE2_FORM2   0xAD /* sector size = 2324 (+4) */
+
+#define MDS_SUBCHAN_NONE            0x00 /* no subchannel */
+#define MDS_SUBCHAN_PW_INTERLEAVED  0x08 /* 96-byte PW subchannel, interleaved */
+
+#define MDS_POINT_TRACK_FIRST   0xA0 /* info about first track */
+#define MDS_POINT_TRACK_LAST    0xA1 /* info about last track  */
+#define MDS_POINT_TRACK_LEADOUT 0xA2 /* info about lead-out    */
+
+#pragma pack(1)
+
+typedef struct {
+    uae_u8 signature[16]; /* "MEDIA DESCRIPTOR" */
+    uae_u8 version[2]; /* Version ? */
+    uae_u16 medium_type; /* Medium type */
+    uae_u16 num_sessions; /* Number of sessions */
+    uae_u16 __dummy1__[2]; /* Wish I knew... */
+    uae_u16 bca_len; /* Length of BCA data (DVD-ROM) */
+    uae_u32 __dummy2__[2];
+    uae_u32 bca_data_offset; /* Offset to BCA data (DVD-ROM) */
+    uae_u32 __dummy3__[6]; /* Probably more offsets */
+    uae_u32 disc_structures_offset; /* Offset to disc structures */
+    uae_u32 __dummy4__[3]; /* Probably more offsets */
+    uae_u32 sessions_blocks_offset; /* Offset to session blocks */
+    uae_u32 dpm_blocks_offset; /* offset to DPM data blocks */
+} MDS_Header; /* length: 88 bytes */
+
+typedef struct {
+    uae_s32 session_start; /* Session's start address */
+    uae_s32 session_end; /* Session's end address */
+    uae_u16 session_number; /* (Unknown) */
+    uae_u8 num_all_blocks; /* Number of all data blocks. */
+    uae_u8 num_nontrack_blocks; /* Number of lead-in data blocks */
+    uae_u16 first_track; /* Total number of sessions in image? */
+    uae_u16 last_track; /* Number of regular track data blocks. */
+    uae_u32 __dummy2__; /* (unknown) */
+    uae_u32 tracks_blocks_offset; /* Offset of lead-in+regular track data blocks. */
+} MDS_SessionBlock; /* length: 24 bytes */
+
+typedef struct {
+    uae_u8 mode; /* Track mode */
+    uae_u8 subchannel; /* Subchannel mode */
+    uae_u8 adr_ctl; /* Adr/Ctl */
+    uae_u8 __dummy2__; /* Track flags? */
+    uae_u8 point; /* Track number. (>0x99 is lead-in track) */
+    
+    uae_u32 __dummy3__;
+    uae_u8 min; /* Min */
+    uae_u8 sec; /* Sec */
+    uae_u8 frame; /* Frame */
+    uae_u32 extra_offset; /* Start offset of this track's extra block. */
+    uae_u16 sector_size; /* Sector size. */
+    
+    uae_u8 __dummy4__[18];
+    uae_u32 start_sector; /* Track start sector (PLBA). */
+    uae_u64 start_offset; /* Track start offset. */
+    uae_u8 session; /* Session or index? */
+    uae_u8 __dummy5__[3];
+    uae_u32 footer_offset; /* Start offset of footer. */
+    uae_u8 __dummy6__[24];
+} MDS_TrackBlock; /* length: 80 bytes */
+
+typedef struct {
+    uae_u32 pregap; /* Number of sectors in pregap. */
+    uae_u32 length; /* Number of sectors in track. */
+} MDS_TrackExtraBlock; /* length: 8 bytes */
+
+typedef struct {
+    uae_u32 filename_offset; /* Start offset of image filename. */
+    uae_u32 widechar_filename; /* Seems to be set to 1 if widechar filename is used */
+    uae_u32 __dummy1__;
+    uae_u32 __dummy2__;
+} MDS_Footer; /* length: 16 bytes */
+
+#pragma pack()
+
+static int parsemds (struct cdunit *cdu, struct zfile *zmds, const TCHAR *img)
+{
+       MDS_Header *head;
+       struct cdtoc *t;
+       uae_u8 *mds = NULL;
+
+       write_log (L"MDS TOC: '%s'\n", img);
+       int size = zfile_size (zmds);
+       mds = xmalloc (uae_u8, size);
+       if (!mds)
+               goto end;
+       if (zfile_fread (mds, size, 1, zmds) != 1)
+               goto end;
+
+       head = (MDS_Header*)mds;
+       if (!memcmp (&head, MEDIA_DESCRIPTOR, strlen (MEDIA_DESCRIPTOR) - 1))
+               goto end;
+       if (head->version[0] != 1) {
+               write_log (L"unsupported version %d, only v.1 supported\n", head->version[0]);
+               goto end;
+       }
+
+       MDS_SessionBlock *sb = (MDS_SessionBlock*)(mds + head->sessions_blocks_offset);
+       cdu->tracks = sb->last_track - sb->first_track + 1;
+       for (int i = 0; i < sb->num_all_blocks; i++) {
+               MDS_TrackBlock *tb = (MDS_TrackBlock*)(mds + sb->tracks_blocks_offset + i * sizeof MDS_TrackBlock);
+               int point = tb->point;
+               int tracknum = -1;
+               if (point == 0xa2)
+                       tracknum = cdu->tracks;
+               else if (point >= 1 && point <= 99)
+                       tracknum = point - 1;
+               if (tracknum >= 0) {
+                       MDS_Footer *footer = tb->footer_offset == 0 ? NULL : (MDS_Footer*)(mds + tb->footer_offset);
+                       MDS_TrackExtraBlock *teb = tb->extra_offset == 0 ? NULL : (MDS_TrackExtraBlock*)(mds + tb->extra_offset);
+                       t = &cdu->toc[tracknum];
+                       t->adr = tb->adr_ctl >> 4;
+                       t->ctrl = tb->adr_ctl & 15;
+                       if (point == 0xa2)
+                               t->address = sb->session_end;
+                       else
+                               t->address = tb->start_sector;
+                       t->track = point;
+                       t->offset = tb->start_offset;
+                       t->size = tb->sector_size;
+
+                       if (footer) {
+                               TCHAR *fname = NULL;
+                               if (footer->widechar_filename == 0)
+                                       fname = au ((char*)(mds + footer->filename_offset));
+                               else
+                                       fname = my_strdup ((wchar_t*)(mds + footer->filename_offset));
+                               if (fname[0] == '*' && fname[1] == '.') {
+                                       TCHAR newname[MAX_DPATH];
+                                       _tcscpy (newname, img);
+                                       TCHAR *ext = _tcsrchr (newname, '.');
+                                       if (ext)
+                                               _tcscpy (ext, fname + 1);
+                                       xfree (fname);
+                                       fname = my_strdup (newname);
+                               }
+
+                               t->handle = zfile_fopen (fname, L"rb", ZFD_NORMAL);
+                               t->fname = my_strdup (fname);
+                               if (t->handle)
+                                       t->filesize = zfile_size (t->handle);
+                       }
+
+                       if (tb->subchannel && t->handle) {
+                               t->suboffset = t->offset + t->size;
+                               t->subcode = 1; // interleaved
+                               t->subhandle = zfile_dup (t->handle);
+                               t->skipsize = SUB_CHANNEL_SIZE;
+                               t->size -= SUB_CHANNEL_SIZE;
+                       }
+
+               }
+       }
+
+end:
+       xfree (mds);
+
+       return cdu->tracks;
+}
+
 static int parseccd (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
 {
        int mode;
@@ -738,7 +948,7 @@ static int parseccd (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
        zimg = zfile_fopen (fname, L"rb", ZFD_NORMAL);
        if (!zimg) {
                write_log (L"CCD: can't open '%s'\n", fname);
-               //return 0;
+               return 0;
        }
        ext = _tcsrchr (fname, '.');
        if (ext)
@@ -830,7 +1040,6 @@ static int parseccd (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
                                if (zimg) {
                                        t->handle = zfile_dup (zimg);
                                        t->fname = my_strdup (zfile_getname (zimg));
-                                       t->filesize = zfile_size (t->handle);
                                }
                                mode = -1;
                        }
@@ -1083,7 +1292,7 @@ static int parse_image (struct cdunit *cdu, const TCHAR *img)
        if (!zcue)
                return 0;
 
-       ext = _tcsrchr (img, '.');
+       ext = _tcsrchr (zfile_getname (zcue), '.');
        if (ext) {
                TCHAR curdir[MAX_DPATH];
                TCHAR oldcurdir[MAX_DPATH], *p;
@@ -1105,6 +1314,8 @@ static int parse_image (struct cdunit *cdu, const TCHAR *img)
                        parsecue (cdu, zcue, img);
                else if (!_tcsicmp (ext, L"ccd"))
                        parseccd (cdu, zcue, img);
+               else if (!_tcsicmp (ext, L"mds"))
+                       parsemds (cdu, zcue, img);
 
                if (oldcurdir[0])
                        my_setcurrentdir (oldcurdir, NULL);
@@ -1141,15 +1352,63 @@ static int parse_image (struct cdunit *cdu, const TCHAR *img)
                write_log (L"\n");
                if (i < cdu->tracks)
                        write_log (L" - %s\n", t->fname);
+               if (t->handle)
+                       t->filesize = zfile_size (t->handle);
        }
 
        cdu->blocksize = 2048;
        cdu->cdsize = cdu->toc[cdu->tracks].address * cdu->blocksize;
+       
 
        zfile_fclose (zcue);
        return 1;
 }
 
+
+static int ismedia (int unitnum, int quick)
+{
+       struct cdunit *cdu = &cdunits[unitnum];
+       if (!cdu->enabled)
+               return -1;
+       return cdu->tracks > 0 ? 1 : 0;
+}
+
+static struct device_info *info_device (int unitnum, struct device_info *di, int quick)
+{
+       struct cdunit *cdu = &cdunits[unitnum];
+       memset (di, 0, sizeof (struct device_info));
+       if (!cdu->enabled)
+               return 0;
+       di->open = cdu->open;
+       di->removable = 1;
+       di->bus = unitnum;
+       di->target = 0;
+       di->lun = 0;
+       di->media_inserted = 0;
+       di->bytespersector = 2048;
+       di->mediapath[0] = 0;
+       di->cylinders = 1;
+       di->trackspercylinder = 1;
+       di->sectorspertrack = cdu->cdsize / di->bytespersector;
+       if (ismedia (unitnum, 1)) {
+               di->media_inserted = 1;
+               _tcscpy (di->mediapath, currprefs.cdslots[unitnum].name);
+       }
+       memset (&di->toc, 0, sizeof (struct cd_toc_head));
+       command_toc (unitnum, &di->toc);
+       di->write_protected = 1;
+       di->type = INQ_ROMD;
+       di->unitnum = unitnum + 1;
+       if (di->mediapath[0]) {
+               _tcscpy (di->label, L"IMG:");
+               _tcscat (di->label, di->mediapath);
+       } else {
+               _tcscpy (di->label, L"IMG:<EMPTY>");
+       }
+       di->backend = L"IMAGE";
+       return di;
+}
+
 static void unload_image (struct cdunit *cdu)
 {
        int i;
@@ -1181,10 +1440,7 @@ static int open_device (int unitnum, const TCHAR *ident)
        cdu->enabled = true;
        cdu->cdda_volume[0] = 0x7fff;
        cdu->cdda_volume[1] = 0x7fff;
-#ifdef RETROPLATFORM
-       rp_cd_change (unitnum, 0);
-       rp_cd_image_change (unitnum, currprefs.cdimagefile[unitnum]);
-#endif
+       blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name);
        return 1;
 }
 
@@ -1198,48 +1454,7 @@ static void close_device (int unitnum)
        uae_sem_destroy (&cdu->sub_sem);
        cdu->open = false;
        cdu->enabled = false;
-#ifdef RETROPLATFORM
-       rp_cd_change (unitnum, 1);
-       rp_cd_image_change (unitnum, currprefs.cdimagefile[unitnum]);
-#endif
-}
-
-static int ismedia (int unitnum, int quick)
-{
-       struct cdunit *cdu = &cdunits[unitnum];
-       if (!cdu->enabled)
-               return -1;
-       return cdu->tracks > 0 ? 1 : 0;
-}
-
-static struct device_info *info_device (int unitnum, struct device_info *di, int quick)
-{
-       struct cdunit *cdu = &cdunits[unitnum];
-       memset (di, 0, sizeof (struct device_info));
-       if (!cdu->enabled)
-               return 0;
-       di->open = cdu->open;
-       di->removable = 1;
-       di->bus = unitnum;
-       di->target = 0;
-       di->lun = 0;
-       di->media_inserted = 0;
-       di->bytespersector = 2048;
-       di->mediapath[0] = 0;
-       di->cylinders = 1;
-       di->trackspercylinder = 1;
-       di->sectorspertrack = cdu->cdsize / di->bytespersector;
-       if (ismedia (unitnum, 1)) {
-               di->media_inserted = 1;
-               _tcscpy (di->mediapath, currprefs.cdimagefile[0]);
-       }
-       memset (&di->toc, 0, sizeof (struct cd_toc_head));
-       command_toc (unitnum, &di->toc);
-       di->write_protected = 1;
-       di->type = INQ_ROMD;
-       di->unitnum = unitnum + 1;
-       _tcscpy (di->label, L"CDEMU");
-       return di;
+       blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name);
 }
 
 static void close_bus (void)
index c7027939048c9f0b55c41101988debedbc454e64..0eccb82c58e0abf69c7acebe309f3abe99482973 100644 (file)
@@ -3,7 +3,7 @@
 *
 * CD32 FMV cartridge
 *
-* Copyright 2008 Toni Wilen
+* Copyright 2008-2010 Toni Wilen
 *
 */
 
 #include "cd32_fmv.h"
 #include "uae.h"
 
-//#define FMV_DEBUG
+#define FMV_DEBUG 1
 
-#define FMV_BASE 0x40000
-#define AUDIO_BASE 0x50000
-#define VIDEO_BASE 0x70000
-#define VIDEO_RAM 0x80000
+/*
+ 0x200000 - 0x23FFFF ROM
+ 0x240000 io/status (single word register?)
+ 0x2500xx L64111 audio decoder (word registers)
+ 0x2700xx CL450 video decoder (word registers)
+ 0x280000 - 0x2FFFFF RAM
+*/
+
+#define IO_BASE                        0x040000
+#define L64111_BASE            0x050000
+#define CL450_BASE             0x070000
+#define VRAM_BASE              0x080000
+
+#define BANK_MASK              0x0F0000
+
+#define IO_IRQ_L641111 0x4000
+#define IO_IRQ_CL450   0x8000
 
 // L64111 registers (from datasheet)
-#define A_DATA 0
-#define A_CONTROL1 2
-#define A_CONTROL2 4
-#define A_CONTROL3 6
-#define A_INT1 8
-#define A_INT2 10
-#define A_TCR 12
-#define A_TORH 14
-#define A_TORL 16
-#define A_PARAM1 18
-#define A_PARAM2 20
-#define A_PARAM3 22
-#define A_PRESENT1 24
-#define A_PRESENT2 26
-#define A_PRESENT3 28
-#define A_PRESENT4 30
-#define A_PRESENT5 32
-#define A_FIFO 34
-#define A_CB_STATUS 36
-#define A_CB_WRITE 38
-#define A_CB_READ 40
+#define A_DATA                  0      //0
+#define A_CONTROL1              1      //2
+#define A_CONTROL2              2      //4
+#define A_CONTROL3              3      //6
+#define A_INT1                  4      //8
+#define A_INT2                  5      //10
+#define A_TCR                   6      //12
+#define A_TORH                  7      //14
+#define A_TORL                  8      //16
+#define A_PARAM1                9      //18
+#define A_PARAM2               10      //20
+#define A_PARAM3               11      //22
+#define A_PRESENT1             12      //24
+#define A_PRESENT2             13      //26
+#define A_PRESENT3             14      //28
+#define A_PRESENT4             15      //30
+#define A_PRESENT5             16      //32
+#define A_FIFO                 17      //34
+#define A_CB_STATUS            18      //36
+#define A_CB_WRITE             19      //38
+#define A_CB_READ              20      //40
 
 static int fmv_mask;
 static uae_u8 *rom;
@@ -55,51 +68,191 @@ static int rom_size = 262144;
 static uaecptr fmv_start = 0x00200000;
 static int fmv_size = 1048576;
 
-static uae_u8 fmv_bget2 (uaecptr addr)
+static uae_u16 l64111regs[32];
+static uae_u16 l64111intmask1, l64111intmask2, l64111intstatus1, l64111intstatus2;
+static uae_u16 io_reg;
+
+static int isdebug (uaecptr addr)
 {
-#ifdef FMV_DEBUG
-       write_log (L"fmv_bget2 %08X PC=%8X\n", addr, M68K_GETPC);
+#if FMV_DEBUG > 2
+       if (M68K_GETPC >= 0x200100)
+               return 1;
+       return 0;
+#endif
+#if (FMV_DEBUG == 2)
+       if (M68K_GETPC >= 0x200100 && (addr & fmv_mask) >= VRAM_BASE)
+               return 1;
+       return 0;
 #endif
-       if (addr >= rom_size && addr < 0x80000) {
-               write_log (L"fmv_bget2 %08X PC=%8X\n", addr, M68K_GETPC);
+       return 0;
+}
+
+static uae_u8 io_bget (uaecptr addr)
+{
+       addr &= 0xffff;
+       write_log (L"FMV: IO byte read access %08x!\n", addr);
+       return 0;
+}
+static uae_u16 io_wget (uaecptr addr)
+{
+       addr &= 0xffff;
+       if (addr != 0)
                return 0;
+       return io_reg;
+}
+static void io_bput (uaecptr addr, uae_u8 v)
+{
+       addr &= 0xffff;
+       write_log (L"FMV: IO byte write access %08x!\n", addr);
+}
+static void io_wput (uaecptr addr, uae_u16 v)
+{
+       addr &= 0xffff;
+       if (addr != 0)
+               return;
+       write_log (L"FMV: IO=%04x\n", v);
+       io_reg = v;
+}
+
+static uae_u8 l64111_bget (uaecptr addr)
+{
+       write_log (L"FMV: L64111 byte read access %08x!\n", addr);
+       return 0;
+}
+static void l64111_bput (uaecptr addr, uae_u8 v)
+{
+       write_log (L"FMV: L64111 byte write access %08x!\n", addr);
+}
+
+static uae_u16 l64111_wget (uaecptr addr)
+{
+       addr >>= 1;
+       addr &= 31;
+#if FMV_DEBUG > 0
+       write_log (L"FMV: L64111 read reg %d -> %04x\n", addr, l64111regs[addr]);
+#endif
+       if (addr == 4)
+               return l64111intstatus1;
+       if (addr == 5)
+               return l64111intstatus1;
+
+       return l64111regs[addr];
+}
+static void l64111_wput (uaecptr addr, uae_u16 v)
+{
+       addr >>= 1;
+       addr &= 31;
+
+#if FMV_DEBUG > 0
+       write_log (L"FMV: L64111 write reg %d = %04x\n", addr, v);
+#endif
+
+       if (addr == 4) {
+               l64111intmask1 = v;
+               return;
        }
+       if (addr == 5) {
+               l64111intmask2 = v;
+               return;
+       }
+
+       l64111regs[addr] = v;
+
+}
+
+static uae_u8 cl450_bget (uaecptr addr)
+{
+       addr &= 0xff;
+       write_log (L"FMV: CL450 byte read access %08x!\n", addr);
+       return 0;
+}
+static uae_u16 cl450_wget (uaecptr addr)
+{
+       addr &= 0xff;
+       addr >>= 1;
+       write_log (L"FMV: CL450 read reg %d\n", addr);
+       return 0;
+}
+static void cl450_bput (uaecptr addr, uae_u8 v)
+{
+       addr &= 0xff;
+       write_log (L"FMV: CL450 byte write access %08x!\n", addr);
+}
+static void cl450_wput (uaecptr addr, uae_u16 v)
+{
+       addr &= 0xff;
+       write_log (L"FMV: CL450 write reg %d = %04x\n", addr, v);
+}
+
+static uae_u8 romram_bget (uaecptr addr)
+{
+#ifdef FMV_DEBUG
+       if (isdebug (addr))
+               write_log (L"romram_bget %08X PC=%08X\n", addr, M68K_GETPC);
+#endif
+       if (addr >= IO_BASE && addr < VRAM_BASE)
+               return 0;
        return rom[addr];
 }
-static void fmv_bput2 (uaecptr addr, uae_u8 v)
+static uae_u16 romram_wget (uaecptr addr)
+{
+#ifdef FMV_DEBUG
+       if (isdebug (addr))
+               write_log (L"romram_wget %08X PC=%08X\n", addr, M68K_GETPC);
+#endif
+       if (addr >= IO_BASE && addr < VRAM_BASE)
+               return 0;
+       return (rom[addr] << 8) | (rom[addr + 1] << 0);
+}
+static void ram_bput (uaecptr addr, uae_u8 v)
 {
-       if (addr >= rom_size && addr < 0x80000) {
-               write_log (L"fmv_bput2 %08X=%02X PC=%8X\n", addr, v & 0xff, M68K_GETPC);
+       if (addr < VRAM_BASE)
+               return;
+       rom[addr] = v;
+       if (isdebug (addr)) {
+               write_log (L"ram_bput %08X=%02X PC=%08X\n", addr, v & 0xff, M68K_GETPC);
+       }
+}
+static void ram_wput (uaecptr addr, uae_u16 v)
+{
+       if (addr < VRAM_BASE)
+               return;
+       rom[addr + 0] = v >> 8;
+       rom[addr + 1] = v >> 0;
+       if (isdebug (addr)) {
+               write_log (L"ram_wput %08X=%04X PC=%08X\n", addr, v & 0xffff, M68K_GETPC);
        }
 }
 
-static uae_u32 REGPARAM2 fmv_lget (uaecptr addr)
+static uae_u32 REGPARAM2 fmv_wget (uaecptr addr)
 {
        uae_u32 v;
-#ifdef JIT
-       special_mem |= S_READ;
-#endif
        addr -= fmv_start & fmv_mask;
        addr &= fmv_mask;
-       v = (fmv_bget2 (addr) << 24) | (fmv_bget2 (addr + 1) << 16) |
-               (fmv_bget2 (addr + 2) << 8) | (fmv_bget2 (addr + 3));
+       int mask = addr & BANK_MASK;
+       if (mask == L64111_BASE)
+               v = l64111_wget (addr);
+       else if (mask == CL450_BASE)
+               v = cl450_wget (addr);
+       else if (mask == IO_BASE)
+               v = io_wget (addr);
+       else
+               v = romram_wget (addr);
+
 #ifdef FMV_DEBUG
-       write_log (L"fmv_lget %08X=%08X PC=%08X\n", addr, v, M68K_GETPC);
+       if (isdebug (addr))
+               write_log (L"fmv_wget %08X=%04X PC=%08X\n", addr, v, M68K_GETPC);
 #endif
        return v;
 }
 
-static uae_u32 REGPARAM2 fmv_wget (uaecptr addr)
+static uae_u32 REGPARAM2 fmv_lget (uaecptr addr)
 {
        uae_u32 v;
-#ifdef JIT
-       special_mem |= S_READ;
-#endif
-       addr -= fmv_start & fmv_mask;
-       addr &= fmv_mask;
-       v = (fmv_bget2 (addr) << 8) | fmv_bget2 (addr + 1);
+       v = (fmv_wget (addr) << 16) | (fmv_wget (addr + 2) << 0);
 #ifdef FMV_DEBUG
-       write_log (L"fmv_wget %08X=%04X PC=%08X\n", addr, v, M68K_GETPC);
+       if (isdebug (addr))
+               write_log (L"fmv_lget %08X=%08X PC=%08X\n", addr, v, M68K_GETPC);
 #endif
        return v;
 }
@@ -107,55 +260,64 @@ static uae_u32 REGPARAM2 fmv_wget (uaecptr addr)
 static uae_u32 REGPARAM2 fmv_bget (uaecptr addr)
 {
        uae_u32 v;
-#ifdef JIT
-       special_mem |= S_READ;
-#endif
        addr -= fmv_start & fmv_mask;
        addr &= fmv_mask;
-       v = fmv_bget2 (addr);
+       int mask = addr & BANK_MASK;
+       if (mask == L64111_BASE)
+               v = l64111_bget (addr);
+       else if (mask == CL450_BASE)
+               v = cl450_bget (addr);
+       else if (mask == IO_BASE)
+               v = io_bget (addr);
+       else
+               v = romram_bget (addr);
        return v;
 }
 
-static void REGPARAM2 fmv_lput (uaecptr addr, uae_u32 l)
+static void REGPARAM2 fmv_wput (uaecptr addr, uae_u32 w)
 {
-#ifdef JIT
-       special_mem |= S_WRITE;
-#endif
        addr -= fmv_start & fmv_mask;
        addr &= fmv_mask;
 #ifdef FMV_DEBUG
-       write_log (L"fmv_lput %08X=%08X PC=%08X\n", addr, l, M68K_GETPC);
+       if (isdebug (addr))
+               write_log (L"fmv_wput %04X=%04X PC=%08X\n", addr, w & 65535, M68K_GETPC);
 #endif
-       fmv_bput2 (addr, l >> 24);
-       fmv_bput2 (addr + 1, l >> 16);
-       fmv_bput2 (addr + 2, l >> 8);
-       fmv_bput2 (addr + 3, l);
+       int mask = addr & BANK_MASK;
+       if (mask == L64111_BASE)
+               l64111_wput (addr, w);
+       else if (mask == CL450_BASE)
+               cl450_wput (addr, w);
+       else if (mask == IO_BASE)
+               io_wput (addr, w);
+       else
+               ram_wput (addr, w);
 }
 
-static void REGPARAM2 fmv_wput (uaecptr addr, uae_u32 w)
+static void REGPARAM2 fmv_lput (uaecptr addr, uae_u32 w)
 {
-#ifdef JIT
-       special_mem |= S_WRITE;
-#endif
-       addr -= fmv_start & fmv_mask;
-       addr &= fmv_mask;
 #ifdef FMV_DEBUG
-       write_log (L"fmv_wput %04X=%04X PC=%08X\n", addr, w & 65535, M68K_GETPC);
+       if (isdebug (addr))
+               write_log (L"fmv_lput %08X=%08X PC=%08X\n", addr, w, M68K_GETPC);
 #endif
-       fmv_bput2 (addr, w >> 8);
-       fmv_bput2 (addr + 1, w);
+       fmv_wput (addr + 0, w >> 16);
+       fmv_wput (addr + 2, w >>  0);
 }
 
 extern addrbank fmv_bank;
 
-static void REGPARAM2 fmv_bput (uaecptr addr, uae_u32 b)
+static void REGPARAM2 fmv_bput (uaecptr addr, uae_u32 w)
 {
-#ifdef JIT
-       special_mem |= S_WRITE;
-#endif
        addr -= fmv_start & fmv_mask;
        addr &= fmv_mask;
-       fmv_bput2 (addr, b);
+       int mask = addr & BANK_MASK;
+       if (mask == L64111_BASE)
+               l64111_bput (addr, w);
+       else if (mask == CL450_BASE)
+               cl450_bput (addr, w);
+       else if (mask == IO_BASE)
+               io_bput (addr, w);
+       else
+               ram_bput (addr, w);
 }
 
 static uae_u32 REGPARAM2 fmv_wgeti (uaecptr addr)
@@ -240,6 +402,5 @@ void cd32_fmv_init (uaecptr start)
        }
        fmv_mask = fmv_size - 1;
        fmv_bank.baseaddr = rom;
-       rom[0x282] = 0;
        map_banks (&fmv_bank, start >> 16, fmv_size >> 16, 0);
 }
index 100153d8026c0125234c22ec20ffc288805e2340..e70bdf450311d81fbf65085bf96116490bc3abfe 100644 (file)
--- a/cdtv.cpp
+++ b/cdtv.cpp
@@ -78,7 +78,7 @@ static volatile int dmac_dma;
 
 static volatile int activate_stch, cdrom_command_done, play_state, play_statewait;
 static volatile int cdrom_sector, cdrom_sectors, cdrom_length, cdrom_offset;
-static volatile int cd_playing, cd_paused, cd_motor, cd_media, cd_error, cd_finished, cd_isready, cd_hunt;
+static volatile int cd_playing, cd_paused, cd_motor, cd_media, cd_error, cd_finished, cd_isready;
 static uae_u32 last_play_pos, last_play_end;
 
 static volatile int cdtv_hsync, dma_finished, cdtv_sectorsize;
@@ -185,8 +185,8 @@ static void cdaudiostop (void)
 static void cdaudiostopfp (void)
 {
        cdaudiostop ();
-       cd_error = 1;
-       cd_audio_status = AUDIO_STATUS_PLAY_ERROR;
+       cd_audio_status = AUDIO_STATUS_NO_STATUS;
+       activate_stch = 1;
 }
 
 static int pause_audio (int pause)
@@ -673,7 +673,7 @@ static void dma_do_thread (void)
                uae_u8 buffer[2352];
                if (!didread || readsector != (cdrom_offset / cdtv_sectorsize)) {
                        readsector = cdrom_offset / cdtv_sectorsize;
-                       if (cdtv_sectorsize == 2336)
+                       if (cdtv_sectorsize != 2048)
                                didread = read_raw (readsector, buffer, cdtv_sectorsize);
                        else
                                didread = sys_command_cd_read (unitnum, buffer, readsector, 1);
@@ -721,20 +721,15 @@ static void *dev_thread (void *p)
                        {
                                int m = ismedia ();
                                if (m < 0) {
-                                       if (!cd_hunt) {
-                                               write_log (L"CDTV: device %d lost\n", unitnum);
-                                               activate_stch = 1;
-                                               cd_hunt = 1;
-                                               cd_media = 0;
-                                       }
+                                       write_log (L"CDTV: device %d lost\n", unitnum);
+                                       activate_stch = 1;
+                                       cd_media = 0;
                                } else if (m != cd_media) {
                                        cd_media = m;
                                        get_toc ();
                                        activate_stch = 1;
                                        if (cd_playing)
                                                cd_error = 1;
-                                       if (!cd_media)
-                                               cd_hunt = 1;
                                }
                                if (cd_media)
                                        get_qcode ();
@@ -956,6 +951,40 @@ static void tp_bput (int addr, uae_u8 v)
 
 static uae_u8 subtransferbuf[SUB_CHANNEL_SIZE];
 
+#define SUBCODE_CYCLES (2 * maxhpos)
+static int subcode_activecnt;
+
+static void subcode_interrupt (uae_u32 v)
+{
+       subcode_activecnt--;
+       if (subcode_activecnt > 0) {
+               if (subcode_activecnt > 1)
+                       subcode_activecnt = 1;
+               return;
+       }
+
+       if (subcodeoffset < -1)
+               return;
+       if (sbcp && scor == 0) {
+               sbcp = 0;
+               // CD+G interrupt didn't read data fast enough, just abort until next packet
+               return;
+       }
+       if (scor < 0) {
+               scor = 0;
+               if (issub ()) {
+                       subcodeoffset = 0;
+               }
+               tp_check_interrupts ();
+       }
+       if (subcodeoffset >= SUB_CHANNEL_SIZE)
+               return;
+       sbcp = 1;
+       tp_check_interrupts ();
+       subcode_activecnt++;
+       event2_newevent2 (SUBCODE_CYCLES, 0, subcode_interrupt);
+}
+
 static uae_u8 tp_bget (int addr)
 {
        uae_u8 v = 0;
@@ -1050,38 +1079,6 @@ void cdtv_getdmadata (uae_u32 *acr)
        *acr = dmac_acr;
 }
 
-static void do_hunt (void)
-{
-       int i;
-       for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-               if (sys_command_ismedia (i, 1) > 0)
-                       break;
-       }
-       if (i == MAX_TOTAL_SCSI_DEVICES) {
-               if (unitnum >= 0 && sys_command_ismedia (unitnum, 1) >= 0)
-                       return;
-               for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-                       if (sys_command_ismedia (i, 1) >= 0)
-                               break;
-               }
-               if (i == MAX_TOTAL_SCSI_DEVICES)
-                       return;
-       }
-       if (unitnum >= 0) {
-               cdaudiostop ();
-               int ou = unitnum;
-               unitnum = -1;
-               sys_command_close (ou);
-       }
-       if (sys_command_open (i) > 0) {
-               struct device_info di = { 0 };
-               sys_command_info (i, &di, 0);
-               unitnum = i;
-               cd_hunt = 0;
-               write_log (L"CDTV: autodetected unit %d ('%s')\n", unitnum, di.label);
-       }
-}
-
 static void checkint (void)
 {
        int irq = 0;
@@ -1143,27 +1140,11 @@ void CDTV_hsync_handler (void)
                tp_check_interrupts ();
        }
 
-       if (sbcp == 0 && subcodeoffset > 0) {
-               sbcp = 1;
-               tp_check_interrupts ();
-       }
-
        if (sten < 0) {
                sten--;
                if (sten < -3)
                        sten = 0;
        }
-       if (scor < 0) {
-               scor--;
-               if (scor <= -2) {
-                       if (issub ()) {
-                               subcodeoffset = 0;
-                               sbcp = 1;
-                       }
-                       scor = 0;
-                       tp_check_interrupts ();
-               }
-       }
 
        static int subchannelcounter;
        if (subchannelcounter > 0)
@@ -1185,6 +1166,8 @@ void CDTV_hsync_handler (void)
                                                subcodebufferoffset -= MAX_SUBCODEBUFFER;
                                        sbcp = 0;
                                        scor = 1;
+                                       subcode_activecnt++;
+                                       event2_newevent2 (SUBCODE_CYCLES, 0, subcode_interrupt);
                                        tp_check_interrupts ();
                                }
                                uae_sem_post (&sub_sem);
@@ -1232,12 +1215,10 @@ void CDTV_hsync_handler (void)
        subqcnt--;
        if (subqcnt < 0) {
                write_comm_pipe_u32 (&requests, 0x0101, 1);
-               if (cd_playing && !cd_hunt)
+               if (cd_playing)
                        subqcnt = 10;
                else
                        subqcnt = 75;
-               if (cd_hunt)
-                       do_hunt ();
        }
 
        if (activate_stch)
@@ -1558,70 +1539,12 @@ static void REGPARAM2 dmac_bput (uaecptr addr, uae_u32 b)
 
 static void open_unit (void)
 {
-       struct device_info di1, *di2;
-       int first = -1;
-       int cdtvunit = -1, audiounit = -1;
-       int opened[MAX_TOTAL_SCSI_DEVICES];
-       int i;
-
-       if (unitnum >= 0)
-               sys_command_close (unitnum);
-       unitnum = -1;
-       cdtv_reset ();
-       if (!device_func_init (0)) {
-               write_log (L"no CDROM support\n");
-               return;
-       }
-       for (unitnum = 0; unitnum < MAX_TOTAL_SCSI_DEVICES; unitnum++) {
-               opened[unitnum] = 0;
-               if (sys_command_open (unitnum)) {
-                       opened[unitnum] = 1;
-                       di2 = sys_command_info (unitnum, &di1, 0);
-                       if (di2 && di2->type == INQ_ROMD) {
-                               write_log (L"%s: ", di2->label);
-                               if (first < 0)
-                                       first = unitnum;
-                               if (get_toc () > 0) {
-                                       if (datatrack) {
-                                               uae_u8 buffer[2048];
-                                               if (sys_command_cd_read (unitnum, buffer, 16, 1)) {
-                                                       if (!memcmp (buffer + 8, "CDTV", 4)) {
-                                                               write_log (L"CDTV\n");
-                                                               if (cdtvunit < 0)
-                                                                       cdtvunit = unitnum;
-                                                       }
-                                               }
-                                       } else {
-                                               write_log (L"Audio CD\n");
-                                               if (audiounit < 0)
-                                                       audiounit = unitnum;
-                                       }
-                               } else {
-                                       write_log (L"TOC read failed\n");
-                               }
-                       }
-               }
-       }
-       unitnum = audiounit;
-       if (cdtvunit >= 0)
-               unitnum = cdtvunit;
-       if (unitnum < 0)
-               unitnum = first;
-       if (unitnum >= 0)
-               opened[unitnum] = 0;
-       for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-               if (opened[i])
-                       sys_command_close (i);
-       }
-       cd_media = 0;
-       if (unitnum >= 0) {
-               cd_media = ismedia () > 0 ? -1 : 0;
-               if (!cd_media)
-                       cd_hunt = 1;
-               if (!get_toc())
-                       cd_media = 0;
-               cdaudiostop ();
-       }
+       struct device_info di;
+       unitnum = get_standard_cd_unit (CD_STANDARD_UNIT_CDTV);
+       sys_command_info (unitnum, &di, 0);
+       write_log (L"using drive %s (unit %d, media %d)\n", di.label, unitnum, di.media_inserted);
+       /* make sure CD audio is not playing */
+       cdaudiostop ();
 }
 
 static void ew (int addr, uae_u32 value)
index 4d6ac5816d8386e334bda995e215877d1a198cef..365d07ba07605e7a7e0dae3b77fe6c4d3e89d7a8 100644 (file)
@@ -179,7 +179,7 @@ static const TCHAR *dongles[] =
        L"rugby coach", L"cricket captain", L"leviathan",
        NULL
 };
-static const TCHAR *cdmodes[] = { L"", L"image", L"ioctl", L"spti", L"aspi", 0 };
+static const TCHAR *cdmodes[] = { L"disabled", L"", L"image", L"ioctl", L"spti", L"aspi", 0 };
 
 static const TCHAR *obsolete[] = {
        L"accuracy", L"gfx_opengl", L"gfx_32bit_blits", L"32bit_blits",
@@ -557,13 +557,13 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        }
 
        for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-               if (p->cdimagefile[i][0] || p->cdimagefileuse[i]) {
+               if (p->cdslots[i].name[0] || p->cdslots[i].inuse) {
                        TCHAR tmp2[MAX_DPATH];
                        _stprintf (tmp, L"cdimage%d", i);
-                       _tcscpy (tmp2, p->cdimagefile[i]);
-                       if (p->cdscsidevicetype[i] != 0 || _tcschr (p->cdimagefile[i], ',')) {
+                       _tcscpy (tmp2, p->cdslots[i].name);
+                       if (p->cdslots[i].type != SCSI_UNIT_DEFAULT || _tcschr (p->cdslots[i].name, ',')) {
                                _tcscat (tmp2, L",");
-                               _tcscat (tmp2, cdmodes[p->cdscsidevicetype[i]]);
+                               _tcscat (tmp2, cdmodes[p->cdslots[i].type + 1]);
                        }
                        cfgfile_write_str (f, tmp, tmp2);
                }
@@ -1144,16 +1144,26 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
                _stprintf (tmp, L"cdimage%d", i);
                if (!_tcsicmp (option, tmp)) {
                        TCHAR *next = _tcsrchr (value, ',');
+                       int type = SCSI_UNIT_DEFAULT;
                        if (next) {
-                               *next = 0;
-                               TCHAR *next2 = _tcschr (next + 1, ':');
+                               *next++ = 0;
+                               TCHAR *next2 = _tcschr (next, ':');
                                if (next2)
                                        *next2 = 0;
-                               cfgfile_intval (option, next + 1, tmp, &p->cdscsidevicetype[i], 1);
+                               int tmpval = 0;
+                               if (cfgfile_intval (option, next, tmp, &type, 1))
+                                       type--;
+                       }
+                       _tcsncpy (p->cdslots[i].name, value, sizeof p->cdslots[i].name);
+                       p->cdslots[i].name[sizeof p->cdslots[i].name - 1] = 0;
+                       p->cdslots[i].inuse = true;
+                       p->cdslots[i].type = type;
+                       // disable all following units
+                       i++;
+                       while (i < MAX_TOTAL_SCSI_DEVICES) {
+                               p->cdslots[i].type = SCSI_UNIT_DISABLED;
+                               i++;
                        }
-                       _tcsncpy (p->cdimagefile[i], value, sizeof p->cdimagefile[i]);
-                       p->cdimagefile[i][sizeof p->cdimagefile[i] - 1] = 0;
-                       p->cdimagefileuse[i] = true;
                        return 1;
                }
        }
index f8211b8806e42bb8c0047eade4ae9513420819bb..b2395ec270e2803653e30bc2c55caa96c5671976 100644 (file)
@@ -61,7 +61,7 @@
 #define SPR0_HPOS 0x15
 #define MAX_SPRITES 8
 #define SPRITE_COLLISIONS
-#define SPEEDUP
+//#define SPEEDUP
 #define AUTOSCALE_SPRITES 1
 
 #define SPRBORDER 0
@@ -1571,10 +1571,12 @@ STATIC_INLINE int one_fetch_cycle_0 (int pos, int ddfstop_to_test, int dma, int
                        finish_final_fetch (pos, fm);
                        return 1;
                }
-               if (plf_state == plf_passed_stop)
+               if (plf_state == plf_passed_stop) {
                        plf_state = plf_passed_stop2;
-               else if (plf_state == plf_passed_stop2)
+               } else if (plf_state == plf_passed_stop2) {
                        plf_state = plf_end;
+               }
+
        }
 
        maybe_check (pos);
@@ -3101,7 +3103,8 @@ STATIC_INLINE uae_u16 VHPOSR (void)
 
 static int test_copper_dangerous (unsigned int address)
 {
-       if ((address & 0x1fe) < ((copcon & 2) ? ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? 0 : 0x40) : 0x80)) {
+       int addr = address & 0x01fe;
+       if (addr < ((copcon & 2) ? ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? 0 : 0x40) : 0x80)) {
                cop_state.state = COP_stop;
                copper_enabled_thisline = 0;
                unset_special (SPCFLAG_COPPER);
index 79c83aab13a80422a867301f29fa196e85c7efb3..7f55bf67ee3aaa0c9e82c2e57fed6222e6f6d8ba 100644 (file)
@@ -1,7 +1,8 @@
 
 #define DEVICE_SCSI_BUFSIZE (65536 - 1024)
 
-#define SCSI_UNIT_NONE 0
+#define SCSI_UNIT_DISABLED -1
+#define SCSI_UNIT_DEFAULT 0
 #define SCSI_UNIT_IMAGE 1
 #define SCSI_UNIT_IOCTL 2
 #define SCSI_UNIT_SPTI 3
@@ -78,6 +79,7 @@ struct device_info {
        TCHAR vendorid[10];
        TCHAR productid[18];
        TCHAR revision[6];
+       TCHAR *backend;
        struct cd_toc_head toc;
 };
 
@@ -115,7 +117,7 @@ typedef uae_u32 (*volume_func)(int, uae_u16, uae_u16);
 typedef int (*qcode_func)(int, uae_u8*, int);
 typedef int (*toc_func)(int, struct cd_toc_head*);
 typedef int (*read_func)(int, uae_u8*, int, int);
-typedef int (*rawread_func)(int, uae_u8*, int, int, int, uae_u16);
+typedef int (*rawread_func)(int, uae_u8*, int, int, int, uae_u32);
 typedef int (*write_func)(int, uae_u8*, int, int);
 typedef int (*isatapi_func)(int);
 typedef int (*ismedia_func)(int, int);
@@ -190,3 +192,8 @@ extern void blkdev_fix_prefs (struct uae_prefs *p);
 extern int isaudiotrack (struct cd_toc_head*, int block);
 extern int isdatatrack (struct cd_toc_head*, int block);
 
+enum cd_standard_unit { CD_STANDARD_UNIT_AUDIO, CD_STANDARD_UNIT_CDTV, CD_STANDARD_UNIT_CD32 };
+
+extern int get_standard_cd_unit (enum cd_standard_unit csu);
+extern void close_standard_cd_unit (int);
+extern void blkdev_cd_change (int unitnum, const TCHAR *name);
index 80479399ce890e61e79f02f2dca8f40955baa7ab..c01197521dfab4a4bda1a074db0f8ab7403eec34 100644 (file)
@@ -69,6 +69,13 @@ struct jport {
 #define TABLET_MOUSEHACK 1
 #define TABLET_REAL 2
 
+struct cdslot
+{
+       TCHAR name[MAX_DPATH];
+       bool inuse;
+       int type;
+};
+
 struct wh {
        int x, y;
        int width, height;
@@ -284,9 +291,7 @@ struct uae_prefs {
        TCHAR sername[256];
        TCHAR amaxromfile[MAX_DPATH];
        TCHAR a2065name[MAX_DPATH];
-       TCHAR cdimagefile[MAX_TOTAL_SCSI_DEVICES][MAX_DPATH];
-       bool cdimagefileuse[MAX_TOTAL_SCSI_DEVICES];
-       int cdscsidevicetype[MAX_TOTAL_SCSI_DEVICES];
+       struct cdslot cdslots[MAX_TOTAL_SCSI_DEVICES];
        TCHAR quitstatefile[MAX_DPATH];
 
        TCHAR path_floppy[256];
index 7d267ce7406d841995838502296b4e9d22638264..17da4f2dfaf70b0b1d555b416b156e2a31611b5f 100644 (file)
@@ -983,6 +983,7 @@ static struct device_info *info_device (int unitnum, struct device_info *di, int
        di->unitnum = unitnum + 1;
        di->removable = sif->removable;
        _tcscpy (di->label, sif->label);
+       di->backend = L"ASPI";
        if (log_scsi) {
                write_log (L"MI=%d TP=%d WP=%d CY=%d BK=%d '%s'\n",
                        di->media_inserted, di->type, di->write_protected, di->cylinders, di->bytespersector, di->label);
index 177da530448f51c08924f29fa04e009e49213372..11ccf0caa6ca3132286034fd9d9617c40e94fd51 100644 (file)
@@ -230,7 +230,7 @@ static int cdda_openwav (struct dev_info_ioctl *ciw)
        wav.wFormatTag = WAVE_FORMAT_PCM;
        mmr = waveOutOpen (&ciw->cdda_wavehandle, WAVE_MAPPER, &wav, 0, 0, WAVE_ALLOWSYNC | WAVE_FORMAT_DIRECT);
        if (mmr != MMSYSERR_NOERROR) {
-               write_log (L"CDDA: wave open %d\n", mmr);
+               write_log (L"IOCTL CDDA: wave open %d\n", mmr);
                cdda_closewav (ciw);
                return 0;
        }
@@ -280,7 +280,7 @@ static void *cdda_play (void *v)
                        whdr[i].lpData = (LPSTR)px[i];
                        mmr = waveOutPrepareHeader (ciw->cdda_wavehandle, &whdr[i], sizeof (WAVEHDR));
                        if (mmr != MMSYSERR_NOERROR) {
-                               write_log (L"CDDA: waveOutPrepareHeader %d:%d\n", i, mmr);
+                               write_log (L"IOCTL CDDA: waveOutPrepareHeader %d:%d\n", i, mmr);
                                goto end;
                        }
                        whdr[i].dwFlags |= WHDR_DONE;
@@ -290,7 +290,7 @@ static void *cdda_play (void *v)
 
                        while (!(whdr[bufnum].dwFlags & WHDR_DONE)) {
                                Sleep (10);
-                               if (!ciw->cdda_play)
+                               if (ciw->cdda_play <= 0)
                                        goto end;
                        }
                        bufon[bufnum] = 0;
@@ -299,7 +299,7 @@ static void *cdda_play (void *v)
                                cdda_pos = ciw->cdda_start;
                                oldplay = ciw->cdda_play;
                                firstloops = 25;
-                               write_log (L"CDDA: playing from %d to %d\n", ciw->cdda_start, ciw->cdda_end);
+                               write_log (L"IOCTL CDDA: playing from %d to %d\n", ciw->cdda_start, ciw->cdda_end);
                                ciw->subcodevalid = false;
                                while (ciw->cdda_paused && ciw->cdda_play > 0)
                                        Sleep (10);
@@ -375,7 +375,7 @@ static void *cdda_play (void *v)
                                bufon[bufnum] = 1;
                                mmr = waveOutWrite (ciw->cdda_wavehandle, &whdr[bufnum], sizeof (WAVEHDR));
                                if (mmr != MMSYSERR_NOERROR) {
-                                       write_log (L"CDDA: waveOutWrite %d\n", mmr);
+                                       write_log (L"IOCTL CDDA: waveOutWrite %d\n", mmr);
                                        break;
                                }
 
@@ -421,7 +421,7 @@ end:
        cdda_closewav (ciw);
        VirtualFree (p, 0, MEM_RELEASE);
        ciw->cdda_play = 0;
-       write_log (L"CDDA: thread killed\n");
+       write_log (L"IOCTL CDDA: thread killed\n");
        return NULL;
 }
 
@@ -488,7 +488,7 @@ static int ioctl_command_play (int unitnum, int startlsn, int endlsn, int scan,
        ciw->cdda_subfunc = subfunc;
        ciw->cdda_scan = scan > 0 ? 10 : (scan < 0 ? 10 : 0);
        if (!ciw->cdda_play) {
-               uae_start_thread (L"cdda_play", cdda_play, ciw, NULL);
+               uae_start_thread (L"cdimage_cdda_play", cdda_play, ciw, NULL);
        }
        ciw->cdda_start = startlsn;
        ciw->cdda_end = endlsn;
@@ -498,7 +498,7 @@ static int ioctl_command_play (int unitnum, int startlsn, int endlsn, int scan,
        return 1;
 }
 
-static void sub_deinterleave (uae_u8 *s, uae_u8 *d)
+static void sub_deinterleave (const uae_u8 *s, uae_u8 *d)
 {
        for (int i = 0; i < 8 * 12; i ++) {
                int dmask = 0x80;
@@ -689,7 +689,7 @@ static void sub_to_deinterleaved (const uae_u8 *s, uae_u8 *d)
        }
 }
 
-static int ioctl_command_rawread (int unitnum, uae_u8 *data, int sector, int size, int sectorsize, uae_u16 extra)
+static int ioctl_command_rawread (int unitnum, uae_u8 *data, int sector, int size, int sectorsize, uae_u32 extra)
 {
        struct dev_info_ioctl *ciw = unitisopen (unitnum);
        if (!ciw)
@@ -720,7 +720,8 @@ static int ioctl_command_rawread (int unitnum, uae_u8 *data, int sector, int siz
                if (!DeviceIoControl (ciw->h, IOCTL_CDROM_RAW_READ, &rri, sizeof rri,
                        p, IOCTL_DATA_BUFFER, &len, NULL)) {
                                DWORD err = GetLastError ();
-                               write_log (L"IOCTL rawread unit=%d sector=%d blocksize=%d, ERR=%d\n", unitnum, sector, sectorsize, err);
+                               write_log (L"IOCTL rawread unit=%d sector=%d blocksize=%d mode=%d, ERR=%d\n",
+                                       unitnum, sector, sectorsize, rri.TrackMode, err);
                }
                reseterrormode (ciw);
                if (data) {
@@ -733,6 +734,7 @@ static int ioctl_command_rawread (int unitnum, uae_u8 *data, int sector, int siz
                }
                ciw->cd_last_pos = sector;
        } else {
+               uae_u8 sectortype = extra >> 16;
                uae_u8 cmd9 = extra >> 8;
                int sync = (cmd9 >> 7) & 1;
                int headercodes = (cmd9 >> 5) & 3;
@@ -748,6 +750,9 @@ static int ioctl_command_rawread (int unitnum, uae_u8 *data, int sector, int siz
 
                if (isaudiotrack (&ciw->di.toc, sector)) {
 
+                       if (sectortype != 0 && sectortype != 1)
+                               return -2;
+
                        for (int i = 0; i < size; i++) {
                                uae_u8 *odata = data;
                                int blocksize = errorfield == 0 ? 2352 : (errorfield == 1 ? 2352 + 294 : 2352 + 296);
@@ -760,7 +765,8 @@ static int ioctl_command_rawread (int unitnum, uae_u8 *data, int sector, int siz
                                memset (p, 0, blocksize);
                                if (!DeviceIoControl (ciw->h, IOCTL_CDROM_RAW_READ, &rri, sizeof rri, p, IOCTL_DATA_BUFFER, &len, NULL)) {
                                        DWORD err = GetLastError ();
-                                       write_log (L"IOCTL rawread unit=%d sector=%d blocksize=%d, ERR=%d\n", unitnum, sector, sectorsize, err);
+                                       write_log (L"IOCTL rawread unit=%d sector=%d blocksize=%d mode=%d, ERR=%d\n",
+                                               unitnum, sector, sectorsize, rri.TrackMode, err);
                                        if (err) {
                                                reseterrormode (ciw);
                                                return ret;
@@ -1006,6 +1012,13 @@ static void update_device_info (int unitnum)
        di->type = ciw->type == DRIVE_CDROM ? INQ_ROMD : INQ_DASD;
        di->unitnum = unitnum + 1;
        _tcscpy (di->label, ciw->drvlettername);
+       di->backend = L"IOCTL";
+}
+
+static void trim (TCHAR *s)
+{
+       while (_tcslen (s) > 0 && s[_tcslen (s) - 1] == ' ')
+               s[_tcslen (s) - 1] = 0;
 }
 
 /* open device level access to cd rom drive */
@@ -1021,6 +1034,7 @@ static int sys_cddev_open (struct dev_info_ioctl *ciw, int unitnum)
                write_log (L"IOCTL: failed to allocate buffer");
                return 1;
        }
+
        _tcscpy (ciw->di.vendorid, L"UAE");
        _stprintf (ciw->di.productid, L"SCSI CD%d IMG", unitnum);
        _tcscpy (ciw->di.revision, L"0.1");
@@ -1030,20 +1044,24 @@ static int sys_cddev_open (struct dev_info_ioctl *ciw, int unitnum)
                memcpy (tmp, inquiry + 8, 8);
                tmp[8] = 0;
                s = au (tmp);
+               trim (s);
                _tcscpy (ciw->di.vendorid, s);
                xfree (s);
                memcpy (tmp, inquiry + 16, 16);
                tmp[16] = 0;
                s = au (tmp);
+               trim (s);
                _tcscpy (ciw->di.productid, s);
                xfree (s);
                memcpy (tmp, inquiry + 32, 4);
                tmp[4] = 0;
                s = au (tmp);
+               trim (s);
                _tcscpy (ciw->di.revision, s);
                xfree (s);
                close_createfile (ciw);
        }
+
        if (!open_createfile (ciw, 0)) {
                write_log (L"IOCTL: failed to open '%s', err=%d\n", ciw->devname, GetLastError ());
                goto error;
@@ -1084,7 +1102,7 @@ static void sys_cddev_close (struct dev_info_ioctl *ciw, int unitnum)
 static int open_device (int unitnum, const TCHAR *ident)
 {
        struct dev_info_ioctl *ciw = NULL;
-       if (ident) {
+       if (ident && ident[0]) {
                for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
                        ciw = &ciw32[i];
                        if (unittable[i] == 0 && ciw->drvletter != 0) {
@@ -1110,6 +1128,7 @@ static int open_device (int unitnum, const TCHAR *ident)
        if (sys_cddev_open (ciw, unitnum) == 0)
                return 1;
        unittable[unitnum] = 0;
+       blkdev_cd_change (unitnum, ciw->drvlettername);
        return 0;
 }
 static void close_device (int unitnum)
@@ -1118,6 +1137,7 @@ static void close_device (int unitnum)
        if (!ciw)
                return;
        sys_cddev_close (ciw, unitnum);
+       blkdev_cd_change (unitnum, ciw->drvlettername);
        unittable[unitnum] = 0;
 }
 
@@ -1216,9 +1236,7 @@ void win32_ioctl_media_change (TCHAR driveletter, int insert)
                        if (unitnum >= 0) {
                                update_device_info (unitnum);
                                scsi_do_disk_change (unitnum, insert, NULL);
-#ifdef RETROPLATFORM
-                               rp_cd_image_change (unitnum, ciw->drvlettername);
-#endif
+                               blkdev_cd_change (unitnum, ciw->drvlettername);
                        }
                }
        }
index d18999b4ee0f28fb3848ef6b0ebfafd855083632..201e1d804ffe8012c91d1ee924f78220ea92ba8a 100644 (file)
@@ -306,6 +306,7 @@ static void close_scsi_device (int unitnum)
        if (!di)
                return;
        close_scsi_device2 (di);
+       blkdev_cd_change (unitnum, di->drvletter ? di->drvlettername : di->name);
        unittable[unitnum] = 0;
 }
 
@@ -413,6 +414,7 @@ static void update_device_info (int unitnum)
        mediacheck_full (dispti, unitnum, di);
        di->type = dispti->type;
        di->unitnum = unitnum + 1;
+       di->backend = L"SPTI";
        if (log_scsi) {
                write_log (L"MI=%d TP=%d WP=%d CY=%d BK=%d RMB=%d '%s'\n",
                        di->media_inserted, di->type, di->write_protected, di->cylinders, di->bytespersector, di->removable, di->label);
@@ -526,6 +528,7 @@ static int open_scsi_device2 (struct dev_info_spti *di, int unitnum)
                xfree (dev);
                update_device_info (unitnum);
                di->open = true;
+               blkdev_cd_change (unitnum, di->drvletter ? di->drvlettername : di->name);
                return 1;
        }
        xfree (dev);
@@ -534,7 +537,7 @@ static int open_scsi_device2 (struct dev_info_spti *di, int unitnum)
 int open_scsi_device (int unitnum, const TCHAR *ident)
 {
        struct dev_info_spti *di = NULL;
-       if (ident) {
+       if (ident && ident[0]) {
                for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
                        di = &dev_info[i];
                        if (unittable[i] == 0 && di->drvletter != 0) {
@@ -651,9 +654,7 @@ void win32_spti_media_change (TCHAR driveletter, int insert)
                        if (unitnum >= 0) {
                                update_device_info (unitnum);
                                scsi_do_disk_change (unitnum, insert, NULL);
-#ifdef RETROPLATFORM
-                               rp_cd_image_change (unitnum, di->drvletter ? di->drvlettername : di->name);
-#endif
+                               blkdev_cd_change (unitnum, di->drvletter ? di->drvlettername : di->name);
                        }
                }
        }
index 1457b0f0f2b76a45827273e79f768fd3743490b7..865306d4ac19474b933deb5e32a1add02a0bf5c2 100644 (file)
@@ -194,9 +194,8 @@ static int port_insert (int num, const TCHAR *name)
 
 static int cd_insert (int num, const TCHAR *name)
 {
-       if (num != 0)
-               return 0;
-       _tcscpy (changed_prefs.cdimagefile[0], name);
+       _tcscpy (changed_prefs.cdslots[num].name, name);
+       changed_prefs.cdslots[num].inuse = true;
        config_changed = 1;
        return 1;
 }
@@ -835,18 +834,14 @@ void rp_fixup_options (struct uae_prefs *p)
        }
 
        for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-               int v = sys_command_ismedia (i, 1);
-               if (v >= 0)
+               if (p->cdslots[i].inuse)
                        cd_mask |= 1 << i;
        }
        RPSendMessagex (RPIPCGM_DEVICES, RP_DEVICE_CD, cd_mask, NULL, 0, &guestinfo, NULL);
        if (cd_mask) {
                for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-                       if ((1 << i) & cd_mask) {
-                               struct device_info di = { 0 };
-                               if (sys_command_info (i, &di, 0))
-                                       rp_cd_image_change (i, di.mediapath);
-                       }
+                       if (p->cdslots[i].inuse)
+                               rp_cd_image_change (i, p->cdslots[i].name);
                }
        }
 
index 11b16e85ec33712fde9421d9b80582d49c4897c2..bb590b1a4bb6cefd2d33f4b0fa00e6798d75aaac 100644 (file)
@@ -3883,32 +3883,45 @@ static void getstartpaths (void)
                posn[1] = 0;
 
        if (path_type < 0 && start_data == 0 && key) {
-               if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, tmp))) {
-                       // installed in Program Files?
-                       if (_tcsnicmp (tmp, start_path_exe, _tcslen (tmp)) == 0) {
-                               if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, tmp))) {
-                                       fixtrailing (tmp);
-                                       _tcscpy (tmp2, tmp);
-                                       _tcscat (tmp2, L"Amiga Files");
-                                       CreateDirectory (tmp2, NULL);
-                                       _tcscat (tmp2, L"\\WinUAE");
-                                       CreateDirectory (tmp2, NULL);
-                                       v = GetFileAttributes (tmp2);
-                                       if (v != INVALID_FILE_ATTRIBUTES && (v & FILE_ATTRIBUTE_DIRECTORY)) {
-                                               _tcscat (tmp2, L"\\");
-                                               path_type = PATH_TYPE_NEWWINUAE;
-                                               _tcscpy (tmp, tmp2);
-                                               _tcscat (tmp, L"Configurations");
-                                               CreateDirectory (tmp, NULL);
-                                               _tcscpy (tmp, tmp2);
-                                               _tcscat (tmp, L"Screenshots");
-                                               CreateDirectory (tmp, NULL);
-                                               _tcscpy (tmp, tmp2);
-                                               _tcscat (tmp, L"Savestates");
-                                               CreateDirectory (tmp, NULL);
-                                               _tcscpy (tmp, tmp2);
-                                               _tcscat (tmp, L"Screenshots");
-                                               CreateDirectory (tmp, NULL);
+               bool ispath = false;
+               _tcscpy (tmp2, start_path_exe);
+               _tcscat (tmp2, L"configurations\\configuration.cache");
+               v = GetFileAttributes (tmp2);
+               if (v != INVALID_FILE_ATTRIBUTES && !(v & FILE_ATTRIBUTE_DIRECTORY))
+                       ispath = true;
+               _tcscpy (tmp2, start_path_exe);
+               _tcscat (tmp2, L"roms");
+               v = GetFileAttributes (tmp2);
+               if (v != INVALID_FILE_ATTRIBUTES && (v & FILE_ATTRIBUTE_DIRECTORY))
+                       ispath = true;
+               if (!ispath) {
+                       if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, tmp))) {
+                               // installed in Program Files?
+                               if (_tcsnicmp (tmp, start_path_exe, _tcslen (tmp)) == 0) {
+                                       if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, tmp))) {
+                                               fixtrailing (tmp);
+                                               _tcscpy (tmp2, tmp);
+                                               _tcscat (tmp2, L"Amiga Files");
+                                               CreateDirectory (tmp2, NULL);
+                                               _tcscat (tmp2, L"\\WinUAE");
+                                               CreateDirectory (tmp2, NULL);
+                                               v = GetFileAttributes (tmp2);
+                                               if (v != INVALID_FILE_ATTRIBUTES && (v & FILE_ATTRIBUTE_DIRECTORY)) {
+                                                       _tcscat (tmp2, L"\\");
+                                                       path_type = PATH_TYPE_NEWWINUAE;
+                                                       _tcscpy (tmp, tmp2);
+                                                       _tcscat (tmp, L"Configurations");
+                                                       CreateDirectory (tmp, NULL);
+                                                       _tcscpy (tmp, tmp2);
+                                                       _tcscat (tmp, L"Screenshots");
+                                                       CreateDirectory (tmp, NULL);
+                                                       _tcscpy (tmp, tmp2);
+                                                       _tcscat (tmp, L"Savestates");
+                                                       CreateDirectory (tmp, NULL);
+                                                       _tcscpy (tmp, tmp2);
+                                                       _tcscat (tmp, L"Screenshots");
+                                                       CreateDirectory (tmp, NULL);
+                                               }
                                        }
                                }
                        }
index a999f03602ef42d07594242c2ce8cd1986db2365..d5f7c0ff03bd3852a07ab5823bb8560d25a26156 100644 (file)
@@ -19,7 +19,7 @@
 #define LANG_DLL 1
 
 #define WINUAEBETA L"4"
-#define WINUAEDATE MAKEBD(2010, 7, 18)
+#define WINUAEDATE MAKEBD(2010, 7, 20)
 #define WINUAEEXTRA L""
 #define WINUAEREV L""
 
index 8b7b0b5c89b0bda0a653084063275845ab060a9d..946c79d246598c23e8195b1ca65701358744ec00 100644 (file)
@@ -95,7 +95,7 @@
 #define USS_FORMAT_STRING_SAVE L"(*.uss)\0*.uss\0"
 #define HDF_FORMAT_STRING L"(*.hdf;*.vhd;*.rdf;*.hdz;*.rdz)\0*.hdf;*.vhd;*.rdf;*.hdz;*.rdz\0"
 #define INP_FORMAT_STRING L"(*.inp)\0*.inp\0"
-#define  CD_FORMAT_STRING L"(*.cue;*.ccd;*.iso)\0*.cue;*.ccd;*.iso;" ARCHIVE_STRING L"\0"
+#define  CD_FORMAT_STRING L"(*.cue;*.ccd;*.mds;*.iso)\0*.cue;*.ccd;*.mds;*.iso;" ARCHIVE_STRING L"\0"
 #define CONFIG_HOST L"Host"
 #define CONFIG_HARDWARE L"Hardware"
 
@@ -1922,15 +1922,15 @@ static UINT_PTR CALLBACK ofnhook (HWND hDlg, UINT message, WPARAM wParam, LPARAM
 
 static void eject_cd (void)
 {
-       workprefs.cdimagefile[0][0] = 0;
+       workprefs.cdslots[0].name[0] = 0;
        quickstart_cddrive[0] = 0;
-       workprefs.cdimagefileuse[0] = false;
+       workprefs.cdslots[0].inuse = false;
        if (full_property_sheet) {
                quickstart_cdtype = 0;
        } else {
                if (quickstart_cdtype > 0) {
                        quickstart_cdtype = 1;
-                       workprefs.cdimagefileuse[0] = true;
+                       workprefs.cdslots[0].inuse = true;
                }
        }
 }
@@ -1949,7 +1949,7 @@ static void selectcd (struct uae_prefs *prefs, HWND hDlg, int num, int id, TCHAR
        SetDlgItemText (hDlg, id, full_path);
        if (quickstart_cddrive[0])
                eject_cd ();
-       _tcscpy (prefs->cdimagefile[0], full_path);
+       _tcscpy (prefs->cdslots[0].name, full_path);
        DISK_history_add (full_path, -1, HISTORY_CD, 0);
 }
 
@@ -4810,8 +4810,8 @@ static void init_quickstartdlg (HWND hDlg)
                        workprefs.df[1][0] = 0;
                        workprefs.df[2][0] = 0;
                        workprefs.df[3][0] = 0;
-                       workprefs.cdimagefile[0][0] = 0;
-                       workprefs.cdimagefileuse[0] = quickstart_cdtype > 0;
+                       workprefs.cdslots[0].name[0] = 0;
+                       workprefs.cdslots[0].inuse = quickstart_cdtype > 0;
                        load_quickstart (hDlg, 1);
                        quickstarthost (hDlg, hostconf);
                }
@@ -5054,12 +5054,12 @@ static INT_PTR CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, L
                                                int len = sizeof quickstart_cddrive / sizeof (TCHAR);
                                                quickstart_cdtype = 2;
                                                SendDlgItemMessage (hDlg, IDC_CD0Q_TYPE, WM_GETTEXT, (WPARAM)len, (LPARAM)quickstart_cddrive);
-                                               _tcscpy (workprefs.cdimagefile[0], quickstart_cddrive);
+                                               _tcscpy (workprefs.cdslots[0].name, quickstart_cddrive);
                                        } else {
                                                eject_cd ();
                                                quickstart_cdtype = val;
                                        }
-                                       workprefs.cdimagefileuse[0] = quickstart_cdtype > 0;
+                                       workprefs.cdslots[0].inuse = quickstart_cdtype > 0;
                                        addfloppytype (hDlg, 1);
                                        addfloppyhistory (hDlg);
                                }
@@ -9102,7 +9102,7 @@ static void harddiskdlg_button (HWND hDlg, WPARAM wParam)
        case IDC_CD_SELECT:
                DiskSelection (hDlg, wParam, 17, &workprefs, NULL);
                quickstart_cdtype = 1;
-               workprefs.cdimagefileuse[0] = true;
+               workprefs.cdslots[0].inuse = true;
                addcdtype (hDlg, IDC_CD_TYPE);
                break;
        case IDC_CD_EJECT:
@@ -9278,7 +9278,7 @@ static INT_PTR CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
                        case IDC_CD_TEXT:
                        getfloppyname (hDlg, 0, 1, IDC_CD_TEXT);
                        quickstart_cdtype = 1;
-                       workprefs.cdimagefileuse[0] = true;
+                       workprefs.cdslots[0].inuse = true;
                        addcdtype (hDlg, IDC_CD_TYPE);
                        addfloppyhistory_2 (hDlg, 0, IDC_CD_TEXT, HISTORY_CD);
                        break;
@@ -9289,14 +9289,14 @@ static INT_PTR CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
                                if (quickstart_cdtype >= 2) {
                                        int len = sizeof quickstart_cddrive / sizeof (TCHAR);
                                        quickstart_cdtype = 2;
-                                       workprefs.cdimagefileuse[0] = true;
+                                       workprefs.cdslots[0].inuse = true;
                                        SendDlgItemMessage (hDlg, IDC_CD_TYPE, WM_GETTEXT, (WPARAM)len, (LPARAM)quickstart_cddrive);
-                                       _tcscpy (workprefs.cdimagefile[0], quickstart_cddrive);
+                                       _tcscpy (workprefs.cdslots[0].name, quickstart_cddrive);
                                } else {
                                        eject_cd ();
                                        quickstart_cdtype = val;
                                        if (val > 0)
-                                               workprefs.cdimagefileuse[0] = true;
+                                               workprefs.cdslots[0].inuse = true;
 
                                }
                                addcdtype (hDlg, IDC_CD_TYPE);
@@ -9401,7 +9401,7 @@ static void addfloppyhistory_2 (HWND hDlg, int n, int f_text, int type)
        SendDlgItemMessage (hDlg, f_text, CB_RESETCONTENT, 0, 0);
        if (type == HISTORY_CD) {
                nn = 1;
-               text = workprefs.cdimagefile[0];
+               text = workprefs.cdslots[0].name;
        } else {
                nn = workprefs.dfxtype[n] + 1;
                text = workprefs.df[n];
@@ -9483,7 +9483,7 @@ static void addcdtype (HWND hDlg, int id)
        SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)tmp);
        int cdtype = quickstart_cdtype;
        if (currentpage != QUICKSTART_ID) {
-               if (full_property_sheet && !workprefs.cdimagefileuse[0] && !workprefs.cdimagefile[0][0])
+               if (full_property_sheet && !workprefs.cdslots[0].inuse && !workprefs.cdslots[0].name[0])
                        cdtype = 0;
        }
        int cnt = 2;
@@ -9495,7 +9495,7 @@ static void addcdtype (HWND hDlg, int id)
                        SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)vol);
                        if (!_tcsicmp (vol, quickstart_cddrive)) {
                                cdtype = quickstart_cdtype = cnt;
-                               _tcscpy (workprefs.cdimagefile[0], vol);
+                               _tcscpy (workprefs.cdslots[0].name, vol);
                        }
                        cnt++;
                }
@@ -9541,7 +9541,7 @@ static void addfloppytype (HWND hDlg, int n)
                        SetWindowText (GetDlgItem (hDlg, f_enable), tmp);
                        addcdtype (hDlg, IDC_CD0Q_TYPE);
                        hide (hDlg, IDC_CD0Q_TYPE, 0);
-                       text = workprefs.cdimagefile[0];
+                       text = workprefs.cdslots[0].name;
                        regsetstr (NULL, L"QuickStartCDDrive", quickstart_cdtype >= 2 ? quickstart_cddrive : L"");
                        regsetint (NULL, L"QuickStartCDType", quickstart_cdtype >= 2 ? 2 : quickstart_cdtype);
                } else {
@@ -9671,7 +9671,7 @@ static void getfloppyname (HWND hDlg, int n, int cd, int f_text)
                } else {
                        if (quickstart_cddrive[0])
                                eject_cd ();
-                       _tcscpy (workprefs.cdimagefile[0], tmp);
+                       _tcscpy (workprefs.cdslots[0].name, tmp);
                }
        }
 }
@@ -13623,7 +13623,7 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int currentpage)
                        ret = 1;
                        break;
                case ZFILE_CDIMAGE:
-                       _tcscpy (workprefs.cdimagefile[0], file);
+                       _tcscpy (workprefs.cdslots[0].name, file);
                        break;
                default:
                        if (currentpage < 0 && !full_property_sheet) {
index 89133feca32d978c1d7cc19dc85a486f5302060c..b1c5bdea7ff75e40afaee215647289ff4c593b7c 100644 (file)
@@ -874,7 +874,7 @@ int save_state (const TCHAR *filename, const TCHAR *description)
                }
        }
 
-       for (i = 0; i < 10; i++) {
+       for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
                dst = save_cd (i, &len);
                if (dst) {
                        _stprintf (name, L"CDU%d", i);
index 9938a0a5687fa557e7f07f37214076d154c82c47..7b948a284c5468b0c58f5900fbc23f429b24211c 100644 (file)
@@ -1073,7 +1073,7 @@ static void dev_reset (void)
                                dev->aunit = unitnum;
                                unitnum++;
                        }
-                       write_log (L"%s:%d = '%s'\n", UAEDEV_SCSI, dev->aunit, dev->di.label);
+                       write_log (L"%s:%d = %s:'%s'\n", UAEDEV_SCSI, dev->aunit, dev->di.backend, dev->di.label);
                }
                dev->di.label[0] = 0;
        }
index 0d9c333635d6797596a6aeefb6c9d6bf09293d2d..40cbac0db535bf6c0e40f18bcb858c65468fdcb9 100644 (file)
@@ -437,6 +437,7 @@ struct zfile *archive_access_zip (struct znode *zn, int flags)
        s = NULL;
        if (unzOpenCurrentFile (uz) != UNZ_OK)
                return 0;
+//     write_log (L"unpacking %s\n", zn->fullname);
        z = zfile_fopen_empty (NULL, zn->fullname, zn->size);
        if (z) {
 //             if (flags & FILE_PEEK)