ide: some reorganization, split from Minimig, support for Archie.
This commit is contained in:
@@ -157,7 +157,6 @@
|
||||
<ClInclude Include="support\minimig\minimig_config.h" />
|
||||
<ClInclude Include="support\minimig\minimig_fdd.h" />
|
||||
<ClInclude Include="support\minimig\minimig_hdd.h" />
|
||||
<ClInclude Include="support\minimig\minimig_hdd_internal.h" />
|
||||
<ClInclude Include="support\minimig\minimig_share.h" />
|
||||
<ClInclude Include="support\neogeo\neogeo_loader.h" />
|
||||
<ClInclude Include="support\pcecd\pcecd.h" />
|
||||
|
||||
@@ -348,9 +348,6 @@
|
||||
<ClInclude Include="support\minimig\minimig_hdd.h">
|
||||
<Filter>Header Files\support</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="support\minimig\minimig_hdd_internal.h">
|
||||
<Filter>Header Files\support</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="support\x86\x86.h">
|
||||
<Filter>Header Files\support</Filter>
|
||||
</ClInclude>
|
||||
|
||||
161
ide.cpp
161
ide.cpp
@@ -13,7 +13,8 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "support/x86/x86.h"
|
||||
#include "support/minimig/minimig_hdd_internal.h"
|
||||
#include "support/minimig/minimig_hdd.h"
|
||||
#include "support/minimig/minimig_config.h"
|
||||
#include "spi.h"
|
||||
#include "user_io.h"
|
||||
#include "file_io.h"
|
||||
@@ -42,6 +43,8 @@
|
||||
#define ide_send_data(databuf, size) ide_sendbuf(ide, 255, (size), (uint16_t*)(databuf))
|
||||
#define ide_recv_data(databuf, size) ide_recvbuf(ide, 255, (size), (uint16_t*)(databuf))
|
||||
|
||||
#define SWAP(a) ((((a)&0x000000ff)<<24)|(((a)&0x0000ff00)<<8)|(((a)&0x00ff0000)>>8)|(((a)&0xff000000)>>24))
|
||||
|
||||
void ide_reg_set(ide_config *ide, uint16_t reg, uint16_t value)
|
||||
{
|
||||
EnableIO();
|
||||
@@ -179,9 +182,113 @@ void ide_set_regs(ide_config *ide)
|
||||
ide_sendbuf(ide, 0, 6, (uint16_t*)data);
|
||||
}
|
||||
|
||||
static void calc_geometry(chs_t *chs, uint64_t size)
|
||||
{
|
||||
uint32_t head = 0, cyl = 0, spt = 0;
|
||||
uint32_t sptt[] = { 63, 127, 255, 0 };
|
||||
uint32_t total = 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;
|
||||
}
|
||||
|
||||
chs->cylinders = cyl;
|
||||
chs->heads = (uint16_t)head;
|
||||
chs->sectors = (uint16_t)spt;
|
||||
}
|
||||
|
||||
static void get_rdb_geometry(RigidDiskBlock *rdb, chs_t *chs, uint64_t size)
|
||||
{
|
||||
chs->heads = SWAP(rdb->rdb_Heads);
|
||||
chs->sectors = SWAP(rdb->rdb_Sectors);
|
||||
chs->cylinders = SWAP(rdb->rdb_Cylinders);
|
||||
if (chs->sectors > 255 || chs->heads > 16)
|
||||
{
|
||||
printf("ATTN: Illegal CHS value(s).");
|
||||
if (!(chs->sectors & 1) && (chs->sectors < 512) && (chs->heads <= 8))
|
||||
{
|
||||
printf(" Translate: sectors %d->%d, heads %d->%d.\n", chs->sectors, chs->sectors / 2, chs->heads, chs->heads * 2);
|
||||
chs->sectors /= 2;
|
||||
chs->heads *= 2;
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" DANGEROUS: Cannot translate to legal CHS values. Re-calculate the CHS.\n");
|
||||
calc_geometry(chs, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void guess_geometry(fileTYPE *f, chs_t *chs, int allow_vrdb)
|
||||
{
|
||||
uint8_t flg = 0;
|
||||
chs->offset = 0;
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
struct RigidDiskBlock *rdb = (struct RigidDiskBlock *)ide_buf;
|
||||
if (!FileReadSec(f, ide_buf)) break;
|
||||
for (int i = 0; i < 512; i++) flg |= ide_buf[i];
|
||||
|
||||
if (rdb->rdb_ID == RDB_MAGIC)
|
||||
{
|
||||
printf("Found RDB header -> native Amiga image.\n");
|
||||
get_rdb_geometry(rdb, chs, f->size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (allow_vrdb && flg)
|
||||
{
|
||||
chs->heads = 16;
|
||||
chs->sectors = 128;
|
||||
|
||||
for (int i = 32; i <= 2048; i <<= 1)
|
||||
{
|
||||
int cylinders = f->size / (512 * i) + 1;
|
||||
if (cylinders < 65536)
|
||||
{
|
||||
chs->sectors = (i < 128) ? i : 128;
|
||||
chs->heads = i / chs->sectors;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int spc = chs->heads * chs->sectors;
|
||||
chs->cylinders = f->size / (512 * spc) + 1;
|
||||
if (chs->cylinders > 65535) chs->cylinders = 65535;
|
||||
chs->offset = -spc;
|
||||
printf("No RDB header found in HDF image. Assume it's image of single partition. Use Virtual RDB header.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
calc_geometry(chs, f->size);
|
||||
if(allow_vrdb) printf("No RDB header found. Possible non-Amiga or empty image.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void ide_set_geometry(drive_t *drive, uint16_t sectors, uint16_t heads)
|
||||
{
|
||||
printf("SPT=%d, Heads=%d\n", sectors, heads);
|
||||
int info = 0;
|
||||
if (drive->heads != heads || drive->spt != sectors)
|
||||
{
|
||||
info = 1;
|
||||
printf("SPT=%d, Heads=%d\n", sectors, heads);
|
||||
}
|
||||
|
||||
drive->heads = heads ? heads : 16;
|
||||
drive->spt = sectors ? sectors : 256;
|
||||
@@ -196,11 +303,9 @@ static void ide_set_geometry(drive_t *drive, uint16_t sectors, uint16_t heads)
|
||||
|
||||
//Maximum 137GB images are supported.
|
||||
drive->cylinders = cylinders;
|
||||
printf("New SPT=%d, Heads=%d, Cylinders=%d\n", drive->spt, drive->heads, drive->cylinders);
|
||||
if(info) printf("New SPT=%d, Heads=%d, Cylinders=%d\n", drive->spt, drive->heads, drive->cylinders);
|
||||
}
|
||||
|
||||
#define SWAP(a) ((((a)&0x000000ff)<<24)|(((a)&0x0000ff00)<<8)|(((a)&0x00ff0000)>>8)|(((a)&0xff000000)>>24))
|
||||
|
||||
static uint32_t checksum_rdb(uint32_t *p, int set)
|
||||
{
|
||||
uint32_t count = SWAP(p[1]);
|
||||
@@ -958,3 +1063,49 @@ void ide_reset(uint8_t hotswap[4])
|
||||
ide_inst[1].drive[0].allow_placeholder = hotswap[2];
|
||||
ide_inst[1].drive[1].allow_placeholder = hotswap[3];
|
||||
}
|
||||
|
||||
int ide_open(uint8_t unit, const char* filename)
|
||||
{
|
||||
static fileTYPE hdd_file[4] = {};
|
||||
chs_t chs = {};
|
||||
|
||||
if (!is_minimig() || ((minimig_config.ide_cfg & 1) && minimig_config.hardfile[unit].cfg))
|
||||
{
|
||||
printf("\nChecking HDD %d\n", unit);
|
||||
if (filename[0] && FileOpenEx(&hdd_file[unit], filename, FileCanWrite(filename) ? O_RDWR : O_RDONLY))
|
||||
{
|
||||
printf("file: \"%s\": ", hdd_file[unit].name);
|
||||
guess_geometry(&hdd_file[unit], &chs, is_minimig() && !strcasecmp(".hdf", filename + strlen(filename) - 4));
|
||||
printf("size: %llu (%llu MB)\n", hdd_file[unit].size, hdd_file[unit].size >> 20);
|
||||
printf("CHS: %u/%u/%u", chs.cylinders, chs.heads, chs.sectors);
|
||||
printf(" (%llu MB), ", ((((uint64_t)chs.cylinders) * chs.heads * chs.sectors) >> 11));
|
||||
printf("Offset: %d\n", chs.offset);
|
||||
|
||||
int present = 0;
|
||||
int cd = 0;
|
||||
|
||||
int len = strlen(filename);
|
||||
const char *ext = filename + len - 4;
|
||||
int vhd = (len > 4 && (!strcasecmp(ext, ".hdf") || (!strcasecmp(ext, ".vhd"))));
|
||||
|
||||
if (!vhd)
|
||||
{
|
||||
const char *img_name = cdrom_parse(unit, filename);
|
||||
if (img_name) present = ide_img_mount(&hdd_file[unit], img_name, 0);
|
||||
if (present) cd = 1;
|
||||
else vhd = 1;
|
||||
}
|
||||
|
||||
if (!present && vhd) present = ide_img_mount(&hdd_file[unit], filename, 1);
|
||||
ide_img_set(unit, present ? &hdd_file[unit] : 0, cd, chs.sectors, chs.heads, cd ? 0 : -chs.offset);
|
||||
if (present) return 1;
|
||||
}
|
||||
|
||||
printf("HDD %d: not present\n", unit);
|
||||
}
|
||||
|
||||
// close if opened earlier.
|
||||
ide_img_set(unit, 0, 0);
|
||||
FileClose(&hdd_file[unit]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
25
ide.h
25
ide.h
@@ -32,7 +32,7 @@
|
||||
#define IDE_STATE_WAIT_PKT_END 5
|
||||
#define IDE_STATE_WAIT_PKT_MODE 6
|
||||
|
||||
typedef struct
|
||||
struct regs_t
|
||||
{
|
||||
uint8_t io_done;
|
||||
uint8_t io_fast;
|
||||
@@ -53,9 +53,9 @@ typedef struct
|
||||
uint8_t io_size;
|
||||
uint8_t error;
|
||||
uint8_t status;
|
||||
} regs_t;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct track_t
|
||||
{
|
||||
char filename[1024];
|
||||
uint32_t start;
|
||||
@@ -66,9 +66,9 @@ typedef struct
|
||||
uint8_t mode2;
|
||||
uint8_t number;
|
||||
int chd_offset;
|
||||
} track_t;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct drive_t
|
||||
{
|
||||
fileTYPE *f;
|
||||
|
||||
@@ -105,9 +105,9 @@ typedef struct
|
||||
uint32_t chd_last_partial_lba;
|
||||
|
||||
uint16_t id[256];
|
||||
} drive_t;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct ide_config
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t bitoff;
|
||||
@@ -117,7 +117,15 @@ typedef struct
|
||||
regs_t regs;
|
||||
|
||||
drive_t drive[2];
|
||||
} ide_config;
|
||||
};
|
||||
|
||||
struct chs_t
|
||||
{
|
||||
uint32_t sectors;
|
||||
uint32_t heads;
|
||||
uint32_t cylinders;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
#include "ide_cdrom.h"
|
||||
|
||||
@@ -138,6 +146,7 @@ int ide_img_mount(fileTYPE *f, const char *name, int rw);
|
||||
void ide_img_set(uint32_t drvnum, fileTYPE *f, int cd, int sectors = 0, int heads = 0, int offset = 0, int type = 0);
|
||||
int ide_is_placeholder(int num);
|
||||
void ide_reset(uint8_t hotswap[4]);
|
||||
int ide_open(uint8_t unit, const char* filename);
|
||||
|
||||
void ide_io(int num, int req);
|
||||
|
||||
|
||||
60
menu.cpp
60
menu.cpp
@@ -152,8 +152,6 @@ enum MENU
|
||||
MENU_MINIMIG_DISK1,
|
||||
MENU_MINIMIG_DISK2,
|
||||
MENU_MINIMIG_HDFFILE_SELECTED,
|
||||
MENU_MINIMIG_HDFFILE_SELECTED2,
|
||||
MENU_MINIMIG_HDFFILE_SELECTED3,
|
||||
MENU_MINIMIG_ADFFILE_SELECTED,
|
||||
MENU_MINIMIG_ROMFILE_SELECTED,
|
||||
MENU_MINIMIG_LOADCONFIG1,
|
||||
@@ -1001,8 +999,6 @@ void HandleUI(void)
|
||||
return;
|
||||
}
|
||||
|
||||
static struct RigidDiskBlock *rdb = nullptr;
|
||||
|
||||
static char opensave;
|
||||
static char ioctl_index;
|
||||
char *p;
|
||||
@@ -5504,62 +5500,10 @@ void HandleUI(void)
|
||||
|
||||
if (ide_is_placeholder(num))
|
||||
{
|
||||
OpenHardfile(num);
|
||||
menustate = MENU_MINIMIG_DISK1;
|
||||
if (ide_check() & 0x8000) ide_open(num, minimig_config.hardfile[num].filename);
|
||||
else OpenHardfile(num, minimig_config.hardfile[num].filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
menustate = checkHDF(minimig_config.hardfile[num].filename, &rdb) ? MENU_MINIMIG_DISK1 : MENU_MINIMIG_HDFFILE_SELECTED2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_MINIMIG_HDFFILE_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: %lu", rdb->rdb_Cylinders);
|
||||
OsdWrite(m++, s, 0, 0);
|
||||
sprintf(s, " Heads: %lu", rdb->rdb_Heads);
|
||||
OsdWrite(m++, s, 0, 0);
|
||||
sprintf(s, " Sectors: %lu", 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++, " Something may not correctly", 0, 0);
|
||||
OsdWrite(m++, " and may corrupt the data!", 0, 0);
|
||||
OsdWrite(m++);
|
||||
}
|
||||
OsdWrite(m++, "", 0, 0);
|
||||
OsdWrite(m++, " OK", 1, 0);
|
||||
while (m < OsdGetSize()) OsdWrite(m++, "", 0, 0);
|
||||
|
||||
menusub_last = menusub;
|
||||
menusub = 0;
|
||||
menustate = MENU_MINIMIG_HDFFILE_SELECTED3;
|
||||
break;
|
||||
|
||||
case MENU_MINIMIG_HDFFILE_SELECTED3:
|
||||
if (select || menu)
|
||||
{
|
||||
menusub = menusub_last;
|
||||
parentstate = menustate;
|
||||
menustate = MENU_MINIMIG_DISK1;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "../../user_io.h"
|
||||
#include "../../input.h"
|
||||
#include "../../support.h"
|
||||
#include "../../ide.h"
|
||||
#include "archie.h"
|
||||
|
||||
#define CONFIG_FILENAME "ARCHIE.CFG"
|
||||
@@ -286,6 +287,11 @@ static void check_cmos(uint8_t cnt)
|
||||
}
|
||||
}
|
||||
|
||||
inline int hdd_open(int unit, char *filename)
|
||||
{
|
||||
return (ide_check() & 0x8000) ? ide_open(unit, filename) : OpenHardfile(unit, filename);
|
||||
}
|
||||
|
||||
void archie_init()
|
||||
{
|
||||
archie_debugf("init");
|
||||
@@ -314,12 +320,12 @@ void archie_init()
|
||||
archie_set_60(archie_get_60());
|
||||
archie_set_afix(archie_get_afix());
|
||||
|
||||
if(!config.hdd_img[0][0] || !OpenHardfile(0, config.hdd_img[0]))
|
||||
if (!config.hdd_img[0][0] || !hdd_open(0, config.hdd_img[0]))
|
||||
{
|
||||
memset(config.hdd_img[0], 0, sizeof(config.hdd_img[0]));
|
||||
}
|
||||
|
||||
if (!config.hdd_img[1][0] || !OpenHardfile(1, config.hdd_img[1]))
|
||||
if (!config.hdd_img[1][0] || !hdd_open(1, config.hdd_img[1]))
|
||||
{
|
||||
memset(config.hdd_img[1], 0, sizeof(config.hdd_img[1]));
|
||||
}
|
||||
@@ -466,7 +472,11 @@ void archie_poll(void)
|
||||
EnableFpga();
|
||||
uint16_t status = spi_w(0);
|
||||
DisableFpga();
|
||||
HandleHDD(status >> 8, 0);
|
||||
|
||||
uint16_t sd_req = ide_check();
|
||||
if (sd_req & 0x8000) ide_io(0, sd_req & 7);
|
||||
else HandleHDD(status >> 8, 0);
|
||||
|
||||
check_cmos(status);
|
||||
check_reset();
|
||||
|
||||
@@ -623,8 +633,5 @@ const char *archie_get_hdd_name(int i)
|
||||
void archie_hdd_mount(char *filename, int idx)
|
||||
{
|
||||
memset(config.hdd_img[idx], 0, sizeof(config.hdd_img[idx]));
|
||||
if (OpenHardfile(idx, filename))
|
||||
{
|
||||
strcpy(config.hdd_img[idx], filename);
|
||||
}
|
||||
if (hdd_open(idx, filename)) strcpy(config.hdd_img[idx], filename);
|
||||
}
|
||||
|
||||
@@ -297,6 +297,13 @@ const char* minimig_get_cfg_info(int num, int label)
|
||||
return "";
|
||||
}
|
||||
|
||||
inline int hdd_open(int unit)
|
||||
{
|
||||
return (ide_check() & 0x8000) ?
|
||||
ide_open(unit, minimig_config.hardfile[unit].filename) :
|
||||
OpenHardfile(unit, minimig_config.hardfile[unit].filename);
|
||||
}
|
||||
|
||||
static int force_reload_kickstart = 0;
|
||||
static void ApplyConfiguration(char reloadkickstart)
|
||||
{
|
||||
@@ -342,7 +349,11 @@ static void ApplyConfiguration(char reloadkickstart)
|
||||
|
||||
rstval = SPI_CPU_HLT;
|
||||
spi_uio_cmd8(UIO_MM2_RST, rstval);
|
||||
spi_uio_cmd8(UIO_MM2_HDD, (minimig_config.ide_cfg & 0x21) | (OpenHardfile(0) ? 2 : 0) | (OpenHardfile(1) ? 4 : 0) | (OpenHardfile(2) ? 8 : 0) | (OpenHardfile(3) ? 16 : 0));
|
||||
spi_uio_cmd8(UIO_MM2_HDD, (minimig_config.ide_cfg & 0x21) |
|
||||
(hdd_open(0) ? 2 : 0) |
|
||||
(hdd_open(1) ? 4 : 0) |
|
||||
(hdd_open(2) ? 8 : 0) |
|
||||
(hdd_open(3) ? 16 : 0));
|
||||
|
||||
minimig_ConfigMemory(memcfg);
|
||||
minimig_ConfigCPU(minimig_config.cpu);
|
||||
|
||||
@@ -738,74 +738,25 @@ uint8_t OpenHardfile(uint8_t unit, const char* filename)
|
||||
hdf->unit = unit;
|
||||
hdf->enabled = 0;
|
||||
|
||||
if (is_minimig())
|
||||
if (!is_minimig() || ((minimig_config.ide_cfg & 1) && minimig_config.hardfile[unit].cfg))
|
||||
{
|
||||
if ((minimig_config.ide_cfg & 1) && minimig_config.hardfile[unit].cfg)
|
||||
printf("\nChecking HDD %d\n", hdf->unit);
|
||||
if (filename[0] && FileOpenEx(&hdf->file, filename, FileCanWrite(filename) ? O_RDWR : O_RDONLY))
|
||||
{
|
||||
printf("\nChecking HDD %d\n", unit);
|
||||
if (minimig_config.hardfile[unit].filename[0])
|
||||
{
|
||||
if (FileOpenEx(&hdf->file, minimig_config.hardfile[unit].filename, FileCanWrite(minimig_config.hardfile[unit].filename) ? O_RDWR : O_RDONLY))
|
||||
{
|
||||
hdf->enabled = 1;
|
||||
printf("file: \"%s\": ", hdf->file.name);
|
||||
SetHardfileGeometry(hdf, !strcasecmp(".hdf", minimig_config.hardfile[unit].filename + strlen(minimig_config.hardfile[unit].filename) - 4));
|
||||
printf("size: %llu (%llu MB)\n", hdf->file.size, hdf->file.size >> 20);
|
||||
printf("CHS: %u/%u/%u", hdf->cylinders, hdf->heads, hdf->sectors);
|
||||
printf(" (%llu MB), ", ((((uint64_t)hdf->cylinders) * hdf->heads * hdf->sectors) >> 11));
|
||||
printf("Offset: %d\n", hdf->offset);
|
||||
|
||||
if (ide_check() & 0x8000)
|
||||
{
|
||||
int present = 0;
|
||||
int cd = 0;
|
||||
|
||||
int len = strlen(minimig_config.hardfile[unit].filename);
|
||||
char *ext = minimig_config.hardfile[unit].filename + len - 4;
|
||||
int vhd = (len > 4 && (!strcasecmp(ext, ".hdf") || (!strcasecmp(ext, ".vhd"))));
|
||||
|
||||
if (!vhd)
|
||||
{
|
||||
const char *img_name = cdrom_parse(unit, minimig_config.hardfile[unit].filename);
|
||||
if (img_name) present = ide_img_mount(&hdf->file, img_name, 0);
|
||||
if (present) cd = 1;
|
||||
else vhd = 1;
|
||||
}
|
||||
|
||||
if (!present && vhd) present = ide_img_mount(&hdf->file, minimig_config.hardfile[unit].filename, 1);
|
||||
ide_img_set(unit, present ? &hdf->file : 0, cd, hdf->sectors, hdf->heads, cd ? 0 : -hdf->offset);
|
||||
if (present) return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("HDD %d: not present\n", unit);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\nChecking HDD %d\n", unit);
|
||||
if (filename[0])
|
||||
{
|
||||
if (FileOpenEx(&hdf->file, filename, FileCanWrite(filename) ? O_RDWR : O_RDONLY))
|
||||
{
|
||||
hdf->enabled = 1;
|
||||
printf("file: \"%s\": ", hdf->file.name);
|
||||
SetHardfileGeometry(hdf, 0);
|
||||
printf("size: %llu (%llu MB)\n", hdf->file.size, hdf->file.size >> 20);
|
||||
printf("CHS: %u/%u/%u", hdf->cylinders, hdf->heads, hdf->sectors);
|
||||
printf(" (%llu MB), ", ((((uint64_t)hdf->cylinders) * hdf->heads * hdf->sectors) >> 11));
|
||||
printf("Offset: %d\n", hdf->offset);
|
||||
return 1;
|
||||
}
|
||||
hdf->enabled = 1;
|
||||
printf("file: \"%s\": ", hdf->file.name);
|
||||
SetHardfileGeometry(hdf, is_minimig() && !strcasecmp(".hdf", filename + strlen(filename) - 4));
|
||||
printf("size: %llu (%llu MB)\n", hdf->file.size, hdf->file.size >> 20);
|
||||
printf("CHS: %u/%u/%u", hdf->cylinders, hdf->heads, hdf->sectors);
|
||||
printf(" (%llu MB), ", ((((uint64_t)hdf->cylinders) * hdf->heads * hdf->sectors) >> 11));
|
||||
printf("Offset: %d\n", hdf->offset);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("HDD %d: not present\n", hdf->unit);
|
||||
}
|
||||
|
||||
// close if opened earlier.
|
||||
if (is_minimig() && (ide_check() & 0x8000)) ide_img_set(unit, 0, 0);
|
||||
FileClose(&hdf->file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3,11 +3,93 @@
|
||||
#ifndef __MINIMIG_HDD_H__
|
||||
#define __MINIMIG_HDD_H__
|
||||
|
||||
#include "minimig_hdd_internal.h"
|
||||
// Structure definitions for RDB emulation.
|
||||
// For hardfiles that have no RDB information, we'll just create a single-partition RDB and Part block
|
||||
// on blocks 0 and 1. All other blocks within the first cylinder will be translated into the hardfile
|
||||
|
||||
#define RDB_MAGIC 0x4B534452 // "RDSK"
|
||||
|
||||
struct RigidDiskBlock {
|
||||
unsigned long rdb_ID; // "RDSK"
|
||||
unsigned long rdb_Summedlongs; // 0x40
|
||||
long rdb_ChkSum; // Sum to zero
|
||||
unsigned long rdb_HostID; // 0x07
|
||||
unsigned long rdb_BlockBytes; // 0x200
|
||||
unsigned long rdb_Flags; // 0x12 (Disk ID valid, no LUNs after this one)
|
||||
unsigned long rdb_BadBlockList; // -1 since we don't provide one
|
||||
unsigned long rdb_PartitionList; // 1
|
||||
unsigned long rdb_FileSysHeaderList; // -1
|
||||
unsigned long rdb_DriveInit; // -1
|
||||
unsigned long rdb_Reserved1[6]; // 0xffffffff
|
||||
unsigned long rdb_Cylinders;
|
||||
unsigned long rdb_Sectors;
|
||||
unsigned long rdb_Heads;
|
||||
unsigned long rdb_Interleave; // 1
|
||||
unsigned long rdb_Park; // =Cylinder count
|
||||
unsigned long rdb_Reserved2[3];
|
||||
unsigned long rdb_WritePreComp; // High cylinder ?
|
||||
unsigned long rdb_ReducedWrite; // High cylinder ?
|
||||
unsigned long rdb_StepRate; // 3 ?
|
||||
unsigned long rdb_Reserved3[5];
|
||||
unsigned long rdb_RDBBlocksLo; // block zero
|
||||
unsigned long rdb_RDBBlocksHi; // block one
|
||||
unsigned long rdb_LoCylinder; // 1
|
||||
unsigned long rdb_HiCylinder; // From the hardfile: cylinder count -1
|
||||
unsigned long rdb_CylBlocks; // From the hardfile: heads * sectors
|
||||
unsigned long rdb_AutoParkSeconds; // zero
|
||||
unsigned long rdb_HighRDSKBlock; // 1
|
||||
unsigned long rdb_Reserved4;
|
||||
char rdb_DiskVendor[8]; // "Don't"
|
||||
char rdb_DiskProduct[16]; // " repartition!"
|
||||
char rdb_DiskRevision[4];
|
||||
char rdb_ControllerVendor[8];
|
||||
char rdb_ControllerProduct[16];
|
||||
char rdb_ControllerRevision[4];
|
||||
unsigned long rdb_Reserved5[10];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct DosEnvec {
|
||||
unsigned long de_TableSize; // Size of Environment vector - 0x10
|
||||
unsigned long de_SizeBlock; // in longwords - 0x80
|
||||
unsigned long de_SecOrg; // 0
|
||||
unsigned long de_Surfaces; // Heads?
|
||||
unsigned long de_SectorPerBlock; // 1
|
||||
unsigned long de_BlocksPerTrack;
|
||||
unsigned long de_Reserved; // 2 ?
|
||||
unsigned long de_PreAlloc; // 0
|
||||
unsigned long de_Interleave; // 0
|
||||
unsigned long de_LowCyl;
|
||||
unsigned long de_HighCyl;
|
||||
unsigned long de_NumBuffers; // 30
|
||||
unsigned long de_BufMemType; // 0 - any available
|
||||
unsigned long de_MaxTransfer; // 0x00ffffff
|
||||
unsigned long de_Mask; // 0x7ffffffe
|
||||
long de_BootPri; // 0
|
||||
unsigned long de_DosType; // 0x444f5301 or 3
|
||||
// Extra fields
|
||||
unsigned long de_Baud;
|
||||
unsigned long de_Control;
|
||||
unsigned long de_BootBlocks;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PartitionBlock {
|
||||
unsigned long pb_ID; // "PART"
|
||||
unsigned long pb_Summedlongs; // 0x40
|
||||
long pb_ChkSum; // Sum to zero
|
||||
unsigned long pb_HostID; // 0x07
|
||||
unsigned long pb_Next; // -1
|
||||
unsigned long pb_Flags; // 1 - Bootable
|
||||
unsigned long pb_Reserved1[2]; // 0
|
||||
unsigned long pb_DevFlags; // 0
|
||||
char pb_DriveName[32]; // 0x03"DH0"
|
||||
unsigned long pb_Reserved2[15];
|
||||
DosEnvec pb_Environment;
|
||||
unsigned long pb_EReserved[12]; // reserved for future environment vector
|
||||
} __attribute__((packed));
|
||||
|
||||
// functions
|
||||
void HandleHDD(uint8_t c1, uint8_t c2);
|
||||
uint8_t OpenHardfile(uint8_t unit, const char* filename = 0);
|
||||
uint8_t OpenHardfile(uint8_t unit, const char* filename);
|
||||
int checkHDF(const char* name, struct RigidDiskBlock **rdb);
|
||||
|
||||
#endif // __HDD_H__
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
#ifndef __MINIMIG_HDD_INTERNAL_H__
|
||||
#define __MINIMIG_HDD_INTERNAL_H__
|
||||
|
||||
// Structure definitions for RDB emulation.
|
||||
// For hardfiles that have no RDB information, we'll just create a single-partition RDB and Part block
|
||||
// on blocks 0 and 1. All other blocks within the first cylinder will be translated into the hardfile
|
||||
|
||||
#define RDB_MAGIC 0x4B534452 // "RDSK"
|
||||
|
||||
struct RigidDiskBlock {
|
||||
unsigned long rdb_ID; // "RDSK"
|
||||
unsigned long rdb_Summedlongs; // 0x40
|
||||
long rdb_ChkSum; // Sum to zero
|
||||
unsigned long rdb_HostID; // 0x07
|
||||
unsigned long rdb_BlockBytes; // 0x200
|
||||
unsigned long rdb_Flags; // 0x12 (Disk ID valid, no LUNs after this one)
|
||||
unsigned long rdb_BadBlockList; // -1 since we don't provide one
|
||||
unsigned long rdb_PartitionList; // 1
|
||||
unsigned long rdb_FileSysHeaderList; // -1
|
||||
unsigned long rdb_DriveInit; // -1
|
||||
unsigned long rdb_Reserved1[6]; // 0xffffffff
|
||||
unsigned long rdb_Cylinders;
|
||||
unsigned long rdb_Sectors;
|
||||
unsigned long rdb_Heads;
|
||||
unsigned long rdb_Interleave; // 1
|
||||
unsigned long rdb_Park; // =Cylinder count
|
||||
unsigned long rdb_Reserved2[3];
|
||||
unsigned long rdb_WritePreComp; // High cylinder ?
|
||||
unsigned long rdb_ReducedWrite; // High cylinder ?
|
||||
unsigned long rdb_StepRate; // 3 ?
|
||||
unsigned long rdb_Reserved3[5];
|
||||
unsigned long rdb_RDBBlocksLo; // block zero
|
||||
unsigned long rdb_RDBBlocksHi; // block one
|
||||
unsigned long rdb_LoCylinder; // 1
|
||||
unsigned long rdb_HiCylinder; // From the hardfile: cylinder count -1
|
||||
unsigned long rdb_CylBlocks; // From the hardfile: heads * sectors
|
||||
unsigned long rdb_AutoParkSeconds; // zero
|
||||
unsigned long rdb_HighRDSKBlock; // 1
|
||||
unsigned long rdb_Reserved4;
|
||||
char rdb_DiskVendor[8]; // "Don't"
|
||||
char rdb_DiskProduct[16]; // " repartition!"
|
||||
char rdb_DiskRevision[4];
|
||||
char rdb_ControllerVendor[8];
|
||||
char rdb_ControllerProduct[16];
|
||||
char rdb_ControllerRevision[4];
|
||||
unsigned long rdb_Reserved5[10];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct DosEnvec {
|
||||
unsigned long de_TableSize; // Size of Environment vector - 0x10
|
||||
unsigned long de_SizeBlock; // in longwords - 0x80
|
||||
unsigned long de_SecOrg; // 0
|
||||
unsigned long de_Surfaces; // Heads?
|
||||
unsigned long de_SectorPerBlock; // 1
|
||||
unsigned long de_BlocksPerTrack;
|
||||
unsigned long de_Reserved; // 2 ?
|
||||
unsigned long de_PreAlloc; // 0
|
||||
unsigned long de_Interleave; // 0
|
||||
unsigned long de_LowCyl;
|
||||
unsigned long de_HighCyl;
|
||||
unsigned long de_NumBuffers; // 30
|
||||
unsigned long de_BufMemType; // 0 - any available
|
||||
unsigned long de_MaxTransfer; // 0x00ffffff
|
||||
unsigned long de_Mask; // 0x7ffffffe
|
||||
long de_BootPri; // 0
|
||||
unsigned long de_DosType; // 0x444f5301 or 3
|
||||
// Extra fields
|
||||
unsigned long de_Baud;
|
||||
unsigned long de_Control;
|
||||
unsigned long de_BootBlocks;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
struct PartitionBlock {
|
||||
unsigned long pb_ID; // "PART"
|
||||
unsigned long pb_Summedlongs; // 0x40
|
||||
long pb_ChkSum; // Sum to zero
|
||||
unsigned long pb_HostID; // 0x07
|
||||
unsigned long pb_Next; // -1
|
||||
unsigned long pb_Flags; // 1 - Bootable
|
||||
unsigned long pb_Reserved1[2]; // 0
|
||||
unsigned long pb_DevFlags; // 0
|
||||
char pb_DriveName[32]; // 0x03"DH0"
|
||||
unsigned long pb_Reserved2[15];
|
||||
struct DosEnvec pb_Environment;
|
||||
unsigned long pb_EReserved[12]; /* reserved for future environment vector */
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif /* HDD_INTERNAL_H */
|
||||
|
||||
Reference in New Issue
Block a user