From dde476df2b6e56a38b7e48f30c10dc4cf151f2e7 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 16 Jul 2017 20:57:02 +0300 Subject: [PATCH] HDF/HD low level metadata support. (ATA Identity, SCSI Inquiry etc..) --- cfgfile.cpp | 524 ++++++++++++++++---------- filesys.cpp | 9 +- hardfile.cpp | 39 +- ide.cpp | 339 +++++++++++++---- include/disk.h | 3 +- include/filesys.h | 2 + include/ide.h | 7 +- include/options.h | 8 +- od-win32/hardfile_win32.cpp | 727 +++++++++++++++++++++++++++++++++--- od-win32/win32gui.cpp | 414 +++++++++++++++----- 10 files changed, 1648 insertions(+), 424 deletions(-) diff --git a/cfgfile.cpp b/cfgfile.cpp index 8c0f9f6d..771f2f04 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -38,6 +38,7 @@ #include "luascript.h" #include "ethernet.h" #include "native2amiga_api.h" +#include "ini.h" #define cfgfile_warning write_log #define cfgfile_warning_obsolete write_log @@ -946,7 +947,7 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) else _tcscpy(hdcs, _T("scide")); } else if (ct == HD_CONTROLLER_TYPE_UAE) { - _tcscpy(hdcs, _T("uae")); + _stprintf(hdcs, _T("uae%d"), ci->controller_unit); } if (romtype) { for (int j = 0; hdcontrollers[j].label; j++) { @@ -973,25 +974,33 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) zfile_fputs (f, tmp2); #endif } else if (ci->type == UAEDEV_HDF || ci->type == UAEDEV_CD || ci->type == UAEDEV_TAPE) { + TCHAR *sfilesys = cfgfile_escape_min(ci->filesys); + TCHAR *sgeometry = cfgfile_escape_min(ci->geometry); _stprintf (tmp, _T("%s,%s:%s,%d,%d,%d,%d,%d,%s,%s"), ci->readonly ? _T("ro") : _T("rw"), ci->devname ? ci->devname : _T(""), str1c, ci->sectors, ci->surfaces, ci->reserved, ci->blocksize, - bp, ci->filesys ? ci->filesys : _T(""), hdcs); + bp, ci->filesys[0] ? sfilesys : _T(""), hdcs); _stprintf (tmp3, _T("%s,%s:%s%s%s,%d,%d,%d,%d,%d,%s,%s"), ci->readonly ? _T("ro") : _T("rw"), ci->devname ? ci->devname : _T(""), str1b, str2b[0] ? _T(":") : _T(""), str2b, ci->sectors, ci->surfaces, ci->reserved, ci->blocksize, - bp, ci->filesys ? ci->filesys : _T(""), hdcs); - if (ci->highcyl || ci->physical_geometry) { + bp, ci->filesys[0] ? sfilesys : _T(""), hdcs); + if (ci->highcyl || ci->physical_geometry || ci->geometry[0]) { TCHAR *s = tmp + _tcslen (tmp); TCHAR *s2 = s; _stprintf (s2, _T(",%d"), ci->highcyl); - if (ci->physical_geometry && ci->pheads && ci->psecs) { - TCHAR *s = tmp + _tcslen (tmp); + if ((ci->physical_geometry && ci->pheads && ci->psecs) || ci->geometry[0]) { + s = tmp + _tcslen (tmp); _stprintf (s, _T(",%d/%d/%d"), ci->pcyls, ci->pheads, ci->psecs); + if (ci->geometry[0]) { + s = tmp + _tcslen (tmp); + _stprintf (s, _T(",%s"), sgeometry); + } } _tcscat (tmp3, s2); + xfree(sfilesys); + xfree(sgeometry); } if (ci->controller_media_type) { _tcscat(tmp, _T(",CF")); @@ -1242,9 +1251,14 @@ static void cfgfile_write_rom_settings(const struct expansionboardsettings *ebs, } } +static bool is_custom_romboard(struct boardromconfig *br) +{ + return ((br->device_type & ROMTYPE_MASK) == ROMTYPE_UAEBOARDZ2 || (br->device_type & ROMTYPE_MASK) == ROMTYPE_UAEBOARDZ3); +} + static void cfgfile_write_board_rom(struct uae_prefs *prefs, struct zfile *f, struct multipath *mp, struct boardromconfig *br) { - TCHAR buf[256]; + TCHAR buf[MAX_DPATH]; TCHAR name[256]; const struct expansionromtype *ert; @@ -1265,7 +1279,7 @@ static void cfgfile_write_board_rom(struct uae_prefs *prefs, struct zfile *f, st _stprintf(buf, _T("%s%s_rom"), name, i ? _T("_ext") : _T("")); cfgfile_dwrite_str (f, buf, br->roms[i].romident); } - if (br->roms[i].autoboot_disabled || ert->subtypes || ert->settings || ert->id_jumper || br->device_order > 0) { + if (br->roms[i].autoboot_disabled || ert->subtypes || ert->settings || ert->id_jumper || br->device_order > 0 || is_custom_romboard(br)) { TCHAR buf2[256], *p; buf2[0] = 0; p = buf2; @@ -1300,6 +1314,23 @@ static void cfgfile_write_board_rom(struct uae_prefs *prefs, struct zfile *f, st if (br->roms[i].device_settings && ert->settings) { cfgfile_write_rom_settings(ert->settings, buf2, br->roms[i].device_settings, br->roms[i].configtext); } + if (is_custom_romboard(br)) { + if (br->roms[i].manufacturer) { + if (buf2[0]) + _tcscat(buf2, _T(",")); + TCHAR *p2 = buf2 + _tcslen(buf2); + _stprintf(p2, _T("mid=%u,pid=%u"), br->roms[i].manufacturer, br->roms[i].product); + } + if (br->roms[i].autoconfig[0]) { + uae_u8 *ac = br->roms[i].autoconfig; + if (buf2[0]) + _tcscat(buf2, _T(",")); + TCHAR *p2 = buf2 + _tcslen(buf2); + _stprintf(p2, _T("data=%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x"), + ac[0], ac[1], ac[2], ac[3], ac[4], ac[5], ac[6], ac[7], + ac[8], ac[9], ac[10], ac[11], ac[12], ac[13], ac[14], ac[15]); + } + } if (buf2[0]) cfgfile_dwrite_str (f, buf, buf2); } @@ -2183,8 +2214,12 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_write (f, _T("cpu_model"), _T("%d"), p->cpu_model); if (p->fpu_model) cfgfile_write (f, _T("fpu_model"), _T("%d"), p->fpu_model); - if (p->mmu_model) - cfgfile_write (f, _T("mmu_model"), _T("%d"), p->mmu_model); + if (p->mmu_model) { + if (p->mmu_ec) + cfgfile_write (f, _T("mmu_model"), _T("68ec0%d"), p->mmu_model % 100); + else + cfgfile_write (f, _T("mmu_model"), _T("%d"), p->mmu_model); + } if (p->ppc_mode) { cfgfile_write_str(f, _T("ppc_model"), p->ppc_model[0] ? p->ppc_model : (p->ppc_mode == 1 ? _T("automatic") : _T("manual"))); cfgfile_write_str(f, _T("ppc_cpu_idle"), ppc_cpu_idle[p->ppc_cpu_idle]); @@ -3414,11 +3449,17 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) return 1; } if (_tcscmp (option, _T("joyport0")) == 0 || _tcscmp (option, _T("joyport1")) == 0) { - inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyport0")) == 0 ? 0 : 1, -1, 0); + int port = _tcscmp (option, _T("joyport0")) == 0 ? 0 : 1; + inputdevice_joyport_config_store(p, _T(""), port, -1, 1); + inputdevice_joyport_config_store(p, _T(""), port, -1, 2); + inputdevice_joyport_config_store(p, value, port, -1, 0); return 1; } if (_tcscmp (option, _T("joyport2")) == 0 || _tcscmp (option, _T("joyport3")) == 0) { - inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyport2")) == 0 ? 2 : 3, -1, 0); + int port = _tcscmp (option, _T("joyport0")) == 0 ? 2 : 3; + inputdevice_joyport_config_store(p, _T(""), port, -1, 1); + inputdevice_joyport_config_store(p, _T(""), port, -1, 2); + inputdevice_joyport_config_store(p, value, port, -1, 0); return 1; } if (cfgfile_strval (option, value, _T("joyport0mode"), &p->jports[0].mode, joyportmodes, 0)) @@ -3901,6 +3942,23 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s break; } } + } else if (ci->controller_type == HD_CONTROLLER_TYPE_UAE) { + int ctrl = ci->controller_type; + int ctrlunit = ci->controller_type_unit; + int cunit = ci->controller_unit; + for (;;) { + for (i = 0; i < p->mountitems; i++) { + if (p->mountconfig[i].ci.controller_type == ctrl && p->mountconfig[i].ci.controller_type_unit == ctrlunit && p->mountconfig[i].ci.controller_unit == cunit) { + cunit++; + if (cunit >= MAX_FILESYSTEM_UNITS) + return NULL; + } + } + if (i == p->mountitems) { + ci->controller_unit = cunit; + break; + } + } } if (ci->type == UAEDEV_CD) { for (i = 0; i < p->mountitems; i++) { @@ -3980,7 +4038,11 @@ static void get_filesys_controller (const TCHAR *hdc, int *type, int *typenum, i if (hdunit < 0 || hdunit >= 8 + 2) hdunit = 0; } - if (hdcv > HD_CONTROLLER_TYPE_UAE) { + if (hdcv == HD_CONTROLLER_TYPE_UAE) { + hdunit = _tstol(hdc + 3); + if (hdunit >= MAX_FILESYSTEM_UNITS) + hdunit = 0; + } else if (hdcv > HD_CONTROLLER_TYPE_UAE) { bool found = false; const TCHAR *ext = _tcsrchr (hdc, '_'); if (ext) { @@ -4039,6 +4101,8 @@ static void get_filesys_controller (const TCHAR *hdc, int *type, int *typenum, i } if (idx >= MAX_DUPLICATE_EXPANSION_BOARDS) idx = MAX_DUPLICATE_EXPANSION_BOARDS - 1; + if (hdunit < 0) + hdunit = 0; *type = hdcv; *typenum = idx; *num = hdunit; @@ -4046,139 +4110,168 @@ static void get_filesys_controller (const TCHAR *hdc, int *type, int *typenum, i static bool parse_geo (const TCHAR *tname, struct uaedev_config_info *uci, struct hardfiledata *hfd, bool empty) { - struct zfile *f; - int found; - TCHAR buf[200]; - - f = zfile_fopen (tname, _T("r")); - if (!f) - return false; - found = hfd == NULL && !empty ? 2 : 0; - if (found) - write_log (_T("Geometry file '%s' detected\n"), tname); - while (zfile_fgets (buf, sizeof buf / sizeof (TCHAR), f)) { - int v; - TCHAR *sep; - - my_trim (buf); - if (_tcslen (buf) == 0) - continue; - if (buf[0] == '[' && buf[_tcslen (buf) - 1] == ']') { - if (found > 1) { - zfile_fclose (f); - return true; - } - found = 0; - buf[_tcslen (buf) - 1] = 0; - my_trim (buf + 1); - if (!_tcsicmp (buf + 1, _T("empty"))) { - if (empty) - found = 1; - } else if (!_tcsicmp (buf + 1, _T("default"))) { - if (!empty) - found = 1; - } else if (hfd) { - uae_u64 size = _tstoi64 (buf + 1); - if (size == hfd->virtsize) - found = 2; - } - if (found) - write_log (_T("Geometry file '%s', entry '%s' detected\n"), tname, buf + 1); - continue; + int found = 0; + TCHAR section[200]; + struct ini_data *ini; + bool ret = false; + + ini = ini_load(tname); + if (!ini) + return ret; + + _tcscpy(section, _T("empty")); + if (empty && ini_getstring(ini, section, NULL, NULL)) { + found = 1; + } + _tcscpy(section, _T("default")); + if (!empty && ini_getstring(ini, section, NULL, NULL)) { + found = 1; + } + _tcscpy(section, _T("geometry")); + if (ini_getstring(ini, section, NULL, NULL)) { + found = 1; + } + if (hfd) { + _stprintf(section, _T("%llu"), hfd->virtsize); + if (ini_getstring(ini, section, NULL, NULL)) { + found = 1; } - if (!found) - continue; + } - sep = _tcschr (buf, '='); - if (!sep) - continue; - sep[0] = 0; + if (found) { + ret = true; + write_log(_T("Geometry file '%s' section '%s' found\n"), tname, section); + _tcscpy(uci->geometry, tname); - TCHAR *key = my_strdup_trim (buf); - TCHAR *val = my_strdup_trim (sep + 1); - if (val[0] == '0' && _totupper (val[1]) == 'X') { - TCHAR *endptr; - v = _tcstol (val, &endptr, 16); - } else { - v = _tstol (val); - } - if (!_tcsicmp (key, _T("surfaces"))) - uci->surfaces = v; - if (!_tcsicmp (key, _T("sectorspertrack")) || !_tcsicmp (key, _T("blockspertrack"))) - uci->sectors = v; - if (!_tcsicmp (key, _T("sectorsperblock"))) - uci->sectorsperblock = v; - if (!_tcsicmp (key, _T("reserved"))) - uci->reserved = v; - if (!_tcsicmp (key, _T("lowcyl"))) - uci->lowcyl = v; - if (!_tcsicmp (key, _T("highcyl")) || !_tcsicmp (key, _T("cyl"))) - uci->highcyl = v; - if (!_tcsicmp (key, _T("blocksize")) || !_tcsicmp (key, _T("sectorsize"))) - uci->blocksize = v; - if (!_tcsicmp (key, _T("buffers"))) - uci->buffers = v; - if (!_tcsicmp (key, _T("maxtransfer"))) - uci->maxtransfer = v; - if (!_tcsicmp (key, _T("interleave"))) - uci->interleave = v; - if (!_tcsicmp (key, _T("dostype"))) - uci->dostype = v; - if (!_tcsicmp (key, _T("bufmemtype"))) - uci->bufmemtype = v; - if (!_tcsicmp (key, _T("stacksize"))) - uci->stacksize = v; - if (!_tcsicmp (key, _T("mask"))) - uci->mask = v; - if (!_tcsicmp (key, _T("unit"))) - uci->unit = v; - if (!_tcsicmp (key, _T("controller"))) - get_filesys_controller (val, &uci->controller_type, &uci->controller_type_unit, &uci->controller_unit); - if (!_tcsicmp (key, _T("flags"))) - uci->flags = v; - if (!_tcsicmp (key, _T("priority"))) - uci->priority = v; - if (!_tcsicmp (key, _T("forceload"))) - uci->forceload = v; - if (!_tcsicmp (key, _T("bootpri"))) { - if (v < -129) - v = -129; - if (v > 127) - v = 127; - uci->bootpri = v; - } - if (!_tcsicmp (key, _T("filesystem"))) - _tcscpy (uci->filesys, val); - if (!_tcsicmp (key, _T("device"))) - _tcscpy (uci->devname, val); - if (!_tcsicmp(key, _T("badblocks"))) { - TCHAR *p = val; - while (p && *p && uci->badblock_num < MAX_UAEDEV_BADBLOCKS) { - struct uaedev_badblock *bb = &uci->badblocks[uci->badblock_num]; - if (!_istdigit(*p)) - break; - bb->first = _tstol(p); - bb->last = bb->first; - TCHAR *p1 = _tcschr(p, ','); - TCHAR *p2 = NULL; - if (p1) { - p2 = p1 + 1; - *p1 = 0; - } - p1 = _tcschr(p, '-'); - if (p1) { - bb->last = _tstol(p1 + 1); + int idx = 0; + for (;;) { + TCHAR *key = NULL, *val = NULL; + int v; + if (!ini_getsectionstring(ini, section, idx, &key, &val)) + break; + if (val[0] == '0' && _totupper (val[1]) == 'X') { + TCHAR *endptr; + v = _tcstol (val, &endptr, 16); + } else { + v = _tstol (val); + } + if (!_tcsicmp (key, _T("surfaces"))) + uci->surfaces = v; + if (!_tcsicmp (key, _T("sectorspertrack")) || !_tcsicmp (key, _T("blockspertrack"))) + uci->sectors = v; + if (!_tcsicmp (key, _T("sectorsperblock"))) + uci->sectorsperblock = v; + if (!_tcsicmp (key, _T("reserved"))) + uci->reserved = v; + if (!_tcsicmp (key, _T("lowcyl"))) + uci->lowcyl = v; + if (!_tcsicmp (key, _T("highcyl")) || !_tcsicmp (key, _T("cyl"))) + uci->highcyl = v; + if (!_tcsicmp (key, _T("blocksize")) || !_tcsicmp (key, _T("sectorsize"))) + uci->blocksize = v; + if (!_tcsicmp (key, _T("buffers"))) + uci->buffers = v; + if (!_tcsicmp (key, _T("maxtransfer"))) + uci->maxtransfer = v; + if (!_tcsicmp (key, _T("interleave"))) + uci->interleave = v; + if (!_tcsicmp (key, _T("dostype"))) + uci->dostype = v; + if (!_tcsicmp (key, _T("bufmemtype"))) + uci->bufmemtype = v; + if (!_tcsicmp (key, _T("stacksize"))) + uci->stacksize = v; + if (!_tcsicmp (key, _T("mask"))) + uci->mask = v; + if (!_tcsicmp (key, _T("unit"))) + uci->unit = v; + if (!_tcsicmp (key, _T("controller"))) + get_filesys_controller (val, &uci->controller_type, &uci->controller_type_unit, &uci->controller_unit); + if (!_tcsicmp (key, _T("flags"))) + uci->flags = v; + if (!_tcsicmp (key, _T("priority"))) + uci->priority = v; + if (!_tcsicmp (key, _T("forceload"))) + uci->forceload = v; + if (!_tcsicmp (key, _T("bootpri"))) { + if (v < -129) + v = -129; + if (v > 127) + v = 127; + uci->bootpri = v; + } + if (!_tcsicmp (key, _T("filesystem"))) + _tcscpy (uci->filesys, val); + if (!_tcsicmp (key, _T("device"))) + _tcscpy (uci->devname, val); + if (!_tcsicmp(key, _T("badblocks"))) { + TCHAR *p = val; + while (p && *p && uci->badblock_num < MAX_UAEDEV_BADBLOCKS) { + struct uaedev_badblock *bb = &uci->badblocks[uci->badblock_num]; + if (!_istdigit(*p)) + break; + bb->first = _tstol(p); + bb->last = bb->first; + TCHAR *p1 = _tcschr(p, ','); + TCHAR *p2 = NULL; + if (p1) { + p2 = p1 + 1; + *p1 = 0; + } + p1 = _tcschr(p, '-'); + if (p1) { + bb->last = _tstol(p1 + 1); + } + uci->badblock_num++; + p = p2; } - uci->badblock_num++; - p = p2; } + xfree (val); + xfree (key); + idx++; } - xfree (val); - xfree (key); } - zfile_fclose (f); - return false; + + uae_u8 *out; + int outsize; + + if (ini_getdata(ini, _T("MODE SENSE"), _T("03"), &out, &outsize) && outsize >= 16) { + uci->psecs = (out[10] << 8) | (out[11] << 0); + uci->blocksize = (out[12] << 8) | (out[13] << 0); + xfree(out); + ret = true; + } + + if (ini_getdata(ini, _T("MODE SENSE"), _T("04"), &out, &outsize) && outsize >= 20) { + uci->pheads = out[5]; + uci->pcyls = (out[2] << 16) | (out[3] << 8) | (out[4] << 0); + xfree(out); + ret = true; + } + + if (ini_getdata(ini, _T("READ CAPACITY"), _T("DATA"), &out, &outsize) && outsize >= 8) { + uci->blocksize = (out[4] << 24) | (out[5] << 16) | (out[6] << 8) | (out[7] << 0); + uci->max_lba = ((out[0] << 24) | (out[1] << 16) | (out[2] << 8) | (out[3] << 0)) + 1; + xfree(out); + ret = true; + } + + void ata_parse_identity(uae_u8 *out, struct uaedev_config_info *uci, bool *lba48, int *max_multiple); + bool ata_get_identity(struct ini_data *ini, uae_u8 *out, bool overwrite); + + uae_u8 ident[512]; + if (ata_get_identity(ini, ident, true)) { + bool lba48; + int max_multiple; + ata_parse_identity(ident, uci, &lba48, &max_multiple); + ret = true; + } + xfree(out); + + ini_free(ini); + return ret; } + bool get_hd_geometry (struct uaedev_config_info *uci) { TCHAR tname[MAX_DPATH]; @@ -4197,7 +4290,9 @@ bool get_hd_geometry (struct uaedev_config_info *uci) parse_geo (tname, uci, NULL, true); } } - if (uci->rootdir[0]) { + if (uci->geometry[0]) { + return parse_geo (uci->geometry, uci, NULL, false); + } else if (uci->rootdir[0]) { _tcscpy (tname, uci->rootdir); _tcscat (tname, _T(".geo")); return parse_geo (tname, uci, NULL, false); @@ -4332,61 +4427,81 @@ static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHA || ! getintval (&tmpp, &uci.blocksize, ',')) goto invalid_fs; if (getintval2 (&tmpp, &uci.bootpri, ',', false)) { + const TCHAR *end; + TCHAR *n; tmpp2 = tmpp; - tmpp = _tcschr (tmpp, ','); - if (tmpp != 0) { + // quoted special case + if (tmpp2[0] == '\"') { + const TCHAR *end; + TCHAR *n = cfgfile_unescape (tmpp2, &end, 0); + if (!n) + goto invalid_fs; + _tcscpy (uci.filesys, n); + xfree(n); + tmpp = (TCHAR*)end; + *tmpp++ = 0; + } else { + tmpp = _tcschr (tmpp, ','); + if (tmpp == 0) + goto empty_fs; *tmpp++ = 0; _tcscpy (uci.filesys, tmpp2); - TCHAR *tmpp2 = _tcschr (tmpp, ','); - if (tmpp2) - *tmpp2++ = 0; - get_filesys_controller (tmpp, &uci.controller_type, &uci.controller_type_unit, &uci.controller_unit); - if (tmpp2) { - if (getintval2 (&tmpp2, &uci.highcyl, ',', false)) { - getintval (&tmpp2, &uci.pcyls, '/'); - getintval (&tmpp2, &uci.pheads, '/'); - getintval2 (&tmpp2, &uci.psecs, '/', true); - if (uci.pheads && uci.psecs) { - uci.physical_geometry = true; - } else { - uci.pheads = uci.psecs = uci.pcyls = 0; - uci.physical_geometry = false; - } + } + get_filesys_controller (tmpp, &uci.controller_type, &uci.controller_type_unit, &uci.controller_unit); + tmpp2 = _tcschr (tmpp, ','); + if (tmpp2) { + tmpp2++; + if (getintval2 (&tmpp2, &uci.highcyl, ',', false)) { + getintval (&tmpp2, &uci.pcyls, '/'); + getintval (&tmpp2, &uci.pheads, '/'); + getintval2 (&tmpp2, &uci.psecs, '/', true); + if (uci.pheads && uci.psecs) { + uci.physical_geometry = true; + } else { + uci.pheads = uci.psecs = uci.pcyls = 0; + uci.physical_geometry = false; + } + if (tmpp2[0]) { + n = cfgfile_unescape (tmpp2, &end, 0); + if (!n) + goto invalid_fs; + _tcscpy(uci.geometry, n); + xfree(n); } } - uci.controller_media_type = 0; - uci.unit_feature_level = 1; + } + uci.controller_media_type = 0; + uci.unit_feature_level = 1; - if (cfgfile_option_find(tmpp2, _T("CF"))) - uci.controller_media_type = 1; - else if (cfgfile_option_find(tmpp2, _T("HD"))) - uci.controller_media_type = 0; + if (cfgfile_option_find(tmpp2, _T("CF"))) + uci.controller_media_type = 1; + else if (cfgfile_option_find(tmpp2, _T("HD"))) + uci.controller_media_type = 0; - TCHAR *pflags; - if ((pflags = cfgfile_option_get(tmpp2, _T("flags")))) { - getintval(&pflags, &uci.unit_special_flags, 0); - } + TCHAR *pflags; + if ((pflags = cfgfile_option_get(tmpp2, _T("flags")))) { + getintval(&pflags, &uci.unit_special_flags, 0); + } - if (cfgfile_option_find(tmpp2, _T("lock"))) - uci.lock = true; + if (cfgfile_option_find(tmpp2, _T("lock"))) + uci.lock = true; - if (cfgfile_option_find(tmpp2, _T("SCSI2"))) - uci.unit_feature_level = HD_LEVEL_SCSI_2; - else if (cfgfile_option_find(tmpp2, _T("SCSI1"))) - uci.unit_feature_level = HD_LEVEL_SCSI_1; - else if (cfgfile_option_find(tmpp2, _T("SASIE"))) - uci.unit_feature_level = HD_LEVEL_SASI_ENHANCED; - else if (cfgfile_option_find(tmpp2, _T("SASI"))) - uci.unit_feature_level = HD_LEVEL_SASI; - else if (cfgfile_option_find(tmpp2, _T("SASI_CHS"))) - uci.unit_feature_level = HD_LEVEL_SASI_CHS; - else if (cfgfile_option_find(tmpp2, _T("ATA2+S"))) - uci.unit_feature_level = HD_LEVEL_ATA_2S; - else if (cfgfile_option_find(tmpp2, _T("ATA2+"))) - uci.unit_feature_level = HD_LEVEL_ATA_2; - else if (cfgfile_option_find(tmpp2, _T("ATA1"))) - uci.unit_feature_level = HD_LEVEL_ATA_1; - } + if (cfgfile_option_find(tmpp2, _T("SCSI2"))) + uci.unit_feature_level = HD_LEVEL_SCSI_2; + else if (cfgfile_option_find(tmpp2, _T("SCSI1"))) + uci.unit_feature_level = HD_LEVEL_SCSI_1; + else if (cfgfile_option_find(tmpp2, _T("SASIE"))) + uci.unit_feature_level = HD_LEVEL_SASI_ENHANCED; + else if (cfgfile_option_find(tmpp2, _T("SASI"))) + uci.unit_feature_level = HD_LEVEL_SASI; + else if (cfgfile_option_find(tmpp2, _T("SASI_CHS"))) + uci.unit_feature_level = HD_LEVEL_SASI_CHS; + else if (cfgfile_option_find(tmpp2, _T("ATA2+S"))) + uci.unit_feature_level = HD_LEVEL_ATA_2S; + else if (cfgfile_option_find(tmpp2, _T("ATA2+"))) + uci.unit_feature_level = HD_LEVEL_ATA_2; + else if (cfgfile_option_find(tmpp2, _T("ATA1"))) + uci.unit_feature_level = HD_LEVEL_ATA_1; } if (type == 2) { uci.device_emu_unit = unit; @@ -4412,6 +4527,9 @@ empty_fs: str = cfgfile_subst_path_load (UNEXPANDED, &p->path_hardfile, uci.rootdir, false); _tcscpy (uci.rootdir, str); } + if (uci.geometry[0]) { + parse_geo(uci.geometry, &uci, NULL, false); + } #ifdef FILESYS add_filesys_config (p, nr, &uci); #endif @@ -4430,7 +4548,7 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) { TCHAR tmp[100]; _stprintf (tmp, _T("uaehf%d"), i); - if (_tcscmp (option, tmp) == 0) { + if (!_tcscmp (option, tmp)) { for (;;) { int type = -1; int unit = -1; @@ -4481,6 +4599,8 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA _tcscpy (uci->rootdir, value); } else if (!_tcscmp (s, _T("filesys"))) { _tcscpy (uci->filesys, value); + } else if (!_tcscmp (s, _T("geometry"))) { + _tcscpy (uci->geometry, value); } else if (!_tcscmp (s, _T("controller"))) { get_filesys_controller (value, &uci->controller_type, &uci->controller_type_unit, &uci->controller_unit); } @@ -4535,6 +4655,8 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA _tcscpy (uci.rootdir, value); } str = cfgfile_subst_path_load (UNEXPANDED, &p->path_hardfile, uci.rootdir, true); + if (uci.geometry[0]) + parse_geo(uci.geometry, &uci, NULL, false); #ifdef FILESYS uci.type = hdf ? UAEDEV_HDF : UAEDEV_DIR; add_filesys_config (p, -1, &uci); @@ -4686,6 +4808,25 @@ static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, con if (v >= 0) brc->roms[idx].subtype = v; } + p = cfgfile_option_get(buf2, _T("mid")); + if (p) { + brc->roms[idx].manufacturer = _tstol(p); + } + p = cfgfile_option_get(buf2, _T("pid")); + if (p) { + brc->roms[idx].product = _tstol(p); + } + p = cfgfile_option_get(buf2, _T("data")); + if (p && _tcslen(p) >= 3 * 16 - 1) { + for (int i = 0; i < sizeof brc->roms[idx].autoconfig; i++) { + TCHAR *s2 = &p[i * 3]; + if (i + 1 < sizeof brc->roms[idx].autoconfig && s2[2] != '.') + break; + TCHAR *endptr; + p[2] = 0; + brc->roms[idx].autoconfig[i] = (uae_u8)_tcstol(s2, &endptr, 16); + } + } } return true; } @@ -5138,7 +5279,14 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH } if (cfgfile_string (option, value, _T("mmu_model"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) { - p->mmu_model = _tstol (tmpbuf); + TCHAR *s =_tcsstr(tmpbuf, _T("ec")); + if (s) { + p->mmu_ec = true; + p->mmu_model = 68000 + _tstol(s + 2); + } else { + p->mmu_ec = false; + p->mmu_model = _tstol(tmpbuf); + } return 1; } @@ -5318,7 +5466,7 @@ void cfgfile_compatibility_rtg(struct uae_prefs *p) int vga = -1; for (int i = 0; i < MAX_RTG_BOARDS; i++) { struct rtgboardconfig *rbc = &p->rtgboards[i]; - if (rbc->rtgmem_type == GFXBOARD_A2410) { + if (rbc->rtgmem_type == GFXBOARD_A2410 || rbc->rtgmem_type == GFXBOARD_RESOLVER) { if (a2410 >= 0) { rbc->rtgmem_size = 0; rbc->rtgmem_type = 0; diff --git a/filesys.cpp b/filesys.cpp index 4e536787..00d5398a 100644 --- a/filesys.cpp +++ b/filesys.cpp @@ -8049,8 +8049,13 @@ static int pt_babe(TrapContext *ctx, uae_u8 *bufrdb, UnitInfo *uip, int unit_no, struct uaedev_config_info *ci = &uip[unit_no].hf.ci; uae_u32 bad; - // blocksize != 128? - if (bufrdb[0x20] != 0 || bufrdb[0x21] != 0 || bufrdb[0x22] != 0 || bufrdb[0x23] != 0x80) + uae_u32 bs = (bufrdb[0x20] << 24) | (bufrdb[0x21] << 16) | (bufrdb[0x22] << 8) | (bufrdb[0x23] << 0); + int bscnt; + for (bscnt = 512; bscnt <= 32768; bscnt <<= 1) { + if (bs == (bscnt >> 2)) + break; + } + if (bscnt > 32768) return 0; bad = rl(bufrdb + 4); diff --git a/hardfile.cpp b/hardfile.cpp index 52ad814c..2ef31a23 100644 --- a/hardfile.cpp +++ b/hardfile.cpp @@ -29,6 +29,7 @@ #include "zfile.h" #include "ide.h" #include "debug.h" +#include "ini.h" #ifdef WITH_CHD #include "archivers/chd/chdtypes.h" @@ -589,7 +590,12 @@ end: } int hdf_open (struct hardfiledata *hfd) { - return hdf_open (hfd, NULL); + int v = hdf_open (hfd, NULL); + if (!v) + return v; + get_hd_geometry(&hfd->ci); + hfd->geometry = ini_load(hfd->ci.geometry); + return v; } void hdf_close (struct hardfiledata *hfd) @@ -608,6 +614,8 @@ void hdf_close (struct hardfiledata *hfd) cf->close(); delete cf; } + ini_free(hfd->geometry); + hfd->geometry = NULL; hfd->chd_handle = NULL; #endif hfd->hfd_type = 0; @@ -1146,6 +1154,15 @@ static int checkbounds (struct hardfiledata *hfd, uae_u64 offset, uae_u64 len, i (uae_u32)(max >> 32),(uae_u32)max); return -1; } + if (hfd->ci.max_lba) { + max = hfd->ci.max_lba * hfd->ci.blocksize; + if (offset >= max) { + write_log (_T("UAEHF SCSI: forced last lba out of bounds, %08X-%08X + %08X-%08X > %08X-%08X\n"), + (uae_u32)(offset >> 32),(uae_u32)offset,(uae_u32)(len >> 32),(uae_u32)len, + (uae_u32)(max >> 32),(uae_u32)max); + return -1; + } + } if ((mode == 1 || mode == 2) && hfd->ci.badblock_num) { offset /= hfd->ci.blocksize; len /= hfd->ci.blocksize; @@ -1368,16 +1385,12 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua r[0] = 0x7f; } else { r[0] = 0; - if (hfd->drive_empty) { - r[1] |= 0x80; // removable.. - r[0] |= 0x20; // not present - } } r[2] = 2; /* supports SCSI-2 */ r[3] = 2; /* response data format */ r[4] = 32; /* additional length */ r[7] = 0; - scsi_len = lr = alen < 36 ? alen : 36; + lr = alen < 36 ? alen : 36; if (hdhfd) { r[2] = hdhfd->ansi_version; r[3] = hdhfd->ansi_version >= 2 ? 2 : 0; @@ -1385,6 +1398,18 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua setdrivestring(hfd->vendor_id, r, 8, 8); setdrivestring(hfd->product_id, r, 16, 16); setdrivestring(hfd->product_rev, r, 32, 4); + uae_u8 *rr; + if (ini_getdata(hfd->geometry, _T("INQUIRY"), _T("00"), &rr, &lr)) { + if (lr > alen) + lr = alen; + memcpy(r, rr, lr); + xfree(rr); + } + if (lun == 0 && hfd->drive_empty) { + r[0] |= 0x20; // not present + r[1] |= 0x80; // removable.. + } + scsi_len = lr; } goto scsi_done; case 0x1b: /* START/STOP UNIT */ @@ -1725,6 +1750,8 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua if (nodisk (hfd)) goto nodisk; blocks = (uae_u32)(hfd->virtsize / hfd->ci.blocksize); + if (hfd->ci.max_lba) + blocks = hfd->ci.max_lba; if (hdhfd) { cyl = hdhfd->cyls; head = hdhfd->heads; diff --git a/ide.cpp b/ide.cpp index 8aaae783..8d0c8f7d 100644 --- a/ide.cpp +++ b/ide.cpp @@ -23,6 +23,7 @@ #include "savestate.h" #include "scsi.h" #include "ide.h" +#include "ini.h" /* STATUS bits */ #define IDE_STATUS_ERR 0x01 // 0 @@ -46,7 +47,81 @@ #define ATAPI_CD 0x01 #define ATAPI_MAX_TRANSFER 32768 -#define MAX_IDE_MULTIPLE_SECTORS 128 + +void ata_parse_identity(uae_u8 *out, struct uaedev_config_info *uci, bool *lba48, int *max_multiple) +{ + *lba48 = false; + *max_multiple = 0; + struct uaedev_config_info uci2; + + uae_u16 v; + + memcpy(&uci2, uci, sizeof(struct uaedev_config_info)); + + uci->blocksize = 512; + + uci->pcyls = (out[1 * 2 + 0] << 8) | (out[1 * 2 + 1] << 0); + uci->pheads = (out[3 * 2 + 0] << 8) | (out[3 * 2 + 1] << 0); + uci->psecs = (out[6 * 2 + 0] << 8) | (out[6 * 2 + 1] << 0); + + if (!uci->pcyls || !uci->pheads || !uci->psecs) { + uci->pcyls = uci2.pcyls; + uci->pheads = uci2.pheads; + uci->psecs = uci2.psecs; + } + + v = (out[59 * 2 + 0] << 8) | (out[59 * 2 + 1] << 0); + if (v & 1) { // multiple mode? + *max_multiple = (out[47 * 2 + 0] << 8) | (out[47 * 2 + 1] << 0); + } + + v = (out[53 * 2 + 0] << 8) | (out[53 * 2 + 1] << 0); + if (v & 1) { // 54-58 valid? + uci->pcyls = (out[54 * 2 + 0] << 8) | (out[54 * 2 + 1] << 0); + uci->pheads = (out[55 * 2 + 0] << 8) | (out[55 * 2 + 1] << 0); + uci->psecs = (out[56 * 2 + 0] << 8) | (out[56 * 2 + 1] << 0); + uci->max_lba = (out[57 * 2 + 0] << 24) | (out[57 * 2 + 1] << 16) | (out[58 * 2 + 0] << 8) | (out[58 * 2 + 1] << 0); + } + v = (out[49 * 2 + 0] << 8) | (out[49 * 2 + 1] << 0); + if (v & (1 << 9)) { // LBA supported? + uci->max_lba = (out[60 * 2 + 0] << 24) | (out[60 * 2 + 1] << 16) | (out[61 * 2 + 0] << 8) | (out[61 * 2 + 1] << 0); + } + v = (out[83 * 2 + 0] << 8) | (out[83 * 2 + 1] << 0); + if ((v & 0xc000) == 0x4000 && (v & (1 << 10))) { // LBA48 supported? + *lba48 = true; + uci->max_lba = (out[100 * 2 + 0] << 24) | (out[100 * 2 + 1] << 16) | (out[101 * 2 + 0] << 8) | (out[101 * 2 + 1] << 0); + uci->max_lba <<= 32; + uci->max_lba |= (out[102 * 2 + 0] << 24) | (out[102 * 2 + 1] << 16) | (out[103 * 2 + 0] << 8) | (out[103 * 2 + 1] << 0); + } +} + +bool ata_get_identity(struct ini_data *ini, uae_u8 *out, bool overwrite) +{ + if (!out) + return false; + if (overwrite) { + uae_u8 *out2; + int len; + if (!ini_getdata(ini, _T("IDENTITY"), _T("DATA"), &out2, &len)) + return false; + if (len == 512) { + memcpy(out, out2, 512); + } + xfree(out2); + } + int v; + if (ini_getval(ini, _T("IDENTITY"), _T("multiple_mode"), &v)) { + if (v) { + out[59 * 2 + 1] |= 1; + out[47 * 2 + 0] = 0; + out[47 * 2 + 1] = v; + } else { + out[59 * 2 + 1] &= ~1; + } + } + + return true; +} uae_u16 adide_decode_word(uae_u16 w) @@ -157,6 +232,46 @@ static void ide_grow_buffer(struct ide_hdf *ide, int newsize) xfree(oldbuf); } +static void sl(uae_u8 *d, int o) +{ + o *= 2; + uae_u16 t = (d[o + 0] << 8) | d[o + 1]; + d[o + 0] = d[o + 2]; + d[o + 1] = d[o + 3]; + d[o + 2] = t >> 8; + d[o + 3] = t; +} +static void ql(uae_u8 *d, int o) +{ + sl(d, o + 1); + o *= 2; + uae_u16 t = (d[o + 0] << 8) | d[o + 1]; + d[o + 0] = d[o + 6]; + d[o + 1] = d[o + 7]; + d[o + 6] = t >> 8; + d[o + 7] = t; +} + +void ata_byteswapidentity(uae_u8 *d) +{ + for (int i = 0; i < 512; i += 2) + { + uae_u8 t = d[i + 0]; + d[i + 0] = d[i + 1]; + d[i + 1] = t; + } + sl(d, 7); + sl(d, 57); + sl(d, 60); + sl(d, 98); + sl(d, 117); + sl(d, 210); + sl(d, 212); + sl(d, 215); + ql(d, 100); + ql(d, 230); +} + static void pw (struct ide_hdf *ide, int offset, uae_u16 w) { if (ide->byteswap) { @@ -168,6 +283,28 @@ static void pw (struct ide_hdf *ide, int offset, uae_u16 w) ide->secbuf[offset * 2 + 1] = w >> 8; } +static void pwand (struct ide_hdf *ide, int offset, uae_u16 w) +{ + if (ide->byteswap) { + w = (w >> 8) | (w << 8); + } + if (ide->adide) + w = adide_decode_word(w); + ide->secbuf[offset * 2 + 0] &= ~((uae_u8)w); + ide->secbuf[offset * 2 + 1] &= ~(w >> 8); +} + +static void pwor (struct ide_hdf *ide, int offset, uae_u16 w) +{ + if (ide->byteswap) { + w = (w >> 8) | (w << 8); + } + if (ide->adide) + w = adide_decode_word(w); + ide->secbuf[offset * 2 + 0] |= (uae_u8)w; + ide->secbuf[offset * 2 + 1] |= w >> 8; +} + static void ps (struct ide_hdf *ide, int offset, const TCHAR *src, int max) { int i, len; @@ -315,87 +452,106 @@ static void ide_recalibrate (struct ide_hdf *ide) ide_interrupt (ide); } -static void ide_identify_drive (struct ide_hdf *ide) +static void ide_identity_buffer(struct ide_hdf *ide) { - uae_u64 totalsecs; - int v; - uae_u8 *buf = ide->secbuf; TCHAR tmp[100]; bool atapi = ide->atapi; bool cf = ide->media_type > 0; + int v; + + memset(ide->secbuf, 0, 512); + + if (ata_get_identity(ide->hdhfd.hfd.geometry, ide->secbuf, true)) { + + if (ide->byteswap) + ata_byteswapidentity(ide->secbuf); + + } else { + + pw (ide, 0, atapi ? 0x85c0 : (cf ? 0x848a : (1 << 6))); + pw (ide, 1, ide->hdhfd.cyls_def); + pw (ide, 2, 0xc837); + pw (ide, 3, ide->hdhfd.heads_def); + pw (ide, 4, ide->blocksize * ide->hdhfd.secspertrack_def); + pw (ide, 5, ide->blocksize); + pw (ide, 6, ide->hdhfd.secspertrack_def); + ps (ide, 10, _T("68000"), 20); /* serial */ + pw (ide, 20, 3); + pw (ide, 21, ide->blocksize); + pw (ide, 22, 4); + ps (ide, 23, _T("0.7"), 8); /* firmware revision */ + if (ide->atapi) + _tcscpy (tmp, _T("UAE-ATAPI")); + else + _stprintf (tmp, _T("UAE-IDE %s"), ide->hdhfd.hfd.product_id); + ps (ide, 27, tmp, 40); /* model */ + pw (ide, 47, ide->max_multiple_mode >> (ide->blocksize / 512 - 1)); /* max sectors in multiple mode */ + pw (ide, 48, 1); + pw (ide, 49, (1 << 9) | (1 << 8)); /* LBA and DMA supported */ + pw (ide, 51, 0x200); /* PIO cycles */ + pw (ide, 52, 0x200); /* DMA cycles */ + pw (ide, 53, 1 | 2 | 4); + pw (ide, 54, ide->hdhfd.cyls); + pw (ide, 55, ide->hdhfd.heads); + pw (ide, 56, ide->hdhfd.secspertrack); + uae_u64 totalsecs = ide->hdhfd.cyls * ide->hdhfd.heads * ide->hdhfd.secspertrack; + pw (ide, 57, (uae_u16)totalsecs); + pw (ide, 58, (uae_u16)(totalsecs >> 16)); + pw (ide, 59, 1); /* Multiple mode supported */ + totalsecs = ide->blocksize ? ide->hdhfd.size / ide->blocksize : 0; + if (totalsecs > 0x0fffffff) + totalsecs = 0x0fffffff; + pw (ide, 60, (uae_u16)totalsecs); + pw (ide, 61, (uae_u16)(totalsecs >> 16)); + pw (ide, 62, 0x0f); + pw (ide, 63, 0x0f); + if (ide->ata_level) { + pw (ide, 64, ide->ata_level ? 0x03 : 0x00); /* PIO3 and PIO4 */ + pw (ide, 65, 120); /* MDMA2 supported */ + pw (ide, 66, 120); + pw (ide, 67, 120); + pw (ide, 68, 120); + pw (ide, 80, (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6)); /* ATA-1 to ATA-6 */ + pw (ide, 81, 0x1c); /* ATA revision */ + pw (ide, 82, (1 << 14) | (atapi ? 0x10 | 4 : 0)); /* NOP, ATAPI: PACKET and Removable media features supported */ + pw (ide, 83, (1 << 14) | (1 << 13) | (1 << 12) | (ide->lba48 ? (1 << 10) : 0)); /* cache flushes, LBA 48 supported */ + pw (ide, 84, 1 << 14); + pw (ide, 85, 1 << 14); + pw (ide, 86, (1 << 14) | (1 << 13) | (1 << 12) | (ide->lba48 ? (1 << 10) : 0)); /* cache flushes, LBA 48 enabled */ + pw (ide, 87, 1 << 14); + pw (ide, 88, (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); /* UDMA modes */ + pw (ide, 93, (1 << 14) | (1 << 13) | (1 << 0)); + if (ide->lba48) { + totalsecs = ide->hdhfd.size / ide->blocksize; + pw (ide, 100, (uae_u16)(totalsecs >> 0)); + pw (ide, 101, (uae_u16)(totalsecs >> 16)); + pw (ide, 102, (uae_u16)(totalsecs >> 32)); + pw (ide, 103, (uae_u16)(totalsecs >> 48)); + } + } + ata_get_identity(ide->hdhfd.hfd.geometry, ide->secbuf, false); + } + v = ide->multiple_mode; + pwor(ide, 59, v > 0 ? 0x100 : 0); + if (!atapi && cf) { + pw(ide, 0, 0x848a); + } else if (!atapi && !cf) { + pwand(ide, 0, 0x8000); + } +} + +static void ide_identify_drive (struct ide_hdf *ide) +{ if (!ide_isdrive (ide)) { ide_fail (ide); return; } - memset (buf, 0, ide->blocksize); - ide->byteswapped_buffer = 1; if (IDE_LOG > 0) write_log (_T("IDE%d identify drive\n"), ide->num); ide_data_ready (ide); ide->direction = 0; - pw (ide, 0, atapi ? 0x85c0 : (cf ? 0x848a : (1 << 6))); - pw (ide, 1, ide->hdhfd.cyls_def); - pw (ide, 2, 0xc837); - pw (ide, 3, ide->hdhfd.heads_def); - pw (ide, 4, ide->blocksize * ide->hdhfd.secspertrack_def); - pw (ide, 5, ide->blocksize); - pw (ide, 6, ide->hdhfd.secspertrack_def); - ps (ide, 10, _T("68000"), 20); /* serial */ - pw (ide, 20, 3); - pw (ide, 21, ide->blocksize); - pw (ide, 22, 4); - ps (ide, 23, _T("0.7"), 8); /* firmware revision */ - if (ide->atapi) - _tcscpy (tmp, _T("UAE-ATAPI")); - else - _stprintf (tmp, _T("UAE-IDE %s"), ide->hdhfd.hfd.product_id); - ps (ide, 27, tmp, 40); /* model */ - pw (ide, 47, MAX_IDE_MULTIPLE_SECTORS >> (ide->blocksize / 512 - 1)); /* max sectors in multiple mode */ - pw (ide, 48, 1); - pw (ide, 49, (1 << 9) | (1 << 8)); /* LBA and DMA supported */ - pw (ide, 51, 0x200); /* PIO cycles */ - pw (ide, 52, 0x200); /* DMA cycles */ - pw (ide, 53, 1 | 2 | 4); - pw (ide, 54, ide->hdhfd.cyls); - pw (ide, 55, ide->hdhfd.heads); - pw (ide, 56, ide->hdhfd.secspertrack); - totalsecs = ide->hdhfd.cyls * ide->hdhfd.heads * ide->hdhfd.secspertrack; - pw (ide, 57, (uae_u16)totalsecs); - pw (ide, 58, (uae_u16)(totalsecs >> 16)); - v = ide->multiple_mode; - pw (ide, 59, (v > 0 ? 0x100 : 0) | v); - totalsecs = ide->blocksize ? ide->hdhfd.size / ide->blocksize : 0; - if (totalsecs > 0x0fffffff) - totalsecs = 0x0fffffff; - pw (ide, 60, (uae_u16)totalsecs); - pw (ide, 61, (uae_u16)(totalsecs >> 16)); - pw (ide, 62, 0x0f); - pw (ide, 63, 0x0f); - if (ide->ata_level) { - pw (ide, 64, ide->ata_level ? 0x03 : 0x00); /* PIO3 and PIO4 */ - pw (ide, 65, 120); /* MDMA2 supported */ - pw (ide, 66, 120); - pw (ide, 67, 120); - pw (ide, 68, 120); - pw (ide, 80, (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6)); /* ATA-1 to ATA-6 */ - pw (ide, 81, 0x1c); /* ATA revision */ - pw (ide, 82, (1 << 14) | (atapi ? 0x10 | 4 : 0)); /* NOP, ATAPI: PACKET and Removable media features supported */ - pw (ide, 83, (1 << 14) | (1 << 13) | (1 << 12) | (ide->lba48 ? (1 << 10) : 0)); /* cache flushes, LBA 48 supported */ - pw (ide, 84, 1 << 14); - pw (ide, 85, 1 << 14); - pw (ide, 86, (1 << 14) | (1 << 13) | (1 << 12) | (ide->lba48 ? (1 << 10) : 0)); /* cache flushes, LBA 48 enabled */ - pw (ide, 87, 1 << 14); - pw (ide, 88, (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); /* UDMA modes */ - pw (ide, 93, (1 << 14) | (1 << 13) | (1 << 0)); - if (ide->lba48) { - totalsecs = ide->hdhfd.size / ide->blocksize; - pw (ide, 100, (uae_u16)(totalsecs >> 0)); - pw (ide, 101, (uae_u16)(totalsecs >> 16)); - pw (ide, 102, (uae_u16)(totalsecs >> 32)); - pw (ide, 103, (uae_u16)(totalsecs >> 48)); - } - } + ide_identity_buffer(ide); } static void set_signature (struct ide_hdf *ide) @@ -468,8 +624,12 @@ static void ide_initialize_drive_parameters (struct ide_hdf *ide) static void ide_set_multiple_mode (struct ide_hdf *ide) { write_log (_T("IDE%d drive multiple mode = %d\n"), ide->num, ide->regs.ide_nsector); - ide->multiple_mode = ide->regs.ide_nsector; - ide_interrupt (ide); + if (ide->regs.ide_nsector > (ide->max_multiple_mode >> (ide->blocksize / 512 - 1))) { + ide_fail(ide); + } else { + ide->multiple_mode = ide->regs.ide_nsector; + } + ide_interrupt(ide); } static void ide_set_features (struct ide_hdf *ide) @@ -755,8 +915,8 @@ static void do_process_rw_command (struct ide_hdf *ide) get_lbachs (ide, &lba, &cyl, &head, &sec); if (IDE_LOG > 1) write_log (_T("IDE%d off=%d, nsec=%d (%d) lba48=%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 + ide->lba48cmd); - if (nsec * ide->blocksize > ide->hdhfd.size - lba * ide->blocksize) { - nsec = (ide->hdhfd.size - lba * ide->blocksize) / ide->blocksize; + if (nsec > ide->max_lba - lba) { + nsec = ide->max_lba - lba; if (IDE_LOG > 1) write_log (_T("IDE%d nsec changed to %d\n"), ide->num, nsec); } @@ -832,7 +992,7 @@ static void ide_read_sectors (struct ide_hdf *ide, int flags) gui_flicker_led (LED_HD, ide->num, 1); nsec = get_nsec (ide); get_lbachs (ide, &lba, &cyl, &head, &sec); - if (lba * ide->blocksize >= ide->hdhfd.size) { + if (lba >= ide->max_lba) { ide_data_ready (ide); ide_fail_err (ide, IDE_ERR_IDNF); return; @@ -870,15 +1030,15 @@ static void ide_write_sectors (struct ide_hdf *ide, int flags) gui_flicker_led (LED_HD, ide->num, 2); nsec = get_nsec (ide); get_lbachs (ide, &lba, &cyl, &head, &sec); - if (lba * ide->blocksize >= ide->hdhfd.size) { + if (lba >= ide->max_lba) { ide_data_ready (ide); ide_fail_err (ide, IDE_ERR_IDNF); return; } if (IDE_LOG > 0) write_log (_T("IDE%d write off=%d, sec=%d (%d) lba48=%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 + ide->lba48cmd); - if (nsec * ide->blocksize > ide->hdhfd.size - lba * ide->blocksize) - nsec = (ide->hdhfd.size - lba * ide->blocksize) / ide->blocksize; + if (nsec > ide->max_lba - lba) + nsec = ide->max_lba - lba; if (nsec <= 0) { ide_data_ready (ide); ide_fail_err (ide, IDE_ERR_IDNF); @@ -904,7 +1064,6 @@ static void ide_do_command (struct ide_hdf *ide, uae_u8 cmd) ide->regs.ide_error = 0; ide->intdrq = false; ide->lba48cmd = false; - ide->byteswapped_buffer = 0; if (ide->atapi) { @@ -1390,12 +1549,15 @@ struct ide_hdf *add_ide_unit (struct ide_hdf **idetable, int max, int ch, struct if (ci) memcpy (&ide->hdhfd.hfd.ci, ci, sizeof (struct uaedev_config_info)); if (ci->type == UAEDEV_CD && ci->device_emu_unit >= 0) { + device_func_init (0); ide->scsi = scsi_alloc_cd (ch, ci->device_emu_unit, true); if (!ide->scsi) { write_log (_T("IDE: CD EMU unit %d failed to open\n"), ide->cd_unit_num); return NULL; } + + ide_identity_buffer(ide); ide->cd_unit_num = ci->device_emu_unit; ide->atapi = true; ide->blocksize = 512; @@ -1404,9 +1566,13 @@ struct ide_hdf *add_ide_unit (struct ide_hdf **idetable, int max, int ch, struct write_log (_T("IDE%d CD %d\n"), ch, ide->cd_unit_num); } else if (ci->type == UAEDEV_HDF) { + if (!hdf_hd_open (&ide->hdhfd)) return NULL; + + ide->max_multiple_mode = 128; ide->blocksize = ide->hdhfd.hfd.ci.blocksize; + ide->max_lba = ide->hdhfd.size / ide->blocksize; ide->lba48 = (ide->hdhfd.hfd.ci.unit_special_flags & 1) || ide->hdhfd.size >= 128 * (uae_u64)0x40000000 ? 1 : 0; gui_flicker_led (LED_HD, ch, -1); ide->cd_unit_num = -1; @@ -1414,12 +1580,25 @@ struct ide_hdf *add_ide_unit (struct ide_hdf **idetable, int max, int ch, struct ide->ata_level = ci->unit_feature_level; if (!ide->ata_level && (ide->hdhfd.size >= 4 * (uae_u64)0x40000000 || ide->media_type)) ide->ata_level = 1; + ide_identity_buffer(ide); + + if (!ide->byteswap) + ata_byteswapidentity(ide->secbuf); + struct uaedev_config_info ci = { 0 }; + ata_parse_identity(ide->secbuf, &ci, &ide->lba48, &ide->max_multiple_mode); + ide->hdhfd.cyls = ide->hdhfd.cyls_def = ci.pcyls; + ide->hdhfd.heads = ide->hdhfd.heads_def = ci.pheads; + ide->hdhfd.secspertrack = ide->hdhfd.secspertrack_def = ci.psecs; + if (ci.max_lba) + ide->max_lba = ci.max_lba; + if (ide->lba48 && !ide->ata_level) + ide->ata_level = 1; - write_log (_T("IDE%d HD '%s', LCHS=%d/%d/%d. PCHS=%d/%d/%d %uM. LBA48=%d\n"), + write_log (_T("IDE%d HD '%s', LCHS=%d/%d/%d. PCHS=%d/%d/%d %uM. MM=%d LBA48=%d\n"), ch, ide->hdhfd.hfd.ci.rootdir, ide->hdhfd.cyls, ide->hdhfd.heads, ide->hdhfd.secspertrack, ide->hdhfd.hfd.ci.pcyls, ide->hdhfd.hfd.ci.pheads, ide->hdhfd.hfd.ci.psecs, - (int)(ide->hdhfd.size / (1024 * 1024)), ide->lba48); + (int)(ide->hdhfd.size / (1024 * 1024)), ide->max_multiple_mode, ide->lba48); } ide->regs.ide_status = 0; diff --git a/include/disk.h b/include/disk.h index 348b81c5..ab46ea1f 100644 --- a/include/disk.h +++ b/include/disk.h @@ -21,7 +21,8 @@ typedef enum { DRV_NONE = -1, DRV_35_DD = 0, DRV_35_HD, DRV_525_SD, DRV_35_DD_ES #define HISTORY_TAPE 5 #define HISTORY_GENLOCK_IMAGE 6 #define HISTORY_GENLOCK_VIDEO 7 -#define HISTORY_MAX 8 +#define HISTORY_GEO 8 +#define HISTORY_MAX 9 struct diskinfo { diff --git a/include/filesys.h b/include/filesys.h index 70612b23..8bcef2b7 100644 --- a/include/filesys.h +++ b/include/filesys.h @@ -74,6 +74,8 @@ struct hardfiledata { int reinsertdelay; bool isreinsert; bool unit_stopped; + + struct ini_data *geometry; }; #define HFD_FLAGS_REALDRIVE 1 diff --git a/include/ide.h b/include/ide.h index 4773b810..0413d2fd 100644 --- a/include/ide.h +++ b/include/ide.h @@ -71,7 +71,6 @@ struct ide_hdf struct ide_hdf *pair; // master<>slave struct ide_thread_state *its; bool byteswap; - int byteswapped_buffer; bool adide; uae_u8 *secbuf; @@ -85,7 +84,9 @@ struct ide_hdf bool lba48; bool lba48cmd; uae_u64 start_lba; + uae_u64 max_lba; int start_nsec; + int max_multiple_mode; uae_u8 multiple_mode; int irq_delay; int irq; @@ -133,6 +134,10 @@ void remove_ide_unit(struct ide_hdf **idetable, int ch); void alloc_ide_mem (struct ide_hdf **ide, int max, struct ide_thread_state *its); void ide_reset_device(struct ide_hdf *ide); +void ata_byteswapidentity(uae_u8 *d); +void ata_parse_identity(uae_u8 *out, struct uaedev_config_info *uci, bool *lba48, int *max_multiple); +bool ata_get_identity(struct ini_data *ini, uae_u8 *out, bool overwrite); + void start_ide_thread(struct ide_thread_state *its); void stop_ide_thread(struct ide_thread_state *its); diff --git a/include/options.h b/include/options.h index ddc8e54a..03bd0155 100644 --- a/include/options.h +++ b/include/options.h @@ -16,7 +16,7 @@ #define UAEMAJOR 3 #define UAEMINOR 5 -#define UAESUBREV 0 +#define UAESUBREV 1 typedef enum { KBD_LANG_US, KBD_LANG_DK, KBD_LANG_DE, KBD_LANG_SE, KBD_LANG_FR, KBD_LANG_IT, KBD_LANG_ES } KbdLang; @@ -192,6 +192,7 @@ struct uaedev_config_info { bool lock; int bootpri; TCHAR filesys[MAX_DPATH]; + TCHAR geometry[MAX_DPATH]; int lowcyl; int highcyl; // zero if detected from size int cyls; // calculated/corrected highcyl @@ -199,6 +200,7 @@ struct uaedev_config_info { int sectors; int reserved; int blocksize; + uae_u64 max_lba; int controller_type; int controller_type_unit; int controller_unit; @@ -361,6 +363,9 @@ struct romconfig int subtype; void *unitdata; TCHAR configtext[256]; + uae_u16 manufacturer; + uae_u8 product; + uae_u8 autoconfig[16]; struct boardromconfig *back; }; #define MAX_BOARD_ROMS 2 @@ -643,6 +648,7 @@ struct uae_prefs { double x86_speed_throttle; int cpu_model; int mmu_model; + bool mmu_ec; int cpu060_revision; int fpu_model; int fpu_revision; diff --git a/od-win32/hardfile_win32.cpp b/od-win32/hardfile_win32.cpp index d33f7802..5c37a7a1 100644 --- a/od-win32/hardfile_win32.cpp +++ b/od-win32/hardfile_win32.cpp @@ -15,6 +15,7 @@ #include "registry.h" #include "win32gui.h" #include "zfile.h" +#include "ini.h" #define hfd_log write_log #define hdf_log2 @@ -65,6 +66,8 @@ struct uae_driveinfo { bool partitiondrive; int readonly; int cylinders, sectors, heads; + int BusType; + }; #define HDF_HANDLE_WIN32 1 @@ -376,6 +379,107 @@ int isharddrive (const TCHAR *name) static TCHAR *hdz[] = { _T("hdz"), _T("zip"), _T("rar"), _T("7z"), NULL }; +static int progressdialogreturn; +static int progressdialogactive; + +static INT_PTR CALLBACK ProgressDialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_DESTROY: + PostQuitMessage (0); + progressdialogactive = 0; + return TRUE; + case WM_CLOSE: + if (progressdialogreturn < 0) + progressdialogreturn = 0; + return TRUE; + case WM_INITDIALOG: + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDCANCEL: + progressdialogreturn = 0; + return TRUE; + } + break; + } + return FALSE; +} + +typedef struct _SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER { + SCSI_PASS_THROUGH_DIRECT spt; + ULONG Filler; + UCHAR SenseBuf[32]; +} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER; + +static bool do_scsi_in(HANDLE h, const uae_u8 *cdb, int cdblen, uae_u8 *in, int insize) +{ + SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb; + DWORD status, returned; + + memset(&swb, 0, sizeof swb); + swb.spt.Length = sizeof (SCSI_PASS_THROUGH); + swb.spt.CdbLength = cdblen; + swb.spt.DataIn = insize > 0 ? SCSI_IOCTL_DATA_IN : 0; + swb.spt.DataTransferLength = insize; + swb.spt.DataBuffer = in; + swb.spt.TimeOutValue = 2 * 60; + swb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, SenseBuf); + swb.spt.SenseInfoLength = 32; + memcpy(swb.spt.Cdb, cdb, cdblen); + status = DeviceIoControl (h, IOCTL_SCSI_PASS_THROUGH_DIRECT, + &swb, sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), + &swb, sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), + &returned, NULL); + if (!status) { + DWORD err = GetLastError(); + write_log(_T("IOCTL_SCSI_PASS_THROUGH_DIRECT: ")); + for (int i = 0; i < cdblen; i++) { + write_log(_T("%02X."), cdb[i]); + } + write_log(_T(" failed %08x\n"), err); + return false; + } else if (swb.spt.ScsiStatus) { + write_log(_T("IOCTL_SCSI_PASS_THROUGH_DIRECT: ")); + for (int i = 0; i < cdblen; i++) { + write_log(_T("%02X."), cdb[i]); + } + write_log(_T("\n")); + write_log(_T("SENSE: ")); + for (int i = 0; i < swb.spt.SenseInfoLength; i++) { + write_log(_T("%02X."), swb.SenseBuf[i]); + } + write_log(_T("\n")); + return false; + } + return true; +} + +#if 0 +static const uae_u8 inquiry[] = { 0x12, 0x01, 0x81, 0, 0xf0, 0 }; +static const uae_u8 modesense[] = { 0x1a, 0x00, 0x3f, 0, 0xf0, 0 }; + +static void scsidirect(HANDLE h) +{ + uae_u8 *inbuf; + + inbuf = (uae_u8*)VirtualAlloc (NULL, 65536, MEM_COMMIT, PAGE_READWRITE); + + do_scsi_in(h, modesense, 6, inbuf, 0xf0); + do_scsi_in(h, inquiry, 6, inbuf, 0xf0); + do_scsi_in(h, realtek_read, 6, inbuf, 0xff00); + + FILE *f = fopen("c:\\temp\\identity.bin", "wb"); + fwrite(inbuf, 1, 512, f); + fclose(f); + + VirtualFree(inbuf, 65536, MEM_RELEASE); +} + +#endif + #if 0 static void getserial (HANDLE h) { @@ -383,12 +487,8 @@ static void getserial (HANDLE h) DISK_GEOMETRY_EX *out; VOLUME_DISK_EXTENTS *vde; - DWORD serial, mcl, fsflags; - if (GetVolumeInformationByHandleW (h, NULL, 0, &serial, &mcl, &fsflags, NULL, 0)) { - } - outsize = sizeof (DISK_GEOMETRY_EX) + 10 * (sizeof (DISK_DETECTION_INFO) + sizeof (DISK_PARTITION_INFO)); - out = xmalloc (outsize); + out = (DISK_GEOMETRY_EX*)xmalloc(uae_u8, outsize); if (DeviceIoControl (h, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, out, outsize, &written, NULL)) { DISK_DETECTION_INFO *ddi = DiskGeometryGetDetect (out); DISK_PARTITION_INFO *dpi = DiskGeometryGetPartition (out); @@ -398,7 +498,7 @@ static void getserial (HANDLE h) outsize = sizeof (VOLUME_DISK_EXTENTS) + sizeof (DISK_EXTENT) * 10; - vde = xmalloc (outsize); + vde = (VOLUME_DISK_EXTENTS*)xmalloc(uae_u8, outsize); if (DeviceIoControl (h, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, vde, outsize, &written, NULL)) { if (vde->NumberOfDiskExtents > 0) write_log(_T("%d\n"), vde->Extents[0].DiskNumber); @@ -408,7 +508,7 @@ static void getserial (HANDLE h) #endif #if 0 -static void queryidentifydevice (struct hardfiledata *hfd) +static void queryataidentity(HANDLE h) { DWORD r, size; uae_u8 *b; @@ -417,22 +517,579 @@ static void queryidentifydevice (struct hardfiledata *hfd) size = sizeof (ATA_PASS_THROUGH_EX) + 512; b = xcalloc (uae_u8, size); ata = (ATA_PASS_THROUGH_EX*)b; + uae_u8 *data = b + sizeof(ATA_PASS_THROUGH_EX); - ata->Length = sizeof ata; + ata->Length = sizeof(ATA_PASS_THROUGH_EX); ata->DataTransferLength = 512; ata->TimeOutValue = 10; ata->AtaFlags = ATA_FLAGS_DRDY_REQUIRED | ATA_FLAGS_DATA_IN; - ata->CurrentTaskFile[6] = 0xec; - ata->DataBufferOffset = ata->Length; + IDEREGS* ir = (IDEREGS*)ata->CurrentTaskFile; + ir->bCommandReg = ID_CMD; + ata->DataBufferOffset = data - b; - if (!DeviceIoControl (hfd->handle->h, IOCTL_ATA_PASS_THROUGH, b, size, b, size, &r, NULL)) { + if (!DeviceIoControl (h, IOCTL_ATA_PASS_THROUGH, b, size, b, size, &r, NULL)) { write_log (_T("IOCTL_ATA_PASS_THROUGH_DIRECT Identify Device failed %d\n"), GetLastError ()); } + + xfree(b); } #endif static int getstorageproperty (PUCHAR outBuf, int returnedLength, struct uae_driveinfo *udi, int ignoreduplicates); +#if 0 +typedef enum _STORAGE_PROTOCOL_TYPE { + ProtocolTypeUnknown = 0x00, + ProtocolTypeScsi, + ProtocolTypeAta, + ProtocolTypeNvme, + ProtocolTypeSd, + ProtocolTypeProprietary = 0x7E, + ProtocolTypeMaxReserved = 0x7F +} STORAGE_PROTOCOL_TYPE, *PSTORAGE_PROTOCOL_TYPE; + +typedef struct _STORAGE_PROTOCOL_SPECIFIC_DATA { + STORAGE_PROTOCOL_TYPE ProtocolType; + DWORD DataType; + DWORD ProtocolDataRequestValue; + DWORD ProtocolDataRequestSubValue; + DWORD ProtocolDataOffset; + DWORD ProtocolDataLength; + DWORD FixedProtocolReturnData; + DWORD Reserved[3]; +} STORAGE_PROTOCOL_SPECIFIC_DATA, *PSTORAGE_PROTOCOL_SPECIFIC_DATA; + +typedef enum _STORAGE_PROTOCOL_ATA_DATA_TYPE { + AtaDataTypeUnknown = 0, + AtaDataTypeIdentify, + AtaDataTypeLogPage +} STORAGE_PROTOCOL_ATA_DATA_TYPE, *PSTORAGE_PROTOCOL_ATA_DATA_TYPE; + +static void getstorageproperty_ataidentity(HANDLE hDevice) +{ + DWORD returnedLength; + DWORD bufferLength = FIELD_OFFSET(STORAGE_PROPERTY_QUERY, AdditionalParameters) + sizeof(STORAGE_PROTOCOL_SPECIFIC_DATA) + 512; + uae_u8 *buffer = xcalloc(uae_u8, bufferLength); + PSTORAGE_PROPERTY_QUERY query = (PSTORAGE_PROPERTY_QUERY)buffer; + PSTORAGE_PROTOCOL_SPECIFIC_DATA protocolData = (PSTORAGE_PROTOCOL_SPECIFIC_DATA)query->AdditionalParameters; + + query->PropertyId = (STORAGE_PROPERTY_ID)50; + query->QueryType = PropertyStandardQuery; + + protocolData->ProtocolType = ProtocolTypeAta; + protocolData->DataType = AtaDataTypeIdentify; + protocolData->ProtocolDataOffset = sizeof(STORAGE_PROTOCOL_SPECIFIC_DATA); + protocolData->ProtocolDataLength = 512; + + DWORD status = DeviceIoControl( + hDevice, + IOCTL_STORAGE_QUERY_PROPERTY, + query, + bufferLength, + query, + bufferLength, + &returnedLength, + NULL); + + DWORD spqerr = GetLastError(); + + xfree(buffer); +} +#endif + +static void bintotextpart(TCHAR *out, uae_u8 *data, int size) +{ + for (int i = 0; i < size; i++) { + uae_u8 b = data[i]; + if (b >= 32 && b < 127) + out[i] = (TCHAR)b; + else + out[i] = '.'; + } + out[size] = 0; +} + +static void bintotextline(TCHAR *out, uae_u8 *data, int size) +{ + TCHAR tmp2[MAX_DPATH]; + int w = 32; + for (int i = 0; i < size; i += w) { + for (int j = 0; j < w + 1 + w / 2; j++) { + tmp2[j * 2 + 0] = ' '; + tmp2[j * 2 + 1] = ' '; + } + for (int j = 0; j < w && j + i < size; j++) { + uae_u8 b = data[i + j]; + _stprintf (tmp2 + j * 2, _T("%02X"), b); + tmp2[j * 2 + 2] = ' '; + if (b >= 32 && b < 127) + tmp2[w * 2 + 1 + j] = (TCHAR)b; + else + tmp2[w * 2 + 1 + j] = '.'; + } + tmp2[w * 2] = ' '; + tmp2[w * 2 + 1 + w] = 0; + _tcscat (out, tmp2); + _tcscat (out, _T("\r\n")); + } +} + +void gui_infotextbox(HWND hDlg, const TCHAR *text); + +static bool hd_get_meta_ata(HWND hDlg, HANDLE h, uae_u8 *datap) +{ + DWORD r, size; + uae_u8 *b; + ATA_PASS_THROUGH_EX *ata; + + size = sizeof (ATA_PASS_THROUGH_EX) + 512; + b = xcalloc (uae_u8, size); + ata = (ATA_PASS_THROUGH_EX*)b; + uae_u8 *data = b + sizeof(ATA_PASS_THROUGH_EX); + ata->Length = sizeof(ATA_PASS_THROUGH_EX); + ata->DataTransferLength = 512; + ata->TimeOutValue = 10; + ata->AtaFlags = ATA_FLAGS_DRDY_REQUIRED | ATA_FLAGS_DATA_IN; + IDEREGS* ir = (IDEREGS*)ata->CurrentTaskFile; + ir->bCommandReg = ID_CMD; + ata->DataBufferOffset = data - b; + if (!DeviceIoControl (h, IOCTL_ATA_PASS_THROUGH, b, size, b, size, &r, NULL)) { + write_log (_T("IOCTL_ATA_PASS_THROUGH_DIRECT ID_CMD failed %08x\n"), GetLastError()); + return false; + } + memcpy(datap, data, 512); + xfree(b); + return true; +} + +#define INQUIRY_LEN 240 + +static const uae_u8 realtek_inquiry_0x83[] = { 0x12, 0x01, 0x83, 0, 0xf0, 0 }; +static const uae_u8 realtek_read[] = { 0xf0, 0x0d, 0xfa, 0x00, 0x02, 0x00 }; + +static bool hd_get_meta_hack(HWND hDlg, HANDLE h, uae_u8 *data, uae_u8 *inq) +{ + uae_u8 cmd[16]; + + memset(data, 0, 512); + memcpy(cmd, realtek_inquiry_0x83, sizeof(realtek_inquiry_0x83)); + if (!do_scsi_in(h, cmd, 6, data, 0xf0)) + return false; + if (memcmp(data + 20, "realtek\0", 8)) { + memset(data, 0, 512); + return false; + } + + memset(data, 0, 512); + memcpy(cmd, realtek_read, sizeof(realtek_read)); + if (!do_scsi_in(h, cmd, 6, data, 512)) { + memset(data, 0, 512); + return false; + } + + int state = 0; + + memset(cmd, 0, 6); // TEST UNIT READY + TCHAR *infotxt; + if (!do_scsi_in(h, cmd, 6, data, 0)) { + state = 1; + infotxt = _T("Realtek hack, insert card."); + } else { + infotxt = _T("Realtek hack, remove and insert the card."); + } + + progressdialogreturn = -1; + progressdialogactive = 1; + HWND hwnd = CustomCreateDialog(IDD_PROGRESSBAR, hDlg, ProgressDialogProc); + if (hwnd == NULL) + return false; + HWND hwndprogress = GetDlgItem (hwnd, IDC_PROGRESSBAR); + ShowWindow(hwndprogress, SW_HIDE); + HWND hwndprogresstxt = GetDlgItem (hwnd, IDC_PROGRESSBAR_TEXT); + ShowWindow(hwnd, SW_SHOW); + + int tcnt = 0; + for (;;) { + if (progressdialogreturn >= 0) + break; + MSG msg; + SendMessage (hwndprogresstxt, WM_SETTEXT, 0, (LPARAM)infotxt); + while (PeekMessage (&msg, hwnd, 0, 0, PM_REMOVE)) { + if (!IsDialogMessage (hwnd, &msg)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } + Sleep(100); + tcnt++; + if (tcnt >= 10) { + memset(cmd, 0, 6); + if (do_scsi_in(h, cmd, 6, data, 0)) { + if (state != 0) { + break; + } + } else { + if (state == 0) { + state++; + infotxt = _T("Removed. Re-insert the card."); + } + } + tcnt = 0; + } + } + + if (progressdialogactive) { + DestroyWindow (hwnd); + MSG msg; + while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } + + memset(data, 0, 512); + memcpy(cmd, realtek_read, sizeof(realtek_read)); + if (do_scsi_in(h, cmd, 6, data, 512)) + return true; + + return false; +} + +static bool hd_get_meta_satl(HWND hDlg, HANDLE h, uae_u8 *data, TCHAR *text, struct ini_data *ini) +{ + uae_u8 cmd[16]; + TCHAR cline[256]; + + memset(cmd, 0, sizeof(cmd)); + cmd[0] = 0x12; // inquiry + cmd[4] = INQUIRY_LEN; + if (!do_scsi_in(h, cmd, 6, data, INQUIRY_LEN)) { + write_log(_T("SAT: INQUIRY failed\n")); + return false; + } + + int type = data[0] & 0x3f; + + _tcscat (text, _T("INQUIRY:\r\n")); + int len = INQUIRY_LEN; + while (len > 0) { + len--; + if (data[len] != 0) + break; + } + len += 3; + len &= ~3; + bintotextline(text, data, len); + _tcscat (text, _T("\r\n")); + bintotextpart(cline, data + 8, 44 - 8); + ini_addnewcomment(ini, _T("INQUIRY"), cline); + ini_addnewdata(ini, _T("INQUIRY"), _T("00"), data, len); + + memset(data, 0, 512); + memset(cmd, 0, sizeof(cmd)); + cmd[0] = 0x25; + if (do_scsi_in(h, cmd, 10, data, 8)) { + _tcscat (text, _T("READ CAPACITY:\r\n")); + bintotextline(text, data, 8); + _tcscat (text, _T("\r\n")); + ini_addnewdata(ini, _T("READ CAPACITY"), _T("DATA"), data, 8); + } + + // get supported evpd pages + memset(data, 0, 512); + memset(cmd, 0, sizeof(cmd)); + cmd[0] = 0x12; // inquiry + cmd[1] = 1; + cmd[4] = INQUIRY_LEN; + if (do_scsi_in(h, cmd, 6, data, INQUIRY_LEN)) { + uae_u8 evpd[256]; + int cnt = 0; + uae_u8 pl = data[3]; + uae_u8 *p = &data[4]; + while (pl != 0) { + if (*p) { + evpd[cnt++] = *p; + } + p++; + pl--; + } + for (int i = 0; i < cnt; i++) { + for (int j = i + 1; j < cnt; j++) { + if (evpd[i] > evpd[j]) { + uae_u8 t = evpd[i]; + evpd[i] = evpd[j]; + evpd[j] = t; + } + } + } + for (int i = 0; i < cnt; i++) { + cmd[2] = evpd[i]; + memset(data, 0, 512); + if (do_scsi_in(h, cmd, 6, data, INQUIRY_LEN)) { + TCHAR tmp[256]; + _stprintf(tmp, _T("INQUIRY %02X:\r\n"), evpd[i]); + _tcscat (text, tmp); + int len = INQUIRY_LEN; + while (len > 0) { + len--; + if (data[len] != 0) + break; + } + len += 3; + len &= ~3; + bintotextline(text, data, len); + _tcscat (text, _T("\r\n")); + _stprintf(tmp, _T("%02X"), evpd[i]); + ini_addnewdata(ini, _T("INQUIRY"),tmp, data, len); + } + } + } + + // get mode sense pages + memset(data, 0, 512); + memset(cmd, 0, sizeof(cmd)); + cmd[0] = 0x5a; + cmd[2] = 0x80 | 0x3f; + cmd[7] = 0xff; + cmd[8] = 0; + if (do_scsi_in(h, cmd, 10, data, 0xff00)) { + TCHAR tmp[256]; + int l = (data[0] << 8) | data[1]; + _tcscat (text, _T("MODE SENSE:\r\n")); + bintotextline(text, data + 2, 4); + _tcscat (text, _T("\r\n")); + ini_addnewdata(ini, _T("MODE SENSE"),_T("PARAMETER LIST"), data + 2, 4); + uae_u16 dbd = (data[6] << 8) | data[7]; + if (dbd) { + _tcscat (text, _T("MODE SENSE BLOCK DESCRIPTOR DATA:\r\n")); + bintotextline(text, data + 8, dbd); + _tcscat (text, _T("\r\n")); + ini_addnewdata(ini, _T("MODE SENSE"), _T("BLOCK DESCRIPTOR DATA"), data + 8, dbd); + } + l -= 8 + dbd; + uae_u8 *p = &data[8 + dbd]; + while (l >= 2) { + uae_u8 page = p[0]; + uae_u8 pl = p[1]; + _stprintf(tmp, _T("MODE SENSE %02X:\r\n"), page); + _tcscat (text, tmp); + bintotextline(text, p, pl + 2); + _tcscat (text, _T("\r\n")); + _stprintf(tmp, _T("%02X"), page); + ini_addnewdata(ini, _T("MODE SENSE"), tmp, p, pl + 2); + p += 2 + pl; + l -= 2 + pl; + } + } + + if (type != 0 && type != 05) { + write_log(_T("SAT: Not Direct access or CD device\n")); + return false; + } + + if (type == 5) { + + memset(cmd, 0, sizeof(cmd)); + memset(data, 0, 512); + cmd[0] = 0x85; // SAT ATA PASSTHROUGH (16) + cmd[1] = 4 << 1; // PIO data-in + cmd[2] = 0x08 | 0x04 | 0x02; // dir = from device, 512 byte block, sector count = block cnt + cmd[6] = 1; // block count + cmd[14] = 0xa1; // identity packet device + if (do_scsi_in(h, cmd, 16, data, 512)) + return true; + write_log(_T("SAT: ATA PASSTHROUGH(16) failed\n")); + + } else { + + memset(cmd, 0, sizeof(cmd)); + memset(data, 0, 512); + cmd[0] = 0xa1; // SAT ATA PASSTHROUGH (12) + cmd[1] = 4 << 1; // PIO data-in + cmd[2] = 0x08 | 0x04 | 0x02; // dir = from device, 512 byte block, sector count = block cnt + cmd[4] = 1; // block count + cmd[9] = 0xec; // identity + if (do_scsi_in(h, cmd, 12, data, 512)) + return true; + write_log(_T("SAT: ATA PASSTHROUGH(12) failed\n")); + } + + return false; +} + +static int stringboxdialogactive; +static TCHAR geometry_file[MAX_DPATH]; +static struct ini_data *hdini; +static INT_PTR CALLBACK StringBoxDialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_DESTROY: + PostQuitMessage (0); + return TRUE; + case WM_CLOSE: + stringboxdialogactive = 0; + DestroyWindow (hDlg); + return TRUE; + case WM_INITDIALOG: + geometry_file[0] = 0; + ShowWindow(GetDlgItem (hDlg, IDC_SAVEBOOTBLOCK), SW_SHOW); + SetWindowText(hDlg, _T("Harddrive information")); + return TRUE; + case WM_COMMAND: + switch (LOWORD (wParam)) + { + case IDC_SAVEBOOTBLOCK: + if (DiskSelection(hDlg, 0, 24, &workprefs, geometry_file)) { + ini_save(hdini, geometry_file); + } + break; + case IDOK: + stringboxdialogactive = -1; + DestroyWindow (hDlg); + return TRUE; + case IDCANCEL: + stringboxdialogactive = 0; + DestroyWindow (hDlg); + return TRUE; + } + break; + } + return FALSE; +} + +void ata_byteswapidentity(uae_u8 *d); + +void hd_get_meta(HWND hDlg, int idx, TCHAR *geometryfile) +{ + struct uae_driveinfo *udi = &uae_drives[idx]; + bool satl = false; + uae_u8 *data = NULL; + uae_u8 inq[INQUIRY_LEN + 4] = { 0 }; + TCHAR *text; + struct ini_data *ini = NULL; + + geometryfile[0] = 0; + text = xcalloc(TCHAR, 10000); + + HANDLE h = CreateFile(udi->device_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (h == INVALID_HANDLE_VALUE) { + write_log(_T("CreateFile('%s') failed, err=%08x\n"), udi->device_path, GetLastError()); + goto end; + } + + ini = ini_new(); + ini_addstring(ini, _T("GEOMETRY"), NULL, NULL); + data = (uae_u8*)VirtualAlloc (NULL, 65536, MEM_COMMIT, PAGE_READWRITE); + inq[0] = 0xff; + + if (udi->BusType == BusTypeAta || udi->BusType == BusTypeSata) { + if (!_tcscmp(udi->vendor_id, _T("ATA "))) { + satl = true; + } + } + + _stprintf(text, _T("BusType: 0x%02x\r\nVendor: '%s'\r\nProduct: '%s'\r\nRevision: '%s'\r\nSerial: '%s'\r\nSize: %llu\r\n\r\n"), + udi->BusType, udi->vendor_id, udi->product_id, udi->product_rev, udi->product_serial, udi->size); + + if (satl || udi->BusType == BusTypeScsi || udi->BusType == BusTypeUsb || udi->BusType == BusTypeRAID) { + if (!hd_get_meta_satl(hDlg, h, data, text, ini)) { + write_log(_T("SAT Passthrough failed\n")); + memset(data, 0, 512); + if (udi->BusType == BusTypeUsb) { + hd_get_meta_hack(hDlg, h, data, inq); + } + if (text[0] == 0) { + _tcscpy(text, _T("SCSI ATA Passthrough error!")); + goto doout; + } + } + } else if (udi->BusType == BusTypeAta || udi->BusType == BusTypeSata) { + if (!hd_get_meta_ata(hDlg, h, data)) { + write_log(_T("ATA Passthrough failed\n")); + _tcscpy(text, _T("ATA Passthrough error!")); + goto doout; + } + } else { + _stprintf(text, _T("Unsupported bus type %02x\n"), udi->BusType); + goto doout; + } + + bool empty = true; + for (int i = 0; i < 512; i++) { + if (data[i] != 0) + empty = false; + } + + if (empty) { + write_log(_T("Nothing returned!\n")); + if (text[0] == 0) { + _tcscpy(text, _T("Nothing returned!")); + goto doout; + } + } + + ata_byteswapidentity(data); + + if (!empty) { + TCHAR cline[256]; + _tcscat (text, _T("IDENTITY:\r\n")); + bintotextline(text, data, 512); + + bintotextpart(cline, data + 27 * 2, 40); + ini_addnewcomment(ini, _T("IDENTITY"), cline); + bintotextpart(cline, data + 23 * 2, 8); + ini_addnewcomment(ini, _T("IDENTITY"), cline); + bintotextpart(cline, data + 10 * 2, 20); + ini_addnewcomment(ini, _T("IDENTITY"), cline); + + ini_addnewdata(ini, _T("IDENTITY"), _T("DATA"), data, 512); + } + +doout: + stringboxdialogactive = 1; + hdini = ini; + HWND hwnd = CustomCreateDialog (IDD_DISKINFO, hDlg, StringBoxDialogProc); + if (hwnd != NULL) { + HFONT font = CreateFont (12, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, _T("Lucida Console")); + if (font) + SendMessage (GetDlgItem (hwnd, IDC_DISKINFOBOX), WM_SETFONT, WPARAM(font), FALSE); + SendMessage (GetDlgItem (hwnd, IDC_DISKINFOBOX), WM_SETTEXT, 0, (LPARAM)text); + while (stringboxdialogactive == 1) { + MSG msg; + int ret; + WaitMessage (); + while ((ret = GetMessage (&msg, NULL, 0, 0))) { + if (ret == -1) + break; + if (!IsWindow (hwnd) || !IsDialogMessage (hwnd, &msg)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } + if (stringboxdialogactive == -1) + break; + } + DeleteObject (font); + } + +end: + if (ini) + ini_free(ini); + + if (data) + VirtualFree(data, 65536, MEM_RELEASE); + + if (h != INVALID_HANDLE_VALUE) + CloseHandle(h); + + _tcscpy(geometryfile, geometry_file); + + xfree(text); +} + static bool getdeviceinfo (HANDLE hDevice, struct uae_driveinfo *udi) { DISK_GEOMETRY dg; @@ -470,6 +1127,8 @@ static bool getdeviceinfo (HANDLE hDevice, struct uae_driveinfo *udi) } } + //queryidentifydevice(hDevice); + udi->device_name[0] = 0; memset (outBuf, 0, sizeof outBuf); query.PropertyId = StorageDeviceProperty; @@ -729,6 +1388,9 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname) if (udi->readonly) hfd->ci.readonly = 1; } + + //hfd->ci.readonly = false; + flags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS; h = CreateFile (udi->device_path, GENERIC_READ | (hfd->ci.readonly ? 0 : GENERIC_WRITE), @@ -756,7 +1418,6 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname) goto end; } - //queryidentifydevice (hfd); _tcsncpy (hfd->vendor_id, udi->vendor_id, 8); _tcsncpy (hfd->product_id, udi->product_id, 16); _tcsncpy (hfd->product_rev, udi->product_rev, 4); @@ -800,11 +1461,15 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname) hfd->warned = -1; #endif } + lock_drive(hfd, name, h); hfd->handle_valid = HDF_HANDLE_WIN32; hfd->emptyname = my_strdup (name); + //getstorageproperty_ataidentity(h); + //queryataidentity(h); + //scsidirect(h); //fixdrive (hfd); } else { @@ -827,7 +1492,7 @@ emptyreal: OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); if (h == INVALID_HANDLE_VALUE && !hfd->ci.readonly) { DWORD err = GetLastError (); - if (err == ERROR_WRITE_PROTECT || err == ERROR_SHARING_VIOLATION) { + if (err == ERROR_WRITE_PROTECT || err == ERROR_ACCESS_DENIED || err == ERROR_SHARING_VIOLATION) { h = CreateFile (name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); if (h != INVALID_HANDLE_VALUE) @@ -1380,6 +2045,12 @@ static int getstorageproperty (PUCHAR outBuf, int returnedLength, struct uae_dri for (i = devDesc->SerialNumberOffset; p[i] != (UCHAR) NULL && i < returnedLength; i++) udi->product_serial[j++] = p[i]; } + + my_trim(udi->vendor_id); + my_trim(udi->product_id); + my_trim(udi->product_rev); + my_trim(udi->product_serial); + if (udi->vendor_id[0]) _tcscat (udi->device_name, udi->vendor_id); if (udi->product_id[0]) { @@ -1409,6 +2080,7 @@ static int getstorageproperty (PUCHAR outBuf, int returnedLength, struct uae_dri udi->device_name[i] = '_'; } write_log (_T("device id string: '%s'\n"), udi->device_name); + udi->BusType = devDesc->BusType; if (ignoreduplicates) { if (!udi->removablemedia) { write_log (_T("drive letter not removable, ignored\n")); @@ -2110,35 +2782,6 @@ int win32_hardfile_media_change (const TCHAR *drvname, int inserted) return gotinsert; } -static int progressdialogreturn; -static int progressdialogactive; - -static INT_PTR CALLBACK ProgressDialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_DESTROY: - PostQuitMessage (0); - progressdialogactive = 0; - return TRUE; - case WM_CLOSE: - if (progressdialogreturn < 0) - progressdialogreturn = 0; - return TRUE; - case WM_INITDIALOG: - return TRUE; - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDCANCEL: - progressdialogreturn = 0; - return TRUE; - } - break; - } - return FALSE; -} - extern HMODULE hUIDLL; extern HINSTANCE hInst; diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 56bf8519..fff9c942 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -96,6 +96,7 @@ #ifdef RETROPLATFORM #include "rp.h" #endif +#include "ini.h" #define GUI_SCALE_DEFAULT 100 #define MIN_GUI_INTERNAL_WIDTH 512 @@ -110,6 +111,7 @@ #define HDF_FORMAT_STRING _T("(*.hdf;*.vhd;*.rdf;*.hdz;*.rdz;*.chd)\0*.hdf;*.vhd;*.rdf;*.hdz;*.rdz;*.chd\0") #define INP_FORMAT_STRING _T("(*.inp)\0*.inp\0") #define CD_FORMAT_STRING _T("(*.cue;*.ccd;*.mds;*.iso;*.chd;*.nrg)\0*.cue;*.ccd;*.mds;*.iso;*.chd;*.nrg;") ARCHIVE_STRING _T("\0") +#define GEO_FORMAT_STRING _T("(*.geo)\0*.geo\0") #define CONFIG_HOST _T("Host") #define CONFIG_HARDWARE _T("Hardware") @@ -650,7 +652,8 @@ static const TCHAR *historytypes[] = _T("FileSysMRUList"), _T("TapeImageMRUList"), _T("GenlockImageMRUList"), - _T("GenlockVideoMRUList") + _T("GenlockVideoMRUList"), + _T("GeometryMRUList") }; static int regread; @@ -692,6 +695,7 @@ void write_disk_history (void) write_disk_history2(HISTORY_TAPE); write_disk_history2(HISTORY_GENLOCK_IMAGE); write_disk_history2(HISTORY_GENLOCK_VIDEO); + write_disk_history2(HISTORY_GEO); } void reset_disk_history (void) @@ -707,6 +711,7 @@ void reset_disk_history (void) DISK_history_add(NULL, i, HISTORY_TAPE, 0); DISK_history_add(NULL, i, HISTORY_GENLOCK_IMAGE, 0); DISK_history_add(NULL, i, HISTORY_GENLOCK_VIDEO, 0); + DISK_history_add(NULL, i, HISTORY_GEO, 0); } rrold = regread; regread = (1 << HISTORY_MAX) - 1; @@ -2262,7 +2267,7 @@ void gui_display (int shortcut) inputdevice_acquire (TRUE); setmouseactive (1); #ifdef AVIOUTPUT - AVIOutput_Begin (); + AVIOutput_Begin (true); #endif } flipgui(false); @@ -2397,6 +2402,35 @@ static void eject_cd (void) } } +void gui_infotextbox(HWND hDlg, const TCHAR *text) +{ + stringboxdialogactive = 1; + HWND hwnd = CustomCreateDialog (IDD_DISKINFO, hDlg ? hDlg : hGUIWnd, StringBoxDialogProc); + if (hwnd == NULL) + return; + + HFONT font = CreateFont (12, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, _T("Lucida Console")); + if (font) + SendMessage (GetDlgItem (hwnd, IDC_DISKINFOBOX), WM_SETFONT, WPARAM(font), FALSE); + SendMessage (GetDlgItem (hwnd, IDC_DISKINFOBOX), WM_SETTEXT, 0, (LPARAM)text); + while (stringboxdialogactive == 1) { + MSG msg; + int ret; + WaitMessage (); + while ((ret = GetMessage (&msg, NULL, 0, 0))) { + if (ret == -1) + break; + if (!IsWindow (hwnd) || !IsDialogMessage (hwnd, &msg)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } + if (stringboxdialogactive == -1) + break; + } + DeleteObject (font); +} + static void infofloppy (HWND hDlg, int n) { struct diskinfo di; @@ -2566,6 +2600,8 @@ static void setdpath (const TCHAR *name, const TCHAR *path) // flag = 20 for genlock image // flag = 21 for genlock video // flag = 22 for floppy replacement (missing statefile) +// fags = 23 for hdf geometry (load) +// fags = 24 for hdf geometry (save) int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs, TCHAR *path_out, int *multi) { @@ -2606,6 +2642,8 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs break; case 2: case 3: + case 23: + case 24: getfilter (flag, _T("hdfPath"), previousfilter, filtername); fetch_path (_T("hdfPath"), init_path, sizeof (init_path) / sizeof (TCHAR)); guid = &diskselectionguids[1]; @@ -2819,6 +2857,14 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs case 21: _tcscpy(szTitle, _T("Select genlock video")); break; + case 23: + case 24: + _tcscpy(szTitle, _T("Select geometry file")); + _stprintf (szFilter, _T("%s "), _T("Geometry files")); + memcpy (szFilter + _tcslen (szFilter), GEO_FORMAT_STRING, sizeof (GEO_FORMAT_STRING) + sizeof (TCHAR)); + defext = _T("geo"); + break; + break; } if (all) { p = szFilter; @@ -2850,7 +2896,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs if (multi) openFileName.Flags |= OFN_ALLOWMULTISELECT; - if (flag == 1 || flag == 3 || flag == 5 || flag == 9 || flag == 16) { + if (flag == 1 || flag == 3 || flag == 5 || flag == 9 || flag == 16 || flag == 24) { openFileName.Flags &= ~OFN_FILEMUSTEXIST; if (!(result = GetSaveFileName_2 (hDlg, &openFileName, guid))) write_log (_T("GetSaveFileNameX() failed, err=%d.\n"), GetLastError ()); @@ -2906,6 +2952,9 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs case IDC_GENLOCKFILESELECT: selectgenlock(prefs, hDlg, IDC_GENLOCKFILE, full_path); break; + case IDC_PATH_GEOMETRY: + SetDlgItemText (hDlg, wParam, full_path); + break; case IDC_CD_SELECT: selectcd (prefs, hDlg, 0, IDC_CD_TEXT, full_path); break; @@ -3030,7 +3079,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs *amiga_path = 0; setdpath (_T("FloppyPath"), openFileName.lpstrFile); } - } else if (flag == 2 || flag == 3) { + } else if (flag == 2 || flag == 3 || flag == 23) { amiga_path = _tcsstr (openFileName.lpstrFile, openFileName.lpstrFileTitle); if (amiga_path && amiga_path != openFileName.lpstrFile) { *amiga_path = 0; @@ -4808,7 +4857,7 @@ void InitializeListView (HWND hDlg) _stprintf (bootpri_str, _T("%d"), ci->bootpri); } else if (type == FILESYS_HARDFILE_RDB || type == FILESYS_HARDDRIVE || ci->controller_type != HD_CONTROLLER_TYPE_UAE) { _stprintf (blocksize_str, _T("%d"), ci->blocksize); - _tcscpy (devname_str, _T("UAE")); + _stprintf (devname_str, _T("UAE:%d"), ci->controller_unit); _tcscpy (volname_str, _T("n/a")); _tcscpy (bootpri_str, _T("n/a")); } else if (type == FILESYS_TAPE) { @@ -9163,10 +9212,19 @@ static void init_expansion2(HWND hDlg, bool init) SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTNUM, CB_SETCURSEL, scsiromselectednum, 0); SendDlgItemMessage(hDlg, IDC_SCSIROMID, CB_RESETCONTENT, 0, 0); - for (int i = 0; i < 8; i++) { - TCHAR tmp[10]; - _stprintf(tmp, _T("%d"), i); - SendDlgItemMessage(hDlg, IDC_SCSIROMID, CB_ADDSTRING, 0, (LPARAM)tmp); + int index; + struct boardromconfig *brc = get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, scsiromselectednum, &index); + const struct expansionromtype *ert = &expansionroms[scsiromselected]; + if (brc && ert && ert->id_jumper) { + for (int i = 0; i < 8; i++) { + TCHAR tmp[10]; + _stprintf(tmp, _T("%d"), i); + SendDlgItemMessage(hDlg, IDC_SCSIROMID, CB_ADDSTRING, 0, (LPARAM)tmp); + } + } else { + SendDlgItemMessage(hDlg, IDC_SCSIROMID, CB_ADDSTRING, 0, (LPARAM)_T("-")); + SendDlgItemMessage(hDlg, IDC_SCSIROMID, CB_SETCURSEL, 0, 0); + ew(hDlg, IDC_SCSIROMID, 0); } } @@ -9189,8 +9247,7 @@ static void values_to_expansion2dlg_sub(HWND hDlg) if (brc) { SendDlgItemMessage(hDlg, IDC_SCSIROMSUBSELECT, CB_SETCURSEL, brc->roms[index].subtype, 0); SendDlgItemMessage(hDlg, IDC_SCSIROMID, CB_SETCURSEL, brc->roms[index].device_id, 0); - } - else if (srt) { + } else if (srt) { SendDlgItemMessage(hDlg, IDC_SCSIROMSUBSELECT, CB_SETCURSEL, 0, 0); SendDlgItemMessage(hDlg, IDC_SCSIROMID, CB_SETCURSEL, 0, 0); } @@ -9207,11 +9264,14 @@ static void values_from_expansion2dlg(HWND hDlg) struct boardromconfig *brc; TCHAR tmp[MAX_DPATH]; bool changed = false; + bool isnew = false; int checked = ischecked(hDlg, IDC_SCSIROMSELECTED); getromfile(hDlg, IDC_SCSIROMFILE, tmp, MAX_DPATH / sizeof(TCHAR)); if (tmp[0] || checked) { const struct expansionromtype *ert = &expansionroms[scsiromselected]; + if (!get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, scsiromselectednum, &index)) + isnew = true; brc = get_device_rom_new(&workprefs, expansionroms[scsiromselected].romtype, scsiromselectednum, &index); if (checked) { if (!brc->roms[index].romfile[0]) @@ -9224,10 +9284,9 @@ static void values_from_expansion2dlg(HWND hDlg) brc->roms[index].autoboot_disabled = ischecked(hDlg, IDC_SCSIROMFILEAUTOBOOT); int v = SendDlgItemMessage(hDlg, IDC_SCSIROMID, CB_GETCURSEL, 0, 0L); - if (v != CB_ERR) + if (v != CB_ERR && !isnew) brc->roms[index].device_id = v; - const struct expansionboardsettings *cbs = ert->settings; if (cbs) { brc->roms[index].device_settings = expansion_gui_item.expansionrom_gui_settings; @@ -11383,6 +11442,7 @@ static void enable_for_cpudlg (HWND hDlg) ew (hDlg, IDC_FPU1, workprefs.cpu_model < 68040 && (workprefs.cpu_model >= 68020 || !workprefs.cpu_compatible)); ew (hDlg, IDC_FPU2, workprefs.cpu_model < 68040 && (workprefs.cpu_model >= 68020 || !workprefs.cpu_compatible)); ew (hDlg, IDC_FPU3, workprefs.cpu_model >= 68040); + ew (hDlg, IDC_MMUENABLEEC, workprefs.cpu_model >= 68030 && workprefs.cachesize == 0); ew (hDlg, IDC_MMUENABLE, workprefs.cpu_model >= 68030 && workprefs.cachesize == 0); ew (hDlg, IDC_CPU_PPC, workprefs.cpu_model >= 68040 && (workprefs.ppc_mode == 1 || (workprefs.ppc_mode == 0 && !is_ppc_cpu(&workprefs)))); @@ -11452,11 +11512,11 @@ static void values_to_cpudlg (HWND hDlg) CheckDlgButton (hDlg, IDC_HARDFLUSH, workprefs.comp_hardflush); CheckDlgButton (hDlg, IDC_CONSTJUMP, workprefs.comp_constjump); CheckDlgButton (hDlg, IDC_JITENABLE, workprefs.cachesize > 0); - CheckDlgButton (hDlg, IDC_MMUENABLE, - ((workprefs.cpu_model == 68060 && workprefs.mmu_model == 68060) || + bool mmu = ((workprefs.cpu_model == 68060 && workprefs.mmu_model == 68060) || (workprefs.cpu_model == 68040 && workprefs.mmu_model == 68040) || (workprefs.cpu_model == 68030 && workprefs.mmu_model == 68030)) && - workprefs.cachesize == 0); + workprefs.cachesize == 0; + CheckRadioButton (hDlg, IDC_MMUENABLEOFF, IDC_MMUENABLE, mmu == 0 ? IDC_MMUENABLEOFF : (mmu && workprefs.mmu_ec) ? IDC_MMUENABLEEC : IDC_MMUENABLE); CheckDlgButton(hDlg, IDC_CPU_PPC, workprefs.ppc_mode || is_ppc_cpu(&workprefs)); if (workprefs.cpu_cycle_exact) { @@ -11505,6 +11565,7 @@ static void values_from_cpudlg (HWND hDlg) newfpu = 0; workprefs.cpu_model = newcpu; workprefs.mmu_model = 0; + workprefs.mmu_ec = false; switch(newcpu) { case 68000: @@ -11522,19 +11583,22 @@ static void values_from_cpudlg (HWND hDlg) if (newcpu != oldcpu) workprefs.address_space_24 = 0; workprefs.fpu_model = newfpu == 0 ? 0 : (newfpu == 2 ? 68882 : 68881); - workprefs.mmu_model = ischecked (hDlg, IDC_MMUENABLE) ? 68030 : 0; + workprefs.mmu_ec = ischecked(hDlg, IDC_MMUENABLEEC); + workprefs.mmu_model = workprefs.mmu_ec || ischecked (hDlg, IDC_MMUENABLE) ? 68030 : 0; break; case 68040: workprefs.fpu_model = newfpu ? 68040 : 0; workprefs.address_space_24 = 0; if (workprefs.fpu_model) workprefs.fpu_model = 68040; - workprefs.mmu_model = ischecked (hDlg, IDC_MMUENABLE) ? 68040 : 0; + workprefs.mmu_ec = ischecked(hDlg, IDC_MMUENABLEEC); + workprefs.mmu_model = workprefs.mmu_ec || ischecked (hDlg, IDC_MMUENABLE) ? 68040 : 0; break; case 68060: workprefs.fpu_model = newfpu ? 68060 : 0; workprefs.address_space_24 = 0; - workprefs.mmu_model = ischecked (hDlg, IDC_MMUENABLE) ? 68060 : 0; + workprefs.mmu_ec = ischecked(hDlg, IDC_MMUENABLEEC); + workprefs.mmu_model = workprefs.mmu_ec || ischecked (hDlg, IDC_MMUENABLE) ? 68060 : 0; break; } @@ -12300,9 +12364,13 @@ static void hardfile_testrdb (struct hfdlg_vals *hdf) hdf->ci.controller_type_unit = 0; break; } - 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)) { + 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) { // RDSK or ADIDE "encoded" RDSK - int blocksize = (id[16] << 24) | (id[17] << 16) | (id[18] << 8) | (id[19] << 0); + int blocksize = 512; + if (!babe) + blocksize = (id[16] << 24) | (id[17] << 16) | (id[18] << 8) | (id[19] << 0); hdf->ci.cyls = hdf->ci.highcyl = hdf->forcedcylinders = 0; hdf->ci.sectors = 0; hdf->ci.surfaces = 0; @@ -12521,6 +12589,16 @@ STATIC_INLINE bool is_hdf_rdb (void) static int hdmenutable[256]; +static void sethardfilegeo(HWND hDlg) +{ + if (current_hfdlg.ci.geometry[0]) { + current_hfdlg.ci.physical_geometry = true; + setchecked(hDlg, IDC_HDF_PHYSGEOMETRY, TRUE); + ew (hDlg, IDC_HDF_PHYSGEOMETRY, FALSE); + get_hd_geometry(¤t_hfdlg.ci); + } +} + static void sethardfiletypes(HWND hDlg) { bool ide = current_hfdlg.ci.controller_type >= HD_CONTROLLER_TYPE_IDE_FIRST && current_hfdlg.ci.controller_type <= HD_CONTROLLER_TYPE_IDE_LAST; @@ -12536,16 +12614,12 @@ static void sethardfiletypes(HWND hDlg) SendDlgItemMessage(hDlg, IDC_HDF_FEATURE_LEVEL, CB_SETCURSEL, current_hfdlg.ci.unit_feature_level, 0); } -static void sethardfile (HWND hDlg) +static void sethd(HWND hDlg) { - bool ide = current_hfdlg.ci.controller_type >= HD_CONTROLLER_TYPE_IDE_FIRST && current_hfdlg.ci.controller_type <= HD_CONTROLLER_TYPE_IDE_LAST; - bool scsi = current_hfdlg.ci.controller_type >= HD_CONTROLLER_TYPE_SCSI_FIRST && current_hfdlg.ci.controller_type <= HD_CONTROLLER_TYPE_SCSI_LAST; bool rdb = is_hdf_rdb (); bool physgeo = rdb && ischecked(hDlg, IDC_HDF_PHYSGEOMETRY); - bool enablegeo = !rdb || physgeo; - bool disables = !rdb || (rdb && current_hfdlg.ci.controller_type == HD_CONTROLLER_TYPE_UAE); + bool enablegeo = !rdb || (physgeo && current_hfdlg.ci.geometry[0] == 0); const struct expansionromtype *ert = get_unit_expansion_rom(current_hfdlg.ci.controller_type); - if (ert && current_hfdlg.ci.controller_unit >= 8) { if (!_tcscmp(ert->name, _T("a2091"))) { current_hfdlg.ci.unit_feature_level = HD_LEVEL_SASI_CHS; @@ -12553,11 +12627,39 @@ static void sethardfile (HWND hDlg) current_hfdlg.ci.unit_feature_level = HD_LEVEL_SCSI_1; } } + if (!physgeo) + current_hfdlg.ci.physical_geometry = false; + ew(hDlg, IDC_SECTORS, enablegeo); + ew(hDlg, IDC_HEADS, enablegeo); + ew(hDlg, IDC_RESERVED, enablegeo); + ew(hDlg, IDC_BLOCKSIZE, enablegeo); +} +static void setharddrive(HWND hDlg) +{ + sethardfilegeo(hDlg); + sethd(hDlg); + ew(hDlg,IDC_BLOCKSIZE, FALSE); + SetDlgItemInt (hDlg, IDC_SECTORS, current_hfdlg.ci.psecs, FALSE); + SetDlgItemInt (hDlg, IDC_HEADS, current_hfdlg.ci.pheads, FALSE); + SetDlgItemInt (hDlg, IDC_RESERVED, current_hfdlg.ci.pcyls, FALSE); + SetDlgItemInt (hDlg, IDC_BLOCKSIZE, current_hfdlg.ci.blocksize, FALSE); + sethardfiletypes(hDlg); +} + +static void sethardfile (HWND hDlg) +{ + sethardfilegeo(hDlg); + + bool ide = current_hfdlg.ci.controller_type >= HD_CONTROLLER_TYPE_IDE_FIRST && current_hfdlg.ci.controller_type <= HD_CONTROLLER_TYPE_IDE_LAST; + bool scsi = current_hfdlg.ci.controller_type >= HD_CONTROLLER_TYPE_SCSI_FIRST && current_hfdlg.ci.controller_type <= HD_CONTROLLER_TYPE_SCSI_LAST; + bool rdb = is_hdf_rdb (); + bool physgeo = rdb && ischecked(hDlg, IDC_HDF_PHYSGEOMETRY); + bool disables = !rdb || (rdb && current_hfdlg.ci.controller_type == HD_CONTROLLER_TYPE_UAE); + + sethd(hDlg); if (!disables) current_hfdlg.ci.bootpri = 0; - if (!physgeo) - current_hfdlg.ci.physical_geometry = false; SetDlgItemText (hDlg, IDC_PATH_NAME, current_hfdlg.ci.rootdir); SetDlgItemText (hDlg, IDC_PATH_FILESYS, current_hfdlg.ci.filesys); SetDlgItemText (hDlg, IDC_HARDFILE_DEVICE, current_hfdlg.ci.devname); @@ -12577,10 +12679,6 @@ static void sethardfile (HWND hDlg) hide (hDlg, IDC_HARDFILE_BOOTPRI, !disables); hide (hDlg, IDC_HARDFILE_BOOTPRI_TEXT, !disables); hide (hDlg, IDC_HDF_PHYSGEOMETRY, !rdb); - ew(hDlg, IDC_SECTORS, enablegeo); - ew(hDlg, IDC_HEADS, enablegeo); - ew(hDlg, IDC_RESERVED, enablegeo); - ew(hDlg, IDC_BLOCKSIZE, enablegeo); hide(hDlg, IDC_RESERVED_TEXT, rdb); hide(hDlg, IDC_CYLINDERS_TEXT, !rdb); gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, current_hfdlg.ci.controller_type + current_hfdlg.ci.controller_type_unit * HD_CONTROLLER_NEXT_UNIT); @@ -12617,7 +12715,7 @@ static void addhdcontroller(HWND hDlg, const struct expansionromtype *erc, int * } } -static void inithdcontroller (HWND hDlg, int ctype, int ctype_unit, int devtype) +static void inithdcontroller (HWND hDlg, int ctype, int ctype_unit, int devtype, bool media) { hdmenutable[0] = -1; @@ -12667,7 +12765,8 @@ static void inithdcontroller (HWND hDlg, int ctype, int ctype_unit, int devtype) _stprintf(tmp, _T("%d"), i + 1); SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)tmp); } - ew(hDlg, IDC_HDF_CONTROLLER_UNIT, TRUE); + if (media) + ew(hDlg, IDC_HDF_CONTROLLER_UNIT, TRUE); } else if (ctype >= HD_CONTROLLER_TYPE_SCSI_FIRST && ctype <= HD_CONTROLLER_TYPE_SCSI_LAST) { const struct expansionromtype *ert = get_unit_expansion_rom(ctype); SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)_T("0")); @@ -12686,11 +12785,20 @@ static void inithdcontroller (HWND hDlg, int ctype, int ctype_unit, int devtype) SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)_T("ST-506 #2")); } } - ew(hDlg, IDC_HDF_CONTROLLER_UNIT, TRUE); + if (media) + ew(hDlg, IDC_HDF_CONTROLLER_UNIT, TRUE); } else if (ctype == HD_CONTROLLER_TYPE_PCMCIA) { SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)_T("SRAM")); SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)_T("IDE")); ew(hDlg, IDC_HDF_CONTROLLER_UNIT, TRUE); + } else if (ctype == HD_CONTROLLER_TYPE_UAE) { + for (int i = 0; i < MAX_FILESYSTEM_UNITS; i++) { + TCHAR tmp[100]; + _stprintf(tmp, _T("%d"), i); + SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)tmp); + } + if (media) + ew(hDlg, IDC_HDF_CONTROLLER_UNIT, TRUE); } else { ew(hDlg, IDC_HDF_CONTROLLER_UNIT, FALSE); } @@ -12715,13 +12823,13 @@ static void inithdcontroller (HWND hDlg, int ctype, int ctype_unit, int devtype) } } -static void inithardfile (HWND hDlg) +static void inithardfile (HWND hDlg, bool media) { TCHAR tmp[MAX_DPATH]; ew (hDlg, IDC_HF_DOSTYPE, FALSE); ew (hDlg, IDC_HF_CREATE, FALSE); - inithdcontroller (hDlg, current_hfdlg.ci.controller_type, current_hfdlg.ci.controller_type_unit, UAEDEV_HDF); + inithdcontroller (hDlg, current_hfdlg.ci.controller_type, current_hfdlg.ci.controller_type_unit, UAEDEV_HDF, media); SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_RESETCONTENT, 0, 0); WIN32GUI_LoadUIString (IDS_HF_FS_CUSTOM, tmp, sizeof (tmp) / sizeof (TCHAR)); SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("RDB/OFS/FFS")); @@ -12818,6 +12926,9 @@ static void updatehdfinfo (HWND hDlg, bool force, bool defaults) blocks = cyls * (secs * heads); if (!blocks && current_hfdlg.ci.blocksize) blocks = bsize / current_hfdlg.ci.blocksize; + if (current_hfdlg.ci.max_lba) + blocks = current_hfdlg.ci.max_lba; + for (i = 0; i < sizeof (idtmp) / sizeof (TCHAR) - 1; i++) { TCHAR c = id[i]; if (c < 32 || c > 126) @@ -12868,7 +12979,7 @@ static void hardfileselecthdf (HWND hDlg, TCHAR *newpath, bool ask, bool newhd) current_hfdlg.ci.sectors = current_hfdlg.ci.reserved = current_hfdlg.ci.surfaces = 0; } } - inithardfile (hDlg); + inithardfile (hDlg, true); hardfile_testrdb (¤t_hfdlg); updatehdfinfo (hDlg, true, true); get_hd_geometry (¤t_hfdlg.ci); @@ -12907,7 +13018,7 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara recursive++; if (current_tapedlg.ci.controller_type < HD_CONTROLLER_TYPE_SCSI_AUTO) current_tapedlg.ci.controller_type = HD_CONTROLLER_TYPE_SCSI_AUTO; - inithdcontroller(hDlg, current_tapedlg.ci.controller_type, current_tapedlg.ci.controller_type_unit, UAEDEV_TAPE); + inithdcontroller(hDlg, current_tapedlg.ci.controller_type, current_tapedlg.ci.controller_type_unit, UAEDEV_TAPE, current_tapedlg.ci.rootdir[0] != 0); SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_tapedlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_tapedlg.ci.controller_unit : current_tapedlg.ci.controller_type_unit, 0); setautocomplete (hDlg, IDC_PATH_NAME); addhistorymenu(hDlg, current_tapedlg.ci.rootdir, IDC_PATH_NAME, HISTORY_TAPE, false); @@ -12940,7 +13051,7 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara current_tapedlg.ci.controller_type_unit = posn / HD_CONTROLLER_NEXT_UNIT; if (current_tapedlg.ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA) current_tapedlg.ci.controller_type_unit = 1; - inithdcontroller(hDlg, current_tapedlg.ci.controller_type, current_tapedlg.ci.controller_type_unit, UAEDEV_TAPE); + inithdcontroller(hDlg, current_tapedlg.ci.controller_type, current_tapedlg.ci.controller_type_unit, UAEDEV_TAPE, current_tapedlg.ci.rootdir); SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_tapedlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_tapedlg.ci.controller_unit : current_tapedlg.ci.controller_type_unit, 0); } break; @@ -13023,7 +13134,7 @@ static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, is_board_enabled(&workprefs, ROMTYPE_GVPS2, 0) || is_board_enabled(&workprefs, ROMTYPE_A4091, 0) || workprefs.cs_cdtvscsi || (workprefs.cs_mbdmac & 3)) ? HD_CONTROLLER_TYPE_SCSI_AUTO : HD_CONTROLLER_TYPE_IDE_AUTO; - inithdcontroller(hDlg, current_cddlg.ci.controller_type, current_cddlg.ci.controller_type_unit, UAEDEV_CD); + inithdcontroller(hDlg, current_cddlg.ci.controller_type, current_cddlg.ci.controller_type_unit, UAEDEV_CD, current_cddlg.ci.rootdir[0] != 0); SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_cddlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_cddlg.ci.controller_unit : current_cddlg.ci.controller_type_unit, 0); InitializeListView (hDlg); recursive--; @@ -13056,7 +13167,7 @@ static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, current_cddlg.ci.controller_type_unit = posn / HD_CONTROLLER_NEXT_UNIT; if (current_cddlg.ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA) current_cddlg.ci.controller_type_unit = 1; - inithdcontroller(hDlg, current_cddlg.ci.controller_type, current_cddlg.ci.controller_type_unit, UAEDEV_CD); + inithdcontroller(hDlg, current_cddlg.ci.controller_type, current_cddlg.ci.controller_type_unit, UAEDEV_CD, current_cddlg.ci.rootdir[0] != 0); SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_cddlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_cddlg.ci.controller_unit : current_cddlg.ci.controller_type_unit, 0); } break; @@ -13124,7 +13235,9 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam setchecked(hDlg, IDC_HDF_PHYSGEOMETRY, current_hfdlg.ci.physical_geometry); setautocomplete (hDlg, IDC_PATH_NAME); setautocomplete (hDlg, IDC_PATH_FILESYS); - inithardfile (hDlg); + setautocomplete (hDlg, IDC_PATH_GEOMETRY); + addhistorymenu(hDlg, current_hfdlg.ci.geometry, IDC_PATH_GEOMETRY, HISTORY_GEO, false); + inithardfile (hDlg, current_hfdlg.ci.rootdir[0] != 0); addhistorymenu(hDlg, current_hfdlg.ci.rootdir, IDC_PATH_NAME, HISTORY_HDF, false); addhistorymenu(hDlg, current_hfdlg.ci.filesys, IDC_PATH_FILESYS, HISTORY_FS, false); updatehdfinfo (hDlg, true, false); @@ -13197,7 +13310,7 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam current_hfdlg.ci.controller_type_unit = posn / HD_CONTROLLER_NEXT_UNIT; if (current_hfdlg.ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA) current_hfdlg.ci.controller_type_unit = 1; - inithdcontroller(hDlg, current_hfdlg.ci.controller_type, current_hfdlg.ci.controller_type_unit, UAEDEV_HDF); + inithdcontroller(hDlg, current_hfdlg.ci.controller_type, current_hfdlg.ci.controller_type_unit, UAEDEV_HDF, current_hfdlg.ci.rootdir[0] != 0); sethardfile(hDlg); } break; @@ -13232,6 +13345,13 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam } break; } + case IDC_PATH_GEOMETRY: + getcomboboxtext(hDlg, IDC_PATH_GEOMETRY, current_hfdlg.ci.geometry, sizeof current_hfdlg.ci.geometry / sizeof(TCHAR)); + if (HIWORD (wParam) == CBN_KILLFOCUS) { + addhistorymenu(hDlg, current_hfdlg.ci.geometry, IDC_PATH_GEOMETRY, HISTORY_GEO, false); + sethardfile(hDlg); + } + break; } switch (LOWORD (wParam)) { @@ -13307,6 +13427,12 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam current_hfdlg.ci.bootpri = 0; sethardfile (hDlg); break; + case IDC_PATH_GEOMETRY_SELECTOR: + DiskSelection (hDlg, IDC_PATH_GEOMETRY, 23, &workprefs, 0); + getcomboboxtext(hDlg, IDC_PATH_GEOMETRY, current_hfdlg.ci.geometry, sizeof current_hfdlg.ci.geometry / sizeof(TCHAR)); + DISK_history_add(current_hfdlg.ci.geometry, -1, HISTORY_GEO, 1); + sethardfile(hDlg); + break; case IDC_SECTORS: p = ischecked(hDlg, IDC_HDF_PHYSGEOMETRY) ? ¤t_hfdlg.ci.psecs : ¤t_hfdlg.ci.sectors; v = *p; @@ -13367,7 +13493,8 @@ extern int harddrive_to_hdf (HWND, struct uae_prefs*, int); static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; - int i; + int v, i; + int *p; LRESULT posn; static int oposn; @@ -13378,14 +13505,15 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara oposn = -1; hdf_init_target (); recursive++; - sethardfiletypes(hDlg); - inithdcontroller(hDlg, current_hfdlg.ci.controller_type, current_hfdlg.ci.controller_type_unit, UAEDEV_HDF); + setautocomplete (hDlg, IDC_PATH_GEOMETRY); + addhistorymenu(hDlg, current_hfdlg.ci.geometry, IDC_PATH_GEOMETRY, HISTORY_GEO, false); + setchecked(hDlg, IDC_HDF_PHYSGEOMETRY, current_hfdlg.ci.physical_geometry); + setharddrive(hDlg); + inithdcontroller(hDlg, current_hfdlg.ci.controller_type, current_hfdlg.ci.controller_type_unit, UAEDEV_HDF, current_hfdlg.ci.rootdir[0] != 0); CheckDlgButton (hDlg, IDC_HDF_RW, !current_hfdlg.ci.readonly); CheckDlgButton (hDlg, IDC_HDF_LOCK, current_hfdlg.ci.lock); SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_RESETCONTENT, 0, 0); ew (hDlg, IDC_HARDDRIVE_IMAGE, FALSE); - ew (hDlg, IDOK, FALSE); - ew (hDlg, IDC_HDF_RW, FALSE); index = -1; for (i = 0; i < hdf_getnumharddrives (); i++) { SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_ADDSTRING, 0, (LPARAM)hdf_getnameharddrive (i, 1, NULL, NULL)); @@ -13409,6 +13537,19 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara if (recursive) break; recursive++; + if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_KILLFOCUS) { + switch (LOWORD(wParam)) { + case IDC_PATH_GEOMETRY: + getcomboboxtext(hDlg, IDC_PATH_GEOMETRY, current_hfdlg.ci.geometry, sizeof current_hfdlg.ci.geometry / sizeof(TCHAR)); + if (HIWORD (wParam) == CBN_KILLFOCUS) { + addhistorymenu(hDlg, current_hfdlg.ci.geometry, IDC_PATH_GEOMETRY, HISTORY_GEO, false); + setharddrive(hDlg); + updatehdfinfo (hDlg, true, false); + } + break; + } + } + if (HIWORD (wParam) == BN_CLICKED) { switch (LOWORD (wParam)) { case IDOK: @@ -13417,6 +13558,18 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara case IDCANCEL: EndDialog (hDlg, 0); break; + case IDC_HDF_PHYSGEOMETRY: + current_hfdlg.ci.physical_geometry = ischecked(hDlg, IDC_HDF_PHYSGEOMETRY); + updatehdfinfo(hDlg, true, false); + setharddrive(hDlg); + break; + case IDC_HARDDRIVE_ID: + if (oposn >= 0) { + void hd_get_meta(HWND hDlg, int idx, TCHAR*); + hd_get_meta(hDlg, oposn, current_hfdlg.ci.geometry); + setharddrive(hDlg); + } + break; case IDC_HARDDRIVE_IMAGE: posn = SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_GETCURSEL, 0, 0); if (posn != CB_ERR) @@ -13440,66 +13593,121 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara break; } } - if (LOWORD (wParam) == IDC_HARDDRIVE) { - posn = SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_GETCURSEL, 0, 0); - if (oposn != posn && posn != CB_ERR) { - oposn = posn; - if (posn >= 0) { - BOOL ena; - int dang = 1; - hdf_getnameharddrive (posn, 1, NULL, &dang); - _tcscpy (current_hfdlg.ci.rootdir, hdf_getnameharddrive (posn, 4, NULL, &dang)); - ena = dang >= 0; - ew (hDlg, IDC_HARDDRIVE_IMAGE, ena); - ew (hDlg, IDOK, ena); - ew (hDlg, IDC_HDF_RW, !dang); - if (dang) - current_hfdlg.ci.readonly = true; - current_hfdlg.ci.blocksize = 512; + switch(LOWORD(wParam)) + { + case IDC_HARDDRIVE: + posn = SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_GETCURSEL, 0, 0); + if (oposn != posn && posn != CB_ERR) { + oposn = posn; + if (posn >= 0) { + BOOL ena; + int dang = 1; + hdf_getnameharddrive (posn, 1, NULL, &dang); + _tcscpy (current_hfdlg.ci.rootdir, hdf_getnameharddrive (posn, 4, NULL, &dang)); + ena = dang >= 0; + ew (hDlg, IDC_HARDDRIVE_IMAGE, ena); + ew (hDlg, IDC_HARDDRIVE_ID, ena); + ew (hDlg, IDC_HDF_LOCK, ena); + ew (hDlg, IDOK, ena); + ew (hDlg, IDC_HDF_RW, !dang); + ew (hDlg, IDC_HDF_FEATURE_LEVEL, ena); + ew (hDlg, IDC_HDF_CONTROLLER, ena); + ew (hDlg, IDC_HDF_CONTROLLER_UNIT, ena); + ew (hDlg, IDC_HDF_CONTROLLER_TYPE, ena); + ew (hDlg, IDC_PATH_GEOMETRY, ena); + ew (hDlg, IDC_PATH_GEOMETRY_SELECTOR, ena); + ew (hDlg, IDC_HDF_PHYSGEOMETRY, ena && current_hfdlg.ci.geometry[0] == 0); + if (dang) + current_hfdlg.ci.readonly = true; + current_hfdlg.ci.blocksize = 512; + current_hfdlg.forcedcylinders = 0; + current_hfdlg.ci.cyls = current_hfdlg.ci.highcyl = current_hfdlg.ci.sectors = current_hfdlg.ci.surfaces = 0; + SetDlgItemText (hDlg, IDC_HDFINFO, _T("")); + SetDlgItemText (hDlg, IDC_HDFINFO2, _T("")); + updatehdfinfo (hDlg, true, current_hfdlg.ci.geometry[0] ? false : true); + gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, current_hfdlg.ci.controller_type + current_hfdlg.ci.controller_type_unit * MAX_DUPLICATE_EXPANSION_BOARDS); + SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_hfdlg.ci.controller_unit : current_hfdlg.ci.controller_type_unit, 0); + CheckDlgButton(hDlg, IDC_HDF_RW, !current_hfdlg.ci.readonly); + _tcscpy (current_hfdlg.ci.rootdir, hdf_getnameharddrive ((int)posn, 4, ¤t_hfdlg.ci.blocksize, NULL)); + setharddrive(hDlg); + } + } + break; + case IDC_HDF_CONTROLLER: + posn = gui_get_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER); + if (posn != CB_ERR && current_hfdlg.ci.controller_type != posn) { + current_hfdlg.ci.controller_type = posn % HD_CONTROLLER_NEXT_UNIT; + current_hfdlg.ci.controller_type_unit = posn / HD_CONTROLLER_NEXT_UNIT; current_hfdlg.forcedcylinders = 0; current_hfdlg.ci.cyls = current_hfdlg.ci.highcyl = current_hfdlg.ci.sectors = current_hfdlg.ci.surfaces = 0; SetDlgItemText (hDlg, IDC_HDFINFO, _T("")); SetDlgItemText (hDlg, IDC_HDFINFO2, _T("")); updatehdfinfo (hDlg, true, true); - gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, current_hfdlg.ci.controller_type + current_hfdlg.ci.controller_type_unit * MAX_DUPLICATE_EXPANSION_BOARDS); + inithdcontroller(hDlg, current_hfdlg.ci.controller_type, current_hfdlg.ci.controller_type_unit, UAEDEV_HDF, current_hfdlg.ci.rootdir[0] != 0); SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_hfdlg.ci.controller_unit : current_hfdlg.ci.controller_type_unit, 0); - CheckDlgButton(hDlg, IDC_HDF_RW, !current_hfdlg.ci.readonly); - _tcscpy (current_hfdlg.ci.rootdir, hdf_getnameharddrive ((int)posn, 4, ¤t_hfdlg.ci.blocksize, NULL)); sethardfiletypes(hDlg); } - } - } else if (LOWORD (wParam) == IDC_HDF_CONTROLLER) { - posn = gui_get_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER); - if (posn != CB_ERR && current_hfdlg.ci.controller_type != posn) { - current_hfdlg.ci.controller_type = posn % HD_CONTROLLER_NEXT_UNIT; - current_hfdlg.ci.controller_type_unit = posn / HD_CONTROLLER_NEXT_UNIT; - current_hfdlg.forcedcylinders = 0; - current_hfdlg.ci.cyls = current_hfdlg.ci.highcyl = current_hfdlg.ci.sectors = current_hfdlg.ci.surfaces = 0; - SetDlgItemText (hDlg, IDC_HDFINFO, _T("")); - SetDlgItemText (hDlg, IDC_HDFINFO2, _T("")); - updatehdfinfo (hDlg, true, true); - inithdcontroller(hDlg, current_hfdlg.ci.controller_type, current_hfdlg.ci.controller_type_unit, UAEDEV_HDF); - SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_hfdlg.ci.controller_unit : current_hfdlg.ci.controller_type_unit, 0); - sethardfiletypes(hDlg); - } - } else if (LOWORD(wParam) == IDC_HDF_CONTROLLER_UNIT) { - posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_GETCURSEL, 0, 0); - if (posn != CB_ERR) { - if (current_hfdlg.ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA) - current_hfdlg.ci.controller_type_unit = posn; - else - current_hfdlg.ci.controller_unit = posn; - } - } else if (LOWORD(wParam) == IDC_HDF_CONTROLLER_TYPE) { - posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_TYPE, CB_GETCURSEL, 0, 0); - if (posn != CB_ERR) { - current_hfdlg.ci.controller_media_type = posn; - } - } else if (LOWORD(wParam) == IDC_HDF_FEATURE_LEVEL) { - posn = SendDlgItemMessage(hDlg, IDC_HDF_FEATURE_LEVEL, CB_GETCURSEL, 0, 0); - if (posn != CB_ERR) { - current_hfdlg.ci.unit_feature_level = posn; - } + break; + case IDC_HDF_CONTROLLER_UNIT: + posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_GETCURSEL, 0, 0); + if (posn != CB_ERR) { + if (current_hfdlg.ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA) + current_hfdlg.ci.controller_type_unit = posn; + else + current_hfdlg.ci.controller_unit = posn; + } + break; + case IDC_HDF_CONTROLLER_TYPE: + posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_TYPE, CB_GETCURSEL, 0, 0); + if (posn != CB_ERR) { + current_hfdlg.ci.controller_media_type = posn; + } + break; + case IDC_HDF_FEATURE_LEVEL: + posn = SendDlgItemMessage(hDlg, IDC_HDF_FEATURE_LEVEL, CB_GETCURSEL, 0, 0); + if (posn != CB_ERR) { + current_hfdlg.ci.unit_feature_level = posn; + } + break; + case IDC_PATH_GEOMETRY_SELECTOR: + DiskSelection (hDlg, IDC_PATH_GEOMETRY, 23, &workprefs, 0); + getcomboboxtext(hDlg, IDC_PATH_GEOMETRY, current_hfdlg.ci.geometry, sizeof current_hfdlg.ci.geometry / sizeof(TCHAR)); + DISK_history_add(current_hfdlg.ci.geometry, -1, HISTORY_GEO, 1); + setharddrive(hDlg); + updatehdfinfo (hDlg, true, false); + break; + case IDC_SECTORS: + p = ¤t_hfdlg.ci.psecs; + v = *p; + *p = GetDlgItemInt (hDlg, IDC_SECTORS, NULL, FALSE); + if (v != *p) { + set_phys_cyls(hDlg); + updatehdfinfo (hDlg, true, false); + ew (hDlg, IDC_HDF_RDB, !is_hdf_rdb ()); + } + break; + case IDC_RESERVED: + p = ¤t_hfdlg.ci.pcyls; + v = *p; + *p = GetDlgItemInt (hDlg, IDC_RESERVED, NULL, FALSE); + if (v != *p) { + if (ischecked(hDlg, IDC_HDF_PHYSGEOMETRY)) { + current_hfdlg.ci.physical_geometry = true; + } + updatehdfinfo (hDlg, true, false); + ew (hDlg, IDC_HDF_RDB, !is_hdf_rdb ()); + } + break; + case IDC_HEADS: + p = ¤t_hfdlg.ci.pheads; + v = *p; + *p = GetDlgItemInt (hDlg, IDC_HEADS, NULL, FALSE); + if (v != *p) { + set_phys_cyls(hDlg); + updatehdfinfo (hDlg, true, false); + ew (hDlg, IDC_HDF_RDB, !is_hdf_rdb ()); + } + break; } recursive--; break; @@ -20396,7 +20604,7 @@ int gui_init (void) } if (ret > 0) { #ifdef AVIOUTPUT - AVIOutput_Begin (); + AVIOutput_Begin (true); #endif } return ret; -- 2.47.3