imported winuaesrc1600b23.zip

This commit is contained in:
Toni Wilen 2009-04-10 14:01:29 +03:00
parent adc44cc27a
commit 04400fb392
13 changed files with 675 additions and 301 deletions

View 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

View 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);
@ -280,7 +282,7 @@
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);
@ -393,7 +395,7 @@
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);

View 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;

View 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);

View 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);

View 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,150 +1995,6 @@ void release_keys (void)
}
}
static int refresh_kb (LPDIRECTINPUTDEVICE8 lpdi, int num)
{
HRESULT hr;
int i;
uae_u8 kc[256];
hr = IDirectInputDevice8_GetDeviceState (lpdi, sizeof (kc), kc);
if (SUCCEEDED (hr)) {
for (i = 0; i < sizeof (kc); i++) {
if (i == 0x80) /* USB KB led causes this, better ignore it */
continue;
if (kc[i] & 0x80)
kc[i] = 1;
else
kc[i] = 0;
if (kc[i] != di_keycodes[num][i]) {
write_log (L"%02X -> %d\n", i, kc[i]);
di_keycodes[num][i] = kc[i];
my_kbd_handler (num, i, kc[i]);
}
}
} else if (hr == DIERR_INPUTLOST) {
acquire (lpdi, L"keyboard");
IDirectInputDevice8_Poll (lpdi);
return 0;
}
IDirectInputDevice8_Poll (lpdi);
return 1;
}
static void read_kb (void)
{
DIDEVICEOBJECTDATA didod[DI_KBBUFFER];
DWORD elements;
HRESULT hr;
LPDIRECTINPUTDEVICE8 lpdi;
int i, j;
int istest = inputdevice_istest ();
if (IGNOREEVERYTHING)
return;
update_leds ();
for (i = 0; i < MAX_INPUT_DEVICES; i++) {
struct didata *did = &di_keyboard[i];
if (!did->acquired)
continue;
lpdi = did->lpdi;
if (!lpdi)
continue;
if (kb_do_refresh & (1 << i)) {
if (!refresh_kb (lpdi, i))
continue;
kb_do_refresh &= ~(1 << i);
}
elements = DI_KBBUFFER;
hr = IDirectInputDevice8_GetDeviceData (lpdi, sizeof(DIDEVICEOBJECTDATA), didod, &elements, 0);
if ((SUCCEEDED (hr) || hr == DI_BUFFEROVERFLOW) && isfocus () > 0) {
if (did->superdevice && (normalkb || rawkb))
continue;
for (j = 0; j < elements; j++) {
int scancode = didod[j].dwOfs;
int pressed = (didod[j].dwData & 0x80) ? 1 : 0;
//write_log (L"%d: %02X %d\n", j, scancode, pressed);
if (!istest)
scancode = keyhack (scancode, pressed, i);
if (scancode < 0)
continue;
di_keycodes[i][scancode] = pressed;
if (istest) {
inputdevice_do_keyboard (scancode, pressed);
} else {
if (stopoutput == 0)
my_kbd_handler (i, scancode, pressed);
}
}
} else if (hr == DIERR_INPUTLOST) {
acquire (lpdi, L"keyboard");
kb_do_refresh |= 1 << i;
} else if (did->acquired && hr == DIERR_NOTACQUIRED) {
acquire (lpdi, L"keyboard");
}
IDirectInputDevice8_Poll (lpdi);
}
#ifdef CATWEASEL
{
uae_u8 kc;
if (stopoutput == 0 && catweasel_read_keyboard (&kc))
inputdevice_do_keyboard (kc & 0x7f, kc & 0x80);
}
#endif
}
void wait_keyrelease (void)
{
stopoutput++;
#if 0
int i, j, maxcount = 10, found;
while (maxcount-- > 0) {
read_kb ();
found = 0;
for (j = 0; j < MAX_INPUT_DEVICES; j++) {
for (i = 0; i < MAX_KEYCODES; i++) {
if (di_keycodes[j][i])
found = 1;
}
}
if (!found)
break;
sleep_millis (10);
}
#endif
release_keys ();
#if 0
for (;;) {
int ok = 0, nok = 0;
for (i = 0; i < MAX_INPUT_DEVICES; i++) {
struct didata *did = &di_mouse[i];
DIMOUSESTATE dis;
LPDIRECTINPUTDEVICE8 lpdi = did->lpdi;
HRESULT hr;
int j;
if (!lpdi)
continue;
nok++;
hr = IDirectInputDevice8_GetDeviceState (lpdi, sizeof (dis), &dis);
if (SUCCEEDED (hr)) {
for (j = 0; j < 4; j++) {
if (dis.rgbButtons[j] & 0x80) break;
}
if (j == 4) ok++;
} else {
ok++;
}
}
if (ok == nok) break;
sleep_millis (10);
}
#endif
stopoutput--;
}
static int acquire_kb (int num, int flags)
{
@ -2213,6 +2071,155 @@ static void unacquire_kb (int num)
}
}
static int refresh_kb (LPDIRECTINPUTDEVICE8 lpdi, int num)
{
HRESULT hr;
int i;
uae_u8 kc[256];
hr = IDirectInputDevice8_GetDeviceState (lpdi, sizeof (kc), kc);
if (SUCCEEDED (hr)) {
for (i = 0; i < sizeof (kc); i++) {
if (i == 0x80) /* USB KB led causes this, better ignore it */
continue;
if (kc[i] & 0x80)
kc[i] = 1;
else
kc[i] = 0;
if (kc[i] != di_keycodes[num][i]) {
write_log (L"%02X -> %d\n", i, kc[i]);
di_keycodes[num][i] = kc[i];
my_kbd_handler (num, i, kc[i]);
}
}
} else if (hr == DIERR_INPUTLOST) {
acquire_kb (num, 0);
IDirectInputDevice8_Poll (lpdi);
return 0;
}
IDirectInputDevice8_Poll (lpdi);
return 1;
}
static void read_kb (void)
{
DIDEVICEOBJECTDATA didod[DI_KBBUFFER];
DWORD elements;
HRESULT hr;
LPDIRECTINPUTDEVICE8 lpdi;
int i, j;
int istest = inputdevice_istest ();
if (IGNOREEVERYTHING)
return;
update_leds ();
for (i = 0; i < MAX_INPUT_DEVICES; i++) {
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;
if (kb_do_refresh & (1 << i)) {
if (!refresh_kb (lpdi, i))
continue;
kb_do_refresh &= ~(1 << i);
}
elements = DI_KBBUFFER;
hr = IDirectInputDevice8_GetDeviceData (lpdi, sizeof(DIDEVICEOBJECTDATA), didod, &elements, 0);
if ((SUCCEEDED (hr) || hr == DI_BUFFEROVERFLOW) && isfocus () > 0) {
if (did->superdevice && (normalkb || rawkb))
continue;
for (j = 0; j < elements; j++) {
int scancode = didod[j].dwOfs;
int pressed = (didod[j].dwData & 0x80) ? 1 : 0;
//write_log (L"%d: %02X %d\n", j, scancode, pressed);
if (!istest)
scancode = keyhack (scancode, pressed, i);
if (scancode < 0)
continue;
di_keycodes[i][scancode] = pressed;
if (istest) {
inputdevice_do_keyboard (scancode, pressed);
} else {
if (stopoutput == 0)
my_kbd_handler (i, scancode, pressed);
}
}
} else if (hr == DIERR_INPUTLOST) {
acquire_kb (i, 0);
kb_do_refresh |= 1 << i;
} 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);
}
#endif
}
void wait_keyrelease (void)
{
stopoutput++;
#if 0
int i, j, maxcount = 10, found;
while (maxcount-- > 0) {
read_kb ();
found = 0;
for (j = 0; j < MAX_INPUT_DEVICES; j++) {
for (i = 0; i < MAX_KEYCODES; i++) {
if (di_keycodes[j][i])
found = 1;
}
}
if (!found)
break;
sleep_millis (10);
}
#endif
release_keys ();
#if 0
for (;;) {
int ok = 0, nok = 0;
for (i = 0; i < MAX_INPUT_DEVICES; i++) {
struct didata *did = &di_mouse[i];
DIMOUSESTATE dis;
LPDIRECTINPUTDEVICE8 lpdi = did->lpdi;
HRESULT hr;
int j;
if (!lpdi)
continue;
nok++;
hr = IDirectInputDevice8_GetDeviceState (lpdi, sizeof (dis), &dis);
if (SUCCEEDED (hr)) {
for (j = 0; j < 4; j++) {
if (dis.rgbButtons[j] & 0x80) break;
}
if (j == 4) ok++;
} else {
ok++;
}
}
if (ok == nok) break;
sleep_millis (10);
}
#endif
stopoutput--;
}
static int get_kb_flags (int kb)
{
return 0;

View 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);

View 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""

View 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;

View 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

View File

@ -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)
*/

54
zfile.c
View File

@ -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);

View 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 (gl (adf, 0) != 2 || gl (adf, 512 - 1 * 4) != 1) {
if (adf->size < 2000000 && adf->rootblock != 880) {
adf->rootblock = 880;
continue;
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;
}
xfree (adf);
return NULL;
}
break;
if (!gotroot) {
bs = adf->blocksize = 512;
if (adf->size < 2000000 && adf->rootblock != 880) {
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;
}
}
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;
}
volname = getBSTR (adf->block + 512 - 20 * 4);
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)
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 ((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);
}
if (size <= 0)
break;
root = gl (adf, 512 - 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;
zfile_fread (dst, bsize, 1, adf->z);
dst += bsize;
size -= bsize;
}
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;