Beispiel #1
0
int zfile_zcompress (struct zfile *f, void *src, int size)
{
    int v;
    z_stream zs;
    uae_u8 outbuf[4096];

#ifdef WIN32
    if (!is_zlib)
	return 0;
#endif
    memset (&zs, 0, sizeof (zs));
    if (deflateInit (&zs, Z_DEFAULT_COMPRESSION) != Z_OK)
	return 0;
    zs.next_in = src;
    zs.avail_in = size;
    v = Z_OK;
    while (v == Z_OK) {
	zs.next_out = outbuf;
        zs.avail_out = sizeof (outbuf);
	v = deflate(&zs, Z_NO_FLUSH | Z_FINISH);
	if (sizeof(outbuf) - zs.avail_out > 0)
	    zfile_fwrite (outbuf, 1, sizeof (outbuf) - zs.avail_out, f);
    }
    deflateEnd (&zs);
    return zs.total_out;
}
Beispiel #2
0
static void flushprtbuf (void)
{
	DWORD written = 0;

	if (!prtbufbytes)
		return;

	if (postscript_print_debugging && prtdump)
		zfile_fwrite (prtbuf, prtbufbytes, 1, prtdump);

	if (currprefs.parallel_postscript_emulation) {

		if (psmode) {
			uae_u8 *p;
			psbuffer = xrealloc (uae_u8*, psbuffer, (psbuffers + 2));
			p = xmalloc (uae_u8, prtbufbytes + 2);
			p[0] = prtbufbytes >> 8;
			p[1] = prtbufbytes;
			memcpy (p + 2, prtbuf, prtbufbytes);
			psbuffer[psbuffers++] = p;
			psbuffer[psbuffers] = NULL;
		}
		prtbufbytes = 0;
		return;

	} else if (prtbufbytes > 0) {
Beispiel #3
0
static void cdtvcr_battram_reset (void)
{
	struct zfile *f;
	int v;

	memset (cdtvcr_ram, 0, CDTVCR_RAM_SIZE);
	f = zfile_fopen (currprefs.flashfile, _T("rb+"), ZFD_NORMAL);
	if (!f) {
		f = zfile_fopen (currprefs.flashfile, _T("wb"), 0);
		if (f) {
			zfile_fwrite (cdtvcr_ram, CDTVCR_RAM_SIZE, 1, f);
			zfile_fclose (f);
		}
		return;
	}
	v = zfile_fread (cdtvcr_ram, 1, CDTVCR_RAM_SIZE, f);
	if (v < CDTVCR_RAM_SIZE)
		zfile_fwrite (cdtvcr_ram + v, 1, CDTVCR_RAM_SIZE - v, f);
	zfile_fclose (f);
}
Beispiel #4
0
static int hdf_write_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
{
    int outlen = 0;

    if (hfd->ci.readonly) {
        if (g_debug) {
            write_log("hfd->readonly\n");
        }
        return 0;
    }
    if (hfd->dangerous) {
        if (g_debug) {
            write_log("hfd->dangerous\n");
        }
        return 0;
    }
    hfd->cache_valid = 0;
    hdf_seek (hfd, offset);
    poscheck (hfd, len);
    memcpy (hfd->cache, buffer, len);
    if (hfd->handle_valid == HDF_HANDLE_LINUX) {
        outlen = fwrite (hfd->cache, 1, len, hfd->handle->h);
        //fflush(hfd->handle->h);
        if (g_debug) {
            write_log("wrote %u bytes (wanted %d) at offset %llx\n", outlen,
                    len, offset);
        }
        const TCHAR *name = hfd->emptyname == NULL ? _T("<unknown>") : hfd->emptyname;
        if (offset == 0) {
            long outlen2;
            uae_u8 *tmp;
            int tmplen = 512;
            tmp = (uae_u8*)xmalloc (uae_u8, tmplen);
            if (tmp) {
                memset (tmp, 0xa1, tmplen);
                hdf_seek (hfd, offset);
                outlen2 = fread (tmp, 1, tmplen, hfd->handle->h);
                if (memcmp (hfd->cache, tmp, tmplen) != 0 || outlen != len)
                    gui_message (_T("\"%s\"\n\nblock zero write failed!"), name);
                xfree (tmp);
            }
        }
    } else if (hfd->handle_valid == HDF_HANDLE_ZFILE) {
        outlen = zfile_fwrite (hfd->cache, 1, len, hfd->handle->zf);
    }
    return outlen;
}
Beispiel #5
0
static void cdtvcr_battram_write (int addr, int v)
{
	struct zfile *f;
	int offset = addr & CDTVCR_RAM_MASK;

	if (offset >= CDTVCR_RAM_SIZE)
		return;
	gui_flicker_led (LED_MD, 0, 2);
	if (cdtvcr_ram[offset] == v)
		return;
	cdtvcr_ram[offset] = v;
	f = zfile_fopen (currprefs.flashfile, _T("rb+"), ZFD_NORMAL);
	if (!f)
		return;
	zfile_fseek (f, offset, SEEK_SET);
	zfile_fwrite (cdtvcr_ram + offset, 1, 1, f);
	zfile_fclose (f);
}
Beispiel #6
0
void inprec_close(void)
{
    if (!inprec_zf)
		return;
    if (inprec_buffer && input_recording > 0) {
		hsync_counter++;
		inprec_rstart(INPREC_END);
		inprec_rend();
		hsync_counter--;
		zfile_fwrite (inprec_buffer, inprec_p - inprec_buffer, 1, inprec_zf);
		inprec_p = inprec_buffer;
    }
    zfile_fclose (inprec_zf);
    inprec_zf = NULL;
    xfree (inprec_buffer);
    inprec_buffer = NULL;
    input_recording = 0;
    write_log ("inprec finished\n");
}
Beispiel #7
0
static void addextra(TCHAR *name, struct zfile **extra, uae_u8 *p, int size)
{
	int i;
	struct zfile *zf = NULL;

	if (!extra)
		return;
	for (i = 0; i < DMS_EXTRA_SIZE; i++) {
		if (!extra[i])
			break;
	}
	if (i == DMS_EXTRA_SIZE)
		return;
	zf = zfile_fopen_empty (NULL, name, size);
	if (!zf)
		return;
	zfile_fwrite (p, size, 1, zf);
	zfile_fseek (zf, 0, SEEK_SET);
	extra[i] = zf;
}
Beispiel #8
0
static void mergecd32 (uae_u8 *dst, uae_u8 *src, int size)
{
	int i, k;
	k = 0;
	for (i = 0; i < size / 2; i += 2) {
		int j = i + size / 2;
		dst[k + 1] = src[i + 0];
		dst[k + 0] = src[i + 1];
		dst[k + 3] = src[j + 0];
		dst[k + 2] = src[j + 1];
		k += 4;
	}
#if 0
	{
		struct zfile *f;
		f = zfile_fopen ("c:\\d\\1.rom","wb", ZFD_NORMAL);
		zfile_fwrite (dst, 1, size, f);
		zfile_fclose(f);
	}
#endif
}
Beispiel #9
0
struct zfile *read_rom_name (const TCHAR *filename)
{
	int i;
	struct zfile *f;

	for (i = 0; i < romlist_cnt; i++) {
		if (!_tcsicmp (filename, rl[i].path)) {
			struct romdata *rd = rl[i].rd;
			f = read_rom (&rd);
			if (f)
				return f;
		}
	}
	f = rom_fopen (filename, L"rb", ZFD_NORMAL);
	if (f) {
		uae_u8 tmp[11];
		zfile_fread (tmp, sizeof tmp, 1, f);
		if (!memcmp (tmp, "AMIROMTYPE1", sizeof tmp)) {
			struct zfile *df;
			int size;
			uae_u8 *buf;
			addkeydir (filename);
			zfile_fseek (f, 0, SEEK_END);
			size = zfile_ftell (f) - sizeof tmp;
			zfile_fseek (f, sizeof tmp, SEEK_SET);
			buf = xmalloc (uae_u8, size);
			zfile_fread (buf, size, 1, f);
			df = zfile_fopen_empty (f, L"tmp.rom", size);
			decode_cloanto_rom_do (buf, size, size);
			zfile_fwrite (buf, size, 1, df);
			zfile_fclose (f);
			xfree (buf);
			zfile_fseek (df, 0, SEEK_SET);
			f = df;
		} else {
			zfile_fseek (f, -((int)sizeof tmp), SEEK_CUR);
		}
	}
	return f;
}
Beispiel #10
0
static int unpack2 (const TCHAR *src, const TCHAR *match, int level)
{
	struct zdirectory *h;
	struct zvolume *zv;
	int ret;
	uae_u8 *b;
	int size;
	TCHAR fn[MAX_DPATH];

	ret = 0;
	zv = zfile_fopen_archive_root (src, ZFD_ALL);
	if (zv == NULL) {
		geterror();
		_tprintf (_T("Couldn't open archive '%s'\n"), src);
		return 0;
	}
	h = zfile_opendir_archive (src);
	if (!h) {
		geterror();
		_tprintf (_T("Couldn't open directory '%s'\n"), src);
		return 0;
	}
	while (zfile_readdir_archive (h, fn)) {
		TCHAR tmp[MAX_DPATH];
		TCHAR *dst;
		struct zfile *s, *d;
		int isdir, flags;

		_tcscpy (tmp, src);
		_tcscat (tmp, sep);
		_tcscat (tmp, fn);
		zfile_fill_file_attrs_archive (tmp, &isdir, &flags, NULL);
		if (isdir) {
			TCHAR *p = _tcsstr (fn, _T(".DIR"));
			if (isdir == ZNODE_VDIR && p && _tcslen (p) == 4) {
				p[0] = 0;
				if (pattern_match (fn, match))
					continue;
				p[0] = '.';
			}
			unpack2 (tmp, match, 1);
			continue;
		}

		if (pattern_match (fn, match)) {
			struct mystat st;

			if (!zfile_stat_archive (tmp, &st)) {
				st.mtime.tv_sec = st.mtime.tv_usec = -1;
			}
			found = 1;
			dst = fn;
			s = zfile_open_archive (tmp, ZFD_NORECURSE);
			if (!s) {
				geterror();
				_tprintf (_T("Couldn't open '%s' for reading\n"), tmp);
				continue;
			}
			zfile_fseek (s, 0, SEEK_END); 
			size = zfile_ftell (s);
			zfile_fseek (s, 0, SEEK_SET);
			b = xcalloc (uae_u8, size);
			if (b) {
				if (zfile_fread (b, size, 1, s) == 1) {
					d = zfile_fopen (dst, _T("wb"), 0);
					if (d) {
						if (zfile_fwrite (b, size, 1, d) == 1) {
							ret = 1;
							_tprintf (_T("%s extracted, %d bytes\n"), dst, size);
						}
						zfile_fclose (d);
						setdate (dst, st.mtime.tv_sec);
					}
				}
				xfree (b);
			}
			zfile_fclose (s);
		}
	}
	geterror ();
	if (!found && !level) {
		_tprintf (_T("'%s' not matched\n"), match);
	}
	return ret;
}
Beispiel #11
0
static int unpack (const TCHAR *src, const TCHAR *filename, const TCHAR *dst, int out, int all, int level)
{
	struct zdirectory *h;
	struct zvolume *zv;
	int ret;
	uae_u8 *b;
	int size;
	TCHAR fn[MAX_DPATH];

	ret = 0;
	zv = zfile_fopen_archive_root (src, ZFD_ALL);
	if (zv == NULL) {
		geterror();
		_tprintf (_T("Couldn't open archive '%s'\n"), src);
		return 0;
	}
	h = zfile_opendir_archive (src);
	if (!h) {
		geterror();
		_tprintf (_T("Couldn't open directory '%s'\n"), src);
		return 0;
	}
	while (zfile_readdir_archive (h, fn)) {
		if (all || !_tcsicmp (filename, fn)) {
			TCHAR tmp[MAX_DPATH];
			struct zfile *s, *d;
			struct mystat st;

			found = 1;
			_tcscpy (tmp, src);
			_tcscat (tmp, sep);
			_tcscat (tmp, fn);
			if (!zfile_stat_archive (tmp, &st)) {
				_tprintf (_T("Couldn't stat '%s'\n"), tmp);
				continue;
			}
			if (dst == NULL || all)
				dst = fn;
			if (st.mode) {
				if (all > 0)
					continue;
				if (all < 0) {
					TCHAR oldcur[MAX_DPATH];
					my_mkdir (fn);
					my_setcurrentdir (fn, oldcur);
					unpack (tmp, fn, dst, out, all, 1);
					my_setcurrentdir (oldcur, NULL);
					setdate (dst, st.mtime.tv_sec);
					continue;
				}
				_tprintf (_T("Directory extraction not yet supported\n"));
				return 0;
			}

			s = zfile_open_archive (tmp, ZFD_ARCHIVE | ZFD_NORECURSE);
			if (!s) {
				geterror();
				_tprintf (_T("Couldn't open '%s' for reading\n"), src);
				continue;
			}
			zfile_fseek (s, 0, SEEK_END);
			size = zfile_ftell (s);
			zfile_fseek (s, 0, SEEK_SET);
			b = xcalloc (uae_u8, size);
			if (b) {
				if (zfile_fread (b, size, 1, s) == 1) {
					if (out) {
						_tprintf (_T("\n"));
						fwrite (b, size, 1, stdout);
					} else {
						d = zfile_fopen (dst, _T("wb"), 0);
						if (d) {
							if (zfile_fwrite (b, size, 1, d) == 1) {
								ret = 1;
								_tprintf (_T("%s extracted, %d bytes\n"), dst, size);
							}
							zfile_fclose (d);
							setdate (dst, st.mtime.tv_sec);
						}
					}
				}
				xfree (b);
			}
			zfile_fclose (s);
			if (!all)
				break;
		}
	}
	geterror ();
	if (!found && !level) {
		if (filename[0])
			_tprintf (_T("'%s' not found\n"), filename);
		else
			_tprintf (_T("nothing extracted\n"));
	}
	return ret;
}
Beispiel #12
0
static USHORT Process_Track(struct zfile *fi, struct zfile *fo, UCHAR *b1, UCHAR *b2, USHORT cmd, USHORT opt, USHORT pwd){
	USHORT hcrc, dcrc, usum, number, pklen1, pklen2, unpklen, l, r;
	UCHAR cmode, flags;


	l = (USHORT)zfile_fread(b1,1,THLEN,fi);

	if (l != THLEN) {
		if (l==0)
			return DMS_FILE_END;
		else
			return ERR_SREAD;
	}

	/*  "TR" identifies a Track Header  */
	if ((b1[0] != 'T')||(b1[1] != 'R')) return ERR_NOTTRACK;

	/*  Track Header CRC  */
	hcrc = (USHORT)((b1[THLEN-2] << 8) | b1[THLEN-1]);

	if (CreateCRC(b1,(ULONG)(THLEN-2)) != hcrc) return ERR_THCRC;

	number = (USHORT)((b1[2] << 8) | b1[3]);	/*  Number of track  */
	pklen1 = (USHORT)((b1[6] << 8) | b1[7]);	/*  Length of packed track data as in archive  */
	pklen2 = (USHORT)((b1[8] << 8) | b1[9]);	/*  Length of data after first unpacking  */
	unpklen = (USHORT)((b1[10] << 8) | b1[11]);	/*  Length of data after subsequent rle unpacking */
	flags = b1[12];		/*  control flags  */
	cmode = b1[13];		/*  compression mode used  */
	usum = (USHORT)((b1[14] << 8) | b1[15]);	/*  Track Data CheckSum AFTER unpacking  */
	dcrc = (USHORT)((b1[16] << 8) | b1[17]);	/*  Track Data CRC BEFORE unpacking  */

	if (cmd == CMD_VIEWFULL) {
		if (number==80)
			write_log (" FileID   ");
		else if (number==0xffff)
			write_log (" Banner   ");
		else if ((number==0) && (unpklen==1024))
			write_log (" FakeBB   ");
		else
			write_log ("   %2d     ",(short)number);

	    write_log ("%5d    %5d   %s  %04X  %04X  %04X    %0d\n", pklen1, unpklen, modes[cmode], usum, hcrc, dcrc, flags);
	}

	if ((pklen1 > TRACK_BUFFER_LEN) || (pklen2 >TRACK_BUFFER_LEN) || (unpklen > TRACK_BUFFER_LEN)) return ERR_BIGTRACK;

	if (zfile_fread(b1,1,(size_t)pklen1,fi) != pklen1) return ERR_SREAD;

	if (CreateCRC(b1,(ULONG)pklen1) != dcrc) return ERR_TDCRC;

	/*  track 80 is FILEID.DIZ, track 0xffff (-1) is Banner  */
	/*  and track 0 with 1024 bytes only is a fake boot block with more advertising */
	/*  FILE_ID.DIZ is never encrypted  */

	if (pwd && (number!=80)) dms_decrypt(b1,pklen1);

	if ((cmd == CMD_UNPACK) && (number<80) && (unpklen>2048)) {
		r = Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags);
		if (r != NO_PROBLEM)
			if (pwd)
				return ERR_BADPASSWD;
			else
				return r;
		if (usum != Calc_CheckSum(b2,(ULONG)unpklen))
			if (pwd)
				return ERR_BADPASSWD;
			else
				return ERR_CSUM;
		if (zfile_fwrite(b2,1,(size_t)unpklen,fo) != unpklen) return ERR_CANTWRITE;
	}

	if ((cmd == CMD_SHOWBANNER) && (number == 0xffff)){
		r = Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags);
		if (r != NO_PROBLEM)
			if (pwd)
				return ERR_BADPASSWD;
			else
				return r;
		if (usum != Calc_CheckSum(b2,(ULONG)unpklen))
			if (pwd)
				return ERR_BADPASSWD;
			else
				return ERR_CSUM;
		printbandiz(b2,unpklen);
	}

	if ((cmd == CMD_SHOWDIZ) && (number == 80)) {
		r = Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags);
		if (r != NO_PROBLEM) return r;
		if (usum != Calc_CheckSum(b2,(ULONG)unpklen)) return ERR_CSUM;
		printbandiz(b2,unpklen);
	}

	return NO_PROBLEM;

}
Beispiel #13
0
static USHORT Process_Track(struct zfile *fi, struct zfile *fo, UCHAR *b1, UCHAR *b2, USHORT cmd, USHORT opt, int dmsflags, struct zfile **extra){
	USHORT hcrc, dcrc, usum, number, pklen1, pklen2, unpklen, l;
	UCHAR cmode, flags;
	int crcerr = 0;


	l = (USHORT)zfile_fread(b1,1,THLEN,fi);

	if (l != THLEN) {
		if (l==0)
			return DMS_FILE_END;
		else
			return ERR_SREAD;
	}

	/*  "TR" identifies a Track Header  */
	if ((b1[0] != 'T')||(b1[1] != 'R')) return ERR_NOTTRACK;

	/*  Track Header CRC  */
	hcrc = (USHORT)((b1[THLEN-2] << 8) | b1[THLEN-1]);

	if (dms_CreateCRC(b1,(ULONG)(THLEN-2)) != hcrc) return ERR_THCRC;

	number = (USHORT)((b1[2] << 8) | b1[3]);	/*  Number of track  */
	pklen1 = (USHORT)((b1[6] << 8) | b1[7]);	/*  Length of packed track data as in archive  */
	pklen2 = (USHORT)((b1[8] << 8) | b1[9]);	/*  Length of data after first unpacking  */
	unpklen = (USHORT)((b1[10] << 8) | b1[11]);	/*  Length of data after subsequent rle unpacking */
	flags = b1[12];		/*  control flags  */
	cmode = b1[13];		/*  compression mode used  */
	usum = (USHORT)((b1[14] << 8) | b1[15]);	/*  Track Data CheckSum AFTER unpacking  */
	dcrc = (USHORT)((b1[16] << 8) | b1[17]);	/*  Track Data CRC BEFORE unpacking  */

	if (dolog)
		write_log (L"DMS: track=%d\n", number);

	if (dolog) {
		if (number==80)
			write_log (L" FileID   ");
		else if (number==0xffff)
			write_log (L" Banner   ");
		else if ((number==0) && (unpklen==1024))
			write_log (L" FakeBB   ");
		else
			write_log (L"   %2d     ",(short)number);

		write_log (L"%5d    %5d   %s  %04X  %04X  %04X    %0d\n", pklen1, unpklen, modes[cmode], usum, hcrc, dcrc, flags);
	}

	if ((pklen1 > TRACK_BUFFER_LEN) || (pklen2 >TRACK_BUFFER_LEN) || (unpklen > TRACK_BUFFER_LEN)) return ERR_BIGTRACK;

	if (zfile_fread(b1,1,(size_t)pklen1,fi) != pklen1) return ERR_SREAD;

	if (dms_CreateCRC(b1,(ULONG)pklen1) != dcrc) {
		log_error (number);
		crcerr = 1;
	}
	/*  track 80 is FILEID.DIZ, track 0xffff (-1) is Banner  */
	/*  and track 0 with 1024 bytes only is a fake boot block with more advertising */
	/*  FILE_ID.DIZ is never encrypted  */

	//if (pwd && (number!=80)) dms_decrypt(b1,pklen1);

	if ((cmd == CMD_UNPACK) && (number<80) && (unpklen>2048)) {
		memset(b2, 0, unpklen);
		if (!crcerr)
			Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags, number, pklen1, usum, dmsflags & DMSFLAG_ENCRYPTED);
		if (number == 0 && zfile_ftell (fo) == 512 * 22) {
			// did we have another cylinder 0 already?
			uae_u8 *p;
			zfile_fseek (fo, 0, SEEK_SET);
			p = xcalloc (uae_u8, 512 * 22);
			zfile_fread (p, 512 * 22, 1, fo);
			addextra(L"BigFakeBootBlock", extra, p, 512 * 22);
			xfree (p);
		}
		zfile_fseek (fo, number * 512 * 22 * ((dmsflags & DMSFLAG_HD) ? 2 : 1), SEEK_SET);
		if (zfile_fwrite(b2,1,(size_t)unpklen,fo) != unpklen)
			return ERR_CANTWRITE;
	} else if (number == 0 && unpklen == 1024) {
		memset(b2, 0, unpklen);
		if (!crcerr)
			Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags, number, pklen1, usum, dmsflags & DMSFLAG_ENCRYPTED);
		addextra(L"FakeBootBlock", extra, b2, unpklen);
	}

	if (crcerr)
		return NO_PROBLEM;

	if (number == 0xffff && extra){
		Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags, number, pklen1, usum, dmsflags & DMSFLAG_ENCRYPTED);
		addextra(L"Banner", extra, b2, unpklen);
		//printbandiz(b2,unpklen);
	}

	if (number == 80 && extra) {
		Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags, number, pklen1, usum, dmsflags & DMSFLAG_ENCRYPTED);
		addextra(L"FILEID.DIZ", extra, b2, unpklen);
		//printbandiz(b2,unpklen);
	}

	return NO_PROBLEM;

}
Beispiel #14
0
struct zfile *read_rom (struct romdata **prd)
{
	struct romdata *rd2 = *prd;
	struct romdata *rd = *prd;
	TCHAR *name;
	int id = rd->id;
	uae_u32 crc32;
	int size;
	uae_u8 *buf, *buf2;

	/* find parent node */
	for (;;) {
		if (rd2 == &roms[0])
			break;
		if (rd2[-1].id != id)
			break;
		rd2--;
	}
	*prd = rd2;
	size = rd2->size;
	crc32 = rd2->crc32;
	name = rd->name;
	buf = xmalloc (uae_u8, size * 2);
	memset (buf, 0xff, size * 2);
	if (!buf)
		return NULL;
	buf2 = buf + size;
	while (rd->id == id) {
		int i, j, add;
		int ok = 0;
		uae_u32 flags = rd->type;
		int odd = (flags & ROMTYPE_ODD) ? 1 : 0;

		add = 0;
		for (i = 0; i < 2; i++) {
			memset (buf, 0, size);
			if (!(flags & (ROMTYPE_EVEN | ROMTYPE_ODD))) {
				read_rom_file (buf, rd);
				if (flags & ROMTYPE_CD32) {
					memcpy (buf2, buf, size);
					mergecd32 (buf, buf2, size);
				}
				add = 1;
				i++;
			} else {
				int romsize = size / 2;
				if (i)
					odd = !odd;
				if (flags & ROMTYPE_8BIT) {
					read_rom_file (buf2, rd);
					if (flags & ROMTYPE_BYTESWAP)
						byteswap (buf2, romsize);
					if (flags & ROMTYPE_SCRAMBLED)
						descramble (rd, buf2, romsize, odd);
					for (j = 0; j < size; j += 2)
						buf[j + odd] = buf2[j / 2];
					read_rom_file (buf2, rd + 1);
					if (flags & ROMTYPE_BYTESWAP)
						byteswap (buf2, romsize);
					if (flags & ROMTYPE_SCRAMBLED)
						descramble (rd + 1, buf2, romsize, !odd);
					for (j = 0; j < size; j += 2)
						buf[j + (1 - odd)] = buf2[j / 2];
				} else {
					read_rom_file (buf2, rd);
					if (flags & ROMTYPE_BYTESWAP)
						byteswap (buf2, romsize);
					if (flags & ROMTYPE_SCRAMBLED)
						descramble (rd, buf2, romsize, odd);
					for (j = 0; j < size; j += 4) {
						buf[j + 2 * odd + 0] = buf2[j / 2 + 0];
						buf[j + 2 * odd + 1] = buf2[j / 2 + 1];
					}
					read_rom_file (buf2, rd + 1);
					if (flags & ROMTYPE_BYTESWAP)
						byteswap (buf2, romsize);
					if (flags & ROMTYPE_SCRAMBLED)
						descramble (rd + 1, buf2, romsize, !odd);
					for (j = 0; j < size; j += 4) {
						buf[j + 2 * (1 - odd) + 0] = buf2[j / 2 + 0];
						buf[j + 2 * (1 - odd) + 1] = buf2[j / 2 + 1];
					}
				}
				add = 2;
			}
			if (get_crc32 (buf, size) == crc32) {
				ok = 1;
			}
			if (!ok && (rd->type & ROMTYPE_AR)) {
				uae_u8 tmp[2];
				tmp[0] = buf[0];
				tmp[1] = buf[1];
				buf[0] = buf[1] = 0;
				if (get_crc32 (buf, size) == crc32)
					ok = 1;
				buf[0] = tmp[0];
				buf[1] = tmp[1];
			}
			if (!ok) {
				/* perhaps it is byteswapped without byteswap entry? */
				byteswap (buf, size);
				if (get_crc32 (buf, size) == crc32)
					ok = 1;
			}
			if (ok) {
				struct zfile *zf = zfile_fopen_empty (NULL, name, size);
				if (zf) {
					zfile_fwrite (buf, size, 1, zf);
					zfile_fseek (zf, 0, SEEK_SET);
				}
				xfree (buf);
				return zf;
			}
		}
		rd += add;

	}
	xfree (buf);
	return NULL;
}