]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc1430b5.zip
authorToni Wilen <twilen@winuae.net>
Mon, 18 Jun 2007 13:31:06 +0000 (16:31 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:34:15 +0000 (21:34 +0200)
136 files changed:
a2091.c
akiko.c
ar.c
arcadia.c
archivers/7z/7zAlloc.c [moved from 7z/7zAlloc.c with 100% similarity]
archivers/7z/7zAlloc.h [moved from 7z/7zAlloc.h with 100% similarity]
archivers/7z/7zBuffer.c [moved from 7z/7zBuffer.c with 100% similarity]
archivers/7z/7zBuffer.h [moved from 7z/7zBuffer.h with 100% similarity]
archivers/7z/7zCrc.c [moved from 7z/7zCrc.c with 100% similarity]
archivers/7z/7zCrc.h [moved from 7z/7zCrc.h with 100% similarity]
archivers/7z/7zDecode.c [moved from 7z/7zDecode.c with 100% similarity]
archivers/7z/7zDecode.h [moved from 7z/7zDecode.h with 100% similarity]
archivers/7z/7zExtract.c [moved from 7z/7zExtract.c with 100% similarity]
archivers/7z/7zExtract.h [moved from 7z/7zExtract.h with 100% similarity]
archivers/7z/7zHeader.c [moved from 7z/7zHeader.c with 100% similarity]
archivers/7z/7zHeader.h [moved from 7z/7zHeader.h with 100% similarity]
archivers/7z/7zIn.c [moved from 7z/7zIn.c with 100% similarity]
archivers/7z/7zIn.h [moved from 7z/7zIn.h with 100% similarity]
archivers/7z/7zItem.c [moved from 7z/7zItem.c with 100% similarity]
archivers/7z/7zItem.h [moved from 7z/7zItem.h with 100% similarity]
archivers/7z/7zMain.c [moved from 7z/7zMain.c with 100% similarity]
archivers/7z/7zMethodID.c [moved from 7z/7zMethodID.c with 100% similarity]
archivers/7z/7zMethodID.h [moved from 7z/7zMethodID.h with 100% similarity]
archivers/7z/7zTypes.h [moved from 7z/7zTypes.h with 100% similarity]
archivers/7z/LzmaDecode.c [moved from 7z/LzmaDecode.c with 100% similarity]
archivers/7z/LzmaDecode.h [moved from 7z/LzmaDecode.h with 100% similarity]
archivers/7z/LzmaTypes.h [moved from 7z/LzmaTypes.h with 100% similarity]
archivers/dms/cdata.h [moved from dms/cdata.h with 100% similarity]
archivers/dms/crc_csum.c [moved from dms/crc_csum.c with 100% similarity]
archivers/dms/crc_csum.h [moved from dms/crc_csum.h with 100% similarity]
archivers/dms/getbits.c [moved from dms/getbits.c with 100% similarity]
archivers/dms/getbits.h [moved from dms/getbits.h with 100% similarity]
archivers/dms/maketbl.c [moved from dms/maketbl.c with 100% similarity]
archivers/dms/maketbl.h [moved from dms/maketbl.h with 100% similarity]
archivers/dms/pfile.c [moved from dms/pfile.c with 99% similarity]
archivers/dms/pfile.h [moved from dms/pfile.h with 100% similarity]
archivers/dms/tables.c [moved from dms/tables.c with 100% similarity]
archivers/dms/tables.h [moved from dms/tables.h with 100% similarity]
archivers/dms/u_deep.c [moved from dms/u_deep.c with 100% similarity]
archivers/dms/u_deep.h [moved from dms/u_deep.h with 100% similarity]
archivers/dms/u_heavy.c [moved from dms/u_heavy.c with 100% similarity]
archivers/dms/u_heavy.h [moved from dms/u_heavy.h with 100% similarity]
archivers/dms/u_init.c [moved from dms/u_init.c with 100% similarity]
archivers/dms/u_init.h [moved from dms/u_init.h with 100% similarity]
archivers/dms/u_medium.c [moved from dms/u_medium.c with 100% similarity]
archivers/dms/u_medium.h [moved from dms/u_medium.h with 100% similarity]
archivers/dms/u_quick.c [moved from dms/u_quick.c with 100% similarity]
archivers/dms/u_quick.h [moved from dms/u_quick.h with 100% similarity]
archivers/dms/u_rle.c [moved from dms/u_rle.c with 100% similarity]
archivers/dms/u_rle.h [moved from dms/u_rle.h with 100% similarity]
archivers/lha/crcio.c [new file with mode: 0755]
archivers/lha/dhuf.c [new file with mode: 0755]
archivers/lha/header.c [new file with mode: 0755]
archivers/lha/huf.c [new file with mode: 0755]
archivers/lha/larc.c [new file with mode: 0755]
archivers/lha/lha.h [new file with mode: 0755]
archivers/lha/lha_macro.h [new file with mode: 0755]
archivers/lha/lhamaketbl.c [new file with mode: 0755]
archivers/lha/lharc.c [new file with mode: 0755]
archivers/lha/shuf.c [new file with mode: 0755]
archivers/lha/slide.c [new file with mode: 0755]
archivers/lha/uae_lha.c [new file with mode: 0755]
archivers/lha/util.c [new file with mode: 0755]
archivers/lzx/unlzx.c [new file with mode: 0755]
archivers/xfd/xfd.c [new file with mode: 0755]
archivers/xfd/xfdmaster.h [new file with mode: 0755]
archivers/zip/unzip.c [moved from unzip.c with 99% similarity]
archivers/zip/unzip.h [moved from include/unzip.h with 100% similarity]
audio.c
blitter.c
blkdev.c
bsdsocket.c
catweasel.c
cdtv.c
cfgfile.c
cia.c
compemu_fpp.c
compemu_support.c
crc32.c
custom.c
debug.c
disk.c
drawing.c
driveclick.c
fdi2raw.c
filesys.c
fpp.c
fsdb.c
gayle.c
gencpu.c
hardfile.c
include/blkdev.h
include/cdtv.h
include/compemu.h
include/crc32.h
include/filesys.h
include/fsdb.h
include/gfxfilter.h
include/memory.h
include/ncr_scsi.h
include/newcpu.h
include/sysdeps.h
include/zarchive.h [new file with mode: 0755]
include/zfile.h
inputdevice.c
keybuf.c
memory.c
moduleripper.c
ncr_scsi.c
newcpu.c
od-win32/avioutput.c
od-win32/bsdsock.c
od-win32/fsdb_win32.c
od-win32/hardfile_win32.c
od-win32/md-fpp.h
od-win32/mman.c
od-win32/picasso96_win.c
od-win32/resources/resource.h
od-win32/resources/resource.hx [moved from od-win32/resources/resource with 99% similarity]
od-win32/resources/winuae.rc
od-win32/sysconfig.h
od-win32/threaddep/thread.h
od-win32/win32.h
od-win32/win32gui.c
od-win32/winuae_msvc/winuae_msvc.vcproj
od-win32/winuaechangelog.txt
prowizard/prowiz.c
savestate.c
scsi.c
scsiemul.c
traps.c
uaeexe.c
uaeipc.c
uaeserial.c
zfile.c
zfile_archive.c [new file with mode: 0755]

diff --git a/a2091.c b/a2091.c
index 9325b4dc77004d7ae19c5c584cc8533d215e126d..cf5327fc6d72dc4a3f326b72a2853ade750287bd 100755 (executable)
--- a/a2091.c
+++ b/a2091.c
@@ -1155,7 +1155,7 @@ int addscsi(int ch, char *path, int blocksize, int readonly,
     struct hd_hardfiledata *hfd;
     freescsi(scsis[ch]);
     scsis[ch] = NULL;
-    hfd = xcalloc(sizeof(struct hd_hardfiledata), 1);
+    hfd = (struct hd_hardfiledata*)xcalloc(sizeof(struct hd_hardfiledata), 1);
     if (!hdf_hd_open(hfd, path, blocksize, readonly, devname, sectors, surfaces, reserved, bootpri, filesys))
        return 0;
     hfd->ansi_version = scsi_level;
@@ -1302,12 +1302,12 @@ void a2091_init (void)
                int i;
                rom_size = 32768;
                rombankswitcher = 1;
-               rom = xmalloc (rom_size * 2);
+               rom = (uae_u8*)xmalloc (rom_size * 2);
                for (i = 0; i < rom_size; i++)
                    zfile_fread(rom + i * 2, 1, 1, z);
            } else {
                rom_size = 16384;
-               rom = xmalloc (rom_size);
+               rom = (uae_u8*)xmalloc (rom_size);
                zfile_fread (rom, rom_size, 1, z);
            }
            zfile_fclose(z);
diff --git a/akiko.c b/akiko.c
index da6bc9e8dff7d3d7273bc7128401b3f4205d7ed7..63823a0dbc695c5bb554cdb5a2af960c3dc571e4 100755 (executable)
--- a/akiko.c
+++ b/akiko.c
@@ -24,6 +24,7 @@
 #include "akiko.h"
 #include "gui.h"
 #include "crc32.h"
+#include "uae.h"
 
 #define AKIKO_DEBUG_NVRAM 0
 #define AKIKO_DEBUG_IO 0
@@ -1411,10 +1412,10 @@ int akiko_init (void)
        }
        if (!sys_cddev_open ()) {
            cdromok = 1;
-           sector_buffer_1 = malloc (SECTOR_BUFFER_SIZE * 2048);
-           sector_buffer_2 = malloc (SECTOR_BUFFER_SIZE * 2048);
-           sector_buffer_info_1 = malloc (SECTOR_BUFFER_SIZE);
-           sector_buffer_info_2 = malloc (SECTOR_BUFFER_SIZE);
+           sector_buffer_1 = (uae_u8*)malloc (SECTOR_BUFFER_SIZE * 2048);
+           sector_buffer_2 = (uae_u8*)malloc (SECTOR_BUFFER_SIZE * 2048);
+           sector_buffer_info_1 = (uae_u8*)malloc (SECTOR_BUFFER_SIZE);
+           sector_buffer_info_2 = (uae_u8*)malloc (SECTOR_BUFFER_SIZE);
            sector_buffer_sector_1 = -1;
            sector_buffer_sector_2 = -1;
            patchrom ();
@@ -1439,7 +1440,7 @@ uae_u8 *save_akiko(int *len)
     uae_u8 *dstbak, *dst;
     int i;
 
-    dstbak = dst = malloc (1000);
+    dstbak = dst = (uae_u8*)malloc (1000);
     save_u16 (0);
     save_u16 (0xCAFE);
     save_u32 (cdrom_status1);
diff --git a/ar.c b/ar.c
index ac95b70fc068387756e3ada6cc1d404159b1590f..c1d21665c0cf7187b1d727eaaf7d981f92befc96 100755 (executable)
--- a/ar.c
+++ b/ar.c
@@ -1572,7 +1572,7 @@ int action_replay_load(void)
        return 0;
     }
     action_replay_flag = ACTION_REPLAY_INACTIVE;
-    armemory_rom = xmalloc (ar_rom_file_size);
+    armemory_rom = (uae_u8*)xmalloc (ar_rom_file_size);
     zfile_fread (armemory_rom, ar_rom_file_size, 1, f);
     zfile_fclose (f);
     if (ar_rom_file_size == 65536) {
@@ -1591,7 +1591,7 @@ int action_replay_load(void)
     }
     arram_mask = arram_size - 1;
     arrom_mask = arrom_size - 1;
-    armemory_ram = xcalloc (arram_size, 1);
+    armemory_ram = (uae_u8*)xcalloc (arram_size, 1);
     write_log("Action Replay %d installed at %08.8X, size %08.8X\n", armodel, arrom_start, arrom_size);
     action_replay_setbanks ();
     action_replay_version();
@@ -1866,7 +1866,7 @@ uae_u8 *save_hrtmon (int *len, uae_u8 *dstptr)
     if (dstptr)
        dstbak = dst = dstptr;
     else
-       dstbak = dst = malloc (hrtmem_size + sizeof ar_custom + sizeof ar_ciaa + sizeof ar_ciab + 1024);
+       dstbak = dst = (uae_u8*)malloc (hrtmem_size + sizeof ar_custom + sizeof ar_ciaa + sizeof ar_ciab + 1024);
     save_u8 (0);
     save_u8 (0);
     save_u32 (0);
index 41829b31a049f95dc843756d3ccbd2df70fb443f..9d6af363ec630fe6f9055e757c910b9baae53350 100755 (executable)
--- a/arcadia.c
+++ b/arcadia.c
@@ -90,7 +90,7 @@ static int load_rom8 (char *xpath, uae_u8 *mem,       int extra)
     struct zfile *zf;
     char path[MAX_DPATH];
     int i;
-    uae_u8 *tmp = xmalloc (131072);
+    uae_u8 *tmp = (uae_u8*)xmalloc (131072);
     char *bin = extra == 1 ? ".bin" : "";
 
     memset (tmp, 0, 131072);
@@ -396,7 +396,7 @@ int arcadia_map_banks (void)
 {
     if (!arcadia_bios)
        return 0;
-    arbmemory = xmalloc (allocated_arbmemory);
+    arbmemory = (uae_u8*)xmalloc (allocated_arbmemory);
     arbbmemory = arbmemory + bios_offset;
     memset (arbmemory, 0, allocated_arbmemory);
     if (!load_roms (arcadia_bios)) {
similarity index 100%
rename from 7z/7zAlloc.c
rename to archivers/7z/7zAlloc.c
similarity index 100%
rename from 7z/7zAlloc.h
rename to archivers/7z/7zAlloc.h
similarity index 100%
rename from 7z/7zBuffer.c
rename to archivers/7z/7zBuffer.c
similarity index 100%
rename from 7z/7zBuffer.h
rename to archivers/7z/7zBuffer.h
similarity index 100%
rename from 7z/7zCrc.c
rename to archivers/7z/7zCrc.c
similarity index 100%
rename from 7z/7zCrc.h
rename to archivers/7z/7zCrc.h
similarity index 100%
rename from 7z/7zDecode.c
rename to archivers/7z/7zDecode.c
similarity index 100%
rename from 7z/7zDecode.h
rename to archivers/7z/7zDecode.h
similarity index 100%
rename from 7z/7zExtract.c
rename to archivers/7z/7zExtract.c
similarity index 100%
rename from 7z/7zExtract.h
rename to archivers/7z/7zExtract.h
similarity index 100%
rename from 7z/7zHeader.c
rename to archivers/7z/7zHeader.c
similarity index 100%
rename from 7z/7zHeader.h
rename to archivers/7z/7zHeader.h
similarity index 100%
rename from 7z/7zIn.c
rename to archivers/7z/7zIn.c
similarity index 100%
rename from 7z/7zIn.h
rename to archivers/7z/7zIn.h
similarity index 100%
rename from 7z/7zItem.c
rename to archivers/7z/7zItem.c
similarity index 100%
rename from 7z/7zItem.h
rename to archivers/7z/7zItem.h
similarity index 100%
rename from 7z/7zMain.c
rename to archivers/7z/7zMain.c
similarity index 100%
rename from 7z/7zMethodID.c
rename to archivers/7z/7zMethodID.c
similarity index 100%
rename from 7z/7zMethodID.h
rename to archivers/7z/7zMethodID.h
similarity index 100%
rename from 7z/7zTypes.h
rename to archivers/7z/7zTypes.h
similarity index 100%
rename from 7z/LzmaDecode.c
rename to archivers/7z/LzmaDecode.c
similarity index 100%
rename from 7z/LzmaDecode.h
rename to archivers/7z/LzmaDecode.h
similarity index 100%
rename from 7z/LzmaTypes.h
rename to archivers/7z/LzmaTypes.h
similarity index 100%
rename from dms/cdata.h
rename to archivers/dms/cdata.h
similarity index 100%
rename from dms/crc_csum.c
rename to archivers/dms/crc_csum.c
similarity index 100%
rename from dms/crc_csum.h
rename to archivers/dms/crc_csum.h
similarity index 100%
rename from dms/getbits.c
rename to archivers/dms/getbits.c
similarity index 100%
rename from dms/getbits.h
rename to archivers/dms/getbits.h
similarity index 100%
rename from dms/maketbl.c
rename to archivers/dms/maketbl.c
similarity index 100%
rename from dms/maketbl.h
rename to archivers/dms/maketbl.h
similarity index 99%
rename from dms/pfile.c
rename to archivers/dms/pfile.c
index a1490c46a35b681ad31abff01a87299d0d876166..dd5f1cc14a32bf0e2c65163bc87373d8ed848f11 100755 (executable)
@@ -404,7 +404,7 @@ static USHORT Unpack_Track(UCHAR *b1, UCHAR *b2, USHORT pklen2, USHORT unpklen,
     passretries--;
     pwrounds = 0;
     maybeencrypted = 0;
-    tmp = malloc (pklen1);
+    tmp = (unsigned char*)malloc (pklen1);
     memcpy (tmp, b1, pklen1);
     for (;;) {
        r = Unpack_Track_2(b1, b2, pklen2, unpklen, cmode, flags);
similarity index 100%
rename from dms/pfile.h
rename to archivers/dms/pfile.h
similarity index 100%
rename from dms/tables.c
rename to archivers/dms/tables.c
similarity index 100%
rename from dms/tables.h
rename to archivers/dms/tables.h
similarity index 100%
rename from dms/u_deep.c
rename to archivers/dms/u_deep.c
similarity index 100%
rename from dms/u_deep.h
rename to archivers/dms/u_deep.h
similarity index 100%
rename from dms/u_heavy.c
rename to archivers/dms/u_heavy.c
similarity index 100%
rename from dms/u_heavy.h
rename to archivers/dms/u_heavy.h
similarity index 100%
rename from dms/u_init.c
rename to archivers/dms/u_init.c
similarity index 100%
rename from dms/u_init.h
rename to archivers/dms/u_init.h
similarity index 100%
rename from dms/u_medium.c
rename to archivers/dms/u_medium.c
similarity index 100%
rename from dms/u_medium.h
rename to archivers/dms/u_medium.h
similarity index 100%
rename from dms/u_quick.c
rename to archivers/dms/u_quick.c
similarity index 100%
rename from dms/u_quick.h
rename to archivers/dms/u_quick.h
similarity index 100%
rename from dms/u_rle.c
rename to archivers/dms/u_rle.c
similarity index 100%
rename from dms/u_rle.h
rename to archivers/dms/u_rle.h
diff --git a/archivers/lha/crcio.c b/archivers/lha/crcio.c
new file mode 100755 (executable)
index 0000000..ecf60ce
--- /dev/null
@@ -0,0 +1,348 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                                                                                        */
+/*                             crcio.c -- crc input / output                                                           */
+/*                                                                                                                                                     */
+/*             Modified                        Nobutaka Watazaki                                                       */
+/*                                                                                                                                                     */
+/*     Ver. 1.14       Source All chagned                              1995.01.14      N.Watazaki              */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+/* ------------------------------------------------------------------------ */
+static unsigned short crctable[UCHAR_MAX + 1];
+static unsigned char subbitbuf, bitcount;
+#ifdef EUC
+static int      putc_euc_cache;
+#endif
+static int      getc_euc_cache;
+
+/* ------------------------------------------------------------------------ */
+void
+make_crctable( /* void */ )
+{
+       unsigned int    i, j, r;
+
+       for (i = 0; i <= UCHAR_MAX; i++) {
+               r = i;
+               for (j = 0; j < CHAR_BIT; j++)
+                       if (r & 1)
+                               r = (r >> 1) ^ CRCPOLY;
+                       else
+                               r >>= 1;
+               crctable[i] = r;
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+#ifdef NEED_INCREMENTAL_INDICATOR
+static void
+put_indicator(count)
+       long int        count;
+{
+       if (!quiet && indicator_threshold) {
+               while (count > indicator_count) {
+                       putchar('o');
+                       fflush(stdout);
+                       indicator_count += indicator_threshold;
+               }
+       }
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+unsigned short
+calccrc(p, n)
+       unsigned char  *p;
+       unsigned int    n;
+{
+       reading_size += n;
+#ifdef NEED_INCREMENTAL_INDICATOR
+       put_indicator(reading_size);
+#endif
+       while (n-- > 0)
+               UPDATE_CRC(*p++);
+       return crc;
+}
+
+/* ------------------------------------------------------------------------ */
+void
+fillbuf(n)                     /* Shift bitbuf n bits left, read n bits */
+       unsigned char   n;
+{
+       while (n > bitcount) {
+               n -= bitcount;
+               lhabitbuf = (lhabitbuf << bitcount) + (subbitbuf >> (CHAR_BIT - bitcount));
+               if (compsize != 0) {
+                       compsize--;
+                       subbitbuf = (unsigned char) zfile_getc(infile);
+               }
+               else
+                       subbitbuf = 0;
+               bitcount = CHAR_BIT;
+       }
+       bitcount -= n;
+       lhabitbuf = (lhabitbuf << n) + (subbitbuf >> (CHAR_BIT - n));
+       subbitbuf <<= n;
+}
+
+/* ------------------------------------------------------------------------ */
+unsigned short
+getbits(n)
+       unsigned char   n;
+{
+       unsigned short  x;
+
+       x = lhabitbuf >> (2 * CHAR_BIT - n);
+       fillbuf(n);
+       return x;
+}
+#if 0
+/* ------------------------------------------------------------------------ */
+void
+putcode(n, x)                  /* Write rightmost n bits of x */
+       unsigned char   n;
+       unsigned short  x;
+{
+       while (n >= bitcount) {
+               n -= bitcount;
+               subbitbuf += x >> (USHRT_BIT - bitcount);
+               x <<= bitcount;
+               if (compsize < origsize) {
+                       if (fwrite(&subbitbuf, 1, 1, outfile) == 0) {
+                               /* fileerror(WTERR, outfile); */
+                           fatal_error("Write error in crcio.c(putcode)\n");
+                               /* exit(errno); */
+                       }
+                       compsize++;
+               }
+               else
+                       unpackable = 1;
+               subbitbuf = 0;
+               bitcount = CHAR_BIT;
+       }
+       subbitbuf += x >> (USHRT_BIT - bitcount);
+       bitcount -= n;
+}
+
+/* ------------------------------------------------------------------------ */
+void
+putbits(n, x)                  /* Write rightmost n bits of x */
+       unsigned char   n;
+       unsigned short  x;
+{
+       x <<= USHRT_BIT - n;
+       while (n >= bitcount) {
+               n -= bitcount;
+               subbitbuf += x >> (USHRT_BIT - bitcount);
+               x <<= bitcount;
+               if (compsize < origsize) {
+                       if (fwrite(&subbitbuf, 1, 1, outfile) == 0) {
+                               /* fileerror(WTERR, outfile); */
+                           fatal_error("Write error in crcio.c(putbits)\n");
+                               /* exit(errno); */
+                       }
+                       compsize++;
+               }
+               else
+                       unpackable = 1;
+               subbitbuf = 0;
+               bitcount = CHAR_BIT;
+       }
+       subbitbuf += x >> (USHRT_BIT - bitcount);
+       bitcount -= n;
+}
+#endif
+/* ------------------------------------------------------------------------ */
+int
+fread_crc(p, n, fp)
+       unsigned char  *p;
+       int             n;
+       struct zfile   *fp;
+{
+       n = zfile_fread(p, 1, n, fp);
+
+       calccrc(p, n);
+       return n;
+}
+
+/* ------------------------------------------------------------------------ */
+void
+fwrite_crc(p, n, fp)
+       unsigned char  *p;
+       int             n;
+       struct zfile   *fp;
+{
+       calccrc(p, n);
+       if (verify_mode)
+               return;
+
+       if (fp) {
+           zfile_fwrite(p, 1, n, fp);
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+void
+init_code_cache( /* void */ )
+{                              /* called from copyfile() in util.c */
+#ifdef EUC
+       putc_euc_cache = EOF;
+#endif
+       getc_euc_cache = EOF;
+}
+
+void
+init_getbits( /* void */ )
+{
+       lhabitbuf = 0;
+       subbitbuf = 0;
+       bitcount = 0;
+       fillbuf(2 * CHAR_BIT);
+#ifdef EUC
+       putc_euc_cache = EOF;
+#endif
+}
+
+/* ------------------------------------------------------------------------ */
+void
+init_putbits( /* void */ )
+{
+       bitcount = CHAR_BIT;
+       subbitbuf = 0;
+       getc_euc_cache = EOF;
+}
+
+/* ------------------------------------------------------------------------ */
+#ifdef EUC
+void
+putc_euc(c, fd)
+       int             c;
+       FILE           *fd;
+{
+       int             d;
+
+       if (putc_euc_cache == EOF) {
+               if (!euc_mode || c < 0x81 || c > 0xFC) {
+                       putc(c, fd);
+                       return;
+               }
+               if (c >= 0xA0 && c < 0xE0) {
+                       putc(0x8E, fd); /* single shift */
+                       putc(c, fd);
+                       return;
+               }
+               putc_euc_cache = c;     /* save first byte */
+               return;
+       }
+       d = putc_euc_cache;
+       putc_euc_cache = EOF;
+       if (d >= 0xA0)
+               d -= 0xE0 - 0xA0;
+       if (c > 0x9E) {
+               c = c - 0x9F + 0x21;
+               d = (d - 0x81) * 2 + 0x22;
+       }
+       else {
+               if (c > 0x7E)
+                       c--;
+               c -= 0x1F;
+               d = (d - 0x81) * 2 + 0x21;
+       }
+       putc(0x80 | d, fd);
+       putc(0x80 | c, fd);
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+int
+fwrite_txt(p, n, fp)
+       unsigned char  *p;
+       int             n;
+       FILE           *fp;
+{
+       while (--n >= 0) {
+               if (*p != '\015' && *p != '\032') {
+#ifdef EUC
+                       putc_euc(*p, fp);
+#else
+                       putc(*p, fp);
+#endif
+               }
+
+               prev_char = *p++;
+       }
+       return (ferror(fp));
+}
+
+/* ------------------------------------------------------------------------ */
+int
+fread_txt(p, n, fp)
+       unsigned char  *p;
+       int             n;
+       FILE           *fp;
+{
+       int             c;
+       int             cnt = 0;
+
+       while (cnt < n) {
+               if (getc_euc_cache != EOF) {
+                       c = getc_euc_cache;
+                       getc_euc_cache = EOF;
+               }
+               else {
+                       if ((c = fgetc(fp)) == EOF)
+                               break;
+                       if (c == '\n') {
+                               getc_euc_cache = c;
+                               ++origsize;
+                               c = '\r';
+                       }
+#ifdef EUC
+                       else if (euc_mode && (c == 0x8E || 0xA0 < c && c < 0xFF)) {
+                               int             d = fgetc(fp);
+                               if (d == EOF) {
+                                       *p++ = c;
+                                       cnt++;
+                                       break;
+                               }
+                               if (c == 0x8E) {        /* single shift (KANA) */
+                                       if ((0x20 < d && d < 0x7F) || (0xA0 < d && d < 0xFF))
+                                               c = d | 0x80;
+                                       else
+                                               getc_euc_cache = d;
+                               }
+                               else {
+                                       if (0xA0 < d && d < 0xFF) {     /* if GR */
+                                               c &= 0x7F;      /* convert to MS-kanji */
+                                               d &= 0x7F;
+                                               if (!(c & 1)) {
+                                                       c--;
+                                                       d += 0x7F - 0x21;
+                                               }
+                                               if ((d += 0x40 - 0x21) > 0x7E)
+                                                       d++;
+                                               if ((c = (c >> 1) + 0x71) >= 0xA0)
+                                                       c += 0xE0 - 0xA0;
+                                       }
+                                       getc_euc_cache = d;
+                               }
+                       }
+#endif
+               }
+               *p++ = c;
+               cnt++;
+       }
+       return cnt;
+}
+
+/* ------------------------------------------------------------------------ */
+unsigned short
+calc_header_crc(p, n)          /* Thanks T.Okamoto */
+       unsigned char  *p;
+       unsigned int    n;
+{
+       crc = 0;
+       while (n-- > 0)
+               UPDATE_CRC(*p++);
+       return crc;
+}
diff --git a/archivers/lha/dhuf.c b/archivers/lha/dhuf.c
new file mode 100755 (executable)
index 0000000..9d6e60c
--- /dev/null
@@ -0,0 +1,350 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                                                                                        */
+/*                             dhuf.c -- Dynamic Hufffman routine                                                      */
+/*                                                                                                                                                     */
+/*             Modified                        H.Yoshizaki                                                                     */
+/*                                                                                                                                                     */
+/*     Ver. 1.14       Source All chagned                              1995.01.14      N.Watazaki              */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+/* ------------------------------------------------------------------------ */
+static short    child[TREESIZE], parent[TREESIZE], block[TREESIZE], edge[TREESIZE], stock[TREESIZE],
+                s_node[TREESIZE / 2];  /* Changed N.Watazaki */
+/*     node[..] -> s_node[..] */
+
+static unsigned short freq[TREESIZE];
+
+static unsigned short total_p;
+static int      avail, n1;
+static int      most_p, nn;
+static unsigned long nextcount;
+/* ------------------------------------------------------------------------ */
+void
+start_c_dyn( /* void */ )
+{
+       int             i, j, f;
+
+       n1 = (n_max >= 256 + maxmatch - THRESHOLD + 1) ? 512 : n_max - 1;
+       for (i = 0; i < TREESIZE_C; i++) {
+               stock[i] = i;
+               block[i] = 0;
+       }
+       for (i = 0, j = n_max * 2 - 2; i < n_max; i++, j--) {
+               freq[j] = 1;
+               child[j] = ~i;
+               s_node[i] = j;
+               block[j] = 1;
+       }
+       avail = 2;
+       edge[1] = n_max - 1;
+       i = n_max * 2 - 2;
+       while (j >= 0) {
+               f = freq[j] = freq[i] + freq[i - 1];
+               child[j] = i;
+               parent[i] = parent[i - 1] = j;
+               if (f == freq[j + 1]) {
+                       edge[block[j] = block[j + 1]] = j;
+               }
+               else {
+                       edge[block[j] = stock[avail++]] = j;
+               }
+               i -= 2;
+               j--;
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+start_p_dyn( /* void */ )
+{
+       freq[ROOT_P] = 1;
+       child[ROOT_P] = ~(N_CHAR);
+       s_node[N_CHAR] = ROOT_P;
+       edge[block[ROOT_P] = stock[avail++]] = ROOT_P;
+       most_p = ROOT_P;
+       total_p = 0;
+       nn = 1 << dicbit;
+       nextcount = 64;
+}
+
+/* ------------------------------------------------------------------------ */
+void
+decode_start_dyn( /* void */ )
+{
+       n_max = 286;
+       maxmatch = MAXMATCH;
+       init_getbits();
+       start_c_dyn();
+       start_p_dyn();
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+reconst(start, end)
+       int             start;
+       int             end;
+{
+       int             i, j, k, l, b;
+       unsigned int    f, g;
+
+       for (i = j = start; i < end; i++) {
+               if ((k = child[i]) < 0) {
+                       freq[j] = (freq[i] + 1) / 2;
+                       child[j] = k;
+                       j++;
+               }
+               if (edge[b = block[i]] == i) {
+                       stock[--avail] = b;
+               }
+       }
+       j--;
+       i = end - 1;
+       l = end - 2;
+       while (i >= start) {
+               while (i >= l) {
+                       freq[i] = freq[j];
+                       child[i] = child[j];
+                       i--, j--;
+               }
+               f = freq[l] + freq[l + 1];
+               for (k = start; f < freq[k]; k++);
+               while (j >= k) {
+                       freq[i] = freq[j];
+                       child[i] = child[j];
+                       i--, j--;
+               }
+               freq[i] = f;
+               child[i] = l + 1;
+               i--;
+               l -= 2;
+       }
+       f = 0;
+       for (i = start; i < end; i++) {
+               if ((j = child[i]) < 0)
+                       s_node[~j] = i;
+               else
+                       parent[j] = parent[j - 1] = i;
+               if ((g = freq[i]) == f) {
+                       block[i] = b;
+               }
+               else {
+                       edge[b = block[i] = stock[avail++]] = i;
+                       f = g;
+               }
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+static int
+swap_inc(p)
+       int             p;
+{
+       int             b, q, r, s;
+
+       b = block[p];
+       if ((q = edge[b]) != p) {       /* swap for leader */
+               r = child[p];
+               s = child[q];
+               child[p] = s;
+               child[q] = r;
+               if (r >= 0)
+                       parent[r] = parent[r - 1] = q;
+               else
+                       s_node[~r] = q;
+               if (s >= 0)
+                       parent[s] = parent[s - 1] = p;
+               else
+                       s_node[~s] = p;
+               p = q;
+               goto Adjust;
+       }
+       else if (b == block[p + 1]) {
+Adjust:
+               edge[b]++;
+               if (++freq[p] == freq[p - 1]) {
+                       block[p] = block[p - 1];
+               }
+               else {
+                       edge[block[p] = stock[avail++]] = p;    /* create block */
+               }
+       }
+       else if (++freq[p] == freq[p - 1]) {
+               stock[--avail] = b;     /* delete block */
+               block[p] = block[p - 1];
+       }
+       return parent[p];
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+update_c(p)
+       int             p;
+{
+       int             q;
+
+       if (freq[ROOT_C] == 0x8000) {
+               reconst(0, n_max * 2 - 1);
+       }
+       freq[ROOT_C]++;
+       q = s_node[p];
+       do {
+               q = swap_inc(q);
+       } while (q != ROOT_C);
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+update_p(p)
+       int             p;
+{
+       int             q;
+
+       if (total_p == 0x8000) {
+               reconst(ROOT_P, most_p + 1);
+               total_p = freq[ROOT_P];
+               freq[ROOT_P] = 0xffff;
+       }
+       q = s_node[p + N_CHAR];
+       while (q != ROOT_P) {
+               q = swap_inc(q);
+       }
+       total_p++;
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+make_new_node(p)
+       int             p;
+{
+       int             q, r;
+
+       r = most_p + 1;
+       q = r + 1;
+       s_node[~(child[r] = child[most_p])] = r;
+       child[q] = ~(p + N_CHAR);
+       child[most_p] = q;
+       freq[r] = freq[most_p];
+       freq[q] = 0;
+       block[r] = block[most_p];
+       if (most_p == ROOT_P) {
+               freq[ROOT_P] = 0xffff;
+               edge[block[ROOT_P]]++;
+       }
+       parent[r] = parent[q] = most_p;
+       edge[block[q] = stock[avail++]] = s_node[p + N_CHAR] = most_p = q;
+       update_p(p);
+}
+
+#if 0
+/* ------------------------------------------------------------------------ */
+static void
+encode_c_dyn(c)
+       unsigned int    c;
+{
+       unsigned int    bits;
+       int             p, d, cnt;
+
+       d = c - n1;
+       if (d >= 0) {
+               c = n1;
+       }
+       cnt = bits = 0;
+       p = s_node[c];
+       do {
+               bits >>= 1;
+               if (p & 1) {
+                       bits |= 0x8000;
+               }
+               if (++cnt == 16) {
+                       putcode(16, bits);
+                       cnt = bits = 0;
+               }
+       } while ((p = parent[p]) != ROOT_C);
+       putcode(cnt, bits);
+       if (d >= 0)
+               putbits(8, d);
+       update_c(c);
+}
+#endif
+/* ------------------------------------------------------------------------ */
+unsigned short
+decode_c_dyn( /* void */ )
+{
+       int             c;
+       short           buf, cnt;
+
+       c = child[ROOT_C];
+       buf = lhabitbuf;
+       cnt = 0;
+       do {
+               c = child[c - (buf < 0)];
+               buf <<= 1;
+               if (++cnt == 16) {
+                       fillbuf(16);
+                       buf = lhabitbuf;
+                       cnt = 0;
+               }
+       } while (c > 0);
+       fillbuf(cnt);
+       c = ~c;
+       update_c(c);
+       if (c == n1)
+               c += getbits(8);
+       return c;
+}
+
+/* ------------------------------------------------------------------------ */
+unsigned short
+decode_p_dyn( /* void */ )
+{
+       int             c;
+       short           buf, cnt;
+
+       while (count > nextcount) {
+               make_new_node(nextcount / 64);
+               if ((nextcount += 64) >= nn)
+                       nextcount = 0xffffffff;
+       }
+       c = child[ROOT_P];
+       buf = lhabitbuf;
+       cnt = 0;
+       while (c > 0) {
+               c = child[c - (buf < 0)];
+               buf <<= 1;
+               if (++cnt == 16) {
+                       fillbuf(16);
+                       buf = lhabitbuf;
+                       cnt = 0;
+               }
+       }
+       fillbuf(cnt);
+       c = (~c) - N_CHAR;
+       update_p(c);
+
+       return (c << 6) + getbits(6);
+}
+#if 0
+/* ------------------------------------------------------------------------ */
+void
+output_dyn(code, pos)
+       unsigned int    code;
+       unsigned int    pos;
+{
+       encode_c_dyn(code);
+       if (code >= 0x100) {
+               encode_p_st0(pos);
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+void
+encode_end_dyn( /* void */ )
+{
+       putcode(7, 0);
+}
+#endif
+/* Local Variables: */
+/* mode:c */
+/* tab-width:4 */
+/* End: */
diff --git a/archivers/lha/header.c b/archivers/lha/header.c
new file mode 100755 (executable)
index 0000000..420a47a
--- /dev/null
@@ -0,0 +1,723 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                                                                                        */
+/*                             header.c -- header manipulate functions                                         */
+/*                                                                                                                                                     */
+/*             Modified                        Nobutaka Watazaki                                                       */
+/*                                                                                                                                                     */
+/*     Original                                                                                                Y.Tagawa                */
+/*     modified                                                                        1991.12.16      M.Oki                   */
+/*     Ver. 1.10  Symbolic Link added                          1993.10.01      N.Watazaki              */
+/*     Ver. 1.13b Symbolic Link Bug Fix                        1994.08.22      N.Watazaki              */
+/*     Ver. 1.14  Source All chagned                           1995.01.14      N.Watazaki              */
+/*  Ver. 1.14i bug fixed                                               2000.10.06  t.okamoto       */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+/* ------------------------------------------------------------------------ */
+static char    *get_ptr;
+/* ------------------------------------------------------------------------ */
+int
+calc_sum(p, len)
+       register char  *p;
+       register int    len;
+{
+       register int    sum;
+
+       for (sum = 0; len; len--)
+               sum += *p++;
+
+       return sum & 0xff;
+}
+
+/* ------------------------------------------------------------------------ */
+static unsigned short
+get_word()
+{
+       int             b0, b1;
+
+       b0 = get_byte();
+       b1 = get_byte();
+       return (b1 << 8) + b0;
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+put_word(v)
+       unsigned int    v;
+{
+       put_byte(v);
+       put_byte(v >> 8);
+}
+
+/* ------------------------------------------------------------------------ */
+static long
+get_longword()
+{
+       long            b0, b1, b2, b3;
+
+       b0 = get_byte();
+       b1 = get_byte();
+       b2 = get_byte();
+       b3 = get_byte();
+       return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0;
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+put_longword(v)
+       long            v;
+{
+       put_byte(v);
+       put_byte(v >> 8);
+       put_byte(v >> 16);
+       put_byte(v >> 24);
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+msdos_to_unix_filename(name, len)
+       register char  *name;
+       register int    len;
+{
+       register int    i;
+
+#ifdef MULTIBYTE_CHAR
+       for (i = 0; i < len; i++) {
+               if (MULTIBYTE_FIRST_P(name[i]) &&
+                   MULTIBYTE_SECOND_P(name[i + 1]))
+                       i++;
+               else if (name[i] == '\\')
+                       name[i] = '/';
+               else if (!noconvertcase && isupper(name[i]))
+                       name[i] = tolower(name[i]);
+       }
+#else
+       for (i = 0; i < len; i++) {
+               if (name[i] == '\\')
+                       name[i] = '/';
+               else if (!noconvertcase && isupper(name[i]))
+                       name[i] = tolower(name[i]);
+       }
+#endif
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+generic_to_unix_filename(name, len)
+       register char  *name;
+       register int    len;
+{
+       register int    i;
+       boolean         lower_case_used = FALSE;
+
+#ifdef MULTIBYTE_CHAR
+       for (i = 0; i < len; i++) {
+               if (MULTIBYTE_FIRST_P(name[i]) &&
+                   MULTIBYTE_SECOND_P(name[i + 1]))
+                       i++;
+               else if (islower(name[i])) {
+                       lower_case_used = TRUE;
+                       break;
+               }
+       }
+       for (i = 0; i < len; i++) {
+               if (MULTIBYTE_FIRST_P(name[i]) &&
+                   MULTIBYTE_SECOND_P(name[i + 1]))
+                       i++;
+               else if (name[i] == '\\')
+                       name[i] = '/';
+               else if (!noconvertcase && !lower_case_used && isupper(name[i]))
+                       name[i] = tolower(name[i]);
+       }
+#else
+       for (i = 0; i < len; i++)
+               if (islower(name[i])) {
+                       lower_case_used = TRUE;
+                       break;
+               }
+       for (i = 0; i < len; i++) {
+               if (name[i] == '\\')
+                       name[i] = '/';
+               else if (!noconvertcase && !lower_case_used && isupper(name[i]))
+                       name[i] = tolower(name[i]);
+       }
+#endif
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+macos_to_unix_filename(name, len)
+       register char  *name;
+       register int    len;
+{
+       register int    i;
+
+       for (i = 0; i < len; i++) {
+               if (name[i] == ':')
+                       name[i] = '/';
+               else if (name[i] == '/')
+                       name[i] = ':';
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+unix_to_generic_filename(name, len)
+       register char  *name;
+       register int    len;
+{
+       register int    i;
+
+       for (i = 0; i < len; i++) {
+               if (name[i] == '/')
+                       name[i] = '\\';
+               else if (islower(name[i]))
+                       name[i] = toupper(name[i]);
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+/*                                                                                                                                                     */
+/* Generic stamp format:                                                                                                       */
+/*                                                                                                                                                     */
+/* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16                                                     */
+/* |<-------- year ------->|<- month ->|<-- day -->|                                           */
+/*                                                                                                                                                     */
+/* 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0                                                     */
+/* |<--- hour --->|<---- minute --->|<- second*2 ->|                                           */
+/*                                                                                                                                                     */
+/* ------------------------------------------------------------------------ */
+
+/*
+ * NOTE : If you don't have `gettimeofday(2)', or your gettimeofday(2)
+ * returns bogus timezone information, try FTIME, MKTIME, TIMELOCAL or TZSET.
+ */
+
+/* choose one */
+#if defined(MKTIME)
+#ifdef TIMELOCAL
+#undef TIMELOCAL
+#endif
+#endif                         /* defined(MKTIME) */
+
+#if defined(MKTIME) || defined(TIMELOCAL)
+#ifdef TZSET
+#undef TZSET
+#endif
+#endif                         /* defined(MKTIME) || defined(TIMELOCAL) */
+
+#if defined(MKTIME) || defined(TIMELOCAL) || defined(TZSET)
+#ifdef FTIME
+#undef FTIME
+#endif
+#endif
+
+#if defined(MKTIME) || defined(TIMELOCAL) || defined(TZSET) || defined(FTIME)
+#ifdef GETTIMEOFDAY
+#undef GETTIMEOFDAY
+#endif
+#else
+#ifndef GETTIMEOFDAY
+#define GETTIMEOFDAY           /* use gettimeofday() */
+#endif
+#endif
+
+#ifdef FTIME
+#include <sys/timeb.h>
+#endif
+
+/*
+ * You may define as : #define TIMEZONE_HOOK           \ extern long
+ * timezone ;  \ extern void tzset();
+ */
+#ifdef TIMEZONE_HOOK
+TIMEZONE_HOOK
+/* Which do you like better, `TIMEZONE_HOOK' or `TIMEZONE_HOOK;' ? */
+#endif
+
+#if defined(TZSET) && defined(_MINIX)
+extern long     timezone;              /* not defined in time.h */
+#endif
+
+/* ------------------------------------------------------------------------ */
+#if defined(FTIME) || defined(GETTIMEOFDAY) || defined(TZSET)
+static long
+gettz()
+#ifdef TZSET
+{
+       tzset();
+       return timezone;
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+#if !defined(TZSET) && defined(FTIME)
+{
+       struct timeb    buf;
+
+       ftime(&buf);
+       return buf.timezone * 60L;
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+#if !defined(TZSET) && !defined(FTIME) /* maybe defined(GETTIMEOFDAY) */
+{
+#ifdef HAVE_TM_ZONE
+       time_t tt;
+
+       time(&tt);
+       return -localtime(&tt)->tm_gmtoff;
+#else /* HAVE_TM_ZONE */
+       struct timeval  tp;
+       struct timezone tzp;
+       gettimeofday(&tp, &tzp);/* specific to 4.3BSD */
+       /*
+        * return (tzp.tz_minuteswest * 60L + (tzp.tz_dsttime != 0 ? 60L *
+        * 60L : 0));
+        */
+       return (tzp.tz_minuteswest * 60L);
+#endif /* HAVE_TM_ZONE */
+}
+#endif
+#endif                         /* defined(FTIME) || defined(GETTIMEOFDAY) ||
+                                * defined(TZSET) */
+
+/* ------------------------------------------------------------------------ */
+#ifdef NOT_USED
+static struct tm *
+msdos_to_unix_stamp_tm(a)
+       long            a;
+{
+       static struct tm t;
+
+       t.tm_sec = (a & 0x1f) * 2;
+       t.tm_min = (a >> 5) & 0x3f;
+       t.tm_hour = (a >> 11) & 0x1f;
+       t.tm_mday = (a >> 16) & 0x1f;
+       t.tm_mon = ((a >> 16 + 5) & 0x0f) - 1;
+       t.tm_year = ((a >> 16 + 9) & 0x7f) + 80;
+       return &t;
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+static          time_t
+generic_to_unix_stamp(t)
+       long            t;
+#if defined(MKTIME) || defined(TIMELOCAL)
+{
+       struct tm       dostm;
+
+       /*
+        * special case:  if MSDOS format date and time were zero, then we
+        * set time to be zero here too.
+        */
+       if (t == 0)
+               return (time_t) 0;
+
+       dostm.tm_sec = (t & 0x1f) * 2;
+       dostm.tm_min = t >> 5 & 0x3f;
+       dostm.tm_hour = t >> 11 & 0x1f;
+       dostm.tm_mday = t >> 16 & 0x1f;
+       dostm.tm_mon = (t >> 16 + 5 & 0x0f) - 1;        /* 0..11 */
+       dostm.tm_year = (t >> 16 + 9 & 0x7f) + 80;
+#if 0
+       dostm.tm_isdst = 0;     /* correct? */
+#endif
+       dostm.tm_isdst = -1;    /* correct? */
+#ifdef MKTIME
+       return (time_t) mktime(&dostm);
+#else                          /* maybe defined(TIMELOCAL) */
+       return (time_t) timelocal(&dostm);
+#endif
+}
+
+#else                          /* defined(MKTIME) || defined(TIMELOCAL) */
+{
+       int             year, month, day, hour, min, sec;
+       long            longtime;
+       static unsigned int dsboy[12] = {0, 31, 59, 90, 120, 151,
+       181, 212, 243, 273, 304, 334};
+       unsigned int    days;
+
+       /*
+        * special case:  if MSDOS format date and time were zero, then we
+        * set time to be zero here too.
+        */
+       if (t == 0)
+               return (time_t) 0;
+
+       year = ((int) (t >> 16 + 9) & 0x7f) + 1980;
+       month = (int) (t >> 16 + 5) & 0x0f;     /* 1..12 means Jan..Dec */
+       day = (int) (t >> 16) & 0x1f;   /* 1..31 means 1st,...31st */
+
+       hour = ((int) t >> 11) & 0x1f;
+       min = ((int) t >> 5) & 0x3f;
+       sec = ((int) t & 0x1f) * 2;
+
+       /* Calculate days since 1970.01.01 */
+       days = (365 * (year - 1970) +   /* days due to whole years */
+               (year - 1970 + 1) / 4 + /* days due to leap years */
+               dsboy[month - 1] +      /* days since beginning of this year */
+               day - 1);       /* days since beginning of month */
+
+       if ((year % 4 == 0) &&
+               (year % 100 != 0 || year % 400 == 0) &&         /* 1999.5.24 t.oka */
+           (month >= 3))       /* if this is a leap year and month */
+               days++;         /* is March or later, add a day */
+
+       /* Knowing the days, we can find seconds */
+       longtime = (((days * 24) + hour) * 60 + min) * 60 + sec;
+       longtime += gettz();    /* adjust for timezone */
+
+       /* LONGTIME is now the time in seconds, since 1970/01/01 00:00:00.  */
+       return (time_t) longtime;
+}
+#endif                         /* defined(MKTIME) || defined(TIMELOCAL) */
+
+/* ------------------------------------------------------------------------ */
+static long
+unix_to_generic_stamp(t)
+       time_t          t;
+{
+       struct tm      *tm = localtime(&t);
+
+       return ((((long) (tm->tm_year - 80)) << 25) +
+               (((long) (tm->tm_mon + 1)) << 21) +
+               (((long) tm->tm_mday) << 16) +
+               (long) ((tm->tm_hour << 11) +
+                       (tm->tm_min << 5) +
+                       (tm->tm_sec / 2)));
+}
+
+/* ------------------------------------------------------------------------ */
+/* build header functions                                                                                                      */
+/* ------------------------------------------------------------------------ */
+boolean
+get_header(fp, hdr)
+       struct zfile   *fp;
+       register LzHeader *hdr;
+{
+       int             header_size;
+       int             name_length;
+       char            data[LZHEADER_STRAGE];
+       char            dirname[FILENAME_LENGTH];
+       int             dir_length = 0;
+       int             checksum;
+       int             i;
+       char           *ptr;
+       int                             extend_size;
+       int                             dmy;
+
+       bzero(hdr, sizeof(LzHeader));
+
+       if (((header_size = zfile_getc(fp)) == EOF) || (header_size == 0)) {
+               return FALSE;   /* finish */
+       }
+
+       if (zfile_fread(data + I_HEADER_CHECKSUM,
+                 sizeof(char), header_size - 1, fp) < header_size - 1) {
+               fatal_error("Invalid header (LHarc file ?)");
+               return FALSE;   /* finish */
+       }
+       setup_get(data + I_HEADER_LEVEL);
+       hdr->header_level = get_byte();
+       if (hdr->header_level != 2 &&
+           zfile_fread(data + header_size, sizeof(char), 2, fp) < 2) {
+               fatal_error("Invalid header (LHarc file ?)");
+               return FALSE;   /* finish */
+       }
+
+       if (hdr->header_level >= 3) {
+               fatal_error("Unknown level header");
+               return FALSE;
+       }
+
+       setup_get(data + I_HEADER_CHECKSUM);
+       checksum = get_byte();
+
+       if (hdr->header_level == 2) {
+               hdr->header_size = header_size + checksum*256;
+       } else {
+               hdr->header_size = header_size;
+       }
+       bcopy(data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE);
+       setup_get(data + I_PACKED_SIZE);
+       hdr->packed_size = get_longword();
+       hdr->original_size = get_longword();
+       hdr->last_modified_stamp = get_longword();
+       hdr->attribute = get_byte();
+
+       if ((hdr->header_level = get_byte()) != 2) {
+               if (calc_sum(data + I_METHOD, header_size) != checksum)
+                       warning("Checksum error (LHarc file?)", "");
+               name_length = get_byte();
+               for (i = 0; i < name_length; i++)
+                       hdr->name[i] = (char) get_byte();
+               hdr->name[name_length] = '\0';
+       }
+       else {
+               hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
+               name_length = 0;
+       }
+
+       /* defaults for other type */
+       hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
+       hdr->unix_gid = 0;
+       hdr->unix_uid = 0;
+
+       if (hdr->header_level == 0) {
+               extend_size = header_size - name_length -22;
+               if (extend_size < 0) {
+                       if (extend_size == -2) {
+                               hdr->extend_type = EXTEND_GENERIC;
+                               hdr->has_crc = FALSE;
+                       } else {
+                               fatal_error("Unkonwn header (lha file?)");
+                               return FALSE;
+                       }
+               } else {
+                       hdr->has_crc = TRUE;
+                       hdr->crc = get_word();
+               }
+
+               if (extend_size >= 1) {
+                       hdr->extend_type = get_byte();
+                       extend_size--;
+               }
+               if (hdr->extend_type == EXTEND_UNIX || hdr->extend_type == EXTEND_AMIGAOS) {
+                       if (extend_size >= 11) {
+                               hdr->minor_version = get_byte();
+                               hdr->unix_last_modified_stamp = (time_t) get_longword();
+                               hdr->unix_mode = get_word();
+                               hdr->unix_uid = get_word();
+                               hdr->unix_gid = get_word();
+                               extend_size -= 11;
+                       } else {
+                               hdr->extend_type = EXTEND_GENERIC;
+                       }
+               }
+               while (extend_size-- > 0)
+                       dmy = get_byte();
+               if (hdr->extend_type == EXTEND_UNIX)
+                       return TRUE;
+       } else if (hdr->header_level == 1) {
+               hdr->has_crc = TRUE;
+               extend_size = header_size - name_length-25;
+               hdr->crc = get_word();
+               hdr->extend_type = get_byte();
+               while (extend_size-- > 0)
+                       dmy = get_byte();
+       } else { /* level 2 */
+               hdr->has_crc = TRUE;
+               hdr->crc = get_word();
+               hdr->extend_type = get_byte();
+       }               
+
+       if (hdr->header_level > 0) {
+               /* Extend Header */
+               if (hdr->header_level != 2)
+                       setup_get(data + hdr->header_size);
+               ptr = get_ptr;
+               while ((header_size = get_word()) != 0) {
+                       if (hdr->header_level != 2 &&
+                       ((data + LZHEADER_STRAGE - get_ptr < header_size) ||
+                        zfile_fread(get_ptr, sizeof(char), header_size, fp) < header_size)) {
+                               fatal_error("Invalid header (LHa file ?)");
+                               return FALSE;
+                       }
+                       switch (get_byte()) {
+                       case 0:
+                               /*
+                                * header crc
+                                */
+                               setup_get(get_ptr + header_size - 3);
+                               break;
+                       case 1:
+                               /*
+                                * filename
+                                */
+                               if (header_size >= 256)
+                                   return FALSE;
+                               for (i = 0; i < header_size - 3; i++)
+                                       hdr->name[i] = (char) get_byte();
+                               hdr->name[header_size - 3] = '\0';
+                               name_length = header_size - 3;
+                               break;
+                       case 2:
+                               /*
+                                * directory
+                                */
+                               if (header_size >= FILENAME_LENGTH)
+                                   return FALSE;
+                               for (i = 0; i < header_size - 3; i++)
+                                       dirname[i] = (char) get_byte();
+                               dirname[header_size - 3] = '\0';
+                               convdelim(dirname, DELIM);
+                               dir_length = header_size - 3;
+                               break;
+                       case 0x40:
+                               /*
+                                * MS-DOS attribute
+                                */
+                               if (hdr->extend_type == EXTEND_MSDOS ||
+                                   hdr->extend_type == EXTEND_HUMAN ||
+                                   hdr->extend_type == EXTEND_AMIGAOS ||
+                                   hdr->extend_type == EXTEND_GENERIC)
+                                       hdr->attribute = get_word();
+                               break;
+                       case 0x50:
+                               /*
+                                * UNIX permission
+                                */
+                               if (hdr->extend_type == EXTEND_UNIX)
+                                       hdr->unix_mode = get_word();
+                               break;
+                       case 0x51:
+                               /*
+                                * UNIX gid and uid
+                                */
+                               if (hdr->extend_type == EXTEND_UNIX) {
+                                       hdr->unix_gid = get_word();
+                                       hdr->unix_uid = get_word();
+                               }
+                               break;
+                       case 0x52:
+                               /*
+                                * UNIX group name
+                                */
+                               setup_get(get_ptr + header_size - 3);
+                               break;
+                       case 0x53:
+                               /*
+                                * UNIX user name
+                                */
+                               setup_get(get_ptr + header_size - 3);
+                               break;
+                       case 0x54:
+                               /*
+                                * UNIX last modified time
+                                */
+                               if (hdr->extend_type == EXTEND_UNIX || hdr->extend_type == EXTEND_AMIGAOS)
+                                       hdr->unix_last_modified_stamp = (time_t) get_longword();
+                               break;
+                       default:
+                               /*
+                                * other headers
+                                */
+                               setup_get(get_ptr + header_size - 3);
+                               break;
+                       }
+               }
+               if (hdr->header_level != 2 && get_ptr - ptr != 2) {
+                       hdr->packed_size -= get_ptr - ptr - 2;
+                       hdr->header_size += get_ptr - ptr - 2;
+               }
+       }
+
+       switch (hdr->extend_type) {
+       case EXTEND_MSDOS:
+               msdos_to_unix_filename(hdr->name, name_length);
+               msdos_to_unix_filename(dirname, dir_length);
+       case EXTEND_HUMAN:
+               if (hdr->header_level == 2)
+                       hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
+               else
+                       hdr->unix_last_modified_stamp =
+                               generic_to_unix_stamp(hdr->last_modified_stamp);
+               break;
+
+#ifdef OSK
+       case EXTEND_OS68K:
+       case EXTEND_XOSK:
+#endif
+       case EXTEND_AMIGAOS:
+       case EXTEND_UNIX:
+               break;
+
+       case EXTEND_MACOS:
+               macos_to_unix_filename(hdr->name, name_length);
+               /* macos_to_unix_filename(dirname, dir_length); */
+               hdr->unix_last_modified_stamp =
+                       generic_to_unix_stamp(hdr->last_modified_stamp);
+               break;
+
+       default:
+               generic_to_unix_filename(hdr->name, name_length);
+               generic_to_unix_filename(dirname, dir_length);
+               if (hdr->header_level == 2)
+                       hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
+               else
+                       hdr->unix_last_modified_stamp =
+                               generic_to_unix_stamp(hdr->last_modified_stamp);
+       }
+
+       if (dir_length) {
+               strcat(dirname, hdr->name);
+               strcpy(hdr->name, dirname);
+               name_length += dir_length;
+       }
+
+       return TRUE;
+}
+
+/* ------------------------------------------------------------------------ */
+void
+init_header(name, v_stat, hdr)
+       char           *name;
+       struct stat    *v_stat;
+       LzHeader       *hdr;
+{
+       int             len;
+
+       if (compress_method == LZHUFF5_METHOD_NUM)  /* Changed N.Watazaki */
+               bcopy(LZHUFF5_METHOD, hdr->method, METHOD_TYPE_STRAGE);
+       else if (compress_method)
+               bcopy(LZHUFF1_METHOD, hdr->method, METHOD_TYPE_STRAGE);
+       else
+               bcopy(LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE);
+
+       hdr->packed_size = 0;
+       hdr->original_size = v_stat->st_size;
+       hdr->last_modified_stamp = unix_to_generic_stamp(v_stat->st_mtime);
+       hdr->attribute = GENERIC_ATTRIBUTE;
+       hdr->header_level = header_level;
+       strcpy(hdr->name, name);
+       len = strlen(name);
+       hdr->crc = 0x0000;
+       hdr->extend_type = EXTEND_UNIX;
+       hdr->unix_last_modified_stamp = v_stat->st_mtime;
+       /* since 00:00:00 JAN.1.1970 */
+#ifdef NOT_COMPATIBLE_MODE
+       /* Please need your modification in this space. */
+#else
+       hdr->unix_mode = v_stat->st_mode;
+#endif
+
+       hdr->unix_uid = v_stat->st_uid;
+       hdr->unix_gid = v_stat->st_gid;
+
+       if (is_directory(v_stat)) {
+               bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
+               hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
+               hdr->original_size = 0;
+               if (len > 0 && hdr->name[len - 1] != '/')
+                       strcpy(&hdr->name[len++], "/");
+       }
+
+#ifdef S_IFLNK 
+       if (is_symlink(v_stat)) {
+               char    lkname[257];
+               int             len;    
+               bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
+               hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
+               hdr->original_size = 0;
+               len = readlink(name, lkname, 256);
+               lkname[len] = (char)'\0';
+               sprintf(hdr->name, "%s|%s", hdr->name, lkname);
+       }
+#endif
+       if (generic_format)
+               unix_to_generic_filename(hdr->name, len);
+}
diff --git a/archivers/lha/huf.c b/archivers/lha/huf.c
new file mode 100755 (executable)
index 0000000..aee9284
--- /dev/null
@@ -0,0 +1,495 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                                                                                        */
+/*                             huf.c -- new static Huffman                                                                     */
+/*                                                                                                                                                     */
+/*             Modified                        Nobutaka Watazaki                                                       */
+/*                                                                                                                                                     */
+/*     Ver. 1.14       Source All chagned                              1995.01.14      N.Watazaki              */
+/*     Ver. 1.14i      Support LH7 & Bug Fixed                 2000.10. 6      t.okamoto               */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+#ifdef sony_news
+#include <sys/param.h>
+#endif
+
+#if defined(__STDC__) || defined(NEWSOS)
+#include <stdlib.h>
+#endif
+
+/* ------------------------------------------------------------------------ */
+unsigned short  left[2 * NC - 1], right[2 * NC - 1];
+unsigned char   c_len[NC], pt_len[NPT];
+unsigned short  c_freq[2 * NC - 1], c_table[4096], c_code[NC], p_freq[2 * NP - 1],
+                pt_table[256], pt_code[NPT], t_freq[2 * NT - 1];
+
+static unsigned char *buf;
+static unsigned int bufsiz;
+static unsigned short blocksize;
+static unsigned short output_pos, output_mask;
+static                         int       pbit;
+static                         int       np;
+/* ------------------------------------------------------------------------ */
+/*                                                             Encording                                                                       */
+/* ------------------------------------------------------------------------ */
+static void
+count_t_freq(/*void*/)
+{
+       short           i, k, n, count;
+
+       for (i = 0; i < NT; i++)
+               t_freq[i] = 0;
+       n = NC;
+       while (n > 0 && c_len[n - 1] == 0)
+               n--;
+       i = 0;
+       while (i < n) {
+               k = c_len[i++];
+               if (k == 0) {
+                       count = 1;
+                       while (i < n && c_len[i] == 0) {
+                               i++;
+                               count++;
+                       }
+                       if (count <= 2)
+                               t_freq[0] += count;
+                       else if (count <= 18)
+                               t_freq[1]++;
+                       else if (count == 19) {
+                               t_freq[0]++;
+                               t_freq[1]++;
+                       }
+                       else
+                               t_freq[2]++;
+               } else
+                       t_freq[k + 2]++;
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+#if 0
+static void
+write_pt_len(n, nbit, i_special)
+       short           n;
+       short           nbit;
+       short           i_special;
+{
+       short           i, k;
+
+       while (n > 0 && pt_len[n - 1] == 0)
+               n--;
+       putbits(nbit, n);
+       i = 0;
+       while (i < n) {
+               k = pt_len[i++];
+               if (k <= 6)
+                       putbits(3, k);
+               else
+                       putbits(k - 3, USHRT_MAX << 1);
+               if (i == i_special) {
+                       while (i < 6 && pt_len[i] == 0)
+                               i++;
+                       putbits(2, i - 3);
+               }
+       }
+}
+/* ------------------------------------------------------------------------ */
+static void
+write_c_len(/*void*/)
+{
+       short           i, k, n, count;
+
+       n = NC;
+       while (n > 0 && c_len[n - 1] == 0)
+               n--;
+       putbits(CBIT, n);
+       i = 0;
+       while (i < n) {
+               k = c_len[i++];
+               if (k == 0) {
+                       count = 1;
+                       while (i < n && c_len[i] == 0) {
+                               i++;
+                               count++;
+                       }
+                       if (count <= 2) {
+                               for (k = 0; k < count; k++)
+                                       putcode(pt_len[0], pt_code[0]);
+                       }
+                       else if (count <= 18) {
+                               putcode(pt_len[1], pt_code[1]);
+                               putbits(4, count - 3);
+                       }
+                       else if (count == 19) {
+                               putcode(pt_len[0], pt_code[0]);
+                               putcode(pt_len[1], pt_code[1]);
+                               putbits(4, 15);
+                       }
+                       else {
+                               putcode(pt_len[2], pt_code[2]);
+                               putbits(CBIT, count - 20);
+                       }
+               }
+               else
+                       putcode(pt_len[k + 2], pt_code[k + 2]);
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+encode_c(c)
+       short           c;
+{
+       putcode(c_len[c], c_code[c]);
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+encode_p(p)
+       unsigned short  p;
+{
+       unsigned short  c, q;
+
+       c = 0;
+       q = p;
+       while (q) {
+               q >>= 1;
+               c++;
+       }
+       putcode(pt_len[c], pt_code[c]);
+       if (c > 1)
+               putbits(c - 1, p);
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+send_block( /* void */ )
+{
+       unsigned char   flags;
+       unsigned short  i, k, root, pos, size;
+
+       root = make_tree(NC, c_freq, c_len, c_code);
+       size = c_freq[root];
+       putbits(16, size);
+       if (root >= NC) {
+               count_t_freq();
+               root = make_tree(NT, t_freq, pt_len, pt_code);
+               if (root >= NT) {
+                       write_pt_len(NT, TBIT, 3);
+               } else {
+                       putbits(TBIT, 0);
+                       putbits(TBIT, root);
+               }
+               write_c_len();
+       } else {
+               putbits(TBIT, 0);
+               putbits(TBIT, 0);
+               putbits(CBIT, 0);
+               putbits(CBIT, root);
+       }
+       root = make_tree(np, p_freq, pt_len, pt_code);
+       if (root >= np) {
+               write_pt_len(np, pbit, -1);
+       }
+       else {
+               putbits(pbit, 0);
+               putbits(pbit, root);
+       }
+       pos = 0;
+       for (i = 0; i < size; i++) {
+               if (i % CHAR_BIT == 0)
+                       flags = buf[pos++];
+               else
+                       flags <<= 1;
+               if (flags & (1 << (CHAR_BIT - 1))) {
+                       encode_c(buf[pos++] + (1 << CHAR_BIT));
+                       k = buf[pos++] << CHAR_BIT;
+                       k += buf[pos++];
+                       encode_p(k);
+               } else
+                       encode_c(buf[pos++]);
+               if (unpackable)
+                       return;
+       }
+       for (i = 0; i < NC; i++)
+               c_freq[i] = 0;
+       for (i = 0; i < np; i++)
+               p_freq[i] = 0;
+}
+/* ------------------------------------------------------------------------ */
+void
+output_st1(c, p)
+       unsigned short  c;
+       unsigned short  p;
+{
+       static unsigned short cpos;
+
+       output_mask >>= 1;
+       if (output_mask == 0) {
+               output_mask = 1 << (CHAR_BIT - 1);
+               if (output_pos >= bufsiz - 3 * CHAR_BIT) {
+                       send_block();
+                       if (unpackable)
+                               return;
+                       output_pos = 0;
+               }
+               cpos = output_pos++;
+               buf[cpos] = 0;
+       }
+       buf[output_pos++] = (unsigned char) c;
+       c_freq[c]++;
+       if (c >= (1 << CHAR_BIT)) {
+               buf[cpos] |= output_mask;
+               buf[output_pos++] = (unsigned char) (p >> CHAR_BIT);
+               buf[output_pos++] = (unsigned char) p;
+               c = 0;
+               while (p) {
+                       p >>= 1;
+                       c++;
+               }
+               p_freq[c]++;
+       }
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+unsigned char  *
+alloc_buf( /* void */ )
+{
+       bufsiz = 16 * 1024 *2;  /* 65408U; */ /* t.okamoto */
+       while ((buf = (unsigned char *) malloc(bufsiz)) == NULL) {
+               bufsiz = (bufsiz / 10) * 9;
+               if (bufsiz < 4 * 1024)
+                       break;
+       }
+       return buf;
+}
+
+/* ------------------------------------------------------------------------ */
+#if 0
+void
+encode_start_st1( /* void */ )
+{
+       int             i;
+
+#if 0
+       if (dicbit <= (MAX_DICBIT - 2)) {
+               pbit = 4;       /* lh4,5 etc. */
+               np = 14;
+       } else {
+               pbit = 5;       /* lh6 */
+               np = 16;
+       }
+#endif
+
+       if (dicbit <= 13) {
+               pbit = 4;       /* lh4,5 etc. */
+               np = 14;
+       } else {
+               pbit = 5;       /* lh6,7 */
+               if (dicbit == 16)
+                       np = 17;
+               else
+                       np = 16;
+       }
+
+       for (i = 0; i < NC; i++)
+               c_freq[i] = 0;
+       for (i = 0; i < np; i++)
+               p_freq[i] = 0;
+       output_pos = output_mask = 0;
+       init_putbits();
+       buf[0] = 0;
+}
+
+/* ------------------------------------------------------------------------ */
+void
+encode_end_st1( /* void */ )
+{
+       if (!unpackable) {
+               send_block();
+               putbits(CHAR_BIT - 1, 0);       /* flush remaining bits */
+       }
+}
+#endif
+/* ------------------------------------------------------------------------ */
+/*                                                             decoding                                                                        */
+/* ------------------------------------------------------------------------ */
+static void
+read_pt_len(nn, nbit, i_special)
+       short           nn;
+       short           nbit;
+       short           i_special;
+{
+       int           i, c, n;
+
+       n = getbits(nbit);
+       if (n == 0) {
+               c = getbits(nbit);
+               for (i = 0; i < nn; i++)
+                       pt_len[i] = 0;
+               for (i = 0; i < 256; i++)
+                       pt_table[i] = c;
+       }
+       else {
+               i = 0;
+               while (i < n) {
+                       c = lhabitbuf >> (16 - 3);
+                       if (c == 7) {
+                               unsigned short  mask = 1 << (16 - 4);
+                               while (mask & lhabitbuf) {
+                                       mask >>= 1;
+                                       c++;
+                               }
+                       }
+                       fillbuf((c < 7) ? 3 : c - 3);
+                       pt_len[i++] = c;
+                       if (i == i_special) {
+                               c = getbits(2);
+                               while (--c >= 0)
+                                       pt_len[i++] = 0;
+                       }
+               }
+               while (i < nn)
+                       pt_len[i++] = 0;
+               make_table(nn, pt_len, 8, pt_table);
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+read_c_len( /* void */ )
+{
+       short           i, c, n;
+
+       n = getbits(CBIT);
+       if (n == 0) {
+               c = getbits(CBIT);
+               for (i = 0; i < NC; i++)
+                       c_len[i] = 0;
+               for (i = 0; i < 4096; i++)
+                       c_table[i] = c;
+       } else {
+               i = 0;
+               while (i < n) {
+                       c = pt_table[lhabitbuf >> (16 - 8)];
+                       if (c >= NT) {
+                               unsigned short  mask = 1 << (16 - 9);
+                               do {
+                                       if (lhabitbuf & mask)
+                                               c = right[c];
+                                       else
+                                               c = left[c];
+                                       mask >>= 1;
+                               } while (c >= NT);
+                       }
+                       fillbuf(pt_len[c]);
+                       if (c <= 2) {
+                               if (c == 0)
+                                       c = 1;
+                               else if (c == 1)
+                                       c = getbits(4) + 3;
+                               else
+                                       c = getbits(CBIT) + 20;
+                               while (--c >= 0)
+                                       c_len[i++] = 0;
+                       }
+                       else
+                               c_len[i++] = c - 2;
+               }
+               while (i < NC)
+                       c_len[i++] = 0;
+               make_table(NC, c_len, 12, c_table);
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+unsigned short
+decode_c_st1( /*void*/ )
+{
+       unsigned short  j, mask;
+
+       if (blocksize == 0) {
+               blocksize = getbits(16);
+               read_pt_len(NT, TBIT, 3);
+               read_c_len();
+               read_pt_len(np, pbit, -1);
+       }
+       blocksize--;
+       j = c_table[lhabitbuf >> 4];
+       if (j < NC)
+               fillbuf(c_len[j]);
+       else {
+               fillbuf(12);
+               mask = 1 << (16 - 1);
+               do {
+                       if (lhabitbuf & mask)
+                               j = right[j];
+                       else
+                               j = left[j];
+                       mask >>= 1;
+               } while (j >= NC);
+               fillbuf(c_len[j] - 12);
+       }
+       return j;
+}
+
+/* ------------------------------------------------------------------------ */
+unsigned short
+decode_p_st1( /* void */ )
+{
+       unsigned short  j, mask;
+
+       j = pt_table[lhabitbuf >> (16 - 8)];
+       if (j < np)
+               fillbuf(pt_len[j]);
+       else {
+               fillbuf(8);
+               mask = 1 << (16 - 1);
+               do {
+                       if (lhabitbuf & mask)
+                               j = right[j];
+                       else
+                               j = left[j];
+                       mask >>= 1;
+               } while (j >= np);
+               fillbuf(pt_len[j] - 8);
+       }
+       if (j != 0)
+               j = (1 << (j - 1)) + getbits(j - 1);
+       return j;
+}
+
+/* ------------------------------------------------------------------------ */
+void
+decode_start_st1( /* void */ )
+{
+       if (dicbit <= 13)  {
+               np = 14;
+               pbit = 4;
+       } else {
+               if (dicbit == 16) {
+                       np = 17; /* for -lh7- */
+               } else {
+                       np = 16;
+               }
+               pbit = 5;
+       }
+
+#if 0
+       if (dicbit <= 13)  {            /* 13 ... Changed N.Watazaki */
+               np = 14;
+               pbit = 4;
+       } else {
+               np = 16;
+               pbit = 5;
+       }
+#endif
+       init_getbits();
+       blocksize = 0;
+}
+
+/* Local Variables: */
+/* mode:c */
+/* tab-width:4 */
+/* End: */
diff --git a/archivers/lha/larc.c b/archivers/lha/larc.c
new file mode 100755 (executable)
index 0000000..a6a2642
--- /dev/null
@@ -0,0 +1,85 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                                                                                        */
+/*                             larc.c -- extra *.lzs                                                                           */
+/*                                                                                                                                                     */
+/*             Modified                        Nobutaka Watazaki                                                       */
+/*                                                                                                                                                     */
+/*     Ver. 1.14       Source All chagned                              1995.01.14      N.Watazaki              */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+/* ------------------------------------------------------------------------ */
+static int      flag, flagcnt, matchpos;
+/* ------------------------------------------------------------------------ */
+unsigned short
+decode_c_lzs( /*void*/ )
+{
+       if (getbits(1)) {
+               return getbits(8);
+       }
+       else {
+               matchpos = getbits(11);
+               return getbits(4) + 0x100;
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+unsigned short
+decode_p_lzs( /*void*/ )
+{
+       return (loc - matchpos - MAGIC0) & 0x7ff;
+}
+
+/* ------------------------------------------------------------------------ */
+void
+decode_start_lzs( /*void*/ )
+{
+       init_getbits();
+}
+
+/* ------------------------------------------------------------------------ */
+unsigned short
+decode_c_lz5( /*void*/ )
+{
+       int             c;
+
+       if (flagcnt == 0) {
+               flagcnt = 8;
+               flag = zfile_getc(infile);
+       }
+       flagcnt--;
+       c = zfile_getc(infile);
+       if ((flag & 1) == 0) {
+               matchpos = c;
+               c = zfile_getc(infile);
+               matchpos += (c & 0xf0) << 4;
+               c &= 0x0f;
+               c += 0x100;
+       }
+       flag >>= 1;
+       return c;
+}
+
+/* ------------------------------------------------------------------------ */
+unsigned short
+decode_p_lz5( /*void*/ )
+{
+       return (loc - matchpos - MAGIC5) & 0xfff;
+}
+
+/* ------------------------------------------------------------------------ */
+void
+decode_start_lz5( /*void*/ )
+{
+       int             i;
+
+       flagcnt = 0;
+       for (i = 0; i < 256; i++)
+               memset(&text[i * 13 + 18], i, 13);
+       for (i = 0; i < 256; i++)
+               text[256 * 13 + 18 + i] = i;
+       for (i = 0; i < 256; i++)
+               text[256 * 13 + 256 + 18 + i] = 255 - i;
+       memset(&text[256 * 13 + 512 + 18], 0, 128);
+       memset(&text[256 * 13 + 512 + 128 + 18], ' ', 128 - 18);
+}
diff --git a/archivers/lha/lha.h b/archivers/lha/lha.h
new file mode 100755 (executable)
index 0000000..baab0fd
--- /dev/null
@@ -0,0 +1,323 @@
+#include "sysconfig.h"
+#include "sysdeps.h"
+#include "zfile.h"
+
+#define SYSTIME_HAS_NO_TM
+#define NODIRECTORY
+#define FTIME
+#define NOBSTRING
+#define NOINDEX
+
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX    Archiver Driver                                                                                     */
+/*                                                                                                                                                     */
+/*             Modified                        Nobutaka Watazaki                                                       */
+/*                                                                                                                                                     */
+/*     Ver. 1.14       Soruce All chagned                              1995.01.14      N.Watazaki              */
+/*     Ver. 1.14i      Modified and bug fixed                  2000.10.06      t.okamoto       */
+/* ------------------------------------------------------------------------ */
+/*
+       Included...
+               lharc.h         interface.h             slidehuf.h
+*/
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <signal.h>
+
+#include "lha_macro.h"
+
+struct encode_option {
+#if 1 || defined(__STDC__) || defined(AIX)
+       void            (*output) ();
+       void            (*encode_start) ();
+       void            (*encode_end) ();
+#else
+       int             (*output) ();
+       int             (*encode_start) ();
+       int             (*encode_end) ();
+#endif
+};
+
+struct decode_option {
+       unsigned short  (*decode_c) ();
+       unsigned short  (*decode_p) ();
+#if 1 || defined(__STDC__) || defined(AIX)
+       void            (*decode_start) ();
+#else
+       int             (*decode_start) ();
+#endif
+};
+
+/* ------------------------------------------------------------------------ */
+/*     LHa File Type Definition                                                                                                */
+/* ------------------------------------------------------------------------ */
+struct string_pool {
+       int             used;
+       int             size;
+       int             n;
+       char           *buffer;
+};
+
+typedef struct LzHeader {
+       unsigned char   header_size;
+       char            method[METHOD_TYPE_STRAGE];
+       long            packed_size;
+       long            original_size;
+       long            last_modified_stamp;
+       unsigned char   attribute;
+       unsigned char   header_level;
+       char            name[256];
+       unsigned short  crc;
+       boolean         has_crc;
+       unsigned char   extend_type;
+       unsigned char   minor_version;
+
+       /* extend_type == EXTEND_UNIX  and convert from other type. */
+       time_t          unix_last_modified_stamp;
+       unsigned short  unix_mode;
+       unsigned short  unix_uid;
+       unsigned short  unix_gid;
+}  LzHeader;
+
+struct interfacing {
+       struct zfile            *infile;
+       struct zfile            *outfile;
+       unsigned long   original;
+       unsigned long   packed;
+       int             dicbit;
+       int             method;
+};
+
+
+/* ------------------------------------------------------------------------ */
+/*     Option switch variable                                                                                                  */
+/* ------------------------------------------------------------------------ */
+/* command line options (common options) */
+EXTERN boolean  quiet;
+EXTERN boolean  text_mode;
+EXTERN boolean  verbose;
+EXTERN boolean  noexec;                /* debugging option */
+EXTERN boolean  force;
+EXTERN boolean  prof;
+EXTERN boolean  delete_after_append;
+EXTERN int             compress_method;
+EXTERN int             header_level;
+/* EXTERN int          quiet_mode; */   /* 1996.8.13 t.okamoto */
+#ifdef EUC
+EXTERN boolean euc_mode;
+#endif
+
+/* list command flags */
+EXTERN boolean  verbose_listing;
+
+/* extract/print command flags */
+EXTERN boolean  output_to_stdout;
+
+/* add/update/delete command flags */
+EXTERN boolean  new_archive;
+EXTERN boolean  update_if_newer;
+EXTERN boolean  generic_format;
+
+EXTERN boolean remove_temporary_at_error;
+EXTERN boolean recover_archive_when_interrupt;
+EXTERN boolean remove_extracting_file_when_interrupt;
+EXTERN boolean get_filename_from_stdin;
+EXTERN boolean ignore_directory;
+EXTERN boolean verify_mode;
+
+/* Indicator flag */
+EXTERN int             quiet_mode;
+
+/* ------------------------------------------------------------------------ */
+/*     Globale Variable                                                                                                                */
+/* ------------------------------------------------------------------------ */
+EXTERN char            **cmd_filev;
+EXTERN int      cmd_filec;
+
+EXTERN char            *archive_name;
+EXTERN char     expanded_archive_name[FILENAME_LENGTH];
+EXTERN char     temporary_name[FILENAME_LENGTH];
+EXTERN char     backup_archive_name[FILENAME_LENGTH];
+
+EXTERN char            *reading_filename, *writting_filename;
+
+/* 1996.8.13 t.okamoto */
+#if 0
+EXTERN boolean  remove_temporary_at_error;
+EXTERN boolean  recover_archive_when_interrupt;
+EXTERN boolean  remove_extracting_file_when_interrupt;
+#endif
+
+EXTERN int      archive_file_mode;
+EXTERN int      archive_file_gid;
+
+EXTERN node            *next;
+/* EXTERN unsigned short crc; */  /* 1996.8.13 t.okamoto */
+
+EXTERN int      noconvertcase; /* 2000.10.6 */
+
+/* slide.c */
+EXTERN int      unpackable;
+EXTERN unsigned long origsize, compsize;
+EXTERN unsigned short dicbit;
+EXTERN unsigned short maxmatch;
+EXTERN unsigned long count;
+EXTERN unsigned long loc;                      /* short -> long .. Changed N.Watazaki */
+EXTERN unsigned char *text;
+EXTERN int             prev_char;
+
+/* huf.c */
+#ifndef LHA_MAIN_SRC  /* t.okamoto 96/2/20 */
+EXTERN unsigned short left[], right[];
+EXTERN unsigned char c_len[], pt_len[];
+EXTERN unsigned short c_freq[], c_table[], c_code[];
+EXTERN unsigned short p_freq[], pt_table[], pt_code[], t_freq[];
+#endif
+
+/* append.c */
+#ifdef NEED_INCREMENTAL_INDICATOR
+EXTERN long            indicator_count;
+EXTERN long            indicator_threshold;
+#endif
+
+/* crcio.c */
+EXTERN struct zfile    *infile, *outfile;
+EXTERN unsigned short crc, lhabitbuf;
+EXTERN int      dispflg;
+EXTERN long            reading_size;
+
+/* from dhuf.c */
+EXTERN unsigned int n_max;
+
+/* lhadd.c */
+EXTERN FILE            *temporary_fp;
+
+/* ------------------------------------------------------------------------ */
+/*     Functions                                                                                                                               */
+/* ------------------------------------------------------------------------ */
+/* from lharc.c */
+extern int             patmatch();
+
+extern void            interrupt();
+
+extern void            message();
+extern void            warning();
+extern void            error();
+extern void            fatal_error();
+
+extern boolean need_file();
+extern int             inquire();
+extern FILE            *xfopen();
+
+extern boolean find_files();
+extern void            free_files();
+
+extern void            init_sp();
+extern void            add_sp();
+extern void            finish_sp();
+extern void            free_sp();
+extern void            cleaning_files();
+
+extern void            build_temporary_name();
+extern void            build_backup_file_name();
+extern void            build_standard_archive_name();
+
+extern FILE            *open_old_archive();
+extern void            init_header();
+extern boolean get_header();
+extern boolean archive_is_msdos_sfx1();
+extern boolean skip_msdos_sfx1_code();
+extern void            write_header();
+extern void            write_archive_tail();
+extern void            copy_old_one();
+extern unsigned char *convdelim();
+extern long            copyfile();
+
+extern void            cmd_list(), cmd_extract(), cmd_add(), cmd_delete();
+
+extern char            *extract_directory;
+
+/* from slide.c */
+
+extern int             encode_alloc();
+extern void            encode();
+extern int             decode();
+
+/* from append.c */
+extern void     start_indicator();
+extern void     finish_indicator();
+extern void     finish_indicator2();
+
+/* slide.c */
+extern void     output_st1();
+extern unsigned char *alloc_buf();
+extern void     encode_start_st1();
+extern void     encode_end_st1();
+extern unsigned short decode_c_st1();
+extern unsigned short decode_p_st1();
+extern void     decode_start_st1();
+
+/* from shuf.c */
+extern void     decode_start_st0();
+extern void     encode_p_st0( /* unsigned short j */ );
+extern void     encode_start_fix();
+extern void     decode_start_fix();
+extern unsigned short decode_c_st0();
+extern unsigned short decode_p_st0();
+
+/* from dhuf.c */
+extern void     start_c_dyn();
+extern void     decode_start_dyn();
+extern unsigned short decode_c_dyn();
+extern unsigned short decode_p_dyn();
+extern void     output_dyn( /* int code, unsigned int pos */ );
+extern void     encode_end_dyn();
+
+extern int      decode_lzhuf();
+
+/* from larc.c */
+
+extern unsigned short decode_c_lzs();
+extern unsigned short decode_p_lzs();
+extern unsigned short decode_c_lz5();
+extern unsigned short decode_p_lz5();
+extern void                      decode_start_lzs();
+extern void                      decode_start_lz5();
+
+extern void    make_table(     /* int nchar, uchar bitlen[], int tablebits,
+                                                       ushort table[] */ );
+
+/* from maketree.c */
+/*
+ * void make_code(short n, uchar len[], ushort code[]); short make_tree(short
+ * nparm, ushort freqparm[], uchar lenparm[], ushort codeparam[]);
+ */
+extern void            make_code( /* int n, uchar len[], ushort code[] */ );
+extern short   make_tree( /* int nparm, ushort freqparm[], uchar lenparm[],
+                                                               ushort codeparam[] */ );
+
+/* from crcio.c */
+extern void                            make_crctable();
+extern unsigned short  calccrc( /* uchar *p, uint n */ );
+extern void                            fillbuf( /* uchar n */ );
+extern unsigned short  getbits( /* uchar n */ );
+extern void                            putcode( /* uchar n, ushort x */ );
+extern void                            putbits( /* uchar n, ushort x */ );
+extern int                             fread_crc( /* uchar *p, int n, FILE *f */ );
+extern void                            fwrite_crc( /* uchar *p, int n, FILE *f */ );
+extern void                            init_getbits();
+extern void                            init_putbits();
+extern void                    make_crctable();
+extern unsigned                short calccrc();
+
+/* from lhadd.c */
+extern int             encode_lzhuf();
+extern int      encode_stored_crc();
+
+#define warning write_log
+#define fatal_error write_log
+#define error write_log
diff --git a/archivers/lha/lha_macro.h b/archivers/lha/lha_macro.h
new file mode 100755 (executable)
index 0000000..a227a81
--- /dev/null
@@ -0,0 +1,357 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX    Archiver Driver     macro define                                                    */
+/*                                                                                                                                                     */
+/*             Modified                        Nobutaka Watazaki                                                       */
+/*                                                                                                                                                     */
+/*     Ver. 1.14       Soruce All chagned                              1995.01.14      N.Watazaki              */
+/*     Ver. 1.14g      modified                                                2000.05.06      T.OKAMOTO               */
+/* ------------------------------------------------------------------------ */
+
+/* external variables */
+extern int      errno;
+
+/* used by qsort() for alphabetic-sort */
+#define STRING_COMPARE(a,b)            strcmp((a),(b))
+
+#define FILENAME_LENGTH        1024
+
+/* ------------------------------------------------------------------------ */
+/* YOUR CUSTOMIZIES                                                                                                                    */
+/* ------------------------------------------------------------------------ */
+
+#ifndef ARCHIVENAME_EXTENTION
+#define ARCHIVENAME_EXTENTION  ".lzh"
+#endif
+#ifndef BACKUPNAME_EXTENTION
+#define BACKUPNAME_EXTENTION   ".bak"
+#endif
+#ifndef TMP_FILENAME_TEMPLATE
+#define TMP_FILENAME_TEMPLATE  "/tmp/lhXXXXXX"
+#endif
+
+#define SJC_FIRST_P(c)                 \
+  (((unsigned char)(c) >= 0x80) &&     \
+   (((unsigned char)(c) < 0xa0) ||     \
+    ((unsigned char)(c) >= 0xe0) &&    \
+    ((unsigned char)(c) < 0xfd)))
+#define SJC_SECOND_P(c)                        \
+  (((unsigned char)(c) >= 0x40) &&     \
+   ((unsigned char)(c) < 0xfd) &&      \
+   ((unsigned char)(c) != 0x7f))
+
+#ifdef MULTIBYTE_CHAR
+#define MULTIBYTE_FIRST_P      SJC_FIRST_P
+#define MULTIBYTE_SECOND_P     SJC_SECOND_P
+#endif                         /* MULTIBYTE_CHAR */
+
+/* ------------------------------------------------------------------------ */
+/*     LHa File Definitions                                                                                                    */
+/* ------------------------------------------------------------------------ */
+#ifdef S_IFLNK
+#define GETSTAT lstat
+#else
+#define GETSTAT stat
+#endif
+
+#ifdef LHA_MAIN_SRC
+#define EXTERN
+#else
+#define EXTERN                         extern
+#endif /* LHA_MAIN_SRC */
+
+#define LZHUFF0_METHOD                 "-lh0-"
+#define LZHUFF1_METHOD                 "-lh1-"
+#define LZHUFF2_METHOD                 "-lh2-"
+#define LZHUFF3_METHOD                 "-lh3-"
+#define LZHUFF4_METHOD                 "-lh4-"
+#define LZHUFF5_METHOD                 "-lh5-"
+#define LZHUFF6_METHOD                 "-lh6-"
+#define LZHUFF7_METHOD                 "-lh7-"
+#define LARC_METHOD                            "-lzs-"
+#define LARC5_METHOD                   "-lz5-"
+#define LARC4_METHOD                   "-lz4-"
+#define LZHDIRS_METHOD                 "-lhd-"
+
+#define METHOD_TYPE_STRAGE             5
+
+/* Added N.Watazaki ..V */
+#define LZHUFF0_METHOD_NUM             0
+#define LZHUFF1_METHOD_NUM             1
+#define LZHUFF2_METHOD_NUM             2
+#define LZHUFF3_METHOD_NUM             3
+#define LZHUFF4_METHOD_NUM             4
+#define LZHUFF5_METHOD_NUM             5
+#define LZHUFF6_METHOD_NUM             6
+#define LZHUFF7_METHOD_NUM             7
+#define LARC_METHOD_NUM                        8
+#define LARC5_METHOD_NUM               9
+#define LARC4_METHOD_NUM               10
+#define LZHDIRS_METHOD_NUM             11
+/* Added N.Watazaki ..^ */
+
+#define I_HEADER_SIZE                  0
+#define I_HEADER_CHECKSUM              1
+#define I_METHOD                               2
+#define I_PACKED_SIZE                  7
+#define I_ORIGINAL_SIZE                        11
+#define I_LAST_MODIFIED_STAMP  15
+#define I_ATTRIBUTE                            19
+#define I_HEADER_LEVEL                 20
+#define I_NAME_LENGTH                  21
+#define I_NAME                                 22
+
+#define I_CRC                                          22      /* + name_length */
+#define I_EXTEND_TYPE                          24      /* + name_length */
+#define I_MINOR_VERSION                                25      /* + name_length */
+#define I_UNIX_LAST_MODIFIED_STAMP     26      /* + name_length */
+#define I_UNIX_MODE                                    30      /* + name_length */
+#define I_UNIX_UID                                     32      /* + name_length */
+#define I_UNIX_GID                                     34      /* + name_length */
+#define I_UNIX_EXTEND_BOTTOM           36      /* + name_length */
+
+#define I_GENERIC_HEADER_BOTTOM                I_EXTEND_TYPE
+
+#define EXTEND_GENERIC                 0
+#define EXTEND_UNIX                            'U'
+#define EXTEND_MSDOS                   'M'
+#define EXTEND_MACOS                   'm'
+#define EXTEND_OS9                             '9'
+#define EXTEND_OS2                             '2'
+#define EXTEND_OS68K                   'K'
+#define EXTEND_OS386                   '3'     /* OS-9000??? */
+#define EXTEND_HUMAN                   'H'
+#define EXTEND_CPM                             'C'
+#define EXTEND_FLEX                            'F'
+#define EXTEND_RUNSER                  'R'
+#define EXTEND_AMIGAOS                 'A'
+
+/* this OS type is not official */
+
+#define EXTEND_TOWNSOS                 'T'
+#define EXTEND_XOSK                            'X'
+
+/*---------------------------------------------------------------------------*/
+
+#define GENERIC_ATTRIBUTE                              0x20
+#define GENERIC_DIRECTORY_ATTRIBUTE            0x10
+#define HEADER_LEVEL0                                  0x00
+#define HEADER_LEVEL1                                  0x01
+#define HEADER_LEVEL2                                  0x02
+
+#define CURRENT_UNIX_MINOR_VERSION             0x00
+
+#define DELIM          ('/')
+#define DELIM2         (0xff)
+#define DELIMSTR       "/"
+
+#define OSK_RW_RW_RW                   0000033
+#define OSK_FILE_REGULAR               0000000
+#define OSK_DIRECTORY_PERM             0000200
+#define OSK_SHARED_PERM                        0000100
+#define OSK_OTHER_EXEC_PERM            0000040
+#define OSK_OTHER_WRITE_PERM   0000020
+#define OSK_OTHER_READ_PERM            0000010
+#define OSK_OWNER_EXEC_PERM            0000004
+#define OSK_OWNER_WRITE_PERM   0000002
+#define OSK_OWNER_READ_PERM            0000001
+
+#define UNIX_FILE_TYPEMASK             0170000
+#define UNIX_FILE_REGULAR              0100000
+#define UNIX_FILE_DIRECTORY            0040000
+#define UNIX_FILE_SYMLINK              0120000
+#define UNIX_SETUID                            0004000
+#define UNIX_SETGID                            0002000
+#define UNIX_STYCKYBIT                 0001000
+#define UNIX_OWNER_READ_PERM   0000400
+#define UNIX_OWNER_WRITE_PERM  0000200
+#define UNIX_OWNER_EXEC_PERM   0000100
+#define UNIX_GROUP_READ_PERM   0000040
+#define UNIX_GROUP_WRITE_PERM  0000020
+#define UNIX_GROUP_EXEC_PERM   0000010
+#define UNIX_OTHER_READ_PERM   0000004
+#define UNIX_OTHER_WRITE_PERM  0000002
+#define UNIX_OTHER_EXEC_PERM   0000001
+#define UNIX_RW_RW_RW                  0000666
+
+#define LZHEADER_STRAGE                        4096
+
+#define MAX_INDICATOR_COUNT            64
+
+typedef short                                  node;
+
+/* ------------------------------------------------------------------------ */
+/*     Slide relation                                                                                                                  */
+/* ------------------------------------------------------------------------ */
+#if defined(__STDC__) || defined(AIX)
+
+#include <limits.h>
+
+#else
+
+#ifndef CHAR_BIT
+#define CHAR_BIT  8
+#endif
+
+#ifndef UCHAR_MAX
+#define UCHAR_MAX                              ((1<<(sizeof(unsigned char)*8))-1)
+#endif
+
+#ifndef USHRT_MAX
+#define USHRT_MAX                              ((1<<(sizeof(unsigned short)*8))-1)
+#endif
+
+#ifndef SHRT_MAX
+#define SHRT_MAX                               ((1<<(sizeof(short)*8-1))-1)
+#endif
+
+#ifndef SHRT_MIN
+#define SHRT_MIN                               (SHRT_MAX-USHRT_MAX)
+#endif
+
+#ifndef ULONG_MAX
+#define ULONG_MAX      ((1<<(sizeof(unsigned long)*8))-1)
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX       ((1<<(sizeof(long)*8-1))-1)
+#endif
+
+#ifndef LONG_MIN
+#define LONG_MIN       (LONG_MAX-ULONG_MAX)
+#endif
+
+#endif /* not __STDC__ */
+
+/* ------------------------------------------------------------------------ */
+/*     FILE Attribute                                                                                                                  */
+/* ------------------------------------------------------------------------ */
+#define is_directory(statp)            (((statp)->st_mode & S_IFMT) == S_IFDIR)
+#define is_symlink(statp)              (((statp)->st_mode & S_IFMT) == S_IFLNK)
+#define is_regularfile(statp)  (((statp)->st_mode & S_IFMT) == S_IFREG)
+
+#ifdef MSDOS
+#define WRITE_BINARY   "wb"
+#define READ_BINARY            "rb"
+#else
+#define WRITE_BINARY   "w"
+#define READ_BINARY            "r"
+#endif
+
+/* ------------------------------------------------------------------------ */
+/*     Memory and String function                                                                                              */
+/* ------------------------------------------------------------------------ */
+#include <string.h>
+
+#ifdef NOINDEX
+#define index                  strchr
+#define rindex                 strrchr
+#endif /* NOINDEX */
+
+#ifdef NOBSTRING
+#define bcmp(a,b,n)            memcmp ((a),(b),(n))
+#define bzero(d,n)             memset((d),0,(n))
+#define bcopy(s,d,n)   memmove((d),(s),(n))
+#endif /* NOBSTRING */
+
+#ifdef USESTRCASECMP
+#define strucmp(p,q)   strcasecmp((p),(q))
+#endif
+
+/* ------------------------------------------------------------------------ */
+/* Individual macro define                                                                                                     */
+/* ------------------------------------------------------------------------ */
+
+/* from crcio.c */
+#define CRCPOLY                        0xA001          /* CRC-16 */
+#define UPDATE_CRC(c)  crc = crctable[(crc ^ (c)) & 0xFF] ^ (crc >> CHAR_BIT)
+
+/* dhuf.c */
+#define N_CHAR      (256 + 60 - THRESHOLD + 1)
+#define TREESIZE_C  (N_CHAR * 2)
+#define TREESIZE_P  (128 * 2)
+#define TREESIZE    (TREESIZE_C + TREESIZE_P)
+#define ROOT_C      0
+#define ROOT_P      TREESIZE_C
+
+/* header.c */
+#define setup_get(PTR) (get_ptr = (PTR))
+#define get_byte()             (*get_ptr++ & 0xff)
+#define put_ptr                        get_ptr
+#define setup_put(PTR) (put_ptr = (PTR))
+#define put_byte(c)            (*put_ptr++ = (char)(c))
+
+/* huf.c */
+#define NP                     (MAX_DICBIT + 1)
+#define NT                     (USHRT_BIT + 3)
+#if 0
+#define PBIT           4               /* smallest integer such that (1 << PBIT) > * NP */
+#define TBIT           5               /* smallest integer such that (1 << TBIT) > * NT */
+#endif
+
+#define PBIT           5               /* smallest integer such that (1 << PBIT) > * NP */
+#define TBIT           5               /* smallest integer such that (1 << TBIT) > * NT */
+
+#define NC                     (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD)
+
+/*             #if NT > NP #define NPT NT #else #define NPT NP #endif  */
+#define NPT                    0x80
+
+/* larc.c */
+#define MAGIC0         18
+#define MAGIC5         19
+
+/* lharc.c */
+#define CMD_UNKNOWN    0
+#define CMD_EXTRACT    1
+#define CMD_ADD                2
+#define CMD_LIST       3
+#define CMD_DELETE     4
+
+#define STREQU(a,b)    (((a)[0] == (b)[0]) ? (strcmp ((a),(b)) == 0) : FALSE)
+
+/* shuf.c */
+#define N1                     286                             /* alphabet size */
+#define N2                     (2 * N1 - 1)    /* # of nodes in Huffman tree */
+#define EXTRABITS      8                               /* >= log2(F-THRESHOLD+258-N1) */
+#define BUFBITS                16                              /* >= log2(MAXBUF) */
+#define LENFIELD       4                               /* bit size of length field for tree output */
+
+/* util.c */
+#define BUFFERSIZE     2048
+#define MAXSFXCODE     1024*64
+
+#ifndef NULL
+#define NULL           (char *)0
+#endif
+
+/* slide.c */
+/*
+#define PERCOLATE  1
+#define NIL        0
+#define HASH(p, c) ((p) + ((c) << hash1) + hash2)
+*/
+
+/* slide.c */
+#ifdef SUPPORT_LH7
+#define MAX_DICBIT                     16      /* lh7 use 16bits */
+#endif
+
+#ifndef SUPPORT_LH7
+#define MAX_DICBIT                     15      /* lh6 use 15bits */
+#endif
+
+#define MAX_DICSIZ                     (1 << MAX_DICBIT)
+#define MATCHBIT                       8       /* bits for MAXMATCH - THRESHOLD */
+#define MAXMATCH                       256     /* formerly F (not more than UCHAR_MAX + 1) */
+#define THRESHOLD                      3       /* choose optimal value */
+
+/* from huf.c */
+
+/* alphabet = {0, 1, 2, ..., NC - 1} */
+#define CBIT                           9       /* $\lfloor \log_2 NC \rfloor + 1$ */
+#define USHRT_BIT                      16      /* (CHAR_BIT * sizeof(ushort)) */
+
+/* Local Variables: */
+/* mode:c */
+/* tab-width:4 */
+/* End: */
diff --git a/archivers/lha/lhamaketbl.c b/archivers/lha/lhamaketbl.c
new file mode 100755 (executable)
index 0000000..95e53d4
--- /dev/null
@@ -0,0 +1,98 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                                                                                        */
+/*                             maketbl.c -- makes decoding table                                                       */
+/*                                                                                                                                                     */
+/*             Modified                        Nobutaka Watazaki                                                       */
+/*                                                                                                                                                     */
+/*     Ver. 1.14       Source All chagned                              1995.01.14      N.Watazaki              */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+void
+lha_make_table(nchar, bitlen, tablebits, table)
+       short           nchar;
+       unsigned char   bitlen[];
+       short           tablebits;
+       unsigned short  table[];
+{
+       unsigned short  count[17];      /* count of bitlen */
+       unsigned short  weight[17];     /* 0x10000ul >> bitlen */
+       unsigned short  start[17];      /* first code of bitlen */
+       unsigned short  total;
+       unsigned int    i, l;
+       int             j, k, m, n, avail;
+       unsigned short *p;
+
+       avail = nchar;
+
+       /* initialize */
+       for (i = 1; i <= 16; i++) {
+               count[i] = 0;
+               weight[i] = 1 << (16 - i);
+       }
+
+       /* count */
+       for (i = 0; i < nchar; i++)
+               count[bitlen[i]]++;
+
+       /* calculate first code */
+       total = 0;
+       for (i = 1; i <= 16; i++) {
+               start[i] = total;
+               total += weight[i] * count[i];
+       }
+       if ((total & 0xffff) != 0)
+               error("make_table()", "Bad table (5)\n");
+
+       /* shift data for make table. */
+       m = 16 - tablebits;
+       for (i = 1; i <= tablebits; i++) {
+               start[i] >>= m;
+               weight[i] >>= m;
+       }
+
+       /* initialize */
+       j = start[tablebits + 1] >> m;
+       k = 1 << tablebits;
+       if (j != 0)
+               for (i = j; i < k; i++)
+                       table[i] = 0;
+
+       /* create table and tree */
+       for (j = 0; j < nchar; j++) {
+               k = bitlen[j];
+               if (k == 0)
+                       continue;
+               l = start[k] + weight[k];
+               if (k <= tablebits) {
+                       /* code in table */
+                       for (i = start[k]; i < l; i++)
+                               table[i] = j;
+               }
+               else {
+                       /* code not in table */
+                       p = &table[(i = start[k]) >> m];
+                       i <<= tablebits;
+                       n = k - tablebits;
+                       /* make tree (n length) */
+                       while (--n >= 0) {
+                               if (*p == 0) {
+                                       right[avail] = left[avail] = 0;
+                                       *p = avail++;
+                               }
+                               if (i & 0x8000)
+                                       p = &right[*p];
+                               else
+                                       p = &left[*p];
+                               i <<= 1;
+                       }
+                       *p = j;
+               }
+               start[k] = l;
+       }
+}
+
+/* Local Variables: */
+/* mode:c */
+/* tab-width:4 */
+/* End: */
diff --git a/archivers/lha/lharc.c b/archivers/lha/lharc.c
new file mode 100755 (executable)
index 0000000..9d01e45
--- /dev/null
@@ -0,0 +1,264 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                                                                                        */
+/*                             lharc.c -- append to archive                                                            */
+/*                                                                                                                                                     */
+/*             Copyright (C) MCMLXXXIX Yooichi.Tagawa                                                          */
+/*             Modified                        Nobutaka Watazaki                                                       */
+/*                                                     Thanks to H.Yoshizaki. (MS-DOS LHarc)                   */
+/*                                                                                                                                                     */
+/*  Ver. 0.00  Original                                                        1988.05.23  Y.Tagawa            */
+/*  Ver. 0.01  Alpha Version (for 4.2BSD)              1989.05.28  Y.Tagawa            */
+/*  Ver. 0.02  Alpha Version Rel.2                             1989.05.29  Y.Tagawa            */
+/*  Ver. 0.03  Release #3  Beta Version                        1989.07.02  Y.Tagawa            */
+/*  Ver. 0.03a Debug                                                   1989.07.03  Y.Tagawa            */
+/*  Ver. 0.03b Modified                                                        1989.07.13  Y.Tagawa            */
+/*  Ver. 0.03c Debug (Thanks to void@rena.dit.junet)                                           */
+/*                                                                                             1989.08.09  Y.Tagawa            */
+/*  Ver. 0.03d Modified (quiet and verbose)            1989.09.14  Y.Tagawa            */
+/*  V1.00  Fixed                                                               1989.09.22  Y.Tagawa            */
+/*  V1.01  Bug Fixed                                                   1989.12.25  Y.Tagawa            */
+/*                                                                                                                                                     */
+/*  DOS-Version Original LHx V C2.01           (C) H.Yohizaki                                  */
+/*                                                                                                                                                     */
+/*  V2.00  UNIX Lharc + DOS LHx -> OSK LHx             1990.11.01  Momozou                     */
+/*  V2.01  Minor Modified                                              1990.11.24  Momozou                     */
+/*                                                                                                                                                     */
+/*  Ver. 0.02  LHx for UNIX                                            1991.11.18  M.Oki                       */
+/*  Ver. 0.03  LHa for UNIX                                            1991.12.17  M.Oki                       */
+/*  Ver. 0.04  LHa for UNIX    beta version            1992.01.20  M.Oki                       */
+/*  Ver. 1.00  LHa for UNIX    Fixed                           1992.03.19  M.Oki                       */
+/*                                                                                                                                                     */
+/*  Ver. 1.10  for Symblic Link                                        1993.06.25  N.Watazaki          */
+/*  Ver. 1.11  for Symblic Link        Bug Fixed               1993.08.18  N.Watazaki          */
+/*  Ver. 1.12  for File Date Check                             1993.10.28  N.Watazaki          */
+/*  Ver. 1.13  Bug Fixed (Idicator calcurate)  1994.02.21  N.Watazaki          */
+/*  Ver. 1.13a Bug Fixed (Sym. Link delete)            1994.03.11  N.Watazaki          */
+/*     Ver. 1.13b Bug Fixed (Sym. Link delete)         1994.07.29  N.Watazaki          */
+/*     Ver. 1.14  Source All chagned                           1995.01.14      N.Watazaki              */
+/*     Ver. 1.14b,c  Bug Fixed                     1996.03.07  t.okamoto               */
+/*  Ver. 1.14d Version up                       1997.01.12  t.okamoto       */
+/*  Ver. 1.14g Bug Fixed                        2000.05.06  t.okamoto       */
+/*  Ver. 1.14i Modified                         2000.10.06  t.okamoto       */
+/* ------------------------------------------------------------------------ */
+#define LHA_MAIN_SRC
+
+#include "lha.h"
+
+/* ------------------------------------------------------------------------ */
+/*                                                             PROGRAM                                                                         */
+/* ------------------------------------------------------------------------ */
+static int      cmd = CMD_UNKNOWN;
+
+/* 1996.8.13 t.okamoto */
+#if 0
+char          **cmd_filev;
+int             cmd_filec;
+
+char           *archive_name;
+char            expanded_archive_name[FILENAME_LENGTH];
+char            temporary_name[FILENAME_LENGTH];
+char            backup_archive_name[FILENAME_LENGTH];
+#endif
+
+/* static functions */
+static void     sort_files();
+static void            print_version();
+
+char               *extract_directory = NULL;
+char             **xfilev;
+int             xfilec = 257;
+
+/* 1996.8.13 t.okamoto */
+#if 0
+char           *writting_filename;
+char           *reading_filename;
+
+int             archive_file_mode;
+int             archive_file_gid;
+#endif
+/* ------------------------------------------------------------------------ */
+static void
+init_variable()                /* Added N.Watazaki */
+{
+/* options */
+       quiet                   = FALSE;
+       text_mode               = FALSE;
+       verbose                 = FALSE;
+       noexec                  = FALSE;        /* debugging option */
+       force                   = FALSE;
+       prof                    = FALSE;
+#ifndef SUPPORT_LH7
+       compress_method = LZHUFF5_METHOD_NUM;
+#endif
+#ifdef SUPPORT_LH7
+       compress_method = LZHUFF7_METHOD_NUM;
+#endif
+
+       header_level    = HEADER_LEVEL1;
+       quiet_mode              = 0;
+
+#ifdef EUC
+       euc_mode                = FALSE;
+#endif
+
+/* view command flags */
+       verbose_listing = FALSE;
+
+/* extract command flags */
+       output_to_stdout = FALSE;
+
+/* append command flags */
+       new_archive                     = FALSE;
+       update_if_newer         = FALSE;
+       delete_after_append = FALSE;
+       generic_format          = FALSE;
+
+       remove_temporary_at_error                               = FALSE;
+       recover_archive_when_interrupt                  = FALSE;
+       remove_extracting_file_when_interrupt   = FALSE;
+       get_filename_from_stdin                                 = FALSE;
+       ignore_directory                                                = FALSE;
+       verify_mode                                                             = FALSE;
+
+       noconvertcase                                                   = FALSE;
+
+       extract_directory = NULL;
+       xfilec = 257;
+}
+
+/* ------------------------------------------------------------------------ */
+/*                                                                                                                                                     */
+/* ------------------------------------------------------------------------ */
+static int
+sort_by_ascii(a, b)
+       char          **a, **b;
+{
+       register char  *p, *q;
+       register int    c1, c2;
+
+       p = *a, q = *b;
+       if (generic_format) {
+               do {
+                       c1 = *(unsigned char *) p++;
+                       c2 = *(unsigned char *) q++;
+                       if (!c1 || !c2)
+                               break;
+                       if (islower(c1))
+                               c1 = toupper(c1);
+                       if (islower(c2))
+                               c2 = toupper(c2);
+               }
+               while (c1 == c2);
+               return c1 - c2;
+       }
+       else {
+               while (*p == *q && *p != '\0')
+                       p++, q++;
+               return *(unsigned char *) p - *(unsigned char *) q;
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+char           *
+xrealloc(old, size)
+       char           *old;
+       int             size;
+{
+       char           *p = (char *) realloc(old, size);
+       if (!p)
+               fatal_error("Not enough memory");
+       return p;
+}
+
+/* ------------------------------------------------------------------------ */
+/*                                                             STRING POOL                                                                     */
+/* ------------------------------------------------------------------------ */
+/*
+  string pool :
+       +-------------+-------------+------+-------------+----------+
+       | N A M E 1 \0| N A M E 2 \0| .... | N A M E n \0|                      |
+       +-------------+-------------+------+-------------+----------+
+         ^ ^            ^ buffer+0 buffer+used buffer+size
+
+  vector :
+       +---------------+---------------+------------- -----------------+
+       | pointer to    | pointer to    | pointer to   ...  pointer to  |
+       |  stringpool   |  N A M E 1    |  N A M E 2   ...   N A M E n  |
+       +---------------+---------------+-------------     -------------+
+       ^ malloc base      returned
+*/
+
+/* ------------------------------------------------------------------------ */
+void
+init_sp(sp)
+       struct string_pool *sp;
+{
+       sp->size = 1024 - 8;    /* any ( >=0 ) */
+       sp->used = 0;
+       sp->n = 0;
+       sp->buffer = (char *) xmalloc(sp->size * sizeof(char));
+}
+
+/* ------------------------------------------------------------------------ */
+void
+add_sp(sp, name, len)
+       struct string_pool *sp;
+       char           *name;   /* stored '\0' at tail */
+       int             len;    /* include '\0' */
+{
+       while (sp->used + len > sp->size) {
+               sp->size *= 2;
+               sp->buffer = (char *) xrealloc(sp->buffer, sp->size * sizeof(char));
+       }
+       bcopy(name, sp->buffer + sp->used, len);
+       sp->used += len;
+       sp->n++;
+}
+
+/* ------------------------------------------------------------------------ */
+void
+finish_sp(sp, v_count, v_vector)
+       register struct string_pool *sp;
+       int            *v_count;
+       char         ***v_vector;
+{
+       int             i;
+       register char  *p;
+       char          **v;
+
+       v = (char **) xmalloc((sp->n + 1) * sizeof(char *));
+       *v++ = sp->buffer;
+       *v_vector = v;
+       *v_count = sp->n;
+       p = sp->buffer;
+       for (i = sp->n; i; i--) {
+               *v++ = p;
+               if (i - 1)
+                       p += strlen(p) + 1;
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+void
+free_sp(vector)
+       char          **vector;
+{
+       vector--;
+       free(*vector);          /* free string pool */
+       free(vector);
+}
+
+
+/* ------------------------------------------------------------------------ */
+/*                                                     READ DIRECTORY FILES                                                    */
+/* ------------------------------------------------------------------------ */
+static          boolean
+include_path_p(path, name)
+       char           *path, *name;
+{
+       char           *n = name;
+       while (*path)
+               if (*path++ != *n++)
+                       return (path[-1] == '/' && *n == '\0');
+       return (*n == '/' || (n != name && path[-1] == '/' && n[-1] == '/'));
+}
diff --git a/archivers/lha/shuf.c b/archivers/lha/shuf.c
new file mode 100755 (executable)
index 0000000..07d21fc
--- /dev/null
@@ -0,0 +1,217 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                                                                                        */
+/*                             shuf.c -- extract static Huffman coding                                         */
+/*                                                                                                                                                     */
+/*             Modified                        Nobutaka Watazaki                                                       */
+/*                                                                                                                                                     */
+/*     Ver. 1.14       Source All chagned                              1995.01.14      N.Watazaki              */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+/* ------------------------------------------------------------------------ */
+#undef NP
+#undef NP2
+
+#define NP                     (8 * 1024 / 64)
+#define NP2                    (NP * 2 - 1)
+/* ------------------------------------------------------------------------ */
+static unsigned int np;
+int             fixed[2][16] = {
+       {3, 0x01, 0x04, 0x0c, 0x18, 0x30, 0},   /* old compatible */
+       {2, 0x01, 0x01, 0x03, 0x06, 0x0D, 0x1F, 0x4E, 0}        /* 8K buf */
+};
+/* ------------------------------------------------------------------------ */
+void
+decode_start_st0( /*void*/ )
+{
+       n_max = 286;
+       maxmatch = MAXMATCH;
+       init_getbits();
+#ifdef SUPPORT_LH7
+       np = 1 << (MAX_DICBIT - 7);
+#endif
+#ifndef SUPPORT_LH7
+       np = 1 << (MAX_DICBIT - 6);
+#endif
+
+}
+#if 0
+/* ------------------------------------------------------------------------ */
+void
+encode_p_st0(j)
+       unsigned short  j;
+{
+       unsigned short  i;
+
+       i = j >> 6;
+       putcode(pt_len[i], pt_code[i]);
+       putbits(6, j & 0x3f);
+}
+#endif
+/* ------------------------------------------------------------------------ */
+static void
+ready_made(method)
+       int             method;
+{
+       int             i, j;
+       unsigned int    code, weight;
+       int            *tbl;
+
+       tbl = fixed[method];
+       j = *tbl++;
+       weight = 1 << (16 - j);
+       code = 0;
+       for (i = 0; i < np; i++) {
+               while (*tbl == i) {
+                       j++;
+                       tbl++;
+                       weight >>= 1;
+               }
+               pt_len[i] = j;
+               pt_code[i] = code;
+               code += weight;
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+#if 0
+void
+encode_start_fix( /*void*/ )
+{
+       n_max = 314;
+       maxmatch = 60;
+       np = 1 << (12 - 6);
+       init_putbits();
+       start_c_dyn();
+       ready_made(0);
+}
+#endif
+/* ------------------------------------------------------------------------ */
+static void
+read_tree_c( /*void*/ )
+{                              /* read tree from file */
+       int             i, c;
+
+       i = 0;
+       while (i < N1) {
+               if (getbits(1))
+                       c_len[i] = getbits(LENFIELD) + 1;
+               else
+                       c_len[i] = 0;
+               if (++i == 3 && c_len[0] == 1 && c_len[1] == 1 && c_len[2] == 1) {
+                       c = getbits(CBIT);
+                       for (i = 0; i < N1; i++)
+                               c_len[i] = 0;
+                       for (i = 0; i < 4096; i++)
+                               c_table[i] = c;
+                       return;
+               }
+       }
+       make_table(N1, c_len, 12, c_table);
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+read_tree_p(/*void*/)
+{                              /* read tree from file */
+       int             i, c;
+
+       i = 0;
+       while (i < NP) {
+               pt_len[i] = getbits(LENFIELD);
+               if (++i == 3 && pt_len[0] == 1 && pt_len[1] == 1 && pt_len[2] == 1) {
+#ifdef SUPPORT_LH7
+                       c = getbits(MAX_DICBIT - 7);
+#else
+                       c = getbits(MAX_DICBIT - 6);
+#endif
+                       for (i = 0; i < NP; i++)
+                               c_len[i] = 0;
+                       for (i = 0; i < 256; i++)
+                               c_table[i] = c;
+                       return;
+               }
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+void
+decode_start_fix(/*void*/)
+{
+       n_max = 314;
+       maxmatch = 60;
+       init_getbits();
+       np = 1 << (12 - 6);
+       start_c_dyn();
+       ready_made(0);
+       make_table(np, pt_len, 8, pt_table);
+}
+
+/* ------------------------------------------------------------------------ */
+unsigned short
+decode_c_st0(/*void*/)
+{
+       int             i, j;
+       static unsigned short blocksize = 0;
+
+       if (blocksize == 0) {   /* read block head */
+               blocksize = getbits(BUFBITS);   /* read block blocksize */
+               read_tree_c();
+               if (getbits(1)) {
+                       read_tree_p();
+               }
+               else {
+                       ready_made(1);
+               }
+               make_table(NP, pt_len, 8, pt_table);
+       }
+       blocksize--;
+       j = c_table[lhabitbuf >> 4];
+       if (j < N1)
+               fillbuf(c_len[j]);
+       else {
+               fillbuf(12);
+               i = lhabitbuf;
+               do {
+                       if ((short) i < 0)
+                               j = right[j];
+                       else
+                               j = left[j];
+                       i <<= 1;
+               } while (j >= N1);
+               fillbuf(c_len[j] - 12);
+       }
+       if (j == N1 - 1)
+               j += getbits(EXTRABITS);
+       return j;
+}
+
+/* ------------------------------------------------------------------------ */
+unsigned short
+decode_p_st0(/*void*/)
+{
+       int             i, j;
+
+       j = pt_table[lhabitbuf >> 8];
+       if (j < np) {
+               fillbuf(pt_len[j]);
+       }
+       else {
+               fillbuf(8);
+               i = lhabitbuf;
+               do {
+                       if ((short) i < 0)
+                               j = right[j];
+                       else
+                               j = left[j];
+                       i <<= 1;
+               } while (j >= np);
+               fillbuf(pt_len[j] - 8);
+       }
+       return (j << 6) + getbits(6);
+}
+
+/* Local Variables: */
+/* mode:c */
+/* tab-width:4 */
+/* End: */
diff --git a/archivers/lha/slide.c b/archivers/lha/slide.c
new file mode 100755 (executable)
index 0000000..4d821ca
--- /dev/null
@@ -0,0 +1,462 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                                                                                        */
+/*                             slice.c -- sliding dictionary with percolating update           */
+/*                                                                                                                                                     */
+/*             Modified                        Nobutaka Watazaki                                                       */
+/*                                                                                                                                                     */
+/*     Ver. 1.14d      Exchanging a search algorithm  1997.01.11    T.Okamoto      */
+/* ------------------------------------------------------------------------ */
+
+#if 0
+#define DEBUG 1
+#endif
+
+#include "lha.h"
+
+
+#ifdef DEBUG
+FILE *fout = NULL;
+static int noslide = 1;
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static unsigned long encoded_origsize;
+
+/* ------------------------------------------------------------------------ */
+
+static unsigned int *hash;
+static unsigned int *prev;
+
+/* static unsigned char  *text; */
+unsigned char *too_flag;
+
+#if 0
+static struct encode_option encode_define[2] = {
+#if 1 || defined(__STDC__) || defined(AIX)
+       /* lh1 */
+       {(void (*) ()) output_dyn,
+               (void (*) ()) encode_start_fix,
+       (void (*) ()) encode_end_dyn},
+       /* lh4, 5,6 */
+       {(void (*) ()) output_st1,
+               (void (*) ()) encode_start_st1,
+       (void (*) ()) encode_end_st1}
+#else
+       /* lh1 */
+       {(int (*) ()) output_dyn,
+               (int (*) ()) encode_start_fix,
+       (int (*) ()) encode_end_dyn},
+       /* lh4, 5,6 */
+       {(int (*) ()) output_st1,
+               (int (*) ()) encode_start_st1,
+       (int (*) ()) encode_end_st1}
+#endif
+};
+#endif
+
+static struct decode_option decode_define[] = {
+       /* lh1 */
+       {decode_c_dyn, decode_p_st0, decode_start_fix},
+       /* lh2 */
+       {decode_c_dyn, decode_p_dyn, decode_start_dyn},
+       /* lh3 */
+       {decode_c_st0, decode_p_st0, decode_start_st0},
+       /* lh4 */
+       {decode_c_st1, decode_p_st1, decode_start_st1},
+       /* lh5 */
+       {decode_c_st1, decode_p_st1, decode_start_st1},
+       /* lh6 */
+       {decode_c_st1, decode_p_st1, decode_start_st1},
+       /* lh7 */
+       {decode_c_st1, decode_p_st1, decode_start_st1},
+       /* lzs */
+       {decode_c_lzs, decode_p_lzs, decode_start_lzs},
+       /* lz5 */
+       {decode_c_lz5, decode_p_lz5, decode_start_lz5}
+};
+
+static struct encode_option encode_set;
+static struct decode_option decode_set;
+
+#if 0
+static node     pos, matchpos, avail, *position, *parent, *prev;
+static int      remainder, matchlen;
+static unsigned char *level, *childcount;
+static unsigned long dicsiz;  /* t.okamoto */
+static unsigned short max_hash_val;
+static unsigned short hash1, hash2;
+#endif
+
+#ifdef SUPPORT_LH7
+#define DICSIZ (1L << 16)
+#define TXTSIZ (DICSIZ * 2L + MAXMATCH)
+#else
+#define DICSIZ (((unsigned long)1) << 15)
+#define TXTSIZ (DICSIZ * 2 + MAXMATCH)
+#endif
+
+#define HSHSIZ (((unsigned long)1) <<15)
+#define NIL 0
+#define LIMIT 0x100    /* chain Ä¹¤Î limit */
+
+static unsigned int txtsiz;
+
+static unsigned long dicsiz;
+
+static unsigned int hval;
+static int matchlen;
+static unsigned int matchpos;
+static unsigned int pos;
+static unsigned int remainder;
+
+#if 0
+/* ------------------------------------------------------------------------ */
+int
+encode_alloc(method)
+       int             method;
+{
+       if (method == LZHUFF1_METHOD_NUM) {     /* Changed N.Watazaki */
+               encode_set = encode_define[0];
+               maxmatch = 60;
+               dicbit = 12;   /* 12 Changed N.Watazaki */
+       } else { /* method LH4(12),LH5(13),LH6(15) */
+               encode_set = encode_define[1];
+               maxmatch = MAXMATCH;
+               if (method == LZHUFF7_METHOD_NUM)
+                       dicbit = MAX_DICBIT; /* 16 bits */
+               else if (method == LZHUFF6_METHOD_NUM)
+                       dicbit = MAX_DICBIT-1;          /* 15 bits */
+               else /* LH5  LH4 is not used */
+                       dicbit = MAX_DICBIT - 3;        /* 13 bits */
+       }
+
+       dicsiz = (((unsigned long)1) << dicbit);
+       txtsiz = dicsiz*2+maxmatch;
+
+       if (hash) return method;
+
+       if (alloc_buf() == NULL) exit(207); /* I don't know this 207. */
+
+       hash = (unsigned int*)malloc(HSHSIZ * sizeof(unsigned int));
+       prev = (unsigned int*)malloc(DICSIZ * sizeof(unsigned int));
+       text = (unsigned char*)malloc(TXTSIZ);
+       too_flag = (unsigned char*)malloc(HSHSIZ);
+
+       if (hash == NULL || prev == NULL || text == NULL || too_flag == NULL)
+               exit(207);
+
+       return method;
+}
+
+/* ------------------------------------------------------------------------ */
+/* ¥Ý¥¤¥ó¥¿¤Î½é´ü²½ */
+
+static void init_slide()
+{
+       unsigned int i;
+
+       for (i = 0; i < HSHSIZ; i++) {
+               hash[i] = NIL;
+               too_flag[i] = 0;
+       }
+       /*
+       for (i = 0; i < DICSIZ; i++) {
+           prev[i] = NIL;
+       }
+       */
+}
+
+/* ¼­½ñ¤ò DICSIZ Ê¬ Á°¤Ë¤º¤é¤¹ */
+
+static void update()
+{
+       unsigned int i, j;
+       unsigned int k;
+       long n;
+
+#if 0
+       memmove(&text[0], &text[dicsiz], (unsigned)(txtsiz - dicsiz));
+#else
+       {
+               int m;
+               i = 0; j = dicsiz; m = txtsiz-dicsiz;
+               while (m-- > 0) {
+                       text[i++] = text[j++];
+               }
+       }
+#endif
+       n = fread_crc(&text[(unsigned)(txtsiz - dicsiz)], 
+                                  (unsigned)dicsiz, infile);
+
+       remainder += n;
+       encoded_origsize += n;
+
+       pos -= dicsiz;
+       for (i = 0; i < HSHSIZ; i++) {
+               j = hash[i];
+               hash[i] = (j > dicsiz) ? j - dicsiz : NIL;
+               too_flag[i] = 0;
+       }
+       for (i = 0; i < dicsiz; i++) {
+               j = prev[i];
+               prev[i] = (j > dicsiz) ? j - dicsiz : NIL;
+       }
+}
+
+
+/* ¸½ºß¤Îʸ»úÎó¤ò¥Á¥§¡¼¥ó¤ËÄɲ乤ë */
+
+static void insert()
+{
+       prev[pos & (dicsiz - 1)] = hash[hval];
+       hash[hval] = pos;
+}
+
+
+/* ¸½ºß¤Îʸ»úÎó¤ÈºÇŰìÃפ¹¤ëʸ»úÎó¤ò¸¡º÷¤·¡¢¥Á¥§¡¼¥ó¤ËÄɲ乤ë */
+
+static void match_insert()
+{
+       unsigned int scan_pos, scan_end, len;
+       unsigned char *a, *b;
+       unsigned int chain, off, h, max;
+
+       max = maxmatch; /* MAXMATCH; */
+       if (matchlen < THRESHOLD - 1) matchlen = THRESHOLD - 1;
+       matchpos = pos;
+
+       off = 0;
+       for (h = hval; too_flag[h] && off < maxmatch - THRESHOLD; ) {
+               h = ((h << 5) ^ text[pos + (++off) + 2]) & (unsigned)(HSHSIZ - 1);
+       }
+       if (off == maxmatch - THRESHOLD) off = 0;
+       for (;;) {
+               chain = 0;
+               scan_pos = hash[h];
+               scan_end = (pos > dicsiz) ? pos + off - dicsiz : off;
+               while (scan_pos > scan_end) {
+                       chain++;
+
+                       if (text[scan_pos + matchlen - off] == text[pos + matchlen]) {
+                               {
+                                       a = text + scan_pos - off;  b = text + pos;
+                                       for (len = 0; len < max && *a++ == *b++; len++);
+                               }
+
+                               if (len > matchlen) {
+                                       matchpos = scan_pos - off;
+                                       if ((matchlen = len) == max) {
+                                               break;
+                                       }
+#ifdef DEBUG
+                                       if (noslide) {
+                                         if (matchpos < dicsiz) {
+                                               printf("matchpos=%u scan_pos=%u dicsiz=%u\n"
+                                                          ,matchpos, scan_pos, dicsiz);
+                                         }
+                                       }
+#endif
+                               }
+                       }
+                       scan_pos = prev[scan_pos & (dicsiz - 1)];
+               }
+
+               if (chain >= LIMIT)
+                       too_flag[h] = 1;
+
+               if (matchlen > off + 2 || off == 0)
+                       break;
+               max = off + 2;
+               off = 0;
+               h = hval;
+       }
+       prev[pos & (dicsiz - 1)] = hash[hval];
+       hash[hval] = pos;
+}
+
+
+/* ¥Ý¥¤¥ó¥¿¤ò¿Ê¤á¡¢¼­½ñ¤ò¹¹¿·¤·¡¢¥Ï¥Ã¥·¥åÃͤò¹¹¿·¤¹¤ë */
+
+static void get_next()
+{
+       remainder--;
+       if (++pos >= txtsiz - maxmatch) {
+               update();
+#ifdef DEBUG
+               noslide = 0;
+#endif
+       }
+       hval = ((hval << 5) ^ text[pos + 2]) & (unsigned)(HSHSIZ - 1);
+}
+
+void encode(lhinterface)
+struct interfacing *lhinterface;
+{
+       int lastmatchlen;
+       unsigned int lastmatchoffset;
+
+#ifdef DEBUG
+       unsigned int addr;
+
+       addr = 0;
+
+       fout = fopen("en", "wt");
+       if (fout == NULL) exit(1);
+#endif
+       infile = lhinterface->infile;
+       outfile = lhinterface->outfile;
+       origsize = lhinterface->original;
+       compsize = count = 0L;
+       crc = unpackable = 0;
+
+       /* encode_alloc(); */ /* allocate_memory(); */
+       init_slide();  
+
+       encode_set.encode_start();
+       memset(&text[0], ' ', (long)TXTSIZ);
+
+       remainder = fread_crc(&text[dicsiz], txtsiz-dicsiz, infile);
+       encoded_origsize = remainder;
+       matchlen = THRESHOLD - 1;
+
+       pos = dicsiz;
+
+       if (matchlen > remainder) matchlen = remainder;
+       hval = ((((text[dicsiz] << 5) ^ text[dicsiz + 1]) << 5) 
+               ^ text[dicsiz + 2]) & (unsigned)(HSHSIZ - 1);
+
+       insert();
+       while (remainder > 0 && ! unpackable) {
+               lastmatchlen = matchlen;  lastmatchoffset = pos - matchpos - 1;
+               --matchlen;
+               get_next();  match_insert();
+               if (matchlen > remainder) matchlen = remainder;
+               if (matchlen > lastmatchlen || lastmatchlen < THRESHOLD) {
+                       encode_set.output(text[pos - 1], 0);
+#ifdef DEBUG
+                       fprintf(fout, "%u C %02X\n", addr, text[pos-1]);
+                       addr++;
+#endif
+                       count++;
+               } else {
+                       encode_set.output(lastmatchlen + (UCHAR_MAX + 1 - THRESHOLD),
+                          (lastmatchoffset) & (dicsiz-1) );
+                       --lastmatchlen;
+
+#ifdef DEBUG
+                       fprintf(fout, "%u M %u %u ", addr,
+                                       lastmatchoffset & (dicsiz-1), lastmatchlen+1);
+                       addr += lastmatchlen +1 ;
+
+                       {
+                         int t,cc;
+                       for (t=0; t<lastmatchlen+1; t++) {
+                         cc = text[(pos-(lastmatchoffset)) & (dicsiz-1)];
+                         fprintf(fout, "%02X ", cc);
+                       }
+                       fprintf(fout, "\n");
+                       }
+#endif
+                       while (--lastmatchlen > 0) {
+                               get_next();  insert();
+                               count++;
+                       }
+                       get_next();
+                       matchlen = THRESHOLD - 1;
+                       match_insert();
+                       if (matchlen > remainder) matchlen = remainder;
+               }
+       }
+       encode_set.encode_end();
+
+       interface->packed = compsize;
+       interface->original = encoded_origsize;
+}
+
+/* ------------------------------------------------------------------------ */
+
+#endif
+
+int
+decode(lhinterface)
+       struct interfacing *lhinterface;
+{
+       unsigned int i, j, k, c;
+       unsigned int dicsiz1, offset;
+       unsigned char *dtext;
+       
+
+#ifdef DEBUG
+       fout = fopen("de", "wt");
+       if (fout == NULL) exit(1);
+#endif
+
+       infile = lhinterface->infile;
+       outfile = lhinterface->outfile;
+       dicbit = lhinterface->dicbit;
+       origsize = lhinterface->original;
+       compsize = lhinterface->packed;
+       decode_set = decode_define[lhinterface->method - 1];
+
+       crc = 0;
+       prev_char = -1;
+       dicsiz = 1L << dicbit;
+       dtext = (unsigned char *) malloc(dicsiz);
+       if (dtext == NULL)
+           return 0;
+       for (i=0; i<dicsiz; i++) dtext[i] = 0x20;
+       decode_set.decode_start();
+       dicsiz1 = dicsiz - 1;
+       offset = (lhinterface->method == LARC_METHOD_NUM) ? 0x100 - 2 : 0x100 - 3;
+       count = 0;
+       loc = 0;
+       while (count < origsize) {
+               c = decode_set.decode_c();
+               if (c <= UCHAR_MAX) {
+#ifdef DEBUG
+                 fprintf(fout, "%u C %02X\n", count, c);
+#endif
+                       dtext[loc++] = c;
+                       if (loc == dicsiz) {
+                               fwrite_crc(dtext, dicsiz, outfile);
+                               loc = 0;
+                       }
+                       count++;
+               }
+               else {
+                       j = c - offset;
+                       i = (loc - decode_set.decode_p() - 1) & dicsiz1;
+#ifdef DEBUG
+                       fprintf(fout, "%u M %u %u ", count, (loc-1-i) & dicsiz1, j);
+#endif
+                       count += j;
+                       for (k = 0; k < j; k++) {
+                               c = dtext[(i + k) & dicsiz1];
+
+#ifdef DEBUG
+                               fprintf(fout, "%02X ", c & 0xff);
+#endif
+                               dtext[loc++] = c;
+                               if (loc == dicsiz) {
+                                       fwrite_crc(dtext, dicsiz, outfile);
+                                       loc = 0;
+                               }
+                       }
+#ifdef DEBUG
+                       fprintf(fout, "\n");
+#endif
+               }
+       }
+       if (loc != 0) {
+               fwrite_crc(dtext, loc, outfile);
+       }
+
+       free(dtext);
+    return 1;
+}
+
+/* Local Variables: */
+/* mode:c */
+/* tab-width:4 */
+/* End: */
diff --git a/archivers/lha/uae_lha.c b/archivers/lha/uae_lha.c
new file mode 100755 (executable)
index 0000000..8fa8602
--- /dev/null
@@ -0,0 +1,90 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+#include "zfile.h"
+#include "zarchive.h"
+
+#include "lha.h"
+
+static char *methods[] =
+{
+       LZHUFF0_METHOD, LZHUFF1_METHOD, LZHUFF2_METHOD, LZHUFF3_METHOD,
+       LZHUFF4_METHOD, LZHUFF5_METHOD, LZHUFF6_METHOD, LZHUFF7_METHOD,
+       LARC_METHOD, LARC5_METHOD, LARC4_METHOD,
+       LZHDIRS_METHOD,
+       NULL
+};
+
+struct zvolume *archive_directory_lha(struct zfile *zf)
+{
+    struct zvolume *zv;
+    struct zarchive_info zai;
+    LzHeader hdr;
+    int i;
+
+    _tzset();
+    zv = zvolume_alloc(zf, ArchiveFormatLHA, NULL);
+    while (get_header(zf, &hdr)) {
+       struct znode *zn;
+       memset(&zai, 0, sizeof zai);
+       zai.name = hdr.name;
+       zai.size = hdr.original_size;
+       zai.flags = hdr.attribute;
+       zai.t = hdr.unix_last_modified_stamp -= _timezone;
+       if (hdr.name[strlen(hdr.name) + 1] != 0)
+           zai.comment = &hdr.name[strlen(hdr.name) + 1];
+       zn = zvolume_addfile_abs(zv, &zai);
+       zn->offset = zfile_ftell(zf);
+       zn->packedsize = hdr.packed_size;
+       for (i = 0; methods[i]; i++) {
+           if (!strcmp(methods[i], hdr.method))
+               zn->method = i;
+       }
+       zfile_fseek(zf, hdr.packed_size, SEEK_CUR);
+       
+    }
+    return zv;
+}
+
+struct zfile *archive_access_lha(struct znode *zn)
+{
+    struct zfile *zf = zn->volume->archive;
+    struct zfile *out = zfile_fopen_empty (zn->name, zn->size);
+    struct interfacing lhinterface;
+
+    zfile_fseek(zf, zn->offset, SEEK_SET);
+
+    lhinterface.method = zn->method;
+    lhinterface.dicbit = 13;   /* method + 8; -lh5- */
+    lhinterface.infile = zf;
+    lhinterface.outfile = out;
+    lhinterface.original = zn->size;
+    lhinterface.packed = zn->packedsize;
+
+    switch (zn->method) {
+       case LZHUFF0_METHOD_NUM:
+       case LARC4_METHOD_NUM:
+           zfile_fread(out->data, zn->size, 1, zf);
+       break;
+       case LARC_METHOD_NUM:           /* -lzs- */
+           lhinterface.dicbit = 11;
+           decode(&lhinterface);
+        break;
+       case LZHUFF1_METHOD_NUM:                /* -lh1- */
+       case LZHUFF4_METHOD_NUM:                /* -lh4- */
+       case LARC5_METHOD_NUM:                  /* -lz5- */
+           lhinterface.dicbit = 12;
+           decode(&lhinterface);
+       break;
+       case LZHUFF6_METHOD_NUM:                /* -lh6- */     /* Added N.Watazaki (^_^) */
+       case LZHUFF7_METHOD_NUM:                /* -lh7- */
+           lhinterface.dicbit = (zn->method - LZHUFF6_METHOD_NUM) + 15;
+       default:
+           decode(&lhinterface);
+    }
+    return out;
+}
diff --git a/archivers/lha/util.c b/archivers/lha/util.c
new file mode 100755 (executable)
index 0000000..0d89c7d
--- /dev/null
@@ -0,0 +1,250 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                                                                                        */
+/*                             util.c -- LHarc Util                                                                            */
+/*                                                                                                                                                     */
+/*             Modified                        Nobutaka Watazaki                                                       */
+/*                                                                                                                                                     */
+/*     Ver. 1.14       Source All chagned                              1995.01.14      N.Watazaki              */
+/*  Ver. 1.14e  Support for sfx archives               1999.05.28      T.Okamoto       */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+/*
+ * util.c - part of LHa for UNIX Feb 26 1992 modified by Masaru Oki Mar  4
+ * 1992 modified by Masaru Oki #ifndef USESTRCASECMP added. Mar 31 1992
+ * modified by Masaru Oki #ifdef NOMEMSET added.
+ */
+
+/* ------------------------------------------------------------------------ */
+extern unsigned short crc;
+
+/* ------------------------------------------------------------------------ */
+/*     convert path delimit
+       erreturns *filename                                                                                                             */
+/* ------------------------------------------------------------------------ */
+unsigned char  *
+convdelim(path, delim)
+       unsigned char  *path;
+       unsigned char   delim;
+{
+       unsigned char   c;
+       unsigned char  *p;
+#ifdef MULTIBYTE_CHAR
+       int             kflg;
+
+       kflg = 0;
+#endif
+       for (p = path; (c = *p) != 0; p++) {
+#ifdef MULTIBYTE_CHAR
+               if (kflg) {
+                       kflg = 0;
+               }
+               else if (MULTIBYTE_FIRST_P(c)) {
+                       kflg = 1;
+               }
+               else
+#endif
+               if (c == '\\' || c == DELIM || c == DELIM2) {
+                       *p = delim;
+                       path = p + 1;
+               }
+       }
+       return path;
+}
+
+
+/*
+ * strdup(3)
+ */
+
+/* ------------------------------------------------------------------------ */
+#ifdef NOSTRDUP
+char           *
+strdup(buf)
+       char           *buf;
+{
+       char           *p;
+
+       if ((p = (char *) malloc(strlen(buf) + 1)) == NULL)
+               return NULL;
+       strcpy(p, buf);
+       return p;
+}
+#endif
+
+/*
+ * memmove( char *dst , char *src , size_t cnt )
+ */
+
+/* ------------------------------------------------------------------------ */
+#if defined(NOBSTRING) && !defined(__STDC__)
+void           *
+memmove(dst, src, cnt)
+       register char  *dst, *src;
+       register int    cnt;
+{
+       if (dst == src)
+               return dst;
+       if (src > dst) {
+               while (--cnt >= 0)
+                       *dst++ = *src++;
+       }
+       else {
+               dst += cnt;
+               src += cnt;
+               while (--cnt >= 0)
+                       *--dst = *--src;
+       }
+       return dst;
+}
+#endif
+
+/*
+ * rename - change the name of file 91.11.02 by Tomohiro Ishikawa
+ * (ishikawa@gaia.cow.melco.CO.JP) 92.01.20 little modified (added #ifdef) by
+ * Masaru Oki 92.01.28 added mkdir() and rmdir() by Tomohiro Ishikawa
+ */
+
+#if defined(NOFTRUNCATE) && !defined(_MINIX)
+
+/* ------------------------------------------------------------------------ */
+int
+rename(from, to)
+       char           *from, *to;
+{
+       struct stat     s1, s2;
+       extern int      errno;
+
+       if (stat(from, &s1) < 0)
+               return (-1);
+       /* is 'FROM' file a directory? */
+       if ((s1.st_mode & S_IFMT) == S_IFDIR) {
+               errno = ENOTDIR;
+               return (-1);
+       }
+       if (stat(to, &s2) >= 0) {       /* 'TO' exists! */
+               /* is 'TO' file a directory? */
+               if ((s2.st_mode & S_IFMT) == S_IFDIR) {
+                       errno = EISDIR;
+                       return (-1);
+               }
+               if (unlink(to) < 0)
+                       return (-1);
+       }
+       if (link(from, to) < 0)
+               return (-1);
+       if (unlink(from) < 0)
+               return (-1);
+       return (0);
+}
+#endif                         /* NOFTRUNCATE */
+/* ------------------------------------------------------------------------ */
+
+#ifdef NOMKDIR
+#ifndef        MKDIRPATH
+#define        MKDIRPATH       "/bin/mkdir"
+#endif
+#ifndef        RMDIRPATH
+#define        RMDIRPATH       "/bin/rmdir"
+#endif
+int
+rmdir(path)
+       char           *path;
+{
+       int             stat, rtn = 0;
+       char           *cmdname;
+       if ((cmdname = (char *) malloc(strlen(RMDIRPATH) + 1 + strlen(path) + 1))
+           == 0)
+               return (-1);
+       strcpy(cmdname, RMDIRPATH);
+       *(cmdname + strlen(RMDIRPATH)) = ' ';
+       strcpy(cmdname + strlen(RMDIRPATH) + 1, path);
+       if ((stat = system(cmdname)) < 0)
+               rtn = -1;       /* fork or exec error */
+       else if (stat) {        /* RMDIR command error */
+               errno = EIO;
+               rtn = -1;
+       }
+       free(cmdname);
+       return (rtn);
+}
+
+/* ------------------------------------------------------------------------ */
+int
+mkdir(path, mode)
+       char           *path;
+       int             mode;
+{
+       int             child, stat;
+       char           *cmdname, *cmdpath = MKDIRPATH;
+       if ((cmdname = (char *) strrchr(cmdpath, '/')) == (char *) 0)
+               cmdname = cmdpath;
+       if ((child = fork()) < 0)
+               return (-1);    /* fork error */
+       else if (child) {       /* parent process */
+               while (child != wait(&stat))    /* ignore signals */
+                       continue;
+       }
+       else {                  /* child process */
+               int             maskvalue;
+               maskvalue = umask(0);   /* get current umask() value */
+               umask(maskvalue | (0777 & ~mode));      /* set it! */
+               execl(cmdpath, cmdname, path, (char *) 0);
+               /* never come here except execl is error */
+               return (-1);
+       }
+       if (stat != 0) {
+               errno = EIO;    /* cannot get error num. */
+               return (-1);
+       }
+       return (0);
+}
+#endif
+
+/*
+ * strucmp modified: Oct 29 1991 by Masaru Oki
+ */
+
+#ifndef USESTRCASECMP
+static int
+my_toupper(n)
+       register int    n;
+{
+       if (n >= 'a' && n <= 'z')
+               return n & (~('a' - 'A'));
+       return n;
+}
+
+/* ------------------------------------------------------------------------ */
+int
+strucmp(s, t)
+       register char  *s, *t;
+{
+       while (my_toupper(*s++) == my_toupper(*t++))
+               if (!*s || !*t)
+                       break;
+       if (!*s && !*t)
+               return 0;
+       return 1;
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+#ifdef NOMEMSET
+/* Public Domain memset(3) */
+char           *
+memset(s, c, n)
+       char           *s;
+       int             c, n;
+{
+       char           *p = s;
+       while (n--)
+               *p++ = (char) c;
+       return s;
+}
+#endif
+
+/* Local Variables: */
+/* mode:c */
+/* tab-width:4 */
+/* compile-command:"gcc -c util.c" */
+/* End: */
diff --git a/archivers/lzx/unlzx.c b/archivers/lzx/unlzx.c
new file mode 100755 (executable)
index 0000000..2354305
--- /dev/null
@@ -0,0 +1,822 @@
+/* $VER: unlzx.c 1.0 (22.2.98) */
+/* Created: 11.2.98 */
+/* Added Pipe support to read from stdin (03.4.01, Erik Meusel)           */
+
+/* LZX Extract in (supposedly) portable C.                                */
+
+/* ********************* WINDOWS PORTING NOTES STARTS *********************/
+
+/* Ported to Windows Platform by Stefano Coletta on 22.5.02               */
+/* creator@mindcreations.com or visit http://creator.mindcreations.com    */
+
+/* Changes to original code include:                                      */
+/* - Using #include <direct.h> to substitute the mkdir() function call    */
+/* - Added #include "getopt.h" to support getopt() function               */
+
+/* Compile with:                                                          */
+/* Microsoft Visual Studio 6.0 SP5 using supplied project file            */
+
+/* ********************** WINDOWS PORTING NOTES END ***********************/
+
+
+/* Thanks to Dan Fraser for decoding the coredumps and helping me track   */
+/* down some HIDEOUSLY ANNOYING bugs.                                     */
+
+/* Everything is accessed as unsigned char's to try and avoid problems    */
+/* with byte order and alignment. Most of the decrunch functions          */
+/* encourage overruns in the buffers to make things as fast as possible.  */
+/* All the time is taken up in crc_calc() and decrunch() so they are      */
+/* pretty damn optimized. Don't try to understand this program.           */
+
+/* ---------------------------------------------------------------------- */
+
+/* - minimal UAE specific version 13-14.06.2007 by Toni Wilen */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include "zfile.h"
+#include "zarchive.h"
+
+/* ---------------------------------------------------------------------- */
+
+static unsigned char *source;
+static unsigned char *destination;
+static unsigned char *source_end;
+static unsigned char *destination_end;
+
+static unsigned int decrunch_method;
+static unsigned int decrunch_length;
+static unsigned int last_offset;
+static unsigned int global_control;
+static int global_shift;
+
+static unsigned char offset_len[8];
+static unsigned short offset_table[128];
+static unsigned char huffman20_len[20];
+static unsigned short huffman20_table[96];
+static unsigned char literal_len[768];
+static unsigned short literal_table[5120];
+
+/* ---------------------------------------------------------------------- */
+
+static unsigned int sum;
+
+static const unsigned int crc_table[256]=
+{
+ 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,
+ 0xE963A535,0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,
+ 0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2,
+ 0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7,
+ 0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,
+ 0xFA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,
+ 0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,
+ 0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,
+ 0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,
+ 0xCFBA9599,0xB8BDA50F,0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,
+ 0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D,0x76DC4190,0x01DB7106,
+ 0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433,
+ 0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D,
+ 0x91646C97,0xE6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,
+ 0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,
+ 0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,
+ 0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,
+ 0xA4D1C46D,0xD3D6F4FB,0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0,
+ 0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,0x5005713C,0x270241AA,
+ 0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F,
+ 0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,
+ 0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,
+ 0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,
+ 0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,
+ 0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB,
+ 0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,
+ 0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0xD6D6A3E8,0xA1D1937E,
+ 0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,
+ 0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,
+ 0x316E8EEF,0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,
+ 0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,
+ 0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,
+ 0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F,
+ 0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38,
+ 0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,0x86D3D2D4,0xF1D4E242,
+ 0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,
+ 0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,
+ 0x616BFFD3,0x166CCF45,0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,
+ 0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB,0xAED16A4A,0xD9D65ADC,
+ 0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9,
+ 0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,
+ 0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,
+ 0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D
+};
+
+/* ---------------------------------------------------------------------- */
+
+static const unsigned char table_one[32]=
+{
+ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14
+};
+
+static const unsigned int table_two[32]=
+{
+ 0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,
+ 1536,2048,3072,4096,6144,8192,12288,16384,24576,32768,49152
+};
+
+static const unsigned int table_three[16]=
+{
+ 0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767
+};
+
+static const unsigned char table_four[34]=
+{
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
+};
+
+/* ---------------------------------------------------------------------- */
+
+/* Possible problems with 64 bit machines here. It kept giving warnings   */
+/* for people so I changed back to ~.                                     */
+
+static void crc_calc(unsigned char *memory, unsigned int length)
+{
+ register unsigned int temp;
+
+ if(length)
+ {
+  temp = ~sum; /* was (sum ^ 4294967295) */
+  do
+  {
+   temp = crc_table[(*memory++ ^ temp) & 255] ^ (temp >> 8);
+  } while(--length);
+  sum = ~temp; /* was (temp ^ 4294967295) */
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* Build a fast huffman decode table from the symbol bit lengths.         */
+/* There is an alternate algorithm which is faster but also more complex. */
+
+static int make_decode_table(int number_symbols, int table_size,
+                      unsigned char *length, unsigned short *table)
+{
+ register unsigned char bit_num = 0;
+ register int symbol;
+ unsigned int leaf; /* could be a register */
+ unsigned int table_mask, bit_mask, pos, fill, next_symbol, reverse;
+ int abort = 0;
+
+ pos = 0; /* consistantly used as the current position in the decode table */
+
+ bit_mask = table_mask = 1 << table_size;
+
+ bit_mask >>= 1; /* don't do the first number */
+ bit_num++;
+
+ while((!abort) && (bit_num <= table_size))
+ {
+  for(symbol = 0; symbol < number_symbols; symbol++)
+  {
+   if(length[symbol] == bit_num)
+   {
+    reverse = pos; /* reverse the order of the position's bits */
+    leaf = 0;
+    fill = table_size;
+    do /* reverse the position */
+    {
+     leaf = (leaf << 1) + (reverse & 1);
+     reverse >>= 1;
+    } while(--fill);
+    if((pos += bit_mask) > table_mask)
+    {
+     abort = 1;
+     break; /* we will overrun the table! abort! */
+    }
+    fill = bit_mask;
+    next_symbol = 1 << bit_num;
+    do
+    {
+     table[leaf] = symbol;
+     leaf += next_symbol;
+    } while(--fill);
+   }
+  }
+  bit_mask >>= 1;
+  bit_num++;
+ }
+
+ if((!abort) && (pos != table_mask))
+ {
+  for(symbol = pos; symbol < table_mask; symbol++) /* clear the rest of the table */
+  {
+   reverse = symbol; /* reverse the order of the position's bits */
+   leaf = 0;
+   fill = table_size;
+   do /* reverse the position */
+   {
+    leaf = (leaf << 1) + (reverse & 1);
+    reverse >>= 1;
+   } while(--fill);
+   table[leaf] = 0;
+  }
+  next_symbol = table_mask >> 1;
+  pos <<= 16;
+  table_mask <<= 16;
+  bit_mask = 32768;
+
+  while((!abort) && (bit_num <= 16))
+  {
+   for(symbol = 0; symbol < number_symbols; symbol++)
+   {
+    if(length[symbol] == bit_num)
+    {
+     reverse = pos >> 16; /* reverse the order of the position's bits */
+     leaf = 0;
+     fill = table_size;
+     do /* reverse the position */
+     {
+      leaf = (leaf << 1) + (reverse & 1);
+      reverse >>= 1;
+     } while(--fill);
+     for(fill = 0; fill < bit_num - table_size; fill++)
+     {
+      if(table[leaf] == 0)
+      {
+       table[(next_symbol << 1)] = 0;
+       table[(next_symbol << 1) + 1] = 0;
+       table[leaf] = next_symbol++;
+      }
+      leaf = table[leaf] << 1;
+      leaf += (pos >> (15 - fill)) & 1;
+     }
+     table[leaf] = symbol;
+     if((pos += bit_mask) > table_mask)
+     {
+      abort = 1;
+      break; /* we will overrun the table! abort! */
+     }
+    }
+   }
+   bit_mask >>= 1;
+   bit_num++;
+  }
+ }
+ if(pos != table_mask) abort = 1; /* the table is incomplete! */
+
+ return(abort);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* Read and build the decrunch tables. There better be enough data in the */
+/* source buffer or it's stuffed. */
+
+static int read_literal_table()
+{
+ register unsigned int control;
+ register int shift;
+ unsigned int temp; /* could be a register */
+ unsigned int symbol, pos, count, fix, max_symbol;
+ int abort = 0;
+
+ control = global_control;
+ shift = global_shift;
+
+ if(shift < 0) /* fix the control word if necessary */
+ {
+  shift += 16;
+  control += *source++ << (8 + shift);
+  control += *source++ << shift;
+ }
+
+/* read the decrunch method */
+
+ decrunch_method = control & 7;
+ control >>= 3;
+ if((shift -= 3) < 0)
+ {
+  shift += 16;
+  control += *source++ << (8 + shift);
+  control += *source++ << shift;
+ }
+
+/* Read and build the offset huffman table */
+
+ if((!abort) && (decrunch_method == 3))
+ {
+  for(temp = 0; temp < 8; temp++)
+  {
+   offset_len[temp] = control & 7;
+   control >>= 3;
+   if((shift -= 3) < 0)
+   {
+    shift += 16;
+    control += *source++ << (8 + shift);
+    control += *source++ << shift;
+   }
+  }
+  abort = make_decode_table(8, 7, offset_len, offset_table);
+ }
+
+/* read decrunch length */
+
+ if(!abort)
+ {
+  decrunch_length = (control & 255) << 16;
+  control >>= 8;
+  if((shift -= 8) < 0)
+  {
+   shift += 16;
+   control += *source++ << (8 + shift);
+   control += *source++ << shift;
+  }
+  decrunch_length += (control & 255) << 8;
+  control >>= 8;
+  if((shift -= 8) < 0)
+  {
+   shift += 16;
+   control += *source++ << (8 + shift);
+   control += *source++ << shift;
+  }
+  decrunch_length += (control & 255);
+  control >>= 8;
+  if((shift -= 8) < 0)
+  {
+   shift += 16;
+   control += *source++ << (8 + shift);
+   control += *source++ << shift;
+  }
+ }
+
+/* read and build the huffman literal table */
+
+ if((!abort) && (decrunch_method != 1))
+ {
+  pos = 0;
+  fix = 1;
+  max_symbol = 256;
+
+  do
+  {
+   for(temp = 0; temp < 20; temp++)
+   {
+    huffman20_len[temp] = control & 15;
+    control >>= 4;
+    if((shift -= 4) < 0)
+    {
+     shift += 16;
+     control += *source++ << (8 + shift);
+     control += *source++ << shift;
+    }
+   }
+   abort = make_decode_table(20, 6, huffman20_len, huffman20_table);
+
+   if(abort) break; /* argh! table is corrupt! */
+
+   do
+   {
+    if((symbol = huffman20_table[control & 63]) >= 20)
+    {
+     do /* symbol is longer than 6 bits */
+     {
+      symbol = huffman20_table[((control >> 6) & 1) + (symbol << 1)];
+      if(!shift--)
+      {
+       shift += 16;
+       control += *source++ << 24;
+       control += *source++ << 16;
+      }
+      control >>= 1;
+     } while(symbol >= 20);
+     temp = 6;
+    }
+    else
+    {
+     temp = huffman20_len[symbol];
+    }
+    control >>= temp;
+    if((shift -= temp) < 0)
+    {
+     shift += 16;
+     control += *source++ << (8 + shift);
+     control += *source++ << shift;
+    }
+    switch(symbol)
+    {
+     case 17:
+     case 18:
+     {
+      if(symbol == 17)
+      {
+       temp = 4;
+       count = 3;
+      }
+      else /* symbol == 18 */
+      {
+       temp = 6 - fix;
+       count = 19;
+      }
+      count += (control & table_three[temp]) + fix;
+      control >>= temp;
+      if((shift -= temp) < 0)
+      {
+       shift += 16;
+       control += *source++ << (8 + shift);
+       control += *source++ << shift;
+      }
+      while((pos < max_symbol) && (count--))
+       literal_len[pos++] = 0;
+      break;
+     }
+     case 19:
+     {
+      count = (control & 1) + 3 + fix;
+      if(!shift--)
+      {
+       shift += 16;
+       control += *source++ << 24;
+       control += *source++ << 16;
+      }
+      control >>= 1;
+      if((symbol = huffman20_table[control & 63]) >= 20)
+      {
+       do /* symbol is longer than 6 bits */
+       {
+        symbol = huffman20_table[((control >> 6) & 1) + (symbol << 1)];
+        if(!shift--)
+        {
+         shift += 16;
+         control += *source++ << 24;
+         control += *source++ << 16;
+        }
+        control >>= 1;
+       } while(symbol >= 20);
+       temp = 6;
+      }
+      else
+      {
+       temp = huffman20_len[symbol];
+      }
+      control >>= temp;
+      if((shift -= temp) < 0)
+      {
+       shift += 16;
+       control += *source++ << (8 + shift);
+       control += *source++ << shift;
+      }
+      symbol = table_four[literal_len[pos] + 17 - symbol];
+      while((pos < max_symbol) && (count--))
+       literal_len[pos++] = symbol;
+      break;
+     }
+     default:
+     {
+      symbol = table_four[literal_len[pos] + 17 - symbol];
+      literal_len[pos++] = symbol;
+      break;
+     }
+    }
+   } while(pos < max_symbol);
+   fix--;
+   max_symbol += 512;
+  } while(max_symbol == 768);
+
+  if(!abort)
+   abort = make_decode_table(768, 12, literal_len, literal_table);
+ }
+
+ global_control = control;
+ global_shift = shift;
+
+ return(abort);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* Fill up the decrunch buffer. Needs lots of overrun for both destination */
+/* and source buffers. Most of the time is spent in this routine so it's  */
+/* pretty damn optimized. */
+
+static void decrunch(void)
+{
+ register unsigned int control;
+ register int shift;
+ unsigned int temp; /* could be a register */
+ unsigned int symbol, count;
+ unsigned char *string;
+
+ control = global_control;
+ shift = global_shift;
+
+ do
+ {
+  if((symbol = literal_table[control & 4095]) >= 768)
+  {
+   control >>= 12;
+   if((shift -= 12) < 0)
+   {
+    shift += 16;
+    control += *source++ << (8 + shift);
+    control += *source++ << shift;
+   }
+   do /* literal is longer than 12 bits */
+   {
+    symbol = literal_table[(control & 1) + (symbol << 1)];
+    if(!shift--)
+    {
+     shift += 16;
+     control += *source++ << 24;
+     control += *source++ << 16;
+    }
+    control >>= 1;
+   } while(symbol >= 768);
+  }
+  else
+  {
+   temp = literal_len[symbol];
+   control >>= temp;
+   if((shift -= temp) < 0)
+   {
+    shift += 16;
+    control += *source++ << (8 + shift);
+    control += *source++ << shift;
+   }
+  }
+  if(symbol < 256)
+  {
+   *destination++ = symbol;
+  }
+  else
+  {
+   symbol -= 256;
+   count = table_two[temp = symbol & 31];
+   temp = table_one[temp];
+   if((temp >= 3) && (decrunch_method == 3))
+   {
+    temp -= 3;
+    count += ((control & table_three[temp]) << 3);
+    control >>= temp;
+    if((shift -= temp) < 0)
+    {
+     shift += 16;
+     control += *source++ << (8 + shift);
+     control += *source++ << shift;
+    }
+    count += (temp = offset_table[control & 127]);
+    temp = offset_len[temp];
+   }
+   else
+   {
+    count += control & table_three[temp];
+    if(!count) count = last_offset;
+   }
+   control >>= temp;
+   if((shift -= temp) < 0)
+   {
+    shift += 16;
+    control += *source++ << (8 + shift);
+    control += *source++ << shift;
+   }
+   last_offset = count;
+
+   count = table_two[temp = (symbol >> 5) & 15] + 3;
+   temp = table_one[temp];
+   count += (control & table_three[temp]);
+   control >>= temp;
+   if((shift -= temp) < 0)
+   {
+    shift += 16;
+    control += *source++ << (8 + shift);
+    control += *source++ << shift;
+   }
+   string = destination - last_offset;
+   do
+   {
+    *destination++ = *string++;
+   } while(--count);
+  }
+ } while((destination < destination_end) && (source < source_end));
+
+ global_control = control;
+ global_shift = shift;
+}
+
+struct zfile *archive_access_lzx (struct znode *zn)
+{
+    unsigned int startpos;
+    struct znode *znfirst, *znlast;
+    struct zfile *zf = zn->volume->archive;
+    struct zfile *dstf;
+    uae_u8 *buf, *dbuf;
+    unsigned int compsize, unpsize;
+
+    dstf = NULL;
+    buf = dbuf = NULL;
+
+    /* find first file in compressed block */
+    unpsize = 0;
+    znfirst = zn;
+    while (znfirst->prev) {
+       znfirst = znfirst->prev;
+       if (!znfirst || znfirst->offset != 0)
+           break;
+       unpsize += znfirst->size;
+    }
+    /* find last file in compressed block */
+    znlast = zn;
+    while (znlast) {
+       unpsize += znlast->size;
+       if (znlast->offset != 0)
+           break;
+       znlast = znlast->next;
+    }
+    if (!znlast)
+       return NULL;
+    /* start offset to compressed block */
+    startpos = znlast->offset;
+    compsize = znlast->packedsize;
+    zfile_fseek (zf, startpos, SEEK_SET);
+    buf = xmalloc(compsize);
+    zfile_fread (buf, compsize, 1, zf);
+    dbuf = xmalloc (unpsize);
+
+    /* unpack complete block */
+    memset(offset_len, 0, sizeof offset_len);
+    memset(literal_len, 0, sizeof literal_len);
+    sum = 0;
+    source = buf;
+    source_end = buf + compsize;
+    global_control = 0;
+    global_shift = -16;
+    last_offset = 1;
+    destination = dbuf;
+    while (unpsize > 0) {
+       uae_u8 *pdest = destination;
+       if (!read_literal_table()) {
+           int s;
+           destination_end = destination + decrunch_length;
+           decrunch();
+           s = destination - pdest;
+           unpsize -= s;
+           crc_calc (pdest, s);
+       } else {
+           write_log("LZX corrupt compressed data\n");
+           goto end;
+       }
+    }
+    /* pre-cache all files we just decompressed */
+    for (;;) {
+        if (znfirst->size && !znfirst->f) {
+           dstf = zfile_fopen_empty (znfirst->name, znfirst->size);
+           zfile_fwrite(dbuf + znfirst->offset2, znfirst->size, 1, dstf);
+           znfirst->f = dstf;
+       }
+       if (znfirst == znlast)
+           break;
+       znfirst = znfirst->next;
+    }
+end:
+    xfree(buf);
+    xfree(dbuf);
+    return zn->f;
+}
+
+struct zvolume *archive_directory_lzx (struct zfile *in_file)
+{
+ unsigned int temp;
+ unsigned int total_pack = 0;
+ unsigned int total_unpack = 0;
+ unsigned int total_files = 0;
+ unsigned int merge_size = 0;
+ int actual;
+ int abort;
+ int result = 1; /* assume an error */
+ struct zvolume *zv;
+ struct znode *zn;
+ struct zarchive_info zai;
+ struct tm tm;
+ unsigned int crc;
+ unsigned int pack_size;
+ unsigned int unpack_size;
+ unsigned char archive_header[31];
+ unsigned char header_filename[256];
+ unsigned char header_comment[256];
+
+ if (zfile_fread(archive_header, 1, 10, in_file) != 10)
+     return 0;
+ if (memcmp(archive_header, "LZX", 3))
+     return 0;
+ zv = zvolume_alloc(in_file, ArchiveFormatLZX, NULL);
+
+ do
+ {
+  abort = 1; /* assume an error */
+  actual = zfile_fread(archive_header, 1, 31, in_file);
+  if(!zfile_ferror(in_file))
+  {
+   if(actual) /* 0 is normal and means EOF */
+   {
+    if(actual == 31)
+    {
+     sum = 0; /* reset CRC */
+     crc = (archive_header[29] << 24) + (archive_header[28] << 16) + (archive_header[27] << 8) + archive_header[26];
+     archive_header[29] = 0; /* Must set the field to 0 before calculating the crc */
+     archive_header[28] = 0;
+     archive_header[27] = 0;
+     archive_header[26] = 0;
+     crc_calc(archive_header, 31);
+     temp = archive_header[30]; /* filename length */
+     actual = zfile_fread(header_filename, 1, temp, in_file);
+     if(!zfile_ferror(in_file))
+     {
+      if(actual == temp)
+      {
+       header_filename[temp] = 0;
+       crc_calc(header_filename, temp);
+       temp = archive_header[14]; /* comment length */
+       actual = zfile_fread(header_comment, 1, temp, in_file);
+       if(!zfile_ferror(in_file))
+       {
+        if(actual == temp)
+        {
+         header_comment[temp] = 0;
+         crc_calc(header_comment, temp);
+         if(sum == crc)
+         {
+         unsigned int year, month, day;
+         unsigned int hour, minute, second;
+         unsigned char attributes;
+          attributes = archive_header[0]; /* file protection modes */
+          unpack_size = (archive_header[5] << 24) + (archive_header[4] << 16) + (archive_header[3] << 8) + archive_header[2]; /* unpack size */
+          pack_size = (archive_header[9] << 24) + (archive_header[8] << 16) + (archive_header[7] << 8) + archive_header[6]; /* packed size */
+          temp = (archive_header[18] << 24) + (archive_header[19] << 16) + (archive_header[20] << 8) + archive_header[21]; /* date */
+          year = ((temp >> 17) & 63) + 1970;
+          month = (temp >> 23) & 15;
+          day = (temp >> 27) & 31;
+          hour = (temp >> 12) & 31;
+          minute = (temp >> 6) & 63;
+          second = temp & 63;
+
+         memset(&zai, 0, sizeof zai);
+         zai.name = header_filename;
+         if (header_comment[0])
+          zai.comment = header_comment;
+         zai.flags |= (attributes & 32) ? 0x80 : 0;
+         zai.flags |= (attributes & 64) ? 0x40 : 0;
+         zai.flags |= (attributes & 128) ? 0x20 : 0;
+         zai.flags |= (attributes & 16) ? 0x10 : 0;
+         zai.flags |= (attributes & 1) ? 0x08 : 0;
+         zai.flags |= (attributes & 2) ? 0x04 : 0;
+         zai.flags |= (attributes & 8) ? 0x02 : 0;
+         zai.flags |= (attributes & 4) ? 0x01 : 0;
+         zai.flags ^= 15;
+         memset(&tm, 0, sizeof tm);
+         tm.tm_hour = hour;
+         tm.tm_min  = minute;
+         tm.tm_sec  = second;
+         tm.tm_year = year - 1900;
+         tm.tm_mon  = month;
+         tm.tm_mday = day;
+         zai.t = mktime(&tm);
+         zai.size = unpack_size;
+         zn = zvolume_addfile_abs(zv, &zai);
+         zn->offset2 = merge_size;
+
+         //write_log("%d %d %d %s\n", unpack_size, merge_size, pack_size, zai.name);
+          total_pack += pack_size;
+          total_unpack += unpack_size;
+          total_files++;
+          merge_size += unpack_size;
+
+         if(pack_size) /* seek past the packed data */
+          {
+           merge_size = 0;
+          zn->offset = zfile_ftell(in_file);
+          zn->packedsize = pack_size;
+           if(!zfile_fseek(in_file, pack_size, SEEK_CUR))
+           {
+            abort = 0; /* continue */
+           }
+          }
+          else
+           abort = 0; /* continue */
+         }
+        }
+       }
+      }
+     }
+    }
+   }
+   else
+   {
+    result = 0; /* normal termination */
+   }
+  }
+ } while(!abort);
+
+ return zv;
+}
diff --git a/archivers/xfd/xfd.c b/archivers/xfd/xfd.c
new file mode 100755 (executable)
index 0000000..2d08dde
--- /dev/null
@@ -0,0 +1,415 @@
+ /*
+  * UAE - The Un*x Amiga Emulator
+  *
+  * Emulate very basic Amiga-like environment for XFD slaves
+  *
+  * All this only because there is no portable XFD replacement..
+  *
+  * (c) 2007 Toni Wilen
+  *
+  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+#include "zfile.h"
+#include "fsdb.h"
+#include "uae.h"
+#include "custom.h"
+#include "memory.h"
+#include "newcpu.h"
+
+/* memory structure
+ *
+ * 0x000676 execbase
+ * 0x000ffc current start of free memory
+ * 0x001000 allocmem code (exec)
+ * 0x001080 freemem code, dummy (exec)
+ * 0x001f00 XFD buffer info
+ * 0x002000 first XFD slave
+ * 0x?????? next XFD slave
+ * ....
+ * 0x?????? decrunched data
+ * 0x?????? free memory (available for slave)
+ * 0xxxf000 end of decompression buffer
+ * end      stack
+ */
+
+static uaecptr exec = 0x676;
+static uaecptr freememaddr = 0x0ffc;
+static uaecptr allocmem = 0x1000;
+static uaecptr freemem = 0x1080;
+static uaecptr bufferinfo = 0x1f00;
+static uaecptr stacksize = 0x1000;
+struct xfdslave
+{
+    struct xfdslave *next;
+    uaecptr start;
+    char *name;
+};
+
+static struct xfdslave *xfdslaves;
+
+#define FAKEMEM_SIZE 524288
+
+static uae_u32 gl(uae_u8 *p)
+{
+    uae_u32 v;
+
+    v = p[0] << 24;
+    v |= p[1] << 16;
+    v |= p[2] << 8;
+    v |= p[3] << 0;
+    return v;
+}
+static uae_u16 gw(uae_u8 *p)
+{
+    uae_u16 v;
+
+    v = p[0] << 8;
+    v |= p[1] << 0;
+    return v;
+}
+static void pl(uae_u8 *p, uae_u32 v)
+{
+    p[0] = v >> 24;
+    p[1] = v >> 16;
+    p[2] = v >> 8;
+    p[3] = v >> 0;
+}
+
+static uae_u8 *codeptr, *xfdmemory;
+static uaecptr codememory;
+static uae_u32 xfdmem_mask;
+
+static int load_xfd(char *path)
+{
+    struct zfile *z;
+    uae_u8 *buf, *p;
+    int size;
+    int first, last, numhunks;
+    int hunksize;
+    uae_u8 *prevhunk;
+    int i, j;
+    uaecptr hunks[10];
+    uaecptr startaddr;
+
+    z = zfile_fopen(path, "rb");
+    if (!z)
+       return 0;
+    zfile_fseek(z, 0, SEEK_END);
+    size = zfile_ftell(z);
+    zfile_fseek(z, 0, SEEK_SET);
+    buf = xmalloc(size);
+    zfile_fread(buf, size, 1, z);
+    zfile_fclose(z);
+    p = buf;
+    if (gl(p) != 0x3f3)
+       goto end;
+    p += 4 + 8;
+    first = gl(p);
+    p += 4;
+    last = gl(p);
+    p += 4;
+    numhunks = last - first + 1;
+    prevhunk = 0;
+    startaddr = codememory;
+
+    for (i = 0; i < numhunks; i++) {
+       uaecptr out = codememory;
+       hunksize = gl(p) * 4;
+       p += 4;
+       pl(codeptr + out, hunksize);
+       if (prevhunk) {
+           pl(prevhunk, out);
+           prevhunk = codeptr + out;
+       }
+       hunks[i] = out + 8;
+       codememory += hunksize + 8;
+    }
+    for (i = 0; i < numhunks; i++) {
+       uae_u32 htype = gl(p);
+       uae_u32 hsize = gl(p + 4) * 4;
+       uaecptr haddr = hunks[i];
+       uaecptr srchunk;
+       uae_u32 relocnum, relochunknum;
+
+       p += 8;
+       if (htype == 0x3e9 || htype == 0x3ea) {
+           memcpy (codeptr + haddr, p, hsize);
+           p += hsize;
+       } else if (htype != 0x3eb) {
+           write_log("RELOC: unknown hunk %08X\n", htype);
+           goto end;
+       }
+       htype = gl(p);
+       p += 4;
+       if (htype == 0x3f2)
+           continue;
+       if (htype != 0x3ec) {
+           write_log("RELOC: expected 000003EC but got %08X\n", htype);
+           goto end;
+       }
+       relocnum = gl(p);
+       p += 4;
+        relochunknum = gl(p);
+       p += 4;
+        srchunk = hunks[relochunknum];
+       for (j = 0; j < relocnum; j++) {
+           uae_u32 off = gl(p);
+           p += 4;
+           pl(codeptr + haddr + off, gl(codeptr + haddr + off) + srchunk);
+       }
+    }
+    write_log("XFD slave '%s' loaded and relocated @%08X (%d bytes) succesfully\n", path, startaddr, codememory - startaddr);
+    p = codeptr + startaddr + 8;
+    if (gl(p + 4) != 'XFDF') {
+       write_log("XFD header corrupt\n");
+       goto end;
+    }
+    p = codeptr + gl(p + 20);
+    for (;;) {
+       int version = gw(p + 4);
+       int mversion = gw(p + 6);
+       uaecptr name = gl(p + 8);
+       int flags = gw(p + 12);
+       int minsize = gl(p + 28);
+       uae_u8 *nameptr = codeptr + name;
+       struct xfdslave *xfds;
+
+       write_log("- '%s' ver %d, master ver %d, minsize %d\n",
+           nameptr, version, mversion, minsize);
+       xfds = xcalloc(sizeof(struct xfdslave), 1);
+       xfds->name = nameptr;
+       xfds->start = p - codeptr;
+       if (!xfdslaves) {
+           xfdslaves = xfds;
+       } else {
+           struct xfdslave *x = xfdslaves;
+           while(x->next)
+               x = x->next;
+           x->next = xfds;
+       }
+       if (!gl(p))
+           break;
+       p = codeptr + gl(p);
+    }
+    return 1;
+end:
+    return 0;
+}
+
+static void initexec(void)
+{
+    
+    pl(codeptr + 4, exec);
+
+    // fake memory allocation functions
+    pl(codeptr + exec - 198, allocmem);
+    pl(codeptr + exec - 210, freemem);
+
+    // lea -4(pc),a0
+    pl(codeptr + allocmem + 0, 0x41fafffa);
+    // move.l (a0),d1; add.l d0,(a0)
+    pl(codeptr + allocmem + 4, 0x2210d190);
+    // move.l d1,d0; rts
+    pl(codeptr + allocmem + 8, 0x20014e75);
+
+    pl(codeptr + freemem, 0x4e750000); // rts
+}
+
+int init_xfd(void)
+{
+    static int init;
+    char tmp[MAX_DPATH];
+    void *d;
+
+    if (init > 0)
+       return 1;
+    if (init < 0)
+       return 0;
+    init = -1;
+
+    codememory = 0x2000;
+    codeptr = malloc (FAKEMEM_SIZE);
+    sprintf (tmp, "%suae_data%cxfd", start_path_data, FSDB_DIR_SEPARATOR);
+    d = my_opendir(tmp);
+    if (d) {
+       while(my_readdir(d, tmp)) {
+           char tmp2[MAX_DPATH];
+           sprintf (tmp2, "%suae_data%cxfd%c%s", start_path_data, FSDB_DIR_SEPARATOR, FSDB_DIR_SEPARATOR, tmp);
+           load_xfd(tmp2);
+       }
+       my_closedir(d);
+    }
+    initexec();
+    codeptr = realloc(codeptr, codememory);
+    xfdmemory = malloc (FAKEMEM_SIZE);
+    init = 1;
+    return 1;
+}
+
+static void execute68k(struct regstruct *r)
+{
+    uaecptr stack = m68k_areg(r, 7);
+    m68k_areg(r, 7) = stack - 4;
+    for (;;) {
+       uae_u32 opcode = get_iword (r, 0);
+       (*cpufunctbl[opcode])(opcode, r);
+       if (m68k_areg(r, 7) >= stack)
+           break;
+    }
+}
+
+static struct zfile *decomp(struct zfile *zf, struct xfdslave *xfds, uae_u32 size, struct regstruct *regs)
+{
+    uae_u8 *p;
+    uae_u32 decompsize;
+    uaecptr decompaddr;
+    struct zfile *zfout;
+
+    p = xfdmemory + bufferinfo;
+    memset(p, 0, 20 * 4);
+    regs->regs[8] = bufferinfo; // A0
+    decompsize = gl (p + 16 * 4);
+    decompaddr = FAKEMEM_SIZE - stacksize - decompsize;
+    pl (p + 6 * 4, decompaddr); // TargetBuffer
+    pl (p + 8 * 4, decompsize);
+    execute68k(regs);
+    if (!regs->regs[0])
+       return 0;
+    decompsize = gl (p + 16 * 4);
+    zfout = zfile_fopen_empty (zfile_getname(zf), decompsize);
+    zfile_fwrite (xfdmemory + decompaddr, decompsize, 1, zf);
+    return zfout;
+}
+
+static struct regstruct backregs;
+static addrbank **back_mem_banks;
+
+
+static uae_u32 REGPARAM3 xfdmem_lget (uaecptr) REGPARAM;
+static uae_u32 REGPARAM3 xfdmem_wget (uaecptr) REGPARAM;
+static uae_u32 REGPARAM3 xfdmem_bget (uaecptr) REGPARAM;
+static void REGPARAM3 xfdmem_lput (uaecptr, uae_u32) REGPARAM;
+static void REGPARAM3 xfdmem_wput (uaecptr, uae_u32) REGPARAM;
+static void REGPARAM3 xfdmem_bput (uaecptr, uae_u32) REGPARAM;
+
+static uae_u32 REGPARAM2 xfdmem_lget (uaecptr addr)
+{
+    uae_u32 *m;
+    addr &= xfdmem_mask;
+    m = (uae_u32 *)(xfdmemory + addr);
+    return do_get_mem_long (m);
+}
+static uae_u32 REGPARAM2 xfdmem_wget (uaecptr addr)
+{
+    uae_u16 *m;
+    addr &= xfdmem_mask;
+    m = (uae_u16 *)(xfdmemory + addr);
+    return do_get_mem_word (m);
+}
+static uae_u32 REGPARAM2 xfdmem_bget (uaecptr addr)
+{
+    addr &= xfdmem_mask;
+    return xfdmemory[addr];
+}
+static void REGPARAM2 xfdmem_lput (uaecptr addr, uae_u32 l)
+{
+    uae_u32 *m;
+    addr &= xfdmem_mask;
+    m = (uae_u32 *)(xfdmemory + addr);
+    do_put_mem_long (m, l);
+}
+static void REGPARAM2 xfdmem_wput (uaecptr addr, uae_u32 w)
+{
+    uae_u16 *m;
+    addr &= xfdmem_mask;
+    m = (uae_u16 *)(xfdmemory + addr);
+    do_put_mem_word (m, w);
+}
+static void REGPARAM2 xfdmem_bput (uaecptr addr, uae_u32 b)
+{
+    addr &= xfdmem_mask;
+    xfdmemory[addr] = b;
+}
+static addrbank xfdmem_bank = {
+    xfdmem_lget, xfdmem_wget, xfdmem_bget,
+    xfdmem_lput, xfdmem_wput, xfdmem_bput,
+    NULL, NULL, NULL, "XFDFAKE",
+    xfdmem_lget, xfdmem_wget, ABFLAG_RAM
+};
+
+static void store_state(void)
+{
+    int i;
+
+    memcpy (&backregs, &regs, sizeof (struct regstruct));
+    back_mem_banks = xmalloc(MEMORY_BANKS * sizeof (addrbank*));
+    memcpy (back_mem_banks, mem_banks, MEMORY_BANKS * sizeof (addrbank*));
+    for (i = 0; i < MEMORY_BANKS; i++)
+       mem_banks[bankindex(i * 65536)] = &xfdmem_bank;
+}
+
+static void restore_state(void)
+{
+    memcpy (mem_banks, back_mem_banks, MEMORY_BANKS * sizeof (addrbank*));
+    xfree(back_mem_banks);
+    memcpy (&regs, &backregs, sizeof (struct regstruct));
+}
+
+struct zfile *decompress_zfd(struct zfile *z)
+{
+    unsigned int size;
+    uae_u8 *p;
+    struct xfdslave *xfds;
+    struct zfile *zfout = NULL;
+
+    if (!init_xfd())
+       return z;
+    memset (xfdmemory, 0, FAKEMEM_SIZE);
+    memcpy (xfdmemory, codeptr, codememory);
+    xfdmem_mask = FAKEMEM_SIZE - 1;
+
+    p = codeptr + codememory;
+    zfile_fseek (z, 0, SEEK_END);
+    size = zfile_ftell (z);
+    zfile_fseek (z, 0, SEEK_SET);
+    zfile_fread (p, size, 1, z);
+
+    store_state();
+
+    xfds = xfdslaves;
+    while (xfds) {
+       uaecptr start = xfds->start;
+       memset(&regs, 0, sizeof regs);
+       pl(codeptr + freememaddr, codememory + size); // reset start of "free memory" 
+       regs.regs[0] = size; // D0
+       regs.regs[8] = codememory; // A0
+       regs.regs[9] = bufferinfo; // A1
+       regs.regs[15] = FAKEMEM_SIZE; // A7
+       pl(xfdmemory + bufferinfo + 0x00, codememory); // SourceBuffer
+       pl(xfdmemory + bufferinfo + 0x04, size); // SourceBufLen
+       m68k_setpc(&regs, gl(xfdmemory + start + 16)); // recog code
+       if (regs.pc) {
+           execute68k(&regs);
+           if (regs.regs[0]) {
+               write_log("XFD slave '%s' recognised the compressed data\n", xfds->name);
+               m68k_setpc(&regs, gl(xfdmemory + start + 20)); // decomp code
+               if (regs.pc)
+                   zfout = decomp(z, xfds, size, &regs);
+               if (zfout)
+                   break;
+           }
+       }
+       xfds = xfds->next;
+    }
+
+    restore_state();
+
+    return zfout;
+}
diff --git a/archivers/xfd/xfdmaster.h b/archivers/xfd/xfdmaster.h
new file mode 100755 (executable)
index 0000000..61b5367
--- /dev/null
@@ -0,0 +1,504 @@
+#ifndef LIBRARIES_XFDMASTER_H
+#define LIBRARIES_XFDMASTER_H
+
+/*
+**     $VER: xfdmaster.h 39.5 (31.08.2002)
+**
+**     Copyright © 1994-2002 by Georg Hörmann, Dirk Stöcker
+**     All Rights Reserved.
+*/
+
+#ifndef EXEC_LIBRARIES_H
+#include <exec/libraries.h>
+#endif
+
+/*********************
+*                    *
+*    Library Base    *
+*                    *
+*********************/
+
+struct xfdMasterBase {
+  struct Library LibNode;
+  ULONG                        xfdm_SegList;      /* PRIVATE! */
+  struct DosLibrary *  xfdm_DosBase;      /* May be used for I/O etc. */
+  struct xfdSlave *    xfdm_FirstSlave;   /* List of available slaves */
+  struct xfdForeMan *  xfdm_FirstForeMan; /* PRIVATE! */
+  ULONG                        xfdm_MinBufferSize;/* (V36) Min. BufSize for xfdRecogBuffer() */
+  ULONG                        xfdm_MinLinkerSize;/* (V36) Min. BufSize for xfdRecogLinker() */
+  struct ExecBase *    xfdm_ExecBase;     /* (V38.2) Cached for fast access */
+};
+
+#define XFDM_VERSION   39              /* for OpenLibrary() */
+#define XFDM_NAME      "xfdmaster.library"
+
+/***************************
+*                          *
+*    Object Types (V36)    *
+*                          *
+***************************/
+
+#define XFDOBJ_BUFFERINFO      1       /* xfdBufferInfo structure */
+#define XFDOBJ_SEGMENTINFO     2       /* xfdSegmentInfo structure */
+#define XFDOBJ_LINKERINFO      3       /* xfdLinkerInfo structure */
+#define XFDOBJ_SCANNODE                4       /* (V37) xfdScanNode structure */
+#define XFDOBJ_SCANHOOK                5       /* (V37) xfdScanHook structure */
+#define XFDOBJ_MAX             5       /* PRIVATE! */
+
+/********************
+*                   *
+*    Buffer Info    *
+*                   *
+********************/
+
+struct xfdBufferInfo {
+  APTR            xfdbi_SourceBuffer;    /* Pointer to source buffer */
+  ULONG                   xfdbi_SourceBufLen;    /* Length of source buffer */
+  struct xfdSlave *xfdbi_Slave;                  /* PRIVATE! */
+  STRPTR          xfdbi_PackerName;      /* Name of recognized packer */
+  UWORD                   xfdbi_PackerFlags;     /* Flags for recognized packer */
+  UWORD                   xfdbi_Error;           /* Error return code */
+  APTR            xfdbi_TargetBuffer;    /* Pointer to target buffer */
+  ULONG                   xfdbi_TargetBufMemType;/* Memtype of target buffer */
+  ULONG                   xfdbi_TargetBufLen;    /* Full length of buffer */
+  ULONG                   xfdbi_TargetBufSaveLen;/* Used length of buffer */
+  ULONG                   xfdbi_DecrAddress;     /* Address to load decrunched file */
+  ULONG                   xfdbi_JmpAddress;      /* Address to jump in file */
+  APTR            xfdbi_Special;         /* Special decrunch info (eg. password) */
+  UWORD                   xfdbi_Flags;           /* (V37) Flags to influence recog/decr */
+  UWORD                   xfdbi_Reserved0;       /* (V38) PRIVATE! */
+  ULONG                   xfdbi_MinTargetLen;    /* (V38) Required length of target buffer */
+  ULONG                   xfdbi_FinalTargetLen;  /* (V38) Final length of decrunched file */
+  APTR            xfdbi_UserTargetBuf;   /* (V38) Target buffer allocated by user */
+  ULONG                   xfdbi_UserTargetBufLen;/* (V38) Target buffer length */
+  ULONG                   xfdbi_MinSourceLen;    /* (V39) minimum source length (tested by
+                                            master library */
+};
+
+#define xfdbi_MaxSpecialLen xfdbi_Error        /* Max. length of special info */
+
+/*********************
+*                    *
+*    Segment Info    *
+*                    *
+*********************/
+
+struct xfdSegmentInfo {
+  ULONG                   xfdsi_SegList;       /* BPTR to segment list */
+  struct xfdSlave *xfdsi_Slave;                /* PRIVATE! */
+  STRPTR          xfdsi_PackerName;    /* Name of recognized packer */
+  UWORD                   xfdsi_PackerFlags;   /* Flags for recognized packer */
+  UWORD                   xfdsi_Error;         /* Error return code */
+  APTR            xfdsi_Special;       /* Special decrunch info (eg. password) */
+  UWORD                   xfdsi_RelMode;       /* (V34) Relocation mode */
+  UWORD                   xfdsi_Flags;         /* (V37) Flags to influence recog/decr */
+};
+
+#define xfdsi_MaxSpecialLen xfdsi_Error        /* Max. length of special info */
+
+/**************************
+*                         *
+*    Linker Info (V36)    *
+*                         *
+**************************/
+
+struct xfdLinkerInfo {
+       APTR    xfdli_Buffer;           /* Pointer to buffer */
+       ULONG   xfdli_BufLen;           /* Length of buffer */
+       STRPTR  xfdli_LinkerName;       /* Name of recognized linker */
+       APTR    xfdli_Unlink;           /* PRIVATE! */
+       UWORD   xfdli_Reserved;         /* Set to NULL */
+       UWORD   xfdli_Error;            /* Error return code */
+       ULONG   xfdli_Hunk1;            /* PRIVATE! */
+       ULONG   xfdli_Hunk2;            /* PRIVATE! */
+       ULONG   xfdli_Amount1;          /* PRIVATE! */
+       ULONG   xfdli_Amount2;          /* PRIVATE! */
+       APTR    xfdli_Save1;            /* Pointer to first unlinked file */
+       APTR    xfdli_Save2;            /* Pointer to second unlinked file */
+       ULONG   xfdli_SaveLen1;         /* Length of first unlinked file */
+       ULONG   xfdli_SaveLen2;         /* Length of second unlinked file */
+};
+
+/************************
+*                       *
+*    Scan Node (V37)    *
+*                       *
+************************/
+
+struct xfdScanNode {
+  struct xfdScanNode *xfdsn_Next;      /* Pointer to next xfdScanNode or NULL */
+  APTR               xfdsn_Save;       /* Pointer to data */
+  ULONG                      xfdsn_SaveLen;    /* Length of data */
+  STRPTR             xfdsn_PackerName; /* Name of recognized packer */
+  UWORD                      xfdsn_PackerFlags;/* Flags for recognized packer */
+};
+
+/************************
+*                       *
+*    Scan Hook (V37)    *
+*                       *
+************************/
+
+struct xfdScanHook {
+  BOOL (* xfdsh_Entry)();      /* Entrypoint of hook code */
+  APTR    xfdsh_Data;          /* Private data of hook */
+  ULONG           xfdsh_ToDo;          /* Bytes still to scan (READ ONLY) */
+  ULONG           xfdsh_ScanNode;      /* Found data right now (or NULL) (READ ONLY) */
+};
+
+/********************
+*                   *
+*    Error Codes    *
+*                   *
+********************/
+
+#define XFDERR_OK              0x0000  /* No errors */
+
+#define XFDERR_NOMEMORY                0x0001  /* Error allocating memory */
+#define XFDERR_NOSLAVE         0x0002  /* No slave entry in info structure */
+#define XFDERR_NOTSUPPORTED    0x0003  /* Slave doesn't support called function */
+#define XFDERR_UNKNOWN         0x0004  /* Unknown file */
+#define XFDERR_NOSOURCE                0x0005  /* No sourcebuffer/seglist specified */
+#define XFDERR_WRONGPASSWORD   0x0006  /* Wrong password for decrunching */
+#define XFDERR_BADHUNK         0x0007  /* Bad hunk structure */
+#define XFDERR_CORRUPTEDDATA   0x0008  /* Crunched data is corrupted */
+#define XFDERR_MISSINGRESOURCE 0x0009  /* (V34) Missing resource (eg. library) */
+#define XFDERR_WRONGKEY                0x000a  /* (V35) Wrong 16/32 bit key */
+#define XFDERR_BETTERCPU       0x000b  /* (V37) Better CPU required */
+#define XFDERR_HOOKBREAK       0x000c  /* (V37) Hook caused break */
+#define XFDERR_DOSERROR                0x000d  /* (V37) Dos error */
+#define XFDERR_NOTARGET                0x000e  /* (V38) No user target given */
+#define XFDERR_TARGETTOOSMALL  0x000f  /* (V38) User target is too small */
+#define XFDERR_TARGETNOTSUPPORTED 0x0010 /* (V38) User target not supported */
+
+#define XFDERR_UNDEFINEDHUNK   0x1000  /* (V34) Undefined hunk type */
+#define XFDERR_NOHUNKHEADER    0x1001  /* (V34) File is not executable */
+#define XFDERR_BADEXTTYPE      0x1002  /* (V34) Bad hunk_ext type */
+#define XFDERR_BUFFERTRUNCATED 0x1003  /* (V34) Unexpected end of file */
+#define XFDERR_WRONGHUNKAMOUNT 0x1004  /* (V34) Wrong amount of hunks */
+#define XFDERR_NOOVERLAYS      0x1005  /* (V36) Overlays not allowed */
+
+#define XFDERR_UNSUPPORTEDHUNK 0x2000  /* (V34) Hunk type not supported */
+#define XFDERR_BADRELMODE      0x2001  /* (V34) Unknown XFDREL_#? mode */
+
+/*******************************
+*                              *
+*    Relocation Modes (V34)    *
+*                              *
+*******************************/
+
+#define XFDREL_DEFAULT         0x0000  /* Use memory types given by hunk_header */
+#define XFDREL_FORCECHIP       0x0001  /* Force all hunks to chip ram */
+#define XFDREL_FORCEFAST       0x0002  /* Force all hunks to fast ram */
+
+/*************************************
+*                                    *
+*    Values for xfd??_PackerFlags    *
+*                                    *
+*************************************/
+
+/* Bit numbers */
+#define XFDPFB_RELOC   0       /* Relocatible file packer */
+#define XFDPFB_ADDR    1       /* Absolute address file packer */
+#define XFDPFB_DATA    2       /* Data file packer */
+
+#define XFDPFB_PASSWORD        4       /* Packer requires password */
+#define XFDPFB_RELMODE 5       /* (V34) Decruncher supports xfdsi_RelMode */
+#define XFDPFB_KEY16   6       /* (V35) Packer requires 16 bit key */
+#define XFDPFB_KEY32   7       /* (V35) Packer requires 32 bit key */
+
+#define        XFDPFB_RECOGLEN 8       /* (V38) slave recognizes target lengths */
+#define        XFDPFB_USERTARGET 9     /* (V38) slave supports user target buffer */
+
+#define XFDPFB_EXTERN  15      /* (V37) PRIVATE */
+
+/* Bit masks */
+#define XFDPFF_RELOC   (1<<XFDPFB_RELOC)
+#define XFDPFF_ADDR    (1<<XFDPFB_ADDR)
+#define XFDPFF_DATA    (1<<XFDPFB_DATA)
+
+#define XFDPFF_PASSWORD        (1<<XFDPFB_PASSWORD)
+#define XFDPFF_RELMODE (1<<XFDPFB_RELMODE)
+#define XFDPFF_KEY16   (1<<XFDPFB_KEY16)
+#define XFDPFF_KEY32   (1<<XFDPFB_KEY32)
+
+#define XFDPFF_RECOGLEN        (1<<XFDPFB_RECOGLEN)
+#define XFDPFF_USERTARGET (1<<XFDPFB_USERTARGET)
+
+#define XFDPFF_EXTERN  (1<<XFDPFB_EXTERN)
+
+/************************************
+*                                   *
+*    Values for xfd??_Flags (V37)   *
+*                                   *
+************************************/
+
+/* Bit numbers */
+#define XFDFB_RECOGEXTERN      0       /* xfdRecog#?() uses external slaves */
+#define        XFDFB_RECOGTARGETLEN    1       /* (V38) xfdRecogBuffer() uses only slaves
+                                          that recognize target lengths */
+#define        XFDFB_RECOGUSERTARGET   2       /* (V38) xfdRecogBuffer() uses only slaves
+                                          that support user targets */
+#define        XFDFB_USERTARGET        3       /* (V38) xfdbi_DecrunchBuffer() decrunchs
+                                          to given xfdbi_UserTarget */
+#define XFDFB_MASTERALLOC      4       /* (V39) master allocated decrunch buffer */ 
+
+/* Bit masks */
+#define XFDFF_RECOGEXTERN      (1<<XFDFB_RECOGEXTERN)
+#define XFDFF_RECOGTARGETLEN   (1<<XFDFB_RECOGTARGETLEN)
+#define XFDFF_RECOGUSERTARGET  (1<<XFDFB_RECOGUSERTARGET)
+#define XFDFF_USERTARGET       (1<<XFDFB_USERTARGET)
+#define XFDFF_MASTERALLOC      (1<<XFDFB_MASTERALLOC)
+
+/****************************************************
+*                                                   *
+*    Flags for xfdTestHunkStructureFlags() (V36)    *
+*                                                   *
+****************************************************/
+
+/* Bit numbers */
+#define XFDTHB_NOOVERLAYS      0       /* Abort on hunk_overlay */
+
+/* Bit masks */
+#define XFDTHF_NOOVERLAYS      (1<<XFDTHB_NOOVERLAYS)
+
+/****************************************
+*                                       *
+*    Flags for xfdStripHunks() (V36)    *
+*                                       *
+****************************************/
+
+/* Bit numbers */
+#define XFDSHB_NAME    0       /* Strip hunk_name */
+#define XFDSHB_SYMBOL  1       /* Strip hunk_symbol */
+#define XFDSHB_DEBUG   2       /* Strip hunk_debug */
+
+/* Bit masks */
+#define XFDSHF_NAME    (1<<XFDSHB_NAME)
+#define XFDSHF_SYMBOL  (1<<XFDSHB_SYMBOL)
+#define XFDSHF_DEBUG   (1<<XFDSHB_DEBUG)
+
+/**************************************
+*                                     *
+*    Flags for xfdScanData() (V37)    *
+*                                     *
+**************************************/
+
+/* Bit numbers */
+#define XFDSDB_USEEXTERN 0     /* Use external slaves for scanning */
+#define XFDSDB_SCANODD 1       /* Scan at odd addresses too */
+
+/* Bit masks */
+#define XFDSDF_USEEXTERN (1<<XFDSDB_USEEXTERN)
+#define XFDSDF_SCANODD (1<<XFDSDB_SCANODD)
+
+/****************
+*               *
+*    Foreman    *
+*               *
+****************/
+
+struct xfdForeMan {
+  ULONG           xfdf_Security;       /* moveq #-1,d0 ; rts */
+  ULONG           xfdf_ID;             /* Set to XFDF_ID */
+  UWORD                   xfdf_Version;        /* Set to XFDF_VERSION */
+  UWORD           xfdf_Reserved;       /* Not used by now, set to NULL */
+  ULONG                   xfdf_Next;           /* PRIVATE! */
+  ULONG                   xfdf_SegList;        /* PRIVATE! */
+  struct xfdSlave *xfdf_FirstSlave;    /* First slave (see below) */
+};
+
+#define XFDF_ID                (('X'<<24)|('F'<<16)|('D'<<8)|('F'))
+#define XFDF_VERSION   1
+
+/**************
+*             *
+*    Slave    *
+*             *
+**************/
+
+struct xfdSlave {
+  struct xfdSlave *xfds_Next;          /* Next slave (or NULL) */
+  UWORD                   xfds_Version;        /* Set to XFDS_VERSION */
+  UWORD           xfds_MasterVersion;  /* Minimum XFDM_VERSION required */
+  STRPTR          xfds_PackerName;     /* Name of packer ('\0' terminated) */
+  UWORD           xfds_PackerFlags;    /* Flags for packer */
+  UWORD           xfds_MaxSpecialLen;  /* Max. length of special info (eg. password) */
+  BOOL         (* xfds_RecogBuffer)();    /* buffer recognition code (or NULL) */
+  BOOL         (* xfds_DecrunchBuffer)(); /* buffer decrunch code (or NULL) */
+  BOOL         (* xfds_RecogSegment)();   /* segment recognition code (or NULL) */
+  BOOL         (* xfds_DecrunchSegment)();/* segment decrunch code (or NULL) */
+  UWORD                   xfds_SlaveID;        /* (V36) Slave ID (only internal slaves) */
+  UWORD                   xfds_ReplaceID;      /* (V36) ID of slave to be replaced */
+  ULONG                   xfds_MinBufferSize;  /* (V36) Min. BufSize for RecogBufferXYZ() */
+};
+
+#define xfds_ScanData xfds_RecogSegment                /* (V37) XFDPFB_DATA: Scan code (or NULL) */
+#define xfds_VerifyData xfds_DecrunchSegment   /* (V37) XFDPFB_DATA: Verify code (or NULL) */
+
+#define XFDS_VERSION   2
+
+/*********************************************
+*                                            *
+*    Additional Recognition Results (V38)    *
+*                                            *
+*********************************************/
+
+struct xfdRecogResult {
+       ULONG   xfdrr_MinTargetLen;     /* Min. required length of target buffer */
+       ULONG   xfdrr_FinalTargetLen;   /* Final length of decrunched file */
+       ULONG   xfdrr_MinSourceLen;     /* (V39) minimum size of source file */
+};
+
+/*********************************
+*                                *
+*    Internal Slave IDs (V36)    *
+*                                *
+*********************************/
+
+#define XFDID_BASE     0x8000
+
+#define XFDID_PowerPacker23            (XFDID_BASE+0x0001)
+#define XFDID_PowerPacker30            (XFDID_BASE+0x0003)
+#define XFDID_PowerPacker30Enc         (XFDID_BASE+0x0005)
+#define XFDID_PowerPacker30Ovl         (XFDID_BASE+0x0007)
+#define XFDID_PowerPacker40            (XFDID_BASE+0x0009)
+#define XFDID_PowerPacker40Lib         (XFDID_BASE+0x000a)
+#define XFDID_PowerPacker40Enc         (XFDID_BASE+0x000b)
+#define XFDID_PowerPacker40LibEnc      (XFDID_BASE+0x000c)
+#define XFDID_PowerPacker40Ovl         (XFDID_BASE+0x000d)
+#define XFDID_PowerPacker40LibOvl      (XFDID_BASE+0x000e)
+#define XFDID_PowerPackerData          (XFDID_BASE+0x000f)
+#define XFDID_PowerPackerDataEnc       (XFDID_BASE+0x0010)
+#define XFDID_ByteKiller13             (XFDID_BASE+0x0011)
+#define XFDID_ByteKiller20             (XFDID_BASE+0x0012)
+#define XFDID_ByteKiller30             (XFDID_BASE+0x0013)
+#define XFDID_ByteKillerPro10          (XFDID_BASE+0x0014)
+#define XFDID_ByteKillerPro10Pro       (XFDID_BASE+0x0015)
+#define XFDID_DragPack10               (XFDID_BASE+0x0016)
+#define XFDID_TNMCruncher11            (XFDID_BASE+0x0017)
+#define XFDID_HQCCruncher20            (XFDID_BASE+0x0018)
+#define XFDID_RSICruncher14            (XFDID_BASE+0x0019)
+#define XFDID_ANCCruncher              (XFDID_BASE+0x001a)
+#define XFDID_ReloKit10                        (XFDID_BASE+0x001b)
+#define XFDID_HighPressureCruncher     (XFDID_BASE+0x001c)
+#define XFDID_STPackedSong             (XFDID_BASE+0x001d)
+#define XFDID_TSKCruncher              (XFDID_BASE+0x001e)
+#define XFDID_LightPack15              (XFDID_BASE+0x001f)
+#define XFDID_CrunchMaster10           (XFDID_BASE+0x0020)
+#define XFDID_HQCCompressor100         (XFDID_BASE+0x0021)
+#define XFDID_FlashSpeed10             (XFDID_BASE+0x0022)
+#define XFDID_CrunchManiaData          (XFDID_BASE+0x0023)
+#define XFDID_CrunchManiaDataEnc       (XFDID_BASE+0x0024)
+#define XFDID_CrunchManiaLib           (XFDID_BASE+0x0025)
+#define XFDID_CrunchManiaNormal                (XFDID_BASE+0x0026)
+#define XFDID_CrunchManiaSimple                (XFDID_BASE+0x0027)
+#define XFDID_CrunchManiaAddr          (XFDID_BASE+0x0028)
+#define XFDID_DefJamCruncher32         (XFDID_BASE+0x0029)
+#define XFDID_DefJamCruncher32Pro      (XFDID_BASE+0x002a)
+#define XFDID_TetraPack102             (XFDID_BASE+0x002b)
+#define XFDID_TetraPack11              (XFDID_BASE+0x002c)
+#define XFDID_TetraPack21              (XFDID_BASE+0x002d)
+#define XFDID_TetraPack21Pro           (XFDID_BASE+0x002e)
+#define XFDID_TetraPack22              (XFDID_BASE+0x002f)
+#define XFDID_TetraPack22Pro           (XFDID_BASE+0x0030)
+#define XFDID_DoubleAction10           (XFDID_BASE+0x0031)
+#define XFDID_DragPack252Data          (XFDID_BASE+0x0032)
+#define XFDID_DragPack252              (XFDID_BASE+0x0033)
+#define XFDID_FCG10                    (XFDID_BASE+0x0034)
+#define XFDID_Freeway07                        (XFDID_BASE+0x0035)
+#define XFDID_IAMPacker10ATM5Data      (XFDID_BASE+0x0036)
+#define XFDID_IAMPacker10ATM5          (XFDID_BASE+0x0037)
+#define XFDID_IAMPacker10ICEData       (XFDID_BASE+0x0038)
+#define XFDID_IAMPacker10ICE           (XFDID_BASE+0x0039)
+#define XFDID_Imploder                 (XFDID_BASE+0x003a)
+#define XFDID_ImploderLib              (XFDID_BASE+0x003b)
+#define XFDID_ImploderOvl              (XFDID_BASE+0x003c)
+#define XFDID_FileImploder             (XFDID_BASE+0x003d)
+#define XFDID_MasterCruncher30Addr     (XFDID_BASE+0x003f)
+#define XFDID_MasterCruncher30         (XFDID_BASE+0x0040)
+#define XFDID_MaxPacker12              (XFDID_BASE+0x0041)
+#define XFDID_PackIt10Data             (XFDID_BASE+0x0042)
+#define XFDID_PackIt10                 (XFDID_BASE+0x0043)
+#define XFDID_PMCNormal                        (XFDID_BASE+0x0044)
+#define XFDID_PMCSample                        (XFDID_BASE+0x0045)
+#define XFDID_XPKPacked                        (XFDID_BASE+0x0046)
+#define XFDID_XPKCrypted               (XFDID_BASE+0x0047)
+#define XFDID_TimeCruncher17           (XFDID_BASE+0x0048)
+#define XFDID_TFACruncher154           (XFDID_BASE+0x0049)
+#define XFDID_TurtleSmasher13          (XFDID_BASE+0x004a)
+#define XFDID_MegaCruncher10           (XFDID_BASE+0x004b)
+#define XFDID_MegaCruncher12           (XFDID_BASE+0x004c)
+#define XFDID_ProPack                  (XFDID_BASE+0x004d)
+#define XFDID_ProPackData              (XFDID_BASE+0x004e)
+#define XFDID_ProPackDataKey           (XFDID_BASE+0x004f)
+#define XFDID_STCruncher10             (XFDID_BASE+0x0050)
+#define XFDID_STCruncher10Data         (XFDID_BASE+0x0051)
+#define XFDID_SpikeCruncher            (XFDID_BASE+0x0052)
+#define XFDID_SyncroPacker46           (XFDID_BASE+0x0053)
+#define XFDID_SyncroPacker46Pro                (XFDID_BASE+0x0054)
+#define XFDID_TitanicsCruncher11       (XFDID_BASE+0x0055)
+#define XFDID_TitanicsCruncher12       (XFDID_BASE+0x0056)
+#define XFDID_TryItCruncher101         (XFDID_BASE+0x0057)
+#define XFDID_TurboSqueezer61          (XFDID_BASE+0x0058)
+#define XFDID_TurboSqueezer80          (XFDID_BASE+0x0059)
+#define XFDID_TurtleSmasher200         (XFDID_BASE+0x005a)
+#define XFDID_TurtleSmasher200Data     (XFDID_BASE+0x005b)
+#define XFDID_StoneCracker270          (XFDID_BASE+0x005c)
+#define XFDID_StoneCracker270Pro       (XFDID_BASE+0x005d)
+#define XFDID_StoneCracker292          (XFDID_BASE+0x005e)
+#define XFDID_StoneCracker299          (XFDID_BASE+0x005f)
+#define XFDID_StoneCracker299d         (XFDID_BASE+0x0060)
+#define XFDID_StoneCracker300          (XFDID_BASE+0x0061)
+#define XFDID_StoneCracker300Data      (XFDID_BASE+0x0062)
+#define XFDID_StoneCracker310          (XFDID_BASE+0x0063)
+#define XFDID_StoneCracker310Data      (XFDID_BASE+0x0064)
+#define XFDID_StoneCracker311          (XFDID_BASE+0x0065)
+#define XFDID_StoneCracker400          (XFDID_BASE+0x0066)
+#define XFDID_StoneCracker400Data      (XFDID_BASE+0x0067)
+#define XFDID_StoneCracker401          (XFDID_BASE+0x0068)
+#define XFDID_StoneCracker401Data      (XFDID_BASE+0x0069)
+#define XFDID_StoneCracker401Addr      (XFDID_BASE+0x006a)
+#define XFDID_StoneCracker401BetaAddr  (XFDID_BASE+0x006b)
+#define XFDID_StoneCracker403Data      (XFDID_BASE+0x006c)
+#define XFDID_StoneCracker404          (XFDID_BASE+0x006d)
+#define XFDID_StoneCracker404Data      (XFDID_BASE+0x006e)
+#define XFDID_StoneCracker404Addr      (XFDID_BASE+0x006f)
+#define XFDID_ChryseisCruncher09       (XFDID_BASE+0x0070)
+#define XFDID_QuickPowerPacker10       (XFDID_BASE+0x0071)
+#define XFDID_GNUPacker12              (XFDID_BASE+0x0072)
+#define XFDID_GNUPacker12Seg           (XFDID_BASE+0x0073)
+#define XFDID_GNUPacker12Data          (XFDID_BASE+0x0074)
+#define XFDID_TrashEliminator10                (XFDID_BASE+0x0075)
+#define XFDID_MasterCruncher30Data     (XFDID_BASE+0x0076)
+#define XFDID_SuperCruncher27          (XFDID_BASE+0x0077)
+#define XFDID_UltimatePacker11         (XFDID_BASE+0x0078)
+#define XFDID_ProPackOld               (XFDID_BASE+0x0079)
+#define XFDID_SACFPQCruncher           (XFDID_BASE+0x007a) /* disabled */
+#define XFDID_PowerPackerPatch10       (XFDID_BASE+0x007b)
+#define XFDID_CFP135                   (XFDID_BASE+0x007c)
+#define XFDID_BOND                     (XFDID_BASE+0x007d)
+#define XFDID_PowerPackerLoadSeg       (XFDID_BASE+0x007e)
+#define XFDID_StoneCracker299b         (XFDID_BASE+0x007f)
+#define XFDID_CrunchyDat10             (XFDID_BASE+0x0080)
+#define XFDID_PowerPacker20            (XFDID_BASE+0x0081)
+#define XFDID_StoneCracker403          (XFDID_BASE+0x0082)
+#define XFDID_PKProtector200           (XFDID_BASE+0x0083)
+#define XFDID_PPbk                     (XFDID_BASE+0x0084)
+#define XFDID_StoneCracker292Data      (XFDID_BASE+0x0085)
+#define XFDID_MegaCruncherObj          (XFDID_BASE+0x0086)
+#define XFDID_DeluxeCruncher1          (XFDID_BASE+0x0087)
+#define XFDID_DeluxeCruncher3          (XFDID_BASE+0x0088)
+#define XFDID_ByteKiller97             (XFDID_BASE+0x0089)
+#define XFDID_TurboSqueezer51          (XFDID_BASE+0x008A)
+#define XFDID_SubPacker10              (XFDID_BASE+0x008B)
+#define XFDID_StoneCracker404Lib       (XFDID_BASE+0x008C)
+#define XFDID_ISC_Pass1                        (XFDID_BASE+0x008D)
+#define XFDID_ISC_Pass2                        (XFDID_BASE+0x008E)
+#define XFDID_ISC_Pass3                        (XFDID_BASE+0x008F)
+#define XFDID_PCompressFALH            (XFDID_BASE+0x0090)
+#define XFDID_PCompressHILH            (XFDID_BASE+0x0091)
+#define XFDID_SMF                      (XFDID_BASE+0x0092)
+#define XFDID_DefJamCruncher32T                (XFDID_BASE+0x0093)
+
+#endif /* LIBRARIES_XFDMASTER_H */
similarity index 99%
rename from unzip.c
rename to archivers/zip/unzip.c
index fae371154af08123f09fa92c247de30632f78b02..7f874394959d9d1541e33c5136196e87fb9cc6d4 100755 (executable)
--- a/unzip.c
@@ -442,7 +442,6 @@ extern int ZEXPORT unzClose (file)
     if (s->pfile_in_zip_read!=NULL)
        unzCloseCurrentFile(file);
 
-       zfile_fclose(s->file);
        TRYFREE(s);
        return UNZ_OK;
 }
similarity index 100%
rename from include/unzip.h
rename to archivers/zip/unzip.h
diff --git a/audio.c b/audio.c
index 99782fda46279db02c3e69e62edb894a04839178..055f707e49217506afbc4b91af15c3650d8c9e0f 100755 (executable)
--- a/audio.c
+++ b/audio.c
@@ -233,7 +233,7 @@ static void do_samplerip(struct audio_channel_data *adp)
            /* replace old identical but shorter sample */
            if (len > rs->len && !memcmp(rs->sample, smp, rs->len)) {
                xfree(rs->sample);
-               rs->sample = xmalloc(len);
+               rs->sample = (uae_u8*)xmalloc(len);
                memcpy(rs->sample, smp, len);
                write_log("SAMPLERIPPER: replaced sample %d (%d -> %d)\n", cnt, rs->len, len);
                rs->len = len;
@@ -249,14 +249,14 @@ static void do_samplerip(struct audio_channel_data *adp)
     }
     if (rs || cnt > 100)
        return;
-    rs = xmalloc(sizeof(struct ripped_sample));
+    rs = (struct ripped_sample*)xmalloc(sizeof(struct ripped_sample));
     if (prev)
        prev->next = rs;
     else
        ripped_samples = rs;
     rs->len = len;
     rs->per = adp->per / CYCLE_UNIT;
-    rs->sample = xmalloc(len);
+    rs->sample = (uae_u8*)xmalloc(len);
     memcpy(rs->sample, smp, len);
     rs->next = NULL;
     rs->changed = 1;
@@ -1796,7 +1796,7 @@ uae_u8 *save_audio (int i, int *len, uae_u8 *dstptr)
     if (dstptr)
        dstbak = dst = dstptr;
     else
-       dstbak = dst = malloc (100);
+       dstbak = dst = (uae_u8*)malloc (100);
     acd = audio_channel + i;
     save_u8 ((uae_u8)acd->state);
     save_u8 (acd->vol);
index b943c8e5c8c77b56413b991ade405b8384a3dc7e..771c16b5baba9ec804fa3011000bec8d04d9d4ff 100755 (executable)
--- a/blitter.c
+++ b/blitter.c
@@ -1194,7 +1194,7 @@ uae_u8 *save_blitter (int *len, uae_u8 *dstptr)
     if (dstptr)
        dstbak = dst = dstptr;
     else
-       dstbak = dst = malloc (16);
+       dstbak = dst = (uae_u8*)malloc (16);
     save_u32(((bltstate != BLT_done) ? 0 : 1) | forced);
     *len = dst - dstbak;
     return dstbak;
index 50a4922a03e8986415a7eb67d27f73fb67787456..7385730f267a3a908a124400d9c24a2ba706b8b3 100755 (executable)
--- a/blkdev.c
+++ b/blkdev.c
@@ -85,7 +85,7 @@ int device_func_init (int flags)
 
 static int audiostatus (int unitnum)
 {
-    uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,DEVICE_SCSI_BUFSIZE>>8,DEVICE_SCSI_BUFSIZE&0xff,0};
+    uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,(uae_u8)(DEVICE_SCSI_BUFSIZE>>8),(uae_u8)(DEVICE_SCSI_BUFSIZE&0xff),0};
     uae_u8 *p = device_func[DF_SCSI]->exec_in (unitnum, cmd, sizeof (cmd), 0);
     if (!p)
        return 0;
@@ -154,7 +154,7 @@ int sys_command_cd_play (int mode, int unitnum,uae_u32 startmsf, uae_u32 endmsf,
 uae_u8 *sys_command_cd_qcode (int mode, int unitnum)
 {
     if (mode == DF_SCSI || !have_ioctl) {
-       uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,DEVICE_SCSI_BUFSIZE>>8,DEVICE_SCSI_BUFSIZE&0xff,0};
+       uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,(uae_u8)(DEVICE_SCSI_BUFSIZE>>8),(uae_u8)(DEVICE_SCSI_BUFSIZE&0xff),0};
        return  device_func[DF_SCSI]->exec_in (unitnum, cmd, sizeof (cmd), 0);
     }
     return device_func[DF_IOCTL]->qcode (unitnum);
@@ -164,7 +164,7 @@ uae_u8 *sys_command_cd_qcode (int mode, int unitnum)
 uae_u8 *sys_command_cd_toc (int mode, int unitnum)
 {
     if (mode == DF_SCSI || !have_ioctl) {
-       uae_u8 cmd [10] = { 0x43,0,2,0,0,0,1,DEVICE_SCSI_BUFSIZE>>8,DEVICE_SCSI_BUFSIZE&0xFF,0};
+       uae_u8 cmd [10] = { 0x43,0,2,0,0,0,1,(uae_u8)(DEVICE_SCSI_BUFSIZE>>8),(uae_u8)(DEVICE_SCSI_BUFSIZE&0xff),0};
        return device_func[DF_SCSI]->exec_in (unitnum, cmd, sizeof(cmd), 0);
     }
     return device_func[DF_IOCTL]->toc (unitnum);
@@ -279,7 +279,7 @@ void scsi_atapi_fixup_pre (uae_u8 *scsi_cmd, int *len, uae_u8 **datap, int *data
        scsi_cmd[9] = scsi_cmd[5];
        scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[4] = scsi_cmd[5] = scsi_cmd[6] = 0;
        *len = 10;
-       p = xmalloc (8 + datalen + 4);
+       p = (uae_u8*)xmalloc (8 + datalen + 4);
        if (datalen > 4)
            memcpy (p + 8, data + 4, datalen - 4);
        p[0] = 0;
@@ -298,7 +298,7 @@ void scsi_atapi_fixup_pre (uae_u8 *scsi_cmd, int *len, uae_u8 **datap, int *data
        scsi_cmd[3] = scsi_cmd[4] = scsi_cmd[5] = scsi_cmd[6] = 0;
        if (l > 8)
            datalen += 4;
-       *datap = xmalloc (datalen);
+       *datap = (uae_u8*)xmalloc (datalen);
        *len = 10;
        *parm = MODE_SENSE_10;
     }
index 56740d7ec68354ff947622cb719a23619fd1a26d..16060627d3d08e040c99855a683bdf2f34b0a505 100755 (executable)
@@ -364,7 +364,7 @@ static struct socketbase *alloc_socketbase (TrapContext *context)
     SB;
     int i;
 
-    if ((sb = calloc (sizeof (struct socketbase), 1)) != NULL) {
+    if ((sb = (struct socketbase*)calloc (sizeof (struct socketbase), 1)) != NULL) {
        sb->ownertask = gettask (context);
 
        m68k_dreg (&context->regs, 0) = -1;
@@ -380,8 +380,8 @@ static struct socketbase *alloc_socketbase (TrapContext *context)
 
        sb->dtablesize = DEFAULT_DTABLE_SIZE;
        /* @@@ check malloc() result */
-       sb->dtable = malloc (sb->dtablesize * sizeof (*sb->dtable));
-       sb->ftable = malloc (sb->dtablesize * sizeof (*sb->ftable));
+       sb->dtable = (SOCKET*)malloc (sb->dtablesize * sizeof (*sb->dtable));
+       sb->ftable = (int*)malloc (sb->dtablesize * sizeof (*sb->ftable));
 
        for (i = sb->dtablesize; i--;)
            sb->dtable[i] = -1;
@@ -407,7 +407,7 @@ static struct socketbase *alloc_socketbase (TrapContext *context)
 
 STATIC_INLINE struct socketbase *get_socketbase (TrapContext *context)
 {
-    return get_pointer (m68k_areg (&context->regs, 6) + offsetof (struct UAEBSDBase, sb));
+    return (struct socketbase*)get_pointer (m68k_areg (&context->regs, 6) + offsetof (struct UAEBSDBase, sb));
 }
 
 static void free_socketbase (TrapContext *context)
@@ -707,7 +707,7 @@ static uae_u32 bsdsocklib_SetDTableSize (SB, int newSize)
     sb->dtablesize = newSize;
     free(sb->dtable);
     free(sb->ftable);
-    sb->dtable = newdtable;
+    sb->dtable = (SOCKET*)newdtable;
     sb->ftable = newftable;
     sb->resultval = 0;
     return 0;
@@ -1488,7 +1488,7 @@ void bsdlib_install (void)
     int i;
 
     if (!sockdata) {
-       sockdata = xcalloc (sizeof (struct sockd), 1);
+       sockdata = (struct sockd*)xcalloc (sizeof (struct sockd), 1);
         for (i = 0; i < SOCKPOOLSIZE; i++)
            sockdata->sockpoolids[i] = UNIQUE_ID;
     }
index 2bb7e19292173be754dbc233c67e868d9e8a337a..d7a1fbc720e3d84b426f05d45dff9a823d24c1f9 100755 (executable)
@@ -481,7 +481,7 @@ static int direct_detect(void)
                    prevResDes = resDes;
                    if(CM_Get_Res_Des_Data_Size_Ex(&dataSize,resDes,0,NULL)!=CR_SUCCESS)
                        continue;
-                   resDesData = malloc (dataSize);
+                   resDesData = (PBYTE)malloc (dataSize);
                    if(!resDesData)
                        continue;
                    if(CM_Get_Res_Des_Data_Ex(resDes,resDesData,dataSize,0,NULL)!=CR_SUCCESS) {
diff --git a/cdtv.c b/cdtv.c
index 3d923097a4308cb36fb8732147765f60504f7230..c2d8ad8c4827458bc43dd1ee602db2d59bf124f2 100755 (executable)
--- a/cdtv.c
+++ b/cdtv.c
@@ -9,8 +9,8 @@
   *
   */
 
-//#define CDTV_DEBUG
-//#define CDTV_DEBUG_CMD
+#define CDTV_DEBUG
+#define CDTV_DEBUG_CMD
 //#define CDTV_DEBUG_6525
 
 #include "sysconfig.h"
@@ -27,6 +27,7 @@
 #include "zfile.h"
 #include "threaddep/thread.h"
 #include "a2091.h"
+#include "uae.h"
 
 
 /* DMAC CNTR bits. */
@@ -795,7 +796,7 @@ static void dmac_start_dma(void)
     }
 }
 
-void cdtv_getdmadata(int *acr)
+void cdtv_getdmadata(uae_u32 *acr)
 {
     *acr = dmac_acr;
 }
index f87a4f540712d060fc4fa17e2932ed7a363ed9b8..1d897fac578d90f6d1bd0e1033f53f1243638096 100755 (executable)
--- a/cfgfile.c
+++ b/cfgfile.c
@@ -179,7 +179,7 @@ char *cfgfile_subst_path (const char *path, const char *subst, const char *file)
     /* @@@ use strcasecmp for some targets.  */
     if (strlen (path) > 0 && strncmp (file, path, strlen (path)) == 0) {
        int l;
-       char *p = xmalloc (strlen (file) + strlen (subst) + 2);
+       char *p = (char*)xmalloc (strlen (file) + strlen (subst) + 2);
        strcpy (p, subst);
        l = strlen (p);
        while (l > 0 && p[l - 1] == '/')
@@ -1055,7 +1055,7 @@ static void decode_rom_ident (char *romfile, int maxlen, char *ident)
 
     if (!ident[0])
        return;
-    romtxt = malloc (10000);
+    romtxt = (char*)malloc (10000);
     romtxt[0] = 0;
     for (round = 0; round < 2; round++) {
        ver = rev = subver = subrev = -1;
@@ -1124,6 +1124,8 @@ int add_filesys_config (struct uae_prefs *p, int index,
                        int secspertrack, int surfaces, int reserved,
                        int blocksize, int bootpri, char *filesysdir, int hdc, int flags) {
     struct uaedev_config_info *uci;
+    int i;
+
     if (index < 0)
        uci = getuci(p);
     else
@@ -1144,7 +1146,19 @@ int add_filesys_config (struct uae_prefs *p, int index,
     uci->controller = hdc;
     strcpy (uci->filesys, filesysdir ? filesysdir : "");
     if (!uci->devname[0])
-       sprintf(uci->devname,"DH%d", uci - &p->mountconfig[0]);
+       sprintf(uci->devname, "DH%d", uci - &p->mountconfig[0]);
+    if (volname && !uci->volname[0]) {
+       for (i = strlen(rootdir) - 1; i >= 0; i--) {
+           char c = rootdir[i];
+           if (c == ':' || c == '/' || c == '\\') {
+               if (i == strlen(rootdir) - 1)
+                   continue;
+               i++;
+               break;
+           }
+       }
+       strcpy (uci->volname, rootdir + i);
+    }
     return 1;
 }
 
@@ -1595,7 +1609,7 @@ static void cfgfile_parse_separated_line (struct uae_prefs *p, char *line1b, cha
            if (sl->option && !strcasecmp (line1b, sl->option)) break;
        }
        if (!sl) {
-           struct strlist *u = xcalloc (sizeof (struct strlist), 1);
+           struct strlist *u = (struct strlist*)xcalloc (sizeof (struct strlist), 1);
            u->option = my_strdup(line3b);
            u->value = my_strdup(line4b);
            u->next = p->all_lines;
@@ -1801,7 +1815,7 @@ int cfgfile_save (struct uae_prefs *p, const char *filename, int type)
 int cfgfile_get_description (const char *filename, char *description, char *hostlink, char *hardwarelink, int *type)
 {
     int result = 0;
-    struct uae_prefs *p = xmalloc (sizeof (struct uae_prefs));
+    struct uae_prefs *p = (struct uae_prefs*)xmalloc (sizeof (struct uae_prefs));
     p->description[0] = 0;
     p->config_host_path[0] = 0;
     p->config_hardware_path[0] = 0;
@@ -2055,7 +2069,7 @@ static void parse_cpu_specs (struct uae_prefs *p, char *spec)
 /* Returns the number of args used up (0 or 1).  */
 int parse_cmdline_option (struct uae_prefs *p, char c, char *arg)
 {
-    struct strlist *u = xcalloc (sizeof (struct strlist), 1);
+    struct strlist *u = (struct strlist*)xcalloc (sizeof (struct strlist), 1);
     const char arg_required[] = "0123rKpImWSAJwNCZUFcblOdHRv";
 
     if (strchr (arg_required, c) && ! arg) {
@@ -2063,7 +2077,7 @@ int parse_cmdline_option (struct uae_prefs *p, char c, char *arg)
        return 0;
     }
 
-    u->option = malloc (2);
+    u->option = (char*)malloc (2);
     u->option[0] = c;
     u->option[1] = 0;
     u->value = my_strdup(arg);
@@ -2196,7 +2210,7 @@ void cfgfile_addcfgparam (char *line)
     }
     if (!cfgfile_separate_line (line, line1b, line2b))
        return;
-    u = xcalloc (sizeof (struct strlist), 1);
+    u = (struct strlist*)xcalloc (sizeof (struct strlist), 1);
     u->option = my_strdup(line1b);
     u->value = my_strdup(line2b);
     u->next = temp_lines;
@@ -2479,12 +2493,12 @@ uae_u32 cfgfile_uaelib_modify (uae_u32 index, uae_u32 parms, uae_u32 size, uae_u
     int i, ret;
 
     put_byte (out, 0);
-    parms_p = xmalloc (size + 1);
+    parms_p = (char*)xmalloc (size + 1);
     if (!parms_p) {
        ret = 10;
        goto end;
     }
-    out_p = xmalloc (outsize + 1);
+    out_p = (char*)xmalloc (outsize + 1);
     if (!out_p) {
        ret = 10;
        goto end;
@@ -3083,13 +3097,17 @@ static int bip_cd32 (struct uae_prefs *p, int config, int compa, int romcheck)
     int roms[2];
 
     buildin_default_prefs_68020 (p);
-    roms[0] = 18;
+    roms[0] = 64;
     roms[1] = -1;
-    if (!configure_rom (p, roms, romcheck))
-       return 0;
-    roms[0] = 19;
-    if (!configure_rom (p, roms, romcheck))
-       return 0;
+    if (!configure_rom (p, roms, 0)) {
+       roms[0] = 18;
+       roms[1] = -1;
+       if (!configure_rom (p, roms, romcheck))
+           return 0;
+       roms[0] = 19;
+       if (!configure_rom (p, roms, romcheck))
+           return 0;
+    }
     p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = 1;
     p->nr_floppies = 0;
     p->dfxtype[0] = DRV_NONE;
diff --git a/cia.c b/cia.c
index 3276640c27e690089590baf24f6274aa01581f10..d1834e3d51d26a539b07d249bcbfc8f4003a6f38 100755 (executable)
--- a/cia.c
+++ b/cia.c
@@ -1232,10 +1232,12 @@ static uae_u8 rtc_memory[13], rtc_alarm[13];
 void rtc_hardreset(void)
 {
     if (currprefs.cs_rtc == 1) { /* MSM6242B */
+       clock_bank.name = "Battery backed up clock (MSM6242B)";
        clock_control_d = 0x1;
        clock_control_e = 0;
        clock_control_f = 0x4; /* 24/12 */
     } else if (currprefs.cs_rtc == 2) { /* RF5C01A */
+       clock_bank.name = "Battery backed up clock (RF5C01A)";
        clock_control_d = 0x4; /* Timer EN */
        clock_control_e = 0;
        clock_control_f = 0;
@@ -1463,7 +1465,7 @@ uae_u8 *save_cia (int num, int *len, uae_u8 *dstptr)
     if (dstptr)
        dstbak = dst = dstptr;
     else
-       dstbak = dst = malloc (16 + 12 + 1 + 1);
+       dstbak = dst = (uae_u8*)malloc (16 + 12 + 1 + 1);
 
     compute_passed_time ();
 
index 2983faee93ae68fedc7d72a15a49a5d291162604..456277e8b3980326493a16d42180705e6d63e97b 100755 (executable)
@@ -49,7 +49,7 @@ static const uae_u16 x86_fpucw[]={
 static const int sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 };
 static const int sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 };
 
-static const struct {
+static struct {
        double b[2];
        double w[2];
        double l[2];
@@ -695,6 +695,7 @@ extern float  fp_1e1, fp_1e2, fp_1e4;
 
 void comp_fpp_opp (uae_u32 opcode, uae_u16 extra)
 {
+    int reg;
     int sreg, prec = 0;
     int        dreg = (extra >> 7) & 7;
     int source = (extra >> 13) & 7;
@@ -766,6 +767,157 @@ void comp_fpp_opp (uae_u32 opcode, uae_u16 extra)
        }
        FAIL(1);
        return;
+     case 6:
+     case 7: 
+       {
+           uae_u32 list = 0;
+           int incr = 0;
+           if (extra & 0x2000) {
+               uae_u32 ad;
+
+               /* FMOVEM FPP->memory */
+               switch ((extra >> 11) & 3) { /* Get out early if failure */
+                case 0:
+                case 2:
+                   break;
+                case 1:
+                case 3: 
+                default:
+                   FAIL(1); return;
+               }
+               ad=comp_fp_adr (opcode);
+               if (ad<0) {
+                   m68k_setpc (&regs, m68k_getpc (&regs) - 4);
+                   op_illg (opcode, &regs);
+                   return;
+               }
+               switch ((extra >> 11) & 3) {
+               case 0: /* static pred */
+                   list = extra & 0xff;
+                   incr = -1;
+                   break;
+               case 2: /* static postinc */
+                   list = extra & 0xff;
+                   incr = 1;
+                   break;
+               case 1: /* dynamic pred */
+               case 3: /* dynamic postinc */
+                  abort();
+               }
+               if (incr < 0) { /* Predecrement */
+                       for (reg = 7; reg >= 0; reg--) {
+                               if (list & 0x80) {
+                                       fmov_ext_mr((uintptr)temp_fp,reg);
+                                       sub_l_ri(ad,4); 
+                                       mov_l_rm(S2,(uintptr)temp_fp);
+                                       writelong_clobber(ad,S2,S3);
+                                       sub_l_ri(ad,4); 
+                                       mov_l_rm(S2,(uintptr)temp_fp+4);
+                                       writelong_clobber(ad,S2,S3);
+                                       sub_l_ri(ad,4); 
+                                       mov_w_rm(S2,(uintptr)temp_fp+8);
+                                       writeword_clobber(ad,S2,S3);
+                               }
+                               list <<= 1;
+                       }
+               }
+               else { /* Postincrement */
+                       for (reg = 0; reg <= 7; reg++) {
+                               if (list & 0x80) {
+                                       fmov_ext_mr((uintptr)temp_fp,reg);
+                                       mov_w_rm(S2,(uintptr)temp_fp+8);
+                                       writeword_clobber(ad,S2,S3);
+                                       add_l_ri(ad,4);
+                                       mov_l_rm(S2,(uintptr)temp_fp+4);
+                                       writelong_clobber(ad,S2,S3);
+                                       add_l_ri(ad,4);
+                                       mov_l_rm(S2,(uintptr)temp_fp);
+                                       writelong_clobber(ad,S2,S3);
+                                       add_l_ri(ad,4);
+                               }
+                               list <<= 1;
+                       }
+               }
+               if ((opcode & 0x38) == 0x18)
+                   mov_l_rr((opcode & 7)+8,ad);
+               if ((opcode & 0x38) == 0x20)
+                   mov_l_rr((opcode & 7)+8,ad);
+           } else {
+               /* FMOVEM memory->FPP */
+
+               uae_u32 ad;
+               switch ((extra >> 11) & 3) { /* Get out early if failure */
+                case 0:
+                case 2:
+                   break;
+                case 1:
+                case 3: 
+                default:
+                   FAIL(1); return;
+               }
+               ad=comp_fp_adr (opcode);
+               if (ad<0) {
+                   m68k_setpc (&regs, m68k_getpc (&regs) - 4);
+                   op_illg (opcode, &regs);
+                   return;
+               }
+               switch ((extra >> 11) & 3) {
+               case 0: /* static pred */
+                   list = extra & 0xff;
+                   incr = -1;
+                   break;
+               case 2: /* static postinc */
+                   list = extra & 0xff;
+                   incr = 1;
+                   break;
+               case 1: /* dynamic pred */
+               case 3: /* dynamic postinc */
+                  abort();
+               }
+
+               if (incr < 0) {
+                       // not reached
+                       for (reg = 7; reg >= 0; reg--) {
+                               if (list & 0x80) {
+                                       sub_l_ri(ad,4);
+                                       readlong(ad,S2,S3);
+                                       mov_l_mr((uintptr)(temp_fp),S2);
+                                       sub_l_ri(ad,4);
+                                       readlong(ad,S2,S3);
+                                       mov_l_mr((uintptr)(temp_fp)+4,S2);
+                                       sub_l_ri(ad,4);
+                                       readword(ad,S2,S3);
+                                       mov_w_mr(((uintptr)temp_fp)+8,S2);
+                                       fmov_ext_rm(reg,(uintptr)(temp_fp));
+                               }
+                               list <<= 1;
+                       }
+               }
+               else {
+                       for (reg = 0; reg <= 7; reg++) {
+                               if (list & 0x80) {
+                                       readword(ad,S2,S3);
+                                       mov_w_mr(((uintptr)temp_fp)+8,S2);
+                                       add_l_ri(ad,4);
+                                       readlong(ad,S2,S3);
+                                       mov_l_mr((uintptr)(temp_fp)+4,S2);
+                                       add_l_ri(ad,4);
+                                       readlong(ad,S2,S3);
+                                       mov_l_mr((uintptr)(temp_fp),S2);
+                                       add_l_ri(ad,4);
+                                       fmov_ext_rm(reg,(uintptr)(temp_fp));
+                               }
+                               list <<= 1;
+                       }
+               }
+               if ((opcode & 0x38) == 0x18)
+                   mov_l_rr((opcode & 7)+8,ad);
+               if ((opcode & 0x38) == 0x20)
+                   mov_l_rr((opcode & 7)+8,ad);
+           }
+       }
+       return;
+#if 0
      case 6: /* FMOVEM  <EA>, FPx-FPz */
        if (!(extra & 0x0800)) {
            uae_u32 list = extra & 0xff;
@@ -839,6 +991,7 @@ void comp_fpp_opp (uae_u32 opcode, uae_u16 extra)
        write_log ("fallback from JIT FMOVEM dynamic register list\n");
        FAIL(1);
        return;
+#endif
      case 2: /* from <EA> to FPx */
        dont_care_fflags();
        if ((extra & 0xfc00) == 0x5c00) { /* FMOVECR */
index 85ddfb29fb2954aeaf7cca72b303e44531362907..36a3a60e081e20eff5338edcbd2b23ee40a19f39 100755 (executable)
@@ -423,9 +423,10 @@ STATIC_INLINE void alloc_blockinfos(void)
  ********************************************************************/
 extern int have_done_picasso;
 
-void check_prefs_changed_comp (void)
+int check_prefs_changed_comp (void)
 {
-    static int cachesize_prev, comptrust_prev, compforce_prev;
+    int changed = 0;
+    static int cachesize_prev, comptrust_prev, compforce_prev, canbang_prev;
 
     currprefs.comptrustbyte = changed_prefs.comptrustbyte;
     currprefs.comptrustword = changed_prefs.comptrustword;
@@ -445,13 +446,16 @@ void check_prefs_changed_comp (void)
            changed_prefs.comptrustlong = currprefs.comptrustlong = comptrust_prev;
            changed_prefs.comptrustnaddr = currprefs.comptrustnaddr = comptrust_prev;
            changed_prefs.compforcesettings = currprefs.compforcesettings = compforce_prev;
+           canbang = canbang_prev;
        } else if (currprefs.cachesize && changed_prefs.cachesize == 0) {
            comptrust_prev = currprefs.comptrustbyte;
            compforce_prev = currprefs.compforcesettings;
            cachesize_prev = currprefs.cachesize;
+           canbang_prev = canbang;
        }
        currprefs.cachesize = changed_prefs.cachesize;
        alloc_cache();
+       changed = 1;
     }
 
     // Turn off illegal-mem logging when using JIT...
@@ -478,6 +482,8 @@ void check_prefs_changed_comp (void)
        changed_prefs.comptrustnaddr= 1;
        changed_prefs.compforcesettings = 1;
 
+       changed = 1;
+
        if(currprefs.cachesize)
        {
            write_log( "JIT: Reverting to \"indirect\" access, because canbang is zero!\n" );
@@ -516,6 +522,7 @@ void check_prefs_changed_comp (void)
        }
 #endif
     }
+    return changed;
 }
 
 /********************************************************************
diff --git a/crc32.c b/crc32.c
index 61c8878eb7b790022179afefd5bd2042fb6a236a..fbf94080740f2fe78b89c74a43e593af4dd4f6fa 100755 (executable)
--- a/crc32.c
+++ b/crc32.c
@@ -2,6 +2,8 @@
 #include "sysconfig.h"
 #include "sysdeps.h"
 
+#include "crc32.h"
+
 static unsigned long crc_table32[256];
 static unsigned short crc_table16[256];
 static void make_crc_table()
@@ -39,4 +41,305 @@ uae_u16 get_crc16( uae_u8 *buf, int len)
     while (len-- > 0)
        crc = (crc << 8) ^ crc_table16[((crc >> 8) ^ (*buf++)) & 0xff];
     return crc;
+}
+
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \
+        | ( (unsigned long) (b)[(i) + 1] << 16 )        \
+        | ( (unsigned long) (b)[(i) + 2] <<  8 )        \
+        | ( (unsigned long) (b)[(i) + 3]       );       \
+}
+#endif
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
+}
+#endif
+
+typedef struct
+{
+    unsigned long total[2];     /*!< number of bytes processed  */
+    unsigned long state[5];     /*!< intermediate digest state  */
+    unsigned char buffer[64];   /*!< data block being processed */
+}
+sha1_context;
+
+static void sha1_starts( sha1_context *ctx )
+{
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    ctx->state[0] = 0x67452301;
+    ctx->state[1] = 0xEFCDAB89;
+    ctx->state[2] = 0x98BADCFE;
+    ctx->state[3] = 0x10325476;
+    ctx->state[4] = 0xC3D2E1F0;
+}
+
+static void sha1_process( sha1_context *ctx, unsigned char data[64] )
+{
+    unsigned long temp, W[16], A, B, C, D, E;
+
+    GET_UINT32_BE( W[0],  data,  0 );
+    GET_UINT32_BE( W[1],  data,  4 );
+    GET_UINT32_BE( W[2],  data,  8 );
+    GET_UINT32_BE( W[3],  data, 12 );
+    GET_UINT32_BE( W[4],  data, 16 );
+    GET_UINT32_BE( W[5],  data, 20 );
+    GET_UINT32_BE( W[6],  data, 24 );
+    GET_UINT32_BE( W[7],  data, 28 );
+    GET_UINT32_BE( W[8],  data, 32 );
+    GET_UINT32_BE( W[9],  data, 36 );
+    GET_UINT32_BE( W[10], data, 40 );
+    GET_UINT32_BE( W[11], data, 44 );
+    GET_UINT32_BE( W[12], data, 48 );
+    GET_UINT32_BE( W[13], data, 52 );
+    GET_UINT32_BE( W[14], data, 56 );
+    GET_UINT32_BE( W[15], data, 60 );
+
+#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+#define R(t)                                            \
+(                                                       \
+    temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^     \
+           W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],      \
+    ( W[t & 0x0F] = S(temp,1) )                         \
+)
+
+#define P(a,b,c,d,e,x)                                  \
+{                                                       \
+    e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
+}
+
+    A = ctx->state[0];
+    B = ctx->state[1];
+    C = ctx->state[2];
+    D = ctx->state[3];
+    E = ctx->state[4];
+
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+#define K 0x5A827999
+
+    P( A, B, C, D, E, W[0]  );
+    P( E, A, B, C, D, W[1]  );
+    P( D, E, A, B, C, W[2]  );
+    P( C, D, E, A, B, W[3]  );
+    P( B, C, D, E, A, W[4]  );
+    P( A, B, C, D, E, W[5]  );
+    P( E, A, B, C, D, W[6]  );
+    P( D, E, A, B, C, W[7]  );
+    P( C, D, E, A, B, W[8]  );
+    P( B, C, D, E, A, W[9]  );
+    P( A, B, C, D, E, W[10] );
+    P( E, A, B, C, D, W[11] );
+    P( D, E, A, B, C, W[12] );
+    P( C, D, E, A, B, W[13] );
+    P( B, C, D, E, A, W[14] );
+    P( A, B, C, D, E, W[15] );
+    P( E, A, B, C, D, R(16) );
+    P( D, E, A, B, C, R(17) );
+    P( C, D, E, A, B, R(18) );
+    P( B, C, D, E, A, R(19) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0x6ED9EBA1
+
+    P( A, B, C, D, E, R(20) );
+    P( E, A, B, C, D, R(21) );
+    P( D, E, A, B, C, R(22) );
+    P( C, D, E, A, B, R(23) );
+    P( B, C, D, E, A, R(24) );
+    P( A, B, C, D, E, R(25) );
+    P( E, A, B, C, D, R(26) );
+    P( D, E, A, B, C, R(27) );
+    P( C, D, E, A, B, R(28) );
+    P( B, C, D, E, A, R(29) );
+    P( A, B, C, D, E, R(30) );
+    P( E, A, B, C, D, R(31) );
+    P( D, E, A, B, C, R(32) );
+    P( C, D, E, A, B, R(33) );
+    P( B, C, D, E, A, R(34) );
+    P( A, B, C, D, E, R(35) );
+    P( E, A, B, C, D, R(36) );
+    P( D, E, A, B, C, R(37) );
+    P( C, D, E, A, B, R(38) );
+    P( B, C, D, E, A, R(39) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) ((x & y) | (z & (x | y)))
+#define K 0x8F1BBCDC
+
+    P( A, B, C, D, E, R(40) );
+    P( E, A, B, C, D, R(41) );
+    P( D, E, A, B, C, R(42) );
+    P( C, D, E, A, B, R(43) );
+    P( B, C, D, E, A, R(44) );
+    P( A, B, C, D, E, R(45) );
+    P( E, A, B, C, D, R(46) );
+    P( D, E, A, B, C, R(47) );
+    P( C, D, E, A, B, R(48) );
+    P( B, C, D, E, A, R(49) );
+    P( A, B, C, D, E, R(50) );
+    P( E, A, B, C, D, R(51) );
+    P( D, E, A, B, C, R(52) );
+    P( C, D, E, A, B, R(53) );
+    P( B, C, D, E, A, R(54) );
+    P( A, B, C, D, E, R(55) );
+    P( E, A, B, C, D, R(56) );
+    P( D, E, A, B, C, R(57) );
+    P( C, D, E, A, B, R(58) );
+    P( B, C, D, E, A, R(59) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0xCA62C1D6
+
+    P( A, B, C, D, E, R(60) );
+    P( E, A, B, C, D, R(61) );
+    P( D, E, A, B, C, R(62) );
+    P( C, D, E, A, B, R(63) );
+    P( B, C, D, E, A, R(64) );
+    P( A, B, C, D, E, R(65) );
+    P( E, A, B, C, D, R(66) );
+    P( D, E, A, B, C, R(67) );
+    P( C, D, E, A, B, R(68) );
+    P( B, C, D, E, A, R(69) );
+    P( A, B, C, D, E, R(70) );
+    P( E, A, B, C, D, R(71) );
+    P( D, E, A, B, C, R(72) );
+    P( C, D, E, A, B, R(73) );
+    P( B, C, D, E, A, R(74) );
+    P( A, B, C, D, E, R(75) );
+    P( E, A, B, C, D, R(76) );
+    P( D, E, A, B, C, R(77) );
+    P( C, D, E, A, B, R(78) );
+    P( B, C, D, E, A, R(79) );
+
+#undef K
+#undef F
+
+    ctx->state[0] += A;
+    ctx->state[1] += B;
+    ctx->state[2] += C;
+    ctx->state[3] += D;
+    ctx->state[4] += E;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+static void sha1_update( sha1_context *ctx, unsigned char *input, int ilen )
+{
+    int fill;
+    unsigned long left;
+
+    if( ilen <= 0 )
+        return;
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if( ctx->total[0] < (unsigned long) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        memcpy( (void *) (ctx->buffer + left),
+                (void *) input, fill );
+        sha1_process( ctx, ctx->buffer );
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 64 )
+    {
+        sha1_process( ctx, input );
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if( ilen > 0 )
+    {
+        memcpy( (void *) (ctx->buffer + left),
+                (void *) input, ilen );
+    }
+}
+
+static const unsigned char sha1_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * SHA-1 final digest
+ */
+static void sha1_finish( sha1_context *ctx, unsigned char output[20] )
+{
+    unsigned long last, padn;
+    unsigned long high, low;
+    unsigned char msglen[8];
+
+    high = ( ctx->total[0] >> 29 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_UINT32_BE( high, msglen, 0 );
+    PUT_UINT32_BE( low,  msglen, 4 );
+
+    last = ctx->total[0] & 0x3F;
+    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
+
+    sha1_update( ctx, (unsigned char *) sha1_padding, padn );
+    sha1_update( ctx, msglen, 8 );
+
+    PUT_UINT32_BE( ctx->state[0], output,  0 );
+    PUT_UINT32_BE( ctx->state[1], output,  4 );
+    PUT_UINT32_BE( ctx->state[2], output,  8 );
+    PUT_UINT32_BE( ctx->state[3], output, 12 );
+    PUT_UINT32_BE( ctx->state[4], output, 16 );
+}
+
+void get_sha1(uae_u8 *input, int len, uae_u8 *out)
+{
+    sha1_context ctx;
+
+    sha1_starts( &ctx );
+    sha1_update( &ctx, input, len );
+    sha1_finish( &ctx, out );
+}
+char *get_sha1_txt(uae_u8 *input, int len)
+{
+    static char outtxt[SHA1_SIZE * 2 + 1];
+    uae_u8 out[SHA1_SIZE];
+    int i;
+    char *p;
+
+    p = outtxt;
+    get_sha1(input, len, out);
+    for (i = 0; i < SHA1_SIZE; i++) {
+       sprintf(p, "%02X", out[i]);
+       p += 2;
+    }
+    *p = 0;
+    return outtxt;
 }
\ No newline at end of file
index 43f6ecd227f67efb3dca8df1e1ba4ec7001ef250..30ec4efc5318206ee351a53e96431b6e3da2aa90 100755 (executable)
--- a/custom.c
+++ b/custom.c
@@ -1045,7 +1045,7 @@ STATIC_INLINE void flush_display (int fm)
     toscr_nbits = 0;
 }
 
-STATIC_INLINE fetch_start(int hpoa)
+STATIC_INLINE void fetch_start(int hpoa)
 {
     fetch_state = fetch_started;
 }
@@ -3070,7 +3070,7 @@ static void BLTSIZH (uae_u16 v)
     do_blitter (current_hpos());
 }
 
-STATIC_INLINE spr_arm (int num, int state)
+STATIC_INLINE void spr_arm (int num, int state)
 {
     switch (state)
     {
@@ -4958,7 +4958,7 @@ STATIC_INLINE uae_u32 REGPARAM2 custom_wget_1 (uaecptr addr, int noput)
     return v;
 }
 
- STATIC_INLINE custom_wget2 (uaecptr addr)
+ STATIC_INLINE uae_u32 custom_wget2 (uaecptr addr)
  {
     uae_u32 v;
     sync_copper_with_cpu (current_hpos (), 1);
@@ -5421,7 +5421,7 @@ uae_u8 *save_custom (int *len, uae_u8 *dstptr, int full)
     if (dstptr)
        dstbak = dst = dstptr;
     else
-       dstbak = dst = malloc (8 + 256 * 2);
+       dstbak = dst = (uae_u8*)malloc (8 + 256 * 2);
 
     SL (currprefs.chipset_mask);
     SW (0);                    /* 000 ? */
@@ -5584,7 +5584,7 @@ uae_u8 *save_custom_agacolors (int *len, uae_u8 *dstptr)
     if (dstptr)
        dstbak = dst = dstptr;
     else
-       dstbak = dst = malloc (256*4);
+       dstbak = dst = (uae_u8*)malloc (256*4);
     for (i = 0; i < 256; i++)
 #ifdef AGA
     SL (current_colors.color_regs_aga[i]);
@@ -5619,7 +5619,7 @@ uae_u8 *save_custom_sprite(int num, int *len, uae_u8 *dstptr)
     if (dstptr)
        dstbak = dst = dstptr;
     else
-       dstbak = dst = malloc (25);
+       dstbak = dst = (uae_u8*)malloc (30);
     SL (spr[num].pt);          /* 120-13E SPRxPT */
     SW (sprpos[num]);          /* 1x0 SPRxPOS */
     SW (sprctl[num]);          /* 1x2 SPRxPOS */
@@ -5696,7 +5696,7 @@ STATIC_INLINE void sync_copper (int hpos)
        update_copper (hpos);
 }
 
-STATIC_INLINE decide_fetch_ce (int hpos)
+STATIC_INLINE void decide_fetch_ce (int hpos)
 {
     if ((ddf_change == vpos || ddf_change + 1 == vpos) && vpos < maxvpos)
        decide_fetch (hpos);
diff --git a/debug.c b/debug.c
index 07f203c28d988a03f56185a902bb573b02fcc236..b5ac9497cbe5e4a4bf1849bcd3d724958da0dab3 100755 (executable)
--- a/debug.c
+++ b/debug.c
@@ -581,8 +581,8 @@ void record_copper (uaecptr addr, int hpos, int vpos)
 {
     int t = nr_cop_records[curr_cop_set];
     if (!cop_record[0]) {
-       cop_record[0] = malloc (NR_COPPER_RECORDS * sizeof (struct cop_record));
-       cop_record[1] = malloc (NR_COPPER_RECORDS * sizeof (struct cop_record));
+       cop_record[0] = (struct cop_record*)malloc (NR_COPPER_RECORDS * sizeof (struct cop_record));
+       cop_record[1] = (struct cop_record*)malloc (NR_COPPER_RECORDS * sizeof (struct cop_record));
     }
     if (t < NR_COPPER_RECORDS) {
        cop_record[curr_cop_set][t].addr = addr;
@@ -740,7 +740,7 @@ static int totaltrainers;
 static void clearcheater(void)
 {
     if (!trainerdata)
-        trainerdata = xmalloc(MAX_CHEAT_VIEW * sizeof (struct trainerstruct));
+        trainerdata = (struct trainerstruct*)xmalloc(MAX_CHEAT_VIEW * sizeof (struct trainerstruct));
     memset(trainerdata, 0, sizeof (struct trainerstruct) * MAX_CHEAT_VIEW);
     totaltrainers = 0;
 }
@@ -823,7 +823,7 @@ static void deepcheatsearch (char **c)
            addr = end - 1;
        }
        memsize2 = (memsize + 7) / 8;
-       memtmp = xmalloc (memsize + memsize2);
+       memtmp = (uae_u8*)xmalloc (memsize + memsize2);
        if (!memtmp)
            return;
        memset (memtmp + memsize, 0xff, memsize2);
@@ -944,7 +944,7 @@ static void cheatsearch (char **c)
        console_out("search reset\n");
        xfree (vlist);
        listsize = memsize;
-       vlist = xcalloc (listsize >> 3, 1);
+       vlist = (uae_u8*)xcalloc (listsize >> 3, 1);
        return;
     }
     val = readint (c);
@@ -966,7 +966,7 @@ static void cheatsearch (char **c)
 
     if (vlist == NULL) {
        listsize = memsize;
-       vlist = xcalloc (listsize >> 3, 1);
+       vlist = (uae_u8*)xcalloc (listsize >> 3, 1);
     }
 
     count = 0;
@@ -1030,7 +1030,7 @@ static void illg_init (void)
     int i;
 
     free (illgdebug);
-    illgdebug = xmalloc (0x1000000);
+    illgdebug = (uae_u8*)xmalloc (0x1000000);
     if (!illgdebug)
        return;
     memset (illgdebug, 3, 0x1000000);
@@ -1146,7 +1146,7 @@ static void smc_detect_init(void)
     if (currprefs.z3fastmem_size)
        smc_size = currprefs.z3fastmem_start + currprefs.z3fastmem_size;
     smc_size += 4;
-    smc_table = xmalloc (smc_size * sizeof (struct smc_item));
+    smc_table = (struct smc_item*)xmalloc (smc_size * sizeof (struct smc_item));
     smc_reset();
     console_out("SMCD enabled\n");
 }
@@ -1464,8 +1464,8 @@ static void initialize_memwatch (int mode)
 
     deinitialize_memwatch();
     as = currprefs.address_space_24 ? 256 : 65536;
-    debug_mem_banks = xmalloc (sizeof (addrbank*) * as);
-    debug_mem_area = xmalloc (sizeof (addrbank) * as);
+    debug_mem_banks = (addrbank**)xmalloc (sizeof (addrbank*) * as);
+    debug_mem_area = (addrbank*)xmalloc (sizeof (addrbank) * as);
     for (i = 0; i < as; i++) {
        a1 = debug_mem_banks[i] = debug_mem_area + i;
        a2 = mem_banks[i];
@@ -1521,7 +1521,7 @@ static void memwatch_dump (int num)
     char *buf;
     int multiplier = num < 0 ? MEMWATCH_TOTAL : 1;
 
-    buf = malloc(50 * multiplier);
+    buf = (char*)malloc(50 * multiplier);
     if (!buf)
         return;
     memwatch_dump2 (buf, 50 * multiplier, num);
@@ -1771,8 +1771,7 @@ STATIC_INLINE uaecptr BPTR2APTR(uaecptr addr)
 }
 static char* BSTR2CSTR(uae_u8 *bstr)
 {
-    char *cstr = NULL;
-    cstr = xmalloc(bstr[0] + 1);
+    char *cstr = (char*)xmalloc(bstr[0] + 1);
     if (cstr) {
         memcpy(cstr, bstr + 1, bstr[0]);
         cstr[bstr[0]] = 0;
@@ -1914,7 +1913,7 @@ static int process_breakpoint(char **c)
     if (!more_params (c))
        return 0;
     if (**c == '\"') {
-       processname = xmalloc(200);
+       processname = (char*)xmalloc(200);
        next_string(c, processname, 200, 0);
     } else {
        processptr = readhex(c);
@@ -2501,7 +2500,7 @@ void debug (void)
                    uaecptr execbase = get_long (4);
                    uaecptr activetask = get_long (execbase + 276);
                    int process = get_byte(activetask + 8) == 13 ? 1 : 0;
-                   char *name = get_real_address(get_long(activetask + 10));
+                   char *name = (char*)get_real_address(get_long(activetask + 10));
                    if (process) {
                        uaecptr cli = BPTR2APTR(get_long(activetask + 172));
                        uaecptr seglist = 0;
@@ -2940,7 +2939,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2)
     }
 
     mmu_slots = 1 << ((currprefs.address_space_24 ? 24 : 32) - MMU_PAGE_SHIFT);
-    mmunl = xcalloc (sizeof (struct mmunode*) * mmu_slots, 1);
+    mmunl = (struct mmunode**)xcalloc (sizeof (struct mmunode*) * mmu_slots, 1);
     size = 1;
     p2 = get_long (p);
     while (get_long (p2) != 0xffffffff) {
@@ -2948,7 +2947,7 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2)
        size++;
     }
     p = banks = get_long (p);
-    snptr = mmubanks = xmalloc (sizeof (struct mmudata) * size);
+    snptr = mmubanks = (struct mmudata*)xmalloc (sizeof (struct mmudata) * size);
     for (;;) {
        int off;
        if (getmmubank(snptr, p))
@@ -2956,12 +2955,12 @@ int mmu_init(int mode, uaecptr parm, uaecptr parm2)
        p += 16;
        off = snptr->addr >> MMU_PAGE_SHIFT;
        if (mmunl[off] == NULL) {
-           mn = mmunl[off] = xcalloc (sizeof (struct mmunode), 1); 
+           mn = mmunl[off] = (struct mmunode*)xcalloc (sizeof (struct mmunode), 1); 
        } else {
            mn = mmunl[off];
            while (mn->next)
                mn = mn->next;
-           mn = mn->next = xcalloc (sizeof (struct mmunode), 1);
+           mn = mn->next = (struct mmunode*)xcalloc (sizeof (struct mmunode), 1);
        }
        mn->mmubank = snptr;
        snptr++;
diff --git a/disk.c b/disk.c
index f57d25c68790a8399477aaa5848a301a3f260cb7..f9789f4754a2c504df617d151457e7649bf43747 100755 (executable)
--- a/disk.c
+++ b/disk.c
@@ -219,7 +219,7 @@ static void disk_checksum(uae_u8 *p, uae_u8 *c)
     c[0] = cs >> 24; c[1] = cs >> 16; c[2] = cs >> 8; c[3] = cs >> 0;
 }
 
-static int dirhash (unsigned char *name)
+static int dirhash (const unsigned char *name)
 {
     unsigned long hash;
     int i;
@@ -969,7 +969,7 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const char
            drv->num_tracks = size / (512 * (drv->num_secs = 11));
 
        if (drv->num_tracks > MAX_TRACKS)
-           write_log ("Your diskfile is too big!\n");
+           write_log ("Your diskfile is too big, %d bytes!\n", size);
        for (i = 0; i < drv->num_tracks; i++) {
            tid = &drv->trackdata[i];
            tid->type = TRACK_AMIGADOS;
@@ -1817,7 +1817,7 @@ void disk_creatediskfile (char *name, int type, drive_type adftype, char *disk_n
     }
 
     f = zfile_fopen (name, "wb");
-    chunk = xmalloc (16384);
+    chunk = (uae_u8*)xmalloc (16384);
     if (f && chunk) {
        memset(chunk,0,16384);
        if (type == 0 && adftype < 2) {
@@ -3144,7 +3144,7 @@ static uae_u32 getadfcrc (drive *drv)
        return 0;
     zfile_fseek (drv->diskfile, 0, SEEK_END);
     size = zfile_ftell (drv->diskfile);
-    b = malloc (size);
+    b = (uae_u8*)malloc (size);
     if (!b)
        return 0;
     zfile_fseek (drv->diskfile, 0, SEEK_SET);
@@ -3163,7 +3163,7 @@ uae_u8 *save_disk(int num, int *len, uae_u8 *dstptr)
     if (dstptr)
        dstbak = dst = dstptr;
     else
-       dstbak = dst = malloc (2+1+1+1+1+4+4+256);
+       dstbak = dst = (uae_u8*)malloc (2+1+1+1+1+4+4+256);
     save_u32 (drv->drive_id);      /* drive type ID */
     save_u8 ((drv->motoroff ? 0:1) | ((disabled & (1 << num)) ? 2 : 0) | (drv->idbit ? 4 : 0));
     save_u8 (drv->cyl);                    /* cylinder */
@@ -3204,7 +3204,7 @@ uae_u8 *save_floppy(int *len, uae_u8 *dstptr)
     if (dstptr)
        dstbak = dst = dstptr;
     else
-       dstbak = dst = malloc(2+1+1+1+1+2);
+       dstbak = dst = (uae_u8*)malloc(2+1+1+1+1+2);
     save_u16 (word);           /* current fifo (low word) */
     save_u8 (bitoffset);       /* dma bit offset */
     save_u8 (dma_enable);      /* disk sync found */
index 467e6cdcce4b9db4472e6db2787e4bba983f93ce..cf9bbc56017c208cfbf9b753b98557bd841f5414 100755 (executable)
--- a/drawing.c
+++ b/drawing.c
@@ -1141,8 +1141,8 @@ static void init_aspect_maps (void)
        free (amiga2aspect_line_map);
 
     /* At least for this array the +1 is necessary. */
-    amiga2aspect_line_map = malloc (sizeof (int) * (MAXVPOS + 1) * 2 + 1);
-    native2amiga_line_map = malloc (sizeof (int) * gfxvidinfo.height);
+    amiga2aspect_line_map = (int*)malloc (sizeof (int) * (MAXVPOS + 1) * 2 + 1);
+    native2amiga_line_map = (int*)malloc (sizeof (int) * gfxvidinfo.height);
 
     if (currprefs.gfx_correct_aspect)
        native_lines_per_amiga_line = ((double)gfxvidinfo.height
@@ -2256,9 +2256,6 @@ void vsync_handle_redraw (int long_frame, int lof_changed)
        }
 
        check_prefs_changed_audio ();
-#ifdef JIT
-       check_prefs_changed_comp ();
-#endif
        check_prefs_changed_custom ();
        check_prefs_changed_cpu ();
 
index ea51ab39770c61e79d8a4b404635029fe84f9842..1f093d6ea4a31ef8c7c7e45cae41fb6130b1dda0 100755 (executable)
@@ -48,7 +48,7 @@ uae_s16 *decodewav (uae_u8 *s, int *lenp)
        if (!memcmp (s, "data", 4)) {
            s += 4;
            len = s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24);
-           dst = xmalloc (len);
+           dst = (uae_s16*)xmalloc (len);
            memcpy (dst, s + 4, len);
            *lenp = len / 2;
            return dst;
@@ -77,7 +77,7 @@ static int loadsample (char *path, struct drvsample *ds)
     }
     zfile_fseek (f, 0, SEEK_END);
     size = zfile_ftell (f);
-    buf = xmalloc (size);
+    buf = (uae_u8*)xmalloc (size);
     zfile_fseek (f, 0, SEEK_SET);
     zfile_fread (buf, size, 1, f);
     zfile_fclose (f);
@@ -208,7 +208,7 @@ void driveclick_reset (void)
     xfree (clickbuffer);
     if (!wave_initialized)
        return;
-    clickbuffer = xmalloc (sndbufsize);
+    clickbuffer = (uae_s16*)xmalloc (sndbufsize);
     sample_step = (freq << DS_SHIFT) / currprefs.sound_freq;
 }
 
index 6dd1f230e5b2eb606339c33023ba91fb05b90759..cb31fa90d592f4a0c9cc2331a4d9d291c2f6739e 100755 (executable)
--- a/fdi2raw.c
+++ b/fdi2raw.c
@@ -158,7 +158,7 @@ struct fdi {
 
 #define get_u32(x) ((((x)[0])<<24)|(((x)[1])<<16)|(((x)[2])<<8)|((x)[3]))
 #define get_u24(x) ((((x)[0])<<16)|(((x)[1])<<8)|((x)[2]))
-STATIC_INLINE put_u32 (uae_u8 *d, uae_u32 v)
+STATIC_INLINE void put_u32 (uae_u8 *d, uae_u32 v)
 {
        d[0] = v >> 24;
        d[1] = v >> 16;
@@ -195,10 +195,10 @@ static uae_u8 *expand_tree (uae_u8 *stream, NODE *node)
                        temp = *stream++;
                        temp2 = 0x80;
                }
-               node->left = fdi_malloc (sizeof (NODE));
+               node->left = (NODE*)fdi_malloc (sizeof (NODE));
                memset (node->left, 0, sizeof (NODE));
                stream_temp = expand_tree (stream, node->left);
-               node->right = fdi_malloc (sizeof (NODE));
+               node->right = (NODE*)fdi_malloc (sizeof (NODE));
                memset (node->right, 0, sizeof (NODE));
                return expand_tree (stream_temp, node->right);
        }
@@ -1360,7 +1360,7 @@ static uae_u8 *fdi_decompress (int pulses, uae_u8 *sizep, uae_u8 *src, int *dofr
                        src += 4;
                }
        } else if (mode == 1) {
-               dst = fdi_malloc (pulses *4);
+               dst = (uae_u8*)fdi_malloc (pulses *4);
                *dofree = 1;
                fdi_decode (src, pulses, dst);
        } else {
@@ -1864,7 +1864,7 @@ static int decode_lowlevel_track (FDI *fdi, int track, struct fdi_cache *cache)
                        idx_off3 = 4;
                }
        } else {
-               idxp = fdi_malloc (pulses * 2);
+               idxp = (uae_u8*)fdi_malloc (pulses * 2);
                idx_free = 1;
                for (i = 0; i < pulses; i++) {
                        idxp[i * 2 + 0] = 2;
@@ -2015,7 +2015,7 @@ FDI *fdi2raw_header(struct zfile *f)
        FDI *fdi;
 
        debuglog ("ALLOC: memory allocated %d\n", fdi_allocated);
-       fdi = fdi_malloc(sizeof(FDI));
+       fdi = (FDI*)fdi_malloc(sizeof(FDI));
        memset (fdi, 0, sizeof (FDI));
        fdi->file = f;
        oldseek = zfile_ftell (fdi->file);
@@ -2041,10 +2041,10 @@ FDI *fdi2raw_header(struct zfile *f)
                }
        }
 
-       fdi->mfmsync_buffer = fdi_malloc (MAX_MFM_SYNC_BUFFER * sizeof(int));
-       fdi->track_src_buffer = fdi_malloc (MAX_SRC_BUFFER);
-       fdi->track_dst_buffer = fdi_malloc (MAX_DST_BUFFER);
-       fdi->track_dst_buffer_timing = fdi_malloc (MAX_TIMING_BUFFER);
+       fdi->mfmsync_buffer = (int*)fdi_malloc (MAX_MFM_SYNC_BUFFER * sizeof(int));
+       fdi->track_src_buffer = (uae_u8*)fdi_malloc (MAX_SRC_BUFFER);
+       fdi->track_dst_buffer = (uae_u8*)fdi_malloc (MAX_DST_BUFFER);
+       fdi->track_dst_buffer_timing = (uae_u16*)fdi_malloc (MAX_TIMING_BUFFER);
 
        fdi->last_track = ((fdi->header[142] << 8) + fdi->header[143]) + 1;
        fdi->last_track *= fdi->header[144] + 1;
index 0f0dd6f38f43daae13b768f3422aa61736dee2fe..46c90262b5d4b8b9687fb415ad33a85478b61aba 100755 (executable)
--- a/filesys.c
+++ b/filesys.c
@@ -285,17 +285,28 @@ static int set_filesys_unit_1 (int nr,
     ui->filesysdir = 0;
 
     if (volname != 0 && volname[0]) {
-       int flags;
+       int flags = 0;
        ui->volname = my_strdup (volname);
        stripsemicolon(ui->volname);
-       flags = my_getvolumeinfo (rootdir);
-       if (flags < 0) {
-           write_log ("directory '%s' not found\n", rootdir);
-           return -1;
-       }
-       if (flags & MYVOLUMEINFO_READONLY) {
-           write_log ("'%s' set to read-only\n", rootdir);
+       if (my_existsfile(rootdir)) {
+           struct zvolume *zv;
+           zv = zfile_fopen_archive(rootdir);
+           if (!zv) {
+               write_log ("'%s' is not a supported archive file\n", rootdir);
+               return -1;
+           }
+           flags = MYVOLUMEINFO_ARCHIVE;
            readonly = 1;
+       } else {
+           flags = my_getvolumeinfo (rootdir);
+           if (flags < 0) {
+               write_log ("directory '%s' not found\n", rootdir);
+               return -1;
+           }
+           if (flags & MYVOLUMEINFO_READONLY) {
+               write_log ("'%s' set to read-only\n", rootdir);
+               readonly = 1;
+           }
        }
        ui->volflags = flags;
     } else {
@@ -705,6 +716,8 @@ find_unit (uaecptr port)
 /* flags and comments supported? */
 static int fsdb_cando (Unit *unit)
 {
+    if (unit->volflags & MYVOLUMEINFO_ARCHIVE)
+       return 1;
     if (currprefs.filesys_custom_uaefsdb  && (unit->volflags & MYVOLUMEINFO_STREAMS))
        return 1;
     if (!currprefs.filesys_no_uaefsdb)
@@ -712,6 +725,39 @@ static int fsdb_cando (Unit *unit)
     return 0;
 }
 
+static void *fs_open (Unit *unit, const char *name, int flags)
+{
+    int isarch = unit->volflags & MYVOLUMEINFO_ARCHIVE;
+    if (isarch)
+       return zfile_open_archive(name, flags);
+    else
+       return my_open(name, flags);
+}
+static void fs_close(Unit *unit, void *fd)
+{
+    int isarch = unit->volflags & MYVOLUMEINFO_ARCHIVE;
+    if (isarch)
+       zfile_close_archive(fd);
+    else
+       my_close(fd);
+}
+static unsigned int fs_read (Unit *unit, void *d, void *b, unsigned int size)
+{
+    int isarch = unit->volflags & MYVOLUMEINFO_ARCHIVE;
+    if (isarch)
+       return zfile_read_archive(d, b, size);
+    else
+       return my_read (d, b, size);
+}
+static unsigned int fs_lseek (Unit *unit, void *d, unsigned int offset, int whence)
+{
+    int isarch = unit->volflags & MYVOLUMEINFO_ARCHIVE;
+    if (isarch)
+       return zfile_lseek_archive(d, offset, whence);
+    else
+       return my_lseek (d, offset, whence);
+}
+
 static void prepare_for_open (char *name)
 {
 #if 0
@@ -983,10 +1029,16 @@ static char *get_nname (Unit *unit, a_inode *base, char *rel,
     char *found;
     char *p = 0;
 
-    aino_test (base);
-
     *modified_rel = 0;
 
+    if (unit->volflags & MYVOLUMEINFO_ARCHIVE) {
+       if (zfile_exists_archive(base->nname, rel))
+           return build_nname(base->nname, rel);
+       return 0;
+    }
+
+    aino_test (base);
+
     /* If we have a mapping of some other aname to "rel", we must pretend
      * it does not exist.
      * This can happen for example if an Amiga program creates a
@@ -1046,6 +1098,22 @@ static char *create_nname (Unit *unit, a_inode *base, char *rel)
     return p;
 }
 
+static int fill_file_attrs(Unit *u, a_inode *base, a_inode *c)
+{
+    if (u->volflags & MYVOLUMEINFO_ARCHIVE) {
+        int isdir, flags;
+        char *comment;
+        zfile_fill_file_attrs_archive(c->nname, &isdir, &flags, &comment);
+        c->dir = isdir;
+        c->amigaos_mode = flags;
+        c->comment = comment;
+       return 1;
+    } else {
+       return fsdb_fill_file_attrs (base, c);
+    }
+    return 0;
+}
+
 /*
  * This gets called if an ACTION_EXAMINE_NEXT happens and we hit an object
  * for which we know the name on the native filesystem, but no corresponding
@@ -1103,11 +1171,13 @@ static a_inode *new_child_aino (Unit *unit, a_inode *base, char *rel)
 {
     char *modified_rel;
     char *nn;
-    a_inode *aino;
+    a_inode *aino = NULL;
+    int isarch = unit->volflags & MYVOLUMEINFO_ARCHIVE;
 
     TRACE(("new_child_aino %s, %s\n", base->aname, rel));
 
-    aino = fsdb_lookup_aino_aname (base, rel);
+    if (!isarch)
+       aino = fsdb_lookup_aino_aname (base, rel);
     if (aino == 0) {
        nn = get_nname (unit, base, rel, &modified_rel);
        if (nn == 0)
@@ -1122,7 +1192,7 @@ static a_inode *new_child_aino (Unit *unit, a_inode *base, char *rel)
        aino->comment = 0;
        aino->has_dbentry = 0;
 
-       if (!fsdb_fill_file_attrs (base, aino)) {
+       if (!fill_file_attrs (unit, base, aino)) {
            xfree (aino);
            return 0;
        }
@@ -1195,6 +1265,7 @@ static a_inode *lookup_child_aino_for_exnext (Unit *unit, a_inode *base, char *r
 {
     a_inode *c = base->child;
     int l0 = strlen (rel);
+    int isarch = unit->volflags & MYVOLUMEINFO_ARCHIVE;
 
     aino_test (base);
     aino_test (c);
@@ -1210,9 +1281,10 @@ static a_inode *lookup_child_aino_for_exnext (Unit *unit, a_inode *base, char *r
     }
     if (c != 0)
        return c;
-    c = fsdb_lookup_aino_nname (base, rel);
+    if (!isarch)
+       c = fsdb_lookup_aino_nname (base, rel);
     if (c == 0) {
-       c = xcalloc (sizeof (a_inode), 1);
+       c = (a_inode*)xcalloc (sizeof (a_inode), 1);
        if (c == 0) {
            *err = ERROR_NO_FREE_STORE;
            return 0;
@@ -1222,12 +1294,12 @@ static a_inode *lookup_child_aino_for_exnext (Unit *unit, a_inode *base, char *r
        c->aname = get_aname (unit, base, rel);
        c->comment = 0;
        c->has_dbentry = 0;
-       if (!fsdb_fill_file_attrs (base, c)) {
+       if (!fill_file_attrs(unit, base, c)) {
            xfree (c);
            *err = ERROR_NO_FREE_STORE;
            return 0;
        }
-       if (c->dir)
+       if (c->dir && !isarch)
            fsdb_clean_dir (c);
     }
     init_child_aino (unit, base, c);
@@ -1304,7 +1376,7 @@ static uae_u32 notifyhash (char *s)
 
 static Notify *new_notify (Unit *unit, char *name)
 {
-    Notify *n = xmalloc(sizeof(Notify));
+    Notify *n = (Notify*)xmalloc(sizeof(Notify));
     uae_u32 hash = notifyhash (name);
     n->next = unit->notifyhash[hash];
     unit->notifyhash[hash] = n;
@@ -1352,7 +1424,7 @@ static Unit *startup_create_unit (UnitInfo *uinfo)
     int i;
     Unit *unit;
 
-    unit = xcalloc (sizeof (Unit), 1);
+    unit = (Unit*)xcalloc (sizeof (Unit), 1);
     unit->next = units;
     units = unit;
     uinfo->self = unit;
@@ -1439,7 +1511,7 @@ static uae_u32 REGPARAM2 startup_handler (TrapContext *context)
     }
 
     if (i == MAX_FILESYSTEM_UNITS
-       || !my_existsdir (mountinfo.ui[i].rootdir))
+       || (!my_existsdir (mountinfo.ui[i].rootdir) && !my_existsfile (mountinfo.ui[i].rootdir)))
     {
        write_log ("Failed attempt to mount device '%s'\n", devname);
        put_long (pkt + dp_Res1, DOS_FALSE);
@@ -1499,8 +1571,13 @@ static void
 do_info (Unit *unit, dpacket packet, uaecptr info)
 {
     struct fs_usage fsu;
+    int ret;
 
-    if (get_fs_usage (unit->ui.rootdir, 0, &fsu) != 0) {
+    if (unit->volflags & MYVOLUMEINFO_ARCHIVE)
+       ret = zfile_fs_usage_archive (unit->ui.rootdir, 0, &fsu);
+    else
+       ret = get_fs_usage (unit->ui.rootdir, 0, &fsu);
+    if (ret != 0) {
        PUT_PCK_RES1 (packet, DOS_FALSE);
        PUT_PCK_RES2 (packet, dos_errno ());
        return;
@@ -1547,7 +1624,7 @@ static void free_key (Unit *unit, Key *k)
     }
 
     if (k->fd != NULL)
-       my_close (k->fd);
+       fs_close (unit, k->fd);
 
     xfree(k);
 }
@@ -2045,12 +2122,16 @@ get_fileinfo (Unit *unit, dpacket packet, uaecptr info, a_inode *aino)
     int fsdb_can = fsdb_cando (unit);
     char *x;
 
+    memset(&statbuf, 0, sizeof statbuf);
     /* No error checks - this had better work. */
-    stat (aino->nname, &statbuf);
+    if (unit->volflags & MYVOLUMEINFO_ARCHIVE)
+       zfile_stat_archive (aino->nname, &statbuf);
+    else
+       stat (aino->nname, &statbuf);
 
     if (aino->parent == 0) {
        /* Guru book says ST_ROOT = 1 (root directory, not currently used)
-        * and some programs really expect 2 from root dir..
+        * but some programs really expect 2 from root dir..
         */
        entrytype = 2;
        x = unit->ui.volname;
@@ -2160,9 +2241,14 @@ static void action_examine_object (Unit *unit, dpacket packet)
 
 static void populate_directory (Unit *unit, a_inode *base)
 {
-    void *d = my_opendir (base->nname);
+    void *d;
     a_inode *aino;
+    int isarch = unit->volflags & MYVOLUMEINFO_ARCHIVE;
 
+    if (isarch)
+       d = zfile_opendir_archive(base->nname);
+    else
+       d = my_opendir (base->nname);
     if (!d)
        return;
     for (aino = base->child; aino; aino = aino->sibling) {
@@ -2179,15 +2265,21 @@ static void populate_directory (Unit *unit, a_inode *base)
        /* Find next file that belongs to the Amiga fs (skipping things
           like "..", "." etc.  */
        do {
-           ok = my_readdir (d, fn);
-       } while (ok && fsdb_name_invalid (fn));
+           if (isarch)
+               ok = zfile_readdir_archive(d, fn);
+           else
+               ok = my_readdir (d, fn);
+       } while (ok && !isarch && fsdb_name_invalid (fn));
        if (!ok)
            break;
        /* This calls init_child_aino, which will notice that the parent is
           being ExNext()ed, and it will increment the locked counts.  */
        aino = lookup_child_aino_for_exnext (unit, base, fn, &err);
     }
-    my_closedir (d);
+    if (isarch)
+       zfile_closedir_archive(d);
+    else
+       my_closedir (d);
 }
 
 static void do_examine (Unit *unit, dpacket packet, ExamineKey *ek, uaecptr info)
@@ -2199,7 +2291,7 @@ static void do_examine (Unit *unit, dpacket packet, ExamineKey *ek, uaecptr info
        name = ek->curr_file->nname;
        get_fileinfo (unit, packet, info, ek->curr_file);
         ek->curr_file = ek->curr_file->sibling;
-       if (!fsdb_exists(name)) {
+       if (!(unit->volflags & MYVOLUMEINFO_ARCHIVE) && !fsdb_exists(name)) {
            TRACE (("%s orphaned", name));
            continue;
        }
@@ -2274,6 +2366,7 @@ static void do_find (Unit *unit, dpacket packet, int mode, int create, int fallb
     uae_u32 err;
     mode_t openmode;
     int aino_created = 0;
+    int isarch = unit->volflags & MYVOLUMEINFO_ARCHIVE;
 
     TRACE(("ACTION_FIND_*(0x%lx,0x%lx,\"%s\",%d,%d)\n", fh, lock, bstr (unit, name), mode, create));
     DUMPLOCK(unit, lock);
@@ -2352,12 +2445,13 @@ static void do_find (Unit *unit, dpacket packet, int mode, int create, int fallb
                | (create ? O_CREAT : 0)
                | (create == 2 ? O_TRUNC : 0));
 
-    fd = my_open (aino->nname, openmode | O_BINARY);
+    fd = fs_open (unit, aino->nname, openmode | O_BINARY);
     if (fd == NULL) {
        if (aino_created)
            delete_aino (unit, aino);
        PUT_PCK_RES1 (packet, DOS_FALSE);
-       PUT_PCK_RES2 (packet, dos_errno ());
+       /* archive and fd == NULL = corrupt archive or out of memory */
+       PUT_PCK_RES2 (packet, isarch ? ERROR_OBJECT_NOT_AROUND : dos_errno ());
        return;
     }
 
@@ -2368,7 +2462,7 @@ static void do_find (Unit *unit, dpacket packet, int mode, int create, int fallb
     k->createmode = create;
     k->notifyactive = create ? 1 : 0;
 
-    if (create)
+    if (create && isarch)
         fsdb_set_file_attrs (aino);
 
     put_long (fh + 36, k->uniq);
@@ -2390,6 +2484,7 @@ action_fh_from_lock (Unit *unit, dpacket packet)
     void *fd;
     mode_t openmode;
     int mode;
+    int isarch = unit->volflags & MYVOLUMEINFO_ARCHIVE;
 
     TRACE(("ACTION_FH_FROM_LOCK(0x%lx,0x%lx)\n", fh, lock));
     DUMPLOCK(unit,lock);
@@ -2416,7 +2511,7 @@ action_fh_from_lock (Unit *unit, dpacket packet)
     if (unit->ui.readonly)
        openmode = O_RDONLY;
 
-    fd = my_open (aino->nname, openmode | O_BINARY);
+    fd = fs_open (unit, aino->nname, openmode | O_BINARY);
 
     if (fd == NULL) {
        PUT_PCK_RES1 (packet, DOS_FALSE);
@@ -2528,9 +2623,9 @@ action_read (Unit *unit, dpacket packet)
      * Try to detect a LoadSeg() */
     if (k->file_pos == 0 && size >= 4) {
        unsigned char buf[4];
-       off_t currpos = my_lseek (k->fd, 0, SEEK_CUR);
+       off_t currpos = fs_lseek (unit, k->fd, 0, SEEK_CUR);
        my_read (k->fd, buf, 4);
-       my_lseek (k->fd, currpos, SEEK_SET);
+       fs_lseek (unit, k->fd, currpos, SEEK_SET);
        if (buf[0] == 0 && buf[1] == 0 && buf[2] == 3 && buf[3] == 0xF3)
            possible_loadseg();
     }
@@ -2538,7 +2633,7 @@ action_read (Unit *unit, dpacket packet)
     if (valid_address (addr, size)) {
        uae_u8 *realpt;
        realpt = get_real_address (addr);
-       actual = my_read (k->fd, realpt, size);
+       actual = fs_read (unit, k->fd, realpt, size);
 
        if (actual == 0) {
            PUT_PCK_RES1 (packet, 0);
@@ -2557,9 +2652,9 @@ action_read (Unit *unit, dpacket packet)
        write_log ("unixfs warning: Bad pointer passed for read: %08x, size %d\n", addr, size);
        /* ugh this is inefficient but easy */
 
-       old = my_lseek (k->fd, 0, SEEK_CUR);
-       filesize = my_lseek (k->fd, 0, SEEK_END);
-       my_lseek (k->fd, old, SEEK_SET);
+       old = fs_lseek (unit, k->fd, 0, SEEK_CUR);
+       filesize = fs_lseek (unit, k->fd, 0, SEEK_END);
+       fs_lseek (unit, k->fd, old, SEEK_SET);
        if (size > filesize)
            size = filesize;
 
@@ -2569,7 +2664,7 @@ action_read (Unit *unit, dpacket packet)
            PUT_PCK_RES2 (packet, ERROR_NO_FREE_STORE);
            return;
        }
-       actual = my_read (k->fd, buf, size);
+       actual = fs_read (unit, k->fd, buf, size);
 
        if (actual < 0) {
            PUT_PCK_RES1 (packet, 0);
@@ -2656,11 +2751,11 @@ action_seek (Unit *unit, dpacket packet)
     TRACE(("ACTION_SEEK(%s,%d,%d)\n", k->aino->nname, pos, mode));
     gui_hd_led (1);
 
-    old = my_lseek (k->fd, 0, SEEK_CUR);
+    old = fs_lseek (unit, k->fd, 0, SEEK_CUR);
     {
        uae_s32 temppos;
-       long filesize = my_lseek (k->fd, 0, SEEK_END);
-       my_lseek (k->fd, old, SEEK_SET);
+       long filesize = fs_lseek (unit, k->fd, 0, SEEK_END);
+       fs_lseek (unit, k->fd, old, SEEK_SET);
 
        if (whence == SEEK_CUR) temppos = old + pos;
        if (whence == SEEK_SET) temppos = pos;
@@ -2672,7 +2767,7 @@ action_seek (Unit *unit, dpacket packet)
            return;
        }
     }
-    res = my_lseek (k->fd, pos, whence);
+    res = fs_lseek (unit, k->fd, pos, whence);
 
     if (-1 == res) {
        PUT_PCK_RES1 (packet, res);
@@ -2739,7 +2834,7 @@ static void action_set_comment (Unit * unit, dpacket packet)
         commented = bstr (unit, comment);
        if (strlen (commented) > 0) {
            char *p = commented;
-           commented = xmalloc (81);
+           commented = (char*)xmalloc (81);
            strncpy (commented, p, 80);
            commented[80] = 0;
        } else {
@@ -3019,11 +3114,11 @@ action_set_file_size (Unit *unit, dpacket packet)
     }
 
     /* Write one then truncate: that should give the right size in all cases.  */
-    offset = my_lseek (k->fd, offset, whence);
+    offset = fs_lseek (unit, k->fd, offset, whence);
     my_write (k->fd, /* whatever */(char *)&k1, 1);
     if (k->file_pos > offset)
        k->file_pos = offset;
-    my_lseek (k->fd, k->file_pos, SEEK_SET);
+    fs_lseek (unit, k->fd, k->file_pos, SEEK_SET);
 
     /* Brian: no bug here; the file _must_ be one byte too large after writing
        The write is supposed to guarantee that the file can't be smaller than
@@ -3048,7 +3143,7 @@ static int relock_do(Unit *unit, a_inode *a1)
         knext = k1->next;
         if (k1->aino == a1 && k1->fd) {
            wehavekeys++;
-           my_close (k1->fd);
+           fs_close (unit, k1->fd);
            write_log ("handle %p freed\n", k1->fd);
        }
     }
@@ -3066,13 +3161,13 @@ static void relock_re(Unit *unit, a_inode *a1, a_inode *a2, int failed)
            mode |= O_BINARY;
            if (failed) {
                /* rename still failed, restore fd */
-               k1->fd = my_open (a1->nname, mode);
+               k1->fd = fs_open (unit, a1->nname, mode);
                write_log ("restoring old handle '%s' %d\n", a1->nname, k1->dosmode);
            } else {
                /* transfer fd to new name */
                if (a2) {
                    k1->aino = a2;
-                   k1->fd = my_open (a2->nname, mode);
+                   k1->fd = fs_open (unit, a2->nname, mode);
                    write_log ("restoring new handle '%s' %d\n", a2->nname, k1->dosmode);
                } else {
                    write_log ("no new handle, deleting old lock(s).\n");
@@ -3082,7 +3177,7 @@ static void relock_re(Unit *unit, a_inode *a1, a_inode *a2, int failed)
                write_log ("relocking failed '%s' -> '%s'\n", a1->nname, a2->nname);
                free_key (unit, k1);
            } else {
-               my_lseek (k1->fd, k1->file_pos, SEEK_SET);
+               fs_lseek (unit, k1->fd, k1->file_pos, SEEK_SET);
            }
        }
     }
@@ -4057,7 +4152,7 @@ static int rdb_mount (UnitInfo *uip, int unit_no, int partnum, uaecptr parmpacke
            rdblock, fileblock, hfd->cylinders, hfd->sectors, hfd->heads);
     }
 
-    buf = xmalloc (readblocksize);
+    buf = (uae_u8*)xmalloc (readblocksize);
     for (i = 0; i <= partnum; i++) {
        if (i == 0)
            partblock = rl (bufrdb + 28);
@@ -4167,7 +4262,7 @@ static int rdb_mount (UnitInfo *uip, int unit_no, int partnum, uaecptr parmpacke
        put_byte (parmpacket + PP_FSHDSTART + i, buf[32 + i]);
     put_long (parmpacket + PP_FSHDSTART, dostype);
     /* we found required FSHD block */
-    fsmem = xmalloc (262144);
+    fsmem = (uae_u8*)xmalloc (262144);
     lsegblock = rl (buf + 72);
     i = 0;
     for (;;) {
@@ -4256,7 +4351,7 @@ static void dofakefilesys (UnitInfo *uip, uaecptr parmpacket)
     zfile_fseek (zf, 0, SEEK_END);
     size = zfile_ftell (zf);
     zfile_fseek (zf, 0, SEEK_SET);
-    uip->rdb_filesysstore = xmalloc (size);
+    uip->rdb_filesysstore = (uae_u8*)xmalloc (size);
     zfile_fread (uip->rdb_filesysstore, size, 1, zf);
     zfile_fclose (zf);
     uip->rdb_filesyssize = size;
@@ -4470,7 +4565,7 @@ static a_inode *restore_filesys_get_base(Unit *u, char *npath)
     /* iterate from root to last to previous path part,
      * create ainos if not already created.
      */
-    path = xcalloc(strlen(npath) + 2, 1);
+    path = (char*)xcalloc(strlen(npath) + 2, 1);
     cnt = 1;
     for (;;) {
        strcpy (path, npath);
@@ -4556,7 +4651,7 @@ static uae_u8 *restore_aino(UnitInfo *ui, Unit *u, uae_u8 *src)
     a_inode *base, *a;
 
     missing = 0;
-    a = xcalloc (sizeof (a_inode), 1);
+    a = (a_inode*)xcalloc (sizeof (a_inode), 1);
     a->uniq = restore_u64 ();
     a->locked_children = restore_u32 ();
     a->exnext_count = restore_u32 ();
@@ -4604,7 +4699,7 @@ static uae_u8 *restore_aino(UnitInfo *ui, Unit *u, uae_u8 *src)
            write_log("*** FS: File '%s' missing!\n", a->nname);
     }
     if (base) {
-       fsdb_fill_file_attrs (base, a);
+       fill_file_attrs (u, base, a);
        init_child_aino_tree (u, base, a);
     } else {
        write_log("*** FS: parent directory missing '%s' ('%s')\n", a->aname, a->nname);
@@ -4633,7 +4728,7 @@ static uae_u8 *restore_key(UnitInfo *ui, Unit *u, uae_u8 *src)
     Key *k;
 
     missing = 0;
-    k = xcalloc(sizeof(Key), 1);
+    k = (Key*)xcalloc(sizeof(Key), 1);
     k->uniq = restore_u64();
     k->file_pos = restore_u32();
     k->createmode = restore_u32();
@@ -4657,9 +4752,9 @@ static uae_u8 *restore_key(UnitInfo *ui, Unit *u, uae_u8 *src)
            write_log("*** FS: Open file '%s' aino id %d != %d\n", p, uniq, a->uniq);
        if (!my_existsfile(pn)) {
            write_log("*** FS: Open file '%s' is missing, creating dummy file!\n", p);
-           k->fd = my_open (pn, openmode | O_CREAT |O_BINARY);
+           k->fd = fs_open (u, pn, openmode | O_CREAT |O_BINARY);
            if (k->fd) {
-               uae_u8 *buf = xcalloc (10000, 1);
+               uae_u8 *buf = (uae_u8*)xcalloc (10000, 1);
                int sp = savedsize;
                while (sp) {
                    int s = sp >= 10000 ? 10000 : sp;
@@ -4672,21 +4767,21 @@ static uae_u8 *restore_key(UnitInfo *ui, Unit *u, uae_u8 *src)
                write_log("*** FS: Open file '%s', couldn't create dummy file!\n", p);
            }
        } else {
-           k->fd = my_open (pn, openmode | O_BINARY);
+           k->fd = fs_open (u, pn, openmode | O_BINARY);
        }
        if (!k->fd) {
            write_log("*** FS: Open file '%s' failed to open!\n", p);
            missing = 1;
        } else {
            size_t s;
-           s = my_lseek (k->fd, 0, SEEK_END);
+           s = fs_lseek (u, k->fd, 0, SEEK_END);
            if (s != savedsize)
                write_log("FS: restored file '%s' size changed! orig=%d, now=%d!!\n", p, savedsize, s);
            if (k->file_pos > s) {
                write_log("FS: restored filepos larger than size of file '%s'!! %d > %d\n", p, k->file_pos, s);
                k->file_pos = s;
            }
-           my_lseek (k->fd, k->file_pos, SEEK_SET);
+           fs_lseek (u,k->fd, k->file_pos, SEEK_SET);
        }
     }
     xfree (p);
@@ -4701,13 +4796,13 @@ static uae_u8 *restore_key(UnitInfo *ui, Unit *u, uae_u8 *src)
 
 static uae_u8 *restore_notify(UnitInfo *ui, Unit *u, uae_u8 *src)
 {
-    Notify *n = xcalloc (sizeof (Notify), 1);
+    Notify *n = (Notify*)xcalloc (sizeof (Notify), 1);
     uae_u32 hash;
     char *s;
 
     n->notifyrequest = restore_u32();
     s = restore_string();
-    n->fullname = xmalloc (strlen(ui->volname) + 2 + strlen(s) + 1);
+    n->fullname = (char*)xmalloc (strlen(ui->volname) + 2 + strlen(s) + 1);
     sprintf (n->fullname, "%s:%s", ui->volname, s);
     xfree(s);
     s = strrchr(n->fullname, '/');
@@ -4773,7 +4868,7 @@ static uae_u8 *restore_filesys_virtual (UnitInfo *ui, uae_u8 *src)
 
 static char *getfullaname(a_inode *a)
 {
-    char *p = xmalloc (2000);
+    char *p = (char*)xmalloc (2000);
     int first = 1;
 
     memset(p, 0, 2000);
@@ -4935,7 +5030,7 @@ uae_u8 *save_filesys_common (int *len)
     uae_u8 *dstbak, *dst;
     if (nr_units() == 0)
        return NULL;
-    dstbak = dst = malloc (10000);
+    dstbak = dst = (uae_u8*)malloc (10000);
     save_u32 (2);
     save_u64 (a_uniq);
     save_u64 (key_uniq);
@@ -4961,7 +5056,7 @@ uae_u8 *save_filesys (int num, int *len)
 
     ui = &mountinfo.ui[num];
     write_log("FS_FILESYS: '%s' '%s'\n", ui->devname, ui->volname);
-    dstbak = dst = malloc (10000);
+    dstbak = dst = (uae_u8*)malloc (10000);
     save_u32 (2); /* version */
     save_u32 (ui->devno);
     save_u16 (type);
diff --git a/fpp.c b/fpp.c
index 01e1b6871defbafcd61748e739a5a1d829ca663b..e5b0f12bc817a84b9284bcb2c5e07e7b4fd43981 100755 (executable)
--- a/fpp.c
+++ b/fpp.c
@@ -10,6 +10,7 @@
 #define __USE_ISOC9X  /* We might be able to pick up a NaN */
 
 #include <math.h>
+#include <float.h>
 
 #include "sysconfig.h"
 #include "sysdeps.h"
@@ -199,6 +200,11 @@ static int get_fpu_version(void)
     return v;
 }
 
+#define fp_round_to_minus_infinity(x) fp_floor(x)
+#define fp_round_to_plus_infinity(x) fp_ceil(x)
+#define fp_round_to_zero(x) ((int)(x))
+#define fp_round_to_nearest(x) ((int)((x) + 0.5))
+
 STATIC_INLINE tointtype toint(fptype src, fptype minval, fptype maxval)
 {
     if (src < minval)
@@ -216,16 +222,24 @@ STATIC_INLINE tointtype toint(fptype src, fptype minval, fptype maxval)
        return (tointtype)tmp_fp;
     }
 #else /* no X86_MSVC */
-    switch ((regs.fpcr >> 4) & 3) {
-    case 0: /* to nearest */
-       return (tointtype)floor (src + 0.5);
-    case 1: /* to zero */
-       return (tointtype)src;
-    case 2: /* down */
-       return (tointtype)floor (src);
-    case 3: /* up */
-       return (tointtype)ceil (src);
-  }
+    switch (get_fpcr() & 0x30) {
+       case FPCR_ROUND_ZERO:
+       result = fp_round_to_zero(src);
+       break;
+       case FPCR_ROUND_MINF:
+       result = fp_round_to_minus_infinity(src);
+       break;
+       case FPCR_ROUND_NEAR:
+       result = fp_round_to_nearest(src);
+       break;
+       case FPCR_ROUND_PINF:
+       result = fp_round_to_plus_infinity(src);
+       break;
+       default:
+       result = src; /* should never be reached */
+       break;
+    }
+    return result;
 #endif
 }
 
@@ -674,9 +688,8 @@ STATIC_INLINE int get_fp_ad (uae_u32 opcode, uae_u32 * ad)
 
 STATIC_INLINE int fpp_cond (uae_u32 opcode, int contition)
 {
-    int N = (regs.fp_result<0);
-    int Z = (regs.fp_result==0);
-    /* int I = (regs.fpsr & 0x2000000) != 0; */
+    int N = (regs.fp_result < 0.0);
+    int Z = (regs.fp_result == 0.0);
     int NotANumber = 0;
 
 #ifdef HAVE_ISNAN
@@ -744,11 +757,7 @@ STATIC_INLINE int fpp_cond (uae_u32 opcode, int contition)
     case 0x1b:
        return NotANumber || Z || !N;
     case 0x1c:
-#if 0
-       return NotANumber || (Z && N); /* This is wrong, compare 0x0c */
-#else
        return NotANumber || (N && !Z);
-#endif
     case 0x1d:
        return NotANumber || Z || N;
     case 0x1e:
@@ -759,7 +768,7 @@ STATIC_INLINE int fpp_cond (uae_u32 opcode, int contition)
     return -1;
 }
 
-void fdbcc_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
+void fpuop_dbcc (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
 {
     uaecptr pc = (uae_u32) m68k_getpc (regs);
     uae_s32 disp = (uae_s32) (uae_s16) next_iword (regs);
@@ -782,7 +791,7 @@ void fdbcc_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
     }
 }
 
-void fscc_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
+void fpuop_scc (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
 {
     uae_u32 ad;
     int cc;
@@ -806,7 +815,7 @@ void fscc_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
     }
 }
 
-void ftrapcc_opp (uae_u32 opcode, struct regstruct *regs, uaecptr oldpc)
+void fpuop_trapcc (uae_u32 opcode, struct regstruct *regs, uaecptr oldpc)
 {
     int cc;
 
@@ -822,7 +831,7 @@ void ftrapcc_opp (uae_u32 opcode, struct regstruct *regs, uaecptr oldpc)
        Exception (7, regs, oldpc - 2);
 }
 
-void fbcc_opp (uae_u32 opcode, struct regstruct *regs, uaecptr pc, uae_u32 extra)
+void fpuop_bcc (uae_u32 opcode, struct regstruct *regs, uaecptr pc, uae_u32 extra)
 {
     int cc;
 
@@ -840,7 +849,7 @@ void fbcc_opp (uae_u32 opcode, struct regstruct *regs, uaecptr pc, uae_u32 extra
     }
 }
 
-void fsave_opp (uae_u32 opcode, struct regstruct *regs)
+void fpuop_save (uae_u32 opcode, struct regstruct *regs)
 {
     uae_u32 ad;
     int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
@@ -910,7 +919,7 @@ void fsave_opp (uae_u32 opcode, struct regstruct *regs)
        m68k_areg (regs, opcode & 7) = ad;
 }
 
-void frestore_opp (uae_u32 opcode, struct regstruct *regs)
+void fpuop_restore (uae_u32 opcode, struct regstruct *regs)
 {
     uae_u32 ad;
     uae_u32 d;
@@ -999,7 +1008,7 @@ static void fround (int reg)
     regs.fp[reg] = (float)regs.fp[reg];
 }
 
-void fpp_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
+void fpuop_arithmetic (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
 {
     int reg;
     fptype src;
@@ -1118,7 +1127,6 @@ void fpp_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
                op_illg (opcode, regs);
                return;
            }
-           //ad = (opcode & 0x38) == 0x20 ? ad - 12 : ad;
            if((opcode & 0x38) == 0x20) {
                if (extra & 0x1000)
                    incr += 4;
@@ -1144,7 +1152,7 @@ void fpp_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
            if ((opcode & 0x38) == 0x18)
                m68k_areg (regs, opcode & 7) = ad;
            if ((opcode & 0x38) == 0x20)
-               m68k_areg (regs, opcode & 7) = ad - 12;
+               m68k_areg (regs, opcode & 7) = ad - incr;
        }
        return;
 
@@ -1178,26 +1186,34 @@ void fpp_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
                incr = 1;
                break;
            }
-           while (list) {
-               uae_u32 wrd1, wrd2, wrd3;
-               if (incr < 0) {
-                   from_exten (regs->fp[fpp_movem_index2[list]], &wrd1, &wrd2, &wrd3);
-                   ad -= 4;
-                   put_long (ad, wrd3);
-                   ad -= 4;
-                   put_long (ad, wrd2);
-                   ad -= 4;
-                   put_long (ad, wrd1);
-               } else {
-                   from_exten (regs->fp[fpp_movem_index1[list]], &wrd1, &wrd2, &wrd3);
-                   put_long (ad, wrd1);
-                   ad += 4;
-                   put_long (ad, wrd2);
-                   ad += 4;
-                   put_long (ad, wrd3);
-                   ad += 4;
+           if (incr < 0) {
+               for (reg = 7; reg >= 0; reg--) {
+                   uae_u32 wrd1, wrd2, wrd3;
+                   if (list & 0x80) {
+                       from_exten (regs->fp[reg], &wrd1, &wrd2, &wrd3);
+                       ad -= 4;
+                       put_long (ad, wrd3);
+                       ad -= 4;
+                       put_long (ad, wrd2);
+                       ad -= 4;
+                       put_long (ad, wrd1);
+                   }
+                   list <<= 1;
+               }
+           } else {
+               for (reg = 0; reg <= 7; reg++) {
+                   uae_u32 wrd1, wrd2, wrd3;
+                   if (list & 0x80) {
+                       from_exten (regs->fp[reg], &wrd1, &wrd2, &wrd3);
+                       put_long (ad, wrd1);
+                       ad += 4;
+                       put_long (ad, wrd2);
+                       ad += 4;
+                       put_long (ad, wrd3);
+                       ad += 4;
+                   }
+                   list <<= 1;
                }
-               list = fpp_movem_next[list];
            }
            if ((opcode & 0x38) == 0x18)
                m68k_areg (regs, opcode & 7) = ad;
@@ -1228,26 +1244,34 @@ void fpp_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
                incr = 1;
                break;
            }
-           while (list) {
-               uae_u32 wrd1, wrd2, wrd3;
-               if (incr < 0) {
-                   ad -= 4;
-                   wrd3 = get_long (ad);
-                   ad -= 4;
-                   wrd2 = get_long (ad);
-                   ad -= 4;
-                   wrd1 = get_long (ad);
-                   regs->fp[fpp_movem_index2[list]] = to_exten (wrd1, wrd2, wrd3);
-               } else {
-                   wrd1 = get_long (ad);
-                   ad += 4;
-                   wrd2 = get_long (ad);
-                   ad += 4;
-                   wrd3 = get_long (ad);
-                   ad += 4;
-                   regs->fp[fpp_movem_index1[list]] = to_exten (wrd1, wrd2, wrd3);
+           if (incr < 0) {
+               for (reg = 7; reg >= 0; reg--) {
+                   uae_u32 wrd1, wrd2, wrd3;
+                   if (list & 0x80) {
+                       ad -= 4;
+                       wrd3 = get_long (ad);
+                       ad -= 4;
+                       wrd2 = get_long (ad);
+                       ad -= 4;
+                       wrd1 = get_long (ad);
+                       regs->fp[reg] = to_exten(wrd1, wrd2, wrd3);
+                   }
+                   list <<= 1;
+               }
+           } else {
+               for (reg = 0; reg <= 7; reg++) {
+                   uae_u32 wrd1, wrd2, wrd3;
+                   if (list & 0x80) {
+                       wrd1 = get_long (ad);
+                       ad += 4;
+                       wrd2 = get_long (ad);
+                       ad += 4;
+                       wrd3 = get_long (ad);
+                       ad += 4;
+                       regs->fp[reg] = to_exten(wrd1, wrd2, wrd3);
+                   }
+                   list <<= 1;
                }
-               list = fpp_movem_next[list];
            }
            if ((opcode & 0x38) == 0x18)
                m68k_areg (regs, opcode & 7) = ad;
@@ -1333,7 +1357,7 @@ void fpp_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
                op_illg (opcode, regs);
                return;
            }
-           MAKE_FPSR (regs, regs->fp[reg]); /* see Motorola 68k Manual */
+           MAKE_FPSR (regs, regs->fp[reg]);
            return;
        }
        if (get_fp_value (opcode, extra, &src) == 0) {
@@ -1391,10 +1415,7 @@ void fpp_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
            regs->fp[reg] = sinh (src);
            break;
        case 0x03: /* FINTRZ */
-           if (src >= 0.0)
-               regs->fp[reg] = floor (src);
-           else
-               regs->fp[reg] = ceil (src);
+           regs->fp[reg] = fp_round_to_zero(src);
            break;
        case 0x04: /* FSQRT */
        case 0x41:
@@ -1474,15 +1495,23 @@ void fpp_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
            break;
        case 0x1e: /* FGETEXP */
            {
-             int expon;
-             frexp (src, &expon);
-             regs->fp[reg] = (double) (expon - 1);
+               if (src == 0) {
+                   regs->fp[reg] = 0;
+               } else {
+                   int expon;
+                   frexp (src, &expon);
+                   regs->fp[reg] = (double) (expon - 1);
+               }
            }
            break;
        case 0x1f: /* FGETMAN */
            {
-             int expon;
-             regs->fp[reg] = frexp (src, &expon) * 2.0;
+               if (src == 0) {
+                   regs->fp[reg] = 0;
+               } else {
+                 int expon;
+                 regs->fp[reg] = frexp (src, &expon) * 2.0;
+               }
            }
            break;
        case 0x20: /* FDIV */
@@ -1494,12 +1523,8 @@ void fpp_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
            break;
        case 0x21: /* FMOD */
            {
-             fptype divi = regs->fp[reg] / src;
-
-             if (divi >= 0.0)
-               regs->fp[reg] -= src * floor (divi);
-             else
-               regs->fp[reg] -= src * ceil (divi);
+               fptype quot = fp_round_to_zero(regs->fp[reg] / src);
+               regs->fp[reg] = regs->fp[reg] - quot * src;
            }
            break;
        case 0x22: /* FADD */
@@ -1520,14 +1545,19 @@ void fpp_opp (uae_u32 opcode, struct regstruct *regs, uae_u16 extra)
            regs->fp[reg] /= src;
            break;
        case 0x25: /* FREM */
-           regs->fp[reg] -= src * floor ((regs->fp[reg] / src) + 0.5);
+           {
+               fptype quot = fp_round_to_nearest(regs->fp[reg] / src);
+               regs->fp[reg] = regs->fp[reg] - quot * src;
+           }
            break;
        case 0x26: /* FSCALE */
+           if (src != 0) {
 #ifdef ldexp
-           regs->fp[reg] = ldexp (regs->fp[reg], (int) src);
+               regs->fp[reg] = ldexp (regs->fp[reg], (int) src);
 #else
-           regs->fp[reg] *= exp (*fp_ln_2 * (int) src);
+               regs->fp[reg] *= exp (*fp_ln_2 * (int) src);
 #endif
+           }
            break;
        case 0x27: /* FSGLMUL */
            regs->fp[reg] *= src;
@@ -1609,7 +1639,7 @@ uae_u8 *save_fpu (int *len, uae_u8 *dstptr)
     if (dstptr)
        dstbak = dst = dstptr;
     else
-       dstbak = dst = malloc(4+4+8*10+4+4+4+4+4);
+       dstbak = dst = (uae_u8*)malloc(4+4+8*10+4+4+4+4+4);
     save_u32 (currprefs.fpu_model);
     save_u32 (0x80000000);
     for (i = 0; i < 8; i++) {
diff --git a/fsdb.c b/fsdb.c
index aee14690013ae074e7ed9ee6a94287fb7b1396dc..3552b92ead9b63b67a11038c1e29263fe67ccdcb 100755 (executable)
--- a/fsdb.c
+++ b/fsdb.c
@@ -331,7 +331,7 @@ void fsdb_dir_writeback (a_inode *dir)
     fseek (f, 0, SEEK_SET);
     tmpbuf = 0;
     if (size > 0) {
-       tmpbuf = malloc (size);
+       tmpbuf = (uae_u8*)malloc (size);
        fread (tmpbuf, 1, size, f);
     }
     TRACE (("**** updating '%s' %d\n", dir->aname, size));
diff --git a/gayle.c b/gayle.c
index 5efc65367a9f77b784c1801972e27880f28f678b..53ad8f7f2fa76f7a495dce710993a4725d17248d 100755 (executable)
--- a/gayle.c
+++ b/gayle.c
@@ -150,7 +150,7 @@ static int ide_drv, ide2, ide_splitter;
 
 static struct ide_hdf *ide;
 
-STATIC_INLINE pw(int offset, uae_u16 w)
+STATIC_INLINE void pw(int offset, uae_u16 w)
 {
     ide->secbuf[offset * 2 + 0] = (uae_u8)w;
     ide->secbuf[offset * 2 + 1] = w >> 8;
@@ -1201,7 +1201,7 @@ uae_u8 *save_gayle (int *len)
 
     if (currprefs.cs_ide <= 0)
        return NULL;
-    dstbak = dst = malloc (1000);
+    dstbak = dst = (uae_u8*)malloc (1000);
     save_u8 (currprefs.cs_ide);
     save_u8 (gayle_intena);
     save_u8 (gayle_irq);
@@ -1218,7 +1218,7 @@ uae_u8 *save_ide (int num, int *len)
        return NULL;
     if (ide->hdhfd.size == 0)
        return NULL;
-    dstbak = dst = malloc (1000);
+    dstbak = dst = (uae_u8*)malloc (1000);
     save_u32(num);
     save_u64(ide->hdhfd.size);
     save_string(ide->hdhfd.path);
index ffc83489b17ba2ba9a65a9fff03d103580e60c85..293630c1d08ecac1e17daafb3da863b504689f7a 100755 (executable)
--- a/gencpu.c
+++ b/gencpu.c
@@ -2762,19 +2762,19 @@ static void gen_opcode (unsigned long int opcode)
        fpulimit();
        genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
        sync_m68k_pc ();
-       printf ("\tfpp_opp(opcode, regs, extra);\n");
+       printf ("\tfpuop_arithmetic(opcode, regs, extra);\n");
        break;
     case i_FDBcc:
        fpulimit();
        genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
        sync_m68k_pc ();
-       printf ("\tfdbcc_opp(opcode, regs, extra);\n");
+       printf ("\tfpuop_dbcc(opcode, regs, extra);\n");
        break;
     case i_FScc:
        fpulimit();
        genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
        sync_m68k_pc ();
-       printf ("\tfscc_opp(opcode, regs, extra);\n");
+       printf ("\tfpuop_scc(opcode, regs, extra);\n");
        break;
     case i_FTRAPcc:
        fpulimit();
@@ -2784,7 +2784,7 @@ static void gen_opcode (unsigned long int opcode)
        if (curi->smode != am_unknown && curi->smode != am_illg)
            genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0);
        sync_m68k_pc ();
-       printf ("\tftrapcc_opp(opcode, regs, oldpc);\n");
+       printf ("\tfpuop_trapcc(opcode, regs, oldpc);\n");
        break;
     case i_FBcc:
        fpulimit();
@@ -2793,17 +2793,17 @@ static void gen_opcode (unsigned long int opcode)
        printf ("\tuaecptr pc = m68k_getpc(regs);\n");
        genamode (curi->dmode, "srcreg", curi->size, "extra", 1, 0, 0);
        sync_m68k_pc ();
-       printf ("\tfbcc_opp(opcode,regs, pc,extra);\n");
+       printf ("\tfpuop_bcc(opcode,regs, pc,extra);\n");
        break;
     case i_FSAVE:
        fpulimit();
        sync_m68k_pc ();
-       printf ("\tfsave_opp(opcode, regs);\n");
+       printf ("\tfpuop_save(opcode, regs);\n");
        break;
     case i_FRESTORE:
        fpulimit();
        sync_m68k_pc ();
-       printf ("\tfrestore_opp(opcode, regs);\n");
+       printf ("\tfpuop_restore(opcode, regs);\n");
        break;
 
      case i_CINVL:
index 3cb7130c68b4ed286d8093832a3e32f8c9a92cb5..fd41ab45ad15ae69011a2718d271d3668142287b 100755 (executable)
@@ -185,7 +185,7 @@ static void create_virtual_rdb(struct hardfiledata *hfd, uae_u32 dostype, int bo
     int cyls = 262144 / (cyl * 512);
     int size = cyl * cyls * 512;
 
-    rdb = xcalloc (size, 1);
+    rdb = (uae_u8*)xcalloc (size, 1);
     hfd->virtual_rdb = rdb;
     hfd->virtual_size = size;
     part = rdb + 512;
@@ -1083,7 +1083,7 @@ static uae_u32 REGPARAM2 hardfile_beginio (TrapContext *context)
 
 static void *hardfile_thread (void *devs)
 {
-    struct hardfileprivdata *hfpd = devs;
+    struct hardfileprivdata *hfpd = (struct hardfileprivdata*)devs;
 
     uae_set_thread_priority (2);
     hfpd->thread_running = 1;
index 989969c798fef1565f0310ba56cd9e4037bf3f96..9cb218655260a3fd42ec3e8b8321e18c0ae09ae3 100755 (executable)
@@ -1,6 +1,6 @@
 
 #define MAX_TOTAL_DEVICES 8
-#define DEVICE_SCSI_BUFSIZE 65536
+#define DEVICE_SCSI_BUFSIZE (65536 - 1024)
 
 //#define device_debug write_log
 #define device_debug
index 23d1fa083c0f935bc11f70c565d2a333e5d67cb7..203c2342d3a3e4e6ad86eb9981f8e2b1469e1df2 100755 (executable)
@@ -20,7 +20,7 @@ int cdtv_add_scsi_unit(int ch, char *path, int blocksize, int readonly,
                       char *devname, int sectors, int surfaces, int reserved,
                       int bootpri, char *filesys);
 
-extern void cdtv_getdmadata(int *);
+extern void cdtv_getdmadata(uae_u32*);
 
 #endif
 
index 53bee8eed13687bb9f1a6f972f18307cc047f9be..8a9fe5e574d9e0ec3880b687615ab3cb76788fab 100755 (executable)
@@ -486,7 +486,7 @@ extern void empty_optimizer(void);
 #define comp_get_ilong(o) do_get_mem_long((uae_u32 *)(comp_pc_p + (o)))
 
 /* Preferences handling */
-void check_prefs_changed_comp (void);
+int check_prefs_changed_comp (void);
 
 struct blockinfo_t;
 
index 9c69d7c9b94435d3cdeca9ae7d48a3d69c9863ee..55722cc562d6eb0f5e05d2054b52312cbb5252f9 100755 (executable)
@@ -1,2 +1,5 @@
 extern uae_u32 get_crc32 (uae_u8 *p, int size);
 extern uae_u16 get_crc16 (uae_u8 *p, int size);
+extern void get_sha1 (uae_u8 *p, int size, uae_u8 *out);
+extern char *get_sha1_txt (uae_u8 *p, int size);
+#define SHA1_SIZE 20
index a0af730e57a1bc4c561abd2b794e7b45d5e331e4..1bd7f11d068942f3360dc62135886f7be2089e9a 100755 (executable)
@@ -36,6 +36,8 @@ struct hardfiledata {
     uae_u64 virtual_size;
 };
 
+#define HFD_FLAGS_REALDRIVE 1
+
 struct hd_hardfiledata {
     struct hardfiledata hfd;
     int bootpri;
index 4a8c523a338dea7bad81b85f06590ade2fb6ac89..cadb25ab0a5aa0d657ebb1ccada758fe3f28260b 100755 (executable)
@@ -144,5 +144,6 @@ extern int custom_fsdb_used_as_nname (a_inode *base, const char *nname);
 
 #define MYVOLUMEINFO_READONLY 1
 #define MYVOLUMEINFO_STREAMS 2
+#define MYVOLUMEINFO_ARCHIVE 4
 
 extern int my_getvolumeinfo (char *root);
index 8b0faaa3f0dfe2ecc83622e1e0d65eef0f4825ec..e77e89d8c713c05ab5113eb5038c99e418a0c3bc 100755 (executable)
@@ -17,7 +17,9 @@ extern void PAL_1x1_16(uae_u16 *src, int pitchs, uae_u16 *trg, int pitcht, int w
 typedef unsigned char uint8;
 typedef unsigned short uint16;
 typedef unsigned long uint32;
+#ifndef __cplusplus
 typedef int bool;
+#endif
 
 extern void S2X_configure (int rb, int gb, int bb, int rs, int gs, int bs);
 extern int Init_2xSaI(int rb, int gb, int bb, int rs, int gs, int bs);
index 31edc5f26fb683b3b26cbe232bc0e1a5e7832b86..c5729b5214290b6426326220aeb3fc577feb168e 100755 (executable)
@@ -346,12 +346,13 @@ struct romdata {
     int ver, rev;
     int subver, subrev;
     char *model;
-    uae_u32 crc32;
     uae_u32 size;
     int id;
     int cpu;
     int cloanto;
     int type;
+    uae_u32 crc32;
+    uae_u32 sha1[5];
     char *configname;
 };
 
index b4e15a255797812322668f3d75e190a2e0ae3340..f3ef02fcf969e72865e9edc83a53981df06f33b7 100755 (executable)
@@ -1,4 +1,4 @@
-void ncr_bput2(uacptr, uae_u32);
+void ncr_bput2(uaecptr, uae_u32);
 uae_u32 ncr_bget2(uaecptr);
 
 extern void ncr_init(void);
index d7b1bf2bd96eb5c518077b7629c8bf7d1961f209..8a7d5c2d8e4aa4570057375a739d449d3fb05023 100755 (executable)
@@ -325,13 +325,13 @@ extern int getDivs68kCycles(uae_s32 dividend, uae_s16 divisor);
 extern void mmu_op       (uae_u32, struct regstruct *regs, uae_u32);
 extern void mmu_op30     (uaecptr, uae_u32, struct regstruct *regs, int, uaecptr);
 
-extern void fpp_opp      (uae_u32, struct regstruct *regs, uae_u16);
-extern void fdbcc_opp    (uae_u32, struct regstruct *regs, uae_u16);
-extern void fscc_opp     (uae_u32, struct regstruct *regs, uae_u16);
-extern void ftrapcc_opp  (uae_u32, struct regstruct *regs, uaecptr);
-extern void fbcc_opp     (uae_u32, struct regstruct *regs, uaecptr, uae_u32);
-extern void fsave_opp    (uae_u32, struct regstruct *regs);
-extern void frestore_opp (uae_u32, struct regstruct *regs);
+extern void fpuop_arithmetic(uae_u32, struct regstruct *regs, uae_u16);
+extern void fpuop_dbcc(uae_u32, struct regstruct *regs, uae_u16);
+extern void fpuop_scc(uae_u32, struct regstruct *regs, uae_u16);
+extern void fpuop_trapcc(uae_u32, struct regstruct *regs, uaecptr);
+extern void fpuop_bcc(uae_u32, struct regstruct *regs, uaecptr, uae_u32);
+extern void fpuop_save(uae_u32, struct regstruct *regs);
+extern void fpuop_restore(uae_u32, struct regstruct *regs);
 extern uae_u32 fpp_get_fpsr (const struct regstruct *regs);
 
 extern void exception3 (uae_u32 opcode, uaecptr addr, uaecptr fault);
@@ -381,7 +381,7 @@ void newcpu_showstate(void);
 #ifdef JIT
 extern void flush_icache(int n);
 extern void compemu_reset(void);
-extern void check_prefs_changed_comp (void);
+extern int check_prefs_changed_comp (void);
 #else
 #define flush_icache(X) do {} while (0)
 #endif
index d812a0e7a164ef50aa3c945cd4d0c1997230fd52..521b0fef2d83a67dc4e17ba01ee76cb98ed6acbd 100755 (executable)
@@ -1,4 +1,7 @@
- /*
+#ifndef UAE_SYSDEPS_H
+#define UAE_SYSDEPS_H
+
+/*
   * UAE - The Un*x Amiga Emulator
   *
   * Try to include the right system headers and get other system-specific
@@ -531,3 +534,5 @@ extern void log_close(void *f);
 #  define bswap_32(x) (((x) << 24) | (((x) << 8) & 0x00FF0000) | (((x) >> 8) & 0x0000FF00) | ((x) >> 24))
 # endif
 #endif
+
+#endif
diff --git a/include/zarchive.h b/include/zarchive.h
new file mode 100755 (executable)
index 0000000..545c53c
--- /dev/null
@@ -0,0 +1,99 @@
+
+struct zfile {
+    char *name;
+    char *zipname;
+    FILE *f;
+    uae_u8 *data;
+    int size;
+    int seek;
+    int deleteafterclose;
+    struct zfile *next;
+};
+
+struct znode {
+    int isfile;
+    struct znode *sibling;
+    struct znode *child;
+    struct zvolume *vchild;
+    struct znode *parent;
+    struct zvolume *volume;
+    struct znode *next;
+    struct znode *prev;
+    char *name;
+    char *fullname;
+    unsigned int size;
+    struct zfile *f;
+    char *comment;
+    int flags;
+    time_t mtime;
+    /* decompressor specific */
+    unsigned int offset;
+    unsigned int offset2;
+    unsigned int method;
+    unsigned int packedsize;
+};
+
+struct zvolume
+{
+    struct zfile *archive;
+    void *handle;
+    struct znode root;
+    struct zvolume *next;
+    struct znode *last;
+    unsigned int size;
+    unsigned int blocks;
+    unsigned int id;
+    unsigned int archivesize;
+    unsigned int method;
+};
+
+struct zarchive_info
+{
+    char *name;
+    unsigned int size;
+    int flags;
+    char *comment;
+    time_t t;
+};
+
+#define ArchiveFormat7Zip '7z  '
+#define ArchiveFormatRAR 'rar '
+#define ArchiveFormatZIP 'zip '
+#define ArchiveFormatLHA 'lha '
+#define ArchiveFormatLZX 'lzx '
+#define ArchiveFormatPLAIN '----'
+#define ArchiveFormatAA 'aa  ' // method only
+
+extern int zfile_is_ignore_ext(const char *name);
+
+extern struct zvolume *zvolume_alloc(struct zfile *z, unsigned int id, void *handle);
+
+extern struct znode *zvolume_addfile_abs(struct zvolume *zv, struct zarchive_info*);
+extern struct znode *zvolume_adddir_abs(struct zvolume *zv, struct zarchive_info *zai);
+extern struct znode *znode_adddir(struct znode *parent, const char *name, struct zarchive_info*);
+
+extern struct zvolume *archive_directory_plain(struct zfile *zf);
+extern struct zfile *archive_access_plain (struct znode *zn);
+extern struct zvolume *archive_directory_lha(struct zfile *zf);
+extern struct zfile *archive_access_lha (struct znode *zn);
+extern struct zvolume *archive_directory_zip(struct zfile *zf);
+extern struct zfile *archive_access_zip (struct znode *zn);
+extern struct zvolume *archive_directory_7z (struct zfile *z);
+extern struct zfile *archive_access_7z (struct znode *zn);
+extern struct zvolume *archive_directory_rar (struct zfile *z);
+extern struct zfile *archive_access_rar (struct znode *zn);
+extern struct zvolume *archive_directory_lzx (struct zfile *in_file);
+extern struct zfile *archive_access_lzx (struct znode *zn);
+extern struct zvolume *archive_directory_arcacc (struct zfile *z, unsigned int id);
+extern struct zfile *archive_access_arcacc (struct znode *zn);
+
+extern struct zfile *archive_access_select (struct zfile *zf, unsigned int id);
+extern struct zfile *archive_access_arcacc_select (struct zfile *zf, unsigned int id);
+
+
+
+extern void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user, unsigned int id);
+
+extern void archive_access_close (void *handle, unsigned int id);
+
+extern struct zfile *archive_getzfile(struct znode *zn, unsigned int id);
index 3a4c2436bbf1b368b5c53423cc0c60caaac231f1..456d9539df8845e2bd93581fd466cde3c09e71b4 100755 (executable)
@@ -7,6 +7,7 @@
   */
 
 struct zfile;
+struct zvolume;
 
 typedef int (*zfile_callback)(struct zfile*, void*);
 
@@ -20,6 +21,8 @@ extern long zfile_ftell (struct zfile *z);
 extern size_t zfile_fread  (void *b, size_t l1, size_t l2, struct zfile *z);
 extern size_t zfile_fwrite  (void *b, size_t l1, size_t l2, struct zfile *z);
 extern size_t zfile_fputs (struct zfile *z, char *s);
+extern int zfile_getc (struct zfile *z);
+extern int zfile_ferror (struct zfile *z);
 extern void zfile_exit (void);
 extern int execute_command (char *);
 extern int zfile_iscompressed (struct zfile *z);
@@ -45,3 +48,17 @@ extern int zfile_isdiskimage (const char *name);
 extern const char *uae_archive_extensions[];
 extern const char *uae_ignoreextensions[];
 extern const char *uae_diskimageextensions[];
+
+extern struct zvolume *zfile_fopen_archive(const char *filename);
+extern void zfile_fclose_archive(struct zvolume *zv);
+extern int zfile_fs_usage_archive(const char *path, const char *disk, struct fs_usage *fsp);
+extern int zfile_stat_archive(const char *path, struct stat *statbuf);
+extern void *zfile_opendir_archive(const char *path);
+extern void zfile_closedir_archive(void*);
+extern int zfile_readdir_archive(void*, char*);
+extern zfile_fill_file_attrs_archive(const char *path, int *isdir, int *flags, char **comment);
+extern unsigned int zfile_lseek_archive (void *d, unsigned int offset, int whence);
+extern unsigned int zfile_read_archive (void *d, void *b, unsigned int size);
+extern void zfile_close_archive (void *d);
+extern void *zfile_open_archive (const char *path, int flags);
+extern int zfile_exists_archive(const char *path, const char *rel);
index 08a69f3b49b8f7e52a136572b759bb2b5ab6243f..a7c41241388ae7ff495d682351e352ad541aba73 100755 (executable)
@@ -140,7 +140,7 @@ int inprec_open(char *fname, int record)
        zfile_fseek (inprec_zf, 0, SEEK_END);
        inprec_size = zfile_ftell (inprec_zf);
        zfile_fseek (inprec_zf, 0, SEEK_SET);
-        inprec_buffer = inprec_p = xmalloc (inprec_size);
+        inprec_buffer = inprec_p = (uae_u8*)xmalloc (inprec_size);
        zfile_fread (inprec_buffer, inprec_size, 1, inprec_zf);
        inprec_plastptr = inprec_buffer;
        id = inprec_pu32();
@@ -159,7 +159,7 @@ int inprec_open(char *fname, int record)
        if (record < -1)
            inprec_div = maxvpos;
     } else if (record > 0) {
-       inprec_buffer = inprec_p = xmalloc (inprec_size);
+       inprec_buffer = inprec_p = (uae_u8*)xmalloc (inprec_size);
        inprec_ru32('UAE\0');
        inprec_ru8(1);
        inprec_ru8(UAEMAJOR);
@@ -755,6 +755,7 @@ void read_inputdevice_config (struct uae_prefs *pr, char *option, char *value)
 static int ievent_alive = 0;
 static int lastmx, lastmy;
 static uae_u32 magicmouse_ibase = 0;
+#define intui "intuition.library"
 
 static uaecptr get_intuitionbase(void)
 {
@@ -781,7 +782,7 @@ static uaecptr get_intuitionbase(void)
        if (b->flags != ABFLAG_ROM && b->flags != ABFLAG_RAM)
            return 0;
        p = b->xlateaddr(v2);
-       if (!strcmp(p, "intuition.library"))
+       if (!memcmp(p, intui, strlen(intui) + 1))
            return v;
     }
     return 0;
index 1de629e1a1730766c281e542ebb70aa0359052fc..86f345a39d7e306d0fe6243d1138c1f7e1e20f71 100755 (executable)
--- a/keybuf.c
+++ b/keybuf.c
@@ -233,7 +233,7 @@ void keybuf_init (void)
 uae_u8 *save_keyboard (int *len)
 {
     uae_u8 *dst, *t;
-    dst = t = malloc (8);
+    dst = t = (uae_u8*)malloc (8);
     save_u32 (getcapslockstate() ? 1 : 0);
     save_u32 (0);
     *len = 8;
index b51aaa24d4bac2155f954eac310a7aba27652403..45ccbe31f228bf6e2bd8e6db0af4ae183e9dd555 100755 (executable)
--- a/memory.c
+++ b/memory.c
@@ -61,7 +61,7 @@ void romlist_add (char *path, struct romdata *rd)
     struct romlist *rl2;
 
     romlist_cnt++;
-    rl = realloc (rl, sizeof (struct romlist) * romlist_cnt);
+    rl = (struct romlist*)realloc (rl, sizeof (struct romlist) * romlist_cnt);
     rl2 = rl + romlist_cnt - 1;
     rl2->path = my_strdup (path);
     rl2->rd = rd;
@@ -102,85 +102,135 @@ struct romdata *getromdatabypath(char *path)
     return NULL;
 }
 
-#define NEXT_ROM_ID 64
+#define NEXT_ROM_ID 65
 
 static struct romdata roms[] = {
-    { "Cloanto Amiga Forever ROM key", 0, 0, 0, 0, 0, 0x869ae1b1, 2069, 0, 0, 1, ROMTYPE_KEY },
-    { "Cloanto Amiga Forever 2006 ROM key", 0, 0, 0, 0, 0, 0xb01c4b56, 750, 48, 0, 1, ROMTYPE_KEY },
-
-    { "KS ROM v1.0 (A1000)(NTSC)", 1, 0, 1, 0, "A1000\0", 0x299790ff, 262144, 1, 0, 0, ROMTYPE_KICK },
-    { "KS ROM v1.1 (A1000)(NTSC)", 1, 1, 31, 34, "A1000\0", 0xd060572a, 262144, 2, 0, 0, ROMTYPE_KICK },
-    { "KS ROM v1.1 (A1000)(PAL)", 1, 1, 31, 34, "A1000\0", 0xec86dae2, 262144, 3, 0, 0, ROMTYPE_KICK },
-    { "KS ROM v1.2 (A1000)", 1, 2, 33, 166, "A1000\0", 0x9ed783d0, 262144, 4, 0, 0, ROMTYPE_KICK },
-    { "KS ROM v1.2 (A500,A1000,A2000)", 1, 2, 33, 180, "A500\0A1000\0A2000\0", 0xa6ce1636, 262144, 5, 0, 0, ROMTYPE_KICK },
-    { "KS ROM v1.3 (A500,A1000,A2000)", 1, 3, 34, 5, "A500\0A1000\0A2000\0", 0xc4f0f55f, 262144, 6, 0, 0, ROMTYPE_KICK },
-    { "KS ROM v1.3 (A3000)", 1, 3, 34, 5, "A3000\0", 0xe0f37258, 262144, 32, 0, 0, ROMTYPE_KICK },
-    { "KS ROM v1.4 (A3000)", 1, 4, 36, 16, "A3000\0", 0xbc0ec13f, 524288, 59, 3, 0, ROMTYPE_KICK },
-
-    { "KS ROM v2.04 (A500+)", 2, 4, 37, 175, "A500+\0", 0xc3bdb240, 524288, 7, 0, 0, ROMTYPE_KICK },
-    { "KS ROM v2.05 (A600)", 2, 5, 37, 299, "A600\0", 0x83028fb5, 524288, 8, 0, 0, ROMTYPE_KICK },
-    { "KS ROM v2.05 (A600HD)", 2, 5, 37, 300, "A600HD\0A600\0", 0x64466c2a, 524288, 9, 0, 0, ROMTYPE_KICK },
-    { "KS ROM v2.05 (A600HD)", 2, 5, 37, 350, "A600HD\0A600\0", 0x43b0df7b, 524288, 10, 0, 0, ROMTYPE_KICK },
-
-    { "KS ROM v3.0 (A1200)", 3, 0, 39, 106, "A1200\0", 0x6c9b07d2, 524288, 11, 0, 0, ROMTYPE_KICK },
-    { "KS ROM v3.0 (A4000)", 3, 0, 39, 106, "A4000\0", 0x9e6ac152, 524288, 12, 2 | 4, 0, ROMTYPE_KICK },
-    { "KS ROM v3.1 (A4000)", 3, 1, 40, 70, "A4000\0", 0x2b4566f1, 524288, 13, 2 | 4, 0, ROMTYPE_KICK },
-    { "KS ROM v3.1 (A500,A600,A2000)", 3, 1, 40, 63, "A500\0A600\0A2000\0", 0xfc24ae0d, 524288, 14, 0, 0, ROMTYPE_KICK },
-    { "KS ROM v3.1 (A1200)", 3, 1, 40, 68, "A1200\0", 0x1483a091, 524288, 15, 1, 0, ROMTYPE_KICK },
-    { "KS ROM v3.1 (A3000)", 3, 1, 40, 68, "A3000\0", 0xefb239cc, 524288, 61, 2, 0, ROMTYPE_KICK },
-    { "KS ROM v3.1 (A4000)(Cloanto)", 3, 1, 40, 68, "A4000\0", 0x43b6dd22, 524288, 31, 2 | 4, 1, ROMTYPE_KICK },
-    { "KS ROM v3.1 (A4000)", 3, 1, 40, 68, "A4000\0", 0xd6bae334, 524288, 16, 2 | 4, 0, ROMTYPE_KICK },
-    { "KS ROM v3.1 (A4000T)", 3, 1, 40, 70, "A4000T\0", 0x75932c3a, 524288, 17, 2 | 4, 0, ROMTYPE_KICK },
-    { "KS ROM v3.X (A4000)(Cloanto)", 3, 10, 45, 57, "A4000\0", 0x08b69382, 524288, 46, 2 | 4, 0, ROMTYPE_KICK },
-
-    { "CD32 KS ROM v3.1", 3, 1, 40, 60, "CD32\0", 0x1e62d4a5, 524288, 18, 1, 0, ROMTYPE_KICKCD32 },
-    { "CD32 extended ROM", 3, 1, 40, 60, "CD32\0", 0x87746be2, 524288, 19, 1, 0, ROMTYPE_EXTCD32 },
-
-    { "CDTV extended ROM v1.00", 1, 0, 1, 0, "CDTV\0", 0x42baa124, 262144, 20, 0, 0, ROMTYPE_EXTCDTV },
-    { "CDTV extended ROM v2.07", 2, 7, 2, 7, "CDTV\0", 0xceae68d2, 262144, 22, 0, 0, ROMTYPE_EXTCDTV },
-    { "CDTV extended ROM v2.30", 2, 30, 2, 30, "CDTV\0", 0x30b54232, 262144, 21, 0, 0, ROMTYPE_EXTCDTV },
-
-    { "A1000 bootstrap ROM", 0, 0, 0, 0, "A1000\0", 0x62f11c04, 8192, 23, 0, 0, ROMTYPE_KICK },
-    { "A1000 bootstrap ROM", 0, 0, 0, 0, "A1000\0", 0x0b1ad2d0, 65536, 24, 0, 0, ROMTYPE_KICK },
-
-    { "Action Replay Mk I v1.00", 1, 0, 1, 0, "AR\0", 0x2d921771, 65536, 52, 0, 0, ROMTYPE_AR },
-    { "Action Replay Mk I v1.50", 1, 50, 1, 50, "AR\0", 0xd4ce0675, 65536, 25, 0, 0, ROMTYPE_AR },
-    { "Action Replay Mk II v2.05", 2, 5, 2, 5, "AR\0", 0x1287301f , 131072, 26, 0, 0, ROMTYPE_AR },
-    { "Action Replay Mk II v2.12", 2, 12, 2, 12, "AR\0", 0x804d0361 , 131072, 27, 0, 0, ROMTYPE_AR },
-    { "Action Replay Mk II v2.14", 2, 14, 2, 14, "AR\0", 0x49650e4f, 131072, 28, 0, 0, ROMTYPE_AR },
-    { "Action Replay Mk III v3.09", 3, 9, 3, 9, "AR\0", 0x0ed9b5aa, 262144, 29, 0, 0, ROMTYPE_AR },
-    { "Action Replay Mk III v3.17", 3, 17, 3, 17, "AR\0", 0xc8a16406, 262144, 30, 0, 0, ROMTYPE_AR },
-    { "Action Replay 1200", 0, 0, 0, 0, "AR\0", 0x8d760101, 262144, 47, 0, 0, ROMTYPE_AR },
-    { "Action Cartridge Super IV Pro (+ROM)", 4, 3, 4, 3, "SUPERIV\0", 0xe668a0be, 170368, 60, 0, 0, ROMTYPE_SUPERIV },
-    { "Action Cartridge Super IV Pro", 0, 0, 0, 0, "SUPERIV\0", 0xffffffff, 0, 62, 0, 0, ROMTYPE_SUPERIV, "SuperIV" },
-    { "HRTMon (built-in)", 0, 0, 0, 0, "HRTMON\0", 0xffffffff, 0, 63, 0, 0, ROMTYPE_HRTMON, "HRTMon" },
-
-    { "A590/A2091 SCSI boot ROM", 0, 0, 6, 0, "A590\0A2091\0", 0x8396cf4e, 16384, 53, 0, 0, ROMTYPE_A2091BOOT },
-    { "A590/A2091 SCSI boot ROM", 0, 0, 6, 6, "A590\0A2091\0", 0x33e00a7a, 16384, 54, 0, 0, ROMTYPE_A2091BOOT },
-    { "A590/A2091 SCSI boot ROM", 0, 0, 7, 0, "A590\0A2091\0", 0x714a97a2, 16384, 55, 0, 0, ROMTYPE_A2091BOOT },
-    { "A590/A2091 SCSI Guru boot ROM", 0, 0, 6, 14, "A590\0A2091\0", 0x04e52f93, 32768, 56, 0, 0, ROMTYPE_A2091BOOT },
-    { "A4091 SCSI boot ROM", 0, 0, 40, 9, "A4091\0", 0x00000000, 32768, 57, 0, 0, ROMTYPE_A4091BOOT },
-    { "A4091 SCSI boot ROM", 0, 0, 40, 13, "A4091\0", 0x54cb9e85, 32768, 58, 0, 0, ROMTYPE_A4091BOOT },
-
-    { "Arcadia OnePlay 2.11", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 49, 0, 0, ROMTYPE_ARCADIABIOS },
-    { "Arcadia TenPlay 2.11", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 50, 0, 0, ROMTYPE_ARCADIABIOS },
-    { "Arcadia OnePlay 3.00", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 51, 0, 0, ROMTYPE_ARCADIABIOS },
-
-    { "Arcadia SportTime Table Hockey", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 33, 0, 0, ROMTYPE_ARCADIAGAME },
-    { "Arcadia SportTime Bowling", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 34, 0, 0, ROMTYPE_ARCADIAGAME },
-    { "Arcadia World Darts", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 35, 0, 0, ROMTYPE_ARCADIAGAME },
-    { "Arcadia Magic Johnson's Fast Break", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 36, 0, 0, ROMTYPE_ARCADIAGAME },
-    { "Arcadia Leader Board Golf", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 37, 0, 0, ROMTYPE_ARCADIAGAME },
-    { "Arcadia Leader Board Golf (alt)", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 38, 0, 0, ROMTYPE_ARCADIAGAME },
-    { "Arcadia Ninja Mission", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 39, 0, 0, ROMTYPE_ARCADIAGAME },
-    { "Arcadia Road Wars", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 40, 0, 0, ROMTYPE_ARCADIAGAME },
-    { "Arcadia Sidewinder", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 41, 0, 0, ROMTYPE_ARCADIAGAME },
-    { "Arcadia Spot", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 42, 0, 0, ROMTYPE_ARCADIAGAME },
-    { "Arcadia Space Ranger", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 43, 0, 0, ROMTYPE_ARCADIAGAME },
-    { "Arcadia Xenon", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 44, 0, 0, ROMTYPE_ARCADIAGAME },
-    { "Arcadia World Trophy Soccer", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 45, 0, 0, ROMTYPE_ARCADIAGAME },
-
-    { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+    { "Cloanto Amiga Forever ROM key", 0, 0, 0, 0, 0, 2069, 0, 0, 1, ROMTYPE_KEY,
+       0x869ae1b1, 0x801bbab3,0x2e3d3738,0x6dd1636d,0x4f1d6fa7,0xe21d5874 },
+    { "Cloanto Amiga Forever 2006 ROM key", 0, 0, 0, 0, 0, 750, 48, 0, 1, ROMTYPE_KEY,
+       0xb01c4b56, 0xbba8e5cd,0x118b8d92,0xafed5693,0x5eeb9770,0x2a662d8f },
+
+    { "KS ROM v1.0 (A1000)(NTSC)", 1, 0, 1, 0, "A1000\0", 262144, 1, 0, 0, ROMTYPE_KICK,
+       0x299790ff, 0x00C15406,0xBEB4B8AB,0x1A16AA66,0xC05860E1,0xA7C1AD79 },
+    { "KS ROM v1.1 (A1000)(NTSC)", 1, 1, 31, 34, "A1000\0", 262144, 2, 0, 0, ROMTYPE_KICK,
+       0xd060572a, 0x4192C505,0xD130F446,0xB2ADA6BD,0xC91DAE73,0x0ACAFB4C},
+    { "KS ROM v1.1 (A1000)(PAL)", 1, 1, 31, 34, "A1000\0", 262144, 3, 0, 0, ROMTYPE_KICK,
+       0xec86dae2, 0x16DF8B5F,0xD524C5A1,0xC7584B24,0x57AC15AF,0xF9E3AD6D },
+    { "KS ROM v1.2 (A1000)", 1, 2, 33, 166, "A1000\0", 262144, 4, 0, 0, ROMTYPE_KICK,
+       0x9ed783d0, 0x6A7BFB5D,0xBD6B8F17,0x9F03DA84,0xD8D95282,0x67B6273B },
+    { "KS ROM v1.2 (A500,A1000,A2000)", 1, 2, 33, 180, "A500\0A1000\0A2000\0", 262144, 5, 0, 0, ROMTYPE_KICK,
+       0xa6ce1636, 0x11F9E62C,0xF299F721,0x84835B7B,0x2A70A163,0x33FC0D88 },
+    { "KS ROM v1.3 (A500,A1000,A2000)", 1, 3, 34, 5, "A500\0A1000\0A2000\0", 262144, 6, 0, 0, ROMTYPE_KICK,
+       0xc4f0f55f, 0x891E9A54,0x7772FE0C,0x6C19B610,0xBAF8BC4E,0xA7FCB785 },
+    { "KS ROM v1.3 (A3000)", 1, 3, 34, 5, "A3000\0", 262144, 32, 0, 0, ROMTYPE_KICK,
+       0xe0f37258, 0xC39BD909,0x4D4E5F4E,0x28C1411F,0x30869504,0x06062E87 },
+    { "KS ROM v1.4 (A3000)", 1, 4, 36, 16, "A3000\0", 524288, 59, 3, 0, ROMTYPE_KICK,
+       0xbc0ec13f, 0xF76316BF,0x36DFF14B,0x20FA349E,0xD02E4B11,0xDD932B07 },
+
+    { "KS ROM v2.04 (A500+)", 2, 4, 37, 175, "A500+\0", 524288, 7, 0, 0, ROMTYPE_KICK,
+       0xc3bdb240, 0xC5839F5C,0xB98A7A89,0x47065C3E,0xD2F14F5F,0x42E334A1 },
+    { "KS ROM v2.05 (A600)", 2, 5, 37, 299, "A600\0", 524288, 8, 0, 0, ROMTYPE_KICK,
+       0x83028fb5, 0x87508DE8,0x34DC7EB4,0x7359CEDE,0x72D2E3C8,0xA2E5D8DB },
+    { "KS ROM v2.05 (A600HD)", 2, 5, 37, 300, "A600HD\0A600\0", 524288, 9, 0, 0, ROMTYPE_KICK,
+       0x64466c2a, 0xF72D8914,0x8DAC39C6,0x96E30B10,0x859EBC85,0x9226637B },
+    { "KS ROM v2.05 (A600HD)", 2, 5, 37, 350, "A600HD\0A600\0", 524288, 10, 0, 0, ROMTYPE_KICK,
+       0x43b0df7b, 0x02843C42,0x53BBD29A,0xBA535B0A,0xA3BD9A85,0x034ECDE4 },
+
+    { "KS ROM v3.0 (A1200)", 3, 0, 39, 106, "A1200\0", 524288, 11, 0, 0, ROMTYPE_KICK,
+       0x6c9b07d2, 0x70033828,0x182FFFC7,0xED106E53,0x73A8B89D,0xDA76FAA5 },
+    { "KS ROM v3.0 (A4000)", 3, 0, 39, 106, "A4000\0", 524288, 12, 2 | 4, 0, ROMTYPE_KICK,
+       0x9e6ac152, 0xF0B4E9E2,0x9E12218C,0x2D5BD702,0x0E4E7852,0x97D91FD7 },
+    { "KS ROM v3.1 (A4000)", 3, 1, 40, 70, "A4000\0", 524288, 13, 2 | 4, 0, ROMTYPE_KICK,
+       0x2b4566f1, 0x81c631dd,0x096bbb31,0xd2af9029,0x9c76b774,0xdb74076c },
+    { "KS ROM v3.1 (A500,A600,A2000)", 3, 1, 40, 63, "A500\0A600\0A2000\0", 524288, 14, 0, 0, ROMTYPE_KICK,
+       0xfc24ae0d, 0x3B7F1493,0xB27E2128,0x30F989F2,0x6CA76C02,0x049F09CA },
+    { "KS ROM v3.1 (A1200)", 3, 1, 40, 68, "A1200\0", 524288, 15, 1, 0, ROMTYPE_KICK,
+       0x1483a091, 0xE2154572,0x3FE8374E,0x91342617,0x604F1B3D,0x703094F1 },
+    { "KS ROM v3.1 (A3000)", 3, 1, 40, 68, "A3000\0", 524288, 61, 2, 0, ROMTYPE_KICK,
+       0xefb239cc, 0xF8E210D7,0x2B4C4853,0xE0C9B85D,0x223BA20E,0x3D1B36EE },
+    { "KS ROM v3.1 (A4000)(Cloanto)", 3, 1, 40, 68, "A4000\0", 524288, 31, 2 | 4, 1, ROMTYPE_KICK,
+       0x43b6dd22, 0xC3C48116,0x0866E60D,0x085E436A,0x24DB3617,0xFF60B5F9 },
+    { "KS ROM v3.1 (A4000)", 3, 1, 40, 68, "A4000\0", 524288, 16, 2 | 4, 0, ROMTYPE_KICK,
+       0xd6bae334, 0x5FE04842,0xD04A4897,0x20F0F4BB,0x0E469481,0x99406F49 },
+    { "KS ROM v3.1 (A4000T)", 3, 1, 40, 70, "A4000T\0", 524288, 17, 2 | 4, 0, ROMTYPE_KICK,
+       0x75932c3a, 0xB0EC8B84,0xD6768321,0xE01209F1,0x1E6248F2,0xF5281A21 },
+    { "KS ROM v3.X (A4000)(Cloanto)", 3, 10, 45, 57, "A4000\0", 524288, 46, 2 | 4, 0, ROMTYPE_KICK,
+       0x08b69382, 0x81D3AEA3,0x0DB7FBBB,0x4AFEE41C,0x21C5ED66,0x2B70CA53 },
+
+    { "CD32 KS ROM v3.1", 3, 1, 40, 60, "CD32\0", 524288, 18, 1, 0, ROMTYPE_KICKCD32,
+       0x1e62d4a5, 0x3525BE88,0x87F79B59,0x29E017B4,0x2380A79E,0xDFEE542D },
+    { "CD32 extended ROM", 3, 1, 40, 60, "CD32\0", 524288, 19, 1, 0, ROMTYPE_EXTCD32,
+       0x87746be2, 0x5BEF3D62,0x8CE59CC0,0x2A66E6E4,0xAE0DA48F,0x60E78F7F },
+    { "CD32 ROM (KS + extended)", 3, 1, 40, 60, "CD32\0", 2 * 524288, 64, 1, 0, ROMTYPE_KICKCD32,
+       0xd3837ae4, 0x06807db3,0x18163745,0x5f4d4658,0x2d9972af,0xec8956d9 },
+
+    { "CDTV extended ROM v1.00", 1, 0, 1, 0, "CDTV\0", 262144, 20, 0, 0, ROMTYPE_EXTCDTV,
+       0x42baa124, 0x7BA40FFA,0x17E500ED,0x9FED041F,0x3424BD81,0xD9C907BE },
+    { "CDTV extended ROM v2.07", 2, 7, 2, 7, "CDTV\0", 262144, 22, 0, 0, ROMTYPE_EXTCDTV,
+       0xceae68d2, 0x5BC114BB,0xA29F60A6,0x14A31174,0x5B3E2464,0xBFA06846 },
+    { "CDTV extended ROM v2.30", 2, 30, 2, 30, "CDTV\0", 262144, 21, 0, 0, ROMTYPE_EXTCDTV,
+       0x30b54232, 0xED7E461D,0x1FFF3CDA,0x321631AE,0x42B80E3C,0xD4FA5EBB },
+
+    { "A1000 bootstrap ROM", 0, 0, 0, 0, "A1000\0", 8192, 23, 0, 0, ROMTYPE_KICK,
+       0x62f11c04, 0xC87F9FAD,0xA4EE4E69,0xF3CCA0C3,0x6193BE82,0x2B9F5FE6 },
+    { "A1000 bootstrap ROM", 0, 0, 0, 0, "A1000\0", 65536, 24, 0, 0, ROMTYPE_KICK,
+       0x0b1ad2d0, 0xBA93B8B8,0x5CA0D83A,0x68225CC3,0x3B95050D,0x72D2FDD7 },
+
+    { "Action Replay Mk I v1.00", 1, 0, 1, 0, "AR\0", 65536, 52, 0, 0, ROMTYPE_AR,
+       0x2d921771, 0x1EAD9DDA,0x2DAD2914,0x6441F5EF,0x72183750,0x22E01248 },
+    { "Action Replay Mk I v1.50", 1, 50, 1, 50, "AR\0", 65536, 25, 0, 0, ROMTYPE_AR,
+       0xd4ce0675, 0x843B433B,0x2C56640E,0x045D5FDC,0x854DC6B1,0xA4964E7C },
+    { "Action Replay Mk II v2.05", 2, 5, 2, 5, "AR\0", 131072, 26, 0, 0, ROMTYPE_AR,
+       0x1287301f, 0xF6601DE8,0x888F0050,0x72BF562B,0x9F533BBC,0xAF1B0074 },
+    { "Action Replay Mk II v2.12", 2, 12, 2, 12, "AR\0", 131072, 27, 0, 0, ROMTYPE_AR,
+       0x804d0361, 0x3194A07A,0x0A82D8B5,0xF2B6AEFA,0x3CA581D6,0x8BA8762B },
+    { "Action Replay Mk II v2.14", 2, 14, 2, 14, "AR\0", 131072, 28, 0, 0, ROMTYPE_AR,
+       0x49650e4f, 0x255D6DF6,0x3A4EAB0A,0x838EB1A1,0x6A267B09,0x59DFF634 },
+    { "Action Replay Mk III v3.09", 3, 9, 3, 9, "AR\0", 262144, 29, 0, 0, ROMTYPE_AR,
+       0x0ed9b5aa, 0x0FF3170A,0xBBF0CA64,0xC9DD93D6,0xEC0C7A01,0xB5436824 },
+    { "Action Replay Mk III v3.17", 3, 17, 3, 17, "AR\0", 262144, 30, 0, 0, ROMTYPE_AR,
+       0xc8a16406, 0x5D4987C2,0xE3FFEA8B,0x1B02E314,0x30EF190F,0x2DB76542 },
+    { "Action Replay 1200", 0, 0, 0, 0, "AR\0", 262144, 47, 0, 0, ROMTYPE_AR,
+       0x8d760101, 0x0F6AB834,0x2810094A,0xC0642F62,0xBA42F78B,0xC0B07E6A },
+    { "Action Cartridge Super IV Pro (+ROM)", 4, 3, 4, 3, "SUPERIV\0", 170368, 60, 0, 0, ROMTYPE_SUPERIV,
+       0xe668a0be, 0x633A6E65,0xA93580B8,0xDDB0BE9C,0x9A64D4A1,0x7D4B4801 },
+    { "Action Cartridge Super IV Pro", 0, 0, 0, 0, "SUPERIV\0", 0, 62, 0, 0, ROMTYPE_SUPERIV,
+       0xffffffff, 0, 0, 0, 0, 0, "SuperIV" },
+    { "HRTMon (built-in)", 0, 0, 0, 0, "HRTMON\0", 0, 63, 0, 0, ROMTYPE_HRTMON,
+       0xffffffff, 0, 0, 0, 0, 0, "HRTMon" },
+
+    { "A590/A2091 SCSI boot ROM", 0, 0, 6, 0, "A590\0A2091\0", 16384, 53, 0, 0, ROMTYPE_A2091BOOT,
+       0x8396cf4e, 0x5E03BC61,0x8C862ABE,0x7BF79723,0xB4EEF4D2,0x1859A0F2 },
+    { "A590/A2091 SCSI boot ROM", 0, 0, 6, 6, "A590\0A2091\0", 16384, 54, 0, 0, ROMTYPE_A2091BOOT,
+       0x33e00a7a, 0x739BB828,0xE874F064,0x9360F59D,0x26B5ED3F,0xBC99BB66 },
+    { "A590/A2091 SCSI boot ROM", 0, 0, 7, 0, "A590\0A2091\0", 16384, 55, 0, 0, ROMTYPE_A2091BOOT,
+       0x714a97a2, 0xE50F01BA,0xF2899892,0x85547863,0x72A82C33,0x3C91276E },
+    { "A590/A2091 SCSI Guru boot ROM", 0, 0, 6, 14, "A590\0A2091\0", 32768, 56, 0, 0, ROMTYPE_A2091BOOT,
+       0x04e52f93, 0x6DA21B6F,0x5E8F8837,0xD64507CD,0x8A4D5CDC,0xAC4F426B },
+    { "A4091 SCSI boot ROM", 0, 0, 40, 9, "A4091\0", 32768, 57, 0, 0, ROMTYPE_A4091BOOT,
+       0x00000000, 0, 0, 0, 0, 0 },
+    { "A4091 SCSI boot ROM", 0, 0, 40, 13, "A4091\0", 32768, 58, 0, 0, ROMTYPE_A4091BOOT,
+       0x54cb9e85, 0x3CE66919,0xF6FD6797,0x4923A12D,0x91B730F1,0xFFB4A7BA },
+
+    { "Arcadia OnePlay 2.11", 0, 0, 0, 0, "ARCADIA\0", 0, 49, 0, 0, ROMTYPE_ARCADIABIOS },
+    { "Arcadia TenPlay 2.11", 0, 0, 0, 0, "ARCADIA\0", 0, 50, 0, 0, ROMTYPE_ARCADIABIOS },
+    { "Arcadia OnePlay 3.00", 0, 0, 0, 0, "ARCADIA\0", 0, 51, 0, 0, ROMTYPE_ARCADIABIOS },
+
+    { "Arcadia SportTime Table Hockey", 0, 0, 0, 0, "ARCADIA\0", 0, 33, 0, 0, ROMTYPE_ARCADIAGAME },
+    { "Arcadia SportTime Bowling", 0, 0, 0, 0, "ARCADIA\0", 0, 34, 0, 0, ROMTYPE_ARCADIAGAME },
+    { "Arcadia World Darts", 0, 0, 0, 0, "ARCADIA\0", 0, 35, 0, 0, ROMTYPE_ARCADIAGAME },
+    { "Arcadia Magic Johnson's Fast Break", 0, 0, 0, 0, "ARCADIA\0", 0, 36, 0, 0, ROMTYPE_ARCADIAGAME },
+    { "Arcadia Leader Board Golf", 0, 0, 0, 0, "ARCADIA\0", 0, 37, 0, 0, ROMTYPE_ARCADIAGAME },
+    { "Arcadia Leader Board Golf (alt)", 0, 0, 0, 0, "ARCADIA\0", 0, 38, 0, 0, ROMTYPE_ARCADIAGAME },
+    { "Arcadia Ninja Mission", 0, 0, 0, 0, "ARCADIA\0", 0, 39, 0, 0, ROMTYPE_ARCADIAGAME },
+    { "Arcadia Road Wars", 0, 0, 0, 0, "ARCADIA\0", 0, 40, 0, 0, ROMTYPE_ARCADIAGAME },
+    { "Arcadia Sidewinder", 0, 0, 0, 0, "ARCADIA\0", 0, 41, 0, 0, ROMTYPE_ARCADIAGAME },
+    { "Arcadia Spot", 0, 0, 0, 0, "ARCADIA\0", 0, 42, 0, 0, ROMTYPE_ARCADIAGAME },
+    { "Arcadia Space Ranger", 0, 0, 0, 0, "ARCADIA\0", 0, 43, 0, 0, ROMTYPE_ARCADIAGAME },
+    { "Arcadia Xenon", 0, 0, 0, 0, "ARCADIA\0", 0, 44, 0, 0, ROMTYPE_ARCADIAGAME },
+    { "Arcadia World Trophy Soccer", 0, 0, 0, 0, "ARCADIA\0", 0, 45, 0, 0, ROMTYPE_ARCADIAGAME },
+
+    { NULL }
 
 };
 
@@ -198,7 +248,7 @@ struct romlist **getromlistbyident(int ver, int rev, int subver, int subrev, cha
     else
        max = romlist_cnt;
     buf = xmalloc((sizeof (struct romlist*) + sizeof (struct romlist)) * (i + 1));
-    rdout = buf;
+    rdout = (struct romlist**)buf;
     rltmp = (struct romlist*)((uae_u8*)buf + (i + 1) * sizeof (struct romlist*));
     out = 0;
     for (i = 0; i < max; i++) {
@@ -291,7 +341,7 @@ struct romlist **getarcadiaroms(void)
            max++;
     }
     buf = xmalloc((sizeof (struct romlist*) + sizeof (struct romlist)) * (max + 1));
-    rdout = buf;
+    rdout = (struct romlist**)buf;
     rltmp = (struct romlist*)((uae_u8*)buf + (max + 1) * sizeof (struct romlist*));
     out = 0;
     for (i = 0; roms[i].name; i++) {
@@ -412,7 +462,7 @@ int load_keyring (struct uae_prefs *p, char *path)
                    keysize = zfile_ftell (f);
                    if (keysize > 0) {
                        zfile_fseek (f, 0, SEEK_SET);
-                       keybuf = xmalloc (keysize);
+                       keybuf = (uae_u8*)xmalloc (keysize);
                        zfile_fread (keybuf, 1, keysize, f);
                        addkey(&keyid, keybuf, keysize, s);
                    }
@@ -481,7 +531,7 @@ int load_keyring (struct uae_prefs *p, char *path)
        keysize = zfile_ftell (f);
        if (keysize > 0) {
            zfile_fseek (f, 0, SEEK_SET);
-           keybuf = xmalloc (keysize);
+           keybuf = (uae_u8*)xmalloc (keysize);
            zfile_fread (keybuf, 1, keysize, f);
            addkey (&keyid, keybuf, keysize, tmp);
        }
@@ -531,7 +581,7 @@ struct romdata *getromdatabyid (int id)
     return 0;
 }
 
-STATIC_INLINE notcrc32(uae_u32 crc32)
+STATIC_INLINE int notcrc32(uae_u32 crc32)
 {
     if (crc32 == 0xffffffff || crc32 == 0x00000000)
        return 1;
@@ -549,34 +599,48 @@ struct romdata *getromdatabycrc (uae_u32 crc32)
     return 0;
 }
 
+static int cmpsha1(uae_u8 *s1, struct romdata *rd)
+{
+    int i;
+
+    for (i = 0; i < SHA1_SIZE / 4; i++) {
+       uae_u32 v1 = (s1[0] << 24) | (s1[1] << 16) | (s1[2] << 8) | (s1[3] << 0);
+       uae_u32 v2 = rd->sha1[i];
+       if (v1 != v2)
+           return -1;
+       s1 += 4;
+    }
+    return 0;
+}
+
 struct romdata *getromdatabydata (uae_u8 *rom, int size)
 {
     int i;
-    uae_u32 crc32a, crc32b, crc32c;
+    uae_u8 sha1a[SHA1_SIZE], sha1b[SHA1_SIZE], sha1c[SHA1_SIZE];
     uae_u8 tmp[4];
     uae_u8 *tmpbuf = NULL;
 
     if (size > 11 && !memcmp (rom, "AMIROMTYPE1", 11)) {
-       uae_u8 *tmpbuf = xmalloc (size);
+       uae_u8 *tmpbuf = (uae_u8*)xmalloc (size);
        int tmpsize = size - 11;
        memcpy (tmpbuf, rom + 11, tmpsize);
        decode_cloanto_rom (tmpbuf, tmpsize, tmpsize);
        rom = tmpbuf;
        size = tmpsize;
     }
-    crc32a = get_crc32 (rom, size);
-    crc32b = get_crc32 (rom, size / 2);
+    get_sha1 (rom, size, sha1a);
+    get_sha1 (rom, size / 2, sha1b);
      /* ignore AR IO-port range until we have full dump */
     memcpy (tmp, rom, 4);
     memset (rom, 0, 4);
-    crc32c = get_crc32 (rom, size);
+    get_sha1 (rom, size, sha1c);
     memcpy (rom, tmp, 4);
     i = 0;
     while (roms[i].name) {
        if (!notcrc32(roms[i].crc32) && roms[i].size >= size) {
-           if (crc32a == roms[i].crc32 || crc32b == roms[i].crc32)
+           if (!cmpsha1(sha1a, &roms[i]) || !cmpsha1(sha1b, &roms[i]))
                return &roms[i];
-           if (crc32c == roms[i].crc32 && roms[i].type == ROMTYPE_AR)
+           if (!cmpsha1(sha1c, &roms[i]) && roms[i].type == ROMTYPE_AR)
                return &roms[i];
        }
        i++;
@@ -594,7 +658,7 @@ struct romdata *getromdatabyzfile (struct zfile *f)
     pos = zfile_ftell (f);
     zfile_fseek (f, 0, SEEK_END);
     size = zfile_ftell (f);
-    p = xmalloc (size);
+    p = (uae_u8*)xmalloc (size);
     if (!p)
        return 0;
     memset (p, 0, size);
@@ -2027,6 +2091,9 @@ static int load_kickstart (void)
 
     if (f != NULL) {
        int filesize, size, maxsize;
+       int kspos = 524288;
+       int extpos = 0;
+
        maxsize = 524288;
        zfile_fseek (f, 0, SEEK_END);
        filesize = zfile_ftell (f);
@@ -2035,19 +2102,25 @@ static int load_kickstart (void)
            filesize = 262144;
            maxsize = 262144;
        }
-       if (filesize >= 524288 * 2)
-           zfile_fseek (f, 524288, SEEK_SET);
+       if (filesize >= 524288 * 2) {
+           struct romdata *rd = getromdatabyzfile(f);
+           if (rd && rd->id == 64) {
+               kspos = 0;
+               extpos = 524288;
+           }
+           zfile_fseek (f, kspos, SEEK_SET);
+       }
        size = read_kickstart (f, kickmemory, maxsize, 1, &cloanto_rom);
        if (size == 0)
            goto err;
         kickmem_mask = size - 1;
        kickmem_size = size;
        if (filesize >= 524288 * 2 && !extendedkickmem_type) {
-           zfile_fseek (f, 0, SEEK_SET);
            extendedkickmem_size = 0x80000;
            extendedkickmem_type = EXTENDED_ROM_KS;
            extendedkickmemory = (uae_u8 *) mapped_malloc (extendedkickmem_size, "rom_e0");
            extendedkickmem_bank.baseaddr = (uae_u8 *) extendedkickmemory;
+           zfile_fseek (f, extpos, SEEK_SET);
            read_kickstart (f, extendedkickmemory, 0x80000,  0, 0);
            extendedkickmem_mask = extendedkickmem_size - 1;
        }
@@ -2200,8 +2273,8 @@ uae_u8 *mapped_malloc (size_t s, char *file)
     answer = shmat (id, 0, 0);
     shmctl (id, IPC_RMID, NULL);
     if (answer != (void *) -1) {
-       x = xmalloc (sizeof (shmpiece));
-       x->native_address = answer;
+       x = (shmpiece*)xmalloc (sizeof (shmpiece));
+       x->native_address = (uae_u8*)answer;
        x->id = id;
        x->size = s;
        x->next = shm_start;
@@ -2872,7 +2945,7 @@ uae_u8 *save_rom (int first, int *len, uae_u8 *dstptr)
     if (dstptr)
        dstbak = dst = dstptr;
     else
-       dstbak = dst = xmalloc (4 + 4 + 4 + 4 + 4 + 256 + 256 + mem_size);
+       dstbak = dst = (uae_u8*)xmalloc (4 + 4 + 4 + 4 + 4 + 256 + 256 + mem_size);
     save_u32 (mem_start);
     save_u32 (mem_size);
     save_u32 (mem_type);
index 2949d4dd70272a1eb95669f86f1e39513bbb31f4..a0241b34f0f7878f56ac9a55ab97ae7b7c994a08 100755 (executable)
@@ -42,7 +42,7 @@ void moduleripper (void)
     size += currprefs.fastmem_size;
     size += currprefs.bogomem_size;
     size += currprefs.z3fastmem_size;
-    buf = p = xmalloc (size);
+    buf = p = (uae_u8*)xmalloc (size);
     if (!buf)
        return;
     memcpy (p, chipmemory, currprefs.chipmem_size);
index 22836a27774ed0202bfdbb9169426ea2230e6ca9..7c651b19c2c9851a2a820d28ec013c6b6f3376bb 100755 (executable)
@@ -492,7 +492,7 @@ void ncr_init (void)
        z = zfile_fopen(rl->path, "rb");
        if (z) {
            write_log("loaded\n");
-           rom = xmalloc (ROM_SIZE * 4);
+           rom = (uae_u8*)xmalloc (ROM_SIZE * 4);
            for (i = 0; i < ROM_SIZE; i++) {
                uae_u8 b;
                zfile_fread(&b, 1, 1, z);
index 22eb4a53ea9e4f9f71d3c92d2ff3e69322572c52..eceee1767f81a872359dc77ecc0042157047da5d 100755 (executable)
--- a/newcpu.c
+++ b/newcpu.c
@@ -67,10 +67,12 @@ int movem_index2[256];
 int movem_next[256];
 
 #ifdef FPUEMU
+#if 0
 int fpp_movem_index1[256];
 int fpp_movem_index2[256];
 int fpp_movem_next[256];
 #endif
+#endif
 
 cpuop_func *cpufunctbl[65536];
 
@@ -144,7 +146,7 @@ static void set_cpu_caches(void)
            flush_icache(1);
        }
     } else {
-       set_cache_state(regs.cacr & 0x8000);
+       set_cache_state((regs.cacr & 0x8000) ? 1 : 0);
     }
 #endif
 }
@@ -237,6 +239,7 @@ static void build_cpufunctbl (void)
 #ifdef JIT
     build_comp ();
 #endif
+    set_cpu_caches ();
 }
 
 void fill_prefetch_slow (struct regstruct *regs)
@@ -279,7 +282,13 @@ static void prefs_changed_cpu (void)
 
 void check_prefs_changed_cpu (void)
 {
-    if (currprefs.cpu_model != changed_prefs.cpu_model
+    int changed = 0;
+
+#ifdef JIT
+    changed = check_prefs_changed_comp ();
+#endif
+    if (changed
+       || currprefs.cpu_model != changed_prefs.cpu_model
        || currprefs.fpu_model != changed_prefs.fpu_model
        || currprefs.cpu_compatible != changed_prefs.cpu_compatible
        || currprefs.cpu_cycle_exact != changed_prefs.cpu_cycle_exact) {
@@ -288,8 +297,9 @@ void check_prefs_changed_cpu (void)
        if (!currprefs.cpu_compatible && changed_prefs.cpu_compatible)
            fill_prefetch_slow (&regs);
        build_cpufunctbl ();
+       changed = 1;
     }
-    if (currprefs.m68k_speed != changed_prefs.m68k_speed) {
+    if (changed || currprefs.m68k_speed != changed_prefs.m68k_speed) {
        currprefs.m68k_speed = changed_prefs.m68k_speed;
        reset_frame_rate_hack ();
        update_68k_cycles ();
@@ -297,6 +307,9 @@ void check_prefs_changed_cpu (void)
     if (currprefs.cpu_idle != changed_prefs.cpu_idle) {
        currprefs.cpu_idle = changed_prefs.cpu_idle;
     }
+    if (changed)
+       set_special (&regs, SPCFLAG_BRK);
+
 }
 
 void init_m68k (void)
@@ -316,6 +329,7 @@ void init_m68k (void)
        movem_next[i] = i & (~(1 << j));
     }
 #ifdef FPUEMU
+#if 0
     for (i = 0 ; i < 256 ; i++) {
        int j;
        for (j = 7 ; j >= 0 ; j--) {
@@ -326,6 +340,7 @@ void init_m68k (void)
        fpp_movem_next[i] = i & (~(1 << j));
     }
 #endif
+#endif
 #if COUNT_INSTRS
     {
        FILE *f = fopen (icountfilename (), "r");
@@ -374,7 +389,6 @@ void init_m68k (void)
     /* We need to check whether NATMEM settings have changed
      * before starting the CPU */
     check_prefs_changed_comp ();
-    set_cpu_caches();
 #endif
 }
 
@@ -2621,7 +2635,7 @@ void m68k_disasm_ea (void *f, uaecptr addr, uaecptr *nextpc, int cnt, uae_u32 *s
 {
     char *buf;
 
-    buf = malloc((MAX_LINEWIDTH + 1) * cnt);
+    buf = (char*)malloc((MAX_LINEWIDTH + 1) * cnt);
     if (!buf)
         return;
     m68k_disasm_2 (buf, (MAX_LINEWIDTH + 1) * cnt, addr, nextpc, cnt, seaddr, deaddr, 1);
@@ -2632,7 +2646,7 @@ void m68k_disasm (void *f, uaecptr addr, uaecptr *nextpc, int cnt)
 {
     char *buf;
 
-    buf = malloc((MAX_LINEWIDTH + 1) * cnt);
+    buf = (char*)malloc((MAX_LINEWIDTH + 1) * cnt);
     if (!buf)
         return;
     m68k_disasm_2 (buf, (MAX_LINEWIDTH + 1) * cnt, addr, nextpc, cnt, NULL, NULL, 0);
@@ -2934,7 +2948,7 @@ uae_u8 *save_cpu (int *len, uae_u8 *dstptr)
     if (dstptr)
        dstbak = dst = dstptr;
     else
-       dstbak = dst = malloc(1000);
+       dstbak = dst = (uae_u8*)malloc(1000);
     model = currprefs.cpu_model;
     save_u32 (model);                                  /* MODEL */
     save_u32 (0x80000000 | (currprefs.address_space_24 ? 1 : 0)); /* FLAGS */
index 6a9a0f80e6548d4b511f4638554459d814f10094..c2de4f8183cb987ec037fa77187718b11c4cf541 100755 (executable)
@@ -48,7 +48,7 @@ static int partcnt;
 static int first_frame = 1;
 
 static unsigned int StreamSizeAudio; // audio write position
-static unsigned int StreamSizeAudioExpected;
+static double StreamSizeAudioExpected;
 
 int avioutput_audio, avioutput_video, avioutput_enabled, avioutput_requested;
 
@@ -661,14 +661,22 @@ static void AVIOuput_WAVWriteAudio (uae_u8 *sndbuffer, int sndbufsize)
     fwrite (sndbuffer, 1, sndbufsize, wavfile);
 }
 
+static int skipsample;
+
 void AVIOutput_WriteAudio(uae_u8 *sndbuffer, int sndbufsize)
 {
+    int size = sndbufsize;
+
     if (!avioutput_audio || !avioutput_enabled)
        return;
+    if (skipsample > 0 && size > wfxSrc.nBlockAlign) {
+       size -= wfxSrc.nBlockAlign;
+       skipsample--;
+    }
     if (avioutput_audio == AVIAUDIO_WAV)
-       AVIOuput_WAVWriteAudio (sndbuffer, sndbufsize);
+       AVIOuput_WAVWriteAudio (sndbuffer, size);
     else
-       AVIOuput_AVIWriteAudio (sndbuffer, sndbufsize);
+       AVIOuput_AVIWriteAudio (sndbuffer, size);
 }
 
 static int getFromDC(LPBITMAPINFO lpbi)
@@ -1121,12 +1129,14 @@ void AVIOutput_Initialize(void)
 
 #include <math.h>
 
-#define ADJUST_SIZE 100
-#define EXP 1.5
+#define ADJUST_SIZE 10
+#define EXP 1.1
 
 void frame_drawn(void)
 {
+#if 0
     double diff, skipmode;
+#endif
     int idiff;
 
     if (!avioutput_video || !avioutput_enabled)
@@ -1139,12 +1149,22 @@ void frame_drawn(void)
 
     AVIOutput_WriteVideo();
 
-    if (!avioutput_audio || (frame_count % avioutput_fps))
+    if (!avioutput_audio)
        return;
 
-    StreamSizeAudioExpected += currprefs.sound_freq;
+    StreamSizeAudioExpected += ((double)currprefs.sound_freq) / avioutput_fps;
     idiff = StreamSizeAudio - StreamSizeAudioExpected;
-    diff = idiff / 100.0;
+    if (idiff > 0) {
+       skipsample += idiff / 10;
+       if (skipsample > 4)
+           skipsample = 4;
+    write_log("%d ", skipsample);
+    }
+    sound_setadjust (0.0);
+
+#if 0
+    write_log("%d ", idiff);
+    diff = idiff / 20.0;
     skipmode = pow (diff < 0 ? -diff : diff, EXP);
     if (idiff < 0)
        skipmode = -skipmode;
@@ -1152,11 +1172,14 @@ void frame_drawn(void)
        skipmode = -ADJUST_SIZE;
     if (skipmode > ADJUST_SIZE)
        skipmode = ADJUST_SIZE;
+    write_log("%d/%.2f\n", idiff, skipmode);
 
     sound_setadjust (skipmode);
 
-    write_log("AVIOutput: diff=%.2f skip=%.2f (%d-%d=%d)\n", diff, skipmode,
-       StreamSizeAudio, StreamSizeAudioExpected, idiff);
+    if (0 && !(frame_count % avioutput_fps))
+       write_log("AVIOutput: diff=%.2f skip=%.2f (%d-%d=%d)\n", diff, skipmode,
+           StreamSizeAudio, StreamSizeAudioExpected, idiff);
+#endif
 }
 
 
index 365f111d285cacebe29046fc5a43febaf694218c..b4c49b29401ec45dd5fced82ac41788705399582 100755 (executable)
@@ -286,7 +286,7 @@ int host_sbinit(TrapContext *context, SB)
        if ((sb->hEvent = CreateEvent(NULL,FALSE,FALSE,NULL)) == NULL)
                return 0;
 
-       sb->mtable = calloc(sb->dtablesize,sizeof(*sb->mtable));
+       sb->mtable = calloc(sb->dtablesize, sizeof(*sb->mtable));
        
        return 1;
 }
@@ -780,7 +780,7 @@ struct threadsock_packet
     SB;
 } sockreq;
 
-static BOOL HandleStuff( void )
+static BOOL HandleStuff(void)
 {
        BOOL quit = FALSE;
        SB = NULL;
@@ -789,7 +789,7 @@ static BOOL HandleStuff( void )
        // 100ms sleepiness might need some tuning...
        //if(WaitForSingleObject( hSockReq, 100 ) == WAIT_OBJECT_0 )
                {
-                       switch( sockreq.packet_type )
+                       switch(sockreq.packet_type)
                        {
                                case connect_req:
                                sockreq.sb->resultval = connect(sockreq.s,(struct sockaddr *)(sockreq.params.connect_s.buf),sockreq.params.connect_s.namelen);
@@ -1062,7 +1062,7 @@ void host_sendto(TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 len,
                        sockreq.params.sendto_s.to = to;
                        sockreq.params.sendto_s.tolen = tolen;
 
-                       if (sb->ftable[sd-1]&SF_RAW_UDP) {
+                       if (sb->ftable[sd - 1] & SF_RAW_UDP) {
                                *(buf+2) = *(realpt+2);
                                *(buf+3) = *(realpt+3);
                                // Copy DST-Port
@@ -1070,7 +1070,7 @@ void host_sendto(TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 len,
                                sockreq.params.sendto_s.realpt += iCut;
                                sockreq.params.sendto_s.len -= iCut;
                        }
-                       if (sb->ftable[sd-1]&SF_RAW_RUDP) {
+                       if (sb->ftable[sd - 1] & SF_RAW_RUDP) {
                                int iTTL;
                                iTTL = (int) *(realpt+8)&0xff;
                                setsockopt(s,IPPROTO_IP,4,(char*) &iTTL,sizeof(iTTL));
@@ -1081,7 +1081,7 @@ void host_sendto(TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 len,
                                sockreq.params.sendto_s.realpt += iCut;
                                sockreq.params.sendto_s.len -= iCut;
                        }
-                       if (sb->ftable[sd-1]&SF_RAW_RICMP) {
+                       if (sb->ftable[sd - 1] & SF_RAW_RICMP) {
                                int iTTL;
                                iTTL = (int) *(realpt+8)&0xff;
                                setsockopt(s,IPPROTO_IP,4,(char*) &iTTL,sizeof(iTTL));
@@ -1091,11 +1091,11 @@ void host_sendto(TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 len,
                        }
 
                        TRIGGER_THREAD;
-                       if (sb->ftable[sd-1]&SF_RAW_UDP||sb->ftable[sd-1]&SF_RAW_RUDP||sb->ftable[sd-1]&SF_RAW_RICMP) {
+                       if ((sb->ftable[sd - 1] & SF_RAW_UDP) || (sb->ftable[sd - 1] & SF_RAW_RUDP) || (sb->ftable[sd-1] & SF_RAW_RICMP)) {
                                sb->resultval += iCut;
                        }
                        if (sb->resultval == -1) {
-                               if (sb->sb_errno != WSAEWOULDBLOCK - WSABASEERR || !(sb->ftable[sd-1] & SF_BLOCKING))
+                               if (sb->sb_errno != WSAEWOULDBLOCK - WSABASEERR || !(sb->ftable[sd - 1] & SF_BLOCKING))
                                        break;
                        } else {
                                realpt += sb->resultval;
@@ -1106,11 +1106,11 @@ void host_sendto(TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 len,
                                        continue;
                        }
 
-                       if (sb->mtable[sd-1] || (wMsg = allocasyncmsg(sb,sd,s)) != 0) {
-                               if (sb->mtable[sd-1] == 0) {
+                       if (sb->mtable[sd - 1] || (wMsg = allocasyncmsg(sb, sd, s)) != 0) {
+                               if (sb->mtable[sd - 1] == 0) {
                                        WSAAsyncSelect(s,hWndSelector ? hAmigaWnd : bsd->hSockWnd,wMsg,FD_WRITE);
                                } else {
-                                       setWSAAsyncSelect(sb,sd,s,FD_WRITE);
+                                       setWSAAsyncSelect(sb, sd, s, FD_WRITE);
                                }
                                        
                                WAITSIGNAL;
@@ -1118,7 +1118,7 @@ void host_sendto(TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 len,
                                if (sb->mtable[sd-1] == 0) {
                                        cancelasyncmsg(context, wMsg);
                                } else {
-                                       setWSAAsyncSelect(sb,sd,s,0);
+                                       setWSAAsyncSelect(sb, sd, s, 0);
                                }
                                
                                if (sb->eintr) {
index 988ccbdbb5db5e349cacf7261d49f0b177ae3804..3c9ded79ae2eca1252e03f929eb457cabc7635fb 100755 (executable)
@@ -262,7 +262,7 @@ int fsdb_fill_file_attrs (a_inode *base, a_inode *aino)
 
     if((mode = GetFileAttributes(aino->nname)) == INVALID_FILE_ATTRIBUTES) {
        write_log("GetFileAttributes('%s') failed! error=%d, aino=%p dir=%d\n",
-           aino->nname, GetLastError(), aino,aino->dir);
+           aino->nname, GetLastError(), aino, aino->dir);
        return 0;
     }
     aino->dir = (mode & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
@@ -327,18 +327,16 @@ int fsdb_set_file_attrs (a_inode *aino)
        return ERROR_OBJECT_NOT_AROUND;
     mode &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
 
-    if (1 || ! aino->dir) {
-       mode = 0;
-       if ((tmpmask & (A_FIBF_WRITE | A_FIBF_DELETE)) == 0)
-           mode |= FILE_ATTRIBUTE_READONLY;
-       if (!(tmpmask & A_FIBF_ARCHIVE))
-           mode |= FILE_ATTRIBUTE_ARCHIVE;
-       if (tmpmask & A_FIBF_PURE)
-           mode |= FILE_ATTRIBUTE_SYSTEM;
-       if (tmpmask & A_FIBF_HIDDEN)
-           mode |= FILE_ATTRIBUTE_HIDDEN;
-       SetFileAttributes (aino->nname, mode);
-    }
+    mode = 0;
+    if ((tmpmask & (A_FIBF_WRITE | A_FIBF_DELETE)) == 0)
+        mode |= FILE_ATTRIBUTE_READONLY;
+    if (!(tmpmask & A_FIBF_ARCHIVE))
+        mode |= FILE_ATTRIBUTE_ARCHIVE;
+    if (tmpmask & A_FIBF_PURE)
+        mode |= FILE_ATTRIBUTE_SYSTEM;
+    if (tmpmask & A_FIBF_HIDDEN)
+        mode |= FILE_ATTRIBUTE_HIDDEN;
+    SetFileAttributes (aino->nname, mode);
 
     aino->dirty = 1;
     if (aino->volflags & MYVOLUMEINFO_STREAMS) {
index e49eb6fb04c3a2b9ad108454b688f09af8e8f81f..77567a36ae40e8ff441d8ea7dfbf8d52033dfd5f 100755 (executable)
@@ -37,6 +37,7 @@ struct uae_driveinfo {
     uae_u64 size;
     uae_u64 offset;
     int bytespersector;
+    int dangerous;
 };
 
 #define HDF_HANDLE_WIN32 1
@@ -81,7 +82,7 @@ static void rdbdump (HANDLE *h, uae_u64 offset, uae_u8 *buf, int blocksize)
     cnt++;
 }
 
-static int safetycheck (HANDLE *h, uae_u64 offset, uae_u8 *buf, int blocksize, int dowarn)
+static int safetycheck (HANDLE *h, uae_u64 offset, uae_u8 *buf, int blocksize)
 {
     int i, j, blocks = 63, empty = 1;
     DWORD outlen, high;
@@ -90,19 +91,19 @@ static int safetycheck (HANDLE *h, uae_u64 offset, uae_u8 *buf, int blocksize, i
        high = (DWORD)(offset >> 32);
        if (SetFilePointer (h, (DWORD)offset, &high, FILE_BEGIN) == INVALID_FILE_SIZE) {
            write_log ("hd ignored, SetFilePointer failed, error %d\n", GetLastError());
-           return 0;
+           return 1;
        }
        memset (buf, 0xaa, blocksize);
        ReadFile (h, buf, blocksize, &outlen, NULL);
        if (outlen != blocksize) {
            write_log ("hd ignored, read error %d!\n", GetLastError());
-           return 0;
+           return 2;
        }
        if (!memcmp (buf, "RDSK", 4)) {
            if (do_rdbdump)
                rdbdump (h, offset, buf, blocksize);
            write_log ("hd accepted (rdb detected at block %d)\n", j);
-           return 1;
+           return -1;
        }
        if (j == 0) {
            for (i = 0; i < blocksize; i++) {
@@ -112,19 +113,15 @@ static int safetycheck (HANDLE *h, uae_u64 offset, uae_u8 *buf, int blocksize, i
        }
        offset += blocksize;
     }
-    if (harddrive_dangerous != 0x1234dead) {
-        if (!empty) {
-           write_log ("hd ignored, not empty and no RDB detected\n");
-           return 0;
-       }
-       write_log ("hd accepted (empty)\n");
-       return 1;
+    if (!empty) {
+        write_log ("hd ignored, not empty and no RDB detected\n");
+        return 0;
     }
-    if (dowarn)
-       gui_message_id (IDS_HARDDRIVESAFETYWARNING);
-    return 2;
+    write_log ("hd accepted (empty)\n");
+    return -2;
 }
 
+
 static void trim (char *s)
 {
     while(strlen(s) > 0 && s[strlen(s) - 1] == ' ')
@@ -168,7 +165,7 @@ int hdf_open (struct hardfiledata *hfd, char *name)
        if (i >= 0) {
            DWORD r;
            udi = &uae_drives[i];
-           hfd->flags = 1;
+           hfd->flags = HFD_FLAGS_REALDRIVE;
            flags =  FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS;
            h = CreateFile (udi->device_path,
                GENERIC_READ | (hfd->readonly ? 0 : GENERIC_WRITE),
@@ -192,11 +189,22 @@ int hdf_open (struct hardfiledata *hfd, char *name)
            }
            hfd->blocksize = udi->bytespersector;
            if (hfd->offset == 0) {
-               if (!safetycheck (hfd->handle, 0, hfd->cache, hfd->blocksize, hfd->warned ? 0 : 1)) {
+               int sf = safetycheck (hfd->handle, 0, hfd->cache, hfd->blocksize);
+               if (sf > 0) {
                    hdf_close (hfd);
                    return 0;
                }
-               hfd->warned = 1;
+               if (sf == 0) {
+                   if (harddrive_dangerous != 0x1234dead) {
+                       gui_message_id (IDS_HARDDRIVESAFETYWARNING1);
+                       hdf_close(hfd);
+                       return 0;
+                   }
+                   if (!hfd->warned) {
+                       gui_message_id (IDS_HARDDRIVESAFETYWARNING2);
+                       hfd->warned = 1;
+                   }
+               }
            }
            hfd->handle_valid = HDF_HANDLE_WIN32;
        }
@@ -907,7 +915,7 @@ Return Value:
            udi->offset = udi->offset2 = pi->StartingOffset.QuadPart;
            udi->size = udi->size2 = pi->PartitionLength.QuadPart;
            write_log ("used\n");
-           if (safetycheck (hDevice, udi->offset, buffer, dg.BytesPerSector, 1)) {
+           if (safetycheck (hDevice, udi->offset, buffer, dg.BytesPerSector) <= 0) {
                sprintf (udi->device_name, "HD_P#%d_%s", pi->PartitionNumber, orgname);
                udi++;
                (*index2)++;
@@ -926,16 +934,11 @@ Return Value:
        write_log ("no MBR partition table detected, checking for RDB\n");
     }
 
-    i = safetycheck (hDevice, 0, buffer, dg.BytesPerSector, 1);
-    if (!i) {
-       ret = 1;
+    udi->dangerous = safetycheck (hDevice, 0, buffer, dg.BytesPerSector);
+    if (udi->dangerous > 0)
        goto end;
-    }
 amipartfound:
-    if (i > 1)
-       sprintf (udi->device_name, "HD_*_%s", orgname);
-    else
-       sprintf (udi->device_name, "HD_%s", orgname);
+    sprintf (udi->device_name, "HD_%s", orgname);
     while (isharddrive (udi->device_name) >= 0)
        strcat (udi->device_name, "_");
     (*index2)++;
@@ -994,13 +997,27 @@ char *hdf_getnameharddrive (int index, int flags)
     static char name[512];
     char tmp[32];
     uae_u64 size = uae_drives[index].size;
+    char *dang = "?";
+
+    switch (uae_drives[index].dangerous)
+    {
+       case -2:
+       dang = "Empty";
+       break;
+       case -1:
+       dang = "RDB";
+       break;
+       case 0:
+       dang = "NON-EMPTY";
+       break;
+    }
 
     if (flags & 1) {
-           if (size >= 1024 * 1024 * 1024)
-               sprintf (tmp, "%.1fG", ((double)(uae_u32)(size / (1024 * 1024))) / 1024.0);
-           else
-               sprintf (tmp, "%.1fM", ((double)(uae_u32)(size / (1024))) / 1024.0);
-       sprintf (name, "[%s] %s", tmp, uae_drives[index].device_name);
+       if (size >= 1024 * 1024 * 1024)
+           sprintf (tmp, "%.1fG", ((double)(uae_u32)(size / (1024 * 1024))) / 1024.0);
+       else
+           sprintf (tmp, "%.1fM", ((double)(uae_u32)(size / (1024))) / 1024.0);
+       sprintf (name, "%10s [%s] %s", dang, tmp, uae_drives[index].device_name);
        return name;
     }
     if (flags & 2)
index aa0f1091778fcbb4c647bc262b9630fd72133f1f..dd89ea465b397f84c661e2898630b2e4ffe424a5 100755 (executable)
@@ -9,6 +9,17 @@
   * Modified 2005 Peter Keunecke
   */
 
+#define        FPCR_ROUNDING_MODE      0x00000030
+#define        FPCR_ROUND_NEAR         0x00000000
+#define        FPCR_ROUND_ZERO         0x00000010
+#define        FPCR_ROUND_MINF         0x00000020
+#define        FPCR_ROUND_PINF         0x00000030
+
+#define        FPCR_ROUNDING_PRECISION 0x000000c0
+#define        FPCR_PRECISION_SINGLE   0x00000040
+#define        FPCR_PRECISION_DOUBLE   0x00000080
+#define FPCR_PRECISION_EXTENDED        0x00000000
+
 #if USE_LONG_DOUBLE
 STATIC_INLINE long double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
 {
index 873d2763e8e13428ff69b387dc34276250222d0d..a22dd5482518712a08f85b4849194af86dab7b1c 100755 (executable)
@@ -18,6 +18,8 @@ static struct shmid_ds shmids[MAX_SHMID];
 
 extern int p96mode;
 
+static int memorylocking = 0;
+
 uae_u8 *natmem_offset = NULL;
 #ifdef CPU_64_BIT
 int max_allowed_mman = 2048;
@@ -27,17 +29,30 @@ int max_allowed_mman = 512;
 
 static uae_u8 *p96mem_offset;
 static uae_u8 *p96fakeram;
+static int p96fakeramsize;
+
+static void *virtualallocwithlock(LPVOID addr, SIZE_T size, DWORD allocationtype, DWORD protect) 
+{
+    void *p = VirtualAlloc (addr, size, allocationtype, protect);
+    if (p && memorylocking && os_winnt)
+       VirtualLock(p, size);
+    return p;
+}
+static void virtualfreewithlock(LPVOID addr, SIZE_T size, DWORD freetype)
+{
+    if (memorylocking && os_winnt)
+       VirtualUnlock(addr, size);
+    VirtualFree(addr, size, freetype);
+}
 
 void cache_free(void *cache)
 {
-    VirtualFree (cache, 0, MEM_RELEASE);
+    virtualfreewithlock(cache, 0, MEM_RELEASE);
 }
 
 void *cache_alloc(int size)
 {
-    uae_u8 *cache;
-    cache = VirtualAlloc (NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
-    return cache;
+    return virtualallocwithlock(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 }
 
 void init_shm(void)
@@ -154,7 +169,6 @@ void mapped_free(uae_u8 *mem)
        xfree (p96fakeram);
        p96fakeram = NULL;
        while(x) {
-           struct shmid_ds blah;
            if (mem == x->native_address) {
                int shmid = x->id;
                shmids[shmid].key = -1;
@@ -275,9 +289,15 @@ void *shmat(int shmid, void *shmaddr, int shmflg)
            } else {
                p96ram_start = currprefs.z3fastmem_start + ((currprefs.z3fastmem_size + 0xffffff) & ~0xffffff);
                shmaddr = natmem_offset + p96ram_start;
-               VirtualFree(shmaddr, os_winnt ? size : 0, os_winnt ? MEM_DECOMMIT : MEM_RELEASE);
-               xfree(p96fakeram);
-               result = p96fakeram = xcalloc (size + 4096, 1);
+               virtualfreewithlock(shmaddr, os_winnt ? size : 0, os_winnt ? MEM_DECOMMIT : MEM_RELEASE);
+               if (os_winnt) {
+                   virtualfreewithlock(p96fakeram, p96fakeramsize, MEM_RELEASE);
+                   p96fakeramsize = size + 4096;
+                   p96fakeram = virtualallocwithlock(NULL, p96fakeramsize, MEM_COMMIT, 0);
+               } else {
+                   xfree(p96fakeram);
+                   result = p96fakeram = xcalloc (size + 4096, 1);
+               }
                shmids[shmid].attached = result;
                return result;
            }
@@ -325,8 +345,8 @@ void *shmat(int shmid, void *shmaddr, int shmflg)
        got = FALSE;
        if (got == FALSE) {
            if (shmaddr)
-               VirtualFree(shmaddr, os_winnt ? size : 0, os_winnt ? MEM_DECOMMIT : MEM_RELEASE);
-           result = VirtualAlloc(shmaddr, size, os_winnt ? MEM_COMMIT : (MEM_RESERVE | MEM_COMMIT | (p96mode ? MEM_WRITE_WATCH : 0)),
+               virtualfreewithlock(shmaddr, os_winnt ? size : 0, os_winnt ? MEM_DECOMMIT : MEM_RELEASE);
+           result = virtualallocwithlock(shmaddr, size, os_winnt ? MEM_COMMIT : (MEM_RESERVE | MEM_COMMIT | (p96mode ? MEM_WRITE_WATCH : 0)),
                PAGE_EXECUTE_READWRITE);
            if (result == NULL) {
                result = (void*)-1;
@@ -334,6 +354,8 @@ void *shmat(int shmid, void *shmaddr, int shmflg)
                    (uae_u8*)shmaddr - natmem_offset, (uae_u8*)shmaddr - natmem_offset + size,
                    size, size >> 10, GetLastError());
            } else {
+               if (memorylocking && os_winnt)
+                   VirtualLock(shmaddr, size);
                shmids[shmid].attached = result; 
                write_log ("VirtualAlloc %08.8X - %08.8X %x (%dk) ok\n",
                    (uae_u8*)shmaddr - natmem_offset, (uae_u8*)shmaddr - natmem_offset + size,
@@ -393,6 +415,8 @@ int shmctl(int shmid, int cmd, struct shmid_ds *buf)
     return result;
 }
 
+#endif
+
 int isinf(double x)
 {
     const int nClass = _fpclass(x);
@@ -403,11 +427,3 @@ int isinf(double x)
        result = 0;
     return result;
 }
-
-int isnan(double x)
-{
-    int result = _isnan(x);
-    return result;
-}
-
-#endif
index 36eb1ba298ec4fdb4df76eb924f8e73c0e2b1e9d..d312941df75b730c58b2487352139cf55a26dd0b 100755 (executable)
@@ -1684,6 +1684,7 @@ static struct modeids mi[] =
     480, 360, 168,
     640, 350, 169,
    1600, 900, 170,
+    960, 600, 171,
    -1,-1,0
 };
 
index 582f726d6a7d5b24b422d01310ee2713e71781d2..d0520767da2fd5d067f55df9a1c843190df49aeb 100755 (executable)
 #define IDS_ROMSCANEND                  319
 #define IDS_ROM_AVAILABLE               320
 #define IDS_ROM_UNAVAILABLE             321
-#define IDS_HARDDRIVESAFETYWARNING      322
+#define IDS_HARDDRIVESAFETYWARNING1     322
 #define IDS_NUMSG_KS68EC020             323
 #define IDS_ROMSCANNOROMS               324
 #define IDS_NUMSG_KICKREP               325
 #define IDR_DBGACCEL                    330
 #define IDS_NUMSG_KS68030               331
 #define IDS_NUMSG_EXPROMNEED            332
+#define IDS_HARDDRIVESAFETYWARNING2     333
 #define IDS_QS_MODELS                   1000
 #define IDS_QS_MODEL_A500               1001
 #define IDS_QS_MODEL_A500P              1002
 #define IDC_NEW_HF                      1340
 #define IDC_NEW_HD                      1341
 #define IDC_PORT0                       1342
+#define IDC_NEW_FSARCH                  1342
 #define IDC_PORT1                       1343
 #define IDC_PATH_NAME                   1362
 #define IDC_SELECTOR                    1363
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NO_MFC                     1
 #define _APS_3D_CONTROLS                     1
-#define _APS_NEXT_RESOURCE_VALUE        253
+#define _APS_NEXT_RESOURCE_VALUE        334
 #define _APS_NEXT_COMMAND_VALUE         40029
 #define _APS_NEXT_CONTROL_VALUE         1773
 #define _APS_NEXT_SYMED_VALUE           101
similarity index 99%
rename from od-win32/resources/resource
rename to od-win32/resources/resource.hx
index f7954a2ca3d20f5b604f8eedc34491dfeb7e990a..582f726d6a7d5b24b422d01310ee2713e71781d2 100755 (executable)
 #define IDS_HDCLONE_OK                  328
 #define IDS_HDCLONE_FAIL                329
 #define IDR_DBGACCEL                    330
+#define IDS_NUMSG_KS68030               331
+#define IDS_NUMSG_EXPROMNEED            332
 #define IDS_QS_MODELS                   1000
 #define IDS_QS_MODEL_A500               1001
 #define IDS_QS_MODEL_A500P              1002
 #define IDS_QS_MODEL_CDTV               1007
 #define IDS_QS_MODEL_UAE                1008
 #define IDS_QS_MODEL_ARCADIA            1009
+#define IDS_QS_MODEL_A3000              1010
+#define IDS_QS_MODEL_A4000              1011
+#define IDS_QS_MODEL_A4000T             1012
 #define IDC_RESOLUTION                  1021
 #define IDC_SERIAL                      1022
 #define IDC_REFRESHRATE                 1022
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        253
 #define _APS_NEXT_COMMAND_VALUE         40029
-#define _APS_NEXT_CONTROL_VALUE         1772
+#define _APS_NEXT_CONTROL_VALUE         1773
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
index 8cf15c2eadc4dc1b77b8b0b695cdfb6e53005499..ee51734bbd6aa7dcfdf7a32ca5d5cff1a78cf8dd 100755 (executable)
@@ -242,21 +242,22 @@ BEGIN
     RTEXT           "Disk label:",IDC_STATIC,14,216,52,10,SS_CENTERIMAGE\r
 END\r
 \r
-IDD_HARDDISK DIALOGEX 0, 0, 300, 231\r
+IDD_HARDDISK DIALOGEX 0, 0, 300, 240\r
 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD\r
 EXSTYLE WS_EX_CONTEXTHELP\r
 FONT 8, "MS Sans Serif", 0, 0, 0x1\r
 BEGIN\r
     CONTROL         "List1",IDC_VOLUMELIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,5,0,290,182\r
-    PUSHBUTTON      "Add &Directory...",IDC_NEW_FS,5,186,64,15\r
-    PUSHBUTTON      "Add &Hardfile...",IDC_NEW_HF,74,186,64,15\r
-    PUSHBUTTON      "Add Ha&rd Drive...",IDC_NEW_HD,143,186,65,15\r
-    PUSHBUTTON      "Remove",IDC_REMOVE,235,186,60,15\r
-    PUSHBUTTON      "&Properties",IDC_EDIT,235,207,60,15\r
-    CONTROL         "Add PC drives at startup",IDC_MAPDRIVES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,205,100,10\r
-    CONTROL         "Disable UAEFSDB-support",IDC_NOUAEFSDB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,205,119,10\r
-    CONTROL         "Don't use Windows Recycle Bin",IDC_NORECYCLEBIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,216,121,10\r
-    CONTROL         "Include network drives",IDC_MAPDRIVES_NET,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,216,101,10\r
+    PUSHBUTTON      "Add &Directory...",IDC_NEW_FS,10,186,64,15\r
+    PUSHBUTTON      "Add &Hardfile...",IDC_NEW_HF,153,186,64,15\r
+    PUSHBUTTON      "Add Ha&rd Drive...",IDC_NEW_HD,223,186,65,15\r
+    PUSHBUTTON      "Remove",IDC_REMOVE,232,207,60,15\r
+    PUSHBUTTON      "&Properties",IDC_EDIT,232,225,60,15\r
+    CONTROL         "Add PC drives at startup",IDC_MAPDRIVES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,209,100,10\r
+    CONTROL         "Disable UAEFSDB-support",IDC_NOUAEFSDB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,209,119,10\r
+    CONTROL         "Don't use Windows Recycle Bin",IDC_NORECYCLEBIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,220,121,10\r
+    CONTROL         "Include network drives",IDC_MAPDRIVES_NET,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,220,101,10\r
+    PUSHBUTTON      "Add Archive...",IDC_NEW_FSARCH,82,186,64,15\r
 END\r
 \r
 IDD_SOUND DIALOGEX 0, 0, 300, 231\r
@@ -1238,8 +1239,10 @@ STRINGTABLE
 BEGIN\r
     IDS_ROM_AVAILABLE       "available"\r
     IDS_ROM_UNAVAILABLE     "unavailable"\r
-    IDS_HARDDRIVESAFETYWARNING \r
-                            "Warning: The safety test has been disabled, and non-empty hard disks were detected.\n\nHard disks marked with 'HD_*_' are not empty."\r
+    IDS_HARDDRIVESAFETYWARNING1 \r
+                            "Warning: The drive safety check is active. Selected drive is not empty and non-RDB partitioned."\r
+    IDS_HARDDRIVESAFETYWARNING2 \r
+                            "Warning: The drive safety check has been disabled, and non-empty and non-RDB partitioned hard disk(s) were detected."\r
     IDS_NUMSG_KS68EC020     "The selected system ROM requires a 68020 with 24-bit addressing or higher CPU."\r
     IDS_ROMSCANNOROMS       "No supported system ROMs detected."\r
     IDS_NUMSG_KICKREP       "You need to have a floppy disk (image file) in DF0: to use the system ROM replacement."\r
index 610af2791bbef489a1aead2bf8f69b30f3562ee3..2e03c01578623d16bc5de50d544f0623ef366f81 100755 (executable)
@@ -36,6 +36,7 @@
 #define SCSIEMU /* uaescsi.device emulation */
 #define UAESERIAL /* uaeserial.device emulation */
 #define FPUEMU /* FPU emulation */
+#define FPU_UAE
 #define MMUEMU
 #define CPUEMU_0 /* generic 680x0 emulation */
 #define CPUEMU_11 /* 68000+prefetch emulation */
 #define SIZEOF_LONG 4
 
 /* The number of bytes in a long long.  */
-#define SIZEOF_LONG_LONG 0
+#define SIZEOF_LONG_LONG 8
 
 /* The number of bytes in a short.  */
 #define SIZEOF_SHORT 2
 
+#define SIZEOF_FLOAT 4
+#define SIZEOF_DOUBLE 8
+
+#define HAVE_ISNAN
+#define HAVE_ISINF
+#define isnan _isnan
+extern int isinf(double);
+
 /* Define if you have the bcopy function.  */
 /* #undef HAVE_BCOPY */
 
index 878a31a14f167c625fea16d80639005c4f5d7e8b..c5979ce9a0b188ecac068527bb81899416f9b3f7 100755 (executable)
@@ -13,7 +13,7 @@ extern void uae_set_thread_priority (int);
 
 #include "commpipe.h"
 
-STATIC_INLINE uae_wait_thread(uae_thread_id *tid)
+STATIC_INLINE void uae_wait_thread(uae_thread_id tid)
 {
     WaitForSingleObject(tid, INFINITE);
 }
index 0be1cf4c91cce7a4c6e8177728a780df0c938535..ea77c5ff8053e5a7935a6e559115b6ebed59ec55 100755 (executable)
@@ -15,9 +15,9 @@
 #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100)
 #define GETBDD(x) ((x) % 100)
 
-#define WINUAEBETA 4
+#define WINUAEBETA 5
 #define WINUAEPUBLICBETA 1
-#define WINUAEDATE MAKEBD(2007, 6, 2)
+#define WINUAEDATE MAKEBD(2007, 6, 18)
 #define WINUAEEXTRA ""
 #define WINUAEREV ""
 
index 0abdaaa82b77a8d2211b76862033f9cb6363b2a7..f0f0db29a1b60c54ae774e71b7d66b02d91a811d 100755 (executable)
@@ -51,6 +51,7 @@
 #include "parallel.h"
 #include "audio.h"
 #include "arcadia.h"
+#include "fsdb.h"
 
 #include "dxwrap.h"
 #include "win32.h"
 #include "uaeipc.h"
 #include "crc32.h"
 
-#define DISK_FORMAT_STRING "(*.adf;*.adz;*.gz;*.dms;*.fdi;*.ipf;*.exe)\0*.adf;*.adz;*.gz;*.dms;*.fdi;*.ipf;*.zip;*.7z;*.rar;*.exe;*.ima\0"
-#define ROM_FORMAT_STRING "(*.rom;*.roz)\0*.rom;*.zip;*.roz;*.7z;*.rar\0"
-#define USS_FORMAT_STRING_RESTORE "(*.uss)\0*.uss;*.gz;*.zip;*.7z;*.rar\0"
+#define ARCHIVE_STRING "*.zip;*.7z;*.rar;*.lha;*.lzh;*.lzx\0"
+
+#define DISK_FORMAT_STRING "(*.adf;*.adz;*.gz;*.dms;*.fdi;*.ipf;*.exe)\0*.adf;*.adz;*.gz;*.dms;*.fdi;*.ipf;*.exe;*.ima;" ARCHIVE_STRING
+#define ROM_FORMAT_STRING "(*.rom;*.roz)\0*.rom;*.roz;" ARCHIVE_STRING
+#define USS_FORMAT_STRING_RESTORE "(*.uss)\0*.uss;*.gz;"  ARCHIVE_STRING
 #define USS_FORMAT_STRING_SAVE "(*.uss)\0*.uss\0"
 #define HDF_FORMAT_STRING "(*.hdf;*.rdf;*.hdz;*.rdz)\0*.hdf;*.rdf;*.hdz;*.rdz\0"
 #define INP_FORMAT_STRING "(*.inp)\0*.inp\0"
@@ -383,7 +386,7 @@ static HWND cachedlist = NULL;
 #define MIN_Z3_MEM 0
 #define MAX_Z3_MEM ((max_z3fastmem >> 20) < 512 ? 9 : ((max_z3fastmem >> 20) < 1024 ? 10 : ((max_z3fastmem >> 20) < 2048) ? 11 : 12))
 #define MIN_P96_MEM 0
-#define MAX_P96_MEM 7
+#define MAX_P96_MEM 8
 #define MIN_MB_MEM 0
 #define MAX_MB_MEM 7
 
@@ -436,9 +439,10 @@ static struct romdata *scan_single_rom_2 (struct zfile *f)
     }
     if (!cl)
        rd = getromdatabydata (rombuf, size);
-    if (!rd)
-       write_log ("'%s' %d, unknown CRC32 %08X\n",
-           zfile_getname(f), size, get_crc32(rombuf, size));
+    if (!rd) {
+       write_log ("Unknown: Size=%d, Name='%s'\nCRC32=%08X SHA1=%s\n",
+          size, zfile_getname(f), get_crc32(rombuf, size), get_sha1_txt(rombuf, size));
+    }
     free (rombuf);
     return rd;
 }
@@ -1135,6 +1139,13 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
     case 13:
        WIN32GUI_LoadUIString(IDS_SELECTINFO, szTitle, MAX_DPATH);
 
+       openFileName.lpstrFilter = NULL;
+       openFileName.lpstrDefExt = NULL;
+       openFileName.lpstrInitialDir = path_out;
+       break;
+    case 14:
+       strcpy (szTitle, "Select supported archive file");
+
        openFileName.lpstrFilter = NULL;
        openFileName.lpstrDefExt = NULL;
        openFileName.lpstrInitialDir = path_out;
@@ -5885,6 +5896,7 @@ struct hfdlg_vals
 
 static struct hfdlg_vals empty_hfdlg = { "", "", "", "", 32, 2, 1, 0, 512, 1, 0, 0 };
 static struct hfdlg_vals current_hfdlg;
+static int archivehd;
 
 static INT_PTR CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
@@ -5894,76 +5906,82 @@ static INT_PTR CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
     LPITEMIDLIST browse;
     char szTitle[MAX_DPATH];
 
-    WIN32GUI_LoadUIString(IDS_SELECTFILESYSROOT, szTitle, MAX_DPATH);
-
-    browse_info.hwndOwner = hDlg;
-    browse_info.pidlRoot = NULL;
-    browse_info.pszDisplayName = directory_path;
-    browse_info.lpszTitle = "";
-    browse_info.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS;
-    browse_info.lpfn = NULL;
-    browse_info.iImage = 0;
-
     switch (msg) {
-     case WM_INITDIALOG:
-       recursive++;
-       SetDlgItemText (hDlg, IDC_VOLUME_NAME, current_fsvdlg.volume);
-       SetDlgItemText (hDlg, IDC_VOLUME_DEVICE, current_fsvdlg.device);
-       SetDlgItemText (hDlg, IDC_PATH_NAME, current_fsvdlg.rootdir);
-       SetDlgItemInt (hDlg, IDC_VOLUME_BOOTPRI, current_fsvdlg.bootpri, TRUE);
-       CheckDlgButton (hDlg, IDC_RW, current_fsvdlg.rw);
-       recursive--;
+       case WM_INITDIALOG:
+       {
+           if (archivehd < 0) {
+               if (my_existsfile(current_fsvdlg.rootdir))
+                   archivehd = 1;
+               else if (my_existsdir(current_fsvdlg.rootdir))
+                   archivehd = 0;
+           }
+           recursive++;
+           SetDlgItemText (hDlg, IDC_VOLUME_NAME, current_fsvdlg.volume);
+           SetDlgItemText (hDlg, IDC_VOLUME_DEVICE, current_fsvdlg.device);
+           SetDlgItemText (hDlg, IDC_PATH_NAME, current_fsvdlg.rootdir);
+           SetDlgItemInt (hDlg, IDC_VOLUME_BOOTPRI, current_fsvdlg.bootpri, TRUE);
+           if (archivehd)
+               current_fsvdlg.rw = 0;
+           CheckDlgButton (hDlg, IDC_RW, current_fsvdlg.rw);
+           ew (hDlg, IDC_RW, !archivehd);
+           recursive--;
+       }
        return TRUE;
 
-     case WM_COMMAND:
-       if (recursive)
-           break;
-       recursive++;
-       if (HIWORD (wParam) == BN_CLICKED) {
-           switch (LOWORD (wParam)) {
-            case IDC_SELECTOR:
-               if ((browse = SHBrowseForFolder (&browse_info)) != NULL) {
-                   SHGetPathFromIDList (browse, directory_path);
-                   SetDlgItemText (hDlg, IDC_PATH_NAME, directory_path);
-               }
+       case WM_COMMAND:
+           if (recursive)
                break;
-            case IDOK:
-                   if(strlen(current_fsvdlg.rootdir) == 0) 
+           recursive++;
+           if (HIWORD (wParam) == BN_CLICKED) {
+               switch (LOWORD (wParam))
+               {
+                   case IDC_SELECTOR:
                    {
-                       char szMessage[MAX_DPATH];
-                       char szTitle[MAX_DPATH];
-                       WIN32GUI_LoadUIString(IDS_MUSTSELECTPATH, szMessage, MAX_DPATH);
-                       WIN32GUI_LoadUIString(IDS_SETTINGSERROR, szTitle, MAX_DPATH);
-
-                       MessageBox(hDlg, szMessage, szTitle,
-                               MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND);
-                       break;
+                       strcpy (directory_path, current_fsvdlg.rootdir);
+                       if (archivehd) {
+                           if (DiskSelection(hDlg, 0, 14, &workprefs, directory_path))
+                               SetDlgItemText (hDlg, IDC_PATH_NAME, directory_path);
+                       } else {
+                           WIN32GUI_LoadUIString(IDS_SELECTFILESYSROOT, szTitle, MAX_DPATH);
+                           browse_info.hwndOwner = hDlg;
+                           browse_info.pidlRoot = NULL;
+                           browse_info.pszDisplayName = directory_path;
+                           browse_info.lpszTitle = "";
+                           browse_info.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS;
+                           browse_info.lpfn = NULL;
+                           browse_info.iImage = 0;
+                           if ((browse = SHBrowseForFolder (&browse_info)) != NULL) {
+                               SHGetPathFromIDList (browse, directory_path);
+                               SetDlgItemText (hDlg, IDC_PATH_NAME, directory_path);
+                           }
+                       }
                    }
-                   if(strlen(current_fsvdlg.volume) == 0)
+                   break;
+                   case IDOK:
                    {
-                       char szMessage[MAX_DPATH];
-                       char szTitle[MAX_DPATH];
-                       WIN32GUI_LoadUIString(IDS_MUSTSELECTNAME, szMessage, MAX_DPATH);
-                       WIN32GUI_LoadUIString(IDS_SETTINGSERROR, szTitle, MAX_DPATH);
-
-                       MessageBox(hDlg, szMessage, szTitle,
+                       if(!my_existsfile(current_fsvdlg.rootdir) && !my_existsdir(current_fsvdlg.rootdir)) {
+                           char szMessage[MAX_DPATH];
+                           char szTitle[MAX_DPATH];
+                           WIN32GUI_LoadUIString(IDS_MUSTSELECTPATH, szMessage, MAX_DPATH);
+                           WIN32GUI_LoadUIString(IDS_SETTINGSERROR, szTitle, MAX_DPATH);
+                           MessageBox(hDlg, szMessage, szTitle,
                                MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND);
-                       break;
+                           break;
+                       }
+                       EndDialog (hDlg, 1);
                    }
-               EndDialog (hDlg, 1);
-
-               break;
-            case IDCANCEL:
-               EndDialog (hDlg, 0);
-               break;
+                   break;
+                   case IDCANCEL:
+                       EndDialog (hDlg, 0);
+                   break;
+               }
            }
-       }
-       GetDlgItemText (hDlg, IDC_PATH_NAME, current_fsvdlg.rootdir, sizeof current_fsvdlg.rootdir);
-       GetDlgItemText (hDlg, IDC_VOLUME_NAME, current_fsvdlg.volume, sizeof current_fsvdlg.volume);
-       GetDlgItemText (hDlg, IDC_VOLUME_DEVICE, current_fsvdlg.device, sizeof current_fsvdlg.device);
-       current_fsvdlg.rw = IsDlgButtonChecked (hDlg, IDC_RW);
-       current_fsvdlg.bootpri = GetDlgItemInt(hDlg, IDC_VOLUME_BOOTPRI, NULL, TRUE);
-       recursive--;
+           GetDlgItemText (hDlg, IDC_PATH_NAME, current_fsvdlg.rootdir, sizeof current_fsvdlg.rootdir);
+           GetDlgItemText (hDlg, IDC_VOLUME_NAME, current_fsvdlg.volume, sizeof current_fsvdlg.volume);
+           GetDlgItemText (hDlg, IDC_VOLUME_DEVICE, current_fsvdlg.device, sizeof current_fsvdlg.device);
+           current_fsvdlg.rw = IsDlgButtonChecked (hDlg, IDC_RW);
+           current_fsvdlg.bootpri = GetDlgItemInt(hDlg, IDC_VOLUME_BOOTPRI, NULL, TRUE);
+           recursive--;
        break;
     }
     return FALSE;
@@ -6331,6 +6349,7 @@ static void harddisk_edit (HWND hDlg)
        }
        current_fsvdlg.rw = !uci->readonly;
        current_fsvdlg.bootpri = uci->bootpri;
+       archivehd = -1;
        if (CustomDialogBox(IDD_FILESYS, hDlg, VolumeSettingsProc)) {
            int result = add_filesys_config (&workprefs, entry, current_fsvdlg.device, current_fsvdlg.volume,
                                        current_fsvdlg.rootdir, ! current_fsvdlg.rw, 0, 0, 0, 0, current_fsvdlg.bootpri, 0, 0, 0);
@@ -6350,6 +6369,13 @@ static void harddiskdlg_button (HWND hDlg, int button)
     switch (button) {
      case IDC_NEW_FS:
        current_fsvdlg = empty_fsvdlg;
+       archivehd = 0;
+       if (CustomDialogBox(IDD_FILESYS, hDlg, VolumeSettingsProc))
+           new_filesys (hDlg);
+       break;
+     case IDC_NEW_FSARCH:
+        archivehd = 1;
+       current_fsvdlg = empty_fsvdlg;
        if (CustomDialogBox(IDD_FILESYS, hDlg, VolumeSettingsProc))
            new_filesys (hDlg);
        break;
@@ -6451,13 +6477,12 @@ static void hilitehd (void)
 
 static INT_PTR CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-
     switch (msg) {
     case WM_INITDIALOG:
        clicked_entry = 0;
        pages[HARDDISK_ID] = hDlg;
        currentpage = HARDDISK_ID;
-       EnableWindow (GetDlgItem(hDlg, IDC_NEW_HD), os_winnt && os_winnt_admin ? TRUE : FALSE);
+       EnableWindow (GetDlgItem(hDlg, IDC_NEW_HD), os_winnt && os_winnt_admin > 1 ? TRUE : FALSE);
        
     case WM_USER:
        CheckDlgButton (hDlg, IDC_MAPDRIVES, workprefs.win32_automount_drives);
@@ -9468,101 +9493,111 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int       currentpage)
     }
     firstdrv = drv;
     for (i = 0; i < cnt; i++) {
+       struct romdata *rd = NULL;
        struct zfile *z;
+       int type = -1;
+
        DragQueryFile (hd, i, file, sizeof (file));
         flags = GetFileAttributes(file);
-       z = zfile_fopen (file, "rb");
-       if (z) {
-           int type = zfile_gettype (z);
-           struct romdata *rd = getromdatabyzfile (z);
-           zfile_fclose (z);
-           switch (type)
-           {
-               case  ZFILE_DISKIMAGE:
-                   if (currentpage == DISK_ID) {
-                       list = 0;
-                       while (list < MAX_SPARE_DRIVES) {
-                           if (!strcasecmp (prefs->dfxlist[list], file))
-                               break;
-                           list++;
-                       }
-                       if (list == MAX_SPARE_DRIVES) {
-                           list = 0;
-                           while (list < MAX_SPARE_DRIVES) {
-                               if (!prefs->dfxlist[list][0]) {
-                                   strcpy (prefs->dfxlist[list], file);
-                                   break;
-                               }
-                               list++;
+       if (flags & FILE_ATTRIBUTE_DIRECTORY)
+           type = ZFILE_HDF;
+       if (type < 0) {
+           z = zfile_fopen (file, "rb");
+           if (z) {
+               type = zfile_gettype (z);
+               rd = getromdatabyzfile (z);
+               zfile_fclose (z);
+               z = NULL;
+           }
+       }
+
+       switch (type)
+       {
+           case  ZFILE_DISKIMAGE:
+               if (currentpage == DISK_ID) {
+                   list = 0;
+                   while (list < MAX_SPARE_DRIVES) {
+                       if (!strcasecmp (prefs->dfxlist[list], file))
+                           break;
+                       list++;
+                   }
+                   if (list == MAX_SPARE_DRIVES) {
+                       list = 0;
+                       while (list < MAX_SPARE_DRIVES) {
+                           if (!prefs->dfxlist[list][0]) {
+                               strcpy (prefs->dfxlist[list], file);
+                               break;
                            }
+                           list++;
                        }
-                   } else {
-                       strcpy (workprefs.df[drv], file);
-                       disk_insert (drv, workprefs.df[drv]);
-                       drv++;
-                       if (drv >= (currentpage == QUICKSTART_ID ? 2 : 4))
-                           drv = 0;
-                       if (workprefs.dfxtype[drv] < 0)
-                           drv = 0;
-                       if (drv == firstdrv)
-                           i = cnt;
                    }
-               break;
-               case ZFILE_ROM:
-                   if (rd) {
-                       if (rd->type == ROMTYPE_KICK || rd->type == ROMTYPE_KICKCD32)
-                           strcpy (prefs->romfile, file);
-                       if (rd->type == ROMTYPE_EXTCD32 || rd->type == ROMTYPE_EXTCDTV)
-                           strcpy (prefs->romextfile, file);
-                       if (rd->type == ROMTYPE_AR)
-                           strcpy (prefs->cartfile, file);
+               } else {
+                   strcpy (workprefs.df[drv], file);
+                   disk_insert (drv, workprefs.df[drv]);
+                   drv++;
+                   if (drv >= (currentpage == QUICKSTART_ID ? 2 : 4))
+                       drv = 0;
+                   if (workprefs.dfxtype[drv] < 0)
+                       drv = 0;
+                   if (drv == firstdrv)
+                       i = cnt;
+               }
+           break;
+           case ZFILE_ROM:
+               if (rd) {
+                   if (rd->type == ROMTYPE_KICK || rd->type == ROMTYPE_KICKCD32)
+                       strcpy (prefs->romfile, file);
+                   if (rd->type == ROMTYPE_EXTCD32 || rd->type == ROMTYPE_EXTCDTV)
+                       strcpy (prefs->romextfile, file);
+                   if (rd->type == ROMTYPE_AR)
+                       strcpy (prefs->cartfile, file);
+               } else {
+                   strcpy (prefs->romfile, file);
+               }
+           break;
+           case ZFILE_HDF:
+               if (flags & FILE_ATTRIBUTE_DIRECTORY) {
+                   add_filesys_config (&workprefs, -1, NULL, "", file, 0,
+                       0, 0, 0, 0, 0, NULL, 0, 0);
+               } else {
+                   add_filesys_config (&workprefs, -1, NULL, NULL, file, 0,
+                       32, 1, 2, 512, 0, NULL, 0, 0);
+               }
+           break;
+           case ZFILE_NVR:
+               strcpy (prefs->flashfile, file);
+           break;
+           case ZFILE_CONFIGURATION:
+               if (target_cfgfile_load (&workprefs, file, 0, 0)) {
+                   if (full_property_sheet) {
+                       inputdevice_updateconfig (&workprefs);
+                       if (!workprefs.start_gui)
+                           ret = 1;
                    } else {
-                       strcpy (prefs->romfile, file);
-                   }
-               break;
-               case ZFILE_HDF:
-               {
-                   if (currentpage == HARDDISK_ID) {
-                       if (flags & FILE_ATTRIBUTE_DIRECTORY) {
-                           add_filesys_config (&workprefs, -1, NULL, "XXX", file, 0,
-                               0, 0, 0, 0, 0, NULL, 0, 0);
-                       } else {
-                           add_filesys_config (&workprefs, -1, NULL, NULL, file, 0,
-                               32, 1, 2, 512, 0, NULL, 0, 0);
-                       }
+                       uae_restart (workprefs.start_gui, file);
+                       ret = 1;
                    }
                }
-               break;
-               case ZFILE_NVR:
-                   strcpy (prefs->flashfile, file);
-               break;
-               case ZFILE_CONFIGURATION:
-                   if (target_cfgfile_load (&workprefs, file, 0, 0)) {
-                       if (full_property_sheet) {
-                           inputdevice_updateconfig (&workprefs);
-                           if (!workprefs.start_gui)
-                               ret = 1;
-                       } else {
-                           uae_restart (workprefs.start_gui, file);
-                           ret = 1;
-                       }
+           break;
+           case ZFILE_STATEFILE:
+               savestate_state = STATE_DORESTORE;
+               strcpy (savestate_fname, file);
+               ret = 1;
+           break;
+           default:
+               if (currentpage == HARDDISK_ID) {
+                   add_filesys_config (&workprefs, -1, NULL, "", file, 0,
+                       0, 0, 0, 0, 0, NULL, 0, 0);
+               } else {
+                   rd = scan_arcadia_rom (file, 0);
+                   if (rd) {
+                       if (rd->type == ROMTYPE_ARCADIABIOS)
+                           strcpy (prefs->romextfile, file);
+                       else if (rd->type == ROMTYPE_ARCADIAGAME)
+                           strcpy (prefs->cartfile, file);
                    }
-               break;
-               case ZFILE_STATEFILE:
-                   savestate_state = STATE_DORESTORE;
-                   strcpy (savestate_fname, file);
-                   ret = 1;
-               break;
-               default:
-               rd = scan_arcadia_rom (file, 0);
-               if (rd) {
-                   if (rd->type == ROMTYPE_ARCADIABIOS)
-                       strcpy (prefs->romextfile, file);
-                   else if (rd->type == ROMTYPE_ARCADIAGAME)
-                       strcpy (prefs->cartfile, file);
                }
-               break;
-           }
+           break;
        }
     }
     DragFinish (hd);
index 9b2ca217efd46a5e86128602c572b1b557bb80b7..6fb09dd184951432435ebbddfd1182c715b29e43 100755 (executable)
@@ -68,7 +68,7 @@
                                SuppressStartupBanner="true"
                                Detect64BitPortabilityProblems="false"
                                DebugInformationFormat="4"
-                               CompileAs="1"
+                               CompileAs="0"
                                DisableSpecificWarnings="4996"
                                EnablePREfast="false"
                        />
                                ProgramDataBaseFileName=".\Release/"
                                WarningLevel="3"
                                SuppressStartupBanner="true"
-                               CompileAs="1"
+                               CompileAs="0"
                                DisableSpecificWarnings="4996"
                                ForcedIncludeFiles=""
                        />
                                ProgramDataBaseFileName=".\FullRelease/"
                                WarningLevel="3"
                                SuppressStartupBanner="true"
-                               CompileAs="1"
+                               CompileAs="0"
                                DisableSpecificWarnings="4996"
                                ForcedIncludeFiles=""
                        />
                                >
                        </File>
                        <File
-                               RelativePath="..\..\unzip.c"
+                               RelativePath="..\..\zfile.c"
                                >
                        </File>
                        <File
-                               RelativePath="..\..\zfile.c"
+                               RelativePath="..\..\zfile_archive.c"
                                >
                        </File>
                </Filter>
                                >
                        </File>
                </Filter>
-               <Filter
-                       Name="dms"
-                       >
-                       <File
-                               RelativePath="..\..\dms\cdata.h"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\dms\crc_csum.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\dms\getbits.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\dms\maketbl.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\dms\pfile.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\dms\tables.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\dms\u_deep.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\dms\u_heavy.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\dms\u_init.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\dms\u_medium.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\dms\u_quick.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\dms\u_rle.c"
-                               >
-                       </File>
-               </Filter>
                <Filter
                        Name="prowizard"
                        >
                        </Filter>
                </Filter>
                <Filter
-                       Name="7z"
+                       Name="decompressors"
                        >
-                       <File
-                               RelativePath="..\..\7z\7zAlloc.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\7z\7zBuffer.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\7z\7zCrc.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\7z\7zDecode.c"
-                               >
-                       </File>
-                       <File
-                               RelativePath="..\..\7z\7zExtract.c"
+                       <Filter
+                               Name="dms"
                                >
-                       </File>
-                       <File
-                               RelativePath="..\..\7z\7zHeader.c"
+                               <File
+                                       RelativePath="..\..\archivers\dms\crc_csum.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\dms\getbits.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\dms\maketbl.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\dms\pfile.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\dms\tables.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\dms\u_deep.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\dms\u_heavy.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\dms\u_init.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\dms\u_medium.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\dms\u_quick.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\dms\u_rle.c"
+                                       >
+                               </File>
+                       </Filter>
+                       <Filter
+                               Name="7z"
                                >
-                       </File>
-                       <File
-                               RelativePath="..\..\7z\7zIn.c"
+                               <File
+                                       RelativePath="..\..\archivers\7z\7zAlloc.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\7z\7zBuffer.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\7z\7zCrc.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\7z\7zDecode.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\7z\7zExtract.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\7z\7zHeader.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\7z\7zIn.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\7z\7zItem.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\7z\7zMain.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\7z\7zMethodID.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\7z\LzmaDecode.c"
+                                       >
+                               </File>
+                       </Filter>
+                       <Filter
+                               Name="lha"
                                >
-                       </File>
-                       <File
-                               RelativePath="..\..\7z\7zItem.c"
+                               <File
+                                       RelativePath="..\..\archivers\lha\crcio.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\lha\dhuf.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\lha\header.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\lha\huf.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\lha\larc.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\lha\lhamaketbl.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\lha\lharc.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\lha\shuf.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\lha\slide.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\lha\uae_lha.c"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\archivers\lha\util.c"
+                                       >
+                               </File>
+                       </Filter>
+                       <Filter
+                               Name="zip"
                                >
-                       </File>
-                       <File
-                               RelativePath="..\..\7z\7zMethodID.c"
+                               <File
+                                       RelativePath="..\..\archivers\zip\unzip.c"
+                                       >
+                               </File>
+                       </Filter>
+                       <Filter
+                               Name="lzx"
                                >
-                       </File>
-                       <File
-                               RelativePath="..\..\7z\LzmaDecode.c"
+                               <File
+                                       RelativePath="..\..\archivers\lzx\unlzx.c"
+                                       >
+                               </File>
+                       </Filter>
+                       <Filter
+                               Name="xfd"
                                >
-                       </File>
+                               <File
+                                       RelativePath="..\..\archivers\xfd\xfd.c"
+                                       >
+                               </File>
+                       </Filter>
                </Filter>
                <File
                        RelativePath="..\resources\drive_click.wav"
index 831045def846c5634de903ad8fd1bd437cb4350f..2ddce2d9efc024433882b7fe34bd52673115ab0a 100755 (executable)
@@ -1,4 +1,38 @@
 
+Beta 5:
+
+- JIT on/off switching via uae-configuration re-enables direct mode
+  This time it really should work as designed.
+- video recording sound pitch change fix (side-effects possible..)
+- random FPU fixes from Aranym (which btw, isn't feature complete
+  either, at least float to integer clamping is missing)
+- rom scanner uses SHA-1 now (instead of CRC32)
+- archive as a harddrive emulation. Data is decompressed on the fly.
+  Only directory tree is allocated in memory during mount-phase.
+  "file not found error" will be returned if decompression fails
+  (corrupt archive?) Already decompressed files will be left in
+  memory (memory is cheap, repeated decompression can be slow)
+- archive support completely rewritten (memory/file leaks possible)
+  Recursive decompression possible (not yet enabled and not fully
+  implemented), not sure if I enable it later or not.. (would
+  enable transparent archives inside archives inside archives etc..)
+- work in progress (this is really crazy idea..): xfd (Amiga
+  decompression library) slave library support via separate 68k
+  emulation instance :D Crazy or very stupid idea, not sure yet..
+  It would enable full transparent decompression support of nearly
+  every Amiga compression format..
+- built-in lha/lzh archive support added
+- built-in lzx archive support added (store mode not supported yet)
+- "add directory/archive" harddrives: only path is mandatory, volume
+  name (if left empty) is automatically generated from selected path
+- added "add archive" harddrive type. Single plain file also accepted.
+- real harddrive "safety check" system changed, now all drives are
+  listed (and marked as empty,non-empty or RDB) but drive is not
+  mounted if safety check is not disabled and drive is non-empty.
+- disable "add harddrive" on vista without full admin privileges
+- harddisk panel directory and archive dragndrop added
+
+
 Beta 4:
 
 - return SCSI-1 style inquiry response when using A590/A2091 SCSI
index 03f08f1d4828963edc1231297f08eea71580038e..1bb874c2951092c3fa5b8caf954d4d0d2aa24b26 100755 (executable)
@@ -322,7 +322,6 @@ int prowizard_search (Uchar *in_data_p, int PW_in_size_p)
       /* The player 6.0a (packed samples)? */
       if ( testP60A_pack() != BAD )
       {
-        write_log ( "\b\b\b\b\b\b\b\bThe Player 6.0A with PACKED samples found at %ld ... cant rip it!\n" , PW_Start_Address );
         /*Rip_P60A ();*/
         /*Depack_P60A ();*/
         continue;
@@ -339,7 +338,6 @@ int prowizard_search (Uchar *in_data_p, int PW_in_size_p)
       /* The player 6.1a (packed samples)? */
       if ( testP61A_pack() != BAD )
       {
-        write_log ( "\b\b\b\b\b\b\b\bThe Player 6.1A with PACKED samples found at %ld ... cant rip it!\n" , PW_Start_Address );
         /*Rip_P61A ();*/
         /*Depack_P61A ();*/
         continue;
index 01bb34eefe977cae9b5ad652e0d47e2f32dbfabb..409e1f9c1d02eec2da647d1521b02d60c5d44576 100755 (executable)
@@ -196,7 +196,7 @@ char *restore_string_func (uae_u8 **dstp)
     uae_u8 *dst = *dstp;
     char *top, *to;
     len = strlen(dst) + 1;
-    top = to = malloc (len);
+    top = to = (char*)malloc (len);
     do {
        v = *dst++;
        *top++ = v;
@@ -311,7 +311,7 @@ static uae_u8 *restore_chunk (struct zfile *f, char *name, size_t *len, size_t *
        && strcmp (name, "PRAM") != 0)
     {
        /* without zeros at the end old state files may not work */
-       mem = calloc (1, len2 + 32);
+       mem = (uae_u8*)calloc (1, len2 + 32);
        zfile_fread (mem, 1, len2, f);
     } else {
        mem = 0;
@@ -604,7 +604,7 @@ int save_state (char *filename, char *description)
            int len, len2, i;
            uae_u8 *tmp;
            len = zfile_ftell(f) - pos;
-           tmp = xmalloc(len);
+           tmp = (uae_u8*)xmalloc(len);
            zfile_fseek(f, pos, SEEK_SET);
            len2 = zfile_fread(tmp, 1, len, f);
            for (i = 0; i < len2; i++)
@@ -1089,7 +1089,7 @@ void savestate_init (void)
     frameextra = 0;
     if (currprefs.statecapture && currprefs.statecapturebuffersize && currprefs.statecapturerate) {
        replaybuffersize = currprefs.statecapturebuffersize;
-       replaybuffer = malloc (replaybuffersize);
+       replaybuffer = (uae_u8*)malloc (replaybuffersize);
     }
 }
 
diff --git a/scsi.c b/scsi.c
index 495c935f74de2597ff6b57074c834fdc1a0cb0ad..6d8348e68fd7ddeefc3cfb637ad63e7411cfa10b 100755 (executable)
--- a/scsi.c
+++ b/scsi.c
@@ -88,7 +88,7 @@ void scsi_emulate_cmd(struct scsi_data *sd)
 
 struct scsi_data *scsi_alloc(int id, struct hd_hardfiledata *hfd)
 {
-    struct scsi_data *sd = xcalloc(sizeof (struct scsi_data), 1);
+    struct scsi_data *sd = (struct scsi_data*)xcalloc(sizeof (struct scsi_data), 1);
     sd->hfd = hfd;
     sd->id = id;
     sd->nativescsiunit = -1;
@@ -102,7 +102,7 @@ struct scsi_data *scsi_alloc_native(int id, int nativeunit)
        write_log("SCSI: native scsi unit %d failed to open\n", nativeunit);
        return NULL;
     }
-    sd = xcalloc(sizeof (struct scsi_data), 1);
+    sd = (struct scsi_data*)xcalloc(sizeof (struct scsi_data), 1);
     sd->id = id;
     sd->nativescsiunit = nativeunit;
     return sd;
index abf83d2b59b26c34fa8000e143257f2c764b71cf..672579a39820917282dea735e0f68953ce3e81e9 100755 (executable)
@@ -25,6 +25,7 @@
 #include "native2amiga.h"
 #include "blkdev.h"
 #include "scsidev.h"
+#include "uae.h"
 
 #define CDDEV_COMMANDS
 
@@ -622,7 +623,7 @@ static uae_u32 REGPARAM2 dev_beginio (TrapContext *context)
 
 static void *dev_thread (void *devs)
 {
-    struct devstruct *dev = devs;
+    struct devstruct *dev = (struct devstruct*)devs;
 
     uae_set_thread_priority (2);
     dev->thread_running = 1;
diff --git a/traps.c b/traps.c
index 624ad267b790d00462bd88664ed2c1a60628620e..25ff7b684c377cacb3d962173e97fdc8a12ca495 100755 (executable)
--- a/traps.c
+++ b/traps.c
@@ -248,7 +248,7 @@ static void *trap_thread (void *arg)
  */
 static void trap_HandleExtendedTrap (TrapHandler handler_func, int has_retval)
 {
-    struct ExtendedTrapContext *context = calloc (1, sizeof (ExtendedTrapContext));
+    struct ExtendedTrapContext *context = (struct ExtendedTrapContext*)calloc (1, sizeof (ExtendedTrapContext));
 
     if (context) {
        uae_sem_init (&context->switch_to_trap_sem, 0, 0);
@@ -368,7 +368,7 @@ static uae_u32 REGPARAM2 m68k_return_handler (struct regstruct *regs)
 
     /* Get trap context from 68k stack. */
     sp = m68k_areg (regs, 7);
-    context = get_pointer(sp);
+    context = (struct ExtendedTrapContext*)get_pointer(sp);
     sp += sizeof (void *);
     m68k_areg (regs, 7) = sp;
 
index 44fa1e254d5fffd3e01536f31ef9b96fc9befd87..98b755d41896415de69d2f751a7365256f2ed3d3 100755 (executable)
--- a/uaeexe.c
+++ b/uaeexe.c
@@ -51,10 +51,10 @@ int uaeexe(const char *cmd)
     if (!running)
        goto NORUN;
 
-    nw = malloc (sizeof *nw);
+    nw = (struct uae_xcmd*)malloc (sizeof *nw);
     if (!nw)
        goto NOMEM;
-    nw->cmd = malloc (strlen (cmd) + 1);
+    nw->cmd = (char*)malloc (strlen (cmd) + 1);
     if (!nw->cmd) {
        free (nw);
        goto NOMEM;
index 1a296693d304eea9ac0ed31ad5800e53b8e37ccd..c8d2bb93e16c84c5e468afd235b79251af12ecdf 100755 (executable)
--- a/uaeipc.c
+++ b/uaeipc.c
@@ -12,7 +12,7 @@
 
 #include <windows.h>
 
-static HANDLE *hipc = INVALID_HANDLE_VALUE, *olevent = INVALID_HANDLE_VALUE;
+static HANDLE hipc = INVALID_HANDLE_VALUE, olevent = INVALID_HANDLE_VALUE;
 static OVERLAPPED ol;
 #define IPC_BUFFER_SIZE 16384
 static uae_u8 buffer[IPC_BUFFER_SIZE], outbuf[IPC_BUFFER_SIZE];
@@ -224,10 +224,10 @@ int checkIPC(struct uae_prefs *p)
     }
     readpending = FALSE;
     write_log("IPC: got message '%s'\n", buffer);
-    parsemessage(buffer, p, outbuf, sizeof outbuf);
+    parsemessage((char*)buffer, p, (char*)outbuf, sizeof outbuf);
     memset (&ol, 0, sizeof ol);
     ol.hEvent = olevent;
-    ok = WriteFile(hipc, outbuf, strlen (outbuf) + 1, &ret, &ol);
+    ok = WriteFile(hipc, outbuf, strlen ((char*)outbuf) + 1, &ret, &ol);
     err = GetLastError();
     if (!ok && err != ERROR_IO_PENDING) {
        write_log ("IPC: WriteFile() err=%d\n", err);
index cf1d286672a51b5c4350c3f01aee725fbdae7f7b..73f2d7fabba0306cb7cb47b35f87c4eec96b2360 100755 (executable)
@@ -344,7 +344,7 @@ static int add_async_request (struct devstruct *dev, uaecptr request)
        write_log ("%s:%d async request %x added\n", getdevname(), dev->unit, request);
 
     uae_sem_wait (&async_sem);
-    ar = xcalloc (sizeof (struct asyncreq), 1);
+    ar = (struct asyncreq*)xcalloc (sizeof (struct asyncreq), 1);
     ar->request = request;
     if (!dev->ar) {
        dev->ar = ar;
@@ -585,7 +585,7 @@ static uae_u32 REGPARAM2 dev_beginio (TrapContext *context)
 
 static void *dev_thread (void *devs)
 {
-    struct devstruct *dev = devs;
+    struct devstruct *dev = (struct devstruct*)devs;
 
     uae_set_thread_priority (2);
     dev->thread_running = 1;
diff --git a/zfile.c b/zfile.c
index 4e58907a9bff8a39e4f3c53012d7be693abfed30..c3afd974879c9c3117e508e2fa938d0427692ad5 100755 (executable)
--- a/zfile.c
+++ b/zfile.c
@@ -4,7 +4,7 @@
   * routines to handle compressed file automatically
   *
   * (c) 1996 Samuel Devulder, Tim Gunn
-  *     2002-2004 Toni Wilen
+  *     2002-2007 Toni Wilen
   */
 
 #define ZLIB_WINAPI
 
 #include "options.h"
 #include "zfile.h"
-#include "unzip.h"
 #include "disk.h"
-#include "dms/pfile.h"
 #include "gui.h"
 #include "crc32.h"
 #include "fsdb.h"
+#include "fsusage.h"
+#include "zarchive.h"
 
-#include <zlib.h>
-
-struct zfile {
-    char *name;
-    char *zipname;
-    FILE *f;
-    uae_u8 *data;
-    int size;
-    int seek;
-    int deleteafterclose;
-    struct zfile *next;
-    int writeskipbytes;
-};
+#include "archivers/zip/unzip.h"
+#include "archivers/dms/pfile.h"
 
 static struct zfile *zlist = 0;
 
-const char *uae_archive_extensions[] = { "zip", "rar", "7z", NULL };
+const char *uae_archive_extensions[] = { "zip", "rar", "7z", "lha", "lzh", "lzx", NULL };
 
 static struct zfile *zfile_create (void)
 {
     struct zfile *z;
 
-    z = malloc (sizeof *z);
+    z = (struct zfile*)malloc (sizeof *z);
     if (!z)
        return 0;
     memset (z, 0, sizeof *z);
@@ -147,74 +136,6 @@ int zfile_gettype (struct zfile *z)
     return ZFILE_UNKNOWN;
 }
 
-#if 0
-#define TMP_PREFIX "uae_"
-
-static struct zfile *createinputfile (struct zfile *z)
-{
-    FILE *f;
-    struct zfile *z2;
-    char *name;
-
-    z2 = zfile_create ();
-    if (!z->data) {
-       z2->name = strdup (z->name);
-       return z2;
-    }
-    name = tempnam (0, TMP_PREFIX);
-    f = fopen (name, "wb");
-    if (!f) return 0;
-    write_log ("created temporary file '%s'\n", name);
-    fwrite (z->data, z->size, 1, f);
-    fclose (f);
-    z2->name = name;
-    z2->deleteafterclose = 1;
-    return z2;
-}
-
-static struct zfile *createoutputfile (struct zfile *z)
-{
-    struct zfile *z2;
-    char *name;
-
-    name = tempnam (0, TMP_PREFIX);
-    z2 = zfile_create ();
-    z2->name = name;
-    z2->deleteafterclose = 1;
-    write_log ("allocated temporary file name '%s'\n", name);
-    return z2;
-}
-
-/* we want to delete temporary files as early as possible */
-static struct zfile *updateoutputfile (struct zfile *z)
-{
-    struct zfile *z2 = 0;
-    int size;
-    FILE *f = fopen (z->name, "rb");
-    for (;;) {
-       if (!f)
-           break;
-       fseek (f, 0, SEEK_END);
-       size = ftell (f);
-       fseek (f, 0, SEEK_SET);
-       if (!size)
-           break;
-       z2 = zfile_fopen_empty (z->name, size);
-       if (!z2)
-           break;
-       fread (z2->data, size, 1, f);
-       fclose (f);
-       zfile_fclose (z);
-       return z2;
-    }
-    if (f)
-       fclose (f);
-    zfile_fclose (z);
-    zfile_fclose (z2);
-    return 0;
-}
-#endif
-
 static struct zfile *zuncompress (struct zfile *z);
 
 struct zfile *zfile_gunzip (struct zfile *z)
@@ -298,17 +219,6 @@ struct zfile *zfile_gunzip (struct zfile *z)
     return z2;
 }
 
-
-static struct zfile *bunzip (const char *decompress, struct zfile *z)
-{
-    return z;
-}
-
-static struct zfile *lha (struct zfile *z)
-{
-    return z;
-}
-
 static struct zfile *dms (struct zfile *z)
 {
     int ret;
@@ -324,22 +234,6 @@ static struct zfile *dms (struct zfile *z)
     return z;
 }
 
-#if 0
-static struct zfile *dms (struct zfile *z)
-{
-    char cmd[2048];
-    struct zfile *zi = createinputfile (z);
-    struct zfile *zo = createoutputfile (z);
-    if (zi && zo) {
-       sprintf(cmd, "xdms -q u \"%s\" +\"%s\"", zi->name, zo->name);
-       execute_command (cmd);
-    }
-    zfile_fclose (zi);
-    zfile_fclose (z);
-    return updateoutputfile (zo);
-}
-#endif
-
 const char *uae_ignoreextensions[] =
     { ".gif", ".jpg", ".png", ".xml", ".pdf", ".txt", 0 };
 const char *uae_diskimageextensions[] =
@@ -371,582 +265,16 @@ int zfile_isdiskimage (const char *name)
     return 0;
 }
 
-#define ArchiveFormat7Zip '7z  '
-#define ArchiveFormatRAR 'rar '
-#define ArchiveFormatZIP 'zip '
-
-#if defined(ARCHIVEACCESS)
-
-struct aaFILETIME
-{
-    uae_u32 dwLowDateTime;
-    uae_u32 dwHighDateTime;
-};
-typedef void* aaHandle;
-// This struct contains file information from an archive. The caller may store 
-// this information for accessing this file after calls to findFirst, findNext
-#define FileInArchiveInfoStringSize 1024
-struct aaFileInArchiveInfo {
-       int ArchiveHandle; // handle for Archive/class pointer
-       uae_u64 CompressedFileSize;
-       uae_u64 UncompressedFileSize;
-       uae_u32 attributes;
-       int IsDir, IsEncrypted;
-       struct aaFILETIME LastWriteTime;
-       char path[FileInArchiveInfoStringSize];
-};
 
-typedef HRESULT (__stdcall *aaReadCallback)(int StreamID, uae_u64 offset, uae_u32 count, void* buf, uae_u32 *processedSize);
-typedef HRESULT (__stdcall *aaWriteCallback)(int StreamID, uae_u64 offset, uae_u32 count, const void *buf, uae_u32 *processedSize);
-typedef aaHandle (__stdcall *aapOpenArchive)(aaReadCallback function, int StreamID, uae_u64 FileSize, int ArchiveType, int *result, char *password);
-typedef int (__stdcall *aapGetFileCount)(aaHandle ArchiveHandle);
-typedef int (__stdcall *aapGetFileInfo)(aaHandle ArchiveHandle, int FileNum, struct aaFileInArchiveInfo *FileInfo);
-typedef int (__stdcall *aapExtract)(aaHandle ArchiveHandle, int FileNum, int StreamID, aaWriteCallback WriteFunc, uae_u64 *written);
-typedef int (__stdcall *aapCloseArchive)(aaHandle ArchiveHandle);
-
-static aapOpenArchive aaOpenArchive;
-static aapGetFileCount aaGetFileCount;
-static aapGetFileInfo aaGetFileInfo;
-static aapExtract aaExtract;
-static aapCloseArchive aaCloseArchive;
-
-#ifdef _WIN32
-#include <windows.h>
-#include "win32.h"
-static HMODULE arcacc_mod;
-
-static void arcacc_free (void)
-{
-    if (arcacc_mod)
-       FreeLibrary (arcacc_mod);
-    arcacc_mod = NULL;
-}
-
-static int arcacc_init (void)
-{
-    if (arcacc_mod)
-       return 1;
-    arcacc_mod = WIN32_LoadLibrary ("archiveaccess.dll");
-    if (!arcacc_mod) {
-       write_log ("failed to open archiveaccess.dll\n");
-       return 0;
-    }
-    aaOpenArchive = (aapOpenArchive) GetProcAddress (arcacc_mod, "aaOpenArchive");
-    aaGetFileCount = (aapGetFileCount) GetProcAddress (arcacc_mod, "aaGetFileCount");
-    aaGetFileInfo = (aapGetFileInfo) GetProcAddress (arcacc_mod, "aaGetFileInfo");
-    aaExtract = (aapExtract) GetProcAddress (arcacc_mod, "aaExtract");
-    aaCloseArchive = (aapCloseArchive) GetProcAddress (arcacc_mod, "aaCloseArchive");
-    if (!aaOpenArchive || !aaGetFileCount || !aaGetFileInfo || !aaExtract || !aaCloseArchive) {
-       write_log ("Missing functions in archiveaccess.dll. Old version?\n");
-       arcacc_free ();
-       return 0;
-    }
-    return 1;
-}
-#endif
-
-#define ARCACC_STACKSIZE 10
-static struct zfile *arcacc_stack[ARCACC_STACKSIZE];
-static int arcacc_stackptr = -1;
-
-static int arcacc_push (struct zfile *f)
-{
-    if (arcacc_stackptr == ARCACC_STACKSIZE - 1)
-       return -1;
-    arcacc_stackptr++;
-    arcacc_stack[arcacc_stackptr] = f;
-    return arcacc_stackptr;
-}
-static void arcacc_pop (void)
-{
-    arcacc_stackptr--;
-}
-
-static HRESULT __stdcall readCallback (int StreamID, uae_u64 offset, uae_u32 count, void *buf, uae_u32 *processedSize)
-{
-    struct zfile *f = arcacc_stack[StreamID];
-    int ret;
-
-    zfile_fseek (f, (long)offset, SEEK_SET);
-    ret = zfile_fread (buf, 1, count, f);
-    if (processedSize)
-       *processedSize = ret;
-    return 0;
-}
-static HRESULT __stdcall writeCallback (int StreamID, uae_u64 offset, uae_u32 count, const void *buf, uae_u32 *processedSize)
-{
-    struct zfile *f = arcacc_stack[StreamID];
-    int ret;
-
-    ret = zfile_fwrite ((void*)buf, 1, count, f);
-    if (processedSize)
-       *processedSize = ret;
-    if (ret != count)
-       return -1;
-    return 0;
-}
-
-static struct zfile *arcacc_unpack (struct zfile *z, int type)
-{
-    aaHandle ah;
-    int status, f;
-    char tmphist[MAX_DPATH];
-    int first = 1;
-    int we_have_file = 0;
-    int size, id_r, id_w;
-    struct zfile *zf;
-    int skipsize = 0;
-
-    tmphist[0] = 0;
-    zf = 0;
-    if (!arcacc_init ())
-       return z;
-    id_r = arcacc_push (z);
-    zfile_fseek (z, 0, SEEK_END);
-    size = zfile_ftell (z);
-    zfile_fseek (z, 0, SEEK_SET);
-    ah = aaOpenArchive (readCallback, id_r, size, type, &status, NULL);
-    if (!status) {
-       int fc = aaGetFileCount (ah);
-       int zipcnt = 0;
-       for (f = 0; f < fc; f++) {
-           struct aaFileInArchiveInfo fi;
-           char *name;
-
-           zipcnt++;
-           memset (&fi, 0, sizeof (fi));
-           aaGetFileInfo (ah, f, &fi);
-           if (fi.IsDir)
-               continue;
-
-           name = fi.path;
-           if (!zfile_is_ignore_ext(name)) {
-               int select = 0;
-               if (tmphist[0]) {
-                   DISK_history_add (tmphist, -1);
-                   tmphist[0] = 0;
-                   first = 0;
-               }
-               if (first) {
-                   if (zfile_isdiskimage (name))
-                       sprintf (tmphist,"%s/%s", z->name, name);
-               } else {
-                   sprintf (tmphist,"%s/%s", z->name, name);
-                   DISK_history_add (tmphist, -1);
-                   tmphist[0] = 0;
-               }
-               if (!z->zipname)
-                   select = 1;
-               if (z->zipname && !strcasecmp (z->zipname, name))
-                   select = -1;
-               if (z->zipname && z->zipname[0] == '#' && atol (z->zipname + 1) == zipcnt)
-                   select = -1;
-               if (select && !we_have_file) {
-
-                   zf = zfile_fopen_empty (name, (int)fi.UncompressedFileSize);
-                   if (zf) {
-                       int err;
-                       uae_u64 written = 0;
-                       zf->writeskipbytes = skipsize;
-                       id_w = arcacc_push (zf);
-                       err = aaExtract (ah, f, id_w, writeCallback, &written);
-                       if (zf->seek != fi.UncompressedFileSize)
-                           write_log ("%s unpack failed, got only %d bytes\n", name, zf->seek);
-                       if (zf->seek == fi.UncompressedFileSize && (select < 0 || zfile_gettype (zf)))
-                           we_have_file = 1;
-                        if (!we_have_file) {
-                           zfile_fclose (zf);
-                           zf = 0;
-                       }
-                       arcacc_pop ();
-                   }
-               }
-           }
-           if (type == ArchiveFormat7Zip) {
-               if (fi.CompressedFileSize)
-                   skipsize = 0;
-               skipsize += (int)fi.UncompressedFileSize;
-           }
-       }
-        aaCloseArchive (ah);
-    }
-    arcacc_pop ();
-    if (zf) {
-       zfile_fclose (z);
-       z = zf;
-       zfile_fseek (z, 0, SEEK_SET);
-    }
-    return z;
-}
-
-#endif
-
-
-#include "7z/7zCrc.h"
-#include "7z/7zIn.h"
-#include "7z/7zExtract.h"
-
-typedef struct _CFileInStream
-{
-  ISzInStream InStream;
-  struct zfile *zf;
-} CFileInStream;
-
-static CFileInStream archiveStream;
-static CArchiveDatabaseEx db;
-static ISzAlloc allocImp;
-static ISzAlloc allocTempImp;
-
-static SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize)
-{
-  CFileInStream *s = (CFileInStream *)object;
-  size_t processedSizeLoc = zfile_fread(buffer, 1, size, s->zf);
-  if (processedSize != 0)
-    *processedSize = processedSizeLoc;
-  return SZ_OK;
-}
-
-static SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
-{
-  CFileInStream *s = (CFileInStream *)object;
-  int res = zfile_fseek(s->zf, pos, SEEK_SET);
-  if (res == 0)
-    return SZ_OK;
-  return SZE_FAIL;
-}
-
-static void init_7z(void)
-{
-    static int initialized;
-    if (initialized)
-       return;
-    initialized = 1;
-    archiveStream.InStream.Read = SzFileReadImp;
-    archiveStream.InStream.Seek = SzFileSeekImp;
-    allocImp.Alloc = SzAlloc;
-    allocImp.Free = SzFree;
-    allocTempImp.Alloc = SzAllocTemp;
-    allocTempImp.Free = SzFreeTemp;
-    InitCrcTable();
-}
-
-static struct zfile *un7z (struct zfile *z)
-{
-    SZ_RESULT res;
-    int i;
-    static int first = 1;
-    char tmphist[MAX_DPATH];
-    struct zfile *zf;
-    int zipcnt = 0;
-    int we_have_file = 0;
-
-    init_7z();
-    SzArDbExInit(&db);
-    tmphist[0] = 0;
-    zf = 0;
-    archiveStream.zf = z;
-    res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp);
-    if (res != SZ_OK)
-       return z;
-    for (i = 0; i < db.Database.NumFiles; i++) {
-       int select = 0;
-       size_t offset;
-       size_t outSizeProcessed;
-       CFileItem *f = db.Database.Files + i;
-       char *name = f->Name;
-
-       zipcnt++;
-       if (f->IsDirectory)
-           continue;
-       if (zfile_is_ignore_ext(name))
-           continue;
-       if (tmphist[0]) {
-           DISK_history_add (tmphist, -1);
-           tmphist[0] = 0;
-           first = 0;
-       }
-       if (first) {
-           if (zfile_isdiskimage (name))
-               sprintf (tmphist,"%s/%s", z->name, name);
-       } else {
-           sprintf (tmphist,"%s/%s", z->name, name);
-           DISK_history_add (tmphist, -1);
-           tmphist[0] = 0;
-       }
-       if (!z->zipname)
-           select = 1;
-       if (z->zipname && !strcasecmp (z->zipname, name))
-           select = -1;
-       if (z->zipname && z->zipname[0] == '#' && atol (z->zipname + 1) == zipcnt)
-           select = -1;
-       if (select && !we_have_file) {
-           zf = zfile_fopen_empty (name, f->Size);
-           if (zf) {
-               uae_u32 blockIndex = 0xffffffff;
-               uae_u8 *outBuffer = 0;
-               size_t outBufferSize = 0;
-               res = SzExtract(&archiveStream.InStream, &db, i, 
-                   &blockIndex, &outBuffer, &outBufferSize, 
-                   &offset, &outSizeProcessed, 
-                   &allocImp, &allocTempImp);
-               if (res == SZ_OK) {
-                   zfile_fwrite (outBuffer + offset, 1, outSizeProcessed, zf);
-                   if (select < 0 || zfile_gettype(zf))
-                       we_have_file = 1;
-               }
-               allocImp.Free(outBuffer);
-               if (!we_have_file) {
-                   zfile_fclose (zf);
-                   zf = 0;
-               }
-           }
-       }
-    }
-    SzArDbExFree(&db, allocImp.Free);
-    if (zf) {
-       zfile_fclose (z);
-       z = zf;
-       zfile_fseek (z, 0, SEEK_SET);
-    }
-    return z;
-}
-
-/* copy and paste job? you are only imagining it! */
-static struct zfile *rarunpackzf; /* stupid unrar.dll */
-#include <unrar.h>
-typedef HANDLE (_stdcall* RAROPENARCHIVE)(struct RAROpenArchiveData*);
-static RAROPENARCHIVE pRAROpenArchive;
-typedef int (_stdcall* RARREADHEADEREX)(HANDLE,struct RARHeaderDataEx*);
-static RARREADHEADEREX pRARReadHeaderEx;
-typedef int (_stdcall* RARPROCESSFILE)(HANDLE,int,char*,char *);
-static RARPROCESSFILE pRARProcessFile;
-typedef int (_stdcall* RARCLOSEARCHIVE)(HANDLE);
-static RARCLOSEARCHIVE pRARCloseArchive;
-typedef void (_stdcall* RARSETCALLBACK)(HANDLE,UNRARCALLBACK,LONG);
-static RARSETCALLBACK pRARSetCallback;
-typedef int (_stdcall* RARGETDLLVERSION)(void);
-static RARGETDLLVERSION pRARGetDllVersion;
-
-static int rar_resetf(struct zfile *z)
-{
-    z->f = fopen (z->name, "rb");
-    if (!z->f) {
-        zfile_fclose (z);
-        return 0;
-    }
-    return 1;
-}
-
-static int canrar(void)
-{
-    static int israr;
-    HMODULE rarlib;
-
-    if (israr == 0) {
-       israr = -1;
-       rarlib = WIN32_LoadLibrary("unrar.dll");
-       if (rarlib) {
-           pRAROpenArchive = (RAROPENARCHIVE)GetProcAddress (rarlib, "RAROpenArchive");
-           pRARReadHeaderEx = (RARREADHEADEREX)GetProcAddress (rarlib, "RARReadHeaderEx");
-           pRARProcessFile = (RARPROCESSFILE)GetProcAddress (rarlib, "RARProcessFile");
-           pRARCloseArchive = (RARCLOSEARCHIVE)GetProcAddress (rarlib, "RARCloseArchive");
-           pRARSetCallback = (RARSETCALLBACK)GetProcAddress (rarlib, "RARSetCallback");
-           pRARGetDllVersion = (RARGETDLLVERSION)GetProcAddress (rarlib, "RARGetDllVersion");
-           if (pRAROpenArchive && pRARReadHeaderEx && pRARProcessFile && pRARCloseArchive && pRARSetCallback) {
-               israr = 1;
-               write_log ("unrar.dll version %08.8X detected and used\n", pRARGetDllVersion ? pRARGetDllVersion() : -1);
-
-           }
-       }
-    }
-    return israr < 0 ? 0 : 1;
-}
-
-static int CALLBACK RARCallbackProc(UINT msg,LONG UserData,LONG P1,LONG P2)
-{
-    if (msg == UCM_PROCESSDATA) {
-       zfile_fwrite((uae_u8*)P1, 1, P2, rarunpackzf);
-       return 0;
-    }
-    return -1;
-}
-static struct zfile *unrar (struct zfile *z)
-{
-    HANDLE hArcData;
-    static int first = 1;
-    char tmphist[MAX_DPATH];
-    struct zfile *zf;
-    int zipcnt;
-    int we_have_file = 0;
-
-    struct RARHeaderDataEx HeaderData; 
-    struct RAROpenArchiveData OpenArchiveData;
-
-    if (!canrar())
-       return arcacc_unpack (z, ArchiveFormatRAR);
-
-    if (z->data)
-        /* wtf? stupid unrar.dll only accept filename as an input.. */
-       return arcacc_unpack (z, ArchiveFormatRAR);
-    fclose (z->f); /* bleh, unrar.dll fails to open the archive if it is already open.. */
-    z->f = NULL;
-    zf = 0;
-    memset(&OpenArchiveData,0,sizeof(OpenArchiveData));
-    OpenArchiveData.ArcName=z->name;
-    OpenArchiveData.OpenMode=RAR_OM_EXTRACT;
-    hArcData=pRAROpenArchive(&OpenArchiveData);
-    if (OpenArchiveData.OpenResult!=0) {
-       if (!rar_resetf(z))
-           return NULL;
-       return arcacc_unpack (z, ArchiveFormatRAR);
-    }
-    pRARSetCallback(hArcData,RARCallbackProc,0);
-    tmphist[0] = 0;
-    zipcnt = 0;
-    while (pRARReadHeaderEx(hArcData,&HeaderData)==0) {
-       int select = 0;
-       int needskip = 1;
-       char *name = HeaderData.FileName;
-       zipcnt++;
-       if (zfile_is_ignore_ext(name))
-           continue;
-       if (tmphist[0]) {
-           DISK_history_add (tmphist, -1);
-           tmphist[0] = 0;
-           first = 0;
-       }
-       if (first) {
-           if (zfile_isdiskimage (name))
-               sprintf (tmphist,"%s/%s", z->name, name);
-       } else {
-           sprintf (tmphist,"%s/%s", z->name, name);
-           DISK_history_add (tmphist, -1);
-           tmphist[0] = 0;
-       }
-       if (!z->zipname)
-           select = 1;
-       if (z->zipname && !strcasecmp (z->zipname, name))
-           select = -1;
-       if (z->zipname && z->zipname[0] == '#' && atol (z->zipname + 1) == zipcnt)
-           select = -1;
-       if (select && !we_have_file && HeaderData.UnpSize > 0) {
-           zf = zfile_fopen_empty (name, HeaderData.UnpSize);
-           rarunpackzf = zf;
-           if (zf && pRARProcessFile(hArcData,RAR_TEST,NULL,NULL) == 0) {
-               needskip = 0;
-               if (select < 0 || zfile_gettype(zf))
-                   we_have_file = 1;
-               if (!we_have_file) {
-                   zfile_fclose (zf);
-                   zf = 0;
-               }
-           }
-       }
-       if (needskip)
-           pRARProcessFile(hArcData,RAR_SKIP,NULL,NULL);
-    }
-    pRARCloseArchive(hArcData);
-    if (zf) {
-       zfile_fclose (z);
-       z = zf;
-       zfile_fseek (z, 0, SEEK_SET);
-    } else {
-       /* bleh continues, reopen the closed archive.. */
-       if (!rar_resetf(z)) 
-           z = NULL;
-    }
-    return z;
-}
-
-static struct zfile *unzip (struct zfile *z)
-{
-    unzFile uz;
-    unz_file_info file_info;
-    char filename_inzip[2048];
-    struct zfile *zf;
-    int err, zipcnt, select, i, we_have_file = 0;
-    char tmphist[MAX_DPATH];
-    int first = 1;
-
-    zf = 0;
-    uz = unzOpen (z);
-    if (!uz)
-       return z;
-    if (unzGoToFirstFile (uz) != UNZ_OK)
-       return z;
-    zipcnt = 1;
-    tmphist[0] = 0;
-    for (;;) {
-       err = unzGetCurrentFileInfo(uz,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
-       if (err != UNZ_OK)
-           return z;
-       if (file_info.uncompressed_size > 0) {
-           i = 0;
-           if (!zfile_is_ignore_ext(filename_inzip)) {
-               if (tmphist[0]) {
-                   DISK_history_add (tmphist, -1);
-                   tmphist[0] = 0;
-                   first = 0;
-               }
-               if (first) {
-                   if (zfile_isdiskimage (filename_inzip))
-                       sprintf (tmphist,"%s/%s", z->name, filename_inzip);
-               } else {
-                   sprintf (tmphist,"%s/%s", z->name, filename_inzip);
-                   DISK_history_add (tmphist, -1);
-                   tmphist[0] = 0;
-               }
-               select = 0;
-               if (!z->zipname)
-                   select = 1;
-               if (z->zipname && !strcasecmp (z->zipname, filename_inzip))
-                   select = -1;
-               if (z->zipname && z->zipname[0] == '#' && atol (z->zipname + 1) == zipcnt)
-                   select = -1;
-               if (select && !we_have_file) {
-                   int err = unzOpenCurrentFile (uz);
-                   if (err == UNZ_OK) {
-                       zf = zfile_fopen_empty (filename_inzip, file_info.uncompressed_size);
-                       if (zf) {
-                           err = unzReadCurrentFile  (uz, zf->data, file_info.uncompressed_size);
-                           unzCloseCurrentFile (uz);
-                           if (err == 0 || err == file_info.uncompressed_size) {
-                               zf = zuncompress (zf);
-                               if (select < 0 || zfile_gettype (zf)) {
-                                   we_have_file = 1;
-                               }
-                           }
-                       }
-                       if (!we_have_file) {
-                           zfile_fclose (zf);
-                           zf = 0;
-                       }
-                   }
-               }
-           }
-       }
-       zipcnt++;
-       err = unzGoToNextFile (uz);
-       if (err != UNZ_OK)
-           break;
-    }
-    if (zf) {
-       zfile_fclose (z);
-       z = zf;
-    }
-    return z;
-}
-
-static const char *plugins_7z[] = { "7z", "rar", "zip", NULL };
-static const char *plugins_7z_x[] = { "7z", "Rar!", "MK" };
-static const int plugins_7z_t[] = { ArchiveFormat7Zip, ArchiveFormatRAR, ArchiveFormatZIP };
+static const char *plugins_7z[] = { "7z", "rar", "zip", "lha", "lzh", "lzx", NULL };
+static const char *plugins_7z_x[] = { "7z", "Rar!", "MK", NULL, NULL, NULL, NULL };
+static const int plugins_7z_t[] = { ArchiveFormat7Zip, ArchiveFormatRAR, ArchiveFormatZIP, ArchiveFormatLHA, ArchiveFormatLHA, ArchiveFormatLZX };
 
 static int iszip (struct zfile *z)
 {
     char *name = z->name;
     char *ext = strrchr (name, '.');
-    uae_u8 header[4];
+    uae_u8 header[6];
     int i;
 
     if (!ext)
@@ -961,6 +289,10 @@ static int iszip (struct zfile *z)
        return ArchiveFormat7Zip;
     if (!strcasecmp (ext, ".rar") && header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
        return ArchiveFormatRAR;
+    if ((!strcasecmp (ext, ".lha") || !strcasecmp (ext, ".lzh")) && header[2] == '-' && header[3] == 'l' && header[3] == 'h' && header[5] == '-')
+       return ArchiveFormatLHA;
+    if (!strcasecmp (ext, ".lzx") && header[0] == 'L' && header[1] == 'Z' && header[2] == 'X')
+       return ArchiveFormatLZX;
 #if defined(ARCHIVEACCESS)
     for (i = 0; plugins_7z[i]; i++) {
        if (plugins_7z_x[i] && !strcasecmp (ext + 1, plugins_7z[i]) &&
@@ -975,15 +307,22 @@ static struct zfile *zuncompress (struct zfile *z)
 {
     char *name = z->name;
     char *ext = strrchr (name, '.');
-    uae_u8 header[4];
+    uae_u8 header[6];
     int i;
 
     if (ext != NULL) {
        ext++;
        if (strcasecmp (ext, "7z") == 0)
-            return un7z (z);
+            return archive_access_select (z, ArchiveFormat7Zip);
        if (strcasecmp (ext, "zip") == 0)
-            return unzip (z);
+            return archive_access_select (z, ArchiveFormatZIP);
+       if (strcasecmp (ext, "lha") == 0
+           || strcasecmp (ext, "lzh") == 0)
+            return archive_access_select (z, ArchiveFormatLHA);
+       if (strcasecmp (ext, "lzx") == 0)
+            return archive_access_select (z, ArchiveFormatLZX);
+       if (strcasecmp (ext, "rar") == 0)
+            return archive_access_select (z, ArchiveFormatRAR);
        if (strcasecmp (ext, "gz") == 0)
             return zfile_gunzip (z);
        if (strcasecmp (ext, "adz") == 0)
@@ -994,17 +333,12 @@ static struct zfile *zuncompress (struct zfile *z)
             return zfile_gunzip (z);
        if (strcasecmp (ext, "dms") == 0)
             return dms (z);
-       if (strcasecmp (ext, "rar") == 0)
-           return unrar (z);
 #if defined(ARCHIVEACCESS)
        for (i = 0; plugins_7z[i]; i++) {
            if (strcasecmp (ext, plugins_7z[i]) == 0)
-               return arcacc_unpack (z, plugins_7z_t[i]);
+               return archive_access_arcacc_select (z, plugins_7z_t[i]);
        }
 #endif
-       if (strcasecmp (ext, "lha") == 0
-           || strcasecmp (ext, "lzh") == 0)
-           return lha (z);
        memset (header, 0, sizeof (header));
        zfile_fseek (z, 0, SEEK_SET);
        zfile_fread (header, sizeof (header), 1, z);
@@ -1012,11 +346,15 @@ static struct zfile *zuncompress (struct zfile *z)
        if (header[0] == 0x1f && header[1] == 0x8b)
            return zfile_gunzip (z);
        if (header[0] == 'P' && header[1] == 'K')
-           return unzip (z);
+            return archive_access_select (z, ArchiveFormatZIP);
        if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
-           return unrar (z);
+            return archive_access_select (z, ArchiveFormatRAR);
        if (header[0] == 'D' && header[1] == 'M' && header[2] == 'S' && header[3] == '!')
            return dms (z);
+       if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X')
+            return archive_access_select (z, ArchiveFormatLZX);
+       if (header[2] == '-' && header[3] == 'l' && header[3] == 'h' && header[5] == '-')
+            return archive_access_select (z, ArchiveFormatLHA);
     }
     return z;
 }
@@ -1089,13 +427,31 @@ static struct zfile *zfile_opensinglefile(struct zfile *l)
 }
 #endif
 
+static struct zfile *zfile_fopen_nozip (const char *name, const char *mode)
+{
+    struct zfile *l;
+    FILE *f;
+
+    if(*name == '\0')
+       return NULL;
+    l = zfile_create ();
+    l->name = strdup (name);
+    f = fopen (name, mode);
+    if (!f) {
+        zfile_fclose (l);
+        return 0;
+    }
+    l->f = f;
+    return l;
+}
+
 static struct zfile *zfile_fopen_2 (const char *name, const char *mode)
 {
     struct zfile *l;
     FILE *f;
-    char zipname[1000];
+    char zipname[MAX_DPATH];
 
-    if( *name == '\0' )
+    if(*name == '\0')
        return NULL;
     l = zfile_create ();
     l->name = strdup (name);
@@ -1123,223 +479,8 @@ static struct zfile *zfile_fopen_2 (const char *name, const char *mode)
     return l;
 }
 
-/* archiveaccess 7z-plugin compressed file scanner */
-static int scan_arcacc_zunzip (struct zfile *z, zfile_callback zc, void *user, int type)
-{
-    char tmp[MAX_DPATH], tmp2[2];
-    struct zfile *zf;
-    aaHandle ah;
-    int err, fc, size, status, i;
-    int id_r, id_w;
-    struct aaFileInArchiveInfo fi;
-    int skipsize = 0;
-
-    memset (&fi, 0, sizeof (fi));
-    if (!arcacc_init ())
-       return 0;
-    zf = 0;
-    id_r = arcacc_push (z);
-    if (id_r < 0)
-       return 0;
-    zfile_fseek (z, 0, SEEK_END);
-    size = zfile_ftell (z);
-    zfile_fseek (z, 0, SEEK_SET);
-    ah = aaOpenArchive (readCallback, id_r, size, type, &status, NULL);
-    if (status) {
-       arcacc_pop ();
-       return 0;
-    }
-    fc = aaGetFileCount (ah);
-    for (i = 0; i < fc; i++) {
-       aaGetFileInfo (ah, i, &fi);
-       if (fi.IsDir)
-           continue;
-       tmp2[0] = FSDB_DIR_SEPARATOR;
-       tmp2[1] = 0;
-       strcpy (tmp, z->name);
-       strcat (tmp, tmp2);
-       strcat (tmp, fi.path);
-       zf = zfile_fopen_empty (tmp, (int)fi.UncompressedFileSize);
-       if (zf) {
-           id_w = arcacc_push (zf);
-           if (id_w >= 0) {
-               uae_u64 written = 0;
-               zf->writeskipbytes = skipsize;
-               err = aaExtract (ah, i, id_w, writeCallback, &written);
-               if (zf->seek == fi.UncompressedFileSize) {
-                   zfile_fseek (zf, 0, SEEK_SET);
-                   if (!zc (zf, user)) {
-                       aaCloseArchive (ah);
-                       arcacc_pop ();
-                       zfile_fclose (zf);
-                       arcacc_pop ();
-                       return 0;
-                   }
-               }
-               arcacc_pop ();
-           }
-           zfile_fclose (zf);
-       }
-       if (fi.CompressedFileSize)
-           skipsize = 0;
-       skipsize += (int)fi.UncompressedFileSize;
-    }
-    aaCloseArchive (ah);
-    arcacc_pop ();
-    return 1;
-}
-
-// rar scan
-static int scan_rar (struct zfile *z, zfile_callback zc, void *user)
-{
-    HANDLE hArcData;
-    struct RARHeaderDataEx HeaderData; 
-    struct RAROpenArchiveData OpenArchiveData;
-
-    if (!canrar())
-       return scan_arcacc_zunzip (z, zc, user, ArchiveFormatRAR);
-    if (z->data)
-       return scan_arcacc_zunzip (z, zc, user, ArchiveFormatRAR);
-    fclose (z->f);
-    z->f = NULL;
-    memset(&OpenArchiveData,0,sizeof(OpenArchiveData));
-    OpenArchiveData.ArcName=z->name;
-    OpenArchiveData.OpenMode=RAR_OM_EXTRACT;
-    hArcData=pRAROpenArchive(&OpenArchiveData);
-    if (OpenArchiveData.OpenResult!=0) {
-       rar_resetf(z);
-       return 0;
-    }
-    pRARSetCallback(hArcData,RARCallbackProc,0);
-    while (pRARReadHeaderEx(hArcData,&HeaderData)==0) {
-       int needskip = 1;
-       char *name = HeaderData.FileName;
-       if (HeaderData.UnpSize > 0) {
-           struct zfile *zf = zfile_fopen_empty (name, HeaderData.UnpSize);
-           rarunpackzf = zf;
-           if (zf && pRARProcessFile(hArcData,RAR_EXTRACT,NULL,NULL) == 0) {
-               needskip = 0;
-               zfile_fseek (zf, 0, SEEK_SET);
-               if (!zc (zf, user)) {
-                   pRARCloseArchive(hArcData);
-                   zfile_fclose (zf);
-                   rar_resetf (z);
-                   return 0;
-               }
-           }
-           zfile_fclose (zf);
-       }
-       if (needskip)
-           pRARProcessFile(hArcData,RAR_SKIP,NULL,NULL);
-    }
-    pRARCloseArchive(hArcData);
-    if (!rar_resetf (z))
-       return 0;
-    return 1;
-}
-
-/* zip (zlib) scanning */
-static int scan_zunzip (struct zfile *z, zfile_callback zc, void *user)
-{
-    unzFile uz;
-    unz_file_info file_info;
-    char filename_inzip[MAX_DPATH];
-    char tmp[MAX_DPATH], tmp2[2];
-    struct zfile *zf;
-    int err;
-
-    zf = 0;
-    uz = unzOpen (z);
-    if (!uz)
-       return 0;
-    if (unzGoToFirstFile (uz) != UNZ_OK)
-       return 0;
-    for (;;) {
-       err = unzGetCurrentFileInfo(uz, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
-       if (err != UNZ_OK)
-           return 0;
-       if (file_info.uncompressed_size > 0) {
-           int err = unzOpenCurrentFile (uz);
-           if (err == UNZ_OK) {
-               tmp2[0] = FSDB_DIR_SEPARATOR;
-               tmp2[1] = 0;
-               strcpy (tmp, z->name);
-               strcat (tmp, tmp2);
-               strcat (tmp, filename_inzip);
-               zf = zfile_fopen_empty (tmp, file_info.uncompressed_size);
-               if (zf) {
-                   err = unzReadCurrentFile  (uz, zf->data, file_info.uncompressed_size);
-                   unzCloseCurrentFile (uz);
-                   if (err == 0 || err == file_info.uncompressed_size) {
-                       zf = zuncompress (zf);
-                       if (!zc (zf, user)) {
-                           zfile_fclose (zf);
-                           return 0;
-                       }
-                   }
-                   zfile_fclose (zf);
-               }
-           }
-       }
-       err = unzGoToNextFile (uz);
-       if (err != UNZ_OK)
-           break;
-    }
-    return 1;
-}
-
-// 7z scan
-static int scan_7z (struct zfile *z, zfile_callback zc, void *user)
-{
-    SZ_RESULT res;
-    int i;
-    struct zfile *zf = NULL;
-    char tmp[MAX_DPATH], tmp2[2];
-
-    init_7z();
-    SzArDbExInit(&db);
-    archiveStream.zf = z;
-    res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp);
-    if (res != SZ_OK)
-       return 0;
-    for (i = 0; i < db.Database.NumFiles; i++) {
-       int select = 0;
-       size_t offset;
-       size_t outSizeProcessed;
-       CFileItem *f = db.Database.Files + i;
-       char *name = f->Name;
-
-       if (f->IsDirectory)
-           continue;
-       tmp2[0] = FSDB_DIR_SEPARATOR;
-       tmp2[1] = 0;
-       strcpy (tmp, z->name);
-       strcat (tmp, tmp2);
-       strcat (tmp, name);
-        zf = zfile_fopen_empty (tmp, f->Size);
-       if (zf) {
-           uae_u32 blockIndex = 0xffffffff;
-           uae_u8 *outBuffer = 0;
-           size_t outBufferSize = 0;
-           res = SzExtract(&archiveStream.InStream, &db, i, 
-               &blockIndex, &outBuffer, &outBufferSize, 
-               &offset, &outSizeProcessed, 
-               &allocImp, &allocTempImp);
-           if (res == SZ_OK) {
-               if (!zc (zf, user)) {
-                   zfile_fclose (zf);
-                   SzArDbExFree(&db, allocImp.Free);
-                   return 0;
-               }
-           }
-           allocImp.Free(outBuffer);
-           zfile_fclose (zf);
-       }
-    }
-    SzArDbExFree(&db, allocImp.Free);
-    return 1;
-}
-
+#ifdef _WIN32
+#include "win32.h"
 
 #define AF "%AMIGAFOREVERDATA%"
 
@@ -1352,6 +493,11 @@ static void manglefilename(char *out, const char *in)
        out[0] = 0;
     strcat(out, in);
 }
+#else
+static void manglefilename(char *out, const char *in)
+{
+}
+#endif
 
 int zfile_zopen (const char *name, zfile_callback zc, void *user)
 {
@@ -1366,14 +512,8 @@ int zfile_zopen (const char *name, zfile_callback zc, void *user)
     ztype = iszip (l);
     if (ztype == 0)
        zc (l, user);
-    else if (ztype == ArchiveFormatZIP)
-       scan_zunzip (l, zc, user);
-    else if (ztype == ArchiveFormat7Zip)
-       scan_7z (l, zc, user);
-    else if (ztype == ArchiveFormatRAR)
-       scan_rar (l, zc, user);
     else
-       scan_arcacc_zunzip (l, zc, user, ztype);
+       archive_access_scan (l, zc, user, ztype);
     zfile_fclose (l);
     return 1;
 }
@@ -1400,7 +540,7 @@ struct zfile *zfile_dup (struct zfile *zf)
     if (!zf->data)
        return NULL;
     nzf = zfile_create();
-    nzf->data = malloc (zf->size);
+    nzf->data = (uae_u8*)malloc (zf->size);
     memcpy (nzf->data, zf->data, zf->size);
     nzf->size = zf->size;
     return nzf;
@@ -1437,9 +577,11 @@ struct zfile *zfile_fopen_empty (const char *name, int size)
     struct zfile *l;
     l = zfile_create ();
     l->name = name ? strdup (name) : "";
-    l->data = malloc (size);
-    l->size = size;
-    memset (l->data, 0, size);
+    if (size) {
+       l->data = (uae_u8*)malloc (size);
+       l->size = size;
+       memset (l->data, 0, size);
+    }
     return l;
 }
 
@@ -1448,7 +590,7 @@ struct zfile *zfile_fopen_data (const char *name, int size, uae_u8 *data)
     struct zfile *l;
     l = zfile_create ();
     l->name = name ? strdup (name) : "";
-    l->data = malloc (size);
+    l->data = (uae_u8*)malloc (size);
     l->size = size;
     memcpy (l->data, data, size);
     return l;
@@ -1464,7 +606,7 @@ long zfile_ftell (struct zfile *z)
 int zfile_fseek (struct zfile *z, long offset, int mode)
 {
     if (z->data) {
-       int old = z->seek;
+       int ret = 0;
        switch (mode)
        {
            case SEEK_SET:
@@ -1477,56 +619,77 @@ int zfile_fseek (struct zfile *z, long offset, int mode)
            z->seek = z->size + offset;
            break;
        }
-       if (z->seek < 0) z->seek = 0;
-       if (z->seek > z->size) z->seek = z->size;
-       return old;
+       if (z->seek < 0) {
+           z->seek = 0;
+           ret = 1;
+       }
+       if (z->seek > z->size) {
+           z->seek = z->size;
+           ret = 1;
+       }
+       return ret;
     }
     return fseek (z->f, offset, mode);
 }
 
 size_t zfile_fread  (void *b, size_t l1, size_t l2,struct zfile *z)
 {
-    long len = l1 * l2;
     if (z->data) {
-       if (z->seek + len > z->size) {
-           len = z->size - z->seek;
-           if (len < 0)
-               len = 0;
+       if (z->seek + l1 * l2 > z->size) {
+           if (l1)
+               l2 = (z->size - z->seek) / l1;
+           else
+               l2 = 0;
+           if (l2 < 0)
+               l2 = 0;
        }
-       memcpy (b, z->data + z->seek, len);
-       z->seek += len;
-       return len;
+       memcpy (b, z->data + z->seek, l1 * l2);
+       z->seek += l1 * l2;
+       return l2;
     }
     return fread (b, l1, l2, z->f);
 }
 
+
+size_t zfile_fwrite  (void *b, size_t l1, size_t l2, struct zfile *z)
+{
+    if (z->data) {
+       if (z->seek + l1 * l2 > z->size) {
+           if (l1)
+               l2 = (z->size - z->seek) / l1;
+           else
+               l2 = 0;
+           if (l2 < 0)
+               l2 = 0;
+       }
+       memcpy (z->data + z->seek, b, l1 * l2);
+       z->seek += l1 * l2;
+       return l2;
+    }
+    return fwrite (b, l1, l2, z->f);
+}
+
+
 size_t zfile_fputs (struct zfile *z, char *s)
 {
     return zfile_fwrite (s, strlen (s), 1, z);
 }
 
-size_t zfile_fwrite  (void *b, size_t l1, size_t l2, struct zfile *z)
+int zfile_getc (struct zfile *z)
 {
-    long len = l1 * l2;
-
-    if (z->writeskipbytes) {
-       z->writeskipbytes -= len;
-       if (z->writeskipbytes >= 0)
-           return len;
-       len = -z->writeskipbytes;
-       z->writeskipbytes = 0;
-    }
+    int out = -1;
     if (z->data) {
-       if (z->seek + len > z->size) {
-           len = z->size - z->seek;
-           if (len < 0)
-               len = 0;
-       }
-       memcpy (z->data + z->seek, b, len);
-       z->seek += len;
-       return len;
+       if (z->seek < z->size)
+           out = z->data[z->seek++];
+    } else {
+       out = fgetc (z->f);
     }
-    return fwrite (b, l1, l2, z->f);
+    return out;
+}
+
+int zfile_ferror (struct zfile *z)
+{
+    return 0;
 }
 
 int zfile_zuncompress (void *dst, int dstsize, struct zfile *src, int srcsize)
@@ -1539,7 +702,7 @@ int zfile_zuncompress (void *dst, int dstsize, struct zfile *src, int srcsize)
     memset (&zs, 0, sizeof(zs));
     if (inflateInit_ (&zs, ZLIB_VERSION, sizeof(z_stream)) != Z_OK)
        return 0;
-    zs.next_out = dst;
+    zs.next_out = (Bytef*)dst;
     zs.avail_out = dstsize;
     incnt = 0;
     v = Z_OK;
@@ -1568,7 +731,7 @@ int zfile_zcompress (struct zfile *f, void *src, int size)
     memset (&zs, 0, sizeof (zs));
     if (deflateInit_ (&zs, Z_DEFAULT_COMPRESSION, ZLIB_VERSION, sizeof(z_stream)) != Z_OK)
        return 0;
-    zs.next_in = src;
+    zs.next_in = (Bytef*)src;
     zs.avail_in = size;
     v = Z_OK;
     while (v == Z_OK) {
@@ -1600,7 +763,7 @@ uae_u32 zfile_crc32 (struct zfile *f)
     pos = zfile_ftell (f);
     zfile_fseek (f, 0, SEEK_END);
     size = zfile_ftell (f);
-    p = xmalloc (size);
+    p = (uae_u8*)xmalloc (size);
     if (!p)
        return 0;
     memset (p, 0, size);
@@ -1612,3 +775,453 @@ uae_u32 zfile_crc32 (struct zfile *f)
     return crc;
 }
 
+static struct zvolume *zvolume_list;
+
+static struct znode *znode_alloc(struct znode *parent, const char *name)
+{
+    char fullpath[MAX_DPATH];
+    struct znode *zn = xcalloc(sizeof(struct znode), 1);
+
+    sprintf(fullpath,"%s%c%s", parent->fullname, FSDB_DIR_SEPARATOR, name);
+    zn->fullname = my_strdup(fullpath);
+    zn->name = my_strdup(name);
+    zn->volume = parent->volume;
+    zn->volume->last->next = zn;
+    zn->prev = zn->volume->last;
+    zn->volume->last = zn;
+    return zn;
+}
+
+static struct znode *znode_alloc_child(struct znode *parent, const char *name)
+{
+    struct znode *zn = znode_alloc(parent, name);
+
+    if (!parent->child) {
+       parent->child = zn;
+    } else {
+        struct znode *pn = parent->child;
+        while (pn->sibling)
+           pn = pn->sibling;
+       pn->sibling = zn;
+    }
+    zn->parent = parent;
+    return zn;
+}
+static struct znode *znode_alloc_sibling(struct znode *sibling, const char *name)
+{
+    struct znode *zn = znode_alloc(sibling->parent, name);
+
+    if (!sibling->sibling) {
+       sibling->sibling = zn;
+    } else {
+        struct znode *pn = sibling->sibling;
+        while (pn->sibling)
+           pn = pn->sibling;
+       pn->sibling = zn;
+    }
+    zn->parent = sibling->parent;
+    return zn;
+}
+
+struct zvolume *zvolume_alloc(struct zfile *z, unsigned int id, void *handle)
+{
+    struct zvolume *zv = xcalloc(sizeof (struct zvolume), 1);
+    struct znode *root;
+    char *name;
+    size_t pos;
+
+    name = zfile_getname(z);
+    root = &zv->root;
+    zv->last = root;
+    zv->archive = z;
+    zv->handle = handle;
+    zv->id = id;
+    zv->blocks = 4;
+    root->volume = zv;
+    root->name = my_strdup(name);
+    root->fullname = my_strdup(name);
+    if (!zvolume_list) {
+       zvolume_list = zv;
+    } else {
+       struct zvolume *v = zvolume_list;
+       while (v->next)
+           v = v->next;
+       v->next = zv;
+    }
+    pos = zfile_ftell(z);
+    zfile_fseek(z, 0, SEEK_END);
+    zv->archivesize = zfile_ftell(z);
+    zfile_fseek(z, pos, SEEK_SET);
+    return zv;
+}
+
+static struct zvolume *get_zvolume(const char *path)
+{
+    struct zvolume *zv = zvolume_list;
+    while (zv) {
+       char *s = zfile_getname(zv->archive);
+       if (strlen(path) >= strlen(s) && !memcmp (path, s, strlen(s)))
+           return zv;
+       zv = zv->next;
+    }
+    return NULL;
+}
+
+static struct znode *get_znode(struct zvolume *zv, const char *ppath)
+{
+    struct znode *zn;
+    const char *path = ppath;
+    int prevlen = 0;
+
+    if (!zv)
+       return NULL;
+    zn = &zv->root;
+    while (zn) {
+       if (zn->isfile) {
+           if (!stricmp(zn->fullname, path))
+               return zn;
+       } else {
+           int len = strlen(zn->fullname);
+           if (strlen(path) >= len && (path[len] == 0 || path[len] == FSDB_DIR_SEPARATOR) && !strnicmp(zn->fullname, path, len)) {
+               if (path[len] == 0)
+                   return zn;
+               if (zn->vchild) {
+                   /* jump to separate tree */
+                   zn = zn->vchild->root.child;
+                   path += prevlen + 1;
+               } else {
+                   zn = zn->child;
+               }
+               prevlen = len;
+               continue;
+           }
+       }
+       zn = zn->sibling;
+    }
+    return NULL;
+}
+
+
+struct znode *znode_adddir(struct znode *parent, const char *name, struct zarchive_info *zai)
+{
+    struct znode *zn;
+    char path[MAX_DPATH];
+    
+    sprintf(path, "%s%c%s", parent->fullname, FSDB_DIR_SEPARATOR, name);
+    zn = get_znode(parent->volume, path);
+    if (zn)
+       return zn;
+    zn = znode_alloc_child(parent, name);
+    zn->mtime = zai->t;
+    parent->volume->blocks++;
+    return zn;
+}
+
+struct znode *zvolume_adddir_abs(struct zvolume *zv, struct zarchive_info *zai)
+{
+    struct znode *zn2;
+    char *path = my_strdup(zai->name);
+    char *p, *p2;
+    int i;
+
+    zn2 = &zv->root;
+    p = p2 = path;
+    for (i = 0; path[i]; i++) {
+       if (path[i] == '/' || path[i] == '\\') {
+           path[i] = 0;
+           zn2 = znode_adddir(zn2, p, zai);
+           path[i] = FSDB_DIR_SEPARATOR;
+           p = p2 = &path[i + 1];
+       }
+    }
+    return znode_adddir(zn2, p, zai);
+}
+
+struct znode *zvolume_addfile_abs(struct zvolume *zv, struct zarchive_info *zai)
+{
+    struct znode *zn, *zn2;
+    int i;
+    char *path = my_strdup(zai->name);
+    char *p, *p2;
+
+    zn2 = &zv->root;
+    p = p2 = path;
+    for (i = 0; path[i]; i++) {
+       if (path[i] == '/' || path[i] == '\\') {
+           path[i] = 0;
+           zn2 = znode_adddir(zn2, p, zai);
+           path[i] = FSDB_DIR_SEPARATOR;
+           p = p2 = &path[i + 1];
+       }
+    }
+    if (p2) {
+       zn = znode_alloc_child(zn2, p2);
+       zn->size = zai->size;
+       zn->isfile = 1;
+       zn->mtime = zai->t;
+       if (zai->comment)
+           zn->comment = my_strdup(zai->comment);
+       zn->flags = zai->flags;
+       zn->volume->blocks += (zai->size + 511) / 512;
+       zn->volume->size += zai->size;
+    }
+    xfree(path);
+    return zn;
+}
+
+static struct zvolume *zfile_fopen_archive_ext(struct zfile *zf)
+{
+    struct zvolume *zv = NULL;
+    char *ext = strrchr (zfile_getname(zf), '.');
+
+    if (ext != NULL) {
+       ext++;
+       if (strcasecmp (ext, "lha") == 0 || strcasecmp (ext, "lzh") == 0)
+            zv = archive_directory_lha (zf);
+       if (strcasecmp (ext, "zip") == 0)
+            zv = archive_directory_zip (zf);
+       if (strcasecmp (ext, "7z") == 0)
+            zv = archive_directory_7z (zf);
+       if (strcasecmp (ext, "lzx") == 0)
+            zv = archive_directory_lzx (zf);
+       if (strcasecmp (ext, "rar") == 0)
+            zv = archive_directory_rar (zf);
+    }
+    return zv;
+}
+
+
+struct zvolume *zfile_fopen_archive_data(struct zfile *zf)
+{
+    struct zvolume *zv = NULL;
+    uae_u8 header[6];
+
+    memset (header, 0, sizeof (header));
+    zfile_fread (header, sizeof (header), 1, zf);
+    zfile_fseek (zf, 0, SEEK_SET);
+    if (header[0] == 'P' && header[1] == 'K')
+         zv = archive_directory_zip (zf);
+    if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
+         zv = archive_directory_rar (zf);
+    if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X')
+         zv = archive_directory_lzx (zf);
+    if (header[2] == '-' && header[3] == 'l' && header[3] == 'h' && header[5] == '-')
+         zv = archive_directory_lha (zf);
+    return zv;
+}
+
+static int zfile_fopen_archive_recurse(struct zvolume *zv)
+{
+    struct znode *zn;
+    int i, added;
+
+    added = 0;
+    zn = zv->root.child;
+    while (zn) {
+       char *ext = strrchr (zn->name, '.');
+       if (ext && !zn->vchild && zn->isfile) {
+           for (i = 0; plugins_7z[i]; i++) {
+               if (!strcasecmp(ext + 1, plugins_7z[i])) {
+                   struct zfile *zf;
+                   struct zvolume *zvnew;
+                   char tmp[MAX_DPATH];
+                   zf = zfile_open_archive(zn->fullname, 0);
+                   zvnew = zfile_fopen_archive_ext(zf);
+                   if (!zvnew) {
+                       zfile_fclose(zf);
+                   } else {
+                       struct znode *zndir;
+                       sprintf(tmp, "%s.DIR", zn->fullname + strlen(zv->root.name) + 1);
+                       zndir = get_znode(zv, tmp);
+                       if (!zndir) {
+                           struct zarchive_info zai = { 0 };
+                           zai.name = tmp;
+                           zai.t = zn->mtime;
+                           zndir = zvolume_adddir_abs(zv, &zai);
+                           zndir->vchild = zvnew;
+                           zfile_fopen_archive_recurse(zvnew);
+                       }
+                   }
+               }
+           }
+       }
+       zn = zn->next;
+    }
+    return 0;
+}
+
+
+struct zvolume *zfile_fopen_archive(const char *filename)
+{
+    struct zvolume *zv = NULL;
+    struct zfile *zf = zfile_fopen_nozip (filename, "rb");
+
+    if (!zf)
+       return NULL;
+    zv = zfile_fopen_archive_ext(zf);
+    if (!zv)
+       zv = zfile_fopen_archive_data(zf);
+#if 0
+    if (zv)
+       zfile_fopen_archive_recurse (zv);
+#endif
+    /* pointless but who cares? */
+    if (!zv)
+       zv = archive_directory_plain (zf);
+    return zv;
+}
+
+void zfile_fclose_archive(struct zvolume *zv)
+{
+    struct znode *zn;
+    struct zvolume *v;
+
+    zn = &zv->root;
+    while (zn) {
+       struct znode *zn2 = zn->next;
+       if (zn->vchild)
+           zfile_fclose_archive(zn->vchild);
+       xfree(zn->comment);
+       xfree(zn->fullname);
+       xfree(zn->name);
+       zfile_fclose(zn->f);
+       if (zn != &zv->root)
+           xfree(zn);
+       zn = zn2;
+    }
+    archive_access_close (zv->handle, zv->id);
+    if (zvolume_list == zv) {
+       zvolume_list = zvolume_list->next;
+    } else {
+       v = zvolume_list;
+       while (v) {
+           if (v->next == zv) {
+               v->next = zv->next;
+               break;
+           }
+           v = v->next;
+       }
+    }
+    xfree(zv);
+}
+
+struct zdirectory {
+    struct znode *n;
+};
+
+void *zfile_opendir_archive(const char *path)
+{
+    struct zvolume *zv = get_zvolume(path);
+    struct znode *zn = get_znode(zv, path);
+    struct zdirectory *zd = xmalloc(sizeof (struct zdirectory));
+
+    if (!zn || (!zn->child && !zn->vchild))
+       return NULL;
+    if (zn->child)
+       zd->n = zn->child;
+    else
+       zd->n = zn->vchild->root.next;
+    return zd;
+}
+void zfile_closedir_archive(struct zdirectory *zd)
+{
+    xfree(zd);
+}
+int zfile_readdir_archive(struct zdirectory *zd, char *out)
+{
+    if (!zd->n)
+       return 0;
+    strcpy (out, zd->n->name);
+    zd->n = zd->n->sibling;
+    return 1;
+}
+
+int zfile_fill_file_attrs_archive(const char *path, int *isdir, int *flags, char **comment)
+{
+    struct zvolume *zv = get_zvolume(path);
+    struct znode *zn = get_znode(zv, path);
+
+    *isdir = 0;
+    *flags = 0;
+    *comment = 0;
+    if (!zn)
+       return 0;
+    *isdir = zn->isfile ? 0 : 1;
+    *flags = zn->flags;
+    if (zn->comment)
+       *comment = my_strdup(zn->comment);
+    return 1;
+}
+
+int zfile_fs_usage_archive(const char *path, const char *disk, struct fs_usage *fsp)
+{
+    struct zvolume *zv = get_zvolume(path);
+
+    if (!zv)
+       return -1;
+    fsp->fsu_blocks = zv->blocks;
+    fsp->fsu_bavail = 0;
+    return 0;
+}
+
+int zfile_stat_archive (const char *path, struct stat *s)
+{
+    struct zvolume *zv = get_zvolume(path);
+    struct znode *zn = get_znode(zv, path);
+
+    if (!zn)
+       return 0;
+    s->st_mode = zn->isfile ? 0 : FILEFLAG_DIR;
+    s->st_size = zn->size;
+    s->st_mtime = zn->mtime;
+    return 1;
+}
+
+unsigned int zfile_lseek_archive (void *d, unsigned int offset, int whence)
+{
+    if (zfile_fseek (d, offset, whence))
+       return -1;
+    return zfile_ftell (d);
+}
+
+unsigned int zfile_read_archive (void *d, void *b, unsigned int size)
+{
+    return zfile_fread (b, 1, size, d);
+}
+
+void zfile_close_archive (void *d)
+{
+    /* do nothing, keep file cached */
+}
+
+void *zfile_open_archive (const char *path, int flags)
+{
+    struct zvolume *zv = get_zvolume(path);
+    struct znode *zn = get_znode(zv, path);
+    struct zfile *z;
+
+    if (!zn)
+       return 0;
+    if (zn->f) {
+       zfile_fseek(zn->f, 0, SEEK_SET);
+       return zn->f;
+    }
+    z = archive_getzfile (zn, zv->id);
+    if (z)
+       zfile_fseek(z, 0, SEEK_SET);
+    zn->f = z;
+    return zn->f;
+}
+
+int zfile_exists_archive (const char *path, const char *rel)
+{
+    char tmp[MAX_DPATH];
+    struct zvolume *zv;
+    struct znode *zn;
+    
+    sprintf(tmp, "%s%c%s", path, FSDB_DIR_SEPARATOR, rel);
+    zv = get_zvolume(tmp);
+    zn = get_znode(zv, tmp);
+    return zn ? 1 : 0;
+}
+
diff --git a/zfile_archive.c b/zfile_archive.c
new file mode 100755 (executable)
index 0000000..2ae74e9
--- /dev/null
@@ -0,0 +1,812 @@
+ /*
+  * UAE - The Un*x Amiga Emulator
+  *
+  * transparent archive handling
+  *
+  *     2007 Toni Wilen
+  */
+
+#define ZLIB_WINAPI
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include "options.h"
+#include "zfile.h"
+#include "archivers/zip/unzip.h"
+#include "archivers/dms/pfile.h"
+#include "crc32.h"
+#include "zarchive.h"
+#include "disk.h"
+
+#include <zlib.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#include "win32.h"
+#endif
+
+static time_t fromdostime(uae_u32 dd)
+{
+    struct tm tm;
+    time_t t;
+    memset(&tm, 0, sizeof tm);
+    tm.tm_hour = (dd >> 11) & 0x1f;
+    tm.tm_min  = (dd >> 5) & 0x3f;
+    tm.tm_sec  = ((dd >> 0) & 0x1f) * 2;
+    tm.tm_year = ((dd >> 25) & 0x7f) + 80;
+    tm.tm_mon  = ((dd >> 21) & 0x0f) - 1;
+    tm.tm_mday = (dd >> 16) & 0x1f;
+    t = mktime(&tm);
+    _tzset();
+    t -= _timezone;
+    return t;
+}
+
+static struct zvolume *getzvolume(struct zfile *zf, unsigned int id)
+{
+    struct zvolume *zv;
+
+    switch (id)
+    {
+       case ArchiveFormatZIP:
+       zv = archive_directory_zip (zf);
+       break;
+       case ArchiveFormat7Zip:
+       zv = archive_directory_7z (zf);
+       break;
+       case ArchiveFormatRAR:
+       zv = archive_directory_rar (zf);
+       break;
+       case ArchiveFormatLHA:
+       zv = archive_directory_lha (zf);
+       break;
+       case ArchiveFormatLZX:
+       zv = archive_directory_lzx (zf);
+       break;
+       case ArchiveFormatPLAIN:
+       zv = archive_directory_plain (zf);
+       break;
+    }
+    if (!zv)
+       zv = archive_directory_arcacc (zf, id);
+    return zv;
+}
+
+struct zfile *archive_getzfile(struct znode *zn, unsigned int id)
+{
+    struct zfile *zf = NULL;
+    switch (id)
+    {
+       case ArchiveFormatZIP:
+       zf = archive_access_zip (zn);
+       break;
+       case ArchiveFormat7Zip:
+       zf = archive_access_7z (zn);
+       break;
+       case ArchiveFormatRAR:
+       zf = archive_access_rar (zn);
+       break;
+       case ArchiveFormatLHA:
+       zf = archive_access_lha (zn);
+       break;
+       case ArchiveFormatLZX:
+       zf = archive_access_lzx (zn);
+       break;
+       case ArchiveFormatPLAIN:
+       zf = archive_access_plain (zn);
+       break;
+    }
+    return zf;
+}
+
+struct zfile *archive_access_select (struct zfile *zf, unsigned int id)
+{
+    struct zvolume *zv = getzvolume(zf, id);
+    struct znode *zn;
+    int zipcnt, first, select;
+    char tmphist[MAX_DPATH];
+    struct zfile *z = NULL;
+    int we_have_file;
+
+    we_have_file = 0;
+    tmphist[0] = 0;
+    zipcnt = 1;
+    first = 1;
+    zn = &zv->root;
+    while (zn) {
+       int isok = 1;
+       
+       if (!zn->isfile)
+           isok = 0;
+       if (zfile_is_ignore_ext(zn->fullname))
+           isok = 0;
+       if (isok) {
+           if (tmphist[0]) {
+               DISK_history_add (tmphist, -1);
+               tmphist[0] = 0;
+               first = 0;
+           }
+           if (first) {
+               if (zfile_isdiskimage (zn->fullname))
+                   strcpy (tmphist, zn->fullname);
+           } else {
+               strcpy (tmphist, zn->fullname);
+               DISK_history_add (tmphist, -1);
+               tmphist[0] = 0;
+           }
+           select = 0;
+           if (!zf->zipname)
+               select = 1;
+           if (zf->zipname && !strcasecmp (zf->zipname, zn->name))
+               select = -1;
+           if (zf->zipname && zf->zipname[0] == '#' && atol (zf->zipname + 1) == zipcnt)
+               select = -1;
+           if (select && !we_have_file) {
+               z = archive_getzfile(zn, id);
+               if (z) {
+                   if (select < 0 || zfile_gettype (z))
+                       we_have_file = 1;
+                   if (!we_have_file) {
+                       zfile_fclose(z);
+                       z = NULL;
+                   }
+               }
+           }
+       }
+       zipcnt++;
+       zn = zn->next;
+    }
+    zfile_fclose_archive (zv);
+    if (z) {
+       zfile_fclose(zf);
+       zf = z;
+    }
+    return zf;
+}
+
+struct zfile *archive_access_arcacc_select (struct zfile *zf, unsigned int id)
+{
+    return zf;
+}
+
+void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user, unsigned int id)
+{
+    struct zvolume *zv;
+    struct znode *zn;
+
+    zv = getzvolume(zf, id);
+    if (!zv)
+       return;
+    zn = &zv->root;
+    while (zn) {
+       if (zn->isfile) {
+           struct zfile *zf = archive_getzfile (zn, id);
+           if (zf) {
+               int ret = zc (zf, user);
+               zfile_fclose(zf);
+               if (ret)
+                   break;
+           }
+       }
+       zn = zn->next;
+    }
+    zfile_fclose_archive (zv);
+}
+
+/* ZIP */
+
+static void archive_close_zip (void *handle)
+{
+    unzClose(handle);
+}
+
+struct zvolume *archive_directory_zip (struct zfile *z)
+{
+    unzFile uz;
+    unz_file_info file_info;
+    char filename_inzip[MAX_DPATH];
+    struct zvolume *zv;
+    int err;
+
+    uz = unzOpen (z);
+    if (!uz)
+       return 0;
+    if (unzGoToFirstFile (uz) != UNZ_OK)
+       return 0;
+    zv = zvolume_alloc(z, ArchiveFormatZIP, uz);
+    for (;;) {
+       char c;
+       struct zarchive_info zai;
+       time_t t;
+       unsigned int dd;
+       err = unzGetCurrentFileInfo(uz, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
+       if (err != UNZ_OK)
+           return 0;
+       dd = file_info.dosDate;
+       t = fromdostime(dd);
+       memset(&zai, 0, sizeof zai);
+       zai.name = filename_inzip;
+       zai.t = t;
+       c = filename_inzip[strlen(filename_inzip) - 1];
+       if (c != '/' && c != '\\') {
+           int err = unzOpenCurrentFile (uz);
+           if (err == UNZ_OK) {
+               struct znode *zn;
+               zai.size = file_info.uncompressed_size;
+               zn = zvolume_addfile_abs(zv, &zai);
+           }
+       } else {
+           filename_inzip[strlen(filename_inzip) - 1] = 0;
+           zvolume_adddir_abs(zv, &zai);
+       }
+       err = unzGoToNextFile (uz);
+       if (err != UNZ_OK)
+           break;
+    }
+    zv->method = ArchiveFormatZIP;
+    return zv;
+}
+
+
+struct zfile *archive_access_zip (struct znode *zn)
+{
+    struct zfile *z = NULL;
+    unzFile uz = zn->volume->handle;
+    int i, err;
+    char tmp[MAX_DPATH];
+
+    strcpy (tmp, zn->fullname + strlen(zn->volume->root.fullname) + 1);
+    if (unzGoToFirstFile (uz) != UNZ_OK)
+       return 0;
+    for (i = 0; tmp[i]; i++) {
+       if (tmp[i] == '\\')
+           tmp[i] = '/';
+    }
+    if (unzLocateFile (uz, tmp, 1) != UNZ_OK) {
+       for (i = 0; tmp[i]; i++) {
+           if (tmp[i] == '/')
+               tmp[i] = '\\';
+       }
+       if (unzLocateFile (uz, tmp, 1) != UNZ_OK)
+           return 0;
+    }
+    if (unzOpenCurrentFile (uz) != UNZ_OK)
+       return 0;
+    z = zfile_fopen_empty (zn->name, zn->size);
+    if (z) {
+       err = unzReadCurrentFile (uz, z->data, zn->size);
+    }
+    unzCloseCurrentFile (uz);
+    return z;
+}
+    
+/* 7Z */
+
+#include "archivers/7z/7zCrc.h"
+#include "archivers/7z/7zIn.h"
+#include "archivers/7z/7zExtract.h"
+
+typedef struct _CFileInStream
+{
+  ISzInStream InStream;
+  struct zfile *zf;
+} CFileInStream;
+
+static ISzAlloc allocImp;
+static ISzAlloc allocTempImp;
+
+static SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize)
+{
+  CFileInStream *s = (CFileInStream *)object;
+  size_t processedSizeLoc = zfile_fread(buffer, 1, size, s->zf);
+  if (processedSize != 0)
+    *processedSize = processedSizeLoc;
+  return SZ_OK;
+}
+
+static SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
+{
+  CFileInStream *s = (CFileInStream *)object;
+  int res = zfile_fseek(s->zf, pos, SEEK_SET);
+  if (res == 0)
+    return SZ_OK;
+  return SZE_FAIL;
+}
+
+static void init_7z(void)
+{
+    static int initialized;
+    if (initialized)
+       return;
+    initialized = 1;
+    allocImp.Alloc = SzAlloc;
+    allocImp.Free = SzFree;
+    allocTempImp.Alloc = SzAllocTemp;
+    allocTempImp.Free = SzFreeTemp;
+    InitCrcTable();
+}
+
+struct SevenZContext
+{
+    CArchiveDatabaseEx db;
+    CFileInStream archiveStream;
+    Byte *outBuffer;
+    size_t outBufferSize;
+    UInt32 blockIndex;
+};
+
+static void archive_close_7z (struct SevenZContext *ctx)
+{
+    SzArDbExFree(&ctx->db, allocImp.Free);
+    allocImp.Free(ctx->outBuffer);
+    xfree(ctx);
+}
+
+struct zvolume *archive_directory_7z (struct zfile *z)
+{
+    SZ_RESULT res;
+    struct zvolume *zv;
+    int i;
+    struct SevenZContext *ctx;
+
+    init_7z();
+    ctx = xcalloc (sizeof (struct SevenZContext), 1);
+    ctx->blockIndex = 0xffffffff;
+    ctx->archiveStream.InStream.Read = SzFileReadImp;
+    ctx->archiveStream.InStream.Seek = SzFileSeekImp;
+    SzArDbExInit(&ctx->db);
+    ctx->archiveStream.zf = z;
+    res = SzArchiveOpen(&ctx->archiveStream.InStream, &ctx->db, &allocImp, &allocTempImp);
+    if (res != SZ_OK) {
+       write_log("7Z: SzArchiveOpen %s returned %d\n", zfile_getname(z), res);
+       return NULL;
+    }
+    zv = zvolume_alloc(z, ArchiveFormat7Zip, ctx);
+    for (i = 0; i < ctx->db.Database.NumFiles; i++) {
+       CFileItem *f = ctx->db.Database.Files + i;
+       char *name = f->Name;
+       struct zarchive_info zai;
+
+       memset(&zai, 0, sizeof zai);
+       zai.name = name;
+       zai.size = f->Size;
+       if (!f->IsDirectory) {
+           struct znode *zn = zvolume_addfile_abs(zv, &zai);
+           zn->offset = i;
+       }
+    }
+    zv->method = ArchiveFormat7Zip;
+    return zv;
+}
+
+struct zfile *archive_access_7z (struct znode *zn)
+{
+    SZ_RESULT res;
+    struct zvolume *zv = zn->volume;
+    struct zfile *z = NULL;
+    size_t offset;
+    size_t outSizeProcessed;
+    struct SevenZContext *ctx;
+
+    ctx = zv->handle;
+    res = SzExtract(&ctx->archiveStream.InStream, &ctx->db, zn->offset, 
+                   &ctx->blockIndex, &ctx->outBuffer, &ctx->outBufferSize, 
+                   &offset, &outSizeProcessed, 
+                   &allocImp, &allocTempImp);
+    if (res == SZ_OK) {
+        z = zfile_fopen_empty (zn->name, zn->size);
+       zfile_fwrite (ctx->outBuffer + offset, zn->size, 1, z);
+    } else {
+       write_log("7Z: SzExtract %s returned %d\n", zn->fullname, res);
+    }
+    return z;
+}
+
+/* RAR */
+
+
+
+/* copy and paste job? you are only imagining it! */
+static struct zfile *rarunpackzf; /* stupid unrar.dll */
+#include <unrar.h>
+typedef HANDLE (_stdcall* RAROPENARCHIVE)(struct RAROpenArchiveData*);
+static RAROPENARCHIVE pRAROpenArchive;
+typedef int (_stdcall* RARREADHEADEREX)(HANDLE,struct RARHeaderDataEx*);
+static RARREADHEADEREX pRARReadHeaderEx;
+typedef int (_stdcall* RARPROCESSFILE)(HANDLE,int,char*,char *);
+static RARPROCESSFILE pRARProcessFile;
+typedef int (_stdcall* RARCLOSEARCHIVE)(HANDLE);
+static RARCLOSEARCHIVE pRARCloseArchive;
+typedef void (_stdcall* RARSETCALLBACK)(HANDLE,UNRARCALLBACK,LONG);
+static RARSETCALLBACK pRARSetCallback;
+typedef int (_stdcall* RARGETDLLVERSION)(void);
+static RARGETDLLVERSION pRARGetDllVersion;
+
+static int rar_resetf(struct zfile *z)
+{
+    z->f = fopen (z->name, "rb");
+    if (!z->f) {
+        zfile_fclose (z);
+        return 0;
+    }
+    return 1;
+}
+
+static int canrar(void)
+{
+    static int israr;
+
+    if (israr == 0) {
+       israr = -1;
+#ifdef _WIN32
+       {
+           HMODULE rarlib;
+
+           rarlib = WIN32_LoadLibrary("unrar.dll");
+           if (rarlib) {
+               pRAROpenArchive = (RAROPENARCHIVE)GetProcAddress (rarlib, "RAROpenArchive");
+               pRARReadHeaderEx = (RARREADHEADEREX)GetProcAddress (rarlib, "RARReadHeaderEx");
+               pRARProcessFile = (RARPROCESSFILE)GetProcAddress (rarlib, "RARProcessFile");
+               pRARCloseArchive = (RARCLOSEARCHIVE)GetProcAddress (rarlib, "RARCloseArchive");
+               pRARSetCallback = (RARSETCALLBACK)GetProcAddress (rarlib, "RARSetCallback");
+               pRARGetDllVersion = (RARGETDLLVERSION)GetProcAddress (rarlib, "RARGetDllVersion");
+               if (pRAROpenArchive && pRARReadHeaderEx && pRARProcessFile && pRARCloseArchive && pRARSetCallback) {
+                   israr = 1;
+                   write_log ("unrar.dll version %08.8X detected and used\n", pRARGetDllVersion ? pRARGetDllVersion() : -1);
+
+               }
+           }
+       }
+#endif
+    }
+    return israr < 0 ? 0 : 1;
+}
+
+static int CALLBACK RARCallbackProc(UINT msg,LONG UserData,LONG P1,LONG P2)
+{
+    if (msg == UCM_PROCESSDATA) {
+       zfile_fwrite((uae_u8*)P1, 1, P2, rarunpackzf);
+       return 0;
+    }
+    return -1;
+}
+
+struct RARContext
+{
+    struct RAROpenArchiveData OpenArchiveData;
+    struct RARHeaderDataEx HeaderData; 
+    HANDLE hArcData;
+};
+
+
+static void archive_close_rar(struct RARContext *rc)
+{
+    pRARCloseArchive (rc->hArcData);
+    xfree(rc);
+}
+
+struct zvolume *archive_directory_rar (struct zfile *z)
+{
+    struct zvolume *zv;
+    struct RARContext *rc;
+    struct zfile *zftmp;
+    int cnt;
+
+    if (!canrar())
+       return archive_directory_arcacc (z, ArchiveFormatRAR);
+    if (z->data)
+        /* wtf? stupid unrar.dll only accept filename as an input.. */
+       return archive_directory_arcacc (z, ArchiveFormatRAR);
+    rc = xcalloc (sizeof (struct RARContext), 1);
+    zv = zvolume_alloc(z, ArchiveFormatRAR, rc);
+    fclose (z->f); /* bleh, unrar.dll fails to open the archive if it is already open.. */
+    z->f = NULL;
+    rc->OpenArchiveData.ArcName = z->name;
+    rc->OpenArchiveData.OpenMode = RAR_OM_LIST;
+    rc->hArcData = pRAROpenArchive(&rc->OpenArchiveData);
+    if (rc->OpenArchiveData.OpenResult != 0) {
+       xfree(rc);
+       if (!rar_resetf(z)) {
+           zfile_fclose_archive(zv);
+           return NULL;
+       }
+        zfile_fclose_archive(zv);
+       return archive_directory_arcacc (z, ArchiveFormatRAR);
+    }
+    pRARSetCallback(rc->hArcData, RARCallbackProc, 0);
+    cnt = 0;
+    while (pRARReadHeaderEx(rc->hArcData, &rc->HeaderData) == 0) {
+       char *name = rc->HeaderData.FileName;
+       struct zarchive_info zai;
+       struct znode *zn;
+       memset(&zai, 0, sizeof zai);
+       zai.name = name;
+       zai.size = rc->HeaderData.UnpSize;
+       zai.t = fromdostime(rc->HeaderData.FileTime);
+        zn = zvolume_addfile_abs(zv, &zai);
+       zn->offset = cnt++;
+        pRARProcessFile(rc->hArcData, RAR_SKIP, NULL, NULL);
+    }
+    pRARCloseArchive(rc->hArcData);
+    zftmp = zfile_fopen_empty (z->name, 0);
+    zv->archive = zftmp;
+    zv->method = ArchiveFormatRAR;
+    zfile_fclose(z);
+    return zv;
+}
+
+struct zfile *archive_access_rar (struct znode *zn)
+{
+    struct RARContext *rc = zn->volume->handle;
+    int i;
+    struct zfile *zf = NULL;
+
+    if (zn->volume->method != ArchiveFormatRAR)
+       return archive_access_arcacc (zn);
+    rc->OpenArchiveData.OpenMode = RAR_OM_EXTRACT;
+    rc->hArcData = pRAROpenArchive(&rc->OpenArchiveData);
+    if (rc->OpenArchiveData.OpenResult != 0)
+       return NULL;
+    pRARSetCallback(rc->hArcData, RARCallbackProc, 0);
+    for (i = 0; i <= zn->offset; i++) {
+       if (pRARReadHeaderEx(rc->hArcData, &rc->HeaderData))
+           return NULL;
+       if (i < zn->offset) {
+           if (pRARProcessFile(rc->hArcData, RAR_SKIP, NULL, NULL))
+               goto end;
+       }
+    }
+    zf = zfile_fopen_empty (zn->name, zn->size);
+    rarunpackzf = zf;
+    if (pRARProcessFile(rc->hArcData, RAR_TEST, NULL, NULL)) {
+       zfile_fclose(zf);
+       zf = NULL;
+    }
+end:
+    pRARCloseArchive(rc->hArcData);
+    return zf;
+}
+
+/* ArchiveAccess */
+
+
+#if defined(ARCHIVEACCESS)
+
+struct aaFILETIME
+{
+    uae_u32 dwLowDateTime;
+    uae_u32 dwHighDateTime;
+};
+typedef void* aaHandle;
+// This struct contains file information from an archive. The caller may store 
+// this information for accessing this file after calls to findFirst, findNext
+#define FileInArchiveInfoStringSize 1024
+struct aaFileInArchiveInfo {
+       int ArchiveHandle; // handle for Archive/class pointer
+       uae_u64 CompressedFileSize;
+       uae_u64 UncompressedFileSize;
+       uae_u32 attributes;
+       int IsDir, IsEncrypted;
+       struct aaFILETIME LastWriteTime;
+       char path[FileInArchiveInfoStringSize];
+};
+
+typedef HRESULT (__stdcall *aaReadCallback)(int StreamID, uae_u64 offset, uae_u32 count, void* buf, uae_u32 *processedSize);
+typedef HRESULT (__stdcall *aaWriteCallback)(int StreamID, uae_u64 offset, uae_u32 count, const void *buf, uae_u32 *processedSize);
+typedef aaHandle (__stdcall *aapOpenArchive)(aaReadCallback function, int StreamID, uae_u64 FileSize, int ArchiveType, int *result, char *password);
+typedef int (__stdcall *aapGetFileCount)(aaHandle ArchiveHandle);
+typedef int (__stdcall *aapGetFileInfo)(aaHandle ArchiveHandle, int FileNum, struct aaFileInArchiveInfo *FileInfo);
+typedef int (__stdcall *aapExtract)(aaHandle ArchiveHandle, int FileNum, int StreamID, aaWriteCallback WriteFunc, uae_u64 *written);
+typedef int (__stdcall *aapCloseArchive)(aaHandle ArchiveHandle);
+
+static aapOpenArchive aaOpenArchive;
+static aapGetFileCount aaGetFileCount;
+static aapGetFileInfo aaGetFileInfo;
+static aapExtract aaExtract;
+static aapCloseArchive aaCloseArchive;
+
+#ifdef _WIN32
+static HMODULE arcacc_mod;
+
+static void arcacc_free (void)
+{
+    if (arcacc_mod)
+       FreeLibrary (arcacc_mod);
+    arcacc_mod = NULL;
+}
+
+static int arcacc_init (void)
+{
+    if (arcacc_mod)
+       return 1;
+    arcacc_mod = WIN32_LoadLibrary ("archiveaccess.dll");
+    if (!arcacc_mod) {
+       write_log ("failed to open archiveaccess.dll\n");
+       return 0;
+    }
+    aaOpenArchive = (aapOpenArchive) GetProcAddress (arcacc_mod, "aaOpenArchive");
+    aaGetFileCount = (aapGetFileCount) GetProcAddress (arcacc_mod, "aaGetFileCount");
+    aaGetFileInfo = (aapGetFileInfo) GetProcAddress (arcacc_mod, "aaGetFileInfo");
+    aaExtract = (aapExtract) GetProcAddress (arcacc_mod, "aaExtract");
+    aaCloseArchive = (aapCloseArchive) GetProcAddress (arcacc_mod, "aaCloseArchive");
+    if (!aaOpenArchive || !aaGetFileCount || !aaGetFileInfo || !aaExtract || !aaCloseArchive) {
+       write_log ("Missing functions in archiveaccess.dll. Old version?\n");
+       arcacc_free ();
+       return 0;
+    }
+    return 1;
+}
+#endif
+
+#define ARCACC_STACKSIZE 10
+static struct zfile *arcacc_stack[ARCACC_STACKSIZE];
+static int arcacc_stackptr = -1;
+
+static int arcacc_push (struct zfile *f)
+{
+    if (arcacc_stackptr == ARCACC_STACKSIZE - 1)
+       return -1;
+    arcacc_stackptr++;
+    arcacc_stack[arcacc_stackptr] = f;
+    return arcacc_stackptr;
+}
+static void arcacc_pop (void)
+{
+    arcacc_stackptr--;
+}
+
+static HRESULT __stdcall readCallback (int StreamID, uae_u64 offset, uae_u32 count, void *buf, uae_u32 *processedSize)
+{
+    struct zfile *f = arcacc_stack[StreamID];
+    int ret;
+
+    zfile_fseek (f, (long)offset, SEEK_SET);
+    ret = zfile_fread (buf, 1, count, f);
+    if (processedSize)
+       *processedSize = ret;
+    return 0;
+}
+static HRESULT __stdcall writeCallback (int StreamID, uae_u64 offset, uae_u32 count, const void *buf, uae_u32 *processedSize)
+{
+    struct zfile *f = arcacc_stack[StreamID];
+    int ret;
+
+    ret = zfile_fwrite ((void*)buf, 1, count, f);
+    if (processedSize)
+       *processedSize = ret;
+    if (ret != count)
+       return -1;
+    return 0;
+}
+
+struct zvolume *archive_directory_arcacc (struct zfile *z, unsigned int id)
+{
+    aaHandle ah;
+    int id_r, status;
+    int fc, f;
+    struct zvolume *zv;
+    int skipsize = 0;
+
+    if (!arcacc_init ())
+       return NULL;
+    zv = zvolume_alloc(z, id, NULL);
+    id_r = arcacc_push (z);
+    ah = aaOpenArchive (readCallback, id_r, zv->archivesize, id, &status, NULL);
+    if (!status) {
+       zv->handle = ah;
+       fc = aaGetFileCount (ah);
+       for (f = 0; f < fc; f++) {
+           struct aaFileInArchiveInfo fi;
+           char *name;
+           struct znode *zn;
+           struct zarchive_info zai;
+
+           memset (&fi, 0, sizeof (fi));
+           aaGetFileInfo (ah, f, &fi);
+           if (fi.IsDir)
+               continue;
+
+           name = fi.path;
+           memset(&zai, 0, sizeof zai);
+           zai.name = name;
+           zai.size = (unsigned int)fi.UncompressedFileSize;
+           zn = zvolume_addfile_abs(zv, &zai);
+           zn->offset = f;
+           zn->method = id;
+
+           if (id == ArchiveFormat7Zip) {
+               if (fi.CompressedFileSize)
+                   skipsize = 0;
+               skipsize += (int)fi.UncompressedFileSize;
+           }
+       }
+       aaCloseArchive (ah);
+    }
+    arcacc_pop ();
+    zv->method = ArchiveFormatAA;
+    return zv;
+}
+
+
+struct zfile *archive_access_arcacc (struct znode *zn)
+{
+    struct zfile *zf;
+    struct zfile *z = zn->volume->archive;
+    int status, id_r, id_w;
+    aaHandle ah;
+    int ok = 0;
+
+    id_r = arcacc_push (z);
+    ah = aaOpenArchive (readCallback, id_r, zn->volume->archivesize, zn->method, &status, NULL);
+    if (!status) {
+       int err;
+       uae_u64 written = 0;
+       struct aaFileInArchiveInfo fi;
+       memset (&fi, 0, sizeof (fi));
+       aaGetFileInfo (ah, zn->offset, &fi);
+       zf = zfile_fopen_empty (zn->name, zn->size);
+       id_w = arcacc_push (zf);
+       err = aaExtract(ah, zn->offset, id_w, writeCallback, &written);
+       if (zf->seek == fi.UncompressedFileSize)
+           ok = 1;
+       arcacc_pop();
+    }
+    aaCloseArchive(ah);
+    arcacc_pop();
+    if (ok)
+       return zf;
+    zfile_fclose(zf);
+    return NULL;
+}
+#endif
+
+void archive_access_close (void *handle, unsigned int id)
+{
+    switch (id)
+    {
+       case ArchiveFormatZIP:
+       archive_close_zip(handle);
+       break;
+       case ArchiveFormat7Zip:
+       archive_close_7z(handle);
+       break;
+       case ArchiveFormatRAR:
+       archive_close_rar(handle);
+       break;
+       case ArchiveFormatLHA:
+       break;
+    }
+}
+
+/* plain single file */
+struct zvolume *archive_directory_plain (struct zfile *z)
+{
+    struct zvolume *zv;
+    struct zarchive_info zai;
+    int i;
+
+    memset(&zai, 0, sizeof zai);
+    zv = zvolume_alloc(z, ArchiveFormatPLAIN, NULL);
+    for (i = strlen(z->name) - 1; i >= 0; i--) {
+       if (z->name[i] == '\\' || z->name[i] == '/' || z->name[i] == ':') {
+           i++;
+           break;
+       }
+    }
+    zai.name = &z->name[i];
+    zfile_fseek(z, 0, SEEK_END);
+    zai.size = zfile_ftell(z);
+    zfile_fseek(z, 0, SEEK_SET);
+    zvolume_addfile_abs(zv, &zai);
+    return zv;
+}
+struct zfile *archive_access_plain (struct znode *zn)
+{
+    struct zfile *z;
+
+    z = zfile_fopen_empty (zn->name, zn->size);
+    zfile_fread(z->data, zn->size, 1, zn->volume->archive);
+    return z;
+}