Add harddrive 0x76 partition support updates and fixes.

This commit is contained in:
Toni Wilen 2023-09-06 20:17:52 +03:00
parent 2448841a54
commit cc0137e72b
7 changed files with 265 additions and 134 deletions

View File

@ -8258,6 +8258,7 @@ static void dump_partinfo (struct hardfiledata *hfd, uae_u8 *pp)
uae_u32 block, flags;
uae_u8 buf[512];
TCHAR dt[32];
uae_u32 error = 0;
flags = rl (pp + 20);
pp[37 + pp[36]] = 0;
@ -8286,7 +8287,7 @@ static void dump_partinfo (struct hardfiledata *hfd, uae_u8 *pp)
write_log (_T("Empty drive\n"));
} else {
block = lowcyl * surfaces * spt;
if (hdf_read (hfd, buf, (uae_u64)blocksize * block, sizeof buf)) {
if (hdf_read (hfd, buf, (uae_u64)blocksize * block, sizeof buf, &error)) {
write_log (_T("First block %d dostype: %08X (%s)\n"), block, rl (buf), dostypes (dt, rl (buf)));
} else {
write_log (_T("First block %d read failed!\n"), block);
@ -8319,6 +8320,7 @@ static void dumprdbblock(const uae_u8 *buf, int block)
static void dump_rdb (UnitInfo *uip, struct hardfiledata *hfd, uae_u8 *bufrdb, uae_u8 *buf, int readblocksize)
{
TCHAR dt[32];
uae_u32 error = 0;
write_log (_T("RDB: HostID: %08x Flags: %08x\n"),
rl (bufrdb + 3 * 4), rl (bufrdb + 5 * 4));
@ -8339,7 +8341,7 @@ static void dump_rdb (UnitInfo *uip, struct hardfiledata *hfd, uae_u8 *bufrdb, u
break;
}
memset (buf, 0, readblocksize);
hdf_read (hfd, buf, partblock * hfd->ci.blocksize, readblocksize);
hdf_read (hfd, buf, partblock * hfd->ci.blocksize, readblocksize, &error);
if (!rdb_checksum ("PART", buf, partblock)) {
write_log (_T("RDB: checksum error PART block %d\n"), partblock);
dumprdbblock(buf, partblock);
@ -8362,7 +8364,7 @@ static void dump_rdb (UnitInfo *uip, struct hardfiledata *hfd, uae_u8 *bufrdb, u
break;
}
memset (buf, 0, readblocksize);
hdf_read (hfd, buf, fileblock * hfd->ci.blocksize, readblocksize);
hdf_read (hfd, buf, fileblock * hfd->ci.blocksize, readblocksize, &error);
if (!rdb_checksum ("FSHD", buf, fileblock)) {
write_log (_T("RDB: checksum error FSHD block %d\n"), fileblock);
dumprdbblock(buf, fileblock);
@ -8412,6 +8414,7 @@ static int pt_babe(TrapContext *ctx, uae_u8 *bufrdb, UnitInfo *uip, int unit_no,
struct hardfiledata *hfd = &uip->hf;
struct uaedev_config_info *ci = &uip[unit_no].hf.ci;
uae_u32 bad;
uae_u32 error = 0;
uae_u32 bs = (bufrdb[0x20] << 24) | (bufrdb[0x21] << 16) | (bufrdb[0x22] << 8) | (bufrdb[0x23] << 0);
int bscnt;
@ -8426,7 +8429,7 @@ static int pt_babe(TrapContext *ctx, uae_u8 *bufrdb, UnitInfo *uip, int unit_no,
if (bad) {
if (bad * hfd->ci.blocksize > FILESYS_MAX_BLOCKSIZE)
return 0;
hdf_read_rdb(hfd, bufrdb2, bad * hfd->ci.blocksize, hfd->ci.blocksize);
hdf_read_rdb(hfd, bufrdb2, bad * hfd->ci.blocksize, hfd->ci.blocksize, &error);
if (bufrdb2[0] != 0xBA || bufrdb2[1] != 0xD1)
return 0;
}
@ -8503,6 +8506,7 @@ static int pt_rdsk (TrapContext *ctx, uae_u8 *bufrdb, int rdblock, UnitInfo *uip
TCHAR *s;
bool showdebug = partnum == 0;
int cnt;
uae_u32 error = 0;
blocksize = rl (bufrdb + 16);
readblocksize = blocksize > hfd->ci.blocksize ? blocksize : hfd->ci.blocksize;
@ -8558,7 +8562,7 @@ static int pt_rdsk (TrapContext *ctx, uae_u8 *bufrdb, int rdblock, UnitInfo *uip
goto error;
}
memset (buf, 0, readblocksize);
hdf_read (hfd, buf, partblock * hfd->ci.blocksize, readblocksize);
hdf_read (hfd, buf, partblock * hfd->ci.blocksize, readblocksize, &error);
if (!rdb_checksum ("PART", buf, partblock)) {
err = -2;
write_log(_T("RDB: checksum error in PART block %d\n"), partblock);
@ -8636,7 +8640,7 @@ static int pt_rdsk (TrapContext *ctx, uae_u8 *bufrdb, int rdblock, UnitInfo *uip
goto error;
}
memset (buf, 0, readblocksize);
hdf_read (hfd, buf, fileblock * hfd->ci.blocksize, readblocksize);
hdf_read (hfd, buf, fileblock * hfd->ci.blocksize, readblocksize, &error);
if (!rdb_checksum ("FSHD", buf, fileblock)) {
write_log (_T("RDB: checksum error in FSHD block %d\n"), fileblock);
dumprdbblock(buf, fileblock);
@ -8671,7 +8675,7 @@ static int pt_rdsk (TrapContext *ctx, uae_u8 *bufrdb, int rdblock, UnitInfo *uip
if (!legalrdbblock (uip, lsegblock))
goto error;
memset (buf, 0, readblocksize);
hdf_read (hfd, buf, lsegblock * hfd->ci.blocksize, readblocksize);
hdf_read (hfd, buf, lsegblock * hfd->ci.blocksize, readblocksize, &error);
if (!rdb_checksum("LSEG", buf, lsegblock)) {
write_log(_T("RDB: checksum error in LSEG block %d\n"), lsegblock);
dumprdbblock(buf, lsegblock);
@ -8705,6 +8709,7 @@ static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum,
struct hardfiledata *hfd = &uip->hf;
int lastblock = 63, rdblock;
uae_u8 bufrdb[FILESYS_MAX_BLOCKSIZE];
uae_u32 error = 0;
write_log (_T("%s:\n"), uip->rootdir);
if (hfd->drive_empty) {
@ -8729,8 +8734,8 @@ static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum,
}
for (rdblock = 0; rdblock < lastblock; rdblock++) {
hdf_read_rdb (hfd, bufrdb, rdblock * hfd->ci.blocksize, hfd->ci.blocksize);
if (rdblock == 0 && bufrdb[0] == 0xBA && bufrdb[1] == 0xBE) {
hdf_read_rdb (hfd, bufrdb, rdblock * hfd->ci.blocksize, hfd->ci.blocksize, &error);
if (!error && rdblock == 0 && bufrdb[0] == 0xBA && bufrdb[1] == 0xBE) {
// A2090 "BABE" partition table?
int v = pt_babe(ctx, bufrdb, uip, unit_no, partnum, parmpacket);
if (v)
@ -8741,13 +8746,14 @@ static int rdb_mount (TrapContext *ctx, UnitInfo *uip, int unit_no, int partnum,
return pt_rdsk(ctx, bufrdb, rdblock, uip, unit_no, partnum, parmpacket);
}
if (!memcmp ("RDSK", bufrdb, 4)) {
uae_u32 error = 0;
bufrdb[0xdc] = 0;
bufrdb[0xdd] = 0;
bufrdb[0xde] = 0;
bufrdb[0xdf] = 0;
if (rdb_checksum ("RDSK", bufrdb, rdblock)) {
write_log (_T("Windows 95/98/ME trashed RDB detected, fixing..\n"));
hdf_write (hfd, bufrdb, rdblock * hfd->ci.blocksize, hfd->ci.blocksize);
hdf_write (hfd, bufrdb, rdblock * hfd->ci.blocksize, hfd->ci.blocksize, &error);
return pt_rdsk(ctx, bufrdb, rdblock, uip, unit_no, partnum, parmpacket);
}
}
@ -8813,6 +8819,7 @@ static int dofakefilesys (TrapContext *ctx, UnitInfo *uip, uaecptr parmpacket, s
int ver = -1, rev = -1;
uae_u32 dostype;
bool autofs = false;
uae_u32 error = 0;
// we already have custom filesystem loaded for earlier hardfile?
if (!ci->forceload) {
@ -8829,7 +8836,7 @@ static int dofakefilesys (TrapContext *ctx, UnitInfo *uip, uaecptr parmpacket, s
if (!ci->dostype) {
memset (buf, 0, 4);
hdf_read (&uip->hf, buf, 0, 512);
hdf_read (&uip->hf, buf, 0, 512, &error);
dostype = (buf[0] << 24) | (buf[1] << 16) |(buf[2] << 8) | buf[3];
} else {
dostype = ci->dostype;
@ -8956,6 +8963,7 @@ static uae_u32 REGPARAM2 filesys_dev_storeinfo (TrapContext *ctx)
int unit_no = no & 65535;
int sub_no = no >> 16;
int type;
uae_u32 error = 0;
if (unit_no >= MAX_FILESYSTEM_UNITS)
return -2;
@ -9085,7 +9093,7 @@ static uae_u32 REGPARAM2 filesys_dev_storeinfo (TrapContext *ctx)
memset(buf, 0, sizeof buf);
if (ci->dostype) { // forced dostype?
trap_put_long(ctx, parmpacket + 80, ci->dostype); /* dostype */
} else if (hdf_read (&uip[unit_no].hf, buf, 0, sizeof buf)) {
} else if (hdf_read (&uip[unit_no].hf, buf, 0, sizeof buf, &error)) {
uae_u32 dt = rl (buf);
if (dt != 0x00000000 && dt != 0xffffffff)
trap_put_long(ctx, parmpacket + 80, dt);

View File

@ -1425,8 +1425,9 @@ static void check_sram_flush (int addr)
int start = pcmcia_write_min & mask;
int end = (pcmcia_write_max + blocksize - 1) & mask;
int len = end - start;
uae_u32 error = 0;
if (len > 0) {
hdf_write (&pcmcia_disk->hfd, pcmcia_common + start, start, len);
hdf_write (&pcmcia_disk->hfd, pcmcia_common + start, start, len, &error);
pcmcia_write_min = -1;
pcmcia_write_max = -1;
}
@ -1511,6 +1512,7 @@ static int initpcmcia (const TCHAR *path, int readonly, int type, int reset, str
if (!pcmcia_disk->hfd.drive_empty) {
int extrasize = 0;
uae_u32 error = 0;
pcmcia_common_size = (int)pcmcia_disk->hfd.virtsize;
if (pcmcia_disk->hfd.virtsize > 4 * 1024 * 1024) {
write_log (_T("PCMCIA SRAM: too large device, %llu bytes\n"), pcmcia_disk->hfd.virtsize);
@ -1521,10 +1523,10 @@ static int initpcmcia (const TCHAR *path, int readonly, int type, int reset, str
pcmcia_common_size = 4 * 1024 * 1024;
}
pcmcia_common = xcalloc (uae_u8, pcmcia_common_size);
hdf_read (&pcmcia_disk->hfd, pcmcia_common, 0, pcmcia_common_size);
hdf_read (&pcmcia_disk->hfd, pcmcia_common, 0, pcmcia_common_size, &error);
pcmcia_card = 1;
if (extrasize >= 512 && extrasize < 1 * 1024 * 1024) {
hdf_read(&pcmcia_disk->hfd, pcmcia_attrs, pcmcia_common_size, extrasize);
hdf_read(&pcmcia_disk->hfd, pcmcia_attrs, pcmcia_common_size, extrasize, &error);
write_log(_T("PCMCIA SRAM: Attribute data read %ld bytes\n"), extrasize);
pcmcia_attrs_full = 1;
} else {

View File

@ -239,6 +239,7 @@ void getchsgeometry_hdf (struct hardfiledata *hfd, uae_u64 size, int *pcyl, int
uae_u8 block[512];
int i;
uae_u64 minsize = 512 * 1024 * 1024;
uae_u32 error = 0;
if (size <= minsize) {
*phead = 1;
@ -246,8 +247,8 @@ void getchsgeometry_hdf (struct hardfiledata *hfd, uae_u64 size, int *pcyl, int
}
memset (block, 0, sizeof block);
if (hfd) {
hdf_read(hfd, block, 0, 512);
if (block[0] == 'D' && block[1] == 'O' && block[2] == 'S') {
hdf_read(hfd, block, 0, 512, &error);
if (!error && block[0] == 'D' && block[1] == 'O' && block[2] == 'S') {
int mode;
for (mode = 0; mode < 2; mode++) {
uae_u32 rootblock;
@ -255,7 +256,7 @@ void getchsgeometry_hdf (struct hardfiledata *hfd, uae_u64 size, int *pcyl, int
getchsgeometry2 (size, pcyl, phead, psectorspertrack, mode);
rootblock = (2 + ((*pcyl) * (*phead) * (*psectorspertrack) - 1)) / 2;
memset (block, 0, sizeof block);
hdf_read(hfd, block, (uae_u64)rootblock * 512, 512);
hdf_read(hfd, block, (uae_u64)rootblock * 512, 512, &error);
for (i = 0; i < 512; i += 4)
chk += (block[i] << 24) | (block[i + 1] << 16) | (block[i + 2] << 8) | (block[i + 3] << 0);
if (!chk && block[0] == 0 && block[1] == 0 && block[2] == 0 && block[3] == 2 &&
@ -561,6 +562,8 @@ void hdf_hd_close (struct hd_hardfiledata *hfd)
int hdf_hd_open (struct hd_hardfiledata *hfd)
{
struct uaedev_config_info *ci = &hfd->hfd.ci;
uae_u32 error = 0;
if (hdf_open (&hfd->hfd) <= 0)
return 0;
hfd->hfd.unitnum = ci->uae_unitnum;
@ -580,8 +583,8 @@ int hdf_hd_open (struct hd_hardfiledata *hfd)
hfd->heads_def = hfd->heads;
if (ci->surfaces && ci->sectors) {
uae_u8 buf[512] = { 0 };
hdf_read (&hfd->hfd, buf, 0, 512);
if (buf[0] != 0 && memcmp (buf, _T("RDSK"), 4)) {
hdf_read (&hfd->hfd, buf, 0, 512, &error);
if (!error && buf[0] != 0 && memcmp (buf, _T("RDSK"), 4)) {
ci->highcyl = (int)((hfd->hfd.virtsize / ci->blocksize) / (ci->sectors * ci->surfaces));
ci->dostype = rl (buf);
create_virtual_rdb (&hfd->hfd);
@ -608,24 +611,24 @@ static uae_u32 vhd_checksum (uae_u8 *p, int offset)
return ~sum;
}
static int hdf_write2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len);
static int hdf_read2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len);
static int hdf_write2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error);
static int hdf_read2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error);
static void hdf_init_cache (struct hardfiledata *hfd)
static void hdf_init_cache(struct hardfiledata *hfd)
{
}
static void hdf_flush_cache (struct hardfiledata *hdf)
static void hdf_flush_cache(struct hardfiledata *hdf)
{
}
static int hdf_cache_read (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
static int hdf_cache_read(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
return hdf_read2 (hfd, buffer, offset, len);
return hdf_read2(hfd, buffer, offset, len, error);
}
static int hdf_cache_write (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
static int hdf_cache_write(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
return hdf_write2 (hfd, buffer, offset, len);
return hdf_write2(hfd, buffer, offset, len, error);
}
int hdf_open (struct hardfiledata *hfd, const TCHAR *pname)
@ -634,6 +637,7 @@ int hdf_open (struct hardfiledata *hfd, const TCHAR *pname)
uae_u8 tmp[512], tmp2[512];
uae_u32 v;
TCHAR filepath[MAX_DPATH];
uae_u32 error = 0;
if ((!pname || pname[0] == 0) && hfd->ci.rootdir[0] == 0)
return 0;
@ -694,7 +698,7 @@ int hdf_open (struct hardfiledata *hfd, const TCHAR *pname)
ret = hdf_open_target (hfd, filepath);
if (ret <= 0)
return ret;
if (hdf_read_target (hfd, tmp, 0, 512) != 512)
if (hdf_read_target (hfd, tmp, 0, 512, &error) != 512)
goto nonvhd;
v = gl (tmp + 8); // features
if ((v & 3) != 2)
@ -710,7 +714,7 @@ int hdf_open (struct hardfiledata *hfd, const TCHAR *pname)
goto nonvhd;
if (vhd_checksum (tmp, 8 + 4 + 4 + 8 + 4 + 4 + 4 + 4 + 8 + 8 + 4 + 4) != v)
goto nonvhd;
if (hdf_read_target (hfd, tmp2, hfd->physsize - sizeof tmp2, 512) != 512)
if (hdf_read_target (hfd, tmp2, hfd->physsize - sizeof tmp2, 512, &error) != 512)
goto end;
if (memcmp (tmp, tmp2, sizeof tmp))
goto nonvhd;
@ -722,7 +726,7 @@ int hdf_open (struct hardfiledata *hfd, const TCHAR *pname)
hfd->vhd_bamoffset = gl (tmp + 8 + 4 + 4 + 4);
if (hfd->vhd_bamoffset == 0 || hfd->vhd_bamoffset >= hfd->physsize)
goto end;
if (hdf_read_target (hfd, tmp, hfd->vhd_bamoffset, 512) != 512)
if (hdf_read_target (hfd, tmp, hfd->vhd_bamoffset, 512, &error) != 512)
goto end;
v = gl (tmp + 8 + 8 + 8 + 4 + 4 + 4);
if (vhd_checksum (tmp, 8 + 8 + 8 + 4 + 4 + 4) != v)
@ -735,7 +739,7 @@ int hdf_open (struct hardfiledata *hfd, const TCHAR *pname)
hfd->vhd_bamsize = (((hfd->virtsize + hfd->vhd_blocksize - 1) / hfd->vhd_blocksize) * 4 + 511) & ~511;
size = hfd->vhd_bamoffset + hfd->vhd_bamsize;
hfd->vhd_header = xmalloc (uae_u8, size);
if (hdf_read_target (hfd, hfd->vhd_header, 0, size) != size)
if (hdf_read_target (hfd, hfd->vhd_header, 0, size, &error) != size)
goto end;
hfd->vhd_sectormap = xmalloc (uae_u8, 512);
hfd->vhd_sectormapblock = -1;
@ -802,6 +806,7 @@ static uae_u64 vhd_read (struct hardfiledata *hfd, void *v, uae_u64 offset, uae_
{
uae_u64 read;
uae_u8 *dataptr = (uae_u8*)v;
uae_u32 error = 0;
//write_log (_T("%08x %08x\n"), (uae_u32)offset, (uae_u32)len);
read = 0;
@ -826,7 +831,7 @@ static uae_u64 vhd_read (struct hardfiledata *hfd, void *v, uae_u64 offset, uae_
if (hfd->vhd_sectormapblock != sectormapblock) {
// read sector bitmap
//write_log (_T("BM %08x\n"), sectormapblock);
if (hdf_read_target (hfd, hfd->vhd_sectormap, sectormapblock, 512) != 512) {
if (hdf_read_target (hfd, hfd->vhd_sectormap, sectormapblock, 512, &error) != 512) {
write_log (_T("vhd_read: bitmap read error\n"));
return read;
}
@ -837,7 +842,7 @@ static uae_u64 vhd_read (struct hardfiledata *hfd, void *v, uae_u64 offset, uae_
// read data block
uae_u64 block = sectoroffset * (uae_u64)512 + hfd->vhd_bitmapsize + bitmapoffsetbits * 512;
//write_log (_T("DB %08x\n"), block);
if (hdf_read_target (hfd, dataptr, block, 512) != 512) {
if (hdf_read_target (hfd, dataptr, block, 512, &error) != 512) {
write_log (_T("vhd_read: data read error\n"));
return read;
}
@ -857,7 +862,7 @@ static int vhd_write_enlarge (struct hardfiledata *hfd, uae_u32 bamoffset)
{
uae_u8 *buf, *p;
int len;
uae_u32 block;
uae_u32 block, error = 0;
int v;
len = hfd->vhd_blocksize + hfd->vhd_bitmapsize + 512;
@ -869,7 +874,7 @@ static int vhd_write_enlarge (struct hardfiledata *hfd, uae_u32 bamoffset)
}
// add footer (same as 512 byte header)
memcpy (buf + len - 512, hfd->vhd_header, 512);
v = hdf_write_target (hfd, buf, hfd->vhd_footerblock, len);
v = hdf_write_target (hfd, buf, hfd->vhd_footerblock, len, &error);
xfree (buf);
if (v != len) {
write_log (_T("vhd_enlarge: footer write error\n"));
@ -883,7 +888,7 @@ static int vhd_write_enlarge (struct hardfiledata *hfd, uae_u32 bamoffset)
p[2] = block >> 8;
p[3] = block >> 0;
// write to disk
if (hdf_write_target (hfd, hfd->vhd_header + hfd->vhd_bamoffset, hfd->vhd_bamoffset, hfd->vhd_bamsize) != hfd->vhd_bamsize) {
if (hdf_write_target (hfd, hfd->vhd_header + hfd->vhd_bamoffset, hfd->vhd_bamoffset, hfd->vhd_bamsize, &error) != hfd->vhd_bamsize) {
write_log (_T("vhd_enlarge: bam write error\n"));
return 0;
}
@ -895,6 +900,7 @@ static uae_u64 vhd_write (struct hardfiledata *hfd, void *v, uae_u64 offset, uae
{
uae_u64 written;
uae_u8 *dataptr = (uae_u8*)v;
uae_u32 error = 0;
//write_log (_T("%08x %08x\n"), (uae_u32)offset, (uae_u32)len);
written = 0;
@ -918,14 +924,14 @@ static uae_u64 vhd_write (struct hardfiledata *hfd, void *v, uae_u64 offset, uae
uae_u64 sectormapblock = sectoroffset * (uae_u64)512 + (bitmapoffsetbytes & ~511);
if (hfd->vhd_sectormapblock != sectormapblock) {
// read sector bitmap
if (hdf_read_target (hfd, hfd->vhd_sectormap, sectormapblock, 512) != 512) {
if (hdf_read_target (hfd, hfd->vhd_sectormap, sectormapblock, 512, &error) != 512) {
write_log (_T("vhd_write: bitmap read error\n"));
return written;
}
hfd->vhd_sectormapblock = sectormapblock;
}
// write data
if (hdf_write_target (hfd, dataptr, sectoroffset * (uae_u64)512 + hfd->vhd_bitmapsize + bitmapoffsetbits * 512, 512) != 512) {
if (hdf_write_target (hfd, dataptr, sectoroffset * (uae_u64)512 + hfd->vhd_bitmapsize + bitmapoffsetbits * 512, 512, &error) != 512) {
write_log (_T("vhd_write: data write error\n"));
return written;
}
@ -933,7 +939,7 @@ static uae_u64 vhd_write (struct hardfiledata *hfd, void *v, uae_u64 offset, uae
if (!(hfd->vhd_sectormap[bitmapoffsetbytes & 511] & (1 << (7 - (bitmapoffsetbits & 7))))) {
// no, we need to mark it allocated and write the modified bitmap back to the disk
hfd->vhd_sectormap[bitmapoffsetbytes & 511] |= (1 << (7 - (bitmapoffsetbits & 7)));
if (hdf_write_target (hfd, hfd->vhd_sectormap, sectormapblock, 512) != 512) {
if (hdf_write_target (hfd, hfd->vhd_sectormap, sectormapblock, 512, &error) != 512) {
write_log (_T("vhd_write: bam write error\n"));
return written;
}
@ -1083,9 +1089,10 @@ end:
return ret;
}
static int hdf_read2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
static int hdf_read2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
int ret = 0, extra = 0;
if (offset < hfd->virtual_size) {
uae_s64 len2 = offset + len <= hfd->virtual_size ? len : hfd->virtual_size - offset;
if (len > INT_MAX) {
@ -1106,7 +1113,7 @@ static int hdf_read2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, in
if (hfd->hfd_type == HFD_VHD_DYNAMIC)
ret = (int)vhd_read (hfd, buffer, offset, len);
else if (hfd->hfd_type == HFD_VHD_FIXED)
ret = hdf_read_target (hfd, buffer, offset + 512, len);
ret = hdf_read_target (hfd, buffer, offset + 512, len, error);
#ifdef WITH_CHD
else if (hfd->hfd_type == HFD_CHD_OTHER) {
chd_file *cf = (chd_file*)hfd->chd_handle;
@ -1133,7 +1140,7 @@ static int hdf_read2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, in
}
#endif
else
ret = hdf_read_target (hfd, buffer, offset, len);
ret = hdf_read_target (hfd, buffer, offset, len, error);
if (ret <= 0)
return ret;
@ -1141,7 +1148,7 @@ static int hdf_read2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, in
return ret;
}
static int hdf_write2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
static int hdf_write2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
if (len > INT_MAX)
return 0;
@ -1162,9 +1169,9 @@ static int hdf_write2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, i
offset -= hfd->virtual_size;
if (hfd->hfd_type == HFD_VHD_DYNAMIC)
ret = (int)vhd_write (hfd, buffer, offset, len);
ret = (int)vhd_write(hfd, buffer, offset, len);
else if (hfd->hfd_type == HFD_VHD_FIXED)
ret = hdf_write_target (hfd, buffer, offset + 512, len);
ret = hdf_write_target(hfd, buffer, offset + 512, len, error);
#ifdef WITH_CHD
else if (hfd->hfd_type == HFD_CHD_OTHER)
return 0;
@ -1189,7 +1196,7 @@ static int hdf_write2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, i
}
#endif
else
ret = hdf_write_target (hfd, buffer, offset, len);
ret = hdf_write_target(hfd, buffer, offset, len, error);
if (ret <= 0)
return ret;
@ -1234,10 +1241,10 @@ static void hdf_byteswap (void *v, int len)
}
}
int hdf_read_rdb (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
int hdf_read_rdb (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
int v;
v = hdf_read (hfd, buffer, offset, len);
v = hdf_read (hfd, buffer, offset, len, error);
if (v > 0 && offset < 16 * 512 && !hfd->byteswap && !hfd->adide) {
uae_u8 *buf = (uae_u8*)buffer;
bool changed = false;
@ -1251,61 +1258,76 @@ int hdf_read_rdb (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int le
write_log (_T("HDF: byteswapped RDB detected\n"));
}
if (changed)
v = hdf_read (hfd, buffer, offset, len);
v = hdf_read (hfd, buffer, offset, len, error);
}
return v;
}
int hdf_read(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
int hdf_read(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
int v;
uae_u32 error2 = 0;
if (error) {
*error = 0;
} else {
error = &error2;
}
hf_log3 (_T("cmd_read: %p %04x-%08x (%d) %08x (%d)\n"),
hf_log3(_T("cmd_read: %p %04x-%08x (%d) %08x (%d)\n"),
buffer, (uae_u32)(offset >> 32), (uae_u32)offset, (uae_u32)(offset / hfd->ci.blocksize), (uae_u32)len, (uae_u32)(len / hfd->ci.blocksize));
if (!hfd->adide) {
v = hdf_cache_read (hfd, buffer, offset, len);
v = hdf_cache_read(hfd, buffer, offset, len, error);
} else {
offset += 512;
v = hdf_cache_read (hfd, buffer, offset, len);
adide_decode (buffer, len);
v = hdf_cache_read(hfd, buffer, offset, len, error);
adide_decode(buffer, len);
}
if (hfd->byteswap)
hdf_byteswap (buffer, len);
hdf_byteswap(buffer, len);
return v;
}
int hdf_write(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
int hdf_write(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
int v;
hf_log3 (_T("cmd_write: %p %04x-%08x (%d) %08x (%d)\n"),
uae_u32 error2 = 0;
if (error) {
*error = 0;
} else {
error = &error2;
}
hf_log3(_T("cmd_write: %p %04x-%08x (%d) %08x (%d)\n"),
buffer, (uae_u32)(offset >> 32), (uae_u32)offset, (uae_u32)(offset / hfd->ci.blocksize), (uae_u32)len, (uae_u32)(len / hfd->ci.blocksize));
if (hfd->byteswap)
hdf_byteswap (buffer, len);
hdf_byteswap(buffer, len);
if (!hfd->adide) {
v = hdf_cache_write (hfd, buffer, offset, len);
v = hdf_cache_write(hfd, buffer, offset, len, error);
} else {
offset += 512;
adide_encode (buffer, len);
v = hdf_cache_write (hfd, buffer, offset, len);
adide_decode (buffer, len);
adide_encode(buffer, len);
v = hdf_cache_write(hfd, buffer, offset, len, error);
adide_decode(buffer, len);
}
if (hfd->byteswap)
hdf_byteswap (buffer, len);
hdf_byteswap(buffer, len);
return v;
}
static uae_u64 cmd_readx(struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len)
static uae_u64 cmd_readx(struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len, uae_u32 *error)
{
if (!len || len > INT_MAX)
return 0;
m68k_cancel_idle();
gui_flicker_led (LED_HD, hfd->unitnum, 1);
return hdf_read (hfd, dataptr, offset, (int)len);
gui_flicker_led(LED_HD, hfd->unitnum, 1);
return hdf_read(hfd, dataptr, offset, (int)len, error);
}
static uae_u64 cmd_read(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len)
static uae_u64 cmd_read(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len, uae_u32 *error)
{
if (!len || len > INT_MAX)
return 0;
@ -1315,7 +1337,7 @@ static uae_u64 cmd_read(TrapContext *ctx, struct hardfiledata *hfd, uaecptr data
return 0;
if (bank_data->check(dataptr, (uae_u32)len)) {
uae_u8 *buffer = bank_data->xlateaddr(dataptr);
return cmd_readx(hfd, buffer, offset, (uae_u32)len);
return cmd_readx(hfd, buffer, offset, (uae_u32)len, error);
}
}
int total = 0;
@ -1323,7 +1345,7 @@ static uae_u64 cmd_read(TrapContext *ctx, struct hardfiledata *hfd, uaecptr data
uae_u8 buf[RTAREA_TRAP_DATA_EXTRA_SIZE];
int max = RTAREA_TRAP_DATA_EXTRA_SIZE & ~511;
int size = (int)(len > max ? max : len);
if (cmd_readx(hfd, buf, offset, size) != size)
if (cmd_readx(hfd, buf, offset, size, error) != size)
break;
trap_put_bytes(ctx, buf, dataptr, size);
offset += size;
@ -1333,16 +1355,16 @@ static uae_u64 cmd_read(TrapContext *ctx, struct hardfiledata *hfd, uaecptr data
}
return total;
}
static uae_u64 cmd_writex(struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len)
static uae_u64 cmd_writex(struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len, uae_u32 *error)
{
if (!len || len > INT_MAX)
return 0;
m68k_cancel_idle();
gui_flicker_led (LED_HD, hfd->unitnum, 2);
return hdf_write (hfd, dataptr, offset, (uae_u32)len);
gui_flicker_led(LED_HD, hfd->unitnum, 2);
return hdf_write(hfd, dataptr, offset, (uae_u32)len, error);
}
static uae_u64 cmd_write(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len)
static uae_u64 cmd_write(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len, uae_u32 *error)
{
if (!len || len > INT_MAX)
return 0;
@ -1352,7 +1374,7 @@ static uae_u64 cmd_write(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dat
return 0;
if (bank_data->check(dataptr, (uae_u32)len)) {
uae_u8 *buffer = bank_data->xlateaddr(dataptr);
return cmd_writex(hfd, buffer, offset, len);
return cmd_writex(hfd, buffer, offset, len, error);
}
}
int total = 0;
@ -1361,7 +1383,7 @@ static uae_u64 cmd_write(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dat
int max = RTAREA_TRAP_DATA_EXTRA_SIZE & ~511;
int size = (int)(len > max ? max : len);
trap_get_bytes(ctx, buf, dataptr, size);
if (cmd_writex(hfd, buf, offset, size) != size)
if (cmd_writex(hfd, buf, offset, size, error) != size)
break;
offset += size;
dataptr += size;
@ -1493,6 +1515,7 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
bool omti = hfd->ci.unit_feature_level == HD_LEVEL_SASI_CHS;
uae_u8 sasi_sense = 0;
uae_u64 current_lba = ~0;
uae_u32 error = 0;
cmd = cmdbuf[0];
@ -1749,7 +1772,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
chkerr = checkbounds(hfd, offset, len, 1);
if (chkerr)
goto checkfail;
scsi_len = (uae_u32)cmd_readx(hfd, scsi_data, offset, len);
scsi_len = (uae_u32)cmd_readx(hfd, scsi_data, offset, len, &error);
if (error) {
chkerr = 1;
goto checkfail;
}
break;
case 0x0e: /* READ SECTOR BUFFER */
len = hfd->ci.blocksize;
@ -1785,7 +1812,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
chkerr = checkbounds(hfd, offset, len, 2);
if (chkerr)
goto checkfail;
scsi_len = (uae_u32)cmd_writex(hfd, scsi_data, offset, len);
scsi_len = (uae_u32)cmd_writex(hfd, scsi_data, offset, len, &error);
if (error) {
chkerr = 2;
goto checkfail;
}
break;
case 0x55: // MODE SELECT(10)
case 0x15: // MODE SELECT(6)
@ -2047,7 +2078,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
chkerr = checkbounds(hfd, offset, len, 1);
if (chkerr)
goto checkfail;
scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
scsi_len = (uae_u32)cmd_readx(hfd, scsi_data, offset, len, &error);
if (error) {
chkerr = 1;
goto checkfail;
}
break;
case 0x2a: /* WRITE (10) */
if (nodisk (hfd))
@ -2062,7 +2097,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
chkerr = checkbounds(hfd, offset, len, 2);
if (chkerr)
goto checkfail;
scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
scsi_len = (uae_u32)cmd_writex(hfd, scsi_data, offset, len, &error);
if (error) {
chkerr = 2;
goto checkfail;
}
break;
case 0x2f: /* VERIFY (10) */
{
@ -2080,7 +2119,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
goto checkfail;
uae_u8 *vb = xmalloc(uae_u8, hfd->ci.blocksize);
while (len > 0) {
uae_u64 readlen = cmd_readx (hfd, vb, offset, hfd->ci.blocksize);
uae_u64 readlen = cmd_readx (hfd, vb, offset, hfd->ci.blocksize, &error);
if (error) {
chkerr = 1;
goto checkfail;
}
if (readlen != hfd->ci.blocksize || memcmp (vb, scsi_data, hfd->ci.blocksize)) {
xfree (vb);
goto miscompare;
@ -2110,7 +2153,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
chkerr = checkbounds(hfd, offset, len, 1);
if (chkerr)
goto checkfail;
scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
scsi_len = (uae_u32)cmd_readx(hfd, scsi_data, offset, len, &error);
if (error) {
chkerr = 1;
goto checkfail;
}
break;
case 0xaa: /* WRITE (12) */
if (nodisk (hfd))
@ -2125,7 +2172,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
chkerr = checkbounds(hfd, offset, len, 2);
if (chkerr)
goto checkfail;
scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len, &error);
if (error) {
chkerr = 2;
goto checkfail;
}
break;
case 0x37: /* READ DEFECT DATA */
if (nodisk (hfd))
@ -2634,7 +2685,7 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
if (isbadblock(hfd, offset, len)) {
goto bad_block;
}
actual = (uae_u32)cmd_read(ctx, hfd, dataptr, offset, len);
actual = (uae_u32)cmd_read(ctx, hfd, dataptr, offset, len, &error);
break;
#if HDF_SUPPORT_TD64
@ -2665,7 +2716,7 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
if (isbadblock(hfd, offset64, len)) {
goto bad_block;
}
actual = (uae_u32)cmd_read(ctx, hfd, dataptr, offset64, len);
actual = (uae_u32)cmd_read(ctx, hfd, dataptr, offset64, len, &error);
break;
#endif
@ -2695,7 +2746,7 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
if (isbadblock(hfd, offset, len)) {
goto bad_block;
}
actual = (uae_u32)cmd_write(ctx, hfd, dataptr, offset, len);
actual = (uae_u32)cmd_write(ctx, hfd, dataptr, offset, len, &error);
}
break;
@ -2732,7 +2783,7 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
if (isbadblock(hfd, offset64, len)) {
goto bad_block;
}
actual = (uae_u32)cmd_write(ctx, hfd, dataptr, offset64, len);
actual = (uae_u32)cmd_write(ctx, hfd, dataptr, offset64, len, &error);
}
break;
#endif

15
ide.cpp
View File

@ -976,6 +976,7 @@ static void do_process_rw_command (struct ide_hdf *ide)
unsigned int cyl, head, sec, nsec, nsec_total;
uae_u64 lba;
bool last = true;
uae_u32 error = 0;
ide->data_offset = 0;
@ -1016,9 +1017,14 @@ static void do_process_rw_command (struct ide_hdf *ide)
write_log (_T("IDE%d write, %d/%d bytes, buffer offset %d\n"), ide->num, nsec * ide->blocksize, nsec_total * ide->blocksize, ide->buffer_offset);
} else {
if (ide->buffer_offset == 0) {
hdf_read(&ide->hdhfd.hfd, ide->secbuf, ide->start_lba * ide->blocksize, ide->start_nsec * ide->blocksize);
hdf_read(&ide->hdhfd.hfd, ide->secbuf, ide->start_lba * ide->blocksize, ide->start_nsec * ide->blocksize, &error);
if (IDE_LOG > 1)
write_log(_T("IDE%d initial read, %d bytes\n"), ide->num, nsec_total * ide->blocksize);
if (error) {
ide_data_ready(ide);
ide_fail_err(ide, IDE_ERR_IDNF);
return;
}
}
if (IDE_LOG > 1)
write_log (_T("IDE%d read, read %d/%d bytes, buffer offset=%d\n"), ide->num, nsec * ide->blocksize, nsec_total * ide->blocksize, ide->buffer_offset);
@ -1033,7 +1039,12 @@ static void do_process_rw_command (struct ide_hdf *ide)
if (IDE_LOG > 1)
write_log(_T("IDE%d write finished, %d bytes\n"), ide->num, ide->start_nsec * ide->blocksize);
ide->intdrq = false;
hdf_write (&ide->hdhfd.hfd, ide->secbuf, ide->start_lba * ide->blocksize, ide->start_nsec * ide->blocksize);
hdf_write(&ide->hdhfd.hfd, ide->secbuf, ide->start_lba * ide->blocksize, ide->start_nsec * ide->blocksize, &error);
if (error) {
ide_data_ready(ide);
ide_fail_err(ide, IDE_ERR_IDNF);
return;
}
}
end:

View File

@ -132,9 +132,9 @@ extern int hdf_open (struct hardfiledata *hfd);
extern int hdf_open (struct hardfiledata *hfd, const TCHAR *altname);
extern int hdf_dup (struct hardfiledata *dhfd, const struct hardfiledata *shfd);
extern void hdf_close (struct hardfiledata *hfd);
extern int hdf_read_rdb (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len);
extern int hdf_read(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len);
extern int hdf_write(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len);
extern int hdf_read_rdb (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error);
extern int hdf_read(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error);
extern int hdf_write(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error);
extern int hdf_getnumharddrives (void);
extern TCHAR *hdf_getnameharddrive (int index, int flags, int *sectorsize, int *dangerousdrive, uae_u32 *outflags);
extern int get_native_path(TrapContext *ctx, uae_u32 lock, TCHAR *out);
@ -152,8 +152,8 @@ extern int hdf_init_target (void);
extern int hdf_open_target (struct hardfiledata *hfd, const TCHAR *name);
extern int hdf_dup_target (struct hardfiledata *dhfd, const struct hardfiledata *shfd);
extern void hdf_close_target (struct hardfiledata *hfd);
extern int hdf_read_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len);
extern int hdf_write_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len);
extern int hdf_read_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error);
extern int hdf_write_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error);
extern int hdf_resize_target (struct hardfiledata *hfd, uae_u64 newsize);
extern void getchsgeometry (uae_u64 size, int *pcyl, int *phead, int *psectorspertrack);

View File

@ -1720,10 +1720,11 @@ static bool getdeviceinfo (HANDLE hDevice, struct uae_driveinfo *udi)
_tcscpy (devname, udi->device_name + 1);
if (devname[0] == ':' && devname[1] == 'P' && devname[2] == '#' &&
(devname[4] == '_' || devname[5] == '_')) {
TCHAR c1 = devname[3];
TCHAR c2 = devname[4];
TCHAR *n = udi->device_name;
if (n[0] == ':' && n[1] == 'P' && n[2] == '#' &&
(n[4] == '_' || n[5] == '_')) {
TCHAR c1 = n[3];
TCHAR c2 = n[4];
if (c1 >= '0' && c1 <= '9') {
amipart = c1 - '0';
if (c2 != '_') {
@ -1853,6 +1854,8 @@ static void lock_drive(struct hardfiledata *hfd, const TCHAR *name, HANDLE drvha
if (!hfd->ci.lock)
return;
if (hfd->flags & HFD_FLAGS_REALDRIVEPARTITION)
return;
// single partition FAT drives seem to lock this way, without need for administrator privileges
if (DeviceIoControl(drvhandle, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &written, NULL)) {
@ -1972,15 +1975,20 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname)
hfd->handle->h = INVALID_HANDLE_VALUE;
hfd_log (_T("hfd attempting to open: '%s'\n"), name);
if (name[0] == ':') {
DWORD rw = GENERIC_READ;
DWORD srw = FILE_SHARE_READ;
int drvnum = -1;
TCHAR *p = _tcschr (name + 1, ':');
if (p) {
// open partitions in shared read/write mode
if (name[0] ==':' && name[1] == 'P') {
rw |= GENERIC_WRITE;
srw |= FILE_SHARE_WRITE;
}
*p++ = 0;
// do not scan for drives if open succeeds and it is a harddrive
// to prevent spinup of sleeping drives
h = CreateFile (p,
GENERIC_READ,
FILE_SHARE_READ,
h = CreateFile (p, rw, srw,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
DWORD err = GetLastError ();
if (h == INVALID_HANDLE_VALUE && err == ERROR_FILE_NOT_FOUND) {
@ -2024,8 +2032,8 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname)
flags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS;
h = CreateFile (udi->device_path,
GENERIC_READ | (hfd->ci.readonly && !chs ? 0 : GENERIC_WRITE),
FILE_SHARE_READ | (hfd->ci.readonly && !chs ? 0 : FILE_SHARE_WRITE),
rw | (hfd->ci.readonly && !chs ? 0 : GENERIC_WRITE),
srw | (hfd->ci.readonly && !chs ? 0 : FILE_SHARE_WRITE),
NULL, OPEN_EXISTING, flags, NULL);
hfd->handle->h = h;
if (h == INVALID_HANDLE_VALUE && !hfd->ci.readonly) {
@ -2273,7 +2281,7 @@ int hdf_dup_target (struct hardfiledata *dhfd, const struct hardfiledata *shfd)
return 1;
}
static int hdf_seek (struct hardfiledata *hfd, uae_u64 offset)
static int hdf_seek (struct hardfiledata *hfd, uae_u64 offset, bool write)
{
DWORD ret;
@ -2285,14 +2293,23 @@ static int hdf_seek (struct hardfiledata *hfd, uae_u64 offset)
if (offset >= hfd->physsize - hfd->virtual_size) {
if (hfd->virtual_rdb)
return -1;
gui_message (_T("hd: tried to seek out of bounds! (%I64X >= %I64X - %I64X)\n"), offset, hfd->physsize, hfd->virtual_size);
abort ();
if (write) {
gui_message (_T("hd: tried to seek out of bounds! (%I64X >= %I64X - %I64X)\n"), offset, hfd->physsize, hfd->virtual_size);
abort ();
}
write_log(_T("hd: tried to seek out of bounds! (%I64X >= %I64X - %I64X)\n"), offset, hfd->physsize, hfd->virtual_size);
return -1;
}
offset += hfd->offset;
if (offset & (hfd->ci.blocksize - 1)) {
gui_message (_T("hd: poscheck failed, offset=%I64X not aligned to blocksize=%d! (%I64X & %04X = %04X)\n"),
if (write) {
gui_message (_T("hd: poscheck failed, offset=%I64X not aligned to blocksize=%d! (%I64X & %04X = %04X)\n"),
offset, hfd->ci.blocksize, offset, hfd->ci.blocksize, offset & (hfd->ci.blocksize - 1));
abort ();
}
write_log(_T("hd: poscheck failed, offset=%I64X not aligned to blocksize=%d! (%I64X & %04X = %04X)\n"),
offset, hfd->ci.blocksize, offset, hfd->ci.blocksize, offset & (hfd->ci.blocksize - 1));
abort ();
return -1;
}
}
if (hfd->handle_valid == HDF_HANDLE_WIN32_NORMAL) {
@ -2394,7 +2411,7 @@ static int hdf_rw (struct hardfiledata *hfd, void *bufferp, uae_u64 offset, int
size = bs - soff;
if (size > len)
size = len;
hdf_seek (hfd, offset & ~mask);
hdf_seek (hfd, offset & ~mask, dowrite != 0);
poscheck (hfd, len);
if (dowrite)
WriteFile (hfd->handle, hfd->cache, bs, &outlen2, NULL);
@ -2409,7 +2426,7 @@ static int hdf_rw (struct hardfiledata *hfd, void *bufferp, uae_u64 offset, int
len -= size;
}
while (len >= bs) { /* aligned access */
hdf_seek (hfd, offset);
hdf_seek (hfd, offset, dowrite != 0);
poscheck (hfd, len);
size = len & ~mask;
if (size > CACHE_SIZE)
@ -2435,7 +2452,7 @@ static int hdf_rw (struct hardfiledata *hfd, void *bufferp, uae_u64 offset, int
len -= size;
}
if (len > 0) { /* len > 0 && len < bs */
hdf_seek (hfd, offset);
hdf_seek (hfd, offset, dowrite != 0);
poscheck (hfd, len);
if (dowrite)
WriteFile (hfd->handle, hfd->cache, bs, &outlen2, NULL);
@ -2462,13 +2479,17 @@ int hdf_write (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
#else
static int hdf_read_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
static int hdf_read_2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
DWORD outlen = 0;
int coffset;
if (offset == 0)
if (len == 0) {
return 0;
}
if (offset == 0) {
hfd->cache_valid = 0;
}
coffset = isincache (hfd, offset, len);
if (coffset >= 0) {
memcpy (buffer, hfd->cache + coffset, len);
@ -2477,8 +2498,10 @@ static int hdf_read_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, i
hfd->cache_offset = offset;
if (offset + CACHE_SIZE > hfd->offset + (hfd->physsize - hfd->virtual_size))
hfd->cache_offset = hfd->offset + (hfd->physsize - hfd->virtual_size) - CACHE_SIZE;
if (hdf_seek(hfd, hfd->cache_offset))
if (hdf_seek(hfd, hfd->cache_offset, false)) {
*error = 45;
return 0;
}
poscheck (hfd, CACHE_SIZE);
if (hfd->handle_valid == HDF_HANDLE_WIN32_NORMAL) {
ReadFile(hfd->handle->h, hfd->cache, CACHE_SIZE, &outlen, NULL);
@ -2486,8 +2509,10 @@ static int hdf_read_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, i
outlen = (DWORD)zfile_fread(hfd->cache, 1, CACHE_SIZE, hfd->handle->zf);
}
hfd->cache_valid = 0;
if (outlen != CACHE_SIZE)
if (outlen != CACHE_SIZE) {
*error = 45;
return 0;
}
hfd->cache_valid = 1;
coffset = isincache (hfd, offset, len);
if (coffset >= 0) {
@ -2496,16 +2521,26 @@ static int hdf_read_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, i
}
write_log (_T("hdf_read: cache bug! offset=%I64d len=%d\n"), offset, len);
hfd->cache_valid = 0;
*error = 45;
return 0;
}
int hdf_read_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
int hdf_read_target(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
int got = 0;
uae_u8 *p = (uae_u8*)buffer;
uae_u32 error2 = 0;
if (hfd->drive_empty)
if (error) {
*error = 0;
} else {
error = &error2;
}
if (hfd->drive_empty) {
*error = 29;
return 0;
}
if (hfd->handle_valid == HDF_HANDLE_WIN32_CHS) {
int len2 = len;
@ -2523,7 +2558,7 @@ int hdf_read_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int
DWORD ret;
if (hfd->physsize < CACHE_SIZE) {
hfd->cache_valid = 0;
if (hdf_seek(hfd, offset))
if (hdf_seek(hfd, offset, false))
return got;
if (hfd->physsize)
poscheck (hfd, len);
@ -2536,7 +2571,7 @@ int hdf_read_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int
maxlen = len;
} else {
maxlen = len > CACHE_SIZE ? CACHE_SIZE : len;
ret = hdf_read_2 (hfd, p, offset, maxlen);
ret = hdf_read_2 (hfd, p, offset, maxlen, error);
}
got += ret;
if (ret != maxlen)
@ -2548,20 +2583,26 @@ int hdf_read_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int
return got;
}
static int hdf_write_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
static int hdf_write_2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
DWORD outlen = 0;
if (hfd->ci.readonly)
if (hfd->ci.readonly) {
*error = 28;
return 0;
if (hfd->dangerous)
}
if (hfd->dangerous) {
*error = 28;
return 0;
}
if (len == 0)
return 0;
hfd->cache_valid = 0;
if (hdf_seek(hfd, offset))
if (hdf_seek(hfd, offset, true)) {
*error = 45;
return 0;
}
poscheck (hfd, len);
memcpy (hfd->cache, buffer, len);
if (hfd->handle_valid == HDF_HANDLE_WIN32_NORMAL) {
@ -2572,12 +2613,17 @@ static int hdf_write_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset,
if (ismounted (hfd->ci.devname, hfd->handle->h)) {
gui_message (_T("\"%s\"\n\nBlock zero write attempt but drive has one or more mounted PC partitions or WinUAE does not have Administrator privileges. Erase the drive or unmount all PC partitions first."), name);
hfd->ci.readonly = true;
*error = 45;
return 0;
}
}
}
WriteFile (hfd->handle->h, hfd->cache, len, &outlen, NULL);
if (outlen != len) {
*error = 45;
}
if (offset == 0) {
DWORD err = GetLastError();
DWORD outlen2;
uae_u8 *tmp;
int tmplen = 512;
@ -2585,10 +2631,12 @@ static int hdf_write_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset,
if (tmp) {
int cmplen = tmplen > len ? len : tmplen;
memset (tmp, 0xa1, tmplen);
hdf_seek (hfd, offset);
hdf_seek (hfd, offset, true);
ReadFile (hfd->handle->h, tmp, tmplen, &outlen2, NULL);
if (memcmp (hfd->cache, tmp, cmplen) != 0 || outlen != len)
gui_message (_T("\"%s\"\n\nblock zero write failed! Make sure WinUAE has Windows Administrator privileges."), name);
if (memcmp (hfd->cache, tmp, cmplen) != 0 || outlen != len) {
gui_message (_T("\"%s\"\n\nblock zero write failed! Make sure WinUAE has Windows Administrator privileges. Error=%d"), name, err);
*error = 45;
}
VirtualFree (tmp, 0, MEM_RELEASE);
}
}
@ -2598,10 +2646,17 @@ static int hdf_write_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset,
return outlen;
}
int hdf_write_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
int hdf_write_target(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len, uae_u32 *error)
{
int got = 0;
uae_u8 *p = (uae_u8*)buffer;
uae_u32 error2 = 0;
if (error) {
*error = 0;
} else {
error = &error2;
}
if (hfd->handle_valid == HDF_HANDLE_WIN32_CHS)
return 0;
@ -2610,7 +2665,7 @@ int hdf_write_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, in
while (len > 0) {
int maxlen = len > CACHE_SIZE ? CACHE_SIZE : len;
int ret = hdf_write_2 (hfd, p, offset, maxlen);
int ret = hdf_write_2(hfd, p, offset, maxlen, error);
if (ret < 0)
return ret;
got += ret;
@ -3411,7 +3466,9 @@ TCHAR *hdf_getnameharddrive (int index, int flags, int *sectorsize, int *dangero
if (nomedia) {
_tcscpy (tmp, _T("N/A"));
} else {
if (size >= 1024 * 1024 * 1024)
if (size == 0)
_tcscpy(tmp, _T("?"));
else if (size >= 1024 * 1024 * 1024)
_stprintf (tmp, _T("%.1fG"), ((double)(uae_u32)(size / (1024 * 1024))) / 1024.0);
else if (size < 10 * 1024 * 1024)
_stprintf (tmp, _T("%lldK"), size / 1024);

View File

@ -14395,6 +14395,7 @@ static void hardfile_testrdb (struct hfdlg_vals *hdf)
uae_u8 id[512];
int i;
struct hardfiledata hfd;
uae_u32 error = 0;
memset (id, 0, sizeof id);
memset (&hfd, 0, sizeof hfd);
@ -14403,15 +14404,15 @@ static void hardfile_testrdb (struct hfdlg_vals *hdf)
hdf->rdb = 0;
if (hdf_open (&hfd, current_hfdlg.ci.rootdir) > 0) {
for (i = 0; i < 16; i++) {
hdf_read_rdb (&hfd, id, i * 512, 512);
if (i == 0 && !memcmp (id + 2, "CIS", 3)) {
hdf_read_rdb (&hfd, id, i * 512, 512, &error);
if (!error && i == 0 && !memcmp (id + 2, "CIS", 3)) {
hdf->ci.controller_type = HD_CONTROLLER_TYPE_CUSTOM_FIRST;
hdf->ci.controller_type_unit = 0;
break;
}
bool babe = id[0] == 0xBA && id[1] == 0xBE; // A2090
if (!memcmp (id, "RDSK\0\0\0", 7) || !memcmp (id, "CDSK\0\0\0", 7) || !memcmp (id, "DRKS\0\0", 6) ||
(id[0] == 0x53 && id[1] == 0x10 && id[2] == 0x9b && id[3] == 0x13 && id[4] == 0 && id[5] == 0) || babe) {
if (!error && (!memcmp (id, "RDSK\0\0\0", 7) || !memcmp (id, "CDSK\0\0\0", 7) || !memcmp (id, "DRKS\0\0", 6) ||
(id[0] == 0x53 && id[1] == 0x10 && id[2] == 0x9b && id[3] == 0x13 && id[4] == 0 && id[5] == 0) || babe)) {
// RDSK or ADIDE "encoded" RDSK
int blocksize = 512;
if (!babe)
@ -14959,6 +14960,7 @@ static void updatehdfinfo(HWND hDlg, bool force, bool defaults, bool realdrive)
TCHAR tmp[200], tmp2[200];
TCHAR idtmp[17];
bool phys = is_hdf_rdb();
uae_u32 error = 0;
bsize = 0;
if (force) {
@ -14975,7 +14977,7 @@ static void updatehdfinfo(HWND hDlg, bool force, bool defaults, bool realdrive)
if (hdf_open (&hfd, current_hfdlg.ci.rootdir) > 0) {
open = true;
for (i = 0; i < 16; i++) {
hdf_read (&hfd, id, i * 512, 512);
hdf_read (&hfd, id, i * 512, 512, &error);
bsize = hfd.virtsize;
current_hfdlg.size = hfd.virtsize;
if (!memcmp (id, "RDSK", 4) || !memcmp (id, "CDSK", 4)) {