]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc2000b21.zip
authorToni Wilen <twilen@winuae.net>
Sun, 15 Nov 2009 13:01:13 +0000 (15:01 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:49:21 +0000 (21:49 +0200)
25 files changed:
blitter.c
custom.c
disk.c
diskutil.c
drawing.c
hardfile.c
include/cpu_prefetch.h
include/memory.h
include/serial.h
include/zarchive.h
include/zfile.h
memory.c
newcpu.c
od-win32/keyboard_win32.c
od-win32/parser.c
od-win32/serial_win32.c
od-win32/sysconfig.h
od-win32/win32.h
od-win32/win32gui.c
od-win32/winuae_msvc/winuae_msvc.vcproj
od-win32/winuaechangelog.txt
prowizard/rippers/Promizer20.c
uaeunp.c
zfile.c
zfile_archive.c

index 21ed1c8227287989555f18318710dec635480515..321c391fba2c503477beea84199b3b0385d4148b 100644 (file)
--- a/blitter.c
+++ b/blitter.c
@@ -10,6 +10,7 @@
 //#define BLITTER_DEBUG_NOWAIT
 //#define BLITTER_DEBUG
 //#define BLITTER_DEBUG_NO_D
+//#define BLITTER_INSTANT
 
 #define SPEEDUP
 
@@ -100,17 +101,17 @@ number of cycles, initial cycle, main cycle
 
 static const int blit_cycle_diagram[][10] =
 {
-       { 2, 0,0,           0,0 },      /* 0 */
-       { 2, 0,0,           0,4 },      /* 1 */
-       { 2, 0,3,           0,3 },      /* 2 */
+       { 2, 0,0,           0,0 },              /* 0 */
+       { 2, 0,0,           0,4 },              /* 1 */
+       { 2, 0,3,           0,3 },              /* 2 */
        { 3, 0,3,0,         0,3,4 },    /* 3 */
        { 3, 0,2,0,         0,2,0 },    /* 4 */
        { 3, 0,2,0,         0,2,4 },    /* 5 */
        { 3, 0,2,3,         0,2,3 },    /* 6 */
        { 4, 0,2,3,0,   0,2,3,4 },  /* 7 */
-       { 2, 1,0,           1,0 },      /* 8 */
-       { 2, 1,0,           1,4 },      /* 9 */
-       { 2, 1,3,           1,3 },      /* A */
+       { 2, 1,0,           1,0 },              /* 8 */
+       { 2, 1,0,           1,4 },              /* 9 */
+       { 2, 1,3,           1,3 },              /* A */
        { 3, 1,3,0,         1,3,4, },   /* B */
        { 3, 1,2,0,         1,2,0 },    /* C */
        { 3, 1,2,0,         1,2,4 },    /* D */
@@ -127,22 +128,22 @@ idle cycle added (still requires free bus cycle)
 
 static const int blit_cycle_diagram_fill[][10] =
 {
-       { 0 },                  /* 0 */
+       { 0 },                                          /* 0 */
        { 3, 0,0,0,         0,4,0 },    /* 1 */
-       { 0 },                  /* 2 */
-       { 0 },                  /* 3 */
-       { 0 },                  /* 4 */
+       { 0 },                                          /* 2 */
+       { 0 },                                          /* 3 */
+       { 0 },                                          /* 4 */
        { 4, 0,2,0,0,   0,2,4,0 },      /* 5 */
-       { 0 },                  /* 6 */
-       { 0 },                  /* 7 */
-       { 0 },                  /* 8 */
+       { 0 },                                          /* 6 */
+       { 0 },                                          /* 7 */
+       { 0 },                                          /* 8 */
        { 3, 1,0,0,         1,4,0 },    /* 9 */
-       { 0 },                  /* A */
-       { 0 },                  /* B */
-       { 0 },                  /* C */
+       { 0 },                                          /* A */
+       { 0 },                                          /* B */
+       { 0 },                                          /* C */
        { 4, 1,2,0,0,   1,2,4,0 },      /* D */
-       { 0 },                  /* E */
-       { 0 },                  /* F */
+       { 0 },                                          /* E */
+       { 0 },                                          /* F */
 };
 
 /*
@@ -1324,6 +1325,9 @@ static void do_blitter2 (int hpos, int copper)
 
        blit_maxcyclecounter = 0x7fffffff;
        if (blitter_cycle_exact) {
+#ifdef BLITTER_INSTANT
+               blitter_handler (0);
+#else
                blitter_hcounter1 = blitter_hcounter2 = 0;
                blitter_vcounter1 = blitter_vcounter2 = 0;
                if (blit_nod)
@@ -1332,6 +1336,7 @@ static void do_blitter2 (int hpos, int copper)
                blit_waitcyclecounter = copper;
                blit_startcycles = 0;
                blit_maxcyclecounter = hblitsize * vblitsize + 2;
+#endif
                return;
        }
 
index 4e3b8dcd0a06edcb05562cb5c479391b8b2aa85b..4ceb32f3de4f1a53089e84a1887ab4de0fd62fa6 100644 (file)
--- a/custom.c
+++ b/custom.c
@@ -224,7 +224,7 @@ uae_u8 cycle_line[256];
 #endif
 
 static uae_u16 bplxdat[8];
-static int bpl1dat_written;
+static int bpl1dat_written, bpl1dat_early;
 static uae_s16 bpl1mod, bpl2mod;
 static uaecptr prevbpl[2][MAXVPOS][8];
 static uaecptr bplpt[8], bplptx[8];
@@ -1072,14 +1072,15 @@ static void clear_fetchbuffer (uae_u32 *ptr, int nwords)
 {
        int i;
 
-       if (! thisline_changed)
-               for (i = 0; i < nwords; i++)
+       if (! thisline_changed) {
+               for (i = 0; i < nwords; i++) {
                        if (ptr[i]) {
                                thisline_changed = 1;
                                break;
                        }
-
-                       memset (ptr, 0, nwords * 4);
+               }
+       }
+       memset (ptr, 0, nwords * 4);
 }
 
 static void update_toscr_planes (void)
@@ -1249,7 +1250,6 @@ static void toscr_fm2 (int nbits) { toscr_0 (nbits, 2); }
 static int flush_plane_data (int fm)
 {
        int i = 0;
-       int fetchwidth = 16 << fm;
 
        if (out_nbits <= 16) {
                i += 16;
@@ -1271,6 +1271,13 @@ static int flush_plane_data (int fm)
                toscr_1 (16, fm);
        }
 
+       if (bpl1dat_early) {
+               // clear possible crap in right border if
+               // bpl1dat was written "out of sync"
+               toscr_1 (16, fm);
+               toscr_1 (16, fm);
+       }
+
        return i >> (1 + toscr_res);
 }
 
@@ -1851,9 +1858,11 @@ STATIC_INLINE void decide_line (int hpos)
                                if (hpos - 2 == ddfstrt_old_hpos)
                                        ok = 0;
                }
-               if (ok && dmaen (DMA_BITPLANE)) {
-                       start_bpl_dma (hpos, plfstrt);
-                       estimate_last_fetch_cycle (plfstrt);
+               if (ok) {
+                       if (dmaen (DMA_BITPLANE)) {
+                               start_bpl_dma (hpos, plfstrt);
+                               estimate_last_fetch_cycle (plfstrt);
+                       }
                        last_decide_line_hpos = hpos;
 #ifndef        CUSTOM_SIMPLE
                        do_sprites (plfstrt);
@@ -1865,8 +1874,8 @@ STATIC_INLINE void decide_line (int hpos)
 #ifndef        CUSTOM_SIMPLE
        if (last_sprite_decide_line_hpos < SPR0_HPOS + 4 * MAX_SPRITES)
                do_sprites (hpos);
-#endif
        last_sprite_decide_line_hpos = hpos;
+#endif
 
        last_decide_line_hpos = hpos;
 }
@@ -2323,7 +2332,7 @@ static void decide_sprites (int hpos)
        int sscanmask = 0x100 << sprite_buffer_res;
        int gotdata = 0;
 
-       if (thisline_decision.nr_planes == 0 && !(bplcon3 & 2))
+       if (thisline_decision.plfleft == -1 && !(bplcon3 & 2))
                return;
 
        if (nodraw () || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point)
@@ -2529,6 +2538,7 @@ static void reset_decisions (void)
        thisline_decision.bplres = bplcon0_res;
        thisline_decision.nr_planes = 0;
        bpl1dat_written = 0;
+       bpl1dat_early = 0;
 
        thisline_decision.plfleft = -1;
        thisline_decision.plflinelen = -1;
@@ -2915,7 +2925,7 @@ STATIC_INLINE int GETHPOS (void)
 STATIC_INLINE uae_u16 VPOSR (void)
 {
        unsigned int csbit = 0;
-       uae_u16 vp = (GETVPOS () >> 8) & 7;
+       uae_u16 vp = GETVPOS ();
        uae_u16 hp = GETHPOS ();
 
        if (hp + HPOS_OFFSET >= maxhpos) {
@@ -2923,6 +2933,8 @@ STATIC_INLINE uae_u16 VPOSR (void)
                if (vp >= maxvpos + lof)
                        vp = 0;
        }
+       vp = (vp >> 8) & 7;
+
        if (currprefs.cs_agnusrev >= 0) {
                csbit |= currprefs.cs_agnusrev  << 8;
        } else {
@@ -3504,6 +3516,8 @@ static void BPLxDAT (int hpos, int num, uae_u16 v)
        bplxdat[num] = v;
        if (num == 0) {
                bpl1dat_written = 1;
+               if (thisline_decision.plfleft == -1)
+                       bpl1dat_early = 1;
                maybe_first_bpl1dat (hpos);
        }
 }
diff --git a/disk.c b/disk.c
index 1950a724861ca01deb6ff3ca42d62ea3ba289173..91f2b73b902e44117cf63fff7fa3aafb683818b0 100644 (file)
--- a/disk.c
+++ b/disk.c
@@ -862,6 +862,8 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
        uae_char buffer[2 + 2 + 4 + 4];
        trackid *tid;
        int num_tracks, size;
+       int canauto;
+       TCHAR *ext;
 
        gui_disk_image_change (dnum, fname);
        drive_image_free (drv);
@@ -873,6 +875,13 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
        drv->useturbo = 0;
        drv->indexoffset = 0;
 
+       canauto = 0;
+       ext = _tcsrchr (fname, '.');
+       if (ext) {
+               if (!_tcsicmp (ext + 1, L"adf") || !_tcsicmp (ext + 1, L"adz") || !_tcsicmp (ext + 1, L"st") || !_tcsicmp (ext + 1, L"ima") || !_tcsicmp (ext + 1, L"img")) 
+                       canauto = 1;
+       }
+
        if (!drv->motoroff) {
                drv->dskready_time = DSKREADY_TIME;
                drv->dskready_down_time = 0;
@@ -985,7 +994,8 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
                }
                drv->useturbo = 1;
 
-       } else if (
+       } else if (canauto && (
+
                // double sided
                size == 9 * 80 * 2 * 512 || size == 18 * 80 * 2 * 512 || size == 10 * 80 * 2 * 512 || size == 20 * 80 * 2 * 512 ||
                size == 9 * 81 * 2 * 512 || size == 18 * 81 * 2 * 512 || size == 10 * 81 * 2 * 512 || size == 20 * 81 * 2 * 512 ||
@@ -993,7 +1003,7 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
                // single sided
                size == 9 * 80 * 1 * 512 || size == 18 * 80 * 1 * 512 || size == 10 * 80 * 1 * 512 || size == 20 * 80 * 1 * 512 ||
                size == 9 * 81 * 1 * 512 || size == 18 * 81 * 1 * 512 || size == 10 * 81 * 1 * 512 || size == 20 * 81 * 1 * 512 ||
-               size == 9 * 82 * 1 * 512 || size == 18 * 82 * 1 * 512 || size == 10 * 82 * 1 * 512 || size == 20 * 82 * 1 * 512) {
+               size == 9 * 82 * 1 * 512 || size == 18 * 82 * 1 * 512 || size == 10 * 82 * 1 * 512 || size == 20 * 82 * 1 * 512)) {
                        /* PC formatted image */
                        int i, side;
 
index 1940fb849c1a2d4835d9bd888764f0a94c547ee8..e872bd9c2960bcb4a4bc97a94982b0b173801fd0 100644 (file)
@@ -253,5 +253,5 @@ int ispctrack(uae_u16 *amigamfmbuffer, uae_u8 *mfmdata, int len, uae_u8 *writebu
        i = drive_write_adf_pc (amigamfmbuffer, amigamfmbuffer + len / 2, writebuffer, writebuffer_ok, track, outsize);
        if (*outsize < 9 * 512)
                *outsize = 9 * 512;
-       return i;
+       return i ? -1 : 0;
 }
index 3f5bf95cf24936a182a3f782355f49b3ab69d404..f61661dc196d9ef32374749637098fa11e494312 100644 (file)
--- a/drawing.c
+++ b/drawing.c
@@ -2564,9 +2564,9 @@ void draw_status_line_single (uae_u8 *buf, int bpp, int y, int totalwidth, uae_u
                on_rgb |= 0x33000000;
                off_rgb |= 0x33000000;
                if (half > 0) {
-                       c = ledcolor (on ? (y > TD_TOTAL_HEIGHT / 2 ? on_rgb2 : on_rgb) : off_rgb, rc, gc, bc, alpha);
+                       c = ledcolor (on ? (y >= TD_TOTAL_HEIGHT / 2 ? on_rgb2 : on_rgb) : off_rgb, rc, gc, bc, alpha);
                } else if (half < 0) {
-                       c = ledcolor (on ? (y <= TD_TOTAL_HEIGHT / 2 ? on_rgb2 : on_rgb) : off_rgb, rc, gc, bc, alpha);
+                       c = ledcolor (on ? (y < TD_TOTAL_HEIGHT / 2 ? on_rgb2 : on_rgb) : off_rgb, rc, gc, bc, alpha);
                } else {
                        c = ledcolor (on ? on_rgb : off_rgb, rc, gc, bc, alpha);
                }
index 9a9435540f3832c5732d1515f1d7eba9074aaea8..caf6e3d43ae99d72f66228ad03556a5384d7dfb8 100644 (file)
@@ -716,18 +716,10 @@ static uae_u64 vhd_write (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 off
                        // block already allocated in bitmap?
                        if (!(hfd->vhd_sectormap[bitmapoffsetbytes & 511] & (1 << (7 - (bitmapoffsetbits & 7))))) {
                                // no, we need to mark it allocated and write the modified bitmap back to the disk
-                               int j;
-                               for (j = 0; j < 512 / 4; j++) {
-                                       if (((uae_u32*)dataptr)[j])
-                                               break;
-                               }
-                               if (j < 512 / 4) {
-                                       // only mark it if there was non-zero data written
-                                       hfd->vhd_sectormap[bitmapoffsetbytes & 511] |= (1 << (7 - (bitmapoffsetbits & 7)));
-                                       if (hdf_write_target (hfd, hfd->vhd_sectormap, sectormapblock, 512) != 512) {
-                                               write_log (L"vhd_write: bam write error\n");
-                                               return written;
-                                       }
+                               hfd->vhd_sectormap[bitmapoffsetbytes & 511] |= (1 << (7 - (bitmapoffsetbits & 7)));
+                               if (hdf_write_target (hfd, hfd->vhd_sectormap, sectormapblock, 512) != 512) {
+                                       write_log (L"vhd_write: bam write error\n");
+                                       return written;
                                }
                        }
                        written += 512;
index 26f3dd84f68e6c317ba77df0b80dc7a51bae1a29..cd402ee1e1e1366168955828ab817e2b57f73102 100644 (file)
@@ -24,7 +24,7 @@ STATIC_INLINE void checkcycles_ce020 (void)
 STATIC_INLINE uae_u32 mem_access_delay_long_read_ce020 (uaecptr addr)
 {
        checkcycles_ce020 ();
-       switch (ce_banktype[(addr >> 16) & 0xff])
+       switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
                if ((addr & 3) != 0) {
@@ -51,7 +51,7 @@ STATIC_INLINE uae_u32 mem_access_delay_long_read_ce020 (uaecptr addr)
 STATIC_INLINE uae_u32 mem_access_delay_longi_read_ce020 (uaecptr addr)
 {
        checkcycles_ce020 ();
-       switch (ce_banktype[(addr >> 16) & 0xff])
+       switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
                if ((addr & 3) != 0) {
@@ -78,7 +78,7 @@ STATIC_INLINE uae_u32 mem_access_delay_longi_read_ce020 (uaecptr addr)
 STATIC_INLINE uae_u32 mem_access_delay_word_read_ce020 (uaecptr addr)
 {
        checkcycles_ce020 ();
-       switch (ce_banktype[(addr >> 16) & 0xff])
+       switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
                if ((addr & 3) == 3) {
@@ -103,7 +103,7 @@ STATIC_INLINE uae_u32 mem_access_delay_word_read_ce020 (uaecptr addr)
 STATIC_INLINE uae_u32 mem_access_delay_wordi_read_ce020 (uaecptr addr)
 {
        checkcycles_ce020 ();
-       switch (ce_banktype[(addr >> 16) & 0xff])
+       switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
                return wait_cpu_cycle_read_ce020 (addr, 1);
@@ -118,7 +118,7 @@ STATIC_INLINE uae_u32 mem_access_delay_wordi_read_ce020 (uaecptr addr)
 STATIC_INLINE uae_u32 mem_access_delay_byte_read_ce020 (uaecptr addr)
 {
        checkcycles_ce020 ();
-       switch (ce_banktype[(addr >> 16) & 0xff])
+       switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
                return wait_cpu_cycle_read_ce020 (addr, 0);
@@ -134,7 +134,7 @@ STATIC_INLINE uae_u32 mem_access_delay_byte_read_ce020 (uaecptr addr)
 STATIC_INLINE void mem_access_delay_byte_write_ce020 (uaecptr addr, uae_u32 v)
 {
        checkcycles_ce020 ();
-       switch (ce_banktype[(addr >> 16) & 0xff])
+       switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
                wait_cpu_cycle_write_ce020 (addr, 0, v);
@@ -150,7 +150,7 @@ STATIC_INLINE void mem_access_delay_byte_write_ce020 (uaecptr addr, uae_u32 v)
 STATIC_INLINE void mem_access_delay_word_write_ce020 (uaecptr addr, uae_u32 v)
 {
        checkcycles_ce020 ();
-       switch (ce_banktype[(addr >> 16) & 0xff])
+       switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
                if ((addr & 3) == 3) {
@@ -175,7 +175,7 @@ STATIC_INLINE void mem_access_delay_word_write_ce020 (uaecptr addr, uae_u32 v)
 STATIC_INLINE void mem_access_delay_long_write_ce020 (uaecptr addr, uae_u32 v)
 {
        checkcycles_ce020 ();
-       switch (ce_banktype[(addr >> 16) & 0xff])
+       switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
                if ((addr & 3) == 3) {
@@ -271,7 +271,7 @@ STATIC_INLINE uae_u32 next_ilong_020ce (void)
 
 STATIC_INLINE uae_u32 mem_access_delay_word_read (uaecptr addr)
 {
-       switch (ce_banktype[(addr >> 16) & 0xff])
+       switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
                return wait_cpu_cycle_read (addr, 1);
@@ -284,7 +284,7 @@ STATIC_INLINE uae_u32 mem_access_delay_word_read (uaecptr addr)
 }
 STATIC_INLINE uae_u32 mem_access_delay_wordi_read (uaecptr addr)
 {
-       switch (ce_banktype[(addr >> 16) & 0xff])
+       switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
                return wait_cpu_cycle_read (addr, 1);
@@ -297,7 +297,7 @@ STATIC_INLINE uae_u32 mem_access_delay_wordi_read (uaecptr addr)
 
 STATIC_INLINE uae_u32 mem_access_delay_byte_read (uaecptr addr)
 {
-       switch (ce_banktype[(addr >> 16) & 0xff])
+       switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
                return wait_cpu_cycle_read (addr, 0);
@@ -310,7 +310,7 @@ STATIC_INLINE uae_u32 mem_access_delay_byte_read (uaecptr addr)
 }
 STATIC_INLINE void mem_access_delay_byte_write (uaecptr addr, uae_u32 v)
 {
-       switch (ce_banktype[(addr >> 16) & 0xff])
+       switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
                wait_cpu_cycle_write (addr, 0, v);
@@ -323,7 +323,7 @@ STATIC_INLINE void mem_access_delay_byte_write (uaecptr addr, uae_u32 v)
 }
 STATIC_INLINE void mem_access_delay_word_write (uaecptr addr, uae_u32 v)
 {
-       switch (ce_banktype[(addr >> 16) & 0xff])
+       switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
                wait_cpu_cycle_write (addr, 1, v);
index e49578c7b6c448c508b5f9951ec3f1acd1664fe5..b369218cfe8d73367abbc291a978621dd092b1cf 100644 (file)
@@ -101,7 +101,7 @@ typedef struct {
 #define CE_MEMBANK_CHIP 1
 #define CE_MEMBANK_CIA 2
 #define CE_MEMBANK_FAST16BIT 3
-extern uae_u8 ce_banktype[256];
+extern uae_u8 ce_banktype[65536];
 
 extern uae_u8 *filesysory;
 extern uae_u8 *rtarea;
index 0ba55c7dbb45c404cc65296b5a38320947bc2301..bdfee4e47a455e4ee8666ce962a73963c613ae50 100644 (file)
@@ -41,3 +41,9 @@ extern int uaeser_break (void*, int brklen);
 extern void uaeser_signal (void*, int source);
 extern void uaeser_trigger (void*);
 extern void uaeser_clearbuffers (void*);
+
+extern void enet_writeser (uae_u16);
+extern int enet_readseravail (void);
+extern int enet_readser (uae_u16 *buffer);
+extern int enet_open (TCHAR *name);
+extern void enet_close (void);
index fc8f1a28bf879f0709364cf126e0dd4de0522693..79f467de18b7d4af49126528056dd0ecd81f34a8 100644 (file)
@@ -124,7 +124,7 @@ extern struct zvolume *archive_directory_fat (struct zfile *z);
 extern struct zfile *archive_access_fat (struct znode *zn);
 extern struct zfile *archive_access_dir (struct znode *zn);
 
-extern struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, unsigned int id, int doselect, int *retcode);
+extern struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, unsigned int id, int doselect, int *retcode, int index);
 extern struct zfile *archive_access_arcacc_select (struct zfile *zf, unsigned int id, int *retcode);
 extern int isfat (uae_u8*);
 
index 626b2731395be8a4eb0a3847b24180d003ebbc31..57cda6eaf3b1bc0907d2207e9fc86252d99d2d8d 100644 (file)
@@ -12,6 +12,7 @@ struct zvolume;
 typedef int (*zfile_callback)(struct zfile*, void*);
 
 extern struct zfile *zfile_fopen (const TCHAR *, const TCHAR *, int mask);
+extern struct zfile *zfile_fopen2 (const TCHAR *, const TCHAR *, int mask, int index);
 extern struct zfile *zfile_fopen_empty (struct zfile*, const TCHAR *name, uae_u64 size);
 extern struct zfile *zfile_fopen_data (const TCHAR *name, uae_u64 size, uae_u8 *data);
 extern struct zfile *zfile_fopen_parent (struct zfile*, const TCHAR*, uae_u64 offset, uae_u64 size);
@@ -44,7 +45,7 @@ extern struct zfile *zfile_gunzip (struct zfile *z);
 extern int zfile_is_diskimage (const TCHAR *name);
 extern int iszip (struct zfile *z);
 extern int zfile_convertimage (const TCHAR *src, const TCHAR *dst);
-extern struct zfile *zuncompress (struct znode*, struct zfile *z, int dodefault, int mask, int *retcode);
+extern struct zfile *zuncompress (struct znode*, struct zfile *z, int dodefault, int mask, int *retcode, int index);
 extern void zfile_seterror (const TCHAR *format, ...);
 extern TCHAR *zfile_geterror (void);
 
index 1f268adc10e795d6a6c8780867eb700d764c561a..0940c4ae44cbd6777696938871688141cc57875f 100644 (file)
--- a/memory.c
+++ b/memory.c
@@ -64,7 +64,7 @@ uae_u32 allocated_z3fastmem, allocated_z3fastmem2;
 uae_u32 allocated_a3000lmem;
 uae_u32 allocated_a3000hmem;
 uae_u32 allocated_cardmem;
-uae_u8 ce_banktype[256];
+uae_u8 ce_banktype[65536];
 
 #if defined(CPU_64_BIT)
 uae_u32 max_z3fastmem = 2048UL * 1024 * 1024;
@@ -1139,11 +1139,18 @@ static uae_u32 dummy_get (uaecptr addr, int size)
        if (currprefs.cpu_model >= 68020)
                return NONEXISTINGDATA;
        v = (regs.irc << 16) | regs.irc;
-       if (v == 4)
-               return v;
-       if (v == 2)
-               return v & 0xffff;
-       return (addr & 1) ? (v & 0xff) : ((v >> 8) & 0xff);
+       if (size == 4) {
+               ;
+       } else if (size == 2) {
+               v &= 0xffff;
+       } else {
+               v = (addr & 1) ? (v & 0xff) : ((v >> 8) & 0xff);
+       }
+#if 0
+       if (addr >= 0x10000000)
+               write_log (L"%08X %d = %08x\n", addr, size, v);
+#endif
+       return v;
 }
 
 static uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
@@ -3385,7 +3392,7 @@ static void fill_ce_banks (void)
 {
        int i;
 
-       memset (ce_banktype, CE_MEMBANK_FAST, 256);
+       memset (ce_banktype, CE_MEMBANK_FAST, sizeof ce_banktype);
        if (&get_mem_bank (0) == &chipmem_bank) {
                for (i = 0; i < (0x200000 >> 16); i++)
                        ce_banktype[i] = CE_MEMBANK_CHIP;
@@ -3410,6 +3417,10 @@ static void fill_ce_banks (void)
                for (i = (0xf80000 >> 16); i <= (0xff0000 >> 16); i++)
                        ce_banktype[i] = CE_MEMBANK_FAST16BIT;
        }
+       if (currprefs.address_space_24) {
+               for (i = 1; i < 256; i++)
+                       memcpy (&ce_banktype[i * 256], &ce_banktype[0], 256);
+       }
 }
 
 void map_overlay (int chip)
index 204189ad7a51d55254aa97aaedf66e7440082212..82d6177f15053b99d591522d20eebba9b8fc16b8 100644 (file)
--- a/newcpu.c
+++ b/newcpu.c
@@ -2705,7 +2705,7 @@ STATIC_INLINE int do_specialties (int cycles)
 
 void prepare_interrupt (void)
 {
-       interrupt_cycles = get_cycles () + 6 * CYCLE_UNIT;
+       interrupt_cycles = get_cycles () + 5 * CYCLE_UNIT + CYCLE_UNIT / 2;
        interrupt_cycles_active = 1;
 }
 
index 5544888f48df3164d864125414dbc353a8849cd2..62c703f983620db5985130d15b7ea9219381a636 100644 (file)
@@ -446,7 +446,7 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
                                        i += 2;
                                }
                                if (v >= 0)
-                                       code = AKS_STATESAVEQUICK + v * 2 + ((shiftpressed () || ctrlpressed()) ? 0 : 1);
+                                       code = AKS_STATESAVEQUICK + v * 2 + ((shiftpressed () || ctrlpressed ()) ? 0 : 1);
                        }
                        break;
                case DIK_SYSRQ:
index 8d69731975978e9b4f8aa8d524e9665b094cffba..f7f04c375782e5a7f194972ae979c2d3cb40596e 100644 (file)
@@ -8,6 +8,9 @@
 */
 
 #include "sysconfig.h"
+
+//#undef SERIAL_ENET
+
 #include <windows.h>
 #include <winspool.h>
 #include <stdlib.h>
@@ -1265,13 +1268,15 @@ int enumserialports (void)
        write_log (L"Serial port enumeration..\n");
        cnt = 0;
 
-#if 0
+#ifdef SERIAL_ENET
        comports[cnt].dev = my_strdup (L"ENET:H");
        comports[cnt].cfgname = my_strdup (comports[0].dev);
-       comports[cnt++].name = my_strdup (L"NET (host)");
+       comports[cnt].name = my_strdup (L"NET (host)");
+       cnt++;
        comports[cnt].dev = my_strdup (L"ENET:L");
        comports[cnt].cfgname = my_strdup (comports[1].dev);
-       comports[cnt++].name = my_strdup (L"NET (client)");
+       comports[cnt].name = my_strdup (L"NET (client)");
+       cnt++;
 #endif
 
        cnt = enumserialports_2 (cnt);
index f2d9820e092d7c6d79088e983e15148b05196b68..3d7c821a7c725173f914ac72ac4e730119428693 100644 (file)
@@ -8,7 +8,11 @@
 *
 */
 
+
 #include "sysconfig.h"
+#ifdef SERIAL_ENET
+#include "enet/enet.h"
+#endif
 #include "sysdeps.h"
 
 #include "options.h"
@@ -36,9 +40,10 @@ static int serial_period_hsyncs, serial_period_hsync_counter;
 static int ninebit;
 int serdev;
 int seriallog;
+int serial_enet;
 
-void serial_open(void);
-void serial_close(void);
+void serial_open (void);
+void serial_close (void);
 
 uae_u16 serper, serdat, serdatr;
 
@@ -100,7 +105,44 @@ static uae_char dochar (int v)
        return '.';
 }
 
-static void checkreceive (int mode)
+static void checkreceive_enet (int mode)
+{
+#ifdef SERIAL_ENET
+       static uae_u32 lastchartime;
+       struct timeval tv;
+       uae_u16 recdata;
+
+       if (!enet_readseravail ())
+               return;
+       if (data_in_serdatr) {
+               /* probably not needed but there may be programs that expect OVRUNs.. */
+               gettimeofday (&tv, NULL);
+               if (tv.tv_sec > lastchartime) {
+                       ovrun = 1;
+                       INTREQ (0x8000 | 0x0800);
+                       while (enet_readser (&recdata));
+                       write_log (L"SERIAL: overrun\n");
+               }
+               return;
+       }
+       if (!enet_readser (&recdata))
+               return;
+       serdatr = recdata & 0x1ff;
+       if (recdata & 0x200)
+               serdatr |= 0x200;
+       else
+               serdatr |= 0x100;
+       gettimeofday (&tv, NULL);
+       lastchartime = tv.tv_sec + 5;
+       data_in_serdatr = 1;
+       serial_check_irq ();
+#if SERIALDEBUG > 2
+       write_log (L"SERIAL: received %02X (%c)\n", serdatr & 0xff, doTCHAR (serdatr));
+#endif
+#endif
+}
+
+static void checkreceive_serial (int mode)
 {
 #ifdef SERIAL_PORT
        static uae_u32 lastchartime;
@@ -108,7 +150,7 @@ static void checkreceive (int mode)
        struct timeval tv;
        int recdata;
 
-       if (!readseravail())
+       if (!readseravail ())
                return;
 
        if (data_in_serdatr) {
@@ -165,6 +207,10 @@ static void checksend (int mode)
 
 #ifdef SERIAL_PORT
        bufstate = checkserwrite ();
+#endif
+#ifdef SERIAL_ENET
+       if (serial_enet)
+               bufstate = 1;
 #endif
        if (!data_in_serdat && !data_in_sershift)
                return;
@@ -175,6 +221,11 @@ static void checksend (int mode)
        if (data_in_serdat && !data_in_sershift) {
                data_in_sershift = 1;
                serdatshift = serdat;
+#ifdef SERIAL_ENET
+               if (serial_enet) {
+                       enet_writeser (serdatshift);
+               }
+#endif
 #ifdef SERIAL_PORT
                if (ninebit)
                        writeser (((serdatshift >> 8) & 1) | 0xa8);
@@ -197,8 +248,10 @@ void serial_hsynchandler (void)
        if (serial_period_hsyncs == 0)
                return;
        serial_period_hsync_counter++;
-       if (serial_period_hsyncs == 1 || (serial_period_hsync_counter % (serial_period_hsyncs - 1)) == 0)
-               checkreceive (0);
+       if (serial_period_hsyncs == 1 || (serial_period_hsync_counter % (serial_period_hsyncs - 1)) == 0) {
+               checkreceive_serial (0);
+               checkreceive_enet (0);
+       }
        if ((serial_period_hsync_counter % serial_period_hsyncs) == 0)
                checksend (0);
 }
@@ -432,15 +485,24 @@ uae_u8 serial_writestatus (uae_u8 newstate, uae_u8 dir)
        return oldserbits;
 }
 
+static int enet_is (TCHAR *name)
+{
+       return !_tcsnicmp (name, L"ENET:", 5);
+}
+
 void serial_open (void)
 {
 #ifdef SERIAL_PORT
        if (serdev)
                return;
        serper = 0;
-       if(!openser (currprefs.sername)) {
-               write_log (L"SERIAL: Could not open device %s\n", currprefs.sername);
-               return;
+       if (enet_is (currprefs.sername)) {
+               enet_open (currprefs.sername);
+       } else {
+               if(!openser (currprefs.sername)) {
+                       write_log (L"SERIAL: Could not open device %s\n", currprefs.sername);
+                       return;
+               }
        }
        serdev = 1;
 #endif
@@ -450,6 +512,7 @@ void serial_close (void)
 {
 #ifdef SERIAL_PORT
        closeser ();
+       enet_close ();
        serdev = 0;
 #endif
 }
@@ -459,10 +522,8 @@ void serial_init (void)
 #ifdef SERIAL_PORT
        if (!currprefs.use_serial)
                return;
-
        if (!currprefs.serial_demand)
                serial_open ();
-
 #endif
 }
 
@@ -481,3 +542,138 @@ void serial_uartbreak (int v)
        serialuartbreak (v);
 #endif
 }
+
+#ifdef SERIAL_ENET
+static ENetHost *enethost, *enetclient;
+static ENetPeer *enetpeer;
+static int enetmode;
+
+void enet_close (void)
+{
+       if (enethost)
+               enet_host_destroy (enethost);
+       enethost = NULL;
+       if (enetclient)
+               enet_host_destroy (enetclient);
+       enetclient = NULL;
+}
+
+int enet_open (TCHAR *name)
+{
+       ENetAddress address;
+       static int initialized;
+
+       if (!initialized) {
+               int err = enet_initialize ();
+               if (err) {
+                       write_log (L"ENET: initialization failed: %d\n", err);
+                       return 0;
+               }
+               initialized = 1;
+       }
+       
+       enet_close ();
+       enetmode = 0;
+       if (!_tcsnicmp (name, L"ENET:L", 6)) {
+               enetclient = enet_host_create (NULL, 1, 0, 0);
+               if (enetclient == NULL) {
+                       write_log (L"ENET: enet_host_create(client) failed\n");
+                       return 0;
+               }
+               write_log (L"ENET: client created\n");
+               enet_address_set_host (&address, "192.168.0.10");
+               address.port = 1234;
+               enetpeer = enet_host_connect (enetclient, &address, 2);
+               if (enetpeer == NULL) {
+                       write_log (L"ENET: connection to host failed\n");
+                       enet_host_destroy (enetclient);
+                       enetclient = NULL;
+               }
+               write_log (L"ENET: connection initialized\n");
+               enetmode = -1;
+               return 1;
+       } else if (!_tcsnicmp (name, L"ENET:H", 6)) {
+               address.host = ENET_HOST_ANY;
+               address.port = 1234;
+               enethost = enet_host_create (&address, 2, 0, 0);
+               if (enethost == NULL) {
+                       write_log (L"ENET: enet_host_create(server) failed\n");
+                       return 0;
+               }
+               write_log (L"ENET: server created\n");
+               enet_address_set_host (&address, "127.0.0.1");
+               address.port = 1234;
+               enetpeer = enet_host_connect (enethost, &address, 2);
+               if (enetpeer == NULL) {
+                       write_log (L"ENET: connection to localhost failed\n");
+                       enet_host_destroy (enetclient);
+                       enetclient = NULL;
+               }
+               write_log (L"ENET: local connection initialized\n");
+               enetmode = 1;
+               return 1;
+       }
+       return 0;
+}
+
+void enet_writeser (uae_u16 w)
+{
+       ENetPacket *p;
+       uae_u8 data[16];
+
+       strcpy (data, "UAE_");
+       data[4] = w >> 8;
+       data[5] = w >> 0;
+       p = enet_packet_create (data, 6, ENET_PACKET_FLAG_RELIABLE);
+       enet_peer_send (enetpeer, 0, p);
+}
+
+static uae_u16 enet_receive[256];
+static int enet_receive_off_w, enet_receive_off_r;
+
+int enet_readseravail (void)
+{
+       ENetEvent evt;
+       ENetHost *host;
+       
+       if (enetmode == 0)
+               return 0;
+       host = enetmode < 0 ? enetclient : enethost;
+       while (enet_host_service (host, &evt, 0)) {
+               switch (evt.type)
+               {
+                       case ENET_EVENT_TYPE_CONNECT:
+                               write_log (L"ENET: connect from %x:%u\n",
+                                       evt.peer->address.host, evt.peer->address.port);
+                               evt.peer->data = 0;
+                       break;
+                       case ENET_EVENT_TYPE_RECEIVE:
+                       {
+                               uae_u8 *p = evt.packet->data;
+                               int len = evt.packet->dataLength;
+                               write_log (L"ENET: packet received, %d bytes\n", len);
+                               if (len == 6) {
+                                       if (((enet_receive_off_w + 1) & 0xff) != enet_receive_off_r) {
+                                               enet_receive[enet_receive_off_w++] = (p[4] << 8) | p[5];
+                                       }
+                               }
+
+                               enet_packet_destroy (evt.packet);
+                       }
+                       break;
+                       case ENET_EVENT_TYPE_DISCONNECT:
+                               write_log (L"ENET: disconnect %p\n", evt.peer->data);
+                       break;
+               }
+       }
+       return 0;
+}
+int enet_readser (uae_u16 *data)
+{
+       if (enet_receive_off_r == enet_receive_off_w)
+               return 0;
+       *data = enet_receive[enet_receive_off_r++];
+       enet_receive_off_r &= 0xff;
+       return 1;
+}
+#endif
\ No newline at end of file
index 1dcb6e2ea05c2e0604aac25af53614167774716c..302dcac02985de07de15e7a7b429b12230a3b4b2 100644 (file)
@@ -37,6 +37,7 @@
 #define PARALLEL_PORT /* parallel port emulation */
 #define PARALLEL_DIRECT /* direct parallel port emulation */
 #define SERIAL_PORT /* serial port emulation */
+#define SERIAL_ENET /* serial port UDP transport */
 #define SCSIEMU /* uaescsi.device emulation */
 #define UAESERIAL /* uaeserial.device emulation */
 #define FPUEMU /* FPU emulation */
index 52bbebd7ada754c3581decb31efb0c3b11b06ae2..30123319b9057b96311140ac3a4904cd01088059 100644 (file)
@@ -17,8 +17,8 @@
 
 #define WINUAEPUBLICBETA 1
 
-#define WINUAEBETA L"20"
-#define WINUAEDATE MAKEBD(2009, 11, 7)
+#define WINUAEBETA L"21"
+#define WINUAEDATE MAKEBD(2009, 11, 15)
 #define WINUAEEXTRA L""
 #define WINUAEREV L""
 
index 443395b4fd34c5b9d7274519c76ec2bd0de8658e..7740f75dabcc83f74259eb9cd7b9b19684e2354b 100644 (file)
@@ -1475,6 +1475,16 @@ static const GUID diskselectionguids[] = {
        { 0xe3741dff, 0x11f2, 0x445f, { 0x94, 0xb0, 0xa3, 0xe7, 0x58, 0xe2, 0xcb, 0xb5 } },
        { 0x2056d641, 0xba13, 0x4312, { 0xaa, 0x75, 0xc5, 0xeb, 0x52, 0xa8, 0x1c, 0xe3 } }
 };
+static void getfilter (int num, TCHAR *name, int *filter, TCHAR *fname)
+{
+       _tcscpy (fname, name);
+       _tcscat (fname, L"_Filter");
+       regqueryint (NULL, fname, &filter[num]);
+}
+static void setfilter (int num, int *filter, TCHAR *fname)
+{
+       regsetint (NULL, fname, filter[num]);
+}
 
 // Common routine for popping up a file-requester
 // flag - 0 for floppy loading, 1 for floppy creation, 2 for loading hdf, 3 for saving hdf
@@ -1491,8 +1501,8 @@ static const GUID diskselectionguids[] = {
 // flag = 16 for recording input
 int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs, TCHAR *path_out, int *multi)
 {
-       static int statefile_previousfilter;
        static int previousfilter[20];
+       TCHAR filtername[MAX_DPATH] = L"";
        OPENFILENAME openFileName;
        TCHAR full_path[MAX_DPATH] = L"";
        TCHAR full_path2[MAX_DPATH];
@@ -1522,23 +1532,27 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                {
                case 0:
                case 1:
+                       getfilter(flag, L"FloppyPath", previousfilter, filtername);
                        fetch_path (L"FloppyPath", init_path, sizeof (init_path) / sizeof (TCHAR));
                        guid = &diskselectionguids[0];
                        break;
                case 2:
                case 3:
+                       getfilter(flag, L"hdfPath", previousfilter, filtername);
                        fetch_path (L"hdfPath", init_path, sizeof (init_path) / sizeof (TCHAR));
                        guid = &diskselectionguids[1];
                        break;
                case 6:
                case 7:
                case 11:
+                       getfilter(flag, L"KickstartPath", previousfilter, filtername);
                        fetch_path (L"KickstartPath", init_path, sizeof (init_path) / sizeof (TCHAR));
                        guid = &diskselectionguids[2];
                        break;
                case 4:
                case 5:
                case 8:
+                       getfilter(flag, L"ConfigurationPath", previousfilter, filtername);
                        fetch_path (L"ConfigurationPath", init_path, sizeof (init_path) / sizeof (TCHAR));
                        guid = &diskselectionguids[3];
                        break;
@@ -1562,13 +1576,16 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                                                *p = 0;
                                        }
                                }
-                               if (!ok)
+                               if (!ok) {
+                                       getfilter(flag, L"StatefilePath", previousfilter, filtername);
                                        fetch_path (L"StatefilePath", init_path, sizeof (init_path) / sizeof (TCHAR));
+                               }
                                guid = &diskselectionguids[4];
                        }
                        break;
                case 15:
                case 16:
+                       getfilter(flag, L"InputPath", previousfilter, filtername);
                        fetch_path (L"InputPath", init_path, sizeof (init_path) / sizeof (TCHAR));
                        guid = &diskselectionguids[5];
                        break;
@@ -1729,7 +1746,10 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                if (!(result = GetOpenFileName_2 (&openFileName, guid)))
                        write_log (L"GetOpenFileNameX() failed, err=%d.\n", GetLastError ());
        }
-       previousfilter[flag] = openFileName.nFilterIndex;
+       if (result) {
+               previousfilter[flag] = openFileName.nFilterIndex;
+               setfilter (flag, previousfilter, filtername);
+       }
 
        memcpy (full_path2, full_path, sizeof (full_path) / sizeof (TCHAR));
        memcpy (stored_path, full_path, sizeof (stored_path) / sizeof (TCHAR));
@@ -7671,6 +7691,14 @@ static void volumeselectdir (HWND hDlg, int newdir)
        }
 }
 
+static void fixvol (TCHAR *s)
+{
+       if (_tcslen (s) == 0)
+               return;
+       if (s[_tcslen (s) - 1] == ':')
+               s[_tcslen (s) - 1] = 0;
+}
+
 static INT_PTR CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
        static int recursive = 0;
@@ -7747,7 +7775,9 @@ static INT_PTR CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
                }
                GetDlgItemText (hDlg, IDC_PATH_NAME, current_fsvdlg.rootdir, sizeof current_fsvdlg.rootdir / sizeof (TCHAR));
                GetDlgItemText (hDlg, IDC_VOLUME_NAME, current_fsvdlg.volume, sizeof current_fsvdlg.volume / sizeof (TCHAR));
+               fixvol (current_fsvdlg.volume);
                GetDlgItemText (hDlg, IDC_VOLUME_DEVICE, current_fsvdlg.device, sizeof current_fsvdlg.device / sizeof (TCHAR));
+               fixvol (current_fsvdlg.device);
                current_fsvdlg.rw = IsDlgButtonChecked (hDlg, IDC_FS_RW);
                current_fsvdlg.bootpri = GetDlgItemInt (hDlg, IDC_VOLUME_BOOTPRI, NULL, TRUE);
                current_fsvdlg.autoboot = IsDlgButtonChecked (hDlg, IDC_FS_AUTOBOOT);
index 258ed5c584eaa3925eef8558066fab0f5cced12b..4b2466b56d148d0ef86385c7671e1e814413c3e4 100644 (file)
@@ -87,7 +87,7 @@
                        <Tool
                                Name="VCLinkerTool"
                                AdditionalOptions="/MACHINE:I386"
-                               AdditionalDependencies="ws2_32.lib ddraw.lib dxguid.lib winmm.lib comctl32.lib version.lib msacm32.lib dsound.lib dinput8.lib d3d9.lib d3dx9.lib winio.lib setupapi.lib wininet.lib dxerr.lib shlwapi.lib zlibstat.lib libpng.lib lglcd.lib wpcap.lib packet.lib openal32.lib wintab32.lib portaudio_x86.lib freetype.lib vfw32.lib wtsapi32.lib avrt.lib wininet.lib"
+                               AdditionalDependencies="ws2_32.lib ddraw.lib dxguid.lib winmm.lib comctl32.lib version.lib msacm32.lib dsound.lib dinput8.lib d3d9.lib d3dx9.lib winio.lib setupapi.lib wininet.lib dxerr.lib shlwapi.lib zlibstat.lib libpng.lib lglcd.lib wpcap.lib packet.lib openal32.lib wintab32.lib portaudio_x86.lib freetype.lib vfw32.lib wtsapi32.lib avrt.lib wininet.lib enet.lib"
                                ShowProgress="0"
                                OutputFile="d:\amiga\winuae.exe"
                                LinkIncremental="2"
                        />
                        <Tool
                                Name="VCLinkerTool"
-                               AdditionalDependencies="ws2_32.lib ddraw.lib dxguid.lib winmm.lib comctl32.lib version.lib msacm32.lib dsound.lib dinput8.lib d3d9.lib d3dx9.lib winio.lib setupapi.lib wininet.lib dxerr.lib shlwapi.lib zlibstat.lib libpng.lib lglcd.lib wpcap.lib packet.lib openal32.lib wintab32.lib portaudio_x86.lib freetype.lib vfw32.lib wtsapi32.lib avrt.lib wininet.lib"
+                               AdditionalDependencies="ws2_32.lib ddraw.lib dxguid.lib winmm.lib comctl32.lib version.lib msacm32.lib dsound.lib dinput8.lib d3d9.lib d3dx9.lib winio.lib setupapi.lib wininet.lib dxerr.lib shlwapi.lib zlibstat.lib libpng.lib lglcd.lib wpcap.lib packet.lib openal32.lib wintab32.lib portaudio_x86.lib freetype.lib vfw32.lib wtsapi32.lib avrt.lib wininet.lib enet.lib"
                                OutputFile="d:\amiga\winuae.exe"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
                        />
                        <Tool
                                Name="VCLinkerTool"
-                               AdditionalDependencies="ws2_32.lib ddraw.lib dxguid.lib winmm.lib comctl32.lib version.lib msacm32.lib dsound.lib dinput8.lib d3d9.lib d3dx9.lib winio.lib setupapi.lib wininet.lib dxerr.lib shlwapi.lib zlibstat.lib libpng.lib lglcd.lib wpcap.lib packet.lib openal32.lib wintab32.lib portaudio_x86.lib freetype.lib vfw32.lib wtsapi32.lib avrt.lib wininet.lib"
+                               AdditionalDependencies="ws2_32.lib ddraw.lib dxguid.lib winmm.lib comctl32.lib version.lib msacm32.lib dsound.lib dinput8.lib d3d9.lib d3dx9.lib winio.lib setupapi.lib wininet.lib dxerr.lib shlwapi.lib zlibstat.lib libpng.lib lglcd.lib wpcap.lib packet.lib openal32.lib wintab32.lib portaudio_x86.lib freetype.lib vfw32.lib wtsapi32.lib avrt.lib wininet.lib enet.lib"
                                OutputFile="d:\amiga\winuae.exe"
                                LinkIncremental="1"
                                SuppressStartupBanner="true"
index fc63efa5a682d8c8b2739bcee2a031042238ceac..6021e96dbce52d7277eec692b92ccaa7e00aa16b 100644 (file)
@@ -1,4 +1,25 @@
 
+Beta 21:
+
+- stupid b20 VPOSR bug fixed (upper vpos bits returned "random" data
+  when new frame was about to start)
+- "manual" BPL1DAT write update, Sequential / Andromeda "Magnet"-part
+- interrupt delay changed to 5.5 (was 6) color clocks (<=5: Gleat Stuff
+  #1 breaks, >=6: Warhead audio breaks)
+- reading non-existing memory in 68000 CE-mode was broken (upper byte
+  was always zero), fixes Time Machine (game has buggy IFF animation
+  reader, IFF parser checks end of file incorrectly and keeps reading
+  "random" data and accessing "random" memory)
+- ProWizard promizer20 converter update (Asle)
+- only autodetect PC/Atari ST image files if file name extension is
+  known (adf, adz, st, ima or img)
+- file dialog file type setting is stored to registry/ini
+- some work with serial port emulation via UDP (ENET). May or may not
+  be implemented before final 2.0. (if you are wondering about ENET in
+  serial port settings..) NOTE: do not expect most serial linked games
+  to work, at least via Internet.. null-modem games expect extremely
+  low latencies.
+
 Beta 20:
 
 - 68000 CE timing updates
index 967e9221be2415084aad7d84f4e3deef1df1c8f8..b0f0c95c4b43b18b3bb2f83cb823150a9d535b19 100644 (file)
@@ -1,3 +1,6 @@
+/* 20091113 - fixed patternlist generation and cleaned a bit */
+
+
 /* testPM2() */
 /* Rip_PM20() */
 /* Depack_PM20() */
@@ -73,17 +76,16 @@ void Rip_PM20 ( void )
 
 void Depack_PM20 ( void )
 {
-  Uchar c1=0x00,c2=0x00;
+  //Uchar c1=0x00;
   short Ref_Max=0;
   long Pats_Address[128];
-  long Read_Pats_Address[128];
   Uchar NOP=0x00; /* number of pattern */
   Uchar *ReferenceTable;
   Uchar *Pattern;
-  long i=0,j=0,k=0,m=0;
+  //long i=0,j=0,k=0,m=0;
   long Total_Sample_Size=0;
   long PatDataSize=0l;
-  long SDAV=0l;
+  //long SDAV=0l;
   Uchar FLAG=OFF;
   Uchar poss[37][2];
   Uchar Note,Smp;
@@ -103,56 +105,83 @@ void Depack_PM20 ( void )
 
   BZERO ( Pats_Address , 128*4 );
 
-  Whatever = (Uchar *) malloc (128);
-  BZERO (Whatever, 128);
-  /* title */
-  fwrite ( &Whatever[0] , 20 , 1 , out );
+  Whatever = (Uchar *) malloc (1085);
+  BZERO (Whatever, 1085);
 
   /* bypass replaycode routine */
-  Where += SAMPLE_DESC;  /* SEEK_SET */
+  Where += SAMPLE_DESC;
 
-  for ( i=0 ; i<31 ; i++ )
+  for ( PW_i=0 ; PW_i<31 ; PW_i++ )
   {
-    /*sample name*/
-    fwrite ( &Whatever[32] , 22 , 1 , out );
-
-    in_data[Where+2] /= 2;
-    if ( (in_data[Where+6] == 0x00) && (in_data[Where+7] == 0x00) )in_data[Where+7] = 0x01;
-    fwrite ( &in_data[Where], 8, 1, out );
-    
-    Total_Sample_Size += (((in_data[Where]*256)+in_data[Where+1])*2);
+    Whatever[PW_i*30+42] = in_data[Where];
+    Whatever[PW_i*30+43] = in_data[Where+1];
+    Total_Sample_Size += (((Whatever[PW_i*30+42]*256)+Whatever[PW_i*30+43])*2);
+    Whatever[PW_i*30+44] = in_data[Where+2]/2;
+    Whatever[PW_i*30+45] = in_data[Where+3];
+    Whatever[PW_i*30+46] = in_data[Where+4];
+    Whatever[PW_i*30+47] = in_data[Where+5];
+    Whatever[PW_i*30+48] = in_data[Where+6];
+    Whatever[PW_i*30+49] = in_data[Where+7];
+    if ( (Whatever[PW_i*30+48] == 0x00) && (Whatever[PW_i*30+49] == 0x00) )Whatever[PW_i*30+49] = 0x01;
+
     Where += 8;
   }
 
-  /*printf ( "REAL Number of patterns : %d\n" , NOP );*/
-
   /* read "used" size of pattern table */
   Where = PW_Start_Address + AFTER_REPLAY_CODE + 2;
   NOP = ((in_data[Where]*256)+in_data[Where+1])/2;
   Where += 2;
-  /*fprintf ( info, "Number of pattern in pattern list : %d\n" , NOP );*/
+  /*printf ( "Number of pattern in pattern list : %d\n" , NOP );*/
 
   /* write size of pattern list */
-  fwrite ( &NOP , 1 , 1 , out );
+  Whatever[950] = NOP;
 
   /* NoiseTracker restart byte */
-  c1 = 0x7f;
-  fwrite ( &c1 , 1 , 1 , out );
+  Whatever[951] = 0x7f;
 
   /* read pattern addys */
-  for ( i=0 ; i<128 ; i++ )
+  for ( PW_i=0 ; PW_i<NOP ; PW_i++ )
   {
-    Pats_Address[i] = (in_data[Where]*256)+in_data[Where+1];
+    Pats_Address[PW_i] = (in_data[Where]*256)+in_data[Where+1] + AFTER_REPLAY_CODE + 4;
     Where += 2;
-    /*fprintf ( info, "[%3ld] : %ld\n", i, Pats_Address[i] );*/
+    //printf ( "[%3ld] : %ld\n", PW_i, Pats_Address[PW_i] );
   }
 
+  /* write pattern table */
+  PW_k = PW_l = 0;
+  for (PW_j=0; PW_j<NOP ; PW_j++)
+  {
+    PW_m = 0x7fffffff; /* min */
+    /*search for min */
+    for (PW_i=0; PW_i<NOP ; PW_i++)
+      if ((Pats_Address[PW_i]<PW_m) && (Pats_Address[PW_i]>PW_k))
+           PW_m = Pats_Address[PW_i];
+    /* if PW_k == PW_m then an already ref was found */
+    if (PW_k == PW_m)
+      continue;
+    /* PW_m is the next minimum */
+    PW_k = PW_m;
+    for (PW_i=0; PW_i<NOP ; PW_i++)
+      if (Pats_Address[PW_i] == PW_k)
+       Whatever[952+PW_i] = (unsigned char)PW_l;
+    PW_l++;
+  }
+  /* PW_l is now the number of pattern saved (+1) */
+  PW_l -= 1;
+
+  /* write tag */
+  Whatever[1080] = 'M';
+  Whatever[1081] = '.';
+  Whatever[1082] = 'K';
+  Whatever[1083] = '.';
+
+  fwrite ( Whatever, 1, 1084, out );
 
   /* a little pre-calc code ... no other way to deal with these unknown pattern data sizes ! :( */
   /* so, first, we get the pattern data size .. */
   Where = PW_Start_Address + ADDRESS_REF_TABLE;
-  j = (in_data[Where]*256*256*256)+(in_data[Where+1]*256*256)+(in_data[Where+2]*256)+in_data[Where+3];
-  PatDataSize = (AFTER_REPLAY_CODE + j) - PATTERN_DATA;
+  PW_j = (in_data[Where]*256*256*256)+(in_data[Where+1]*256*256)+(in_data[Where+2]*256)+in_data[Where+3];
+  PatDataSize = (AFTER_REPLAY_CODE + PW_j) - PATTERN_DATA;
   /*fprintf ( info, "Pattern data size : %ld\n" , PatDataSize );*/
 
   /* go back to pattern data starting address */
@@ -161,110 +190,82 @@ void Depack_PM20 ( void )
   /* now, reading all pattern data to get the max value of note */
   WholePatternData = (Uchar *) malloc (PatDataSize+1);
   BZERO (WholePatternData, PatDataSize+1);
-  for ( j=0 ; j<PatDataSize ; j+=2 )
+  for ( PW_j=0 ; PW_j<PatDataSize ; PW_j+=2 )
   {
-    WholePatternData[j] = in_data[Where+j];
-    WholePatternData[j+1] = in_data[Where+j+1];
-    if ( ((WholePatternData[j]*256)+WholePatternData[j+1]) > Ref_Max )
-      Ref_Max = ((WholePatternData[j]*256)+WholePatternData[j+1]);
+    WholePatternData[PW_j] = in_data[Where+PW_j];
+    WholePatternData[PW_j+1] = in_data[Where+PW_j+1];
+    if ( ((WholePatternData[PW_j]*256)+WholePatternData[PW_j+1]) > Ref_Max )
+      Ref_Max = ((WholePatternData[PW_j]*256)+WholePatternData[PW_j+1]);
   }
 
   /* read "reference Table" */
   Where = PW_Start_Address + ADDRESS_REF_TABLE;
-  j = (in_data[Where]*256*256*256)+(in_data[Where+1]*256*256)+(in_data[Where+2]*256)+in_data[Where+3];
-  Where = PW_Start_Address + AFTER_REPLAY_CODE + j;
+  PW_j = (in_data[Where]*256*256*256)+(in_data[Where+1]*256*256)+(in_data[Where+2]*256)+in_data[Where+3];
+  Where = PW_Start_Address + AFTER_REPLAY_CODE + PW_j;
 
   Ref_Max += 1;  /* coz 1st value is 0 ! */
-  i = Ref_Max * 4; /* coz each block is 4 bytes long */
-  ReferenceTable = (Uchar *) malloc ( i );
-  BZERO ( ReferenceTable, i );
-  for ( j=0 ; j<i ; j++) ReferenceTable[j] = in_data[Where+j];
+  PW_i = Ref_Max * 4; /* coz each block is 4 bytes long */
+  ReferenceTable = (Uchar *) malloc ( PW_i );
+  BZERO ( ReferenceTable, PW_i );
+  for ( PW_j=0 ; PW_j<PW_i ; PW_j++) ReferenceTable[PW_j] = in_data[Where+PW_j];
 
   /* go back to pattern data starting address */
   Where = PW_Start_Address + PATTERN_DATA;
 
 
-  c1=0; /* will count patterns */
-  k=0; /* current note number */
+  PW_k=0; /* current note number */
   Pattern = (Uchar *) malloc (65536);
   BZERO (Pattern, 65536);
-  i=0;
-  for ( j=0 ; j<PatDataSize ; j+=2 )
+  PW_i=0;
+  for ( PW_j=0 ; PW_j<PatDataSize ; PW_j+=2 )
   {
-    if ( (i%1024) == 0 )
-    {
-      Read_Pats_Address[c1] = j;
-      c1 += 0x01;
-      /*      fprintf ( info, " -> new pattern %2d (addy :%ld)\n", c1, j );*/
-    }
+    PW_m = ((WholePatternData[PW_j]*256)+WholePatternData[PW_j+1])*4;
 
-    m = ((WholePatternData[j]*256)+WholePatternData[j+1])*4;
-
-    Smp  = ReferenceTable[m];
+    Smp  = ReferenceTable[PW_m];
     Smp  = Smp >> 2;
-    Note = ReferenceTable[m+1];
+    Note = ReferenceTable[PW_m+1];
       
-    Pattern[i]   = (Smp&0xf0);
-    Pattern[i]   |= poss[(Note/2)][0];
-    Pattern[i+1] = poss[(Note/2)][1];
-    Pattern[i+2] = ReferenceTable[m+2];
-    Pattern[i+2] |= ((Smp<<4)&0xf0);
-    Pattern[i+3] = ReferenceTable[m+3];
+    Pattern[PW_i]   = (Smp&0xf0);
+    Pattern[PW_i]   |= poss[(Note/2)][0];
+    Pattern[PW_i+1] = poss[(Note/2)][1];
+    Pattern[PW_i+2] = ReferenceTable[PW_m+2];
+    Pattern[PW_i+2] |= ((Smp<<4)&0xf0);
+    Pattern[PW_i+3] = ReferenceTable[PW_m+3];
     /*fprintf ( info, "[%4ld][%ld][%ld] %2x %2x %2x %2x",i,k%4,j,Pattern[i],Pattern[i+1],Pattern[i+2],Pattern[i+3] );*/
 
-    if ( ( (Pattern[i+2] & 0x0f) == 0x0d ) ||
-        ( (Pattern[i+2] & 0x0f) == 0x0b ) )
+    if ( ( (Pattern[PW_i+2] & 0x0f) == 0x0d ) ||
+        ( (Pattern[PW_i+2] & 0x0f) == 0x0b ) )
     {
       /*fprintf ( info, " <- D or B detected" );*/
       FLAG = ON;
     }
-    if ( (FLAG == ON) && ((k%4) == 3) )
+    if ( (FLAG == ON) && ((PW_k%4) == 3) )
     {
       /*fprintf ( info, "\n -> bypassing end of pattern" );*/
       FLAG=OFF;
-      while ( (i%1024) != 0)
-       i ++;
-      i -= 4;
+      while ( (PW_i%1024) != 0)
+           PW_i ++;
+      PW_i -= 4;
     }
 
-    k += 1;
-    i += 4;
+    PW_k += 1;
+    PW_i += 4;
     /*fprintf ( info, "\n" );*/
   }
 
   free ( ReferenceTable );
   free ( WholePatternData );
 
-  /* write pattern table */
-  BZERO ( Whatever, 128 );
-  for ( c2=0; c2<128 ; c2+=0x01 )
-    for ( i=0 ; i<NOP ; i++ )
-      if ( Pats_Address[c2] == Read_Pats_Address[i])
-       Whatever[c2] = (Uchar) i;
-  while ( i<128 )
-    Whatever[i++] = 0x00;
-  fwrite ( &Whatever[0], 128, 1, out );
-
-  /* write tag */
-  Whatever[0] = 'M';
-  Whatever[1] = '.';
-  Whatever[2] = 'K';
-
-  fwrite ( &Whatever[0] , 1 , 1 , out );
-  fwrite ( &Whatever[1] , 1 , 1 , out );
-  fwrite ( &Whatever[2] , 1 , 1 , out );
-  fwrite ( &Whatever[1] , 1 , 1 , out );
-
   free ( Whatever );
 
   /* write pattern data */
-  /* c1 is still the number of patterns stored */
-  fwrite ( Pattern, c1*1024, 1, out );
+  /* PW_l is still the number of patterns stored */
+  fwrite ( Pattern, PW_l*1024, 1, out );
 
   /* get address of sample data .. and go there */
   Where = PW_Start_Address + ADDRESS_SAMPLE_DATA;
-  SDAV = (in_data[Where]*256*256*256)+(in_data[Where+1]*256*256)+(in_data[Where+2]*256)+in_data[Where+3];
-  Where = PW_Start_Address + AFTER_REPLAY_CODE + SDAV;
+  PW_i = (in_data[Where]*256*256*256)+(in_data[Where+1]*256*256)+(in_data[Where+2]*256)+in_data[Where+3];
+  Where = PW_Start_Address + AFTER_REPLAY_CODE + PW_i;
 
 
   /* read and save sample data */
index e5fea759bc4ba5eeebe44f86d1f0be729e9db911..cbbc55f970669971d4d91a4400970b51ab0327f9 100644 (file)
--- a/uaeunp.c
+++ b/uaeunp.c
@@ -15,7 +15,7 @@ TCHAR start_path_data[MAX_DPATH];
 TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
 
 struct uae_prefs currprefs;
-static int debug = 1;
+static int debug = 0;
 static int amigatest;
 
 #define WRITE_LOG_BUF_SIZE 4096
@@ -721,6 +721,9 @@ int wmain (int argc, wchar_t *argv[], wchar_t *envp[])
 
 - vhd read support
 - dms, ipf (and possible other) disk image formats didn't unpack inside archives
+- fixed duplicate vdir entries with some image types
+- all raw disk image formats support Amiga, FAT and extended adf extraction
+- cache relatively slow ipf and fdi extracted data
 
 0.6:
 
diff --git a/zfile.c b/zfile.c
index 1e2f53438db6cd426487c4d4aab8988969a6bdc9..4f4b8a0adb648203020f20f16b0712ed472f682c 100644 (file)
--- a/zfile.c
+++ b/zfile.c
@@ -33,6 +33,121 @@ static struct zfile *zlist = 0;
 
 const TCHAR *uae_archive_extensions[] = { L"zip", L"rar", L"7z", L"lha", L"lzh", L"lzx", NULL };
 
+#define MAX_CACHE_ENTRIES 10
+
+struct zdisktrack
+{
+       void *data;
+       int len;
+};
+struct zdiskimage
+{
+       int tracks;
+       struct zdisktrack zdisktracks[2 * 84];
+};
+struct zcache
+{
+       TCHAR *name;
+       struct zdiskimage *zd;
+       void *data;
+       int size;
+       struct zcache *next;
+       time_t tm;
+};
+static struct zcache *zcachedata;
+
+static struct zcache *cache_get (const TCHAR *name)
+{
+       struct zcache *zc = zcachedata;
+       while (zc) {
+               if (!_tcscmp (name, zc->name)) {
+                       zc->tm = time (NULL);
+                       return zc;
+               }
+               zc = zc->next;
+       }
+       return NULL;
+}
+
+static void zcache_flush (void)
+{
+}
+
+static void zcache_free_data (struct zcache *zc)
+{
+       int i;
+       if (zc->zd) {
+               for (i = 0; i < zc->zd->tracks; i++) {
+                       xfree (zc->zd->zdisktracks[i].data);
+               }
+               xfree (zc->zd);
+       }
+       xfree (zc->data);
+       xfree (zc->name);
+}
+
+static void zcache_free (struct zcache *zc)
+{
+       struct zcache *pl = NULL;
+       struct zcache *l  = zcachedata;
+       struct zcache *nxt;
+
+       while (l != zc) {
+               if (l == 0)
+                       return;
+               pl = l;
+               l = l->next;
+       }
+       if (l)
+               nxt = l->next;
+       zcache_free_data (zc);
+       if (l == 0)
+               return;
+       if(!pl)
+               zcachedata = nxt;
+       else
+               pl->next = nxt;
+}
+
+static void zcache_close (void)
+{
+       struct zcache *zc = zcachedata;
+       while (zc) {
+               struct zcache *n = zc->next;
+               zcache_free_data (zc);
+               xfree (n);
+               zc = n;
+       }
+}
+
+static void zcache_check (void)
+{
+       int cnt = 0;
+       struct zcache *zc = zcachedata, *last = NULL;
+       while (zc) {
+               last = zc;
+               zc = zc->next;
+               cnt++;
+       }
+       write_log (L"CACHE: %d\n", cnt);
+       if (cnt >= MAX_CACHE_ENTRIES && last)
+               zcache_free (last);
+}
+
+static struct zcache *zcache_put (const TCHAR *name, struct zdiskimage *data)
+{
+       struct zcache *zc;
+       
+       zcache_check ();
+       zc = xcalloc (sizeof (struct zcache), 1);
+       zc->next = zcachedata;
+       zcachedata = zc;
+       zc->zd = data;
+       zc->name = my_strdup (name);
+       zc->tm = time (NULL);
+       return zc;
+}
+       
 static struct zfile *zfile_create (struct zfile *prev)
 {
        struct zfile *z;
@@ -475,7 +590,7 @@ static void truncate880k (struct zfile *z)
        z->size = 880 * 512 * 2;
 }
 
-static struct zfile *extadf (struct zfile *z, int pctype)
+static struct zfile *extadf (struct zfile *z, int index, int *retcode)
 {
        int i, r;
        struct zfile *zo;
@@ -487,8 +602,11 @@ static struct zfile *extadf (struct zfile *z, int pctype)
        int outsize;
        TCHAR newname[MAX_DPATH];
        TCHAR *ext;
+       int cantrunc = 0;
+       int done = 0;
 
-       //pctype = 1;
+       if (index > 1)
+               return NULL;
 
        mfm = xcalloc (32000, 1);
        amigamfmbuffer = xcalloc (32000, 1);
@@ -502,14 +620,19 @@ static struct zfile *extadf (struct zfile *z, int pctype)
        _tcscpy (newname, zfile_getname (z));
        ext = _tcsrchr (newname, '.');
        if (ext) {
-               _tcscpy (newname + _tcslen (newname) - _tcslen (ext), L".ext.adf");
+               _tcscpy (newname + _tcslen (newname) - _tcslen (ext), L".std.adf");
        } else {
-               _tcscat (newname, L".adf");
+               _tcscat (newname, L".std.adf");
        }
+       if (index > 0)
+               _tcscpy (newname + _tcslen (newname) - 4, L".ima");
+
        zo = zfile_fopen_empty (z, newname, 0);
        if (!zo)
                goto end;
 
+       if (retcode)
+               *retcode = 1;
        pos = 12;
        outsize = 0;
        for (i = 0; i < tracks; i++) {
@@ -527,134 +650,226 @@ static struct zfile *extadf (struct zfile *z, int pctype)
                        zfile_fread (mfm, len, 1, z);
                        memset (writebuffer_ok, 0, sizeof writebuffer_ok);
                        memset (outbuf, 0, 16384);
-                       if (pctype <= 0) {
+                       if (index == 0) {
                                r = isamigatrack (amigamfmbuffer, (uae_u8*)mfm, len, outbuf, writebuffer_ok, i, &outsize);
                                if (r < 0 && i == 0) {
                                        zfile_seterror (L"'%s' is not AmigaDOS formatted", zo->name);
                                        goto end;
                                }
+                               if (i == 0)
+                                       done = 1;
                        } else {
                                r = ispctrack (amigamfmbuffer, (uae_u8*)mfm, len, outbuf, writebuffer_ok, i, &outsize);
                                if (r < 0 && i == 0) {
                                        zfile_seterror (L"'%s' is not PC formatted", zo->name);
                                        goto end;
                                }
+                               if (i == 0)
+                                       done = 1;
                        }
                } else {
                        outsize = 512 * 11;
+                       if (bitlen / 8 > 18000)
+                               outsize *= 2;
                        zfile_fread (outbuf, outsize, 1, z);
+                       cantrunc = 1;
+                       if (index == 0)
+                               done = 1;
                }
                zfile_fwrite (outbuf, outsize, 1, zo);
 
                offs += len;
 
        }
+       if (done == 0)
+               goto end;
        zfile_fclose (z);
        xfree (mfm);
        xfree (amigamfmbuffer);
-       truncate880k (zo);
+       if (cantrunc)
+               truncate880k (zo);
        return zo;
 end:
        zfile_fclose (zo);
        xfree (mfm);
        xfree (amigamfmbuffer);
-       return z;
+       return NULL;
 }
 
 
 #include "fdi2raw.h"
-static struct zfile *fdi (struct zfile *z, int type)
+static struct zfile *fdi (struct zfile *z, int index, int *retcode)
 {
        int i, j, r;
        struct zfile *zo;
        TCHAR *orgname = zfile_getname (z);
        TCHAR *ext = _tcsrchr (orgname, '.');
        TCHAR newname[MAX_DPATH];
-       uae_u16 *mfm;
        uae_u16 *amigamfmbuffer;
        uae_u8 writebuffer_ok[32], *outbuf;
        int tracks, len, outsize;
        FDI *fdi;
+       int startpos = 0;
+       uae_u8 tmp[12];
+       struct zcache *zc;
+
+       if (index > 2)
+               return NULL;
+
+       zc = cache_get (z->name);
+       if (!zc) {
+               uae_u16 *mfm;
+               struct zdiskimage *zd;
+               fdi = fdi2raw_header (z);
+               if (!fdi)
+                       return NULL;
+               mfm = xcalloc (32000, 1);
+               zd = xcalloc (sizeof (struct zdiskimage), 1);
+               tracks = fdi2raw_get_last_track (fdi);
+               zd->tracks = tracks;
+               for (i = 0; i < tracks; i++) {
+                       uae_u8 *buf, *p;
+                       fdi2raw_loadtrack (fdi, mfm, NULL, i, &len, NULL, NULL, 1);
+                       len /= 8;
+                       buf = p = xmalloc (len);
+                       for (j = 0; j < len / 2; j++) {
+                               uae_u16 v = mfm[j];
+                               *p++ = v >> 8;
+                               *p++ = v;
+                       }
+                       zd->zdisktracks[i].data = buf;
+                       zd->zdisktracks[i].len = len;
+               }
+               fdi2raw_header_free (fdi);
+               zc = zcache_put (z->name, zd);
+       }
 
-       fdi = fdi2raw_header (z);
-       if (!fdi)
-               return z;
-       mfm = xcalloc (32000, 1);
        amigamfmbuffer = xcalloc (32000, 1);
        outbuf = xcalloc (16384, 1);
-       tracks = fdi2raw_get_last_track (fdi);
+       tracks = zc->zd->tracks;
        if (ext) {
                _tcscpy (newname, orgname);
                _tcscpy (newname + _tcslen (newname) - _tcslen (ext), L".adf");
        } else {
                _tcscat (newname, L".adf");
        }
+       if (index == 1)
+               _tcscpy (newname + _tcslen (newname) - 4, L".ima");
+       if (index == 2)
+               _tcscpy (newname + _tcslen (newname) - 4, L".ext.adf");
        zo = zfile_fopen_empty (z, newname, 0);
        if (!zo)
                goto end;
+       if (retcode)
+               *retcode = 1;
+       if (index > 1) {
+               zfile_fwrite ("UAE-1ADF", 8, 1, zo);
+               tmp[0] = 0; tmp[1] = 0; /* flags (reserved) */
+               tmp[2] = 0; tmp[3] = tracks; /* number of tracks */
+               zfile_fwrite (tmp, 4, 1, zo);
+               memset (tmp, 0, sizeof tmp);
+               tmp[2] = 0; tmp[3] = 1; /* track type */
+               startpos = zfile_ftell (zo);
+               for (i = 0; i < tracks; i++)
+                       zfile_fwrite (tmp, sizeof tmp, 1, zo);
+       }
        outsize = 0;
        for (i = 0; i < tracks; i++) {
-               uae_u8 *p = (uae_u8*)mfm;
-               fdi2raw_loadtrack (fdi, mfm, NULL, i, &len, NULL, NULL, 1);
-               len /= 8;
-               for (j = 0; j < len / 2; j++) {
-                       uae_u16 v = mfm[j];
-                       *p++ = v >> 8;
-                       *p++ = v;
-               }
+               uae_u8 *p = zc->zd->zdisktracks[i].data;
+               len = zc->zd->zdisktracks[i].len;
                memset (writebuffer_ok, 0, sizeof writebuffer_ok);
                memset (outbuf, 0, 16384);
-               if (type <= 0) {
-                       r = isamigatrack (amigamfmbuffer, (uae_u8*)mfm, len, outbuf, writebuffer_ok, i, &outsize);
+               if (index == 0) {
+                       r = isamigatrack (amigamfmbuffer, p, len, outbuf, writebuffer_ok, i, &outsize);
                        if (r < 0 && i == 0) {
                                zfile_seterror (L"'%s' is not AmigaDOS formatted", orgname);
                                goto end;
                        }
-               } else if (type == 1) {
-                       r = ispctrack (amigamfmbuffer, (uae_u8*)mfm, len, outbuf, writebuffer_ok, i, &outsize);
+                       zfile_fwrite (outbuf, outsize, 1, zo);
+               } else if (index == 1) {
+                       r = ispctrack (amigamfmbuffer, p, len, outbuf, writebuffer_ok, i, &outsize);
                        if (r < 0 && i == 0) {
                                zfile_seterror (L"'%s' is not PC formatted", orgname);
                                goto end;
                        }
+                       zfile_fwrite (outbuf, outsize, 1, zo);
+               } else {
+                       int pos = zfile_ftell (zo);
+                       int maxlen = len > 12798 ? len : 12798;
+                       int lenb = len * 8;
+
+                       if (maxlen & 1)
+                               maxlen++;
+                       zfile_fseek (zo, startpos + i * 12 + 4, SEEK_SET);
+                       tmp[4] = 0; tmp[5] = 0; tmp[6] = maxlen >> 8; tmp[7] = maxlen;
+                       tmp[8] = lenb >> 24; tmp[9] = lenb >> 16; tmp[10] = lenb >> 8; tmp[11] = lenb;
+                       zfile_fwrite (tmp + 4, 2, 4, zo);
+                       zfile_fseek (zo, pos, SEEK_SET);
+                       zfile_fwrite (p, 1, len, zo);
+                       if (maxlen > len)
+                               zfile_fwrite (outbuf, 1, maxlen - len, zo);
                }
-               zfile_fwrite (outbuf, outsize, 1, zo);
        }
        zfile_fclose (z);
-       fdi2raw_header_free (fdi);
-       xfree (mfm);
        xfree (amigamfmbuffer);
        xfree (outbuf);
-       truncate880k (zo);
+       if (index == 0)
+               truncate880k (zo);
        return zo;
 end:
-       if (zo)
-               zfile_fclose (zo);
-       fdi2raw_header_free (fdi);
-       xfree (mfm);
+       zfile_fclose (zo);
        xfree (amigamfmbuffer);
        xfree (outbuf);
-       return z;
+       return NULL;
 }
 
 #ifdef CAPS
 #include "caps/caps_win32.h"
-static struct zfile *ipf (struct zfile *z, int type)
+static struct zfile *ipf (struct zfile *z, int index, int *retcode)
 {
        int i, j, r;
        struct zfile *zo;
        TCHAR *orgname = zfile_getname (z);
        TCHAR *ext = _tcsrchr (orgname, '.');
        TCHAR newname[MAX_DPATH];
-       uae_u16 *mfm;
        uae_u16 *amigamfmbuffer;
        uae_u8 writebuffer_ok[32];
        int tracks, len;
        int outsize;
+       int startpos = 0;
        uae_u8 *outbuf;
+       uae_u8 tmp[12];
+       struct zcache *zc;
+
+       if (index > 2)
+               return NULL;
+
+       zc = cache_get (z->name);
+       if (!zc) {
+               uae_u16 *mfm;
+               struct zdiskimage *zd;
+               if (!caps_loadimage (z, 0, &tracks))
+                       return NULL;
+               mfm = xcalloc (32000, 1);
+               zd = xcalloc (sizeof (struct zdiskimage), 1);
+               zd->tracks = tracks;
+               for (i = 0; i < tracks; i++) {
+                       uae_u8 *buf, *p;
+                       caps_loadrevolution (mfm, 0, i, &len);
+                       len /= 8;
+                       buf = p = xmalloc (len);
+                       for (j = 0; j < len / 2; j++) {
+                               uae_u16 v = mfm[j];
+                               *p++ = v >> 8;
+                               *p++ = v;
+                       }
+                       zd->zdisktracks[i].data = buf;
+                       zd->zdisktracks[i].len = len;
+               }
+               caps_unloadimage (0);
+               zc = zcache_put (z->name, zd);
+       }
 
-       if (!caps_loadimage (z, 0, &tracks))
-               return z;
-       mfm = xcalloc (32000, 1);
        outbuf = xcalloc (16384, 1);
        amigamfmbuffer = xcalloc (32000, 1);
        if (ext) {
@@ -663,43 +878,80 @@ static struct zfile *ipf (struct zfile *z, int type)
        } else {
                _tcscat (newname, L".adf");
        }
+       if (index == 1)
+               _tcscpy (newname + _tcslen (newname) - 4, L".ima");
+       if (index == 2)
+               _tcscpy (newname + _tcslen (newname) - 4, L".ext.adf");
+
        zo = zfile_fopen_empty (z, newname, 0);
        if (!zo)
                goto end;
+
+       if (retcode)
+               *retcode = 1;
+
+       tracks = zc->zd->tracks;
+
+       if (index > 1) {
+               zfile_fwrite ("UAE-1ADF", 8, 1, zo);
+               tmp[0] = 0; tmp[1] = 0; /* flags (reserved) */
+               tmp[2] = 0; tmp[3] = tracks; /* number of tracks */
+               zfile_fwrite (tmp, 4, 1, zo);
+               memset (tmp, 0, sizeof tmp);
+               tmp[2] = 0; tmp[3] = 1; /* track type */
+               startpos = zfile_ftell (zo);
+               for (i = 0; i < tracks; i++)
+                       zfile_fwrite (tmp, sizeof tmp, 1, zo);
+       }
+
        outsize = 0;
        for (i = 0; i < tracks; i++) {
-               uae_u8 *p = (uae_u8*)mfm;
-               caps_loadrevolution (mfm, 0, i, &len);
-               len /= 8;
-               for (j = 0; j < len / 2; j++) {
-                       uae_u16 v = mfm[j];
-                       *p++ = v >> 8;
-                       *p++ = v;
-               }
+               uae_u8 *p = zc->zd->zdisktracks[i].data;
+               len = zc->zd->zdisktracks[i].len;
                memset (writebuffer_ok, 0, sizeof writebuffer_ok);
                memset (outbuf, 0, 16384);
-               r = isamigatrack (amigamfmbuffer, (uae_u8*)mfm, len, outbuf, writebuffer_ok, i, &outsize);
-               if (r < 0 && i == 0) {
-                       zfile_seterror (L"'%s' is not AmigaDOS formatted", orgname);
-                       goto end;
+               if (index == 0) {
+                       r = isamigatrack (amigamfmbuffer, p, len, outbuf, writebuffer_ok, i, &outsize);
+                       if (r < 0 && i == 0) {
+                               zfile_seterror (L"'%s' is not AmigaDOS formatted", orgname);
+                               goto end;
+                       }
+                       zfile_fwrite (outbuf, 1, outsize, zo);
+               } else if (index == 1) {
+                       r = ispctrack (amigamfmbuffer, p, len, outbuf, writebuffer_ok, i, &outsize);
+                       if (r < 0 && i == 0) {
+                               zfile_seterror (L"'%s' is not PC formatted", orgname);
+                               goto end;
+                       }
+                       zfile_fwrite (outbuf, outsize, 1, zo);
+               } else {
+                       int pos = zfile_ftell (zo);
+                       int maxlen = len > 12798 ? len : 12798;
+                       int lenb = len * 8;
+
+                       if (maxlen & 1)
+                               maxlen++;
+                       zfile_fseek (zo, startpos + i * 12 + 4, SEEK_SET);
+                       tmp[4] = 0; tmp[5] = 0; tmp[6] = maxlen >> 8; tmp[7] = maxlen;
+                       tmp[8] = lenb >> 24; tmp[9] = lenb >> 16; tmp[10] = lenb >> 8; tmp[11] = lenb;
+                       zfile_fwrite (tmp + 4, 2, 4, zo);
+                       zfile_fseek (zo, pos, SEEK_SET);
+                       zfile_fwrite (p, 1, len, zo);
+                       if (maxlen > len)
+                               zfile_fwrite (outbuf, 1, maxlen - len, zo);
                }
-               zfile_fwrite (outbuf, 1, outsize, zo);
        }
-       caps_unloadimage (0);
        zfile_fclose (z);
-       xfree (mfm);
        xfree (amigamfmbuffer);
        xfree (outbuf);
-       truncate880k (zo);
+       if (index == 0)
+               truncate880k (zo);
        return zo;
 end:
-       if (zo)
-               zfile_fclose (zo);
-       caps_unloadimage (0);
-       xfree (mfm);
+       zfile_fclose (zo);
        xfree (amigamfmbuffer);
        xfree (outbuf);
-       return z;
+       return NULL;
 }
 #endif
 
@@ -845,7 +1097,7 @@ int zfile_is_diskimage (const TCHAR *name)
 
 static const TCHAR *archive_extensions[] = {
        L"7z", L"rar", L"zip", L"lha", L"lzh", L"lzx",
-       L"adf", L"adz", L"dsq", L"dms", L"ipf", L"fdi", L"wrp",
+       L"adf", L"adz", L"dsq", L"dms", L"ipf", L"fdi", L"wrp", L"ima",
        L"hdf",
        NULL
 };
@@ -914,6 +1166,10 @@ int iszip (struct zfile *z)
                                return ArchiveFormatFAT;
                        return 0;
                }
+               if (!strcasecmp (ext, L".ima")) {
+                       if (isfat (header))
+                               return ArchiveFormatFAT;
+               }
        }
        if (mask & ZFD_HD) {
                if (!strcasecmp (ext, L".hdf")) {
@@ -938,7 +1194,7 @@ int iszip (struct zfile *z)
        return 0;
 }
 
-struct zfile *zuncompress (struct znode *parent, struct zfile *z, int dodefault, int mask, int *retcode)
+struct zfile *zuncompress (struct znode *parent, struct zfile *z, int dodefault, int mask, int *retcode, int index)
 {
        TCHAR *name = z->name;
        TCHAR *ext = NULL;
@@ -958,56 +1214,48 @@ struct zfile *zuncompress (struct znode *parent, struct zfile *z, int dodefault,
        if (ext != NULL) {
                if (mask & ZFD_ARCHIVE) {
                        if (strcasecmp (ext, L"7z") == 0)
-                               return archive_access_select (parent, z, ArchiveFormat7Zip, dodefault, retcode);
+                               return archive_access_select (parent, z, ArchiveFormat7Zip, dodefault, retcode, index);
                        if (strcasecmp (ext, L"zip") == 0)
-                               return archive_access_select (parent, z, ArchiveFormatZIP, dodefault, retcode);
+                               return archive_access_select (parent, z, ArchiveFormatZIP, dodefault, retcode, index);
                        if (strcasecmp (ext, L"lha") == 0 || strcasecmp (ext, L"lzh") == 0)
-                               return archive_access_select (parent, z, ArchiveFormatLHA, dodefault, retcode);
+                               return archive_access_select (parent, z, ArchiveFormatLHA, dodefault, retcode, index);
                        if (strcasecmp (ext, L"lzx") == 0)
-                               return archive_access_select (parent, z, ArchiveFormatLZX, dodefault, retcode);
+                               return archive_access_select (parent, z, ArchiveFormatLZX, dodefault, retcode, index);
                        if (strcasecmp (ext, L"rar") == 0)
-                               return archive_access_select (parent, z, ArchiveFormatRAR, dodefault, retcode);
+                               return archive_access_select (parent, z, ArchiveFormatRAR, dodefault, retcode, index);
                }
                if (mask & ZFD_UNPACK) {
-                       if (strcasecmp (ext, L"gz") == 0)
-                               return zfile_gunzip (z);
-                       if (strcasecmp (ext, L"adz") == 0)
-                               return zfile_gunzip (z);
-                       if (strcasecmp (ext, L"roz") == 0)
-                               return zfile_gunzip (z);
-                       if (strcasecmp (ext, L"hdz") == 0)
-                               return zfile_gunzip (z);
-                       if (strcasecmp (ext, L"dms") == 0)
-                               return dms (z);
-                       if (strcasecmp (ext, L"wrp") == 0)
-                               return wrp (z);
+                       if (index == 0) {
+                               if (strcasecmp (ext, L"gz") == 0)
+                                       return zfile_gunzip (z);
+                               if (strcasecmp (ext, L"adz") == 0)
+                                       return zfile_gunzip (z);
+                               if (strcasecmp (ext, L"roz") == 0)
+                                       return zfile_gunzip (z);
+                               if (strcasecmp (ext, L"hdz") == 0)
+                                       return zfile_gunzip (z);
+                               if (strcasecmp (ext, L"dms") == 0)
+                                       return dms (z);
+                               if (strcasecmp (ext, L"wrp") == 0)
+                                       return wrp (z);
+                       }
                }
                if (mask & ZFD_RAWDISK) {
 #ifdef CAPS
-                       if (strcasecmp (ext, L"ipf") == 0) {
-                               if (mask & ZFD_RAWDISK_PC)
-                                       return ipf (z, 1);
-                               else if (mask & ZFD_RAWDISK_AMIGA)
-                                       return ipf (z, 0);
-                               else
-                                       return ipf (z, -1);
-                       }
+                       if (strcasecmp (ext, L"ipf") == 0)
+                               return ipf (z, index, retcode);
 #endif
-                       if (strcasecmp (ext, L"fdi") == 0) {
-                               if (mask & ZFD_RAWDISK_PC)
-                                       return fdi (z, 1);
-                               else if (mask & ZFD_RAWDISK_AMIGA)
-                                       return fdi (z, 0);
-                               else
-                                       return fdi (z, -1);
-                       }
+                       if (strcasecmp (ext, L"fdi") == 0)
+                               return fdi (z, index, retcode);
                        if (mask & (ZFD_RAWDISK_PC | ZFD_RAWDISK_AMIGA))
                                return NULL;
                }
 #if defined(ARCHIVEACCESS)
-               for (i = 0; plugins_7z_x[i]; i++) {
-                       if ((plugins_7z_t[i] & mask) && strcasecmp (ext, plugins_7z[i]) == 0)
-                               return archive_access_arcacc_select (z, plugins_7z_t[i], retcode);
+               if (index == 0) {
+                       for (i = 0; plugins_7z_x[i]; i++) {
+                               if ((plugins_7z_t[i] & mask) && strcasecmp (ext, plugins_7z[i]) == 0)
+                                       return archive_access_arcacc_select (z, plugins_7z_t[i], retcode);
+                       }
                }
 #endif
        }
@@ -1015,62 +1263,51 @@ struct zfile *zuncompress (struct znode *parent, struct zfile *z, int dodefault,
        zfile_fseek (z, 0, SEEK_SET);
        zfile_fread (header, sizeof (header), 1, z);
        zfile_fseek (z, 0, SEEK_SET);
-       if (!memcmp (header, "conectix", 8))
+       if (!memcmp (header, "conectix", 8)) {
+               if (index > 0)
+                       return NULL;
                return vhd (z);
+       }
 
        if (mask & ZFD_UNPACK) {
-               if (header[0] == 0x1f && header[1] == 0x8b)
-                       return zfile_gunzip (z);
-               if (header[0] == 'D' && header[1] == 'M' && header[2] == 'S' && header[3] == '!')
-                       return dms (z);
-               if (header[0] == 'P' && header[1] == 'K' && header[2] == 'D')
-                       return dsq (z, 0);
+               if (index == 0) {
+                       if (header[0] == 0x1f && header[1] == 0x8b)
+                               return zfile_gunzip (z);
+                       if (header[0] == 'D' && header[1] == 'M' && header[2] == 'S' && header[3] == '!')
+                               return dms (z);
+                       if (header[0] == 'P' && header[1] == 'K' && header[2] == 'D')
+                               return dsq (z, 0);
+               }
        }
        if (mask & ZFD_RAWDISK) {
 #ifdef CAPS
-               if (header[0] == 'C' && header[1] == 'A' && header[2] == 'P' && header[3] == 'S') {
-                       if (mask & ZFD_RAWDISK_PC)
-                               return ipf (z, 1);
-                       else if (mask & ZFD_RAWDISK_AMIGA)
-                               return ipf (z, 0);
-                       else
-                               return ipf (z, -1);
-               }
+               if (header[0] == 'C' && header[1] == 'A' && header[2] == 'P' && header[3] == 'S')
+                       return ipf (z, index, retcode);
 #endif
-               if (!memcmp (header, "Formatte", 8)) {
-                       if (mask & ZFD_RAWDISK_PC)
-                               return fdi (z, 1);
-                       else if (mask & ZFD_RAWDISK_AMIGA)
-                               return fdi (z, 0);
-                       else
-                               return fdi (z, -1);
-               }
-               if (!memcmp (header, "UAE-1ADF", 8)) {
-                       if (mask & ZFD_RAWDISK_PC)
-                               return extadf (z, 1);
-                       else if (mask & ZFD_RAWDISK_AMIGA)
-                               return extadf (z, 0);
-                       else
-                               return extadf (z, -1);
-               }
+               if (!memcmp (header, "Formatte", 8))
+                       return fdi (z, index, retcode);
+               if (!memcmp (header, "UAE-1ADF", 8))
+                       return extadf (z, index, retcode);
        }
+       if (index > 0)
+               return NULL;
        if (mask & ZFD_ARCHIVE) {
                if (header[0] == 'P' && header[1] == 'K')
-                       return archive_access_select (parent, z, ArchiveFormatZIP, dodefault, retcode);
+                       return archive_access_select (parent, z, ArchiveFormatZIP, dodefault, retcode, index);
                if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
-                       return archive_access_select (parent, z, ArchiveFormatRAR, dodefault, retcode);
+                       return archive_access_select (parent, z, ArchiveFormatRAR, dodefault, retcode, index);
                if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X')
-                       return archive_access_select (parent, z, ArchiveFormatLZX, dodefault, retcode);
+                       return archive_access_select (parent, z, ArchiveFormatLZX, dodefault, retcode, index);
                if (header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-')
-                       return archive_access_select (parent, z, ArchiveFormatLHA, dodefault, retcode);
+                       return archive_access_select (parent, z, ArchiveFormatLHA, dodefault, retcode, index);
        }
        if (mask & ZFD_ADF) {
                if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
-                       return archive_access_select (parent, z, ArchiveFormatADF, dodefault, retcode);
+                       return archive_access_select (parent, z, ArchiveFormatADF, dodefault, retcode, index);
                if (header[0] == 'S' && header[1] == 'F' && header[2] == 'S')
-                       return archive_access_select (parent, z, ArchiveFormatADF, dodefault, retcode);
+                       return archive_access_select (parent, z, ArchiveFormatADF, dodefault, retcode, index);
                if (isfat (header))
-                       return archive_access_select (parent, z, ArchiveFormatFAT, dodefault, retcode);
+                       return archive_access_select (parent, z, ArchiveFormatFAT, dodefault, retcode, index);
        }
 
        if (ext) {
@@ -1080,7 +1317,7 @@ struct zfile *zuncompress (struct znode *parent, struct zfile *z, int dodefault,
                }
                if (mask & ZFD_ADF) {
                        if (strcasecmp (ext, L"adf") == 0 && !memcmp (header, "DOS", 3))
-                               return archive_access_select (parent, z, ArchiveFormatADF, dodefault, retcode);
+                               return archive_access_select (parent, z, ArchiveFormatADF, dodefault, retcode, index);
                }
        }
        return NULL;
@@ -1271,7 +1508,7 @@ int zfile_zopen (const TCHAR *name, zfile_callback zc, void *user)
 /*
 * fopen() for a compressed file
 */
-static struct zfile *zfile_fopen_x (const TCHAR *name, const TCHAR *mode, int mask)
+static struct zfile *zfile_fopen_x (const TCHAR *name, const TCHAR *mode, int mask, int index)
 {
        int cnt = 10;
        struct zfile *l, *l2;
@@ -1290,7 +1527,7 @@ static struct zfile *zfile_fopen_x (const TCHAR *name, const TCHAR *mode, int ma
        while (cnt-- > 0) {
                int rc;
                zfile_fseek (l, 0, SEEK_SET);
-               l2 = zuncompress (NULL, l, 0, mask, &rc);
+               l2 = zuncompress (NULL, l, 0, mask, &rc, index);
                if (!l2) {
                        if (rc < 0) {
                                zfile_fclose (l);
@@ -1405,7 +1642,7 @@ end:
 }
 #endif
 
-struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask)
+static struct zfile *zfile_fopenx (const TCHAR *name, const TCHAR *mode, int mask, int index)
 {
        struct zfile *f;
        TCHAR tmp[MAX_DPATH];
@@ -1415,7 +1652,7 @@ struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask)
        if (isinternetfile (name))
                return zfile_fopen_internet (name, mode, mask);
 #endif
-       f = zfile_fopen_x (name, mode, mask);
+       f = zfile_fopen_x (name, mode, mask, index);
        if (f)
                return f;
        if (_tcslen (name) <= 2)
@@ -1423,7 +1660,7 @@ struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask)
        if (name[1] != ':') {
                _tcscpy (tmp, start_path_data);
                _tcscat (tmp, name);
-               f = zfile_fopen_x (tmp, mode, mask);
+               f = zfile_fopen_x (tmp, mode, mask, index);
                if (f)
                        return f;
        }
@@ -1448,7 +1685,14 @@ struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask)
 #endif
        return NULL;
 }
-
+struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask)
+{
+       return zfile_fopenx (name, mode, mask, 0);
+}
+struct zfile *zfile_fopen2 (const TCHAR *name, const TCHAR *mode, int mask, int index)
+{
+       return zfile_fopenx (name, mode, mask, index);
+}
 
 struct zfile *zfile_dup (struct zfile *zf)
 {
@@ -2219,6 +2463,7 @@ static struct zvolume *prepare_recursive_volume (struct zvolume *zv, const TCHAR
        struct zfile *zf = NULL;
        struct zvolume *zvnew = NULL;
        int i;
+       int done = 0;
 
 #ifdef ZFILE_DEBUG
        write_log (L"unpacking '%s'\n", path);
@@ -2228,33 +2473,39 @@ static struct zvolume *prepare_recursive_volume (struct zvolume *zv, const TCHAR
                goto end;
        zvnew = zfile_fopen_archive_ext (zv->parentz, zf);
        if (!zvnew) {
+               int rc;
+               int index;
                struct zfile *zf2, *zf3;
                TCHAR oldname[MAX_DPATH];
                _tcscpy (oldname, zf->name);
-               zf3 = zfile_dup (zf);
-               if (zf3) {
-                       zf2 = zuncompress (&zv->root, zf3, 0, ZFD_ALL, NULL);
+               index = 0;
+               for (;;) {
+                       zf3 = zfile_dup (zf);
+                       if (!zf3)
+                               break;
+                       zf2 = zuncompress (&zv->root, zf3, 0, ZFD_ALL, &rc, index);
                        if (zf2) {
-                               TCHAR newname[MAX_DPATH];
-                               _tcscpy (newname, zf2->name);
-                               for (i = _tcslen (newname) - 1; i > 0; i--) {
-                                       if (newname[i] == '\\' || newname[i] == '/')
-                                               break;
+                               zvnew = archive_directory_plain (zf2);
+                               if (zvnew) {
+                                       zvnew->parent = zv->parent;
+                                       zfile_fopen_archive_recurse (zvnew);
+                                       done = 1;
                                }
-                               //_tcscat (oldname, newname + i);
-                               //xfree (zf2->name);
-                               //zf2->name = my_strdup (oldname);
-                               zf = zf2;
-                               zvnew = archive_directory_plain (zf);
                        } else {
                                zfile_fclose (zf3);
+                               if (rc == 0)
+                                       break;
                        }
+                       index++;
+                       break;
                }
+       } else {
+               zvnew->parent = zv->parent;
+               zfile_fopen_archive_recurse (zvnew);
+               done = 1;
        }
-       if (!zvnew)
+       if (!done)
                goto end;
-       zvnew->parent = zv->parent;
-       zfile_fopen_archive_recurse (zvnew);
        zfile_fclose_archive (zv);
        return zvnew;
 end:
index 547faad32470d281ebe55bcebdba2f3bd4382b91..257a3d0b7ffbf26cc5ee56a27577b0921a5daa1e 100644 (file)
@@ -123,7 +123,7 @@ struct zfile *archive_getzfile (struct znode *zn, unsigned int id)
        return zf;
 }
 
-struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, unsigned int id, int dodefault, int *retcode)
+struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, unsigned int id, int dodefault, int *retcode, int index)
 {
        struct zvolume *zv;
        struct znode *zn;
@@ -135,6 +135,8 @@ struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, uns
 
        if (retcode)
                *retcode = 0;
+       if (index > 0)
+               return NULL;
        zv = getzvolume (parent, zf, id);
        if (!zv)
                return NULL;
@@ -887,7 +889,7 @@ struct zvolume *archive_directory_plain (struct zfile *z)
        struct znode *zn;
        struct zarchive_info zai;
        uae_u8 id[8];
-       int rc;
+       int rc, index;
 
        memset (&zai, 0, sizeof zai);
        zv = zvolume_alloc (z, ArchiveFormatPLAIN, NULL, NULL);
@@ -906,9 +908,12 @@ struct zvolume *archive_directory_plain (struct zfile *z)
                zn = addfile (zv, z, L"s/startup-sequence", data, strlen (data));
                xfree (data);
        }
-       zf = zfile_dup (z);
-       if (zf) {
-               zf2 = zuncompress (NULL, zf, 0, ZFD_ALL & ~ZFD_ADF, &rc);
+       index = 0;
+       for (;;) {
+               zf = zfile_dup (z);
+               if (!zf)
+                       break;
+               zf2 = zuncompress (NULL, zf, 0, ZFD_ALL & ~ZFD_ADF, &rc, index);
                if (zf2) {
                        zf = NULL;
                        zai.name = zfile_getfilename (zf2);
@@ -918,9 +923,13 @@ struct zvolume *archive_directory_plain (struct zfile *z)
                        zfile_fseek (zf2, 0, SEEK_SET);
                        zn = zvolume_addfile_abs (zv, &zai);
                        if (zn)
-                               zn->offset = 1;
+                               zn->offset = index + 1;
                        zfile_fclose (zf2);
+               } else {
+                       if (rc == 0)
+                               break;
                }
+               index++;
                zfile_fclose (zf);
        }
        return zv;
@@ -932,7 +941,7 @@ struct zfile *archive_access_plain (struct znode *zn)
        if (zn->offset) {
                struct zfile *zf;
                z = zfile_fopen_empty (zn->volume->archive, zn->fullname, zn->size);
-               zf = zfile_fopen (zfile_getname (zn->volume->archive), L"rb", zn->volume->archive->zfdmask & ~ZFD_ADF);
+               zf = zfile_fopen2 (zfile_getname (zn->volume->archive), L"rb", zn->volume->archive->zfdmask & ~ZFD_ADF, zn->offset - 1);
                if (zf) {
                        zfile_fread (z->data, zn->size, 1, zf);
                        zfile_fclose (zf);