diff options
author | 2019-08-01 21:40:55 -0400 | |
---|---|---|
committer | 2019-08-01 21:40:55 -0400 | |
commit | f136e7b0eb0ab42fc30d4e2594d0e79c97b0f427 (patch) | |
tree | e4cb4e57c7734de04abe59956ef520b9b1240dbd /src/lib | |
parent | 95b60c1a4991ce1ded2f1fe60f832ac2b725785b (diff) |
harddisk: Support non-CHD harddisk images in raw and 2MG format [R. Belmont]
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/util/harddisk.cpp | 77 | ||||
-rw-r--r-- | src/lib/util/harddisk.h | 3 |
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); |