]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc1600b23.zip
authorToni Wilen <twilen@winuae.net>
Fri, 10 Apr 2009 11:01:29 +0000 (14:01 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:45:52 +0000 (21:45 +0200)
13 files changed:
filesys.asm
filesys_bootrom.c
hardfile.c
include/zarchive.h
include/zfile.h
od-win32/dinput.c
od-win32/hardfile_win32.c
od-win32/win32.h
od-win32/win32_scale2x.c
od-win32/winuaechangelog.txt
uaeunp.c
zfile.c
zfile_archive.c

index 50c614ba87de38bbb800b4567e73af100450498d..0081a0c3574762699d7660132168ff8d6059d604 100644 (file)
@@ -86,6 +86,7 @@ residenthack
        subq.l #4,d2
        bne.s .cp1
 
+       jsr -$0078(a6)
        move.l a6,a1
        move.w #-$48,a0 ;InitCode
        move.l a2,d0
@@ -94,6 +95,7 @@ residenthack
        lea myafterdos(pc),a0
        move.l a0,residentcodejump1-residentcodestart+2(a2)
        jsr -$27C(a6) ;CacheClearU
+       jsr -$007e(a6)
 .rsh
        movem.l (sp)+,d0-d2/a0-a2/a6
        rts
@@ -101,14 +103,18 @@ residenthack
 myafterdos
        move.l (sp),a0
        move.l 2(a0),a0
+       move.l a0,-(sp)
+       jsr (a0) ;jump to original InitCode
+       move.l (sp)+,a0
+       addq.l #4,sp ;remove return address
        movem.l d0-d7/a1-a6,-(sp)
        move.l a6,a1
        move.l a0,d0
-       move.w #-$48,a0 ;InitResident
-       jsr -$01a4(a6) ;SetFunction
+       move.w #-$48,a0 ;InitCode
+       jsr -$01a4(a6) ;SetFunction (restore original)
        bsr.w clipboard_init
        movem.l (sp)+,d0-d7/a1-a6
-       rts
+       rts ;return directly to caller
 
        cnop 0,4
 residentcodestart:
@@ -2031,18 +2037,6 @@ CLIP_POINTER_NOTIFY = (CLIP_BUF+CLIP_BUF_SIZE)
 CLIP_POINTER_PREFS = (CLIP_POINTER_NOTIFY+48)
 CLIP_END = (CLIP_POINTER_PREFS+32)
 
-;clipboard_resident:
-;      dc.w $4afc
-;      dc.l 0
-;      dc.l 26
-;      dc.b 4 ; RTF_AFTERDOS
-;      dc.b 1
-;      dc.b 0 ; NT_UNKNOWN
-;      dc.b -125
-;      dc.l clname-clipboard_resident
-;      dc.l clname-clipboard_resident
-;      dc.l clipboard_init-clipboard_resident
-
 clipboard_init:
        movem.l a5/a6,-(sp)
        move.l 4.w,a6
index 00fd32dc94b6fef32373a69cd8b5aa422313b4e8..5c5e475e744eb77f90bc88764a4ff01b65c509e7 100644 (file)
@@ -1,22 +1,24 @@
  db(0x00); db(0x00); db(0x00); db(0x10); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x00); db(0x00); db(0x00); db(0x09); db(0x60); db(0x00); db(0x0a); db(0x12);
- db(0x00); db(0x00); db(0x07); db(0xf4); db(0x00); db(0x00); db(0x00); db(0xc0);
- db(0x00); db(0x00); db(0x02); db(0x1c); db(0x00); db(0x00); db(0x00); db(0x24);
- db(0x00); db(0x00); db(0x02); db(0xd8); db(0x00); db(0x00); db(0x0d); db(0xe4);
- db(0x00); db(0x00); db(0x12); db(0x74); db(0x43); db(0xfa); db(0x16); db(0xcb);
+ db(0x00); db(0x00); db(0x00); db(0x09); db(0x60); db(0x00); db(0x0a); db(0x22);
+ db(0x00); db(0x00); db(0x08); db(0x04); db(0x00); db(0x00); db(0x00); db(0xd0);
+ db(0x00); db(0x00); db(0x02); db(0x2c); db(0x00); db(0x00); db(0x00); db(0x24);
+ db(0x00); db(0x00); db(0x02); db(0xe8); db(0x00); db(0x00); db(0x0d); db(0xf4);
+ db(0x00); db(0x00); db(0x12); db(0x84); db(0x43); db(0xfa); db(0x16); db(0xdb);
  db(0x4e); db(0xae); db(0xff); db(0xa0); db(0x20); db(0x40); db(0x20); db(0x28);
  db(0x00); db(0x16); db(0x20); db(0x40); db(0x4e); db(0x90); db(0x4e); db(0x75);
  db(0x48); db(0xe7); db(0xe0); db(0xe2); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x0c); db(0x6e); db(0x00); db(0x25); db(0x00); db(0x14); db(0x65); db(0x3c);
+ db(0x0c); db(0x6e); db(0x00); db(0x25); db(0x00); db(0x14); db(0x65); db(0x44);
  db(0x70); db(0x14); db(0x24); db(0x00); db(0x22); db(0x3c); db(0x00); db(0x01);
  db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80);
- db(0x67); db(0x2a); db(0x24); db(0x40); db(0x20); db(0x4a); db(0x43); db(0xfa);
- db(0x00); db(0x4c); db(0x20); db(0xd9); db(0x59); db(0x82); db(0x66); db(0xfa);
- db(0x22); db(0x4e); db(0x30); db(0x7c); db(0xff); db(0xb8); db(0x20); db(0x0a);
- db(0x4e); db(0xae); db(0xfe); db(0x5c); db(0x25); db(0x40); db(0x00); db(0x0e);
- db(0x41); db(0xfa); db(0x00); db(0x10); db(0x25); db(0x48); db(0x00); db(0x08);
- db(0x4e); db(0xae); db(0xfd); db(0x84); db(0x4c); db(0xdf); db(0x47); db(0x07);
+ db(0x67); db(0x32); db(0x24); db(0x40); db(0x20); db(0x4a); db(0x43); db(0xfa);
+ db(0x00); db(0x5c); db(0x20); db(0xd9); db(0x59); db(0x82); db(0x66); db(0xfa);
+ db(0x4e); db(0xae); db(0xff); db(0x88); db(0x22); db(0x4e); db(0x30); db(0x7c);
+ db(0xff); db(0xb8); db(0x20); db(0x0a); db(0x4e); db(0xae); db(0xfe); db(0x5c);
+ db(0x25); db(0x40); db(0x00); db(0x0e); db(0x41); db(0xfa); db(0x00); db(0x14);
+ db(0x25); db(0x48); db(0x00); db(0x08); db(0x4e); db(0xae); db(0xfd); db(0x84);
+ db(0x4e); db(0xae); db(0xff); db(0x82); db(0x4c); db(0xdf); db(0x47); db(0x07);
  db(0x4e); db(0x75); db(0x20); db(0x57); db(0x20); db(0x68); db(0x00); db(0x02);
+ db(0x2f); db(0x08); db(0x4e); db(0x90); db(0x20); db(0x5f); db(0x58); db(0x8f);
  db(0x48); db(0xe7); db(0xff); db(0x7e); db(0x22); db(0x4e); db(0x20); db(0x08);
  db(0x30); db(0x7c); db(0xff); db(0xb8); db(0x4e); db(0xae); db(0xfe); db(0x5c);
  db(0x61); db(0x00); db(0x11); db(0xd2); db(0x4c); db(0xdf); db(0x7e); db(0xff);
@@ -90,7 +92,7 @@
  db(0x60); db(0x00); db(0xff); db(0x74); db(0x30); db(0x3c); db(0xff); db(0x50);
  db(0x61); db(0x00); db(0x09); db(0x86); db(0x70); db(0x04); db(0x4e); db(0x90);
  db(0x70); db(0x01); db(0x4c); db(0xdf); db(0x04); db(0x00); db(0x4e); db(0x75);
- db(0x48); db(0xe7); db(0xc0); db(0xc0); db(0x61); db(0x00); db(0xfd); db(0x5a);
+ db(0x48); db(0xe7); db(0xc0); db(0xc0); db(0x61); db(0x00); db(0xfd); db(0x4a);
  db(0x70); db(0x1a); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
  db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x22); db(0x40); db(0x41); db(0xfa);
  db(0x13); db(0xc6); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa);
  db(0xff); db(0x18); db(0x61); db(0x00); db(0x03); db(0x9c); db(0x4e); db(0x90);
  db(0x20); db(0x03); db(0x16); db(0x29); db(0x00); db(0x4f); db(0x4a); db(0x80);
  db(0x66); db(0x1a); db(0x27); db(0x7c); db(0x00); db(0x00); db(0x17); db(0x70);
- db(0x00); db(0x14); db(0x41); db(0xfa); db(0xf7); db(0x30); db(0x20); db(0x08);
+ db(0x00); db(0x14); db(0x41); db(0xfa); db(0xf7); db(0x20); db(0x20); db(0x08);
  db(0xe4); db(0x88); db(0x27); db(0x40); db(0x00); db(0x20); db(0x70); db(0xff);
  db(0x27); db(0x40); db(0x00); db(0x24); db(0x08); db(0x07); db(0x00); db(0x00);
  db(0x67); db(0x3a); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x70); db(0x14);
  db(0x24); db(0x51); db(0x70); db(0x18); db(0x4e); db(0xae); db(0xff); db(0x2e);
  db(0x06); db(0x86); db(0x00); db(0x01); db(0x00); db(0x00); db(0x20); db(0x0a);
  db(0x66); db(0xec); db(0x26); db(0x87); db(0x2a); db(0x1f); db(0x4e); db(0x75);
- db(0x41); db(0xfa); db(0xf3); db(0xa2); db(0x02); db(0x80); db(0x00); db(0x00);
+ db(0x41); db(0xfa); db(0xf3); db(0x92); db(0x02); db(0x80); db(0x00); db(0x00);
  db(0xff); db(0xff); db(0xd1); db(0xc0); db(0x4e); db(0x75); db(0x20); db(0x88);
  db(0x58); db(0x90); db(0x42); db(0xa8); db(0x00); db(0x04); db(0x21); db(0x48);
  db(0x00); db(0x08); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x20); db(0x22);
index b980c7b161a1e2a38690399f196a947a62c9be41..bbf4d9459dbb32519d7c3e8ff509b268fe7ce9f5 100644 (file)
@@ -179,7 +179,7 @@ void getchshd (struct hardfiledata *hfd, int *pcyl, int *phead, int *psectorsper
     *psectorspertrack = spt;
 }
 
-static void pl(uae_u8 *p, int off, uae_u32 v)
+static void pl (uae_u8 *p, int off, uae_u32 v)
 {
     p += off * 4;
     p[0] = v >> 24;
@@ -188,7 +188,7 @@ static void pl(uae_u8 *p, int off, uae_u32 v)
     p[3] = v >> 0;
 }
 
-static void rdb_crc(uae_u8 *p)
+static void rdb_crc (uae_u8 *p)
 {
     uae_u32 sum;
     int i, blocksize;
@@ -552,7 +552,6 @@ end:
     return ret;
 }
 
-
 static uae_u64 vhd_read (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len)
 {
     uae_u32 bamoffset;
index a9fe26a18bc7441b1672098f52ac0435d6f9fc38..b7c2f224341307debb7d6ebf0435d8e40e8d5b6d 100644 (file)
@@ -100,12 +100,12 @@ 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 zvolume *archive_directory_adf (struct zfile *z);
+extern struct zvolume *archive_directory_adf (struct znode *zn, struct zfile *z);
 extern struct zfile *archive_access_adf (struct znode *zn);
 extern struct zvolume *archive_directory_rdb (struct zfile *z);
 extern struct zfile *archive_access_rdb (struct znode *zn);
 
-extern struct zfile *archive_access_select (struct zfile *zf, unsigned int id, int doselect);
+extern struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, unsigned int id, int doselect);
 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);
index 7fbe378f057d25df3b0e995bc76ea537ebdce23b..8c630222cdaf548ba92f0ccfa655fea98e982cb5 100644 (file)
@@ -42,7 +42,7 @@ extern struct zfile *zfile_gunzip (struct zfile *z);
 extern int zfile_isdiskimage (const TCHAR *name);
 extern int iszip (struct zfile *z);
 extern int zfile_convertimage (const TCHAR *src, const TCHAR *dst);
-extern struct zfile *zuncompress (struct zfile *z, int dodefault, int imgonly);
+extern struct zfile *zuncompress (struct znode*, struct zfile *z, int dodefault, int imgonly);
 extern void zfile_seterror (const TCHAR *format, ...);
 extern TCHAR *zfile_geterror (void);
 
index 67f5bbd1580e9ecba723b66cb7d5286387e3d371..5bb24c9ed6e242bfebcbc5b163897e8cf31e403e 100644 (file)
@@ -1117,12 +1117,14 @@ void handle_rawinput (LPARAM lParam)
 
 static void unacquire (LPDIRECTINPUTDEVICE8 lpdi, TCHAR *txt)
 {
+    HRESULT hr;
     if (lpdi) {
-       HRESULT hr = IDirectInputDevice8_Unacquire (lpdi);
+       hr = IDirectInputDevice8_Unacquire (lpdi);
        if (FAILED (hr) && hr != DI_NOEFFECT)
            write_log (L"unacquire %s failed, %s\n", txt, DXError (hr));
     }
 }
+
 static int acquire (LPDIRECTINPUTDEVICE8 lpdi, TCHAR *txt)
 {
     HRESULT hr = DI_OK;
@@ -1993,6 +1995,82 @@ void release_keys (void)
     }
 }
 
+
+static int acquire_kb (int num, int flags)
+{
+    LPDIRECTINPUTDEVICE8 lpdi = di_keyboard[num].lpdi;
+
+    unacquire (lpdi, L"keyboard");
+    if (currprefs.keyboard_leds_in_use) {
+#ifdef WINDDK
+       if (!currprefs.win32_kbledmode) {
+           if (DefineDosDevice (DDD_RAW_TARGET_PATH, L"Kbd", L"\\Device\\KeyboardClass0")) {
+               kbhandle = CreateFile (L"\\\\.\\Kbd", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+               if (kbhandle == INVALID_HANDLE_VALUE) {
+                   write_log (L"kbled: CreateFile failed, error %d\n", GetLastError());
+                   currprefs.win32_kbledmode = 1;
+               }
+           } else {
+               currprefs.win32_kbledmode = 1;
+               write_log (L"kbled: DefineDosDevice failed, error %d\n", GetLastError());
+           }
+       }
+#else
+       currprefs.kbledmode = 1;
+#endif
+       oldleds = get_leds ();
+       if (oldusedleds < 0)
+           oldusedleds = newleds = oldleds;
+       set_leds (oldusedleds);
+    }
+
+    setcoop (&di_keyboard[num], DISCL_NOWINKEY | DISCL_FOREGROUND | DISCL_EXCLUSIVE, L"keyboard");
+    kb_do_refresh = ~0;
+    di_keyboard[num].acquired = -1;
+    if (acquire (lpdi, L"keyboard")) {
+       if (di_keyboard[num].rawinput)
+           rawkb++;
+       else if (di_keyboard[num].superdevice)
+           superkb++;
+       else
+           normalkb++;
+       di_keyboard[num].acquired = 1;
+    }
+    register_rawinput ();
+    return di_keyboard[num].acquired > 0 ? 1 : 0;
+}
+
+static void unacquire_kb (int num)
+{
+    LPDIRECTINPUTDEVICE8 lpdi = di_keyboard[num].lpdi;
+
+    unacquire (lpdi, L"keyboard");
+    if (di_keyboard[num].acquired > 0) {
+       if (di_keyboard[num].rawinput)
+           rawkb--;
+       else if (di_keyboard[num].superdevice)
+           superkb--;
+       else
+           normalkb--;
+       di_keyboard[num].acquired = 0;
+    }
+    release_keys ();
+
+    if (currprefs.keyboard_leds_in_use) {
+       if (oldusedleds >= 0) {
+           set_leds (oldleds);
+           oldusedleds = oldleds;
+       }
+#ifdef WINDDK
+       if (kbhandle != INVALID_HANDLE_VALUE) {
+           CloseHandle (kbhandle);
+           DefineDosDevice (DDD_REMOVE_DEFINITION, L"Kbd", NULL);
+           kbhandle = INVALID_HANDLE_VALUE;
+       }
+#endif
+    }
+}
+
 static int refresh_kb (LPDIRECTINPUTDEVICE8 lpdi, int num)
 {
     HRESULT hr;
@@ -2015,7 +2093,7 @@ static int refresh_kb (LPDIRECTINPUTDEVICE8 lpdi, int num)
            }
        }
     } else if (hr == DIERR_INPUTLOST) {
-       acquire (lpdi, L"keyboard");
+       acquire_kb (num, 0);
        IDirectInputDevice8_Poll (lpdi);
        return 0;
     }
@@ -2023,7 +2101,6 @@ static int refresh_kb (LPDIRECTINPUTDEVICE8 lpdi, int num)
     return 1;
 }
 
-
 static void read_kb (void)
 {
     DIDEVICEOBJECTDATA didod[DI_KBBUFFER];
@@ -2041,6 +2118,11 @@ static void read_kb (void)
        struct didata *did = &di_keyboard[i];
        if (!did->acquired)
            continue;
+       if (isfocus () == 0) {
+           if (did->acquired > 0)
+               unacquire_kb (i);
+           continue;
+       }
        lpdi = did->lpdi;
        if (!lpdi)
            continue;
@@ -2071,15 +2153,15 @@ static void read_kb (void)
                }
            }
        } else if (hr == DIERR_INPUTLOST) {
-           acquire (lpdi, L"keyboard");
+           acquire_kb (i, 0);
            kb_do_refresh |= 1 << i;
-       } else if (did->acquired &&  hr == DIERR_NOTACQUIRED) {
-           acquire (lpdi, L"keyboard");
+       } else if (did->acquired && hr == DIERR_NOTACQUIRED) {
+           acquire_kb (i, 0);
        }
        IDirectInputDevice8_Poll (lpdi);
     }
 #ifdef CATWEASEL
-    {
+    if (isfocus ()) {
        uae_u8 kc;
        if (stopoutput == 0 && catweasel_read_keyboard (&kc))
            inputdevice_do_keyboard (kc & 0x7f, kc & 0x80);
@@ -2138,81 +2220,6 @@ void wait_keyrelease (void)
     stopoutput--;
 }
 
-static int acquire_kb (int num, int flags)
-{
-    LPDIRECTINPUTDEVICE8 lpdi = di_keyboard[num].lpdi;
-
-    unacquire (lpdi, L"keyboard");
-    if (currprefs.keyboard_leds_in_use) {
-#ifdef WINDDK
-       if (!currprefs.win32_kbledmode) {
-           if (DefineDosDevice (DDD_RAW_TARGET_PATH, L"Kbd", L"\\Device\\KeyboardClass0")) {
-               kbhandle = CreateFile (L"\\\\.\\Kbd", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
-               if (kbhandle == INVALID_HANDLE_VALUE) {
-                   write_log (L"kbled: CreateFile failed, error %d\n", GetLastError());
-                   currprefs.win32_kbledmode = 1;
-               }
-           } else {
-               currprefs.win32_kbledmode = 1;
-               write_log (L"kbled: DefineDosDevice failed, error %d\n", GetLastError());
-           }
-       }
-#else
-       currprefs.kbledmode = 1;
-#endif
-       oldleds = get_leds ();
-       if (oldusedleds < 0)
-           oldusedleds = newleds = oldleds;
-       set_leds (oldusedleds);
-    }
-
-    setcoop (&di_keyboard[num], DISCL_NOWINKEY | DISCL_FOREGROUND | DISCL_EXCLUSIVE, L"keyboard");
-    kb_do_refresh = ~0;
-    di_keyboard[num].acquired = -1;
-    if (acquire (lpdi, L"keyboard")) {
-       if (di_keyboard[num].rawinput)
-           rawkb++;
-       else if (di_keyboard[num].superdevice)
-           superkb++;
-       else
-           normalkb++;
-       di_keyboard[num].acquired = 1;
-    }
-    register_rawinput ();
-    return di_keyboard[num].acquired > 0 ? 1 : 0;
-}
-
-static void unacquire_kb (int num)
-{
-    LPDIRECTINPUTDEVICE8 lpdi = di_keyboard[num].lpdi;
-
-    unacquire (lpdi, L"keyboard");
-    if (di_keyboard[num].acquired > 0) {
-       if (di_keyboard[num].rawinput)
-           rawkb--;
-       else if (di_keyboard[num].superdevice)
-           superkb--;
-       else
-           normalkb--;
-       di_keyboard[num].acquired = 0;
-    }
-    release_keys ();
-
-    if (currprefs.keyboard_leds_in_use) {
-       if (oldusedleds >= 0) {
-           set_leds (oldleds);
-           oldusedleds = oldleds;
-       }
-#ifdef WINDDK
-       if (kbhandle != INVALID_HANDLE_VALUE) {
-           CloseHandle (kbhandle);
-           DefineDosDevice (DDD_REMOVE_DEFINITION, L"Kbd", NULL);
-           kbhandle = INVALID_HANDLE_VALUE;
-       }
-#endif
-    }
-}
-
 static int get_kb_flags (int kb)
 {
     return 0;
index b2762e62e809670420a7b71ed3dea280ef32c58d..47bea70fdec8f7bfc688d96c089f946e8b2d6321 100644 (file)
@@ -756,7 +756,7 @@ static int getstorageproperty (PUCHAR outBuf, int returnedLength, struct uae_dri
 
 static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWORD *index2, uae_u8 *buffer, int ignoreduplicates)
 {
-    int i, nosp;
+    int i, nosp, geom_ok;
     int ret = -1;
     STORAGE_PROPERTY_QUERY query;
     DRIVE_LAYOUT_INFORMATION           *dli;
@@ -854,6 +854,7 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR
     }
     _tcscpy (orgname, udi->device_name);
     udi->bytespersector = 512;
+    geom_ok = 1;
     if (!DeviceIoControl (hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, (void*)&dg, sizeof (dg), &returnedLength, NULL)) {
        DWORD err = GetLastError();
        if (isnomediaerr (err)) {
@@ -861,8 +862,8 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR
            goto amipartfound;
        }
        write_log (L"IOCTL_DISK_GET_DRIVE_GEOMETRY failed with error code %d.\n", err);
-       ret = 1;
-       goto end;
+       dg.BytesPerSector = 512;
+       geom_ok = 0;
     }
     udi->readonly = 0;
     if (!DeviceIoControl (hDevice, IOCTL_DISK_IS_WRITABLE, NULL, 0, NULL, 0, &returnedLength, NULL)) {
@@ -878,22 +879,30 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR
        if (!nosp)
            write_log (L"IOCTL_DISK_GET_LENGTH_INFO not supported, detected disk size may not be correct.\n");
     }
-    udi->bytespersector = dg.BytesPerSector;
-    if (dg.BytesPerSector < 512) {
-       write_log (L"unsupported blocksize < 512 (%d)\n", dg.BytesPerSector);
-       ret = 1;
-       goto end;
-    }
-    if (dg.BytesPerSector > 2048) {
-       write_log (L"unsupported blocksize > 2048 (%d)\n", dg.BytesPerSector);
+    if (geom_ok == 0 && gli_ok == 0) {
+       write_log (L"Can't detect size of device\n");
        ret = 1;
        goto end;
     }
+
     udi->offset = 0;
-    write_log (L"BPS=%d Cyls=%I64d TPC=%d SPT=%d MediaType=%d\n",
-       dg.BytesPerSector, dg.Cylinders.QuadPart, dg.TracksPerCylinder, dg.SectorsPerTrack, dg.MediaType);
-    udi->size = (uae_u64)dg.BytesPerSector * (uae_u64)dg.Cylinders.QuadPart *
-       (uae_u64)dg.TracksPerCylinder * (uae_u64)dg.SectorsPerTrack;
+    if (geom_ok) {
+       udi->bytespersector = dg.BytesPerSector;
+       if (dg.BytesPerSector < 512) {
+           write_log (L"unsupported blocksize < 512 (%d)\n", dg.BytesPerSector);
+           ret = 1;
+           goto end;
+       }
+       if (dg.BytesPerSector > 2048) {
+           write_log (L"unsupported blocksize > 2048 (%d)\n", dg.BytesPerSector);
+           ret = 1;
+           goto end;
+       }
+        write_log (L"BPS=%d Cyls=%I64d TPC=%d SPT=%d MediaType=%d\n",
+           dg.BytesPerSector, dg.Cylinders.QuadPart, dg.TracksPerCylinder, dg.SectorsPerTrack, dg.MediaType);
+       udi->size = (uae_u64)dg.BytesPerSector * (uae_u64)dg.Cylinders.QuadPart *
+           (uae_u64)dg.TracksPerCylinder * (uae_u64)dg.SectorsPerTrack;
+    }
     if (gli_ok)
        udi->size = gli.Length.QuadPart;
     write_log (L"device size %I64d (0x%I64x) bytes\n", udi->size, udi->size);
index a370e05de10216744011d0d7bc1bd2a03ea9f672..92b75f3f0c33baf5effdb3b3dd5fbfdfd411d4fe 100644 (file)
@@ -17,8 +17,8 @@
 
 #define WINUAEPUBLICBETA 1
 
-#define WINUAEBETA L"22"
-#define WINUAEDATE MAKEBD(2009, 4, 8)
+#define WINUAEBETA L"23"
+#define WINUAEDATE MAKEBD(2009, 4, 10)
 #define WINUAEEXTRA L""
 #define WINUAEREV L""
 
index 4987b796d0a6640f1937400f2badbfa16120e51d..78de8ff2f794e1af3cd6ffeae36688ad18d7d665 100644 (file)
@@ -491,6 +491,8 @@ void S2X_render (void)
            }
            for (i = 0; i < ah * scale; i++) {
                int w = aw * scale * (dst_depth / 8);
+               if (dptr + w > enddptr)
+                   break;
                memcpy (dptr, sptr2, w);
                sptr2 += w;
                dptr += pitch;
index 3dae2f73515a291b822d2364a193f9e420f73473..299ab1b14ca922737278a146b9ecc622ce2dd828 100644 (file)
@@ -1,4 +1,12 @@
 
+Beta 23:
+
+- archives (zip etc) didn't unpack
+- directinput keyboard was not always unacquired when focus was lost
+- hq2x/3x/4x crash in specific situations (old random bug)
+- clipboard initialization changed again, now initialized after all
+  residents have been initialized (previously it was after dos)
+
 Beta 22:
 
 - do not change priority if current priority is HIGH or REALTIME
index 32b64be0bd469dbc6fd5f27507df1c86499f2c7c..5b3efd8c27f8afd2718e63834be8a9f96e79294f 100644 (file)
--- a/uaeunp.c
+++ b/uaeunp.c
@@ -15,7 +15,7 @@ TCHAR start_path_data[MAX_DPATH];
 TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
 
 struct uae_prefs currprefs;
-static int debug = 0;
+static int debug = 1;
 
 #define WRITE_LOG_BUF_SIZE 4096
 void write_log (const TCHAR *format, ...)
@@ -395,6 +395,7 @@ static int unpack (const TCHAR *src, const TCHAR *filename, const TCHAR *dst, in
                break;
        }
     }
+    geterror ();
     if (!found && !level) {
        _tprintf (L"'%s' not found\n", fn);
     }
@@ -480,6 +481,7 @@ static int unpack2 (const TCHAR *src, const TCHAR *match, int level)
            zfile_fclose (s);
        }
     }
+    geterror ();
     if (!found && !level) {
        _tprintf (L"'%s' not matched\n", match);
     }
@@ -623,7 +625,7 @@ int wmain (int argc, wchar_t *argv[], wchar_t *envp[])
        ok = 1;
     }
     if (!ok) {
-       _tprintf (L"UAE unpacker uaeunp 0.4c by Toni Wilen (c)2009\n");
+       _tprintf (L"UAE unpacker uaeunp 0.5b by Toni Wilen (c)2009\n");
        _tprintf (L"\n");
        _tprintf (L"List: \"uaeunp (-l) <path>\"\n");
        _tprintf (L"List all recursively: \"uaeunp -l <path> **\"\n");
@@ -634,7 +636,7 @@ int wmain (int argc, wchar_t *argv[], wchar_t *envp[])
        _tprintf (L"Output to console: \"uaeunp (-x) -o <path> <filename>\"\n");
        _tprintf (L"\n");
        _tprintf (L"Supported disk image formats:\n");
-       _tprintf (L" ADF and HDF (OFS/FFS), DMS, encrypted DMS, IPF, FDI, DSQ, WRP\n");
+       _tprintf (L" ADF and HDF (OFS/FFS/SFS/SFS2), DMS, encrypted DMS, IPF, FDI, DSQ, WRP\n");
        _tprintf (L"Supported archive formats:\n");
        _tprintf (L" 7ZIP, LHA, LZX, RAR (unrar.dll), ZIP, ArchiveAccess.DLL\n");
        _tprintf (L"Miscellaneous formats:\n");
@@ -644,3 +646,19 @@ int wmain (int argc, wchar_t *argv[], wchar_t *envp[])
     }
     return 0;
 }
+
+/*
+    0.5:
+
+    - adf protection flags fixed
+    - sfs support added
+    - >512 block sizes supported (rdb hardfiles only)
+
+    0.5b:
+
+    - SFS file extraction fixed
+    - SFS2 supported
+    - block size autodetection implemented (if non-rdb hardfile)
+
+
+*/
\ No newline at end of file
diff --git a/zfile.c b/zfile.c
index 608ab21125cb142318bde5a68117c347ed2d3d53..23bbb8e36a71b9197a05d7b4bbc4c03b2ccf45b2 100644 (file)
--- a/zfile.c
+++ b/zfile.c
@@ -594,6 +594,8 @@ int iszip (struct zfile *z)
        if (!strcasecmp (ext, L".hdf")) {
            if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
                return ArchiveFormatADF;
+           if (header[0] == 'S' && header[1] == 'F' && header[2] == 'S')
+               return ArchiveFormatADF;
            if (header[0] == 'R' && header[1] == 'D' && header[2] == 'S' && header[3] == 'K')
                return ArchiveFormatRDB;
            return 0;
@@ -609,7 +611,7 @@ int iszip (struct zfile *z)
     return 0;
 }
 
-struct zfile *zuncompress (struct zfile *z, int dodefault, int mask)
+struct zfile *zuncompress (struct znode *parent, struct zfile *z, int dodefault, int mask)
 {
     TCHAR *name = z->name;
     TCHAR *ext = NULL;
@@ -627,15 +629,15 @@ struct zfile *zuncompress (struct zfile *z, int dodefault, int mask)
     if (ext != NULL) {
        if (mask & ZFD_ARCHIVE) {
            if (strcasecmp (ext, L"7z") == 0)
-                return archive_access_select (z, ArchiveFormat7Zip, dodefault);
+                return archive_access_select (parent, z, ArchiveFormat7Zip, dodefault);
            if (strcasecmp (ext, L"zip") == 0)
-                return archive_access_select (z, ArchiveFormatZIP, dodefault);
+                return archive_access_select (parent, z, ArchiveFormatZIP, dodefault);
            if (strcasecmp (ext, L"lha") == 0 || strcasecmp (ext, L"lzh") == 0)
-                return archive_access_select (z, ArchiveFormatLHA, dodefault);
+                return archive_access_select (parent, z, ArchiveFormatLHA, dodefault);
            if (strcasecmp (ext, L"lzx") == 0)
-                return archive_access_select (z, ArchiveFormatLZX, dodefault);
+                return archive_access_select (parent, z, ArchiveFormatLZX, dodefault);
            if (strcasecmp (ext, L"rar") == 0)
-                return archive_access_select (z, ArchiveFormatRAR, dodefault);
+                return archive_access_select (parent, z, ArchiveFormatRAR, dodefault);
        }
        if (mask & ZFD_UNPACK) {
            if (strcasecmp (ext, L"gz") == 0)
@@ -690,17 +692,19 @@ struct zfile *zuncompress (struct zfile *z, int dodefault, int mask)
     }
     if (mask & ZFD_ARCHIVE) {
         if (header[0] == 'P' && header[1] == 'K')
-           return archive_access_select (z, ArchiveFormatZIP, dodefault);
+           return archive_access_select (parent, z, ArchiveFormatZIP, dodefault);
         if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
-           return archive_access_select (z, ArchiveFormatRAR, dodefault);
+           return archive_access_select (parent, z, ArchiveFormatRAR, dodefault);
        if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X')
-           return archive_access_select (z, ArchiveFormatLZX, dodefault);
+           return archive_access_select (parent, z, ArchiveFormatLZX, dodefault);
        if (header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-')
-           return archive_access_select (z, ArchiveFormatLHA, dodefault);
+           return archive_access_select (parent, z, ArchiveFormatLHA, dodefault);
     }
     if (mask & ZFD_ADF) {
        if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
-           return archive_access_select (z, ArchiveFormatADF, dodefault);
+           return archive_access_select (parent, z, ArchiveFormatADF, dodefault);
+       if (header[0] == 'S' && header[1] == 'F' && header[2] == 'S')
+           return archive_access_select (parent, z, ArchiveFormatADF, dodefault);
     }
 
     if (ext) {
@@ -710,7 +714,7 @@ struct zfile *zuncompress (struct zfile *z, int dodefault, int mask)
        }
        if (mask & ZFD_ADF) {
            if (strcasecmp (ext, L"adf") == 0 && !memcmp (header, "DOS", 3))
-               return archive_access_select (z, ArchiveFormatADF, dodefault);
+               return archive_access_select (parent, z, ArchiveFormatADF, dodefault);
        }
     }
     return z;
@@ -902,7 +906,7 @@ struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask)
        return l;
     l2 = NULL;
     while (cnt-- > 0) {
-       l = zuncompress (l, 0, mask);
+       l = zuncompress (NULL, l, 0, mask);
        if (!l)
            break;
        zfile_fseek (l, 0, SEEK_SET);
@@ -975,6 +979,10 @@ struct zfile *zfile_fopen_empty (struct zfile *prev, const TCHAR *name, uae_u64
     l->name = name ? my_strdup (name) : L"";
     if (size) {
        l->data = xcalloc (size, 1);
+       if (!l->data)  {
+           xfree (l);
+           return NULL;
+       }
        l->size = size;
     } else {
        l->data = xcalloc (1, 1);
@@ -1462,7 +1470,7 @@ static struct zvolume *get_zvolume (const TCHAR *path)
     return NULL;
 }
 
-static struct zvolume *zfile_fopen_archive_ext (struct zfile *zf)
+static struct zvolume *zfile_fopen_archive_ext (struct znode *parent, struct zfile *zf)
 {
     struct zvolume *zv = NULL;
     TCHAR *name = zfile_getname (zf);
@@ -1491,19 +1499,19 @@ static struct zvolume *zfile_fopen_archive_ext (struct zfile *zf)
        if (strcasecmp (ext, L"rar") == 0)
             zv = archive_directory_rar (zf);
        if (strcasecmp (ext, L"adf") == 0 && !memcmp (header, "DOS", 3))
-            zv = archive_directory_adf (zf);
+            zv = archive_directory_adf (parent, zf);
        if (strcasecmp (ext, L"hdf") == 0)  {
            if (!memcmp (header, "RDSK", 4))
                zv = archive_directory_rdb (zf);
            else
-               zv = archive_directory_adf (zf);
+               zv = archive_directory_adf (parent, zf);
        }
     }
     return zv;
 }
 
 
-struct zvolume *zfile_fopen_archive_data (struct zfile *zf)
+static struct zvolume *zfile_fopen_archive_data (struct znode *parent, struct zfile *zf)
 {
     struct zvolume *zv = NULL;
     uae_u8 header[7];
@@ -1520,7 +1528,7 @@ struct zvolume *zfile_fopen_archive_data (struct zfile *zf)
     if (header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-')
         zv = archive_directory_lha (zf);
     if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
-        zv = archive_directory_adf (zf);
+        zv = archive_directory_adf (parent, zf);
     if (header[0] == 'R' && header[1] == 'D' && header[2] == 'S' && header[3] == 'K')
         zv = archive_directory_rdb (zf);
     return zv;
@@ -1550,6 +1558,8 @@ static void zfile_fopen_archive_recurse2 (struct zvolume *zv, struct znode *zn)
        zndir->vfile = zn;
        zndir->vchild = zvnew;
        zvnew->parent = zv;
+       zndir->offset = zn->offset;
+       zndir->offset2 = zn->offset2;
     }
 }
 
@@ -1589,10 +1599,10 @@ static struct zvolume *prepare_recursive_volume (struct zvolume *zv, const TCHAR
     zf = zfile_open_archive (path, 0);
     if (!zf)
        goto end;
-    zvnew = zfile_fopen_archive_ext (zf);
+    zvnew = zfile_fopen_archive_ext (zv->parentz, zf);
     if (!zvnew) {
        struct zfile *zf2 = zf;
-       zf = zuncompress (zf2, 0, 1);
+       zf = zuncompress (&zv->root, zf2, 0, ZFD_ALL);
        if (zf != zf2)
            zvnew = archive_directory_plain (zf);
     }
@@ -1763,9 +1773,9 @@ struct zvolume *zfile_fopen_archive (const TCHAR *filename)
     if (!zf)
        return NULL;
     zf->zfdmask = ZFD_ALL;
-    zv = zfile_fopen_archive_ext (zf);
+    zv = zfile_fopen_archive_ext (NULL, zf);
     if (!zv)
-       zv = zfile_fopen_archive_data (zf);
+       zv = zfile_fopen_archive_data (NULL, zf);
 #if 0
     if (!zv) {
        struct zfile *zf2 = zuncompress (zf, 0, 0);
index d17dd102ab885ae22833a1af37507b9a22b50e80..7671c5af4db574e9d578ae1f377714cd64ebb66a 100644 (file)
@@ -44,7 +44,7 @@ static time_t fromdostime (uae_u32 dd)
     return t;
 }
 
-static struct zvolume *getzvolume (struct zfile *zf, unsigned int id)
+static struct zvolume *getzvolume (struct znode *parent, struct zfile *zf, unsigned int id)
 {
     struct zvolume *zv = NULL;
 
@@ -69,7 +69,7 @@ static struct zvolume *getzvolume (struct zfile *zf, unsigned int id)
        zv = archive_directory_plain (zf);
        break;
        case ArchiveFormatADF:
-       zv = archive_directory_adf (zf);
+       zv = archive_directory_adf (parent, zf);
        break;
        case ArchiveFormatRDB:
        zv = archive_directory_rdb (zf);
@@ -114,7 +114,7 @@ struct zfile *archive_getzfile (struct znode *zn, unsigned int id)
     return zf;
 }
 
-struct zfile *archive_access_select (struct zfile *zf, unsigned int id, int dodefault)
+struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, unsigned int id, int dodefault)
 {
     struct zvolume *zv;
     struct znode *zn;
@@ -123,7 +123,7 @@ struct zfile *archive_access_select (struct zfile *zf, unsigned int id, int dode
     struct zfile *z = NULL;
     int we_have_file;
 
-    zv = getzvolume (zf, id);
+    zv = getzvolume (parent, zf, id);
     if (!zv)
        return zf;
     we_have_file = 0;
@@ -176,7 +176,7 @@ struct zfile *archive_access_select (struct zfile *zf, unsigned int id, int dode
            }
        }
        zipcnt++;
-       zn = zn->sibling;
+       zn = zn->next;
     }
 #ifndef _CONSOLE
     if (first && tmphist[0])
@@ -203,7 +203,7 @@ void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user, unsig
     struct zvolume *zv;
     struct znode *zn;
 
-    zv = getzvolume (zf, id);
+    zv = getzvolume (NULL, zf, id);
     if (!zv)
        return;
     zn = &zv->root;
@@ -222,7 +222,7 @@ void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user, unsig
                }
            }
        }
-       zn = zn->sibling;
+       zn = zn->next;
     }
     zfile_fclose_archive (zv);
 }
@@ -886,7 +886,7 @@ struct zvolume *archive_directory_plain (struct zfile *z)
        xfree (data);
     }
     zf = zfile_dup (z);
-    zf2 = zuncompress (zf, 0, 1);
+    zf2 = zuncompress (NULL, zf, 0, ZFD_ALL);
     if (zf2 != zf) {
        zf = zf2;
        zai.name = zfile_getfilename (zf);
@@ -908,13 +908,15 @@ struct zfile *archive_access_plain (struct znode *zn)
     if (zn->offset) {
        struct zfile *zf;
        z = zfile_fopen_empty (zn->volume->archive, zn->fullname, zn->size);
-       zf = zfile_fopen (zfile_getname (zn->volume->archive), L"rb", zn->volume->archive->zfdmask);
+       zf = zfile_fopen (zfile_getname (zn->volume->archive), L"rb", zn->volume->archive->zfdmask & ~ZFD_ADF);
        zfile_fread (z->data, zn->size, 1, zf);
        zfile_fclose (zf);
     } else {
        z = zfile_fopen_empty (zn->volume->archive, zn->fullname, zn->size);
-       zfile_fseek (zn->volume->archive, 0, SEEK_SET);
-       zfile_fread (z->data, zn->size, 1, zn->volume->archive);
+       if (z) {
+           zfile_fseek (zn->volume->archive, 0, SEEK_SET);
+           zfile_fread (z->data, zn->size, 1, zn->volume->archive);
+       }
     }
     return z;
 }
@@ -929,6 +931,24 @@ struct adfhandle {
     uae_u32 dostype;
 };
 
+
+static int dos_checksum (uae_u8 *p, int blocksize)
+{
+    uae_u32 cs = 0;
+    int i;
+    for (i = 0; i < blocksize; i += 4)
+       cs += (p[i] << 24) | (p[i + 1] << 16) | (p[i + 2] << 8) | (p[i + 3] << 0);
+    return cs;
+}
+static int sfs_checksum (uae_u8 *p, int blocksize, int sfs2)
+{
+    uae_u32 cs = sfs2 ? 2 : 1;
+    int i;
+    for (i = 0; i < blocksize; i += 4)
+       cs += (p[i] << 24) | (p[i + 1] << 16) | (p[i + 2] << 8) | (p[i + 3] << 0);
+    return cs;
+}
+
 static TCHAR *getBSTR (uae_u8 *bstr)
 {
     int n = *bstr++;
@@ -940,14 +960,24 @@ static TCHAR *getBSTR (uae_u8 *bstr)
     buf[i] = 0;
     return au (buf);
 }
+
 static uae_u32 gl (struct adfhandle *adf, int off)
 {
     uae_u8 *p = adf->block + off;
     return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
 }
+static uae_u32 glx (uae_u8 *p)
+{
+    return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
+}
+static uae_u32 gwx (uae_u8 *p)
+{
+    return (p[0] << 8) | (p[1] << 0);
+}
 
 static const int secs_per_day = 24 * 60 * 60;
 static const int diff = (8 * 365 + 2) * (24 * 60 * 60);
+static const int diff2 = (-8 * 365 - 2) * (24 * 60 * 60);
 static time_t put_time (long days, long mins, long ticks)
 {
     time_t t;
@@ -985,13 +1015,14 @@ static void recurseadf (struct znode *zn, int root, TCHAR *name)
     struct zvolume *zv = zn->volume;
     struct adfhandle *adf = zv->handle;
     TCHAR name2[MAX_DPATH];
+    int bs = adf->blocksize;
 
-    for (i = 6; i < 78; i++) {
+    for (i = 0; i < bs / 4 - 56; i++) {
        int block;
        if (!adf_read_block (adf, root))
            return;
-       block = gl (adf, i * 4);
-       while (block > 0 && block < adf->size / 512) {
+       block = gl (adf, (i + 6) * 4);
+       while (block > 0 && block < adf->size / bs) {
            struct zarchive_info zai;
            TCHAR *fname;
            uae_u32 size, secondary;
@@ -1002,12 +1033,12 @@ static void recurseadf (struct znode *zn, int root, TCHAR *name)
                break;
            if (gl (adf, 1 * 4) != block)
                break;
-           secondary = gl (adf, 512 - 1 * 4);
+           secondary = gl (adf, bs - 1 * 4);
            if (secondary != -3 && secondary != 2)
                break;
            memset (&zai, 0, sizeof zai);
-           fname = getBSTR (adf->block + 512 - 20 * 4);
-           size = gl (adf, 512 - 47 * 4);
+           fname = getBSTR (adf->block + bs - 20 * 4);
+           size = gl (adf, bs - 47 * 4);
            name2[0] = 0;
            if (name[0]) {
                TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
@@ -1017,10 +1048,8 @@ static void recurseadf (struct znode *zn, int root, TCHAR *name)
            _tcscat (name2, fname);
            zai.name = name2;
            zai.size = size;
-           zai.flags = gl (adf, 512 - 48);
-           zai.t = put_time (gl (adf, 512 - 23 * 4),
-               gl (adf, 512 - 22 * 4),
-               gl (adf, 512 - 21 * 4));
+           zai.flags = gl (adf, bs - 48 * 4);
+           zai.t = put_time (gl (adf, bs - 23 * 4), gl (adf, bs - 22 * 4),gl (adf, bs - 21 * 4));
            if (secondary == -3) {
                struct znode *znnew = zvolume_addfile_abs (zv, &zai);
                znnew->offset = block;
@@ -1032,17 +1061,103 @@ static void recurseadf (struct znode *zn, int root, TCHAR *name)
                    return;
            }
            xfree (fname);
-           block = gl (adf, 512 - 4 * 4);
+           block = gl (adf, bs - 4 * 4);
        }
     }
 }
 
-struct zvolume *archive_directory_adf (struct zfile *z)
+static void recursesfs (struct znode *zn, int root, TCHAR *name, int sfs2)
+{
+    struct zvolume *zv = zn->volume;
+    struct adfhandle *adf = zv->handle;
+    TCHAR name2[MAX_DPATH];
+    int bs = adf->blocksize;
+    int block;
+    uae_u8 *p, *s;
+    struct zarchive_info zai;
+
+    block = root;
+    while (block) {
+        if (!adf_read_block (adf, block))
+           return;
+       p = adf->block + 12 + 3 * 4;
+       while (glx (p + 4) && p < adf->block + adf->blocksize - 27) {
+           TCHAR *fname;
+           int i;
+           int align;
+
+           memset (&zai, 0, sizeof zai);
+           zai.flags = glx (p + 8) ^ 0x0f;
+           s = p + (sfs2 ? 27 : 25);
+           fname = au (s);
+           i = 0;
+           while (*s) {
+               s++;
+               i++;
+           }
+           s++;
+           i++;
+           if (*s)
+               zai.comment = au (s);
+           while (*s) {
+               s++;
+               i++;
+           }
+           s++;
+           i++;
+           i += sfs2 ? 27 : 25;
+           align = i & 1;
+
+           name2[0] = 0;
+           if (name[0]) {
+               TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
+               _tcscpy (name2, name);
+               _tcscat (name2, sep);
+           }
+           _tcscat (name2, fname);
+           zai.name = name2;
+           if (sfs2)
+               zai.t = glx (p + 22) - diff2;
+           else
+               zai.t = glx (p + 20) - diff;
+           if (p[sfs2 ? 26 : 24] & 0x80) { // dir
+               struct znode *znnew = zvolume_adddir_abs (zv, &zai);
+               int newblock = glx (p + 16);
+               if (newblock) {
+                   znnew->offset = block;
+                   recursesfs (znnew, newblock, name2, sfs2);
+               }
+               if (!adf_read_block (adf, block))
+                   return;
+           } else {
+               struct znode *znnew;
+               if (sfs2) {
+                   uae_u64 b1 = p[16];
+                   uae_u64 b2 = p[17];
+                   zai.size = (b1 << 40) | (b2 << 32) | glx (p + 18) ;
+               } else {
+                   zai.size = glx (p + 16);
+               }
+               znnew = zvolume_addfile_abs (zv, &zai);
+               znnew->offset = block;
+               znnew->offset2 = p - adf->block;
+           }
+           xfree (zai.comment);
+           xfree (fname);
+           p += i + align;
+       }
+       block = gl (adf, 12 + 4);
+    }
+
+}
+
+struct zvolume *archive_directory_adf (struct znode *parent, struct zfile *z)
 {
     struct zvolume *zv;
     struct adfhandle *adf;
-    TCHAR *volname;
+    TCHAR *volname = NULL;
     TCHAR name[MAX_DPATH];
+    int gotroot = 0;
 
     adf = xcalloc (sizeof (struct adfhandle), 1);
     zfile_fseek (z, 0, SEEK_END);
@@ -1050,81 +1165,285 @@ struct zvolume *archive_directory_adf (struct zfile *z)
     zfile_fseek (z, 0, SEEK_SET);
 
     adf->blocksize = 512;
+    if (parent && parent->offset2) {
+       if (parent->offset2 == 1024 || parent->offset2 == 2048 || parent->offset2 == 4096 || parent->offset2 == 8192 ||
+           parent->offset2 == 16384 || parent->offset2 == 32768 || parent->offset2 == 65536) {
+           adf->blocksize = parent->offset2;
+           gotroot = 1;
+       }
+    }
+
     adf->highblock = adf->size / adf->blocksize;
     adf->z = z;
 
-    if (!adf_read_block (adf, 0)) {
-       xfree (adf);
-       return NULL;
-    }
+    if (!adf_read_block (adf, 0))
+       goto fail;
     adf->dostype = gl (adf, 0);
 
-    adf->rootblock = ((adf->size / 512) - 1 + 2) / 2;
-    for (;;) {
-       if (!adf_read_block (adf, adf->rootblock)) {
-           xfree (adf);
-           return NULL;
+    if ((adf->dostype & 0xffffff00) == 'DOS\0') {
+       int bs = adf->blocksize;
+        int res;
+
+        adf->rootblock = ((adf->size / bs) - 1 + 2) / 2;
+       if (!gotroot) {
+           for (res = 2; res >= 1; res--) {
+               for (bs = 512; bs < 65536; bs <<= 1) {
+                   adf->blocksize = bs;
+                   adf->rootblock = ((adf->size / bs) - 1 + res) / 2;
+                   if (!adf_read_block (adf, adf->rootblock))
+                       continue;
+                   if (gl (adf, 0) != 2 || gl (adf, bs - 1 * 4) != 1)
+                       continue;
+                   if (dos_checksum (adf->block, bs) != 0)
+                       continue;
+                   gotroot = 1;
+                   break;
+               }
+               if (gotroot)
+                   break;
+           }
        }
-       if (gl (adf, 0) != 2 || gl (adf, 512 - 1 * 4) != 1) {
+       if (!gotroot) {
+           bs = adf->blocksize = 512;
            if (adf->size < 2000000 && adf->rootblock != 880) {
-               adf->rootblock = 880;
-               continue;
+               adf->rootblock = 880;
+               if (gl (adf, 0) != 2 || gl (adf, bs - 1 * 4) != 1)
+                   goto fail;
+               if (dos_checksum (adf->block, bs) != 0)
+                   goto fail;
+               goto fail;
            }
-           xfree (adf);
-           return NULL;
        }
-       break;
-    }
 
-    volname = getBSTR (adf->block + 512 - 20 * 4);
+        if (!adf_read_block (adf, adf->rootblock))
+           goto fail;
+        if (gl (adf, 0) != 2 || gl (adf, bs - 1 * 4) != 1)
+           goto fail;
+       if (dos_checksum (adf->block, adf->blocksize) != 0)
+           goto fail;
+       adf->blocksize = bs;
+        adf->highblock = adf->size / adf->blocksize;
+       volname = getBSTR (adf->block + adf->blocksize - 20 * 4);
+       zv = zvolume_alloc (z, ArchiveFormatADF, NULL, NULL);
+       zv->method = ArchiveFormatADF;
+       zv->handle = adf;
+    
+       name[0] = 0;
+       recurseadf (&zv->root, adf->rootblock, name);
+
+    } else if ((adf->dostype & 0xffffff00) == 'SFS\0') {
+
+       uae_u16 version, sfs2;
+
+       for (;;) {
+           for (;;) {
+               version = gl (adf, 12) >> 16;
+               sfs2 = version > 3;
+               if (version > 4)
+                   break;
+               adf->rootblock = gl (adf, 104);
+               if (!adf_read_block (adf, adf->rootblock))
+                   break;
+               if (gl (adf, 0) != 'OBJC')
+                   break;
+               if (sfs_checksum (adf->block, adf->blocksize, sfs2))
+                   break;
+               adf->rootblock = gl (adf, 40);
+               if (!adf_read_block (adf, adf->rootblock))
+                   break;
+               if (gl (adf, 0) != 'OBJC')
+                   break;
+               if (sfs_checksum (adf->block, adf->blocksize, sfs2))
+                   break;
+               gotroot = 1;
+               break;
+           }
+           if (gotroot)
+               break;
+           adf->blocksize <<= 1;
+           if (adf->blocksize == 65536)
+               break;
+       }
+       if (!gotroot)
+           goto fail;
+
+       zv = zvolume_alloc (z, ArchiveFormatADF, NULL, NULL);
+       zv->method = ArchiveFormatADF;
+       zv->handle = adf;
+
+       name[0] = 0;
+       recursesfs (&zv->root, adf->rootblock, name, version > 3);
+
+    } else {
+       goto fail;
+    }
 
-    zv = zvolume_alloc (z, ArchiveFormatADF, NULL, NULL);
-    zv->method = ArchiveFormatADF;
-    zv->handle = adf;
 
-    name[0] = 0;
-    recurseadf (&zv->root, adf->rootblock, name);
+    xfree (volname);
     return zv;
+fail:
+    xfree (adf);
+    return NULL;
 }
 
+struct sfsblock
+{
+    int block;
+    int length;
+};
+
+static int sfsfindblock (struct adfhandle *adf, int btree, int theblock, struct sfsblock **sfsb, int *sfsblockcnt, int *sfsmaxblockcnt, int sfs2)
+{
+    int nodecount, isleaf, nodesize;
+    int i;
+    uae_u8 *p;
+
+    if (!btree)
+       return 0;
+    if (!adf_read_block (adf, btree))
+        return 0;
+    if (memcmp (adf->block, "BNDC", 4))
+        return 0;
+    nodecount = gwx (adf->block + 12);
+    isleaf = adf->block[14];
+    nodesize = adf->block[15];
+    p = adf->block + 16;
+    for (i = 0; i < nodecount; i++) {
+       if (isleaf) {
+           uae_u32 key = glx (p);
+           uae_u32 next = glx (p + 4);
+           uae_u32 prev = glx (p + 8);
+           uae_u32 blocks;
+           if (sfs2)
+               blocks = glx (p + 12);
+           else
+               blocks = gwx (p + 12);
+           if (key == theblock) {
+               struct sfsblock *sb;
+               if (*sfsblockcnt >= *sfsmaxblockcnt) {
+                   *sfsmaxblockcnt += 100;
+                   *sfsb = realloc (*sfsb, (*sfsmaxblockcnt) * sizeof (struct sfsblock));
+               }
+               sb = *sfsb + (*sfsblockcnt);
+               sb->block = key;
+               sb->length = blocks;
+               (*sfsblockcnt)++;
+               return next;
+           }
+       } else {
+           uae_u32 key = glx (p);
+           uae_u32 data = glx (p + 4);
+           int newblock = sfsfindblock (adf, data, theblock, sfsb, sfsblockcnt, sfsmaxblockcnt, sfs2);
+           if (newblock)
+               return newblock;
+           if (!adf_read_block (adf, btree))
+               return 0;
+           if (memcmp (adf->block, "BNDC", 4))
+               return 0;
+       }
+        p += nodesize;
+    }
+    return 0;
+}
+
+
 struct zfile *archive_access_adf (struct znode *zn)
 {
-    struct zfile *z;
-    int block, root, ffs;
+    struct zfile *z = NULL;
+    int root, ffs;
     struct adfhandle *adf = zn->volume->handle;
-    int size;
+    int size, bs;
     int i;
     uae_u8 *dst;
 
     size = zn->size;
+    bs = adf->blocksize;
     z = zfile_fopen_empty (zn->volume->archive, zn->fullname, size);
     if (!z)
        return NULL;
-    ffs = adf->dostype & 1;
-    root = zn->offset;
-    dst = z->data;
-    for (;;) {
-       adf_read_block (adf, root);
-       for (i = 128 - 51; i >= 6; i--) {
-           int bsize = ffs ? 512 : 488;
-           block = gl (adf, i * 4);
-           if (size < bsize)
+
+    if ((adf->dostype & 0xffffff00) == 'DOS\0') {
+
+       ffs = adf->dostype & 1;
+       root = zn->offset;
+       dst = z->data;
+       for (;;) {
+           adf_read_block (adf, root);
+           for (i = bs / 4 - 51; i >= 6; i--) {
+               int bsize = ffs ? bs : bs - 24;
+               int block = gl (adf, i * 4);
+               if (size < bsize)
+                   bsize = size;
+               if (ffs)
+                   zfile_fseek (adf->z, block * adf->blocksize, SEEK_SET);
+               else
+                   zfile_fseek (adf->z, block * adf->blocksize + 24, SEEK_SET);
+               zfile_fread (dst, bsize, 1, adf->z);
+               size -= bsize;
+               dst += bsize;
+               if (size <= 0)
+                   break;
+           }
+           if (size <= 0)
+               break;
+           root = gl (adf, bs - 2 * 4);
+       }
+    } else if ((adf->dostype & 0xffffff00) == 'SFS\0') {
+
+       struct sfsblock *sfsblocks;
+       int sfsblockcnt, sfsmaxblockcnt, i;
+       int bsize;
+       int block = zn->offset;
+       int dblock;
+       int btree, version, sfs2;
+       uae_u8 *p;
+
+       if (!adf_read_block (adf, 0))
+           goto end;
+       btree = glx (adf->block + 108);
+       version = gwx (adf->block + 12);
+       sfs2 = version > 3;
+
+       if (!adf_read_block (adf, block))
+           goto end;
+       p = adf->block + zn->offset2;
+       dblock = glx (p + 12);
+
+       sfsblockcnt = 0;
+       sfsmaxblockcnt = 0;
+       sfsblocks = NULL;
+       if (size > 0) {
+           int nextblock = dblock;
+           while (nextblock) {
+               nextblock = sfsfindblock (adf, btree, nextblock, &sfsblocks, &sfsblockcnt, &sfsmaxblockcnt, sfs2);
+           }
+       }
+
+       bsize = 0;
+       for (i = 0; i < sfsblockcnt; i++)
+           bsize += sfsblocks[i].length * adf->blocksize;
+       if (bsize < size)
+           write_log (L"SFS extracting error, %s size mismatch %d<%d\n", z->name, bsize, size);
+
+       dst = z->data;
+        block = zn->offset;
+       for (i = 0; i < sfsblockcnt; i++) {
+           block = sfsblocks[i].block;
+           bsize = sfsblocks[i].length * adf->blocksize;
+           zfile_fseek (adf->z, block * adf->blocksize, SEEK_SET);
+           if (bsize > size)
                bsize = size;
-           if (ffs)
-               zfile_fseek (adf->z, block * adf->blocksize, SEEK_SET);
-           else
-               zfile_fseek (adf->z, block * adf->blocksize + (512 - 488), SEEK_SET);
            zfile_fread (dst, bsize, 1, adf->z);
-           size -= bsize;
            dst += bsize;
-           if (size <= 0)
-               break;
+           size -= bsize; 
        }
-       if (size <= 0)
-           break;
-       root = gl (adf, 512 - 2 * 4);
+
+       xfree (sfsblocks);
     }
     return z;
+end:
+    zfile_fclose (z);
+    return NULL;
 }
 
 static void archive_close_adf (void *v)
@@ -1175,10 +1494,10 @@ struct zvolume *archive_directory_rdb (struct zfile *z)
        struct znode *zn;
         struct zarchive_info zai;
        TCHAR tmp[MAX_DPATH];
-       int surf, spt, lowcyl, highcyl, reserved;
+       int surf, spt, spb, lowcyl, highcyl, reserved;
        int size, block, blocksize, rootblock;
        uae_u8 *p;
-       TCHAR comment[81], *com;
+       TCHAR comment[81], *dos;
 
        if (partnum == 0)
            partblock = rl (buf + 28);
@@ -1194,31 +1513,37 @@ struct zvolume *archive_directory_rdb (struct zfile *z)
 
        p = buf + 128 - 16;
        surf = rl (p + 28);
+       spb = rl (p + 32);
        spt = rl (p + 36);
        reserved = rl (p + 40);
        lowcyl = rl (p + 52);
        highcyl = rl (p + 56);
-       blocksize = rl (p + 20) * 4;
+       blocksize = rl (p + 20) * 4 * spb;
        block = lowcyl * surf * spt;
 
        size = (highcyl - lowcyl + 1) * surf * spt;
        size *= blocksize;
 
-       rootblock = ((size / blocksize) - 1 + 2) / 2;
+       dos = tochar (buf + 192, 4);
+
+       if (!memcmp (dos, L"DOS", 3))
+           rootblock = ((size / blocksize) - 1 + 2) / 2;
+       else
+           rootblock = 0;
 
        devname = getBSTR (buf + 36);
        _stprintf (tmp, L"%s.hdf", devname);
        memset (&zai, 0, sizeof zai);
-       com = tochar (buf + 192, 4);
        _stprintf (comment, L"FS=%s LO=%d HI=%d HEADS=%d SPT=%d RES=%d BLOCK=%d ROOT=%d",
-           com, lowcyl, highcyl, surf, spt, reserved, blocksize, rootblock);
+           dos, lowcyl, highcyl, surf, spt, reserved, blocksize, rootblock);
        zai.comment = comment;
-       xfree (com);
+       xfree (dos);
         zai.name = tmp;
        zai.size = size;
        zai.flags = -1;
        zn = zvolume_addfile_abs (zv, &zai);
        zn->offset = partblock;
+       zn->offset2 = blocksize; // örp?
     }
 
     zv->method = ArchiveFormatRDB;