drv->ddhd = 1;
} else if (size == 18 * 80 * 2 * 512 || size == 18 * 81 * 2 * 512 || size == 18 * 82 * 2 * 512) {
drv->num_secs = 18;
- drv->ddhd = 1;
+ drv->ddhd = 2;
} else if (size == 10 * 80 * 2 * 512 || size == 10 * 81 * 2 * 512 || size == 10 * 82 * 2 * 512) {
drv->num_secs = 10;
- drv->ddhd = 2;
+ drv->ddhd = 1;
} else if (size == 20 * 80 * 2 * 512 || size == 20 * 81 * 2 * 512 || size == 20 * 82 * 2 * 512) {
drv->num_secs = 20;
drv->ddhd = 2;
static void decode_pcdos (drive *drv)
{
- int i;
+ int i, len;
int tr = drv->cyl * 2 + side;
uae_u16 *dstmfmbuf, *mfm2;
uae_u8 secbuf[1000];
crc16 = get_crc16 (secbuf + 56, 3 + 1 + 512);
secbuf[60 + 512] = crc16 >> 8;
secbuf[61 + 512] = crc16 & 0xff;
- memset(secbuf + 512 + 62, 0x4e, (tracklen / 2 - 96) / drv->num_secs - 574 / drv->ddhd);
+ len = (tracklen / 2 - 96) / drv->num_secs - 574 / drv->ddhd;
+ if (len > 0)
+ memset(secbuf + 512 + 62, 0x4e, len);
dstmfmbuf = mfmcoder (secbuf, mfm2, 60 + 512 + 2 + 76 / drv->ddhd);
mfm2[12] = 0x4489;
mfm2[13] = 0x4489;
uae_u8 tmp[8];
uae_u8 cyl, head, size;
- cyl = mfmdecode(&mbuf, shift);
- head = mfmdecode(&mbuf, shift);
- sector = mfmdecode(&mbuf, shift);
- size = mfmdecode(&mbuf, shift);
- crc = (mfmdecode(&mbuf, shift) << 8) | mfmdecode(&mbuf, shift);
+ cyl = mfmdecode (&mbuf, shift);
+ head = mfmdecode (&mbuf, shift);
+ sector = mfmdecode (&mbuf, shift);
+ size = mfmdecode (&mbuf, shift);
+ crc = (mfmdecode (&mbuf, shift) << 8) | mfmdecode (&mbuf, shift);
tmp[0] = 0xa1; tmp[1] = 0xa1; tmp[2] = 0xa1; tmp[3] = mark;
tmp[4] = cyl; tmp[5] = head; tmp[6] = sector; tmp[7] = size;
- if (get_crc16(tmp, 8) != crc || cyl != drv->cyl || head != side || size != 2 || sector < 1 || sector > drv->num_secs) {
+ if (get_crc16 (tmp, 8) != crc || cyl != drv->cyl || head != side || size != 2 || sector < 1 || sector > drv->num_secs) {
write_log (L"PCDOS: track %d, corrupted sector header\n", drv->cyl * 2 + side);
return 1;
}
if (sector < 0)
continue;
for (i = 0; i < 512; i++)
- secbuf[i + 4] = mfmdecode(&mbuf, shift);
- crc = (mfmdecode(&mbuf, shift) << 8) | mfmdecode(&mbuf, shift);
- if (get_crc16(secbuf, 3 + 1 + 512) != crc) {
+ secbuf[i + 4] = mfmdecode (&mbuf, shift);
+ crc = (mfmdecode (&mbuf, shift) << 8) | mfmdecode (&mbuf, shift);
+ if (get_crc16 (secbuf, 3 + 1 + 512) != crc) {
write_log (L"PCDOS: track %d, sector %d data checksum error\n",
drv->cyl * 2 + side, sector + 1);
continue;
drive *drv = &floppy[i];
if (!(disabled & (1 << i))) {
console_out_f (L"Drive %d: motor %s cylinder %2d sel %s %s mfmpos %d/%d\n",
- i, drv->motoroff ? "off" : " on", drv->cyl, (selected & (1 << i)) ? "no" : "yes",
- drive_writeprotected(drv) ? "ro" : "rw", drv->mfmpos, drv->tracklen);
+ i, drv->motoroff ? L"off" : L" on", drv->cyl, (selected & (1 << i)) ? L"no" : L"yes",
+ drive_writeprotected(drv) ? L"ro" : L"rw", drv->mfmpos, drv->tracklen);
w = word;
for (j = 0; j < 15; j++) {
console_out_f (L"%04X ", w);
#include "sysconfig.h"
#include "sysdeps.h"
+#include "crc32.h"
+
#define MFMMASK 0x55555555
static uae_u32 getmfmlong (uae_u16 * mbuf)
{
#define FLOPPY_WRITE_LEN 6250
-static int drive_write_adf_amigados (uae_u16 *mbuf, uae_u16 *mend, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track)
+static int drive_write_adf_amigados (uae_u16 *mbuf, uae_u16 *mend, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track, int *outsize)
{
int i;
uae_u32 odd, even, chksum, id, dlong;
uae_u8 secbuf[544];
mend -= (4 + 16 + 8 + 512);
+ *outsize = 11 * 512;
for (;;) {
int trackoffs;
}
/* search and align to 0x4489 WORDSYNC markers */
-int isamigatrack(uae_u16 *amigamfmbuffer, uae_u8 *mfmdata, int len, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track)
+int isamigatrack(uae_u16 *amigamfmbuffer, uae_u8 *mfmdata, int len, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track, int *outsize)
{
uae_u16 *dst = amigamfmbuffer;
int shift, syncshift, sync;
uae_u32 l;
uae_u16 w;
+ *outsize = 11 * 512;
len *= 8;
sync = syncshift = shift = 0;
while (len--) {
}
}
if (sync)
- return drive_write_adf_amigados (amigamfmbuffer, dst, writebuffer, writebuffer_ok, track);
+ return drive_write_adf_amigados (amigamfmbuffer, dst, writebuffer, writebuffer_ok, track, outsize);
return -1;
-}
\ No newline at end of file
+}
+
+static uae_u16 getmfmword (uae_u16 *mbuf, int shift)
+{
+ return (mbuf[0] << shift) | (mbuf[1] >> (16 - shift));
+}
+static uae_u8 mfmdecode (uae_u16 **mfmp, int shift)
+{
+ uae_u16 mfm = getmfmword (*mfmp, shift);
+ uae_u8 out = 0;
+ int i;
+
+ (*mfmp)++;
+ mfm &= 0x5555;
+ for (i = 0; i < 8; i++) {
+ out >>= 1;
+ if (mfm & 1)
+ out |= 0x80;
+ mfm >>= 2;
+ }
+ return out;
+}
+
+static int drive_write_adf_pc (uae_u16 *mbuf, uae_u16 *mend, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track, int *outsize)
+{
+ int sectors, shift, sector, i;
+ uae_u8 mark;
+ uae_u8 secbuf[3 + 1 + 512];
+ uae_u16 crc;
+ int mfmcount;
+
+ secbuf[0] = secbuf[1] = secbuf[2] = 0xa1;
+ secbuf[3] = 0xfb;
+
+ sectors = 0;
+ sector = -1;
+ shift = 0;
+ mend -= (4 + 16 + 8 + 512);
+ mfmcount = 0;
+ for (;;) {
+
+ *outsize = sectors * 512;
+ while (getmfmword (mbuf, shift) != 0x4489) {
+ if (mbuf >= mend) {
+ if (sectors >= 7) {
+ *outsize = sectors * 512;
+ return 0;
+ }
+ write_log (L"* track %d, unexpected end of data\n", track);
+ return 1;
+ }
+ shift++;
+ if (shift == 16) {
+ shift = 0;
+ mbuf++;
+ }
+ }
+ mfmcount++;
+ while (getmfmword (mbuf, shift) == 0x4489) {
+ mfmcount++;
+ if (mbuf >= mend) {
+ if (sectors >= 7) {
+ *outsize = sectors * 512;
+ return 0;
+ }
+ return 1;
+ }
+ mbuf++;
+ }
+ mfmcount = 0;
+ mark = mfmdecode (&mbuf, shift);
+ if (mark == 0xfe) {
+ uae_u8 tmp[8];
+ uae_u8 cyl, head, size;
+
+ cyl = mfmdecode (&mbuf, shift);
+ head = mfmdecode (&mbuf, shift);
+ sector = mfmdecode (&mbuf, shift);
+ size = mfmdecode (&mbuf, shift);
+ crc = (mfmdecode (&mbuf, shift) << 8) | mfmdecode (&mbuf, shift);
+
+ tmp[0] = 0xa1; tmp[1] = 0xa1; tmp[2] = 0xa1; tmp[3] = mark;
+ tmp[4] = cyl; tmp[5] = head; tmp[6] = sector; tmp[7] = size;
+ if (get_crc16 (tmp, 8) != crc || cyl != track / 2 || head != (track & 1) || size != 2 || sector < 1 || sector > 20) {
+ write_log (L"PCDOS: track %d, corrupted sector header\n", track);
+ continue;
+ }
+ sector--;
+ continue;
+ }
+ if (mark != 0xfb) {
+ write_log (L"PCDOS: track %d: unknown address mark %02X\n", track, mark);
+ continue;
+ }
+ if (sector < 0)
+ continue;
+ for (i = 0; i < 512; i++)
+ secbuf[i + 4] = mfmdecode (&mbuf, shift);
+ sectors++;
+ memcpy (writebuffer + sector * 512, secbuf + 4, 512);
+ sector = 0;
+ crc = (mfmdecode (&mbuf, shift) << 8) | mfmdecode (&mbuf, shift);
+ if (get_crc16 (secbuf, 3 + 1 + 512) != crc) {
+ write_log (L"PCDOS: track %d, sector %d data checksum error\n",
+ track, sector + 1);
+ continue;
+ }
+
+ }
+
+}
+
+int ispctrack(uae_u16 *amigamfmbuffer, uae_u8 *mfmdata, int len, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track, int *outsize)
+{
+ int i;
+ for (i = 0; i < len / 2; i++)
+ amigamfmbuffer[i] = mfmdata[i * 2 + 1] | (mfmdata[i * 2 + 0] << 8);
+ i = drive_write_adf_pc (amigamfmbuffer, amigamfmbuffer + len / 2, writebuffer, writebuffer_ok, track, outsize);
+ if (*outsize < 9 * 512)
+ *outsize = 9 * 512;
+ return i;
+}
-int isamigatrack (uae_u16 *amigamfmbuffer, uae_u8 *mfmdata, int len, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track);
+int isamigatrack (uae_u16 *amigamfmbuffer, uae_u8 *mfmdata, int len, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track, int *outsize);
+int ispctrack (uae_u16 *amigamfmbuffer, uae_u8 *mfmdata, int len, uae_u8 *writebuffer, uae_u8 *writebuffer_ok, int track, int *outsize);
#define UAEMAJOR 1
#define UAEMINOR 6
-#define UAESUBREV 0
+#define UAESUBREV 1
typedef enum { KBD_LANG_US, KBD_LANG_DK, KBD_LANG_DE, KBD_LANG_SE, KBD_LANG_FR, KBD_LANG_IT, KBD_LANG_ES } KbdLang;
TCHAR *mode;
FILE *f;
uae_u8 *data;
- uae_u64 size;
- uae_u64 seek;
+ uae_s64 size;
+ uae_s64 seek;
int deleteafterclose;
int textmode;
struct zfile *next;
int zfdmask;
+ struct zfile *parent;
+ uae_u64 offset;
+ int opencnt;
};
#define ZNODE_FILE 0
struct znode *vfile; // points to real file when this node is virtual directory
TCHAR *name;
TCHAR *fullname;
- uae_u64 size;
+ uae_s64 size;
struct zfile *f;
TCHAR *comment;
int flags;
struct znode *last;
struct znode *parentz;
struct zvolume *parent;
- uae_u64 size;
+ uae_s64 size;
unsigned int blocks;
unsigned int id;
- uae_u64 archivesize;
+ uae_s64 archivesize;
unsigned int method;
TCHAR *volumename;
int zfdmask;
struct zarchive_info
{
const TCHAR *name;
- uae_u64 size;
+ uae_s64 size;
int flags;
TCHAR *comment;
time_t t;
#define ArchiveFormatAA 'aa ' // method only
#define ArchiveFormatADF 'DOS '
#define ArchiveFormatRDB 'RDSK'
+#define ArchiveFormatMBR 'MBR '
+#define ArchiveFormatFAT 'FAT '
extern int zfile_is_ignore_ext(const TCHAR *name);
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 zvolume *archive_directory_fat (struct zfile *z);
+extern struct zfile *archive_access_fat (struct znode *zn);
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 int isfat (uae_u8*);
extern void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user, unsigned int id);
extern struct zfile *zfile_fopen (const TCHAR *, const TCHAR *, int mask);
extern struct zfile *zfile_fopen_empty (struct zfile*, const TCHAR *name, uae_u64 size);
extern struct zfile *zfile_fopen_data (const TCHAR *name, uae_u64 size, uae_u8 *data);
+extern struct zfile *zfile_fopen_parent (struct zfile*, const TCHAR*, uae_u64 offset, uae_u64 size);
+
extern int zfile_exists (const TCHAR *name);
extern void zfile_fclose (struct zfile *);
extern uae_s64 zfile_fseek (struct zfile *z, uae_s64 offset, int mode);
#define ZFD_UNPACK 8 //gzip,dms
#define ZFD_RAWDISK 16 //fdi->adf,ipf->adf etc..
#define ZFD_NORMAL (ZFD_ARCHIVE|ZFD_UNPACK)
-#define ZFD_ALL -1
+#define ZFD_ALL 0x0000ffff
+
+#define ZFD_RAWDISK_AMIGA 0x10000
+#define ZFD_RAWDISK_PC 0x200000
#define ZFILE_UNKNOWN 0
#define ZFILE_CONFIGURATION 1
int aspi_allow_all = 0;
static int busses, AspiLoaded;
-static DWORD (*pfnGetASPI32SupportInfo)(void);
-static DWORD (*pfnSendASPI32Command)(LPSRB);
-static BOOL (*pfnGetASPI32Buffer)(PASPI32BUFF);
-static BOOL (*pfnFreeASPI32Buffer)(PASPI32BUFF);
-static BOOL (*pfnTranslateASPI32Address)(PDWORD, PDWORD);
+static DWORD (_cdecl *pfnGetASPI32SupportInfo)(void);
+static DWORD (_cdecl *pfnSendASPI32Command)(LPSRB);
+static BOOL (_cdecl *pfnGetASPI32Buffer)(PASPI32BUFF);
+static BOOL (_cdecl *pfnFreeASPI32Buffer)(PASPI32BUFF);
+static BOOL (_cdecl *pfnTranslateASPI32Address)(PDWORD, PDWORD);
static HANDLE hAspiLib;
static int scanphase;
* Get a pointer to GetASPI32SupportInfo function
* and a pointer to SendASPI32Command function
*/
- pfnGetASPI32SupportInfo = (DWORD(*)(void))GetProcAddress(hAspiLib, "GetASPI32SupportInfo");
- pfnSendASPI32Command = (DWORD(*)(LPSRB))GetProcAddress(hAspiLib, "SendASPI32Command");
+ pfnGetASPI32SupportInfo = (DWORD(_cdecl *)(void))GetProcAddress (hAspiLib, "GetASPI32SupportInfo");
+ pfnSendASPI32Command = (DWORD(_cdecl *)(LPSRB))GetProcAddress (hAspiLib, "SendASPI32Command");
if (pfnGetASPI32SupportInfo == NULL || pfnSendASPI32Command == NULL) {
write_log (L"ASPI: obsolete wnaspi32.dll found\n");
return FALSE;
}
- pfnGetASPI32Buffer = (BOOL(*)(PASPI32BUFF))GetProcAddress(hAspiLib, "GetASPI32Buffer");
- pfnFreeASPI32Buffer = (BOOL(*)(PASPI32BUFF))GetProcAddress(hAspiLib, "FreeASPI32Buffer");
- pfnTranslateASPI32Address = (BOOL(*)(PDWORD, PDWORD))GetProcAddress(hAspiLib, "TranslateASPI32Address");
+ pfnGetASPI32Buffer = (BOOL(_cdecl *)(PASPI32BUFF))GetProcAddress (hAspiLib, "GetASPI32Buffer");
+ pfnFreeASPI32Buffer = (BOOL(_cdecl *)(PASPI32BUFF))GetProcAddress (hAspiLib, "FreeASPI32Buffer");
+ pfnTranslateASPI32Address = (BOOL(_cdecl *)(PDWORD, PDWORD))GetProcAddress (hAspiLib, "TranslateASPI32Address");
/*
* Set AspiLoaded variable
DirectDraw_FillSurface (dxdata.primary, NULL, 0);
}
-extern int vblank_skip;
+extern int vblank_skip, turbo_emulation;
static void flip (void)
{
int result = 0;
HRESULT ddrval = DD_OK;
DWORD flags = DDFLIP_WAIT;
+ if (turbo_emulation)
+ flags |= DDFLIP_NOVSYNC;
if (dxdata.backbuffers == 2) {
DirectDraw_Blit (dxdata.flipping[1], dxdata.flipping[0]);
if (currprefs.gfx_avsync) {
}
}
} else {
- ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags);
+ ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags| DDFLIP_NOVSYNC);
}
} else if(dxdata.backbuffers == 1) {
if (currprefs.gfx_avsync) {
flip ();
recurse--;
}
- } else if(FAILED (ddrval)) {
+ } else if (FAILED (ddrval)) {
write_log (L"IDirectDrawSurface7_Flip: %s\n", DXError (ddrval));
}
}
case ERROR_INVALID_DRIVE:
case ERROR_INVALID_NAME:
case ERROR_PATH_NOT_FOUND:
+ case ERROR_NOT_READY:
+ case ERROR_BAD_UNIT:
return ERROR_OBJECT_NOT_AROUND;
case ERROR_HANDLE_DISK_FULL:
char *s;
buf[0] = 1;
do_put_mem_long ((uae_u32 *)(buf + 1), aino->amigaos_mode);
- s = uacp (aino->nname, currprefs.win32_fscodepage);
+ s = uacp (aino->aname, currprefs.win32_fscodepage);
strncpy (buf + 5, s, 256);
buf[5 + 256] = '\0';
xfree (s);
buf[5 + 2 * 257 + 80] = '\0';
xfree (s);
do_put_mem_long ((uae_u32 *)(buf + 5 + 2 * 257 + 81), winmode);
- _tcsncpy ((TCHAR*)(buf + 604), aino->nname, 256);
+ _tcsncpy ((TCHAR*)(buf + 604), aino->aname, 256);
_tcsncpy ((TCHAR*)(buf + 1118), nn, 256);
aino->has_dbentry = 0;
}
HANDLE h;
WIN32_FIND_DATA fd;
static a_inode dummy;
- TCHAR *s;
tmp1 = build_nname (base->nname, UAEFSDB_BEGINSX);
if (!tmp1)
return NULL;
- s = au (fsdb + offset);
h = FindFirstFile (tmp1, &fd);
if (h != INVALID_HANDLE_VALUE) {
do {
if (read_uaefsdb (base->nname, fd.cFileName, fsdb)) {
+ TCHAR *s = au (fsdb + offset);
if (same_aname (s, aname)) {
int winmode;
FindClose (h);
return &dummy;
return aino_from_buf (base, fsdb, &winmode);
}
+ xfree (s);
}
} while (FindNextFile (h, &fd));
FindClose (h);
}
- xfree (s);
xfree (tmp1);
return NULL;
}
memset (buf, 0xaa, blocksize);
ReadFile (h, buf, blocksize, &outlen, NULL);
if (outlen != blocksize) {
- write_log (L"hd ignored, read error %d!\n", GetLastError());
+ write_log (L"hd ignored, read error %d!\n", GetLastError ());
return 2;
}
if (j == 0 && buf[0] == 0x39 && buf[1] == 0x10 && buf[2] == 0xd3 && buf[3] == 0x12) {
hfd->virtual_size = 0;
hfd->virtual_rdb = NULL;
if (!hfd->cache) {
- write_log (L"VirtualAlloc(%d) failed, error %d\n", CACHE_SIZE, GetLastError());
+ write_log (L"VirtualAlloc(%d) failed, error %d\n", CACHE_SIZE, GetLastError ());
goto end;
}
hfd_log (L"hfd open: '%s'\n", name);
if (h == INVALID_HANDLE_VALUE)
goto end;
if (!DeviceIoControl(h, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &r, NULL))
- write_log (L"WARNING: '%s' FSCTL_ALLOW_EXTENDED_DASD_IO returned %d\n", name, GetLastError());
+ write_log (L"WARNING: '%s' FSCTL_ALLOW_EXTENDED_DASD_IO returned %d\n", name, GetLastError ());
_tcsncpy (hfd->vendor_id, udi->vendor_id, 8);
_tcsncpy (hfd->product_id, udi->product_id, 16);
_tcsncpy (hfd->product_rev, udi->product_rev, 4);
DWORD ret, low, high;
high = 0;
ret = SetFilePointer (h, 0, &high, FILE_END);
- if (ret == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
+ if (ret == INVALID_FILE_SIZE && GetLastError () != NO_ERROR)
goto end;
low = GetFileSize (h, &high);
- if (low == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
+ if (low == INVALID_FILE_SIZE && GetLastError () != NO_ERROR)
goto end;
low &= ~(hfd->blocksize - 1);
hfd->physsize = hfd->virtsize = ((uae_u64)high << 32) | low;
//\r
\r
VS_VERSION_INFO VERSIONINFO\r
- FILEVERSION 1,6,0,0\r
- PRODUCTVERSION 1,6,0,0\r
+ FILEVERSION 1,6,1,0\r
+ PRODUCTVERSION 1,6,1,0\r
FILEFLAGSMASK 0x3fL\r
#ifdef _DEBUG\r
FILEFLAGS 0x1L\r
BLOCK "040904b0"\r
BEGIN\r
VALUE "FileDescription", "WinUAE"\r
- VALUE "FileVersion", "1.6.0"\r
+ VALUE "FileVersion", "1.6.1"\r
VALUE "InternalName", "WinUAE"\r
VALUE "LegalCopyright", "© 1996-2009 under the GNU Public License (GPL)"\r
VALUE "OriginalFilename", "WinUAE.exe"\r
VALUE "ProductName", "WinUAE"\r
- VALUE "ProductVersion", "1.6.0"\r
+ VALUE "ProductVersion", "1.6.1"\r
END\r
END\r
BLOCK "VarFileInfo"\r
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
+ RandomizedBaseAddress="1"
TargetMachine="1"
/>
<Tool
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IncludePath)</IncludePath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
if (c != normalcursor)
return;
}
+ if (active) {
+ if (IsWindowVisible (hAmigaWnd) == FALSE)
+ return;
+ }
if (active < 0)
active = 1;
+
mouseactive = active;
mouseposx = mouseposy = 0;
p->win32_rtgallowscaling = 0;
p->win32_rtgscaleaspectratio = -1;
p->win32_rtgvblankrate = 0;
- p->win32_fscodepage = 1252;
+ p->win32_fscodepage = 0;
}
if (type == 1 || type == 0) {
p->win32_uaescsimode = get_aspi (p->win32_uaescsimode);
#define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100)
#define GETBDD(x) ((x) % 100)
-#define WINUAEPUBLICBETA 0
+#define WINUAEPUBLICBETA 1
-#define WINUAEBETA L""
-#define WINUAEDATE MAKEBD(2009, 5, 21)
+#define WINUAEBETA L"Beta 1"
+#define WINUAEDATE MAKEBD(2009, 5, 30)
#define WINUAEEXTRA L""
#define WINUAEREV L""
static int create_windows_2 (void)
{
+ static int firstwindow = 1;
int dxfs = currentmode->flags & (DM_DX_FULLSCREEN);
int d3dfs = currentmode->flags & (DM_D3D_FULLSCREEN);
int fsw = currentmode->flags & (DM_W_FULLSCREEN);
SetCursorPos (x + w / 2, y + h / 2);
addnotifications (hAmigaWnd, FALSE);
if (hMainWnd != hAmigaWnd) {
- ShowWindow (hMainWnd, SW_SHOWNORMAL);
+ ShowWindow (hMainWnd, firstwindow ? SW_SHOWDEFAULT : SW_SHOWNORMAL);
UpdateWindow (hMainWnd);
}
- ShowWindow (hAmigaWnd, SW_SHOWNORMAL);
+ ShowWindow (hAmigaWnd, firstwindow ? SW_SHOWDEFAULT : SW_SHOWNORMAL);
UpdateWindow (hAmigaWnd);
+ firstwindow = 0;
return 1;
}
if (drvdrag) {
type = ZFILE_DISKIMAGE;
- } else if (zip) {
+ } else if (zip || harddrive) {
do_filesys_insert (file);
continue;
}
+Beta 1
+
+- development PC updated to Intel Core i7 based. (Asus P6T DeluxeV2,
+ i7 920 2.66GHz CPU @ 3.7GHz, 3x2G 1866MHz RAM)
+- ASPI crash fixed (calling convention mismatch.. I didn't test and
+ only assumed previous fix would be the only problem left..)
+- filesys default codepage changed to default ansi page (1252 breaks
+ many non-european characters)
+- added more directory harddrive error codes to Windows->Amiga code
+ translation table (unit not ready, bad unit)
+- directory harddrive Windows illegal character handling was broken
+- do not capture mouse at startup if window is hidden/minimized
+- archive dragging to HD-led really mounts it as a harddrive, even
+ if it contains only disk images
+- 1760k HD and 10 sector DD PC formatted had switched internal
+ DD/HD flag (=above image types didn't work)
+- FAT12 formatted images supported as a harddrive (uaeunp feature)
+- turbo/warp mode in fullscreen mode wasn't as fast as possible
+
Final 1.6.0
- filter mode PAL aspect ratio corrected (~5% difference) if keep
ok = 1;
}
if (!ok) {
- _tprintf (L"UAE unpacker uaeunp 0.5c by Toni Wilen (c)2009\n");
+ _tprintf (L"UAE unpacker uaeunp 0.6 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");
_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/SFS/SFS2), DMS, encrypted DMS, IPF, FDI, DSQ, WRP\n");
+ _tprintf (L" ADF, HDF, DMS, encrypted DMS, IPF, FDI, DSQ, WRP\n");
+ _tprintf (L"Supported filesystems:\n");
+ _tprintf (L" OFS, FFS, SFS, SFS2 and FAT12\n");
_tprintf (L"Supported archive formats:\n");
_tprintf (L" 7ZIP, LHA, LZX, RAR (unrar.dll), ZIP, ArchiveAccess.DLL\n");
_tprintf (L"Miscellaneous formats:\n");
}
/*
+ 0.6:
+
+ - rdb handling optimization (no more huge memory usage)
+ - fat16 supported
+
0.5:
- adf protection flags fixed
const TCHAR *uae_archive_extensions[] = { L"zip", L"rar", L"7z", L"lha", L"lzh", L"lzx", NULL };
-static struct zfile *zfile_create (void)
+static struct zfile *zfile_create (struct zfile *prev)
{
struct zfile *z;
memset (z, 0, sizeof *z);
z->next = zlist;
zlist = z;
+ z->opencnt = 1;
+ if (prev) {
+ z->zfdmask = prev->zfdmask;
+ }
return z;
}
if (!f)
return;
+ if (f->opencnt < 0) {
+ write_log (L"zfile: tried to free already closed filehandle!\n");
+ return;
+ }
+ f->opencnt--;
+ if (f->opencnt > 0)
+ return;
+ f->opencnt = -100;
+ if (f->parent) {
+ f->parent->opencnt--;
+ if (f->parent->opencnt <= 0)
+ zfile_fclose (f->parent);
+ }
while (l != f) {
if (l == 0) {
- write_log (L"zfile: tried to free already freed filehandle!\n");
+ write_log (L"zfile: tried to free already freed or nonexisting filehandle!\n");
return;
}
pl = l;
return z2;
}
-static struct zfile *extadf (struct zfile *z)
+static struct zfile *extadf (struct zfile *z, int pctype)
{
int i, r;
struct zfile *zo;
uae_u16 *mfm;
uae_u16 *amigamfmbuffer;
- uae_u8 writebuffer_ok[11];
- int tracks, size, len, offs, pos;
+ uae_u8 writebuffer_ok[32], *outbuf;
+ int tracks, len, offs, pos;
uae_u8 buffer[2 + 2 + 4 + 4];
+ int outsize;
+ TCHAR newname[MAX_DPATH];
+ TCHAR *ext;
+
+ //pctype = 1;
mfm = xcalloc (32000, 1);
amigamfmbuffer = xcalloc (32000, 1);
+ outbuf = xcalloc (16384, 1);
zfile_fread (buffer, 1, 8, z);
zfile_fread (buffer, 1, 4, z);
tracks = buffer[2] * 256 + buffer[3];
offs = 8 + 2 + 2 + tracks * (2 + 2 + 4 + 4);
- size = tracks * 512 * 11;
- zo = zfile_fopen_empty (z, zfile_getname (z), size);
+ _tcscpy (newname, zfile_getname (z));
+ ext = _tcsrchr (newname, '.');
+ if (ext) {
+ _tcscpy (newname + _tcslen (newname) - _tcslen (ext), L".ext.adf");
+ } else {
+ _tcscat (newname, L".adf");
+ }
+ zo = zfile_fopen_empty (z, newname, 0);
if (!zo)
goto end;
pos = 12;
+ outsize = 0;
for (i = 0; i < tracks; i++) {
int type, bitlen;
if (type == 1) {
zfile_fread (mfm, len, 1, z);
memset (writebuffer_ok, 0, sizeof writebuffer_ok);
- r = isamigatrack (amigamfmbuffer, (uae_u8*)mfm, len, zo->data + i * 512 * 11, writebuffer_ok, i);
- if (r < 0 && i == 0) {
- zfile_seterror (L"'%s' is not AmigaDOS formatted", zo->name);
- goto end;
+ memset (outbuf, 0, 16384);
+ if (pctype <= 0) {
+ r = isamigatrack (amigamfmbuffer, (uae_u8*)mfm, len, outbuf, writebuffer_ok, i, &outsize);
+ if (r < 0 && i == 0) {
+ zfile_seterror (L"'%s' is not AmigaDOS formatted", zo->name);
+ goto end;
+ }
+ } else {
+ r = ispctrack (amigamfmbuffer, (uae_u8*)mfm, len, outbuf, writebuffer_ok, i, &outsize);
+ if (r < 0 && i == 0) {
+ zfile_seterror (L"'%s' is not PC formatted", zo->name);
+ goto end;
+ }
}
} else {
- zfile_fread (zo->data + i * 512 * 11, 11 * 512, 1, z);
+ outsize = 512 * 11;
+ zfile_fread (outbuf, outsize, 1, z);
}
+ zfile_fwrite (outbuf, outsize, 1, zo);
offs += len;
#include "fdi2raw.h"
-static struct zfile *fdi (struct zfile *z)
+static struct zfile *fdi (struct zfile *z, int type)
{
int i, j, r;
struct zfile *zo;
TCHAR newname[MAX_DPATH];
uae_u16 *mfm;
uae_u16 *amigamfmbuffer;
- uae_u8 writebuffer_ok[11];
- int tracks, size, len;
+ uae_u8 writebuffer_ok[32], *outbuf;
+ int tracks, len, outsize;
FDI *fdi;
fdi = fdi2raw_header (z);
return z;
mfm = xcalloc (32000, 1);
amigamfmbuffer = xcalloc (32000, 1);
+ outbuf = xcalloc (16384, 1);
tracks = fdi2raw_get_last_track (fdi);
- size = tracks * 512 * 11;
if (ext) {
_tcscpy (newname, orgname);
_tcscpy (newname + _tcslen (newname) - _tcslen (ext), L".adf");
} else {
_tcscat (newname, L".adf");
}
- zo = zfile_fopen_empty (z, newname, size);
+ zo = zfile_fopen_empty (z, newname, 0);
if (!zo)
goto end;
+ outsize = 0;
for (i = 0; i < tracks; i++) {
uae_u8 *p = (uae_u8*)mfm;
fdi2raw_loadtrack (fdi, mfm, NULL, i, &len, NULL, NULL, 1);
*p++ = v;
}
memset (writebuffer_ok, 0, sizeof writebuffer_ok);
- r = isamigatrack (amigamfmbuffer, (uae_u8*)mfm, len, zo->data + i * 512 * 11, writebuffer_ok, i);
- if (r < 0 && i == 0) {
- zfile_seterror (L"'%s' is not AmigaDOS formatted", orgname);
- goto end;
+ memset (outbuf, 0, 16384);
+ if (type <= 0) {
+ r = isamigatrack (amigamfmbuffer, (uae_u8*)mfm, len, outbuf, writebuffer_ok, i, &outsize);
+ if (r < 0 && i == 0) {
+ zfile_seterror (L"'%s' is not AmigaDOS formatted", orgname);
+ goto end;
+ }
+ } else if (type == 1) {
+ r = ispctrack (amigamfmbuffer, (uae_u8*)mfm, len, outbuf, writebuffer_ok, i, &outsize);
+ if (r < 0 && i == 0) {
+ zfile_seterror (L"'%s' is not PC formatted", orgname);
+ goto end;
+ }
}
+ zfile_fwrite (outbuf, outsize, 1, zo);
}
zfile_fclose (z);
fdi2raw_header_free (fdi);
xfree (mfm);
xfree (amigamfmbuffer);
+ xfree (outbuf);
return zo;
end:
if (zo)
fdi2raw_header_free (fdi);
xfree (mfm);
xfree (amigamfmbuffer);
+ xfree (outbuf);
return z;
}
-
#ifdef CAPS
#include "caps/caps_win32.h"
-static struct zfile *ipf (struct zfile *z)
+static struct zfile *ipf (struct zfile *z, int type)
{
int i, j, r;
struct zfile *zo;
TCHAR newname[MAX_DPATH];
uae_u16 *mfm;
uae_u16 *amigamfmbuffer;
- uae_u8 writebuffer_ok[11];
- int tracks, size, len;
-
+ uae_u8 writebuffer_ok[32];
+ int tracks, len;
+ int outsize;
+ uae_u8 *outbuf;
if (!caps_loadimage (z, 0, &tracks))
return z;
mfm = xcalloc (32000, 1);
+ outbuf = xcalloc (16384, 1);
amigamfmbuffer = xcalloc (32000, 1);
- size = tracks * 512 * 11;
if (ext) {
_tcscpy (newname, orgname);
_tcscpy (newname + _tcslen (newname) - _tcslen (ext), L".adf");
} else {
_tcscat (newname, L".adf");
}
- zo = zfile_fopen_empty (z, newname, size);
+ zo = zfile_fopen_empty (z, newname, 0);
if (!zo)
goto end;
+ outsize = 0;
for (i = 0; i < tracks; i++) {
uae_u8 *p = (uae_u8*)mfm;
caps_loadrevolution (mfm, 0, i, &len);
*p++ = v;
}
memset (writebuffer_ok, 0, sizeof writebuffer_ok);
- r = isamigatrack (amigamfmbuffer, (uae_u8*)mfm, len, zo->data + i * 512 * 11, writebuffer_ok, i);
+ memset (outbuf, 0, 16384);
+ r = isamigatrack (amigamfmbuffer, (uae_u8*)mfm, len, outbuf, writebuffer_ok, i, &outsize);
if (r < 0 && i == 0) {
zfile_seterror (L"'%s' is not AmigaDOS formatted", orgname);
goto end;
}
+ zfile_fwrite (outbuf, 1, outsize, zo);
}
caps_unloadimage (0);
zfile_fclose (z);
xfree (mfm);
xfree (amigamfmbuffer);
+ xfree (outbuf);
return zo;
end:
if (zo)
caps_unloadimage (0);
xfree (mfm);
xfree (amigamfmbuffer);
+ xfree (outbuf);
return z;
}
#endif
{
TCHAR *name = z->name;
TCHAR *ext = _tcsrchr (name, '.');
- uae_u8 header[7];
+ uae_u8 header[32];
int i;
int mask = z->zfdmask;
if (!strcasecmp (ext, L".adf")) {
if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
return ArchiveFormatADF;
+ if (isfat (header))
+ return ArchiveFormatFAT;
return 0;
}
}
return ArchiveFormatADF;
if (header[0] == 'R' && header[1] == 'D' && header[2] == 'S' && header[3] == 'K')
return ArchiveFormatRDB;
+ if (isfat (header))
+ return ArchiveFormatFAT;
return 0;
}
}
{
TCHAR *name = z->name;
TCHAR *ext = NULL;
- uae_u8 header[8];
+ uae_u8 header[32];
int i;
if (!mask)
- return z;
+ return NULL;
if (name) {
ext = _tcsrchr (name, '.');
if (ext)
}
if (mask & ZFD_RAWDISK) {
#ifdef CAPS
- if (strcasecmp (ext, L"ipf") == 0)
- return ipf (z);
+ if (strcasecmp (ext, L"ipf") == 0) {
+ if (mask & ZFD_RAWDISK_PC)
+ return ipf (z, 1);
+ else if (mask & ZFD_RAWDISK_AMIGA)
+ return ipf (z, 0);
+ else
+ return ipf (z, -1);
+ }
#endif
- if (strcasecmp (ext, L"fdi") == 0)
- return fdi (z);
+ if (strcasecmp (ext, L"fdi") == 0) {
+ if (mask & ZFD_RAWDISK_PC)
+ return fdi (z, 1);
+ else if (mask & ZFD_RAWDISK_AMIGA)
+ return fdi (z, 0);
+ else
+ return fdi (z, -1);
+ }
+ if (mask & (ZFD_RAWDISK_PC | ZFD_RAWDISK_AMIGA))
+ return NULL;
}
#if defined(ARCHIVEACCESS)
for (i = 0; plugins_7z_x[i]; i++) {
}
if (mask & ZFD_RAWDISK) {
#ifdef CAPS
- if (header[0] == 'C' && header[1] == 'A' && header[2] == 'P' && header[3] == 'S')
- return ipf (z);
+ if (header[0] == 'C' && header[1] == 'A' && header[2] == 'P' && header[3] == 'S') {
+ if (mask & ZFD_RAWDISK_PC)
+ return ipf (z, 1);
+ else if (mask & ZFD_RAWDISK_AMIGA)
+ return ipf (z, 0);
+ else
+ return ipf (z, -1);
+ }
#endif
- if (!memcmp (header, "Formatte", 8))
- return fdi (z);
- if (!memcmp (header, "UAE-1ADF", 8))
- return extadf (z);
+ if (!memcmp (header, "Formatte", 8)) {
+ if (mask & ZFD_RAWDISK_PC)
+ return fdi (z, 1);
+ else if (mask & ZFD_RAWDISK_AMIGA)
+ return fdi (z, 0);
+ else
+ return fdi (z, -1);
+ }
+ if (!memcmp (header, "UAE-1ADF", 8)) {
+ if (mask & ZFD_RAWDISK_PC)
+ return extadf (z, 1);
+ else if (mask & ZFD_RAWDISK_AMIGA)
+ return extadf (z, 0);
+ else
+ return extadf (z, -1);
+ }
}
if (mask & ZFD_ARCHIVE) {
if (header[0] == 'P' && header[1] == 'K')
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 (isfat (header))
+ return archive_access_select (parent, z, ArchiveFormatFAT, dodefault);
}
if (ext) {
return archive_access_select (parent, z, ArchiveFormatADF, dodefault);
}
}
- return z;
+ return NULL;
}
if(*name == '\0')
return NULL;
- l = zfile_create ();
+ l = zfile_create (NULL);
l->name = my_strdup (name);
l->mode = my_strdup (mode);
f = _tfopen (name, mode);
}
l->zfdmask = mask;
} else {
- l = zfile_create ();
+ l = zfile_create (NULL);
l->mode = my_strdup (mode);
l->name = my_strdup (name);
l->zfdmask = mask;
return l;
l2 = NULL;
while (cnt-- > 0) {
- l = zuncompress (NULL, l, 0, mask);
- if (!l)
- break;
zfile_fseek (l, 0, SEEK_SET);
- if (l == l2)
+ l2 = zuncompress (NULL, l, 0, mask);
+ zfile_fseek (l, 0, SEEK_SET);
+ if (!l2)
break;
- l2 = l;
+ l = l2;
}
return l;
}
if (!zf)
return NULL;
if (zf->data) {
- nzf = zfile_create ();
+ nzf = zfile_create (zf);
nzf->data = xmalloc (zf->size);
memcpy (nzf->data, zf->data, zf->size);
nzf->size = zf->size;
nzf = openzip (zf->name);
return nzf;
} else {
- nzf = zfile_create ();
+ nzf = zfile_create (zf);
nzf->f = _tfopen (zf->name, zf->mode);
}
zfile_fseek (nzf, zf->seek, SEEK_SET);
struct zfile *zfile_fopen_empty (struct zfile *prev, const TCHAR *name, uae_u64 size)
{
struct zfile *l;
- l = zfile_create ();
+ l = zfile_create (prev);
l->name = name ? my_strdup (name) : L"";
if (size) {
l->data = xcalloc (size, 1);
l->data = xcalloc (1, 1);
l->size = 0;
}
- if (prev) {
- l->zfdmask = prev->zfdmask;
+ return l;
+}
+
+struct zfile *zfile_fopen_parent (struct zfile *z, const TCHAR *name, uae_u64 offset, uae_u64 size)
+{
+ struct zfile *l;
+
+ l = zfile_create (z);
+ if (name)
+ l->name = my_strdup (name);
+ else if (z->name)
+ l->name = my_strdup (z->name);
+ l->size = size;
+ l->offset = offset;
+ for (;;) {
+ l->parent = z;
+ if (!z->parent)
+ break;
+ l->offset += z->offset;
+ z = z->parent;
}
+ z->opencnt++;
return l;
}
struct zfile *zfile_fopen_data (const TCHAR *name, uae_u64 size, uae_u8 *data)
{
struct zfile *l;
- l = zfile_create ();
+
+ l = zfile_create (NULL);
l->name = name ? my_strdup (name) : L"";
l->data = xmalloc (size);
l->size = size;
uae_s64 zfile_ftell (struct zfile *z)
{
+ uae_s64 v;
if (z->data)
return z->seek;
- return _ftelli64 (z->f);
+ if (z->parent) {
+ v = _ftelli64 (z->parent->f);
+ v -= z->offset;
+ } else {
+ v = _ftelli64 (z->f);
+ }
+ return v;
}
uae_s64 zfile_fseek (struct zfile *z, uae_s64 offset, int mode)
ret = 1;
}
return ret;
+ } else {
+ if (z->parent) {
+ switch (mode)
+ {
+ case SEEK_SET:
+ if (offset >= z->size) {
+ _fseeki64 (z->parent->f, z->offset + z->size, SEEK_SET);
+ return 1;
+ } else if (offset < 0) {
+ return 1;
+ }
+ return _fseeki64 (z->parent->f, offset + z->offset, SEEK_SET);
+
+ case SEEK_END:
+ if (offset > 0)
+ return 1;
+ if (offset < -z->size) {
+ _fseeki64 (z->parent->f, z->offset, SEEK_SET);
+ return 1;
+ }
+ return _fseeki64 (z->parent->f, offset + z->size + z->offset, SEEK_SET);
+
+ case SEEK_CUR:
+ {
+ uae_s64 v = zfile_ftell (z->parent);
+ if (v + offset > z->size) {
+ _fseeki64 (z->parent->f, z->offset + z->size, SEEK_SET);
+ return 1;
+ } else if (v + offset < 0) {
+ _fseeki64 (z->parent->f, z->offset, SEEK_SET);
+ return 1;
+ }
+ return _fseeki64 (z->parent->f, v + offset + z->offset, SEEK_SET);
+ }
+ }
+ } else {
+ return _fseeki64 (z->f, offset, mode);
+ }
}
- return _fseeki64 (z->f, offset, mode);
+ return 1;
}
size_t zfile_fread (void *b, size_t l1, size_t l2,struct zfile *z)
if (l2 < 0)
l2 = 0;
}
- memcpy (b, z->data + z->seek, l1 * l2);
+ memcpy (b, z->data + z->offset + z->seek, l1 * l2);
z->seek += l1 * l2;
return l2;
}
+ if (z->parent) {
+ uae_s64 v;
+ uae_s64 size = z->size;
+ z = z->parent;
+ v = zfile_ftell (z);
+ if (v + l1 * l2 > size) {
+ if (l1)
+ l2 = (size - v) / l1;
+ else
+ l2 = 0;
+ if (l2 < 0)
+ l2 = 0;
+ }
+ }
return fread (b, l1, l2, z->f);
}
size_t zfile_fwrite (void *b, size_t l1, size_t l2, struct zfile *z)
{
+ if (z->parent)
+ return 0;
if (z->data) {
- if (z->seek + l1 * l2 > z->size) {
- if (l1)
- l2 = (z->size - z->seek) / l1;
- else
- l2 = 0;
- if (l2 < 0)
- l2 = 0;
+ int off = z->seek + l1 * l2;
+ if (off > z->size) {
+ z->data = realloc (z->data, off);
+ z->size = off;
}
memcpy (z->data + z->seek, b, l1 * l2);
z->seek += l1 * l2;
{
int out = -1;
if (z->data) {
- if (z->seek < z->size)
+ if (z->seek < z->size) {
out = z->data[z->seek++];
+ }
} else {
out = fgetc (z->f);
}
static struct zvolume *zfile_fopen_archive_data (struct znode *parent, struct zfile *zf)
{
struct zvolume *zv = NULL;
- uae_u8 header[7];
+ uae_u8 header[32];
memset (header, 0, sizeof (header));
zfile_fread (header, sizeof (header), 1, 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);
+ if (isfat (header))
+ zv = archive_directory_fat (zf);
return zv;
}
goto end;
zvnew = zfile_fopen_archive_ext (zv->parentz, zf);
if (!zvnew) {
- struct zfile *zf2 = zf;
- zf = zuncompress (&zv->root, zf2, 0, ZFD_ALL);
- if (zf != zf2)
+ struct zfile *zf2 = zuncompress (&zv->root, zf, 0, ZFD_ALL);
+ if (zf2) {
+ zf = zf2;
zvnew = archive_directory_plain (zf);
+ }
}
if (!zvnew)
goto end;
zvolume_addtolist (zv);
else
zfile_fclose (zf);
+
return zv;
}
xfree (zn->fullname);
xfree (zn->name);
zfile_fclose (zn->f);
+ memset (zn, 0, sizeof (struct znode));
if (zn != &zv->root)
xfree (zn);
zn = zn2;
case ArchiveFormatRDB:
zv = archive_directory_rdb (zf);
break;
+ case ArchiveFormatFAT:
+ zv = archive_directory_fat (zf);
+ break;
}
if (!zv)
zv = archive_directory_arcacc (zf, id);
case ArchiveFormatRDB:
zf = archive_access_rdb (zn);
break;
+ case ArchiveFormatFAT:
+ zf = archive_access_fat (zn);
+ break;
}
return zf;
}
{
struct zarchive_info zai;
struct znode *zn;
- struct zfile *z = zfile_fopen_empty (zf, path, size);
-
+ struct zfile *z;
+
+ z = zfile_fopen_empty (zf, path, size);
zfile_fwrite (data, size, 1, z);
memset(&zai, 0, sizeof zai);
zai.name = path;
}
zf = zfile_dup (z);
zf2 = zuncompress (NULL, zf, 0, ZFD_ALL);
- if (zf2 != zf) {
- zf = zf2;
- zai.name = zfile_getfilename (zf);
+ if (zf2) {
+ zf = NULL;
+ zai.name = zfile_getfilename (zf2);
zai.flags = -1;
- zfile_fseek(zf, 0, SEEK_END);
+ zfile_fseek (zf2, 0, SEEK_END);
zai.size = zfile_ftell (zf2);
- zfile_fseek(zf, 0, SEEK_SET);
+ zfile_fseek (zf2, 0, SEEK_SET);
zn = zvolume_addfile_abs (zv, &zai);
if (zn)
zn->offset = 1;
+ zfile_fclose (zf2);
}
- zfile_fclose (zf2);
+ zfile_fclose (zf);
return zv;
}
struct zfile *archive_access_plain (struct znode *zn)
struct zfile *zf;
z = zfile_fopen_empty (zn->volume->archive, zn->fullname, zn->size);
zf = zfile_fopen (zfile_getname (zn->volume->archive), L"rb", zn->volume->archive->zfdmask & ~ZFD_ADF);
- zfile_fread (z->data, zn->size, 1, zf);
- zfile_fclose (zf);
+ if (zf) {
+ zfile_fread (z->data, zn->size, 1, zf);
+ zfile_fclose (zf);
+ }
} else {
z = zfile_fopen_empty (zn->volume->archive, zn->fullname, zn->size);
if (z) {
bs = adf->blocksize = 512;
if (adf->size < 2000000 && adf->rootblock != 880) {
adf->rootblock = 880;
+ 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, bs) != 0)
goto fail;
- goto fail;
}
}
size = zn->size;
}
- zf = zfile_fopen_empty (z, zn->fullname, size);
- zfile_fseek (z, block * blocksize, SEEK_SET);
- zfile_fread (zf->data, size, 1, z);
+ zf = zfile_fopen_parent (z, zn->fullname, block * blocksize, size);
return zf;
}
+int isfat (uae_u8 *p)
+{
+ int i, b;
+
+ if ((p[0x15] & 0xf0) != 0xf0)
+ return 0;
+ if (p[0x0b] != 0x00 || p[0x0c] != 0x02)
+ return 0;
+ b = 0;
+ for (i = 0; i < 8; i++) {
+ if (p[0x0d] & (1 << i))
+ b++;
+ }
+ if (b != 1)
+ return 0;
+ if (p[0x0f] != 0)
+ return 0;
+ if (p[0x0e] > 8 || p[0x0e] == 0)
+ return 0;
+ if (p[0x10] == 0 || p[0x10] > 8)
+ return 0;
+ b = (p[0x12] << 8) | p[0x11];
+ if (b > 8192 || b <= 0)
+ return 0;
+ b = p[0x16] | (p[0x17] << 8);
+ if (b == 0 || b > 8192)
+ return 0;
+ return 1;
+}
+
+/*
+ * The epoch of FAT timestamp is 1980.
+ * : bits : value
+ * date: 0 - 4: day (1 - 31)
+ * date: 5 - 8: month (1 - 12)
+ * date: 9 - 15: year (0 - 127) from 1980
+ * time: 0 - 4: sec (0 - 29) 2sec counts
+ * time: 5 - 10: min (0 - 59)
+ * time: 11 - 15: hour (0 - 23)
+ */
+#define SECS_PER_MIN 60
+#define SECS_PER_HOUR (60 * 60)
+#define SECS_PER_DAY (SECS_PER_HOUR * 24)
+#define UNIX_SECS_1980 315532800L
+#if BITS_PER_LONG == 64
+#define UNIX_SECS_2108 4354819200L
+#endif
+/* days between 1.1.70 and 1.1.80 (2 leap days) */
+#define DAYS_DELTA (365 * 10 + 2)
+/* 120 (2100 - 1980) isn't leap year */
+#define YEAR_2100 120
+#define IS_LEAP_YEAR(y) (!((y) & 3) && (y) != YEAR_2100)
+
+/* Linear day numbers of the respective 1sts in non-leap years. */
+static time_t days_in_year[] = {
+ /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
+ 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0,
+};
+
+/* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */
+static time_t fat_time_fat2unix (uae_u16 time, uae_u16 date, int fat12)
+{
+ time_t second, day, leap_day, month, year;
+
+ if (0 && fat12) {
+ year = date & 0x7f;
+ month = (date >> 7) & 0x0f;
+ day = (date >> 11);
+ } else {
+ year = date >> 9;
+ month = max(1, (date >> 5) & 0xf);
+ day = max(1, date & 0x1f) - 1;
+ }
+
+ leap_day = (year + 3) / 4;
+ if (year > YEAR_2100) /* 2100 isn't leap year */
+ leap_day--;
+ if (IS_LEAP_YEAR(year) && month > 2)
+ leap_day++;
+
+ second = (time & 0x1f) << 1;
+ second += ((time >> 5) & 0x3f) * SECS_PER_MIN;
+ second += (time >> 11) * SECS_PER_HOUR;
+ second += (year * 365 + leap_day
+ + days_in_year[month] + day
+ + DAYS_DELTA) * SECS_PER_DAY;
+ return second;
+}
+
+static int getcluster (struct zfile *z, int cluster, int fatstart, int fatbits)
+{
+ uae_u32 fat = 0;
+ uae_u8 p[4];
+ int offset = cluster * fatbits;
+ zfile_fseek (z, fatstart * 512 + offset / 8, SEEK_SET);
+ if (fatbits == 12) {
+ zfile_fread (p, 2, 1, z);
+ if ((offset & 4))
+ fat = ((p[0] & 0xf0) >> 4) | (p[1] << 4);
+ else
+ fat = (p[0]) | ((p[1] & 0x0f) << 8);
+ if (fat >= 0xff0)
+ return -1;
+ } else if (fatbits == 16) {
+ zfile_fread (p, 2, 1, z);
+ fat = p[0] | (p[1] << 8);
+ if (fat >= 0xfff0)
+ return -1;
+ } else if (fatbits == 32) {
+ zfile_fread (p, 4, 1, z);
+ fat = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+ fat &= ~0x0fffffff;
+ if (fat >= 0x0ffffff0)
+ return -1;
+ }
+ return fat;
+}
+
+static void fatdirectory (struct zfile *z, struct zvolume *zv, TCHAR *name, int startblock, int entries, int sectorspercluster, int fatstart, int dataregion, int fatbits)
+{
+ struct zarchive_info zai;
+ struct znode *znnew;
+ int i, j;
+
+ for (i = 0; i < entries; i++) {
+ TCHAR name2[MAX_DPATH], *fname;
+ uae_s64 size;
+ uae_u8 fatname[16];
+ uae_u8 buf[32];
+ int attr, cnt, ext;
+ int startcluster;
+
+ memset (buf, 0, sizeof buf);
+ memset (&zai, 0, sizeof zai);
+ zfile_fseek (z, startblock * 512 + i * 32, SEEK_SET);
+ zfile_fread (buf, 32, 1, z);
+ if (buf[0] == 0)
+ break;
+ if (buf[0] == 0xe5)
+ continue;
+ if (buf[0] == 0x05)
+ buf[0] = 0xe5;
+ size = buf[0x1c] | (buf[0x1d] << 8) | (buf[0x1e] << 16) | (buf[0x1f] << 24);
+ attr = buf[0x0b];
+ startcluster = buf[0x1a] | (buf[0x1b] << 8);
+ if ((attr & (0x4 | 0x2)) == 0x06) // system+hidden
+ continue;
+ if (attr & 8) // disk name
+ continue;
+ if (attr & 1) // read-only
+ zai.flags |= 1 << 3;
+ if (!(attr & 32)) // archive
+ zai.flags |= 1 << 4;
+
+ cnt = 0;
+ ext = 0;
+ for (j = 0; j < 8 && buf[j] != 0x20 && buf[j] != 0; j++)
+ fatname[cnt++] = buf[j];
+ for (j = 0; j < 3 && buf[8 + j] != 0x20 && buf[8 + j] != 0; j++) {
+ if (ext == 0)
+ fatname[cnt++] = '.';
+ ext = 1;
+ fatname[cnt++] = buf[8 + j];
+ }
+ fatname[cnt] = 0;
+
+ fname = au (fatname);
+ name2[0] = 0;
+ if (name[0]) {
+ TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
+ _tcscpy (name2, name);
+ _tcscat (name2, sep);
+ }
+ _tcscat (name2, fname);
+
+ zai.name = name2;
+ zai.t = fat_time_fat2unix (buf[0x16] | (buf[0x17] << 8), buf[0x18] | (buf[0x19] << 8), 1);
+ if (attr & (16 | 8)) {
+ int nextblock, cluster;
+ nextblock = dataregion + (startcluster - 2) * sectorspercluster;
+ cluster = getcluster (z, startcluster, fatstart, fatbits);
+ if ((cluster < 0 || cluster >= 3) && nextblock != startblock) {
+ znnew = zvolume_adddir_abs (zv, &zai);
+ fatdirectory (z, zv, name2, nextblock, sectorspercluster * 512 / 32, sectorspercluster, fatstart, dataregion, fatbits);
+ while (cluster >= 3) {
+ nextblock = dataregion + (cluster - 2) * sectorspercluster;
+ fatdirectory (z, zv, name2, nextblock, sectorspercluster * 512 / 32, sectorspercluster, fatstart, dataregion, fatbits);
+ cluster = getcluster (z, cluster, fatstart, fatbits);
+ }
+ }
+ } else {
+ zai.size = size;
+ znnew = zvolume_addfile_abs (zv, &zai);
+ znnew->offset = startcluster;
+ }
+
+ xfree (fname);
+ }
+}
+
+struct zvolume *archive_directory_fat (struct zfile *z)
+{
+ uae_u8 buf[512] = { 0 };
+ int fatbits = 12;
+ struct zvolume *zv;
+ int rootdir, reserved, sectorspercluster;
+ int numfats, sectorsperfat, rootentries;
+ int dataregion;
+
+ zfile_fseek (z, 0, SEEK_SET);
+ zfile_fread (buf, 1, 512, z);
+
+ if (!isfat (buf))
+ return NULL;
+ reserved = buf[0x0e] | (buf[0x0f] << 8);
+ numfats = buf[0x10];
+ sectorsperfat = buf[0x16] | (buf[0x17] << 8);
+ rootentries = buf[0x11] | (buf[0x12] << 8);
+ sectorspercluster = buf[0x0d];
+ rootdir = reserved + numfats * sectorsperfat;
+ dataregion = rootdir + rootentries * 32 / 512;
+
+ zv = zvolume_alloc (z, ArchiveFormatFAT, NULL, NULL);
+ fatdirectory (z, zv, L"", rootdir, rootentries, sectorspercluster, reserved, dataregion, fatbits);
+ zv->method = ArchiveFormatFAT;
+ return zv;
+}
+
+struct zfile *archive_access_fat (struct znode *zn)
+{
+ uae_u8 buf[512] = { 0 };
+ int fatbits = 12;
+ int size = zn->size;
+ struct zfile *sz, *dz;
+ int rootdir, reserved, sectorspercluster;
+ int numfats, sectorsperfat, rootentries;
+ int dataregion;
+ int offset, cluster;
+
+ sz = zn->volume->archive;
+
+ zfile_fseek (sz, 0, SEEK_SET);
+ zfile_fread (buf, 1, 512, sz);
+
+ if (!isfat (buf))
+ return NULL;
+ reserved = buf[0x0e] | (buf[0x0f] << 8);
+ numfats = buf[0x10];
+ sectorsperfat = buf[0x16] | (buf[0x17] << 8);
+ rootentries = buf[0x11] | (buf[0x12] << 8);
+ sectorspercluster = buf[0x0d];
+ rootdir = reserved + numfats * sectorsperfat;
+ dataregion = rootdir + rootentries * 32 / 512;
+
+ dz = zfile_fopen_empty (sz, zn->fullname, size);
+ if (!dz)
+ return NULL;
+
+ offset = 0;
+ cluster = zn->offset;
+ while (size && cluster >= 2) {
+ int left = size > sectorspercluster * 512 ? sectorspercluster * 512 : size;
+ int sector = dataregion + (cluster - 2) * sectorspercluster;
+ zfile_fseek (sz, sector * 512, SEEK_SET);
+ zfile_fread (dz->data + offset, 1, left, sz);
+ size -= left;
+ offset += left;
+ cluster = getcluster (sz, cluster, reserved, fatbits);
+ }
+
+ return dz;
+}
+
void archive_access_close (void *handle, unsigned int id)
{
switch (id)