Support for HDF with illegal CHS.
This commit is contained in:
57
menu.cpp
57
menu.cpp
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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__
|
||||
|
||||
Reference in New Issue
Block a user