]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2300b6
authorToni Wilen <twilen@winuae.net>
Sat, 24 Jul 2010 12:20:08 +0000 (15:20 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 24 Jul 2010 12:20:08 +0000 (15:20 +0300)
20 files changed:
a2065.cpp
audio.cpp
blkdev.cpp
blkdev_cdimage.cpp
disk.cpp
include/blkdev.h
include/zarchive.h
include/zfile.h
od-win32/blkdev_win32_ioctl.cpp
od-win32/mp3decoder.cpp
od-win32/mp3decoder.h
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32_uaenet.cpp
od-win32/win32_uaenet.h
od-win32/win32gui.cpp
od-win32/winuaechangelog.txt
sana2.cpp
zfile.cpp
zfile_archive.cpp

index 1d4c4fbe352d7cf1f53a1d65616b9efad74da14a..c445f8e812a610ba3c7a7212b80490c8f172a77f 100644 (file)
--- a/a2065.cpp
+++ b/a2065.cpp
@@ -225,7 +225,7 @@ static int mungepacket (uae_u8 *packet, int len)
        return ret;
 }
 
-static int getfunc (struct devstruct *dev, uae_u8 *d, int *len)
+static int getfunc (struct s2devstruct *dev, uae_u8 *d, int *len)
 {
        int tlen;
 
@@ -249,7 +249,7 @@ static int mcfilter (const uae_u8 *data)
        return 1; // just allow everything
 }
 
-static void gotfunc (struct devstruct *dev, const uae_u8 *data2, int len)
+static void gotfunc (struct s2devstruct *dev, const uae_u8 *data2, int len)
 {
        int i;
        int size, insize, first;
index abb32ca8c67fc82a3fa94be4ee50a0ff3da8ad57..ecf240699d0a450e0655232094865174e5416f02 100644 (file)
--- a/audio.cpp
+++ b/audio.cpp
@@ -64,7 +64,7 @@ static bool debugchannel (int ch)
 
 STATIC_INLINE bool usehacks (void)
 {
-       return currprefs.cpu_model >= 68020 || currprefs.m68k_speed != -1;
+       return currprefs.cpu_model >= 68020 || currprefs.m68k_speed != 0;
 }
 
 #define SINC_QUEUE_MAX_AGE 2048
index 545359db736b22fba2016d1217cf688e5747f83d..de1634979bceba623a9b28526a1bdf39a283084b 100644 (file)
@@ -24,6 +24,7 @@ static int scsiemu[MAX_TOTAL_SCSI_DEVICES];
 
 static struct device_functions *device_func[MAX_TOTAL_SCSI_DEVICES];
 static int openlist[MAX_TOTAL_SCSI_DEVICES];
+static int waspaused[MAX_TOTAL_SCSI_DEVICES];
 
 /* convert minutes, seconds and frames -> logical sector number */
 int msf2lsn (int msf)
@@ -316,12 +317,14 @@ int sys_command_isopen (int unitnum)
 
 int sys_command_open (int unitnum)
 {
+       waspaused[unitnum] = 0;
        return sys_command_open_internal (unitnum, currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : NULL);
 }
 
 
 void sys_command_close (int unitnum)
 {
+       waspaused[unitnum] = 0;
        if (openlist[unitnum] <= 0)
                write_log (L"BUG unit %d close: opencnt=%d!\n", unitnum, openlist[unitnum]);
        if (device_func[unitnum]) {
@@ -353,6 +356,32 @@ int device_func_init (int flags)
        return 1;
 }
 
+void blkdev_entergui (void)
+{
+       for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
+               waspaused[i] = 0;
+               struct device_info di;
+               if (sys_command_info (i, &di, 1)) {
+                       if (sys_command_cd_pause (i, 1) == 0)
+                               waspaused[i] = 1;
+               }
+       }
+}
+void blkdev_exitgui (void)
+{
+       for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
+               if (waspaused[i]) {
+                       struct device_info di;
+                       if (sys_command_info (i, &di, 1)) {
+                               sys_command_cd_pause (i, 0);
+                       }
+               }
+               waspaused[i] = 0;
+       }
+}
+
+
+
 static TCHAR newimagefiles[MAX_TOTAL_SCSI_DEVICES][256];
 static int imagechangetime[MAX_TOTAL_SCSI_DEVICES];
 static bool cdimagefileinuse[MAX_TOTAL_SCSI_DEVICES], wasopen[MAX_TOTAL_SCSI_DEVICES];
@@ -656,6 +685,8 @@ int sys_command_ismedia (int unitnum, int quick)
 
 struct device_info *sys_command_info (int unitnum, struct device_info *di, int quick)
 {
+       if (failunit (unitnum))
+               return NULL;
        return device_func[unitnum]->info (unitnum, di, quick);
 }
 
@@ -1466,7 +1497,7 @@ static int execscsicmd_direct (int unitnum, struct amigascsi *as)
 
        as->status = scsi_emulate (unitnum, cmd, as->cmd_len, scsi_datap, &datalen, replydata, &replylen, as->sensedata, &senselen);
 
-       as->cmdactual = as->status == 0 ? 0 : as->cmd_len; /* fake scsi_CmdActual */
+       as->cmdactual = as->status != 0 ? 0 : as->cmd_len; /* fake scsi_CmdActual */
        if (as->status) {
                io_error = 45; /* HFERR_BadStatus */
                as->sense_len = senselen;
@@ -1584,3 +1615,4 @@ uae_u8 *restore_cd (int num, uae_u8 *src)
 }
 
 #endif
+
index 4ef7d456184ec4c319f89b2652745dea2c0fba89..30f80f90a1b1f65993a3f4d20d484808dc4a8254 100644 (file)
@@ -84,7 +84,6 @@ struct cdunit {
        play_subchannel_callback cdda_subfunc;
 
        int imagechange;
-       int donotmountme;
        TCHAR newfile[MAX_DPATH];
        uae_sem_t sub_sem;
        struct device_info di;
@@ -93,6 +92,9 @@ struct cdunit {
 static struct cdunit cdunits[MAX_TOTAL_SCSI_DEVICES];
 static int bus_open;
 
+static volatile int cdimage_unpack_thread, cdimage_unpack_active;
+static smp_comm_pipe unpack_pipe;
+
 static struct cdunit *unitisopen (int unitnum)
 {
        struct cdunit *cdu = &cdunits[unitnum];
@@ -194,10 +196,7 @@ static void flac_get_size (struct cdtoc *t)
 }
 static uae_u8 *flac_get_data (struct cdtoc *t)
 {
-       if (t->data)
-               return t->data;
        write_log (L"FLAC: unpacking '%s'..\n", zfile_getname (t->handle));
-       t->data = xcalloc (uae_u8,t->filesize + 2352);
        t->writeoffset = 0;
        FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new ();
        if (decoder) {
@@ -340,6 +339,51 @@ static void dosub (struct cdunit *cdu, struct cdtoc *t, int sector)
        cdu->cdda_subfunc (d, 1);
 }
 
+
+static void *cdda_unpack_func (void *v)
+{
+       cdimage_unpack_thread = 1;
+       mp3decoder *mp3dec = NULL;
+
+       for (;;) {
+               uae_u32 cduidx = read_comm_pipe_u32_blocking (&unpack_pipe);
+               if (cdimage_unpack_thread == 0)
+                       break;
+               uae_u32 tocidx = read_comm_pipe_u32_blocking (&unpack_pipe);
+               struct cdunit *cdu = &cdunits[cduidx];
+               struct cdtoc *t = &cdu->toc[tocidx];
+               if (t->handle) {
+                       // force unpack if handle points to delayed zipped file
+                       uae_s64 pos = zfile_ftell (t->handle);
+                       zfile_fseek (t->handle, -1, SEEK_END);
+                       uae_u8 b;
+                       zfile_fread (&b, 1, 1, t->handle);
+                       zfile_fseek (t->handle, pos, SEEK_SET);
+                       if (!t->data && (t->enctype == AUDENC_MP3 || t->enctype == AUDENC_FLAC)) {
+                               t->data = xcalloc (uae_u8, t->filesize + 2352);
+                               cdimage_unpack_active = 1;
+                               if (t->data) {
+                                       if (t->enctype == AUDENC_MP3) {
+                                               if (!mp3dec) {
+                                                       try {
+                                                               mp3dec = new mp3decoder();
+                                                       } catch (exception) { };
+                                               }
+                                               if (mp3dec)
+                                                       t->data = mp3dec->get (t->handle, t->data, t->filesize);
+                                       } else if (t->enctype == AUDENC_FLAC) {
+                                               flac_get_data (t);
+                                       }
+                               }
+                       }
+               }
+               cdimage_unpack_active = 2;
+       }
+       delete mp3dec;
+       cdimage_unpack_thread = -1;
+       return 0;
+}
+
 static void *cdda_play_func (void *v)
 {
        int cdda_pos;
@@ -354,7 +398,6 @@ static void *cdda_play_func (void *v)
        MMRESULT mmr;
        int volume[2], volume_main;
        int oldplay;
-       mp3decoder *mp3dec = NULL;
        struct cdunit *cdu = (struct cdunit*)v;
        int firstloops;
 
@@ -408,29 +451,17 @@ static void *cdda_play_func (void *v)
                                } else {
                                        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->data) {
-                                               if (t->enctype == AUDENC_MP3) {
-                                                       if (!mp3dec) {
-                                                               try {
-                                                                       mp3dec = new mp3decoder();
-                                                               } catch (exception) { };
-                                                       }
-                                                       if (mp3dec)
-                                                               t->data = mp3dec->get (t->handle, t->filesize);
-                                               } else if (t->enctype == AUDENC_FLAC) {
-                                                       flac_get_data (t);
-                                               }
-                                       }
+                                       // do this even if audio is not compressed, t->handle also could be
+                                       // compressed and we want to unpack it in background too
+                                       while (cdimage_unpack_active == 1)
+                                               Sleep (10);
+                                       cdimage_unpack_active = 0;
+                                       write_comm_pipe_u32 (&unpack_pipe, cdu - &cdunits[0], 0);
+                                       write_comm_pipe_u32 (&unpack_pipe, t - &cdu->toc[0], 1);
+                                       while (cdimage_unpack_active == 0)
+                                               Sleep (10);
                                }
-                               int millis;
-                               struct _timeb tb2;
-                               _ftime (&tb2);
-                               millis = (tb2.time - tb.time) * 1000;
-                               if (tb2.millitm >= tb.millitm)
-                                       millis += tb2.millitm - tb.millitm;
-                               else
-                                       millis += 1000 - tb.millitm + tb2.millitm;
-                               firstloops = 150 - millis * 75 / 1000;
+                               firstloops = 150;
                                while (cdu->cdda_paused && cdu->cdda_play > 0) {
                                        Sleep (10);
                                        firstloops = -1;
@@ -454,6 +485,8 @@ static void *cdda_play_func (void *v)
                                int sector, cnt;
                                int dofinish = 0;
 
+                               gui_flicker_led (LED_CD, cdu->di.unitnum - 1, LED_CD_AUDIO);
+
                                memset (px[bufnum], 0, num_sectors * 2352);
 
                                if (firstloops > 0) {
@@ -550,9 +583,11 @@ end:
        for (i = 0; i < 2; i++)
                waveOutUnprepareHeader  (cdda_wavehandle, &whdr[i], sizeof (WAVEHDR));
 
+       while (cdimage_unpack_active == 1)
+               Sleep (10);
+
        cdda_closewav ();
        xfree (p);
-       delete mp3dec;
        cdu->cdda_play = 0;
        write_log (L"IMAGE CDDA: thread killed\n");
        return NULL;
@@ -782,7 +817,7 @@ static int command_read (int unitnum, uae_u8 *data, int sector, int size)
        if (!t || t->handle == NULL)
                return NULL;
        cdda_stop (cdu);
-       if (t->size == 2848) {
+       if (t->size == 2048) {
                int offset = 0;
                zfile_fseek (t->handle, t->offset + sector * t->size + offset, SEEK_SET);
                zfile_fread (data, size, 2048, t->handle);
@@ -847,7 +882,6 @@ static int command_toc (int unitnum, struct cd_toc_head *th)
        toc++;
 
        memcpy (&cdu->di.toc, th, sizeof (struct cd_toc_head));
-       gui_flicker_led (LED_CD, unitnum, 1);
        return 1;
 }
 
@@ -1237,9 +1271,8 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
                        if (_tcsicmp (fnametype, L"BINARY") && _tcsicmp (fnametype, L"WAVE") && _tcsicmp (fnametype, L"MP3") && _tcsicmp (fnametype, L"FLAC")) {
                                write_log (L"CUE: unknown file type '%s' ('%s')\n", fnametype, fname);
                        }
-                       if (!_tcsicmp (fnametype, L"WAVE"))
-                               fnametypeid = AUDENC_PCM;
-                       else if (!_tcsicmp (fnametype, L"MP3"))
+                       fnametypeid = AUDENC_PCM;
+                       if (!_tcsicmp (fnametype, L"MP3"))
                                fnametypeid = AUDENC_MP3;
                        else if (!_tcsicmp (fnametype, L"FLAC"))
                                fnametypeid = AUDENC_FLAC;
@@ -1298,14 +1331,14 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
                                }
 
                                newfile = 0;
-                               ztrack = zfile_fopen (fname, L"rb", ZFD_ARCHIVE);
+                               ztrack = zfile_fopen (fname, L"rb", ZFD_ARCHIVE | ZFD_DELAYEDOPEN);
                                if (!ztrack) {
                                        TCHAR tmp[MAX_DPATH];
                                        _tcscpy (tmp, fname);
                                        p = tmp + _tcslen (tmp);
                                        while (p > tmp) {
                                                if (*p == '/' || *p == '\\') {
-                                                       ztrack = zfile_fopen (p + 1, L"rb", ZFD_ARCHIVE);
+                                                       ztrack = zfile_fopen (p + 1, L"rb", ZFD_ARCHIVE | ZFD_DELAYEDOPEN);
                                                        if (ztrack) {
                                                                xfree (fname);
                                                                fname = my_strdup (p + 1);
@@ -1326,7 +1359,7 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
                                                s2[0] = 0;
                                                _tcscat (tmp, L"\\");
                                                _tcscat (tmp, fname);
-                                               ztrack = zfile_fopen (tmp, L"rb", ZFD_ARCHIVE);
+                                               ztrack = zfile_fopen (tmp, L"rb", ZFD_ARCHIVE | ZFD_DELAYEDOPEN);
                                        }
                                }
                                t->track = tracknum;
@@ -1392,8 +1425,8 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
                                                        }
                                                        t->offset += zfile_ftell (zf);
                                                        t->filesize = size;
-                                                       t->enctype = fnametypeid;
                                                }
+                                               t->enctype = fnametypeid;
                                        } else if (fnametypeid == AUDENC_MP3 && t->handle) {
                                                if (!mp3dec) {
                                                        try {
@@ -1532,7 +1565,7 @@ static struct device_info *info_device (int unitnum, struct device_info *di, int
        struct cdunit *cdu = &cdunits[unitnum];
        memset (di, 0, sizeof (struct device_info));
        if (!cdu->enabled)
-               return 0;
+               return NULL;
        di->open = cdu->open;
        di->removable = 1;
        di->bus = unitnum;
@@ -1595,6 +1628,12 @@ static int open_device (int unitnum, const TCHAR *ident)
        cdu->cdda_volume[0] = 0x7fff;
        cdu->cdda_volume[1] = 0x7fff;
        blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name);
+       if (cdimage_unpack_thread == 0) {
+               init_comm_pipe (&unpack_pipe, 10, 1);
+               uae_start_thread (L"cdimage_unpack", cdda_unpack_func, NULL, NULL);
+               while (cdimage_unpack_thread == 0)
+                       Sleep (10);
+       }
        return 1;
 }
 
@@ -1607,8 +1646,16 @@ static void close_device (int unitnum)
        unload_image (cdu);
        uae_sem_destroy (&cdu->sub_sem);
        cdu->open = false;
-       cdu->enabled = false;
        blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name);
+       if (cdimage_unpack_thread) {
+               cdimage_unpack_thread = 0;
+               write_comm_pipe_u32 (&unpack_pipe, -1, 0);
+               write_comm_pipe_u32 (&unpack_pipe, -1, 1);
+               while (cdimage_unpack_thread == 0)
+                       Sleep (10);
+               cdimage_unpack_thread = 0;
+               destroy_comm_pipe (&unpack_pipe);
+       }
 }
 
 static void close_bus (void)
@@ -1617,6 +1664,12 @@ static void close_bus (void)
                write_log (L"IMAGE close_bus() when already closed!\n");
                return;
        }
+       for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
+               struct cdunit *cdu = &cdunits[i];
+               if (cdu->open)
+                       close_device (i);
+               cdu->enabled = false;
+       }
        bus_open = 0;
        write_log (L"IMAGE driver closed.\n");
 }
index f7adccbabfc7cc9ebcc356b3818a1d340b73bf06..daa8b7b9d90ea1559b61078c647575c12a9055bc 100644 (file)
--- a/disk.cpp
+++ b/disk.cpp
@@ -2781,6 +2781,15 @@ static void disk_doupdate_predict (int startcycle)
        }
 }
 
+int disk_fifostatus (void)
+{
+       if (fifo_inuse[0] && fifo_inuse[1] && fifo_inuse[2])
+               return 1;
+       if (!fifo_inuse[0] && !fifo_inuse[1] && !fifo_inuse[2])
+               return -1;
+       return 0;
+}
+
 static bool doreaddma (void)
 {
        if (dmaen (DMA_DISK) && bitoffset == 15 && dma_enable && dskdmaen == 2 && dsklength >= 0) {
@@ -2795,6 +2804,9 @@ static bool doreaddma (void)
                        }
                        DSKDAT (word);
                        dsklength--;
+               } else if (dsklength == 0 && disk_fifostatus () < 0) {
+                       // zero length transfer wouldn't finish without this
+                       disk_dmafinished ();
                }
                return true;
        }
@@ -3280,14 +3292,6 @@ uae_u16 DSKDATR (void)
        }
        return v;
 }
-int disk_fifostatus (void)
-{
-       if (fifo_inuse[0] && fifo_inuse[1] && fifo_inuse[2])
-               return 1;
-       if (!fifo_inuse[0] && !fifo_inuse[1] && !fifo_inuse[2])
-               return -1;
-       return 0;
-}
 
 uae_u16 disk_dmal (void)
 {
index 7f55bf67ee3aaa0c9e82c2e57fed6222e6f6d8ba..eee0b7717db1e521fc389d63822db6cbd38ca545 100644 (file)
@@ -197,3 +197,7 @@ enum cd_standard_unit { CD_STANDARD_UNIT_AUDIO, CD_STANDARD_UNIT_CDTV, CD_STANDA
 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);
+
+extern void blkdev_entergui (void);
+extern void blkdev_exitgui (void);
+
index d8353a93b744264f911864a924f380f75f6bcb05..45ec42d7a0e44682644ad68bfdad6fcec731725b 100644 (file)
@@ -11,6 +11,7 @@ struct zfile {
     uae_u8 *data; // unpacked data
     int dataseek; // use seek position even if real file
        struct zfile *archiveparent; // set if parent is archive and this has not yet been unpacked (datasize < size)
+       int archiveid;
     uae_s64 size; // real size
        uae_s64 datasize; // available size (not yet unpacked completely?)
     uae_s64 seek; // seek position
@@ -98,6 +99,7 @@ struct zarchive_info
 
 #define PEEK_BYTES 1024
 #define FILE_PEEK 1
+#define FILE_DELAYEDOPEN 2
 
 extern int zfile_is_ignore_ext (const TCHAR *name);
 
@@ -141,5 +143,6 @@ extern void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user
 extern void archive_access_close (void *handle, unsigned int id);
 
 extern struct zfile *archive_getzfile (struct znode *zn, unsigned int id, int flags);
+extern struct zfile *archive_unpackzfile (struct zfile *zf);
 
 extern struct zfile *decompress_zfd (struct zfile*);
\ No newline at end of file
index 9d7f86b0325465ac59ebea29697ee705410258d1..4fef64eb784ae6360c2502aa191e5c8ba17a218c 100644 (file)
@@ -78,6 +78,7 @@ extern TCHAR *zfile_geterror (void);
 #define ZFD_CD 32 //cue/iso, cue has priority over iso
 #define ZFD_DISKHISTORY 0x100 //allow diskhistory (if disk image)
 #define ZFD_CHECKONLY 0x200 //file exists checkc
+#define ZFD_DELAYEDOPEN 0x400 //do not unpack, just get metadata
 #define ZFD_NORMAL (ZFD_ARCHIVE|ZFD_UNPACK)
 #define ZFD_ALL 0x0000ffff
 
index 1ab36e97a8a6c02e9912adcd448b153898787bc8..f56be63db1b5e33239523846eecd3a9713f3b390 100644 (file)
@@ -281,7 +281,7 @@ static int spti_read (struct dev_info_ioctl *ciw, int unitnum, uae_u8 *data, int
        cmd[4] = (uae_u8)(sector >> 8);
        cmd[5] = (uae_u8)(sector >> 0);
        if (unitnum >= 0)
-               gui_flicker_led (LED_CD, unitnum, 1);
+               gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE);
        int len = sizeof cmd;
        return do_raw_scsi (ciw, unitnum,  cmd, len, data, tlen);
 }
@@ -474,6 +474,8 @@ static void *cdda_play (void *v)
                                if (!isaudiotrack (&ciw->di.toc, cdda_pos))
                                        goto end; // data track?
 
+                               gui_flicker_led (LED_CD, ciw->di.unitnum - 1, LED_CD_AUDIO);
+
                                uae_sem_wait (&ciw->sub_sem);
                                ciw->subcodevalid = false;
                                memset (ciw->subcode, 0, sizeof ciw->subcode);
@@ -790,7 +792,7 @@ static int ioctl_command_rawread (int unitnum, uae_u8 *data, int sector, int siz
        if (log_scsi)
                write_log (L"IOCTL rawread unit=%d sector=%d blocksize=%d\n", unitnum, sector, sectorsize);
        cdda_stop (ciw);
-       gui_flicker_led (LED_CD, unitnum, 1);
+       gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE);
        if (sectorsize > 0) {
                if (sectorsize != 2336 && sectorsize != 2352 && sectorsize != 2048 &&
                        sectorsize != 2336 + 96 && sectorsize != 2352 + 96 && sectorsize != 2048 + 96)
@@ -878,7 +880,7 @@ static int ioctl_command_readwrite (int unitnum, int sector, int size, int write
        cdda_stop (ciw);
        ciw->cd_last_pos = sector;
        while (cnt-- > 0) {
-               gui_flicker_led (LED_CD, unitnum, 1);
+               gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE);
                seterrormode (ciw);
                if (SetFilePointer (ciw->h, sector * ciw->di.bytespersector, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
                        reseterrormode (ciw);
@@ -890,7 +892,7 @@ static int ioctl_command_readwrite (int unitnum, int sector, int size, int write
                break;
        }
        while (size-- > 0) {
-               gui_flicker_led (LED_CD, unitnum, 1);
+               gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE);
                seterrormode (ciw);
                if (write) {
                        if (data) {
@@ -928,7 +930,7 @@ static int ioctl_command_readwrite (int unitnum, int sector, int size, int write
                        }
                }
                reseterrormode (ciw);
-               gui_flicker_led (LED_CD, unitnum, 1);
+               gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE);
        }
        return 1;
 }
@@ -998,7 +1000,7 @@ static int ioctl_command_toc (int unitnum, struct cd_toc_head *tocout)
 
        if (!open_createfile (ciw, 0))
                return 0;
-       gui_flicker_led (LED_CD, unitnum, 1);
+       gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE);
        while (cnt-- > 0) {
                seterrormode (ciw);
                if (!DeviceIoControl (ciw->h, IOCTL_CDROM_READ_TOC, NULL, 0, toc, sizeof (CDROM_TOC), &len, NULL)) {
@@ -1045,7 +1047,7 @@ static int ioctl_command_toc (int unitnum, struct cd_toc_head *tocout)
        t->paddress = th->lastaddress;
        t++;
 
-       gui_flicker_led (LED_CD, unitnum, 1);
+       gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE);
        memcpy (tocout, th, sizeof (struct cd_toc_head));
        return 1;
 }
index 882f98b757eff20725fc140e7e242b5486e298ed..2887b77a610ee6c849fbff1b23514cad3da535f2 100644 (file)
@@ -99,13 +99,12 @@ mp3decoder::mp3decoder()
        }
 }
 
-uae_u8 *mp3decoder::get (struct zfile *zf, int maxsize)
+uae_u8 *mp3decoder::get (struct zfile *zf, uae_u8 *outbuf, int maxsize)
 {
        MMRESULT mmr;
        unsigned long rawbufsize = 0;
        LPBYTE mp3buf;
        LPBYTE rawbuf;
-       uae_u8 *outbuf = NULL;
        int outoffset = 0;
        ACMSTREAMHEADER mp3streamHead;
        HACMSTREAM h = (HACMSTREAM)g_mp3stream;
@@ -133,7 +132,6 @@ uae_u8 *mp3decoder::get (struct zfile *zf, int maxsize)
                return NULL;
        }
        zfile_fseek(zf, 0, SEEK_SET);
-       outbuf = xcalloc(uae_u8, maxsize + 2352);
        for (;;) {
                int count = zfile_fread(mp3buf, 1, MP3_BLOCK_SIZE, zf);
                if (count != MP3_BLOCK_SIZE)
index 7655c801cbdd745847237a8edfd1a97ce189afc7..0fa1d9264bcabb6c4fc15aacd65ac9fadf518dc7 100644 (file)
@@ -5,6 +5,6 @@ class mp3decoder
 public:
        mp3decoder();
        ~mp3decoder();
-       uae_u8 *get(struct zfile *zf, int maxsize);
+       uae_u8 *get(struct zfile *zf, uae_u8 *, int maxsize);
        uae_u32 mp3decoder::getsize(struct zfile *zf);
 };
index bb590b1a4bb6cefd2d33f4b0fa00e6798d75aaac..aefd3661ce408b01224b83ee14d5b3989d126891 100644 (file)
@@ -84,6 +84,7 @@
 #include "cdtv.h"
 #include "direct3d.h"
 #include "clipboard_win32.h"
+#include "blkdev.h"
 #ifdef RETROPLATFORM
 #include "rp.h"
 #endif
@@ -416,6 +417,7 @@ void resumepaused (int priority)
 #ifdef CDTV
        cdtv_exitgui ();
 #endif
+       blkdev_exitgui ();
        if (pausemouseactive)
                setmouseactive (-1);
        pausemouseactive = 0;
@@ -437,6 +439,7 @@ void setpaused (int priority)
 #ifdef CDTV
        cdtv_entergui ();
 #endif
+       blkdev_entergui ();
        pausemouseactive = 1;
        if (isfullscreen () <= 0) {
                pausemouseactive = mouseactive;
index bc460e4c57b9ad0d75bac7835d6b9a988bd6108b..4114b427d48a96bc50bed83daaca03c584292cc4 100644 (file)
@@ -18,8 +18,8 @@
 #define WINUAEPUBLICBETA 1
 #define LANG_DLL 1
 
-#define WINUAEBETA L"5"
-#define WINUAEDATE MAKEBD(2010, 7, 23)
+#define WINUAEBETA L"6"
+#define WINUAEDATE MAKEBD(2010, 7, 24)
 #define WINUAEEXTRA L""
 #define WINUAEREV L""
 
index d021abbca536ebd4eedf0131250ba6ee877c82c5..b599aa5b9c26650fa2b2a329b2a8c679e29e7b9d 100644 (file)
@@ -156,7 +156,7 @@ static void *uaenet_trap_threadr (void *arg)
                r = pcap_next_ex (sd->fp, &header, &pkt_data);
                if (r == 1) {
                        uae_sem_wait (&sd->change_sem);
-                       sd->gotfunc ((struct devstruct*)sd->user, pkt_data, header->len);
+                       sd->gotfunc ((struct s2devstruct*)sd->user, pkt_data, header->len);
                        uae_sem_post (&sd->change_sem);
                }
                if (r < 0) {
@@ -180,7 +180,7 @@ static void *uaenet_trap_threadw (void *arg)
                int donotwait = 0;
                int towrite = sd->mtu;
                uae_sem_wait (&sd->change_sem);
-               if (sd->getfunc ((struct devstruct*)sd->user, sd->writebuffer, &towrite)) {
+               if (sd->getfunc ((struct s2devstruct*)sd->user, sd->writebuffer, &towrite)) {
                        pcap_sendpacket (sd->fp, sd->writebuffer, towrite);
                        donotwait = 1;
                }
index 55071bbab5d22164eb58567a5a506335ea75bb6b..daefde5bf23b10e87347a7263ffe16b8afecb818 100644 (file)
@@ -7,8 +7,8 @@ struct netdriverdata
     int active;
 };
 
-typedef void (uaenet_gotfunc)(struct devstruct *dev, const uae_u8 *data, int len);
-typedef int (uaenet_getfunc)(struct devstruct *dev, uae_u8 *d, int *len);
+typedef void (uaenet_gotfunc)(struct s2devstruct *dev, const uae_u8 *data, int len);
+typedef int (uaenet_getfunc)(struct s2devstruct *dev, uae_u8 *d, int *len);
 
 #define MAX_TOTAL_NET_DEVICES 10
 
@@ -20,7 +20,7 @@ extern int uaenet_getdatalenght (void);
 extern int uaenet_getbytespending (void*);
 extern int uaenet_open (void*, struct netdriverdata*, void*, uaenet_gotfunc*, uaenet_getfunc*, int);
 extern void uaenet_close (void*);
-extern void uaenet_gotdata (struct devstruct *dev, const uae_u8 *data, int len);
-extern int uaenet_getdata (struct devstruct *dev, uae_u8 *d, int *len);
+extern void uaenet_gotdata (struct s2devstruct *dev, const uae_u8 *data, int len);
+extern int uaenet_getdata (struct s2devstruct *dev, uae_u8 *d, int *len);
 extern void uaenet_trigger (void*);
 
index 946c79d246598c23e8195b1ca65701358744ec00..74087578f0bbaf6085dca453705e1b7c723c940c 100644 (file)
@@ -914,7 +914,9 @@ static TCHAR *favoritepopup (HWND hwnd, int drive)
                                        idx2--;
                                        if (p2) {
                                                fname = my_strdup (p2 + 1);
-                                               p2[0] = 0;
+                                               do {
+                                                       *p2-- = 0;
+                                               } while (p2 > tmp2 && *p2 == ' ');
                                                p2 = _tcschr (fname, '"');
                                                if (p2)
                                                        *p2 = 0;
@@ -2440,6 +2442,8 @@ static BOOL CreateHardFile (HWND hDlg, UINT hfsizem, TCHAR *dostype, TCHAR *newp
                if (dynamic) {
                        if (!_stscanf (dostype, L"%x", &dt))
                                dt = 0;
+                       if (_tcslen (init_path) > 4 && !_tcsicmp (init_path + _tcslen (init_path) - 4, L".hdf"))
+                               _tcscpy (init_path + _tcslen (init_path) - 4, L".vhd");
                        result = vhd_create (init_path, hfsize, dt);
                } else {
                        SetCursor (LoadCursor (NULL, IDC_WAIT));
@@ -9095,7 +9099,7 @@ static ACCEL HarddiskAccel[] = {
        { 0, 0, 0 }
 };
 
-static void harddiskdlg_button (HWND hDlg, WPARAM wParam)
+static int harddiskdlg_button (HWND hDlg, WPARAM wParam)
 {
        int button = LOWORD (wParam);
        switch (button) {
@@ -9115,19 +9119,19 @@ static void harddiskdlg_button (HWND hDlg, WPARAM wParam)
                archivehd = 0;
                if (CustomDialogBox (IDD_FILESYS, hDlg, VolumeSettingsProc))
                        new_filesys (hDlg, -1);
-               break;
+               return 1;
        case IDC_NEW_FSARCH:
                archivehd = 1;
                current_fsvdlg = empty_fsvdlg;
                if (CustomDialogBox (IDD_FILESYS, hDlg, VolumeSettingsProc))
                        new_filesys (hDlg, -1);
-               break;
+               return 1;
 
        case IDC_NEW_HF:
                current_hfdlg = empty_hfdlg;
                if (CustomDialogBox (IDD_HARDFILE, hDlg, HardfileSettingsProc))
                        new_hardfile (hDlg, -1);
-               break;
+               return 1;
 
        case IDC_NEW_HD:
                memset (&current_hfdlg, 0, sizeof (current_hfdlg));
@@ -9139,25 +9143,25 @@ static void harddiskdlg_button (HWND hDlg, WPARAM wParam)
                        if (CustomDialogBox (IDD_HARDDRIVE, hDlg, HarddriveSettingsProc))
                                new_harddrive (hDlg, -1);
                }
-               break;
+               return 1;
 
        case IDC_EDIT:
                harddisk_edit (hDlg);
-               break;
+               return 1;
 
        case IDC_REMOVE:
                harddisk_remove (hDlg);
-               break;
+               return 1;
 
        case IDC_UP:
                harddisk_move (hDlg, 1);
                clicked_entry--;
-               break;
+               return 1;
 
        case IDC_DOWN:
                harddisk_move (hDlg, 0);
                clicked_entry++;
-               break;
+               return 1;
 
        case IDC_MAPDRIVES_AUTO:
                workprefs.win32_automount_removable = ischecked (hDlg, IDC_MAPDRIVES_AUTO);
@@ -9188,6 +9192,7 @@ static void harddiskdlg_button (HWND hDlg, WPARAM wParam)
                break;
 
        }
+       return 0;
 }
 
 static void harddiskdlg_volume_notify (HWND hDlg, NM_LISTVIEW *nmlistview)
@@ -9316,9 +9321,10 @@ static INT_PTR CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
                                hilitehd ();
                                break;
                        default:
-                               harddiskdlg_button (hDlg, wParam);
-                               InitializeListView (hDlg);
-                               hilitehd ();
+                               if (harddiskdlg_button (hDlg, wParam)) {
+                                       InitializeListView (hDlg);
+                                       hilitehd ();
+                               }
                                break;
                        }
                }
index 4b0c7433e077502d87afebe52c5af6b0f268df45..68d2ea1007684b7558f6f7ee1ea45be649a259a3 100644 (file)
@@ -1,9 +1,58 @@
 
+- MP3/FLAC background decompression, no more delayed CDA startup if audio file
+  decompression takes more than 2 seconds
+- implemented "delayed decompression" zfile open flag, currently only zip backend supports it
+  and it is only enabled when using CD images. Most zipped CD images with big audio files
+  start almost instantly now
+- potential memory corruption crash in zfile_fclose() if file had parent file(s)
+- zero length disk DMA (used by some copy protections) never finished, broke in b1
+- fixed extra space characters in favorite menu items
+- pause uaescsi.device CDA when emulation is paused or GUI is open
+- uaescsi.device CDA lights green on screen CD led
+- cue/bin audio tracks were completely silent (cue/wav worked)
+- on the fly image switching didn't send uaescsi.device change interrupts correctly
+  if CDFS polling flag was disabled (empty drive without diskchange command)
+- new dynamic hardfiles have .vhd extension instead of .hdf
+
+Beta 5
+
+- version number bumped to 2.3
 - few lines of non-filter scanlines was missing in bottom part of display
+- audio DMA start interrupt is now immediate after starting DMA in too fast CPU modes
+  (normally when audio state changes to 5), fixes EasyACDDA hang. Seems to be
+  yet another audio.device bug when CPU and memory is "too fast"..
+
+More CD related changes and updates:
+
+- unified CD32/CDTV CD unit allocation, also internal unit number is always zero =
+  GUI CD media change now work as expected
+- CDTV frontpanel Stop now quits frontpanel/CD+G mode correctly
+- added more obsolete SCSI commands: PLAY AUDIO TRACK RELATIVE (10) and (12) and
+  PLAY AUDIO (12) (10-byte version was added in b4)
+- CDTV subchannel hardware interrupt timing improved, CD+G works in cycle-exact mode now
+- cd configuration code cleanups
+- added mds/mdf image format (only v1 and first session, v2 appears to be scrambled..)
+- cdimage0 in configuration file now disables all following units (backwards compatiblity)
+  add 2 or more cdimage[0-7]= lines in increasing order if you want multiple units configured
+- cue/ccd/iso/mds detection in zipped cd images stopped working
+- moved 2048 to 2352 byte sector conversion code to generic image mounter code from CD32
+  emulation, CD32 FMV ROM now detects VideoCDs (and then it hangs)
 - mp3 cd audio: detect audio length using ID3v2 TLEN tag if it exists, assume it is CBR MP3 if
-  first 100 frames have same bit rate, fallback to original slow full file scan if no tags and VBR
-- remove mp3 decoding time from audio playback delay time, better av sync if decoding takes less
+  first 100 frames have equal bit rate, fallback to original slow full file scan if no tags and VBR
+- remove mp3 decoding time from audio playback delay time, keeps av sync if decoding takes less
   than 2 seconds
+- FLAC CD audio tracks supported (cue/iso/flac), perhaps this will be useful in future..
+  (remember to redownload winuaeinclibs.zip if you want to recompile this or future versions)
+- note that currently both mp3 and flac decoding needs to finish before playback starts which
+  can take few seconds on slow machines
+- some XP-only CD access issues fixed, tested on VMware workstation (donated by Cloanto).
+  VirtualPC sucks too much.
+- when looking for cue/iso/ccd/mds inside archives: do not attempt to autodetect (unpack)
+  other files. CD image archives containing audio tracks should start faster now (all audio
+  tracks are still unpacked at startup but previously they were unpacked twice)
+
+Future todo: hardware IDE (ATAPI) and SCSI emulation to CD SCSI emulation connection, no big CD
+GUI updates until it has been designed. (won't be done in this beta series)
 
 Beta 4:
 
@@ -47,11 +96,6 @@ If CD32 or CDTV is started in "autodetect" mode and it chose unit 1 or later (CD
 Audio CD inserted), unit 0 changes are ignored until original drive becomes empty. This
 needs to be more intelligent.
 
-Configuration file accepts cdimage0 to cdimage7. Full syntax:
-cdimagex=image path or device name,cd backend(:reserved for future)
-Cd backend not mandatory. Supported CD backend names are:
-image, ioctl, spti and aspi. (this is autoselected when using GUI)
-
 Beta 3:
 
 - most debugger options now accept .b, .w and .l size extension (+special .3 if 3-byte word),
index be8f1d541033e841b7a5b993f4662101e80105f0..088b07d96b08ae3819d5684f8fb66f2001b0293b 100644 (file)
--- a/sana2.cpp
+++ b/sana2.cpp
@@ -168,7 +168,7 @@ struct mcast {
        int cnt;
 };
 
-struct devstruct {
+struct s2devstruct {
        int unit, opencnt, exclusive, promiscuous;
        struct asyncreq *ar;
        struct asyncreq *s2p;
@@ -197,7 +197,7 @@ struct devstruct {
 
 #define FLUSH_TIMEOUT 20
 
-struct priv_devstruct {
+struct priv_s2devstruct {
        int inuse;
        int unit;
        int flags; /* OpenDevice() */
@@ -224,19 +224,19 @@ struct priv_devstruct {
 };
 
 static struct netdriverdata *td;
-static struct devstruct devst[MAX_TOTAL_NET_DEVICES];
-static struct priv_devstruct pdevst[MAX_OPEN_DEVICES];
+static struct s2devstruct devst[MAX_TOTAL_NET_DEVICES];
+static struct priv_s2devstruct pdevst[MAX_OPEN_DEVICES];
 static uae_u32 nscmd_cmd;
 static uae_sem_t change_sem, async_sem;
 
-static struct devstruct *getdevstruct (int unit)
+static struct s2devstruct *gets2devstruct (int unit)
 {
        if (unit >= MAX_TOTAL_NET_DEVICES || unit < 0)
                return 0;
        return &devst[unit];
 }
 
-static struct priv_devstruct *getpdevstruct (uaecptr request)
+static struct priv_s2devstruct *getps2devstruct (uaecptr request)
 {
        int i = get_long (request + 24);
        if (i < 0 || i >= MAX_OPEN_DEVICES || pdevst[i].inuse == 0) {
@@ -247,7 +247,7 @@ static struct priv_devstruct *getpdevstruct (uaecptr request)
 }
 
 static void *dev_thread (void *devs);
-static int start_thread (struct devstruct *dev)
+static int start_thread (struct s2devstruct *dev)
 {
        if (dev->thread_running)
                return 1;
@@ -261,14 +261,14 @@ static int start_thread (struct devstruct *dev)
 static uae_u32 REGPARAM2 dev_close_2 (TrapContext *context)
 {
        uae_u32 request = m68k_areg (regs, 1);
-       struct priv_devstruct *pdev = getpdevstruct (request);
-       struct devstruct *dev;
+       struct priv_s2devstruct *pdev = getps2devstruct (request);
+       struct s2devstruct *dev;
 
        if (!pdev) {
                write_log (L"%s close with unknown request %08X!?\n", SANA2NAME, request);
                return 0;
        }
-       dev = getdevstruct (pdev->unit);
+       dev = gets2devstruct (pdev->unit);
        if (!dev) {
                write_log (L"%s:%d close with unknown request %08X!?\n", SANA2NAME, pdev->unit, request);
                return 0;
@@ -349,8 +349,8 @@ static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context)
        uae_u32 unit = m68k_dreg (regs, 0);
        uae_u32 flags = m68k_dreg (regs, 1);
        uaecptr buffermgmt;
-       struct devstruct *dev = getdevstruct (unit);
-       struct priv_devstruct *pdev = 0;
+       struct s2devstruct *dev = gets2devstruct (unit);
+       struct priv_s2devstruct *pdev = 0;
        int i;
        uaecptr tagp, tagpnext;
 
@@ -486,7 +486,7 @@ static void freepacket (struct s2packet *s2p)
        xfree (s2p);
 }
 
-static void add_async_packet (struct devstruct *dev, struct s2packet *s2p, uaecptr request)
+static void add_async_packet (struct s2devstruct *dev, struct s2packet *s2p, uaecptr request)
 {
        struct asyncreq *ar, *ar2;
 
@@ -503,7 +503,7 @@ static void add_async_packet (struct devstruct *dev, struct s2packet *s2p, uaecp
        ar->request = request;
 }
 
-static void rem_async_packet (struct devstruct *dev, uaecptr request)
+static void rem_async_packet (struct s2devstruct *dev, uaecptr request)
 {
        struct asyncreq *ar, *prevar;
 
@@ -527,7 +527,7 @@ static void rem_async_packet (struct devstruct *dev, uaecptr request)
        uae_sem_post (&async_sem);
 }
 
-static struct asyncreq *get_async_request (struct devstruct *dev, uaecptr request, int ready)
+static struct asyncreq *get_async_request (struct s2devstruct *dev, uaecptr request, int ready)
 {
        struct asyncreq *ar;
        int ret = 0;
@@ -546,7 +546,7 @@ static struct asyncreq *get_async_request (struct devstruct *dev, uaecptr reques
        return ar;
 }
 
-static int add_async_request (struct devstruct *dev, uaecptr request)
+static int add_async_request (struct s2devstruct *dev, uaecptr request)
 {
        struct asyncreq *ar, *ar2;
 
@@ -568,7 +568,7 @@ static int add_async_request (struct devstruct *dev, uaecptr request)
        return 1;
 }
 
-static int release_async_request (struct devstruct *dev, uaecptr request)
+static int release_async_request (struct s2devstruct *dev, uaecptr request)
 {
        struct asyncreq *ar, *prevar;
 
@@ -595,7 +595,7 @@ static int release_async_request (struct devstruct *dev, uaecptr request)
        return 0;
 }
 
-static void do_abort_async (struct devstruct *dev, uaecptr request)
+static void do_abort_async (struct s2devstruct *dev, uaecptr request)
 {
        put_byte (request + 30, get_byte (request + 30) | 0x20);
        put_byte (request + 31, IOERR_ABORTED);
@@ -603,7 +603,7 @@ static void do_abort_async (struct devstruct *dev, uaecptr request)
        write_comm_pipe_u32 (&dev->requests, request, 1);
 }
 
-static void abort_async (struct devstruct *dev, uaecptr request)
+static void abort_async (struct s2devstruct *dev, uaecptr request)
 {
        struct asyncreq *ar = get_async_request (dev, request, 1);
        if (!ar) {
@@ -615,7 +615,7 @@ static void abort_async (struct devstruct *dev, uaecptr request)
        do_abort_async (dev, request);
 }
 
-static void signalasync (struct devstruct *dev, struct asyncreq *ar, int actual, int err)
+static void signalasync (struct s2devstruct *dev, struct asyncreq *ar, int actual, int err)
 {
        uaecptr request = ar->request;
        int command = get_word (request + 28);
@@ -691,7 +691,7 @@ static uae_u64 amigaaddrto64 (uaecptr d)
        return addr;
 }
 
-static void addmulticastaddresses (struct devstruct *dev, uae_u64 start, uae_u64 end)
+static void addmulticastaddresses (struct s2devstruct *dev, uae_u64 start, uae_u64 end)
 {
        struct mcast *mc, *mc2;
 
@@ -718,7 +718,7 @@ static void addmulticastaddresses (struct devstruct *dev, uae_u64 start, uae_u64
                mc2->next = mc;
        }
 }
-static int delmulticastaddresses (struct devstruct *dev, uae_u64 start, uae_u64 end)
+static int delmulticastaddresses (struct s2devstruct *dev, uae_u64 start, uae_u64 end)
 {
        struct mcast *mc, *prevmc;
 
@@ -744,7 +744,7 @@ static int delmulticastaddresses (struct devstruct *dev, uae_u64 start, uae_u64
        return 0;
 }
 
-static struct s2packet *createreadpacket (struct devstruct *dev, const uae_u8 *d, int len)
+static struct s2packet *createreadpacket (struct s2devstruct *dev, const uae_u8 *d, int len)
 {
        struct s2packet *s2p = xcalloc (struct s2packet, 1);
        s2p->data = xmalloc (uae_u8, dev->td->mtu + ETH_HEADER_SIZE + 2);
@@ -753,7 +753,7 @@ static struct s2packet *createreadpacket (struct devstruct *dev, const uae_u8 *d
        return s2p;
 }
 
-static int handleread (TrapContext *ctx, struct priv_devstruct *pdev, uaecptr request, uae_u8 *d, int len, int cmd)
+static int handleread (TrapContext *ctx, struct priv_s2devstruct *pdev, uaecptr request, uae_u8 *d, int len, int cmd)
 {
        uae_u8 flags = get_byte (request + 30);
        uaecptr data = get_long (request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2 + 4);
@@ -794,7 +794,7 @@ static int handleread (TrapContext *ctx, struct priv_devstruct *pdev, uaecptr re
        return 1;
 }
 
-void uaenet_gotdata (struct devstruct *dev, const uae_u8 *d, int len)
+void uaenet_gotdata (struct s2devstruct *dev, const uae_u8 *d, int len)
 {
        uae_u16 type;
        struct mcast *mc;
@@ -853,7 +853,7 @@ static struct s2packet *createwritepacket (TrapContext *ctx, uaecptr request)
        uaecptr srcaddr = request + 32 + 4 + 4;
        uaecptr dstaddr = request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES;
        uae_u16 packettype = get_long (request + 32 + 4);
-       struct priv_devstruct *pdev = getpdevstruct (request);
+       struct priv_s2devstruct *pdev = getps2devstruct (request);
        struct s2packet *s2p;
 
        if (!pdev)
@@ -881,7 +881,7 @@ static struct s2packet *createwritepacket (TrapContext *ctx, uaecptr request)
        return s2p;
 }
 
-static int uaenet_getdata (struct devstruct *dev, uae_u8 *d, int *len)
+static int uaenet_getdata (struct s2devstruct *dev, uae_u8 *d, int *len)
 {
        int gotit;
        struct asyncreq *ar;
@@ -895,7 +895,7 @@ static int uaenet_getdata (struct devstruct *dev, uae_u8 *d, int *len)
                        int command = get_word (request + 28);
                        uae_u32 packettype = get_long (request + 32 + 4);
                        if (command == CMD_WRITE || command == S2_BROADCAST || command == S2_MULTICAST) {
-                               struct priv_devstruct *pdev = getpdevstruct (request);
+                               struct priv_s2devstruct *pdev = getps2devstruct (request);
                                struct asyncreq *ars2p = dev->s2p;
                                while (ars2p) {
                                        if (ars2p->request == request) {
@@ -921,7 +921,7 @@ static int uaenet_getdata (struct devstruct *dev, uae_u8 *d, int *len)
        return gotit;
 }
 
-void checkevents (struct devstruct *dev, int mask, int sem)
+void checkevents (struct s2devstruct *dev, int mask, int sem)
 {
        struct asyncreq *ar;
 
@@ -942,7 +942,7 @@ void checkevents (struct devstruct *dev, int mask, int sem)
                uae_sem_post (&async_sem);
 }
 
-static int checksize (uaecptr request, struct devstruct *dev)
+static int checksize (uaecptr request, struct s2devstruct *dev)
 {
        uae_u32 datalength = get_long (request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2);
 
@@ -951,15 +951,15 @@ static int checksize (uaecptr request, struct devstruct *dev)
        return 1;
 }
 
-static void flush (struct priv_devstruct *pdev)
+static void flush (struct priv_s2devstruct *pdev)
 {
        struct asyncreq *ar;
-       struct devstruct *dev;
+       struct s2devstruct *dev;
 
-       dev = getdevstruct (pdev->unit);
+       dev = gets2devstruct (pdev->unit);
        ar = dev->ar;
        while (ar) {
-               if (!ar->ready && getpdevstruct (ar->request) == pdev) {
+               if (!ar->ready && getps2devstruct (ar->request) == pdev) {
                        ar->ready = 1;
                        do_abort_async (dev, ar->request);
                }
@@ -967,7 +967,7 @@ static void flush (struct priv_devstruct *pdev)
        }
 }
 
-static int dev_do_io_2 (struct devstruct *dev, uaecptr request, int quick)
+static int dev_do_io_2 (struct s2devstruct *dev, uaecptr request, int quick)
 {
        uae_u8 flags = get_byte (request + 30);
        uae_u32 command = get_word (request + 28);
@@ -982,7 +982,7 @@ static int dev_do_io_2 (struct devstruct *dev, uaecptr request, int quick)
        uae_u32 wire_error = 0;
        int i;
        int async = 0;
-       struct priv_devstruct *pdev = getpdevstruct (request);
+       struct priv_s2devstruct *pdev = getps2devstruct (request);
 
        if (log_net)
                write_log (L"S2: C=%02d T=%04X S=%02X%02X%02X%02X%02X%02X D=%02X%02X%02X%02X%02X%02X L=%d D=%08X SD=%08X BM=%08X\n",
@@ -1225,10 +1225,10 @@ end:
        return async;
 }
 
-static int dev_do_io (struct devstruct *dev, uaecptr request, int quick)
+static int dev_do_io (struct s2devstruct *dev, uaecptr request, int quick)
 {
        uae_u32 command = get_word (request + 28);
-       struct priv_devstruct *pdev = getpdevstruct (request);
+       struct priv_s2devstruct *pdev = getps2devstruct (request);
        uaecptr data = get_long (request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2 + 4);
 
        put_byte (request + 31, 0);
@@ -1267,7 +1267,7 @@ static int dev_can_quick (uae_u32 command)
        return 0;
 }
 
-static int dev_canquick (struct devstruct *dev, uaecptr request)
+static int dev_canquick (struct s2devstruct *dev, uaecptr request)
 {
        uae_u32 command = get_word (request + 28);
        return dev_can_quick (command);
@@ -1278,8 +1278,8 @@ static uae_u32 REGPARAM2 dev_beginio (TrapContext *context)
        uae_u32 request = m68k_areg (regs, 1);
        uae_u8 flags = get_byte (request + 30);
        int command = get_word (request + 28);
-       struct priv_devstruct *pdev = getpdevstruct (request);
-       struct devstruct *dev;
+       struct priv_s2devstruct *pdev = getps2devstruct (request);
+       struct s2devstruct *dev;
 
        put_byte (request + 8, NT_MESSAGE);
        if (!pdev) {
@@ -1287,7 +1287,7 @@ static uae_u32 REGPARAM2 dev_beginio (TrapContext *context)
                put_byte (request + 31, 32);
                return get_byte (request + 31);
        }
-       dev = getdevstruct (pdev->unit);
+       dev = gets2devstruct (pdev->unit);
        if (!dev) {
                write_log (L"%s unknown iorequest (2) %08x\n", getdevname (), request);
                put_byte (request + 31, 32);
@@ -1334,7 +1334,7 @@ static uae_u32 REGPARAM2 dev_beginio (TrapContext *context)
 
 static void *dev_thread (void *devs)
 {
-       struct devstruct *dev = (struct devstruct*)devs;
+       struct s2devstruct *dev = (struct s2devstruct*)devs;
 
        uae_set_thread_priority (NULL, 1);
        dev->thread_running = 1;
@@ -1380,15 +1380,15 @@ static uae_u32 REGPARAM2 dev_init (TrapContext *context)
 static uae_u32 REGPARAM2 dev_abortio (TrapContext *context)
 {
        uae_u32 request = m68k_areg (regs, 1);
-       struct priv_devstruct *pdev = getpdevstruct (request);
-       struct devstruct *dev;
+       struct priv_s2devstruct *pdev = getps2devstruct (request);
+       struct s2devstruct *dev;
 
        if (!pdev) {
                write_log (L"%s abortio but no request %08x found!\n", getdevname(), request);
                put_byte (request + 31, 32);
                return get_byte (request + 31);
        }
-       dev = getdevstruct (pdev->unit);
+       dev = gets2devstruct (pdev->unit);
        if (!dev) {
                write_log (L"%s (%d) abortio but no request %08x found!\n", getdevname(), pdev->unit, request);
                put_byte (request + 31, 32);
@@ -1415,7 +1415,7 @@ static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx)
                pdevst[i].tmp = 0;
 
        for (i = 0; i < MAX_TOTAL_NET_DEVICES; i++) {
-               struct devstruct *dev = &devst[i];
+               struct s2devstruct *dev = &devst[i];
                struct s2packet *p;
                if (dev->online) {
                        while (dev->readqueue) {
@@ -1430,7 +1430,7 @@ static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx)
                                                int command = get_word (request + 28);
                                                uae_u32 packettype = get_long (request + 32 + 4);
                                                if (command == CMD_READ && (packettype == type || (packettype <= 1500 && type <= 1500))) {
-                                                       struct priv_devstruct *pdev = getpdevstruct (request);
+                                                       struct priv_s2devstruct *pdev = getps2devstruct (request);
                                                        if (pdev && pdev->tmp == 0) {
                                                                if (handleread (ctx, pdev, request, p->data, p->len, command)) {
                                                                        if (log_net)
@@ -1455,7 +1455,7 @@ static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx)
                                                uaecptr request = ar->request;
                                                int command = get_word (request + 28);
                                                if (command == S2_READORPHAN) {
-                                                       struct priv_devstruct *pdev = getpdevstruct (request);
+                                                       struct priv_s2devstruct *pdev = getps2devstruct (request);
                                                        if (pdev && pdev->tmp <= 0) {
                                                                if (log_net)
                                                                        write_log (L"-> %p Accepted, S2_READORPHAN, REQ=%08X LEN=%d\n", p, request, p->len);
@@ -1497,7 +1497,7 @@ static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx)
                                uaecptr request = ar->request;
                                int command = get_word (request + 28);
                                if (command == S2_ONLINE) {
-                                       struct priv_devstruct *pdev = getpdevstruct (request);
+                                       struct priv_s2devstruct *pdev = getps2devstruct (request);
                                        dev->packetsreceived = 0;
                                        dev->packetssent = 0;
                                        dev->baddata = 0;
@@ -1525,7 +1525,7 @@ static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx)
                                                write_comm_pipe_u32 (&dev->requests, request, 1);
                                                uaenet_vsync_requested--;
                                        } else {
-                                               struct priv_devstruct *pdev = getpdevstruct (request);
+                                               struct priv_s2devstruct *pdev = getps2devstruct (request);
                                                if (pdev) {
                                                        dev->flush_timeout--;
                                                        if (dev->flush_timeout <= 0) {
@@ -1554,7 +1554,7 @@ static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx)
 static void dev_reset (void)
 {
        int i;
-       struct devstruct *dev;
+       struct s2devstruct *dev;
        int unitnum = 0;
 
        write_log (L"%s reset\n", getdevname());
@@ -1574,10 +1574,10 @@ static void dev_reset (void)
                }
                while (dev->mc)
                        delmulticastaddresses (dev, dev->mc->start, dev->mc->end);
-               memset (dev, 0, sizeof (struct devstruct));
+               memset (dev, 0, sizeof (struct s2devstruct));
        }
        for (i = 0; i < MAX_OPEN_DEVICES; i++)
-               memset (&pdevst[i], 0, sizeof (struct priv_devstruct));
+               memset (&pdevst[i], 0, sizeof (struct priv_s2devstruct));
        uaenet_vsync_requested = 0;
        uaenet_int_requested = 0;
        irq_init = 0;
index e840e24b3d66332dea97d0c65844406325cd00b9..ad540aea72e3e5080337fe8ebb7bf0c2740323ad 100644 (file)
--- a/zfile.cpp
+++ b/zfile.cpp
@@ -147,7 +147,14 @@ static struct zcache *zcache_put (const TCHAR *name, struct zdiskimage *data)
        zc->tm = time (NULL);
        return zc;
 }
-       
+
+static void checkarchiveparent (struct zfile *z)
+{
+       // unpack completely if opened in PEEK mode
+       if (z->archiveparent)
+               archive_unpackzfile (z);
+}
+
 static struct zfile *zfile_create (struct zfile *prev)
 {
        struct zfile *z;
@@ -191,10 +198,6 @@ void zfile_exit (void)
 
 void zfile_fclose (struct zfile *f)
 {
-       struct zfile *pl = NULL;
-       struct zfile *l  = zlist;
-       struct zfile *nxt;
-
        //write_log (L"%p\n", f);
        if (!f)
                return;
@@ -211,6 +214,13 @@ void zfile_fclose (struct zfile *f)
                if (f->parent->opencnt <= 0)
                        zfile_fclose (f->parent);
        }
+       if (f->archiveparent) {
+               zfile_fclose (f->archiveparent);
+               f->archiveparent = NULL;
+       }
+       struct zfile *pl = NULL;
+       struct zfile *nxt;
+       struct zfile *l  = zlist;
        while (l != f) {
                if (l == 0) {
                        write_log (L"zfile: tried to free already freed or nonexisting filehandle!\n");
@@ -1836,6 +1846,8 @@ struct zfile *zfile_dup (struct zfile *zf)
        struct zfile *nzf;
        if (!zf)
                return NULL;
+       if (zf->archiveparent)
+               checkarchiveparent (zf);
        if (zf->userdata)
                return NULL;
        if (!zf->data && zf->dataseek) {
@@ -1846,12 +1858,17 @@ struct zfile *zfile_dup (struct zfile *zf)
                memcpy (nzf->data, zf->data, zf->size);
                nzf->size = zf->size;
                nzf->datasize = zf->datasize;
-       } else if (zf->zipname) {
-               nzf = openzip (zf->name);
-               return nzf;
-       } else {
+       } else { 
+               if (zf->zipname) {
+                       nzf = openzip (zf->name);
+                       if (nzf)
+                               return nzf;
+               }
+               FILE *ff = _tfopen (zf->name, zf->mode);
+               if (!ff)
+                       return NULL;
                nzf = zfile_create (zf);
-               nzf->f = _tfopen (zf->name, zf->mode);
+               nzf->f = ff;
        }
        zfile_fseek (nzf, zf->seek, SEEK_SET);
        if (zf->name)
@@ -1997,8 +2014,10 @@ size_t zfile_fread  (void *b, size_t l1, size_t l2, struct zfile *z)
                return z->zfileread (b, l1, l2, z);
        if (z->data) {
                if (z->datasize < z->size && z->seek + l1 * l2 > z->datasize) {
-                       write_log (L"zfile_fread(%s) attempted to read past PEEK_BYTES\n", z->name);
-
+                       if (z->archiveparent) {
+                               archive_unpackzfile (z);
+                               return zfile_fread (b, l1, l2, z);
+                       }
                        return 0;
                }
                if (z->seek + l1 * l2 > z->size) {
@@ -2037,6 +2056,8 @@ size_t zfile_fread  (void *b, size_t l1, size_t l2, struct zfile *z)
 
 size_t zfile_fwrite (void *b, size_t l1, size_t l2, struct zfile *z)
 {
+       if (z->archiveparent)
+               return 0;
        if (z->zfilewrite)
                return z->zfilewrite (b, l1, l2, z);
        if (z->parent && z->useparent)
@@ -2065,6 +2086,7 @@ size_t zfile_fputs (struct zfile *z, TCHAR *s)
 
 char *zfile_fgetsa (char *s, int size, struct zfile *z)
 {
+       checkarchiveparent (z);
        if (z->data) {
                char *os = s;
                int i;
@@ -2090,6 +2112,7 @@ char *zfile_fgetsa (char *s, int size, struct zfile *z)
 
 TCHAR *zfile_fgets (TCHAR *s, int size, struct zfile *z)
 {
+       checkarchiveparent (z);
        if (z->data) {
                char s2[MAX_DPATH];
                char *p = s2;
@@ -2133,6 +2156,7 @@ int zfile_putc (int c, struct zfile *z)
 
 int zfile_getc (struct zfile *z)
 {
+       checkarchiveparent (z);
        int out = -1;
        if (z->data) {
                if (z->seek < z->size) {
@@ -2159,14 +2183,10 @@ uae_u8 *zfile_getdata (struct zfile *z, uae_s64 offset, int len)
                zfile_fseek (z, 0, SEEK_SET);
        }
        b = xmalloc (uae_u8, len);
-       if (z->data) {
-               memcpy (b, z->data + offset, len);
-       } else {
-               pos = zfile_ftell (z);
-               zfile_fseek (z, offset, SEEK_SET);
-               zfile_fread (b, len, 1, z);
-               zfile_fseek (z, pos, SEEK_SET);
-       }
+       pos = zfile_ftell (z);
+       zfile_fseek (z, offset, SEEK_SET);
+       zfile_fread (b, len, 1, z);
+       zfile_fseek (z, pos, SEEK_SET);
        return b;
 }
 
index 0fb55de8036d2fcf48de584a9e4af7c25b37cba9..6d35afe06f68ef67eca58bad472384690a3be26a 100644 (file)
@@ -24,6 +24,8 @@
 
 #include <zlib.h>
 
+#define unpack_log write_log
+
 static time_t fromdostime (uae_u32 dd)
 {
        struct tm tm;
@@ -84,49 +86,6 @@ static struct zvolume *getzvolume (struct znode *parent, struct zfile *zf, unsig
        return zv;
 }
 
-struct zfile *archive_getzfile (struct znode *zn, unsigned int id, int flags)
-{
-       struct zfile *zf = NULL;
-
-       switch (id)
-       {
-       case ArchiveFormatZIP:
-               zf = archive_access_zip (zn, flags);
-               break;
-       case ArchiveFormat7Zip:
-               zf = archive_access_7z (zn);
-               break;
-       case ArchiveFormatRAR:
-               zf = archive_access_rar (zn);
-               break;
-       case ArchiveFormatLHA:
-               zf = archive_access_lha (zn);
-               break;
-       case ArchiveFormatLZX:
-               zf = archive_access_lzx (zn);
-               break;
-       case ArchiveFormatPLAIN:
-               zf = archive_access_plain (zn);
-               break;
-       case ArchiveFormatADF:
-               zf = archive_access_adf (zn);
-               break;
-       case ArchiveFormatRDB:
-               zf = archive_access_rdb (zn);
-               break;
-       case ArchiveFormatFAT:
-               zf = archive_access_fat (zn);
-               break;
-       case ArchiveFormatDIR:
-               zf = archive_access_dir (zn);
-               break;
-       case ArchiveFormatTAR:
-               zf = archive_access_tar (zn);
-               break;
-       }
-       return zf;
-}
-
 struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, unsigned int id, int dodefault, int *retcode, int index)
 {
        struct zvolume *zv;
@@ -138,6 +97,7 @@ struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, uns
        int diskimg;
        int mask = zf->zfdmask;
        int canhistory = (mask & ZFD_DISKHISTORY) && !(mask & ZFD_CHECKONLY);
+       int getflag = (mask &  ZFD_DELAYEDOPEN) ? FILE_DELAYEDOPEN : 0;
 
        if (retcode)
                *retcode = 0;
@@ -206,12 +166,12 @@ struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, uns
                                                ft = ZFILE_CDIMAGE;
                                        }
                                } else {
-                                       zt = archive_getzfile (zn, id, FILE_PEEK);
+                                       zt = archive_getzfile (zn, id, getflag);
                                        ft = zfile_gettype (zt);
                                }
                                if ((select < 0 || ft) && whf > we_have_file) {
                                        if (!zt)
-                                               zt = archive_getzfile (zn, id, FILE_PEEK);
+                                               zt = archive_getzfile (zn, id, getflag);
                                        we_have_file = whf;
                                        if (z)
                                                zfile_fclose (z);
@@ -358,7 +318,6 @@ struct zfile *archive_access_tar (struct znode *zn)
 
 static void archive_close_zip (void *handle)
 {
-       unzClose (handle);
 }
 
 struct zvolume *archive_directory_zip (struct zfile *z)
@@ -373,7 +332,7 @@ struct zvolume *archive_directory_zip (struct zfile *z)
                return 0;
        if (unzGoToFirstFile (uz) != UNZ_OK)
                return 0;
-       zv = zvolume_alloc (z, ArchiveFormatZIP, uz, NULL);
+       zv = zvolume_alloc (z, ArchiveFormatZIP, NULL, NULL);
        for (;;) {
                char filename_inzip2[MAX_DPATH];
                TCHAR c;
@@ -409,22 +368,29 @@ struct zvolume *archive_directory_zip (struct zfile *z)
                if (err != UNZ_OK)
                        break;
        }
+       unzClose (uz);
        zv->method = ArchiveFormatZIP;
        return zv;
 }
 
 
-struct zfile *archive_access_zip (struct znode *zn, int flags)
+static struct zfile *archive_do_zip (struct znode *zn, struct zfile *z, int flags)
 {
-       struct zfile *z = NULL;
-       unzFile uz = zn->volume->handle;
-       int i, err;
+       unzFile uz;
+       int i;
        TCHAR tmp[MAX_DPATH];
+       TCHAR *name = z ? z->archiveparent->name : zn->volume->root.fullname;
        char *s;
 
-       _tcscpy (tmp, zn->fullname + _tcslen (zn->volume->root.fullname) + 1);
-       if (unzGoToFirstFile (uz) != UNZ_OK)
+       uz = unzOpen (z ? z->archiveparent : zn->volume->archive);
+       if (!uz)
                return 0;
+       if (z)
+               _tcscpy (tmp, z->archiveparent->name);
+       else
+               _tcscpy (tmp, zn->fullname + _tcslen (zn->volume->root.fullname) + 1);
+       if (unzGoToFirstFile (uz) != UNZ_OK)
+               goto error;
        for (i = 0; tmp[i]; i++) {
                if (tmp[i] == '\\')
                        tmp[i] = '/';
@@ -439,22 +405,52 @@ struct zfile *archive_access_zip (struct znode *zn, int flags)
                s = ua (tmp);
                if (unzLocateFile (uz, s, 1) != UNZ_OK) {
                        xfree (s);
-                       return 0;
+                       goto error;
                }
        }
        xfree (s);
        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);
+               goto error;
+       if (!z)
+               z = zfile_fopen_empty (NULL, zn->fullname, zn->size);
        if (z) {
-//             if (flags & FILE_PEEK)
-//                     z->datasize = PEEK_BYTES;
-               err = unzReadCurrentFile (uz, z->data, z->datasize);
+               int err = -1;
+               if (!(flags & FILE_DELAYEDOPEN) || z->size <= PEEK_BYTES) {
+                       unpack_log (L"ZIP: unpacking %s, flags=%d\n", name, flags);
+                       err = unzReadCurrentFile (uz, z->data, z->datasize);
+                       unpack_log (L"ZIP: unpacked, code=%d\n", err);
+               } else {
+                       z->archiveparent = zfile_dup (zn->volume->archive);
+                       if (z->archiveparent) {
+                               unpack_log (L"ZIP: delayed open '%s'\n", name);
+                               xfree (z->archiveparent->name);
+                               z->archiveparent->name = my_strdup (tmp);
+                               z->datasize = PEEK_BYTES;
+                               err = unzReadCurrentFile (uz, z->data, z->datasize);
+                               unpack_log (L"ZIP: unpacked, code=%d\n", err);
+                       } else {
+                               unpack_log (L"ZIP: unpacking %s (failed DELAYEDOPEN)\n", name);
+                               err = unzReadCurrentFile (uz, z->data, z->datasize);
+                               unpack_log (L"ZIP: unpacked, code=%d\n", err);
+                       }
+               }
        }
        unzCloseCurrentFile (uz);
+       unzClose (uz);
        return z;
+error:
+       unzClose (uz);
+       return NULL;
+}
+
+static struct zfile *archive_access_zip (struct znode *zn, int flags)
+{
+       return archive_do_zip (zn, NULL, flags);
+}
+static struct zfile *archive_unpack_zip (struct zfile *zf)
+{
+       return archive_do_zip (NULL, zf, 0);
 }
 
 /* 7Z */
@@ -590,7 +586,7 @@ struct zvolume *archive_directory_7z (struct zfile *z)
        return zv;
 }
 
-struct zfile *archive_access_7z (struct znode *zn)
+static struct zfile *archive_access_7z (struct znode *zn)
 {
        SRes res;
        struct zvolume *zv = zn->volume;
@@ -738,7 +734,7 @@ struct zvolume *archive_directory_rar (struct zfile *z)
        return zv;
 }
 
-struct zfile *archive_access_rar (struct znode *zn)
+static struct zfile *archive_access_rar (struct znode *zn)
 {
        struct RARContext *rc = (struct RARContext*)zn->volume->handle;
        int i;
@@ -935,7 +931,7 @@ struct zvolume *archive_directory_arcacc (struct zfile *z, unsigned int id)
 }
 
 
-struct zfile *archive_access_arcacc (struct znode *zn)
+static struct zfile *archive_access_arcacc (struct znode *zn)
 {
        struct zfile *zf;
        struct zfile *z = zn->volume->archive;
@@ -1049,7 +1045,7 @@ struct zvolume *archive_directory_plain (struct zfile *z)
        }
        return zv;
 }
-struct zfile *archive_access_plain (struct znode *zn)
+static struct zfile *archive_access_plain (struct znode *zn)
 {
        struct zfile *z;
 
@@ -1500,7 +1496,7 @@ static int sfsfindblock (struct adfhandle *adf, int btree, int theblock, struct
 }
 
 
-struct zfile *archive_access_adf (struct znode *zn)
+static struct zfile *archive_access_adf (struct znode *zn)
 {
        struct zfile *z = NULL;
        int root, ffs;
@@ -1713,7 +1709,7 @@ struct zvolume *archive_directory_rdb (struct zfile *z)
        return zv;
 }
 
-struct zfile *archive_access_rdb (struct znode *zn)
+static struct zfile *archive_access_rdb (struct znode *zn)
 {
        struct zfile *z = zn->volume->archive;
        struct zfile *zf;
@@ -1978,7 +1974,7 @@ struct zvolume *archive_directory_fat (struct zfile *z)
        return zv;
 }
 
-struct zfile *archive_access_fat (struct znode *zn)
+static struct zfile *archive_access_fat (struct znode *zn)
 {
        uae_u8 buf[512] = { 0 };
        int fatbits = 12;
@@ -2047,8 +2043,72 @@ void archive_access_close (void *handle, unsigned int id)
        }
 }
 
-struct zfile *archive_access_dir (struct znode *zn)
+static struct zfile *archive_access_dir (struct znode *zn)
 {
        return zfile_fopen (zn->fullname, L"rb", 0);
 }
 
+
+struct zfile *archive_unpackzfile (struct zfile *zf)
+{
+       struct zfile *zout = NULL;
+       if (!zf->archiveparent)
+               return NULL;
+       unpack_log (L"delayed unpack '%s'\n", zf->name);
+       zf->datasize = zf->size;
+       switch (zf->archiveid)
+       {
+       case ArchiveFormatZIP:
+               zout = archive_unpack_zip (zf);
+               break;
+       }
+       zfile_fclose (zf->archiveparent);
+       zf->archiveparent = NULL;
+       zf->archiveid = 0;
+       return NULL;
+}
+
+struct zfile *archive_getzfile (struct znode *zn, unsigned int id, int flags)
+{
+       struct zfile *zf = NULL;
+
+       switch (id)
+       {
+       case ArchiveFormatZIP:
+               zf = archive_access_zip (zn, flags);
+               break;
+       case ArchiveFormat7Zip:
+               zf = archive_access_7z (zn);
+               break;
+       case ArchiveFormatRAR:
+               zf = archive_access_rar (zn);
+               break;
+       case ArchiveFormatLHA:
+               zf = archive_access_lha (zn);
+               break;
+       case ArchiveFormatLZX:
+               zf = archive_access_lzx (zn);
+               break;
+       case ArchiveFormatPLAIN:
+               zf = archive_access_plain (zn);
+               break;
+       case ArchiveFormatADF:
+               zf = archive_access_adf (zn);
+               break;
+       case ArchiveFormatRDB:
+               zf = archive_access_rdb (zn);
+               break;
+       case ArchiveFormatFAT:
+               zf = archive_access_fat (zn);
+               break;
+       case ArchiveFormatDIR:
+               zf = archive_access_dir (zn);
+               break;
+       case ArchiveFormatTAR:
+               zf = archive_access_tar (zn);
+               break;
+       }
+       if (zf)
+               zf->archiveid = id;
+       return zf;
+}