Merged latest WinUAE and uae4arm changes. Added 64-bit support.
This commit is contained in:
parent
f7e40e29f8
commit
dd0c748dde
172 changed files with 33410 additions and 16837 deletions
507
src/hardfile.cpp
507
src/hardfile.cpp
|
@ -23,31 +23,11 @@
|
|||
#include "scsi.h"
|
||||
#include "gayle.h"
|
||||
#include "execio.h"
|
||||
#include "zfile.h"
|
||||
|
||||
#define HDF_SUPPORT_NSD 1
|
||||
#define HDF_SUPPORT_TD64 1
|
||||
#define HDF_SUPPORT_DS 1
|
||||
#define HDF_SUPPORT_DS_PARTITION 0
|
||||
|
||||
#undef DEBUGME
|
||||
#define hf_log(fmt, ...)
|
||||
#define hf_log2(fmt, ...)
|
||||
#define scsi_log(fmt, ...)
|
||||
#define hf_log3(fmt, ...)
|
||||
|
||||
//#define DEBUGME
|
||||
#ifdef DEBUGME
|
||||
#undef hf_log
|
||||
#define hf_log write_log
|
||||
#undef hf_log2
|
||||
#define hf_log2 write_log
|
||||
#undef hf_log3
|
||||
#define hf_log3 write_log
|
||||
#undef scsi_log
|
||||
#define scsi_log write_log
|
||||
#endif
|
||||
|
||||
int enable_ds_partition_hdf;
|
||||
|
||||
#define MAX_ASYNC_REQUESTS 50
|
||||
#define ASYNC_REQUEST_NONE 0
|
||||
|
@ -59,14 +39,15 @@ struct hardfileprivdata {
|
|||
uae_u8 *d_request_iobuf[MAX_ASYNC_REQUESTS];
|
||||
int d_request_type[MAX_ASYNC_REQUESTS];
|
||||
uae_u32 d_request_data[MAX_ASYNC_REQUESTS];
|
||||
smp_comm_pipe requests;
|
||||
int thread_running;
|
||||
uae_thread_id thread_id;
|
||||
uae_sem_t sync_sem;
|
||||
uaecptr base;
|
||||
int changenum;
|
||||
uaecptr changeint;
|
||||
smp_comm_pipe requests;
|
||||
int thread_running;
|
||||
uae_thread_id thread_id;
|
||||
uae_sem_t sync_sem;
|
||||
uaecptr base;
|
||||
int changenum;
|
||||
uaecptr changeint;
|
||||
struct scsi_data *sd;
|
||||
bool directorydrive;
|
||||
};
|
||||
|
||||
#define HFD_CHD_OTHER 5
|
||||
|
@ -109,13 +90,6 @@ static void getchs2 (struct hardfiledata *hfd, int *cyl, int *cylsec, int *head,
|
|||
int heads;
|
||||
int sectors = 63;
|
||||
|
||||
if (hfd->ci.physical_geometry) {
|
||||
*cyl = hfd->ci.pcyls;
|
||||
*tracksec = hfd->ci.psecs;
|
||||
*head = hfd->ci.pheads;
|
||||
*cylsec = (*head) * (*tracksec);
|
||||
return;
|
||||
}
|
||||
/* do we have RDB values? */
|
||||
if (hfd->rdbcylinders) {
|
||||
*cyl = hfd->rdbcylinders;
|
||||
|
@ -156,9 +130,6 @@ static void getchs2 (struct hardfiledata *hfd, int *cyl, int *cylsec, int *head,
|
|||
static void getchsx (struct hardfiledata *hfd, int *cyl, int *cylsec, int *head, int *tracksec)
|
||||
{
|
||||
getchs2 (hfd, cyl, cylsec, head, tracksec);
|
||||
hf_log (_T("CHS: %08X-%08X %d %d %d %d %d\n"),
|
||||
(uae_u32)(hfd->virtsize >> 32),(uae_u32)hfd->virtsize,
|
||||
*cyl, *cylsec, *head, *tracksec);
|
||||
}
|
||||
|
||||
static void getchsgeometry2 (uae_u64 size, int *pcyl, int *phead, int *psectorspertrack, int mode)
|
||||
|
@ -219,42 +190,6 @@ void getchsgeometry (uae_u64 size, int *pcyl, int *phead, int *psectorspertrack)
|
|||
getchsgeometry2 (size, pcyl, phead, psectorspertrack, 0);
|
||||
}
|
||||
|
||||
void getchsgeometry_hdf (struct hardfiledata *hfd, uae_u64 size, int *pcyl, int *phead, int *psectorspertrack)
|
||||
{
|
||||
uae_u8 block[512];
|
||||
int i;
|
||||
uae_u64 minsize = 512 * 1024 * 1024;
|
||||
|
||||
if (size <= minsize) {
|
||||
*phead = 1;
|
||||
*psectorspertrack = 32;
|
||||
}
|
||||
memset (block, 0, sizeof block);
|
||||
if (hfd) {
|
||||
hdf_read (hfd, block, 0, 512);
|
||||
if (block[0] == 'D' && block[1] == 'O' && block[2] == 'S') {
|
||||
int mode;
|
||||
for (mode = 0; mode < 2; mode++) {
|
||||
uae_u32 rootblock;
|
||||
uae_u32 chk = 0;
|
||||
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);
|
||||
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 &&
|
||||
block[4] == 0 && block[5] == 0 && block[6] == 0 && block[7] == 0 &&
|
||||
block[8] == 0 && block[9] == 0 && block[10] == 0 && block[11] == 0 &&
|
||||
block[508] == 0 && block[509] == 0 && block[510] == 0 && block[511] == 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getchsgeometry2 (size, pcyl, phead, psectorspertrack, size <= minsize ? 1 : 2);
|
||||
}
|
||||
|
||||
void getchspgeometry (uae_u64 total, int *pcyl, int *phead, int *psectorspertrack, bool idegeometry)
|
||||
{
|
||||
uae_u64 blocks = total / 512;
|
||||
|
@ -351,26 +286,56 @@ static uae_u32 get_filesys_version(uae_u8 *fs, int size)
|
|||
return (ver << 16) | rev;
|
||||
}
|
||||
|
||||
// hardware block size is always 256 or 512
|
||||
// filesystem block size can be 256, 512 or larger
|
||||
static void create_virtual_rdb (struct hardfiledata *hfd)
|
||||
{
|
||||
uae_u8 *rdb, *part, *denv;
|
||||
uae_u8 *rdb, *part, *denv, *fs;
|
||||
int fsblocksize = hfd->ci.blocksize;
|
||||
int hardblocksize = fsblocksize >= 512 ? 512 : 256;
|
||||
int cyl = hfd->ci.surfaces * hfd->ci.sectors;
|
||||
int cyls = 262144 / (cyl * 512);
|
||||
int size = cyl * cyls * 512;
|
||||
int cyls = (262144 + (cyl * fsblocksize) - 1) / (cyl * fsblocksize);
|
||||
int size = cyl * cyls * fsblocksize;
|
||||
int idx = 0;
|
||||
uae_u8 *filesys = NULL;
|
||||
int filesyslen = 0;
|
||||
uae_u32 fsver = 0;
|
||||
|
||||
write_log(_T("Creating virtual RDB (RDB size=%d, %d blocks). H=%d S=%d HBS=%d FSBS=%d)\n"),
|
||||
size, size / hardblocksize, hfd->ci.surfaces, hfd->ci.sectors, hardblocksize, fsblocksize);
|
||||
|
||||
if (hfd->ci.filesys[0]) {
|
||||
struct zfile *f = NULL;
|
||||
TCHAR fspath[MAX_DPATH];
|
||||
cfgfile_resolve_path_out_load(hfd->ci.filesys, fspath, MAX_DPATH, PATH_HDF);
|
||||
filesys = zfile_load_file(fspath, &filesyslen);
|
||||
if (filesys) {
|
||||
fsver = get_filesys_version(filesys, filesyslen);
|
||||
if (fsver == 0xffffffff)
|
||||
fsver = (99 << 16) | 99;
|
||||
if (filesyslen & 3) {
|
||||
xfree(filesys);
|
||||
filesys = NULL;
|
||||
filesyslen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int filesysblocks = (filesyslen + hardblocksize - 5 * 4 - 1) / (hardblocksize - 5 * 4);
|
||||
|
||||
rdb = xcalloc (uae_u8, size);
|
||||
hfd->virtual_rdb = rdb;
|
||||
hfd->virtual_size = size;
|
||||
part = rdb + 512;
|
||||
pl(rdb, 0, 0x5244534b);
|
||||
pl(rdb, 1, 64);
|
||||
|
||||
pl(rdb, 0, 0x5244534b); // "RDSK"
|
||||
pl(rdb, 1, 256 / 4);
|
||||
pl(rdb, 2, 0); // chksum
|
||||
pl(rdb, 3, 7); // hostid
|
||||
pl(rdb, 4, 512); // blockbytes
|
||||
pl(rdb, 4, hardblocksize); // blockbytes
|
||||
pl(rdb, 5, 0); // flags
|
||||
pl(rdb, 6, -1); // badblock
|
||||
pl(rdb, 7, 1); // part
|
||||
pl(rdb, 8, -1); // fs
|
||||
pl(rdb, 7, idx + 1); // part
|
||||
pl(rdb, 8, filesys ? idx + 2 : -1); // fs
|
||||
pl(rdb, 9, -1); // driveinit
|
||||
pl(rdb, 10, -1); // reserved
|
||||
pl(rdb, 11, -1); // reserved
|
||||
|
@ -378,10 +343,10 @@ static void create_virtual_rdb (struct hardfiledata *hfd)
|
|||
pl(rdb, 13, -1); // reserved
|
||||
pl(rdb, 14, -1); // reserved
|
||||
pl(rdb, 15, -1); // reserved
|
||||
pl(rdb, 16, hfd->ci.highcyl);
|
||||
pl(rdb, 16, hfd->ci.highcyl + cyls - 1);
|
||||
pl(rdb, 17, hfd->ci.sectors);
|
||||
pl(rdb, 18, hfd->ci.surfaces);
|
||||
pl(rdb, 19, hfd->ci.interleave); // interleave
|
||||
pl(rdb, 18, hfd->ci.surfaces * fsblocksize / hardblocksize);
|
||||
pl(rdb, 19, hfd->ci.interleave);
|
||||
pl(rdb, 20, 0); // park
|
||||
pl(rdb, 21, -1); // res
|
||||
pl(rdb, 22, -1); // res
|
||||
|
@ -395,24 +360,26 @@ static void create_virtual_rdb (struct hardfiledata *hfd)
|
|||
pl(rdb, 30, -1); // res
|
||||
pl(rdb, 31, -1); // res
|
||||
pl(rdb, 32, 0); // rdbblockslo
|
||||
pl(rdb, 33, cyl * cyls); // rdbblockshi
|
||||
pl(rdb, 33, cyl * cyls * fsblocksize / hardblocksize - 1); // rdbblockshi
|
||||
pl(rdb, 34, cyls); // locyl
|
||||
pl(rdb, 35, hfd->ci.highcyl + cyls); // hicyl
|
||||
pl(rdb, 36, cyl); // cylblocks
|
||||
pl(rdb, 35, hfd->ci.highcyl + cyls - 1); // hicyl
|
||||
pl(rdb, 36, cyl * fsblocksize / hardblocksize); // cylblocks
|
||||
pl(rdb, 37, 0); // autopark
|
||||
pl(rdb, 38, 2); // highrdskblock
|
||||
pl(rdb, 38, (1 + 1 + (filesysblocks ? 2 + filesysblocks : 0) - 1)); // highrdskblock
|
||||
pl(rdb, 39, -1); // res
|
||||
ua_copy ((char*)rdb + 40 * 4, 8, hfd->vendor_id);
|
||||
ua_copy ((char*)rdb + 42 * 4, 16, hfd->product_id);
|
||||
ua_copy ((char*)rdb + 46 * 4, 4, _T("UAE"));
|
||||
rdb_crc (rdb);
|
||||
idx++;
|
||||
|
||||
pl(part, 0, 0x50415254);
|
||||
pl(part, 1, 64);
|
||||
pl(part, 2, 0);
|
||||
pl(part, 3, 0);
|
||||
pl(part, 4, -1);
|
||||
pl(part, 5, 1); // bootable
|
||||
part = rdb + hardblocksize * idx;
|
||||
pl(part, 0, 0x50415254); // "PART"
|
||||
pl(part, 1, 256 / 4);
|
||||
pl(part, 2, 0); // chksum
|
||||
pl(part, 3, 7); // hostid
|
||||
pl(part, 4, -1); // next
|
||||
pl(part, 5, hfd->ci.bootpri < -128 ? 2 : hfd->ci.bootpri == -128 ? 0 : 1); // bootable/nomount
|
||||
pl(part, 6, -1);
|
||||
pl(part, 7, -1);
|
||||
pl(part, 8, 0); // devflags
|
||||
|
@ -420,11 +387,11 @@ static void create_virtual_rdb (struct hardfiledata *hfd)
|
|||
ua_copy ((char*)part + 9 * 4 + 1, 30, hfd->ci.devname);
|
||||
|
||||
denv = part + 128;
|
||||
pl(denv, 0, 80);
|
||||
pl(denv, 1, 512 / 4);
|
||||
pl(denv, 0, 16);
|
||||
pl(denv, 1, fsblocksize / 4);
|
||||
pl(denv, 2, 0); // secorg
|
||||
pl(denv, 3, hfd->ci.surfaces);
|
||||
pl(denv, 4, hfd->ci.blocksize / 512);
|
||||
pl(denv, 4, 1);
|
||||
pl(denv, 5, hfd->ci.sectors);
|
||||
pl(denv, 6, hfd->ci.reserved);
|
||||
pl(denv, 7, 0); // prealloc
|
||||
|
@ -438,9 +405,54 @@ static void create_virtual_rdb (struct hardfiledata *hfd)
|
|||
pl(denv, 15, hfd->ci.bootpri);
|
||||
pl(denv, 16, hfd->ci.dostype);
|
||||
rdb_crc (part);
|
||||
idx++;
|
||||
|
||||
if (filesys) {
|
||||
fs = rdb + hardblocksize * idx;
|
||||
pl(fs, 0, 0x46534844); // "FSHD"
|
||||
pl(fs, 1, 256 / 4);
|
||||
pl(fs, 2, 0); // chksum
|
||||
pl(fs, 3, 7); // hostid
|
||||
pl(fs, 4, -1); // next
|
||||
pl(fs, 5, 0); // flags
|
||||
pl(fs, 8, hfd->ci.dostype);
|
||||
pl(fs, 9, fsver); // version
|
||||
pl(fs, 10, 0x100 | 0x80 | 0x20 | 0x10); // patchflags: seglist + globvec + pri + stack
|
||||
pl(fs, 15, hfd->ci.stacksize); // stack
|
||||
pl(fs, 16, hfd->ci.priority); // priority
|
||||
pl(fs, 18, idx + 1); // first lseg
|
||||
pl(fs, 19, -1); // globvec
|
||||
rdb_crc(fs);
|
||||
idx++;
|
||||
|
||||
int offset = 0;
|
||||
for (;;) {
|
||||
uae_u8 *lseg = rdb + hardblocksize * idx;
|
||||
int lsegdatasize = hardblocksize - 5 * 4;
|
||||
if (lseg + hardblocksize > rdb + size)
|
||||
break;
|
||||
pl(lseg, 0, 0x4c534547); // "LSEG"
|
||||
pl(lseg, 1, hardblocksize / 4);
|
||||
pl(lseg, 2, 0); // chksum
|
||||
pl(lseg, 3, 7); // hostid
|
||||
int v = filesyslen - offset;
|
||||
if (v <= lsegdatasize) {
|
||||
memcpy(lseg + 5 * 4, filesys + offset, v);
|
||||
pl(lseg, 4, -1);
|
||||
pl(lseg, 1, 5 + v / 4);
|
||||
rdb_crc(lseg);
|
||||
break;
|
||||
}
|
||||
memcpy(lseg + 5 * 4, filesys + offset, lsegdatasize);
|
||||
offset += lsegdatasize;
|
||||
idx++;
|
||||
pl(lseg, 4, idx); // next
|
||||
rdb_crc(lseg);
|
||||
}
|
||||
xfree(filesys);
|
||||
}
|
||||
|
||||
hfd->virtsize += size;
|
||||
|
||||
}
|
||||
|
||||
void hdf_hd_close (struct hd_hardfiledata *hfd)
|
||||
|
@ -450,35 +462,29 @@ void hdf_hd_close (struct hd_hardfiledata *hfd)
|
|||
hdf_close (&hfd->hfd);
|
||||
}
|
||||
|
||||
int hdf_hd_open(struct hd_hardfiledata *hfd)
|
||||
int hdf_hd_open (struct hd_hardfiledata *hfd)
|
||||
{
|
||||
struct uaedev_config_info *ci = &hfd->hfd.ci;
|
||||
if (hdf_open(&hfd->hfd) <= 0)
|
||||
if (hdf_open (&hfd->hfd) <= 0)
|
||||
return 0;
|
||||
hfd->hfd.unitnum = ci->uae_unitnum;
|
||||
if (ci->physical_geometry) {
|
||||
hfd->cyls = ci->pcyls;
|
||||
hfd->heads = ci->pheads;
|
||||
hfd->secspertrack = ci->psecs;
|
||||
}
|
||||
else if (ci->highcyl && ci->surfaces && ci->sectors) {
|
||||
if (ci->highcyl && ci->surfaces && ci->sectors) {
|
||||
hfd->cyls = ci->highcyl;
|
||||
hfd->heads = ci->surfaces;
|
||||
hfd->secspertrack = ci->sectors;
|
||||
}
|
||||
else {
|
||||
getchshd(&hfd->hfd, &hfd->cyls, &hfd->heads, &hfd->secspertrack);
|
||||
} else {
|
||||
getchshd (&hfd->hfd, &hfd->cyls, &hfd->heads, &hfd->secspertrack);
|
||||
}
|
||||
hfd->cyls_def = hfd->cyls;
|
||||
hfd->secspertrack_def = hfd->secspertrack;
|
||||
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);
|
||||
if (buf[0] != 0 && memcmp (buf, _T("RDSK"), 4)) {
|
||||
ci->highcyl = (hfd->hfd.virtsize / ci->blocksize) / (ci->sectors * ci->surfaces);
|
||||
ci->dostype = rl(buf);
|
||||
create_virtual_rdb(&hfd->hfd);
|
||||
ci->dostype = rl (buf);
|
||||
create_virtual_rdb (&hfd->hfd);
|
||||
while (ci->highcyl * ci->surfaces * ci->sectors > hfd->cyls_def * hfd->secspertrack_def * hfd->heads_def) {
|
||||
hfd->cyls_def++;
|
||||
}
|
||||
|
@ -488,20 +494,6 @@ int hdf_hd_open(struct hd_hardfiledata *hfd)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static uae_u32 vhd_checksum(uae_u8 *p, int offset)
|
||||
{
|
||||
int i;
|
||||
uae_u32 sum;
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < 512; i++) {
|
||||
if (offset >= 0 && i >= offset && i < offset + 4)
|
||||
continue;
|
||||
sum += p[i];
|
||||
}
|
||||
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);
|
||||
|
||||
|
@ -518,40 +510,78 @@ static int hdf_cache_write (struct hardfiledata *hfd, void *buffer, uae_u64 offs
|
|||
int hdf_open (struct hardfiledata *hfd, const TCHAR *pname)
|
||||
{
|
||||
int ret;
|
||||
TCHAR filepath[MAX_DPATH];
|
||||
|
||||
if ((!pname || pname[0] == 0) && hfd->ci.rootdir[0] == 0)
|
||||
return 0;
|
||||
hfd->byteswap = 0;
|
||||
hfd->hfd_type = 0;
|
||||
hfd->virtual_size = 0;
|
||||
hfd->virtual_rdb = NULL;
|
||||
if (!pname)
|
||||
pname = hfd->ci.rootdir;
|
||||
ret = hdf_open_target (hfd, pname);
|
||||
cfgfile_resolve_path_out_load(pname, filepath, MAX_DPATH, PATH_HDF);
|
||||
ret = hdf_open_target (hfd, filepath);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
hfd->hfd_type = 0;
|
||||
return 1;
|
||||
}
|
||||
int hdf_open (struct hardfiledata *hfd)
|
||||
{
|
||||
return hdf_open (hfd, NULL);
|
||||
int v = hdf_open (hfd, NULL);
|
||||
return v;
|
||||
}
|
||||
|
||||
void hdf_close (struct hardfiledata *hfd)
|
||||
{
|
||||
hdf_close_target (hfd);
|
||||
hfd->hfd_type = 0;
|
||||
}
|
||||
|
||||
static int hdf_read2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
|
||||
{
|
||||
return hdf_read_target (hfd, buffer, offset, len);
|
||||
int ret = 0, extra = 0;
|
||||
if (offset < hfd->virtual_size) {
|
||||
uae_s64 len2 = offset + len <= hfd->virtual_size ? len : hfd->virtual_size - offset;
|
||||
if (!hfd->virtual_rdb)
|
||||
return 0;
|
||||
memcpy(buffer, hfd->virtual_rdb + offset, len2);
|
||||
len -= len2;
|
||||
if (len <= 0)
|
||||
return len2;
|
||||
offset += len2;
|
||||
buffer = (uae_u8*)buffer + len2;
|
||||
extra = len2;
|
||||
}
|
||||
offset -= hfd->virtual_size;
|
||||
|
||||
ret = hdf_read_target (hfd, buffer, offset, len);
|
||||
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
ret += extra;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hdf_write2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
|
||||
{
|
||||
return hdf_write_target (hfd, buffer, offset, len);
|
||||
int ret = 0, extra = 0;
|
||||
// writes to virtual RDB are ignored
|
||||
if (offset < hfd->virtual_size) {
|
||||
uae_s64 len2 = offset + len <= hfd->virtual_size ? len : hfd->virtual_size - offset;
|
||||
len -= len2;
|
||||
if (len <= 0)
|
||||
return len2;
|
||||
offset += len2;
|
||||
buffer = (uae_u8*)buffer + len2;
|
||||
extra = len2;
|
||||
}
|
||||
offset -= hfd->virtual_size;
|
||||
|
||||
ret = hdf_write_target (hfd, buffer, offset, len);
|
||||
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
ret += extra;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hdf_byteswap (void *v, int len)
|
||||
|
@ -588,9 +618,6 @@ int hdf_read (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
|
|||
{
|
||||
int v;
|
||||
|
||||
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));
|
||||
|
||||
v = hdf_cache_read (hfd, buffer, offset, len);
|
||||
if (hfd->byteswap)
|
||||
hdf_byteswap (buffer, len);
|
||||
|
@ -601,9 +628,6 @@ int hdf_write (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
|
|||
{
|
||||
int v;
|
||||
|
||||
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);
|
||||
v = hdf_cache_write (hfd, buffer, offset, len);
|
||||
|
@ -623,10 +647,12 @@ static uae_u64 cmd_read(TrapContext *ctx, struct hardfiledata *hfd, uaecptr data
|
|||
return 0;
|
||||
if (!ctx) {
|
||||
addrbank *bank_data = &get_mem_bank (dataptr);
|
||||
if (!bank_data || !bank_data->check (dataptr, len))
|
||||
if (!bank_data)
|
||||
return 0;
|
||||
uae_u8 *buffer = bank_data->xlateaddr (dataptr);
|
||||
return cmd_readx (hfd, buffer, offset, len);
|
||||
if (bank_data->check (dataptr, len)) {
|
||||
uae_u8 *buffer = bank_data->xlateaddr (dataptr);
|
||||
return cmd_readx (hfd, buffer, offset, len);
|
||||
}
|
||||
}
|
||||
int total = 0;
|
||||
while (len > 0) {
|
||||
|
@ -655,10 +681,12 @@ static uae_u64 cmd_write(TrapContext *ctx, struct hardfiledata *hfd, uaecptr dat
|
|||
return 0;
|
||||
if (!ctx) {
|
||||
addrbank *bank_data = &get_mem_bank (dataptr);
|
||||
if (!bank_data || !bank_data->check (dataptr, len))
|
||||
if (!bank_data)
|
||||
return 0;
|
||||
uae_u8 *buffer = bank_data->xlateaddr (dataptr);
|
||||
return cmd_writex (hfd, buffer, offset, len);
|
||||
if (bank_data->check(dataptr, len)) {
|
||||
uae_u8 *buffer = bank_data->xlateaddr (dataptr);
|
||||
return cmd_writex (hfd, buffer, offset, len);
|
||||
}
|
||||
}
|
||||
int total = 0;
|
||||
while (len > 0) {
|
||||
|
@ -693,7 +721,7 @@ static int checkbounds (struct hardfiledata *hfd, uae_u64 offset, uae_u64 len, i
|
|||
|
||||
static bool is_writeprotected(struct hardfiledata *hfd)
|
||||
{
|
||||
return hfd->ci.readonly || hfd->dangerous || currprefs.harddrive_read_only;
|
||||
return hfd->ci.readonly || currprefs.harddrive_read_only;
|
||||
}
|
||||
|
||||
static int nodisk (struct hardfiledata *hfd)
|
||||
|
@ -1179,7 +1207,7 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
|
|||
bdsize = 0;
|
||||
if (!dbd) {
|
||||
uae_u32 blocks = (uae_u32)(hfd->virtsize / hfd->ci.blocksize);
|
||||
wl(p + 0, blocks < 0x01000000 ? blocks : 0);
|
||||
wl(p + 0, blocks >= 0x00ffffff ? 0x00ffffff : blocks);
|
||||
wl(p + 4, hfd->ci.blocksize);
|
||||
bdsize = 8;
|
||||
p += bdsize;
|
||||
|
@ -1265,11 +1293,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
|
|||
{
|
||||
int pmi = cmdbuf[8] & 1;
|
||||
uae_u32 lba = (cmdbuf[2] << 24) | (cmdbuf[3] << 16) | (cmdbuf[4] << 8) | cmdbuf[5];
|
||||
uae_u32 blocks;
|
||||
uae_u64 blocks;
|
||||
int cyl, head, tracksec;
|
||||
if (nodisk (hfd))
|
||||
goto nodisk;
|
||||
blocks = (uae_u32)(hfd->virtsize / hfd->ci.blocksize);
|
||||
blocks = hfd->virtsize / hfd->ci.blocksize;
|
||||
if (hfd->ci.max_lba)
|
||||
blocks = hfd->ci.max_lba;
|
||||
if (hdhfd) {
|
||||
|
@ -1290,7 +1318,7 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
|
|||
lba = blocks;
|
||||
blocks = lba;
|
||||
}
|
||||
wl (r, blocks - 1);
|
||||
wl (r, (uae_u32)(blocks <= 0x100000000 ? blocks - 1 : 0xffffffff));
|
||||
wl (r + 4, hfd->ci.blocksize);
|
||||
scsi_len = lr = 8;
|
||||
}
|
||||
|
@ -1505,7 +1533,7 @@ scsi_done:
|
|||
return status;
|
||||
}
|
||||
|
||||
static int handle_scsi (TrapContext *ctx, uae_u8 *iobuf, uaecptr request, struct hardfiledata *hfd, struct scsi_data *sd)
|
||||
static int handle_scsi (TrapContext *ctx, uae_u8 *iobuf, uaecptr request, struct hardfiledata *hfd, struct scsi_data *sd, bool safeonly)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -1526,46 +1554,46 @@ static int handle_scsi (TrapContext *ctx, uae_u8 *iobuf, uaecptr request, struct
|
|||
scsi_sense_len = (scsi_flags & 4) ? 4 : /* SCSIF_OLDAUTOSENSE */
|
||||
(scsi_flags & 2) ? scsi_sense_len : /* SCSIF_AUTOSENSE */
|
||||
32;
|
||||
scsi_log (_T("hdf scsiemu: cmd=%02X,%d flags=%02X sense=%p,%d data=%p,%d\n"),
|
||||
cmd, scsi_cmd_len, scsi_flags, scsi_sense, scsi_sense_len, scsi_data, scsi_len);
|
||||
|
||||
sd->cmd_len = scsi_cmd_len;
|
||||
sd->data_len = scsi_len;
|
||||
|
||||
trap_get_bytes(ctx, sd->cmd, scsi_cmd, sd->cmd_len);
|
||||
for (int i = 0; i < sd->cmd_len; i++) {
|
||||
scsi_log (_T("%02X%c"), sd->cmd[i], i < sd->cmd_len - 1 ? '.' : ' ');
|
||||
}
|
||||
scsi_log (_T("\n"));
|
||||
|
||||
scsi_emulate_analyze(sd);
|
||||
scsi_start_transfer(sd);
|
||||
if (sd->direction > 0) {
|
||||
trap_get_bytes(ctx, sd->buffer, scsi_data, sd->data_len);
|
||||
scsi_emulate_cmd(sd);
|
||||
if (safeonly && !scsi_cmd_is_safe(sd->cmd[0])) {
|
||||
sd->reply_len = 0;
|
||||
sd->data_len = 0;
|
||||
sd->status = 2;
|
||||
sd->sense_len = 18;
|
||||
sd->sense[0] = 0x70;
|
||||
sd->sense[2] = 5; /* ILLEGAL REQUEST */
|
||||
sd->sense[12] = 0x30; /* INCOMPATIBLE MEDIUM INSERTED */
|
||||
} else {
|
||||
scsi_emulate_cmd(sd);
|
||||
if (sd->direction < 0)
|
||||
trap_put_bytes(ctx, sd->buffer, scsi_data, sd->data_len);
|
||||
scsi_emulate_analyze(sd);
|
||||
if (sd->direction > 0) {
|
||||
trap_get_bytes(ctx, sd->buffer, scsi_data, sd->data_len);
|
||||
scsi_emulate_cmd(sd);
|
||||
} else {
|
||||
scsi_emulate_cmd(sd);
|
||||
if (sd->direction < 0)
|
||||
trap_put_bytes(ctx, sd->buffer, scsi_data, sd->data_len);
|
||||
}
|
||||
}
|
||||
|
||||
put_word_host(scsicmd + 18, sd->status != 0 ? 0 : sd->cmd_len); /* fake scsi_CmdActual */
|
||||
put_byte_host(scsicmd + 21, sd->status); /* scsi_Status */
|
||||
if (sd->reply_len > 0) {
|
||||
trap_put_bytes(ctx, sd->reply, scsi_data, sd->reply_len);
|
||||
scsi_log (_T("RD:"));
|
||||
int i = 0;
|
||||
while (i < sd->reply_len && i < 24) {
|
||||
scsi_log (_T("%02X%c"), sd->reply[i], i < sd->reply_len - 1 ? '.' : ' ');
|
||||
i++;
|
||||
}
|
||||
scsi_log (_T("\n"));
|
||||
}
|
||||
if (scsi_sense) {
|
||||
trap_put_bytes(ctx, sd->sense, scsi_sense, sd->sense_len < scsi_sense_len ? sd->sense_len : scsi_sense_len);
|
||||
int slen = sd->sense_len < scsi_sense_len ? sd->sense_len : scsi_sense_len;
|
||||
trap_put_bytes(ctx, sd->sense, scsi_sense, slen);
|
||||
if (scsi_sense_len > sd->sense_len) {
|
||||
trap_set_bytes(ctx, scsi_sense + sd->sense_len, 0, scsi_sense_len - sd->sense_len);
|
||||
}
|
||||
put_word_host(scsicmd + 28, slen); /* scsi_SenseActual */
|
||||
} else {
|
||||
put_word_host(scsicmd + 28, 0);
|
||||
}
|
||||
if (sd->data_len < 0) {
|
||||
put_long_host(scsicmd + 8, 0); /* scsi_Actual */
|
||||
|
@ -1604,14 +1632,6 @@ void hardfile_do_disk_change (struct uaedev_config_data *uci, bool insert)
|
|||
int fsid = uci->configoffset;
|
||||
struct hardfiledata *hfd;
|
||||
|
||||
if (uci->ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA) {
|
||||
if (uci->ci.controller_type_unit == 0) {
|
||||
gayle_modify_pcmcia_sram_unit (&uci->ci, insert);
|
||||
} else {
|
||||
gayle_modify_pcmcia_ide_unit (&uci->ci, insert);
|
||||
}
|
||||
return;
|
||||
}
|
||||
hfd = get_hardfile_data (fsid);
|
||||
if (!hfd)
|
||||
return;
|
||||
|
@ -1627,7 +1647,6 @@ static int add_async_request (struct hardfileprivdata *hfpd, uae_u8 *iobuf, uaec
|
|||
if (hfpd->d_request[i] == request) {
|
||||
hfpd->d_request_type[i] = type;
|
||||
hfpd->d_request_data[i] = data;
|
||||
hf_log (_T("old async request %p (%d) added\n"), request, type);
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
|
@ -1639,12 +1658,10 @@ static int add_async_request (struct hardfileprivdata *hfpd, uae_u8 *iobuf, uaec
|
|||
hfpd->d_request_iobuf[i] = iobuf;
|
||||
hfpd->d_request_type[i] = type;
|
||||
hfpd->d_request_data[i] = data;
|
||||
hf_log (_T("async request %p (%d) added (total=%d)\n"), request, type, i);
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
hf_log (_T("async request overflow %p!\n"), request);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1660,19 +1677,16 @@ static int release_async_request (struct hardfileprivdata *hfpd, uaecptr request
|
|||
hfpd->d_request_iobuf[i] = 0;
|
||||
hfpd->d_request_data[i] = 0;
|
||||
hfpd->d_request_type[i] = 0;
|
||||
hf_log (_T("async request %p removed\n"), request);
|
||||
return type;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
hf_log (_T("tried to remove non-existing request %p\n"), request);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void abort_async (struct hardfileprivdata *hfpd, uaecptr request, int errcode, int type)
|
||||
{
|
||||
int i;
|
||||
hf_log (_T("aborting async request %p\n"), request);
|
||||
i = 0;
|
||||
while (i < MAX_ASYNC_REQUESTS) {
|
||||
if (hfpd->d_request[i] == request && hfpd->d_request_type[i] == ASYNC_REQUEST_TEMP) {
|
||||
|
@ -1684,12 +1698,9 @@ static void abort_async (struct hardfileprivdata *hfpd, uaecptr request, int err
|
|||
i++;
|
||||
}
|
||||
i = release_async_request (hfpd, request);
|
||||
if (i >= 0) {
|
||||
hf_log (_T("asyncronous request=%08X aborted, error=%d\n"), request, errcode);
|
||||
}
|
||||
}
|
||||
|
||||
static void *hardfile_thread (void *devs);
|
||||
static int hardfile_thread (void *devs);
|
||||
static int start_thread (TrapContext *ctx, int unit)
|
||||
{
|
||||
struct hardfileprivdata *hfpd = &hardfpd[unit];
|
||||
|
@ -1730,20 +1741,34 @@ static uae_u32 REGPARAM2 hardfile_open (TrapContext *ctx)
|
|||
if (unit >= 0 && unit < MAX_FILESYSTEM_UNITS) {
|
||||
struct hardfileprivdata *hfpd = &hardfpd[unit];
|
||||
struct hardfiledata *hfd = get_hardfile_data_controller(unit);
|
||||
if (hfd && (hfd->handle_valid || hfd->drive_empty) && start_thread (ctx, unit)) {
|
||||
trap_put_word(ctx, hfpd->base + 32, trap_get_word(ctx, hfpd->base + 32) + 1);
|
||||
trap_put_long(ctx, ioreq + 24, unit); /* io_Unit */
|
||||
trap_put_byte(ctx, ioreq + 31, 0); /* io_Error */
|
||||
trap_put_byte(ctx, ioreq + 8, 7); /* ln_type = NT_REPLYMSG */
|
||||
if (!hfpd->sd)
|
||||
hfpd->sd = scsi_alloc_generic(hfd, UAEDEV_HDF);
|
||||
hf_log (_T("hardfile_open, unit %d (%d), OK\n"), unit, trap_get_dreg (ctx, 0));
|
||||
return 0;
|
||||
if (hfd) {
|
||||
if (hfd->ci.type == UAEDEV_DIR) {
|
||||
if (start_thread(ctx, unit)) {
|
||||
hfpd->directorydrive = true;
|
||||
trap_put_word(ctx, hfpd->base + 32, trap_get_word(ctx, hfpd->base + 32) + 1);
|
||||
trap_put_long(ctx, ioreq + 24, unit); /* io_Unit */
|
||||
trap_put_byte(ctx, ioreq + 31, 0); /* io_Error */
|
||||
trap_put_byte(ctx, ioreq + 8, 7); /* ln_type = NT_REPLYMSG */
|
||||
if (!hfpd->sd)
|
||||
hfpd->sd = scsi_alloc_generic(hfd, UAEDEV_DIR, unit);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if ((hfd->handle_valid || hfd->drive_empty) && start_thread(ctx, unit)) {
|
||||
hfpd->directorydrive = false;
|
||||
trap_put_word(ctx, hfpd->base + 32, trap_get_word(ctx, hfpd->base + 32) + 1);
|
||||
trap_put_long(ctx, ioreq + 24, unit); /* io_Unit */
|
||||
trap_put_byte(ctx, ioreq + 31, 0); /* io_Error */
|
||||
trap_put_byte(ctx, ioreq + 8, 7); /* ln_type = NT_REPLYMSG */
|
||||
if (!hfpd->sd)
|
||||
hfpd->sd = scsi_alloc_generic(hfd, UAEDEV_HDF, unit);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unit < 1000 || is_hardfile(unit) == FILESYS_VIRTUAL)
|
||||
if (unit < 1000)
|
||||
err = 50; /* HFERR_NoBoard */
|
||||
hf_log (_T("hardfile_open, unit %d (%d), ERR=%d\n"), unit, trap_get_dreg(ctx, 0), err);
|
||||
trap_put_long(ctx, ioreq + 20, (uae_u32)err);
|
||||
trap_put_byte(ctx, ioreq + 31, (uae_u8)err);
|
||||
return (uae_u32)err;
|
||||
|
@ -1789,6 +1814,11 @@ static void unaligned (int cmd, uae_u64 offset, uae_u64 len, int blocksize)
|
|||
blocksize);
|
||||
}
|
||||
|
||||
static bool vdisk(struct hardfileprivdata *hfdp)
|
||||
{
|
||||
return hfdp->directorydrive;
|
||||
}
|
||||
|
||||
static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struct hardfileprivdata *hfpd, uae_u8 *iobuf, uaecptr request)
|
||||
{
|
||||
uae_u32 dataptr, offset, actual = 0, cmd;
|
||||
|
@ -1806,6 +1836,8 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
|||
case CMD_READ:
|
||||
if (nodisk (hfd))
|
||||
goto no_disk;
|
||||
if (vdisk(hfpd))
|
||||
goto v_disk;
|
||||
offset = get_long_host(iobuf + 44);
|
||||
len = get_long_host(iobuf + 36); /* io_Length */
|
||||
if (offset & bmask) {
|
||||
|
@ -1832,6 +1864,8 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
|||
#if defined(HDF_SUPPORT_NSD) || defined(HDF_SUPPORT_TD64)
|
||||
if (nodisk (hfd))
|
||||
goto no_disk;
|
||||
if (vdisk(hfpd))
|
||||
goto v_disk;
|
||||
offset64 = get_long_host(iobuf + 44) | ((uae_u64)get_long_host(iobuf + 32) << 32);
|
||||
len = get_long_host(iobuf + 36); /* io_Length */
|
||||
if (offset64 & bmask) {
|
||||
|
@ -1854,6 +1888,8 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
|||
case CMD_FORMAT: /* Format */
|
||||
if (nodisk (hfd))
|
||||
goto no_disk;
|
||||
if (vdisk(hfpd))
|
||||
goto v_disk;
|
||||
if (is_writeprotected(hfd)) {
|
||||
error = 28; /* write protect */
|
||||
} else {
|
||||
|
@ -1886,6 +1922,8 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
|||
#if defined(HDF_SUPPORT_NSD) || defined(HDF_SUPPORT_TD64)
|
||||
if (nodisk (hfd))
|
||||
goto no_disk;
|
||||
if (vdisk(hfpd))
|
||||
goto v_disk;
|
||||
if (is_writeprotected(hfd)) {
|
||||
error = 28; /* write protect */
|
||||
} else {
|
||||
|
@ -1910,6 +1948,8 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
|||
|
||||
#if HDF_SUPPORT_NSD
|
||||
case NSCMD_DEVICEQUERY:
|
||||
if (vdisk(hfpd))
|
||||
goto v_disk;
|
||||
trap_put_long(ctx, dataptr + 0, 0);
|
||||
trap_put_long(ctx, dataptr + 4, 16); /* size */
|
||||
trap_put_word(ctx, dataptr + 8, NSDEVTYPE_TRACKDISK);
|
||||
|
@ -1920,8 +1960,14 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
|||
#endif
|
||||
|
||||
case CMD_GETDRIVETYPE:
|
||||
if (vdisk(hfpd))
|
||||
goto v_disk;
|
||||
#if HDF_SUPPORT_NSD
|
||||
actual = DRIVE_NEWSTYLE;
|
||||
break;
|
||||
#else
|
||||
goto no_cmd;
|
||||
#endif
|
||||
|
||||
case CMD_GETNUMTRACKS:
|
||||
{
|
||||
|
@ -1938,6 +1984,8 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
|||
getchsx (hfd, &cyl, &cylsec, &head, &tracksec);
|
||||
trap_put_long(ctx, dataptr + 0, hfd->ci.blocksize);
|
||||
size = hfd->virtsize / hfd->ci.blocksize;
|
||||
if (!size)
|
||||
size = hfd->ci.max_lba;
|
||||
if (size > 0x00ffffffff)
|
||||
size = 0xffffffff;
|
||||
trap_put_long(ctx, dataptr + 4, (uae_u32)size);
|
||||
|
@ -1967,9 +2015,20 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
|||
case CMD_CLEAR:
|
||||
case CMD_MOTOR:
|
||||
case CMD_SEEK:
|
||||
break;
|
||||
|
||||
#if HDF_SUPPORT_TD64
|
||||
case TD_SEEK64:
|
||||
if (vdisk(hfpd))
|
||||
goto v_disk;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HDF_SUPPORT_NSD
|
||||
case NSCMD_TD_SEEK64:
|
||||
break;
|
||||
if (vdisk(hfpd))
|
||||
goto v_disk;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case CMD_REMOVE:
|
||||
hfpd->changeint = get_long (request + 40);
|
||||
|
@ -1980,26 +2039,34 @@ static uae_u32 hardfile_do_io (TrapContext *ctx, struct hardfiledata *hfd, struc
|
|||
break;
|
||||
|
||||
case CMD_ADDCHANGEINT:
|
||||
if (vdisk(hfpd))
|
||||
goto v_disk;
|
||||
error = add_async_request (hfpd, iobuf, request, ASYNC_REQUEST_CHANGEINT, get_long_host(iobuf + 40));
|
||||
if (!error)
|
||||
async = 1;
|
||||
break;
|
||||
case CMD_REMCHANGEINT:
|
||||
if (vdisk(hfpd))
|
||||
goto v_disk;
|
||||
release_async_request (hfpd, request);
|
||||
break;
|
||||
|
||||
#if HDF_SUPPORT_DS
|
||||
case HD_SCSICMD: /* SCSI */
|
||||
if (!hfd->ci.sectors && !hfd->ci.surfaces && !hfd->ci.reserved) {
|
||||
error = handle_scsi(ctx, iobuf, request, hfd, hfpd->sd);
|
||||
if (vdisk(hfpd)) {
|
||||
error = handle_scsi(ctx, iobuf, request, hfd, hfpd->sd, true);
|
||||
} else if (!hfd->ci.sectors && !hfd->ci.surfaces && !hfd->ci.reserved) {
|
||||
error = handle_scsi(ctx, iobuf, request, hfd, hfpd->sd, false);
|
||||
} else { /* we don't want users trashing their "partition" hardfiles with hdtoolbox */
|
||||
error = IOERR_NOCMD;
|
||||
write_log (_T("UAEHF: HD_SCSICMD tried on regular HDF, unit %d\n"), unit);
|
||||
error = handle_scsi(ctx, iobuf, request, hfd, hfpd->sd, true);
|
||||
}
|
||||
actual = 30; // sizeof(struct SCSICmd)
|
||||
break;
|
||||
#endif
|
||||
|
||||
case CD_EJECT:
|
||||
if (vdisk(hfpd))
|
||||
goto v_disk;
|
||||
if (hfd->ci.sectors && hfd->ci.surfaces) {
|
||||
int len = get_long_host(iobuf + 36);
|
||||
if (len) {
|
||||
|
@ -2024,6 +2091,9 @@ bad_command:
|
|||
bad_len:
|
||||
error = IOERR_BADLENGTH;
|
||||
break;
|
||||
v_disk:
|
||||
error = IOERR_BadDriveType;
|
||||
break;
|
||||
no_disk:
|
||||
error = 29; /* no disk */
|
||||
break;
|
||||
|
@ -2036,9 +2106,6 @@ no_disk:
|
|||
put_long_host(iobuf + 32, actual);
|
||||
put_byte_host(iobuf + 31, error);
|
||||
|
||||
hf_log2 (_T("hf: unit=%d, request=%p, cmd=%d offset=%u len=%d, actual=%d error%=%d\n"), unit, request,
|
||||
get_word_host(iobuf + 28), get_long_host(iobuf + 44), get_long_host(iobuf + 36), actual, error);
|
||||
|
||||
return async;
|
||||
}
|
||||
|
||||
|
@ -2049,15 +2116,12 @@ static uae_u32 REGPARAM2 hardfile_abortio (TrapContext *ctx)
|
|||
struct hardfiledata *hfd = get_hardfile_data_controller(unit);
|
||||
struct hardfileprivdata *hfpd = &hardfpd[unit];
|
||||
|
||||
hf_log2 (_T("uaehf.device abortio "));
|
||||
start_thread(ctx, unit);
|
||||
if (!hfd || !hfpd || !hfpd->thread_running) {
|
||||
trap_put_byte(ctx, request + 31, 32);
|
||||
hf_log2 (_T("error\n"));
|
||||
return trap_get_byte(ctx, request + 31);
|
||||
}
|
||||
trap_put_byte(ctx, request + 31, -2);
|
||||
hf_log2 (_T("unit=%d, request=%08X\n"), unit, request);
|
||||
abort_async (hfpd, request, -2, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -2117,10 +2181,7 @@ static uae_u32 REGPARAM2 hardfile_beginio (TrapContext *ctx)
|
|||
put_byte_host(iobuf + 31, 0);
|
||||
canquick = hardfile_canquick(ctx, hfd, iobuf);
|
||||
if (((flags & 1) && canquick) || (canquick < 0)) {
|
||||
hf_log (_T("hf quickio unit=%d request=%p cmd=%d\n"), unit, request, cmd);
|
||||
if (hardfile_do_io(ctx, hfd, hfpd, iobuf, request)) {
|
||||
hf_log2 (_T("uaehf.device cmd %d bug with IO_QUICK\n"), cmd);
|
||||
}
|
||||
hardfile_do_io(ctx, hfd, hfpd, iobuf, request);
|
||||
uae_u8 v = get_byte_host(iobuf + 31);
|
||||
trap_put_bytes(ctx, iobuf + 8, request + 8, 48 - 8);
|
||||
xfree(iobuf);
|
||||
|
@ -2128,7 +2189,6 @@ static uae_u32 REGPARAM2 hardfile_beginio (TrapContext *ctx)
|
|||
uae_ReplyMsg (request);
|
||||
return v;
|
||||
} else {
|
||||
hf_log2 (_T("hf asyncio unit=%d request=%p cmd=%d\n"), unit, request, cmd);
|
||||
add_async_request(hfpd, iobuf, request, ASYNC_REQUEST_TEMP, 0);
|
||||
put_byte_host(iobuf + 30, get_byte_host(iobuf + 30) & ~1);
|
||||
trap_put_bytes(ctx, iobuf + 8, request + 8, 48 - 8);
|
||||
|
@ -2139,7 +2199,7 @@ static uae_u32 REGPARAM2 hardfile_beginio (TrapContext *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
static void *hardfile_thread (void *devs)
|
||||
static int hardfile_thread (void *devs)
|
||||
{
|
||||
struct hardfileprivdata *hfpd = (struct hardfileprivdata *)devs;
|
||||
|
||||
|
@ -2162,7 +2222,6 @@ static void *hardfile_thread (void *devs)
|
|||
release_async_request (hfpd, request);
|
||||
uae_ReplyMsg (request);
|
||||
} else {
|
||||
hf_log2 (_T("async request %08X\n"), request);
|
||||
trap_put_bytes(ctx, iobuf + 8, request + 8, 48 - 8);
|
||||
}
|
||||
uae_sem_post (&change_sem);
|
||||
|
@ -2216,7 +2275,7 @@ void hardfile_install (void)
|
|||
uae_sem_init (&change_sem, 0, 1);
|
||||
|
||||
ROM_hardfile_resname = ds (_T("uaehf.device"));
|
||||
ROM_hardfile_resid = ds (_T("UAE hardfile.device 0.4"));
|
||||
ROM_hardfile_resid = ds (_T("UAE hardfile.device 0.6"));
|
||||
|
||||
nscmd_cmd = here ();
|
||||
dw (NSCMD_DEVICEQUERY);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue