From 96b44693aec782f54d2fcac1ec9f1177b91a0394 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 15 Nov 2009 15:01:13 +0200 Subject: [PATCH] imported winuaesrc2000b21.zip --- blitter.c | 41 +- custom.c | 38 +- disk.c | 14 +- diskutil.c | 2 +- drawing.c | 4 +- hardfile.c | 16 +- include/cpu_prefetch.h | 26 +- include/memory.h | 2 +- include/serial.h | 6 + include/zarchive.h | 2 +- include/zfile.h | 3 +- memory.c | 25 +- newcpu.c | 2 +- od-win32/keyboard_win32.c | 2 +- od-win32/parser.c | 11 +- od-win32/serial_win32.c | 218 ++++++++- od-win32/sysconfig.h | 1 + od-win32/win32.h | 4 +- od-win32/win32gui.c | 36 +- od-win32/winuae_msvc/winuae_msvc.vcproj | 6 +- od-win32/winuaechangelog.txt | 21 + prowizard/rippers/Promizer20.c | 185 ++++---- uaeunp.c | 5 +- zfile.c | 571 +++++++++++++++++------- zfile_archive.c | 23 +- 25 files changed, 910 insertions(+), 354 deletions(-) diff --git a/blitter.c b/blitter.c index 21ed1c82..321c391f 100644 --- 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; } diff --git a/custom.c b/custom.c index 4e3b8dcd..4ceb32f3 100644 --- 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 1950a724..91f2b73b 100644 --- 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; diff --git a/diskutil.c b/diskutil.c index 1940fb84..e872bd9c 100644 --- a/diskutil.c +++ b/diskutil.c @@ -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; } diff --git a/drawing.c b/drawing.c index 3f5bf95c..f61661dc 100644 --- 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); } diff --git a/hardfile.c b/hardfile.c index 9a943554..caf6e3d4 100644 --- a/hardfile.c +++ b/hardfile.c @@ -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; diff --git a/include/cpu_prefetch.h b/include/cpu_prefetch.h index 26f3dd84..cd402ee1 100644 --- a/include/cpu_prefetch.h +++ b/include/cpu_prefetch.h @@ -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); diff --git a/include/memory.h b/include/memory.h index e49578c7..b369218c 100644 --- a/include/memory.h +++ b/include/memory.h @@ -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; diff --git a/include/serial.h b/include/serial.h index 0ba55c7d..bdfee4e4 100644 --- a/include/serial.h +++ b/include/serial.h @@ -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); diff --git a/include/zarchive.h b/include/zarchive.h index fc8f1a28..79f467de 100644 --- a/include/zarchive.h +++ b/include/zarchive.h @@ -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*); diff --git a/include/zfile.h b/include/zfile.h index 626b2731..57cda6ea 100644 --- a/include/zfile.h +++ b/include/zfile.h @@ -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); diff --git a/memory.c b/memory.c index 1f268adc..0940c4ae 100644 --- 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) diff --git a/newcpu.c b/newcpu.c index 204189ad..82d6177f 100644 --- 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; } diff --git a/od-win32/keyboard_win32.c b/od-win32/keyboard_win32.c index 5544888f..62c703f9 100644 --- a/od-win32/keyboard_win32.c +++ b/od-win32/keyboard_win32.c @@ -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: diff --git a/od-win32/parser.c b/od-win32/parser.c index 8d697319..f7f04c37 100644 --- a/od-win32/parser.c +++ b/od-win32/parser.c @@ -8,6 +8,9 @@ */ #include "sysconfig.h" + +//#undef SERIAL_ENET + #include #include #include @@ -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); diff --git a/od-win32/serial_win32.c b/od-win32/serial_win32.c index f2d9820e..3d7c821a 100644 --- a/od-win32/serial_win32.c +++ b/od-win32/serial_win32.c @@ -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 diff --git a/od-win32/sysconfig.h b/od-win32/sysconfig.h index 1dcb6e2e..302dcac0 100644 --- a/od-win32/sysconfig.h +++ b/od-win32/sysconfig.h @@ -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 */ diff --git a/od-win32/win32.h b/od-win32/win32.h index 52bbebd7..30123319 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -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"" diff --git a/od-win32/win32gui.c b/od-win32/win32gui.c index 443395b4..7740f75d 100644 --- a/od-win32/win32gui.c +++ b/od-win32/win32gui.c @@ -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); diff --git a/od-win32/winuae_msvc/winuae_msvc.vcproj b/od-win32/winuae_msvc/winuae_msvc.vcproj index 258ed5c5..4b2466b5 100644 --- a/od-win32/winuae_msvc/winuae_msvc.vcproj +++ b/od-win32/winuae_msvc/winuae_msvc.vcproj @@ -87,7 +87,7 @@ =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 diff --git a/prowizard/rippers/Promizer20.c b/prowizard/rippers/Promizer20.c index 967e9221..b0f0c95c 100644 --- a/prowizard/rippers/Promizer20.c +++ b/prowizard/rippers/Promizer20.c @@ -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_iPW_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 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 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 ; iname)) { + 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: diff --git a/zfile_archive.c b/zfile_archive.c index 547faad3..257a3d0b 100644 --- a/zfile_archive.c +++ b/zfile_archive.c @@ -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); -- 2.47.3