Support for HDF with illegal CHS.

This commit is contained in:
sorgelig
2018-05-23 05:37:46 +08:00
parent 368089a803
commit 64fce22926
3 changed files with 122 additions and 26 deletions

View File

@@ -84,6 +84,8 @@ enum MENU
MENU_HARDFILE_SELECT1,
MENU_HARDFILE_SELECT2,
MENU_HARDFILE_SELECTED,
MENU_HARDFILE_SELECTED2,
MENU_HARDFILE_SELECTED3,
MENU_LOADCONFIG_1,
MENU_LOADCONFIG_2,
MENU_SAVECONFIG_1,
@@ -641,7 +643,8 @@ void HandleUI(void)
// No UI in unknown cores.
return;
}
struct RigidDiskBlock *rdb;
char *p;
char s[40];
@@ -2049,7 +2052,7 @@ void HandleUI(void)
OsdWrite(5, s, menusub == 4, 0);
OsdWrite(6, "", 0, 0);
OsdWrite(7, " Hard disk", menusub == 5, 0);
OsdWrite(7, " Hard disks", menusub == 5, 0);
OsdWrite(8, " Chipset", menusub == 6, 0);
OsdWrite(9, " Memory", menusub == 7, 0);
OsdWrite(10, " Audio & Video", menusub == 8, 0);
@@ -2764,6 +2767,56 @@ void HandleUI(void)
if (len > sizeof(config.hardfile[num].filename) - 1) len = sizeof(config.hardfile[num].filename) - 1;
if(len) memcpy(config.hardfile[num].filename, SelectedPath, len);
config.hardfile[num].filename[len] = 0;
menustate = checkHDF(config.hardfile[num].filename, &rdb) ? MENU_SETTINGS_HARDFILE1 : MENU_HARDFILE_SELECTED2;
}
break;
case MENU_HARDFILE_SELECTED2:
m = 0;
menumask = 0x1;
if (!rdb)
{
OsdWrite(m++, "", 0, 0);
OsdWrite(m++, "", 0, 0);
OsdWrite(m++, "", 0, 0);
OsdWrite(m++, "", 0, 0);
OsdWrite(m++, "", 0, 0);
OsdWrite(m++, " Cannot open the file", 0, 0);
}
else
{
OsdWrite(m++, "", 0, 0);
OsdWrite(m++, " !! DANGEROUS !!", 0, 0);
OsdWrite(m++, "", 0, 0);
OsdWrite(m++, " RDB has illegal CHS values:", 0, 0);
sprintf(s, " Cylinders: %d", rdb->rdb_Cylinders);
OsdWrite(m++, s, 0, 0);
sprintf(s, " Heads: %d", rdb->rdb_Heads);
OsdWrite(m++, s, 0, 0);
sprintf(s, " Sectors: %d", rdb->rdb_Sectors);
OsdWrite(m++, s, 0, 0);
OsdWrite(m++, "", 0, 0);
OsdWrite(m++, " Max legal values:", 0, 0);
OsdWrite(m++, " C:65536, H:16, S:255", 0, 0);
OsdWrite(m++, "", 0, 0);
OsdWrite(m++, " Some functions won't work", 0, 0);
OsdWrite(m++, " correctly and may corrupt", 0, 0);
OsdWrite(m++, " the data!", 0, 0);
}
OsdWrite(m++, "", 0, 0);
OsdWrite(m++, " OK", 1, 0);
while (m < OsdGetSize()) OsdWrite(m++, "", 0, 0);
menusub_last = menusub;
menusub = 0;
menustate = MENU_HARDFILE_SELECTED3;
break;
case MENU_HARDFILE_SELECTED3:
if (select || menu)
{
menusub = menusub_last;
parentstate = menustate;
menustate = MENU_SETTINGS_HARDFILE1;
}
break;

View File

@@ -24,7 +24,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "hardware.h"
#include "file_io.h"
#include "minimig_hdd.h"
#include "minimig_hdd_internal.h"
#include "menu.h"
#include "minimig_config.h"
#include "debug.h"
@@ -63,7 +62,7 @@ typedef struct
{
int enabled;
fileTYPE file;
unsigned short cylinders;
unsigned long cylinders;
unsigned short heads;
unsigned short sectors;
unsigned short sectors_per_block;
@@ -493,32 +492,46 @@ static void GetRDBGeometry(hdfTYPE *pHDF)
pHDF->heads = SWAP(rdb->rdb_Heads);
pHDF->sectors = SWAP(rdb->rdb_Sectors);
pHDF->cylinders = SWAP(rdb->rdb_Cylinders);
if (pHDF->sectors > 255)
if (pHDF->sectors > 255 || pHDF->heads > 16)
{
printf("ATTN: Too many sectors per track %d.", pHDF->sectors);
if (pHDF->sectors & 1)
printf("ATTN: Illegal CHS value(s).");
if (!(pHDF->sectors & 1) && (pHDF->sectors < 512) && (pHDF->heads <= 8))
{
printf(" Odd number of sectors, Cannot translate. Give up! 8-E\n");
printf(" Translate: sectors %d->%d, heads %d->%d.\n", pHDF->sectors, pHDF->sectors / 2, pHDF->heads, pHDF->heads * 2);
pHDF->sectors /= 2;
pHDF->heads *= 2;
return;
}
if (pHDF->sectors > 511)
{
printf(" Really, too many! Give up! 8-E\n");
return;
}
printf(" DANGEROUS: Cannot translate to legal CHS values. Re-calculate the CHS.\n");
if (pHDF->heads > 8)
{
printf(" Too many heads (%d). Cannot translate. Give up! 8-E\n", pHDF->heads);
return;
}
printf(" Translate: sectors %d->%d, heads %d->%d.\n", pHDF->sectors, pHDF->sectors / 2, pHDF->heads, pHDF->heads * 2);
pHDF->sectors /= 2;
pHDF->heads *= 2;
}
uint32_t head, cyl, spt;
uint32_t sptt[] = { 63, 127, 255, 0 };
uint32_t total = pHDF->file.size / 512;
for (int i = 0; sptt[i] != 0; i++)
{
spt = sptt[i];
for (head = 4; head <= 16; head++)
{
cyl = total / (head * spt);
if (total <= 1024 * 1024)
{
if (cyl <= 1023) break;
}
else
{
if (cyl < 16383) break;
if (cyl < 32767 && head >= 5) break;
if (cyl <= 65536) break;
}
}
if (head <= 16) break;
}
pHDF->cylinders = cyl;
pHDF->heads = (unsigned short)head;
pHDF->sectors = (unsigned short)spt;
}
}
static void write_sector(int unit, uint32_t lba)
@@ -752,12 +765,12 @@ static void SetHardfileGeometry(hdfTYPE *pHDF, int isHDF)
{
if (cyl < 16383) break;
if (cyl < 32767 && head >= 5) break;
if (cyl <= 65535) break; // Should there some head constraint here?
if (cyl <= 65536) break; // Should there some head constraint here?
}
}
if (head <= 16) break;
}
pHDF->cylinders = (unsigned short)cyl;
pHDF->cylinders = cyl;
pHDF->heads = (unsigned short)head;
pHDF->sectors = (unsigned short)spt;
@@ -806,3 +819,30 @@ unsigned char OpenHardfile(unsigned char unit)
FileClose(&hdf[unit].file);
return 0;
}
int checkHDF(const char* name, struct RigidDiskBlock **rdb)
{
fileTYPE file = { 0 };
*rdb = NULL;
if (FileOpenEx(&file, name, O_RDONLY))
{
*rdb = (struct RigidDiskBlock *)sector_buffer;
for (int i = 0; i<16; ++i)
{
if (!FileReadSec(&file, sector_buffer)) break;
if ((*rdb)->rdb_ID == 0x4B534452)
{
FileClose(&file);
(*rdb)->rdb_Heads = SWAP((*rdb)->rdb_Heads);
(*rdb)->rdb_Sectors = SWAP((*rdb)->rdb_Sectors);
(*rdb)->rdb_Cylinders = SWAP((*rdb)->rdb_Cylinders);
return ((*rdb)->rdb_Heads <= 16 && (*rdb)->rdb_Sectors <= 255 && (*rdb)->rdb_Cylinders <= 65536);
}
}
FileClose(&file);
return 1; // non-HDF file
}
return 0;
}

View File

@@ -3,8 +3,11 @@
#ifndef __MINIMIG_HDD_H__
#define __MINIMIG_HDD_H__
#include "minimig_hdd_internal.h"
// functions
void HandleHDD(unsigned char c1, unsigned char c2);
unsigned char OpenHardfile(unsigned char unit);
int checkHDF(const char* name, struct RigidDiskBlock **rdb);
#endif // __HDD_H__