From: Toni Wilen Date: Sat, 30 May 2009 17:20:27 +0000 (+0300) Subject: imported winuaesrc1610b1.zip X-Git-Tag: 2100~79 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=7db9ec53ed68652cf76cd2709c00a127d7598a7c;p=francis%2Fwinuae.git imported winuaesrc1610b1.zip --- diff --git a/disk.c b/disk.c index 1d5b2863..dec1869a 100644 --- a/disk.c +++ b/disk.c @@ -997,10 +997,10 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR 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; @@ -1281,7 +1281,7 @@ static uae_u16 *mfmcoder (uae_u8 *src, uae_u16 *dest, int len) 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]; @@ -1326,7 +1326,9 @@ static void decode_pcdos (drive *drv) 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; @@ -1815,15 +1817,15 @@ static int drive_write_pcdos (drive *drv) 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; } @@ -1837,9 +1839,9 @@ static int drive_write_pcdos (drive *drv) 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; @@ -2473,8 +2475,8 @@ void dumpdisk (void) 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); diff --git a/diskutil.c b/diskutil.c index be0b238b..543d124b 100644 --- a/diskutil.c +++ b/diskutil.c @@ -1,6 +1,8 @@ #include "sysconfig.h" #include "sysdeps.h" +#include "crc32.h" + #define MFMMASK 0x55555555 static uae_u32 getmfmlong (uae_u16 * mbuf) { @@ -9,7 +11,7 @@ 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; @@ -17,6 +19,7 @@ static int drive_write_adf_amigados (uae_u16 *mbuf, uae_u16 *mend, uae_u8 *write uae_u8 secbuf[544]; mend -= (4 + 16 + 8 + 512); + *outsize = 11 * 512; for (;;) { int trackoffs; @@ -99,13 +102,14 @@ next: } /* 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--) { @@ -127,6 +131,127 @@ int isamigatrack(uae_u16 *amigamfmbuffer, uae_u8 *mfmdata, int len, uae_u8 *writ } } 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; +} diff --git a/include/diskutil.h b/include/diskutil.h index 48daf0e5..b390818a 100644 --- a/include/diskutil.h +++ b/include/diskutil.h @@ -1,2 +1,3 @@ -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); diff --git a/include/options.h b/include/options.h index a109f632..6364dc2c 100644 --- a/include/options.h +++ b/include/options.h @@ -9,7 +9,7 @@ #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; diff --git a/include/zarchive.h b/include/zarchive.h index b7c2f224..c7d59712 100644 --- a/include/zarchive.h +++ b/include/zarchive.h @@ -5,12 +5,15 @@ struct zfile { 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 @@ -28,7 +31,7 @@ struct znode { 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; @@ -49,10 +52,10 @@ struct zvolume 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; @@ -61,7 +64,7 @@ struct zvolume struct zarchive_info { const TCHAR *name; - uae_u64 size; + uae_s64 size; int flags; TCHAR *comment; time_t t; @@ -76,6 +79,8 @@ struct zarchive_info #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); @@ -104,9 +109,12 @@ 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 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); diff --git a/include/zfile.h b/include/zfile.h index 8c630222..3c6e21ba 100644 --- a/include/zfile.h +++ b/include/zfile.h @@ -14,6 +14,8 @@ typedef int (*zfile_callback)(struct zfile*, void*); 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); @@ -53,7 +55,10 @@ extern TCHAR *zfile_geterror (void); #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 diff --git a/od-win32/blkdev_win32_aspi.c b/od-win32/blkdev_win32_aspi.c index e74773a8..6b0398d3 100644 --- a/od-win32/blkdev_win32_aspi.c +++ b/od-win32/blkdev_win32_aspi.c @@ -26,11 +26,11 @@ int aspi_allow_misc = 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; @@ -220,17 +220,17 @@ static int open_driver (SCSI *scgp) * 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 diff --git a/od-win32/dxwrap.c b/od-win32/dxwrap.c index 25efd1ec..4cef8893 100644 --- a/od-win32/dxwrap.c +++ b/od-win32/dxwrap.c @@ -921,13 +921,15 @@ void DirectDraw_FillPrimary (void) 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) { @@ -943,7 +945,7 @@ static void flip (void) } } } 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) { @@ -961,7 +963,7 @@ static void flip (void) flip (); recurse--; } - } else if(FAILED (ddrval)) { + } else if (FAILED (ddrval)) { write_log (L"IDirectDrawSurface7_Flip: %s\n", DXError (ddrval)); } } diff --git a/od-win32/fsdb_mywin32.c b/od-win32/fsdb_mywin32.c index 88fa816a..e000fc58 100644 --- a/od-win32/fsdb_mywin32.c +++ b/od-win32/fsdb_mywin32.c @@ -315,6 +315,8 @@ int dos_errno (void) 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: diff --git a/od-win32/fsdb_win32.c b/od-win32/fsdb_win32.c index 9299e10c..e4ae2f4b 100644 --- a/od-win32/fsdb_win32.c +++ b/od-win32/fsdb_win32.c @@ -205,7 +205,7 @@ static void create_uaefsdb (a_inode *aino, uae_u8 *buf, int winmode) 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); @@ -219,7 +219,7 @@ static void create_uaefsdb (a_inode *aino, uae_u8 *buf, int winmode) 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; } @@ -525,16 +525,15 @@ static a_inode *custom_fsdb_lookup_aino (a_inode *base, const TCHAR *aname, int 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); @@ -544,11 +543,11 @@ static a_inode *custom_fsdb_lookup_aino (a_inode *base, const TCHAR *aname, int return &dummy; return aino_from_buf (base, fsdb, &winmode); } + xfree (s); } } while (FindNextFile (h, &fd)); FindClose (h); } - xfree (s); xfree (tmp1); return NULL; } diff --git a/od-win32/hardfile_win32.c b/od-win32/hardfile_win32.c index 57a5953e..07ab2597 100644 --- a/od-win32/hardfile_win32.c +++ b/od-win32/hardfile_win32.c @@ -115,7 +115,7 @@ static int safetycheck (HANDLE *h, uae_u64 offset, uae_u8 *buf, int blocksize) 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) { @@ -188,7 +188,7 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname) 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); @@ -212,7 +212,7 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname) 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); @@ -272,10 +272,10 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname) 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; diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index 1278564d..485348ad 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -972,8 +972,8 @@ IDI_PATHS ICON "paths.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,6,0,0 - PRODUCTVERSION 1,6,0,0 + FILEVERSION 1,6,1,0 + PRODUCTVERSION 1,6,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -989,12 +989,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "WinUAE" - VALUE "FileVersion", "1.6.0" + VALUE "FileVersion", "1.6.1" VALUE "InternalName", "WinUAE" VALUE "LegalCopyright", "© 1996-2009 under the GNU Public License (GPL)" VALUE "OriginalFilename", "WinUAE.exe" VALUE "ProductName", "WinUAE" - VALUE "ProductVersion", "1.6.0" + VALUE "ProductVersion", "1.6.1" END END BLOCK "VarFileInfo" diff --git a/od-win32/uaeunp/uaeunp.vcproj b/od-win32/uaeunp/uaeunp.vcproj index e2f2f075..dc094be8 100644 --- a/od-win32/uaeunp/uaeunp.vcproj +++ b/od-win32/uaeunp/uaeunp.vcproj @@ -65,6 +65,7 @@ LinkIncremental="2" GenerateDebugInformation="true" SubSystem="1" + RandomizedBaseAddress="1" TargetMachine="1" /> $(Configuration)\ false $(IncludePath) + $(LibraryPath) diff --git a/od-win32/win32.c b/od-win32/win32.c index 97a132fd..e685f40a 100644 --- a/od-win32/win32.c +++ b/od-win32/win32.c @@ -525,10 +525,15 @@ void setmouseactive (int active) if (c != normalcursor) return; } + if (active) { + if (IsWindowVisible (hAmigaWnd) == FALSE) + return; + } if (active < 0) active = 1; + mouseactive = active; mouseposx = mouseposy = 0; @@ -2084,7 +2089,7 @@ void target_default_options (struct uae_prefs *p, int type) 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); diff --git a/od-win32/win32.h b/od-win32/win32.h index 3ecc7f7a..41ceb121 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -15,10 +15,10 @@ #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"" diff --git a/od-win32/win32gfx.c b/od-win32/win32gfx.c index bbbef30a..03ebaaf6 100644 --- a/od-win32/win32gfx.c +++ b/od-win32/win32gfx.c @@ -2009,6 +2009,7 @@ static int getbestmode (int nextbest) 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); @@ -2228,11 +2229,12 @@ static int create_windows_2 (void) 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; } diff --git a/od-win32/win32gui.c b/od-win32/win32gui.c index 98b43ef6..554a54a2 100644 --- a/od-win32/win32gui.c +++ b/od-win32/win32gui.c @@ -11708,7 +11708,7 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int currentpage) if (drvdrag) { type = ZFILE_DISKIMAGE; - } else if (zip) { + } else if (zip || harddrive) { do_filesys_insert (file); continue; } diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index b42b5cec..982d719f 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,23 @@ +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 diff --git a/uaeunp.c b/uaeunp.c index 0970666c..53c0f182 100644 --- a/uaeunp.c +++ b/uaeunp.c @@ -692,7 +692,7 @@ int wmain (int argc, wchar_t *argv[], wchar_t *envp[]) 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) \"\n"); _tprintf (L"List all recursively: \"uaeunp -l **\"\n"); @@ -703,7 +703,9 @@ int wmain (int argc, wchar_t *argv[], wchar_t *envp[]) _tprintf (L"Output to console: \"uaeunp (-x) -o \"\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"); @@ -715,6 +717,11 @@ int wmain (int argc, wchar_t *argv[], wchar_t *envp[]) } /* + 0.6: + + - rdb handling optimization (no more huge memory usage) + - fat16 supported + 0.5: - adf protection flags fixed diff --git a/zfile.c b/zfile.c index 23bbb8e3..e23e5d7c 100644 --- a/zfile.c +++ b/zfile.c @@ -33,7 +33,7 @@ static struct zfile *zlist = 0; 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; @@ -43,6 +43,10 @@ static struct zfile *zfile_create (void) memset (z, 0, sizeof *z); z->next = zlist; zlist = z; + z->opencnt = 1; + if (prev) { + z->zfdmask = prev->zfdmask; + } return z; } @@ -77,9 +81,22 @@ void zfile_fclose (struct zfile *f) 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; @@ -227,30 +244,43 @@ struct zfile *zfile_gunzip (struct zfile *z) 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; @@ -265,14 +295,25 @@ static struct zfile *extadf (struct zfile *z) 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; @@ -290,7 +331,7 @@ end: #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; @@ -299,8 +340,8 @@ static struct zfile *fdi (struct zfile *z) 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); @@ -308,17 +349,18 @@ static struct zfile *fdi (struct zfile *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); @@ -329,16 +371,27 @@ static struct zfile *fdi (struct zfile *z) *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) @@ -346,13 +399,13 @@ end: 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; @@ -361,24 +414,26 @@ static struct zfile *ipf (struct zfile *z) 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); @@ -389,16 +444,19 @@ static struct zfile *ipf (struct zfile *z) *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) @@ -406,6 +464,7 @@ end: caps_unloadimage (0); xfree (mfm); xfree (amigamfmbuffer); + xfree (outbuf); return z; } #endif @@ -541,7 +600,7 @@ int iszip (struct zfile *z) { TCHAR *name = z->name; TCHAR *ext = _tcsrchr (name, '.'); - uae_u8 header[7]; + uae_u8 header[32]; int i; int mask = z->zfdmask; @@ -587,6 +646,8 @@ int iszip (struct zfile *z) 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; } } @@ -598,6 +659,8 @@ int iszip (struct zfile *z) return ArchiveFormatADF; if (header[0] == 'R' && header[1] == 'D' && header[2] == 'S' && header[3] == 'K') return ArchiveFormatRDB; + if (isfat (header)) + return ArchiveFormatFAT; return 0; } } @@ -615,11 +678,11 @@ struct zfile *zuncompress (struct znode *parent, struct zfile *z, int dodefault, { 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) @@ -655,11 +718,25 @@ struct zfile *zuncompress (struct znode *parent, struct zfile *z, int dodefault, } 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++) { @@ -682,13 +759,31 @@ struct zfile *zuncompress (struct znode *parent, struct zfile *z, int dodefault, } 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') @@ -705,6 +800,8 @@ struct zfile *zuncompress (struct znode *parent, struct zfile *z, int 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 (isfat (header)) + return archive_access_select (parent, z, ArchiveFormatFAT, dodefault); } if (ext) { @@ -717,7 +814,7 @@ struct zfile *zuncompress (struct znode *parent, struct zfile *z, int dodefault, return archive_access_select (parent, z, ArchiveFormatADF, dodefault); } } - return z; + return NULL; } @@ -766,7 +863,7 @@ static struct zfile *zfile_fopen_nozip (const TCHAR *name, const TCHAR *mode) 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); @@ -829,7 +926,7 @@ static struct zfile *zfile_fopen_2 (const TCHAR *name, const TCHAR *mode, int ma } l->zfdmask = mask; } else { - l = zfile_create (); + l = zfile_create (NULL); l->mode = my_strdup (mode); l->name = my_strdup (name); l->zfdmask = mask; @@ -906,13 +1003,12 @@ struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int 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; } @@ -923,7 +1019,7 @@ struct zfile *zfile_dup (struct zfile *zf) 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; @@ -931,7 +1027,7 @@ struct zfile *zfile_dup (struct zfile *zf) 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); @@ -975,7 +1071,7 @@ int zfile_iscompressed (struct zfile *z) 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); @@ -988,16 +1084,36 @@ struct zfile *zfile_fopen_empty (struct zfile *prev, const TCHAR *name, uae_u64 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; @@ -1007,9 +1123,16 @@ struct zfile *zfile_fopen_data (const TCHAR *name, uae_u64 size, uae_u8 *data) 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) @@ -1037,8 +1160,46 @@ 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) @@ -1052,23 +1213,36 @@ 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; @@ -1158,8 +1332,9 @@ int zfile_getc (struct zfile *z) { 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); } @@ -1514,7 +1689,7 @@ static struct zvolume *zfile_fopen_archive_ext (struct znode *parent, struct zfi 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); @@ -1531,6 +1706,8 @@ static struct zvolume *zfile_fopen_archive_data (struct znode *parent, struct 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; } @@ -1601,10 +1778,11 @@ static struct zvolume *prepare_recursive_volume (struct zvolume *zv, const TCHAR 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; @@ -1800,6 +1978,7 @@ struct zvolume *zfile_fopen_archive (const TCHAR *filename) zvolume_addtolist (zv); else zfile_fclose (zf); + return zv; } @@ -1868,6 +2047,7 @@ void zfile_fclose_archive (struct zvolume *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; diff --git a/zfile_archive.c b/zfile_archive.c index ffbae8df..c441ac75 100644 --- a/zfile_archive.c +++ b/zfile_archive.c @@ -74,6 +74,9 @@ static struct zvolume *getzvolume (struct znode *parent, struct zfile *zf, unsig case ArchiveFormatRDB: zv = archive_directory_rdb (zf); break; + case ArchiveFormatFAT: + zv = archive_directory_fat (zf); + break; } if (!zv) zv = archive_directory_arcacc (zf, id); @@ -110,6 +113,9 @@ struct zfile *archive_getzfile (struct znode *zn, unsigned int id) case ArchiveFormatRDB: zf = archive_access_rdb (zn); break; + case ArchiveFormatFAT: + zf = archive_access_fat (zn); + break; } return zf; } @@ -844,8 +850,9 @@ static struct znode *addfile (struct zvolume *zv, struct zfile *zf, const TCHAR { 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; @@ -887,18 +894,19 @@ struct zvolume *archive_directory_plain (struct zfile *z) } 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) @@ -909,8 +917,10 @@ 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) { @@ -1207,11 +1217,12 @@ struct zvolume *archive_directory_adf (struct znode *parent, struct zfile *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; } } @@ -1593,12 +1604,283 @@ struct zfile *archive_access_rdb (struct znode *zn) 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)