summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/util/harddisk.cpp77
-rw-r--r--src/lib/util/harddisk.h3
2 files changed, 73 insertions, 7 deletions
diff --git a/src/lib/util/harddisk.cpp b/src/lib/util/harddisk.cpp
index 31c6a36ed28..5db97e3417b 100644
--- a/src/lib/util/harddisk.cpp
+++ b/src/lib/util/harddisk.cpp
@@ -9,12 +9,10 @@
***************************************************************************/
#include <assert.h>
-
#include "harddisk.h"
-
+#include "osdcore.h"
#include <stdlib.h>
-
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
@@ -22,6 +20,7 @@
struct hard_disk_file
{
chd_file * chd; /* CHD file */
+ util::core_file *fhandle; /* core_file if not a CHD */
hard_disk_info info; /* hard disk info */
};
@@ -63,10 +62,49 @@ hard_disk_file *hard_disk_open(chd_file *chd)
/* fill in the data */
file->chd = chd;
+ file->fhandle = nullptr;
file->info.cylinders = cylinders;
file->info.heads = heads;
file->info.sectors = sectors;
file->info.sectorbytes = sectorbytes;
+ file->info.fileoffset = 0;
+ return file;
+}
+
+hard_disk_file *hard_disk_open(util::core_file &corefile, uint32_t skipoffs)
+{
+ hard_disk_file *file;
+
+ /* allocate memory for the hard disk file */
+ file = (hard_disk_file *)malloc(sizeof(hard_disk_file));
+ if (file == nullptr)
+ return nullptr;
+
+ file->chd = nullptr;
+ file->fhandle = &corefile;
+ file->info.sectorbytes = 512;
+ file->info.cylinders = 0;
+ file->info.heads = 0;
+ file->info.sectors = 0;
+ file->info.fileoffset = skipoffs;
+
+ // attempt to guess geometry in case this is an ATA situation
+ for (uint32_t totalsectors = (corefile.size() - skipoffs) / file->info.sectorbytes; ; totalsectors++)
+ for (uint32_t cursectors = 63; cursectors > 1; cursectors--)
+ if (totalsectors % cursectors == 0)
+ {
+ uint32_t totalheads = totalsectors / cursectors;
+ for (uint32_t curheads = 16; curheads > 1; curheads--)
+ if (totalheads % curheads == 0)
+ {
+ file->info.cylinders = totalheads / curheads;
+ file->info.heads = curheads;
+ file->info.sectors = cursectors;
+ osd_printf_verbose("Guessed CHS of %d/%d/%d\n", file->info.cylinders, file->info.heads, file->info.sectors);
+ return file;
+ }
+ }
+
return file;
}
@@ -77,6 +115,11 @@ hard_disk_file *hard_disk_open(chd_file *chd)
void hard_disk_close(hard_disk_file *file)
{
+ if (file->fhandle)
+ {
+ file->fhandle->flush();
+ }
+
free(file);
}
@@ -132,8 +175,18 @@ hard_disk_info *hard_disk_get_info(hard_disk_file *file)
uint32_t hard_disk_read(hard_disk_file *file, uint32_t lbasector, void *buffer)
{
- chd_error err = file->chd->read_units(lbasector, buffer);
- return (err == CHDERR_NONE);
+ if (file->chd)
+ {
+ chd_error err = file->chd->read_units(lbasector, buffer);
+ return (err == CHDERR_NONE);
+ }
+ else
+ {
+ uint32_t actual = 0;
+ file->fhandle->seek(file->info.fileoffset + (lbasector * file->info.sectorbytes), SEEK_SET);
+ actual = file->fhandle->read(buffer, file->info.sectorbytes);
+ return (actual == file->info.sectorbytes);
+ }
}
@@ -156,6 +209,16 @@ uint32_t hard_disk_read(hard_disk_file *file, uint32_t lbasector, void *buffer)
uint32_t hard_disk_write(hard_disk_file *file, uint32_t lbasector, const void *buffer)
{
- chd_error err = file->chd->write_units(lbasector, buffer);
- return (err == CHDERR_NONE);
+ if (file->chd)
+ {
+ chd_error err = file->chd->write_units(lbasector, buffer);
+ return (err == CHDERR_NONE);
+ }
+ else
+ {
+ uint32_t actual = 0;
+ file->fhandle->seek(file->info.fileoffset + (lbasector * file->info.sectorbytes), SEEK_SET);
+ actual = file->fhandle->write(buffer, file->info.sectorbytes);
+ return (actual == file->info.sectorbytes);
+ }
}
diff --git a/src/lib/util/harddisk.h b/src/lib/util/harddisk.h
index c0551703ca7..2a4b727e7e7 100644
--- a/src/lib/util/harddisk.h
+++ b/src/lib/util/harddisk.h
@@ -29,6 +29,7 @@ struct hard_disk_info
uint32_t heads;
uint32_t sectors;
uint32_t sectorbytes;
+ uint32_t fileoffset; // offset in the file where the HDD image starts. not valid for CHDs.
};
@@ -38,6 +39,8 @@ struct hard_disk_info
***************************************************************************/
hard_disk_file *hard_disk_open(chd_file *chd);
+hard_disk_file *hard_disk_open(util::core_file &corefile, uint32_t skipoffs);
+
void hard_disk_close(hard_disk_file *file);
chd_file *hard_disk_get_chd(hard_disk_file *file);