diff options
author | 2007-12-17 15:19:59 +0000 | |
---|---|---|
committer | 2007-12-17 15:19:59 +0000 | |
commit | 7b77f1218624ea26dbb2efd85a19f795f5d4e02e (patch) | |
tree | 19209304095572b4fd61c2a2d6a5aa75c4e471ad /src/lib/util/harddisk.c | |
parent | 3da7f476068b3ffef713218ba2fc1bd5030f2c38 (diff) |
Initial checkin of MAME 0.121.mame0121
Diffstat (limited to 'src/lib/util/harddisk.c')
-rw-r--r-- | src/lib/util/harddisk.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/src/lib/util/harddisk.c b/src/lib/util/harddisk.c new file mode 100644 index 00000000000..a4edf8524d9 --- /dev/null +++ b/src/lib/util/harddisk.c @@ -0,0 +1,170 @@ +/*************************************************************************** + + Generic MAME hard disk implementation, with differencing files + + Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + +***************************************************************************/ + +#include "harddisk.h" + + + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +struct _hard_disk_file +{ + chd_file * chd; /* CHD file */ + hard_disk_info info; /* hard disk info */ + UINT32 hunksectors; /* sectors per hunk */ + UINT32 cachehunk; /* which hunk is cached */ + UINT8 * cache; /* cache of the current hunk */ +}; + + + +/*************************************************************************** + CORE IMPLEMENTATION +***************************************************************************/ + +/*------------------------------------------------- + hard_disk_open - open a hard disk handle, + given a chd_file +-------------------------------------------------*/ + +hard_disk_file *hard_disk_open(chd_file *chd) +{ + int cylinders, heads, sectors, sectorbytes; + hard_disk_file *file; + char metadata[256]; + chd_error err; + + /* punt if no CHD */ + if (chd == NULL) + return NULL; + + /* read the hard disk metadata */ + err = chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL); + if (err != CHDERR_NONE) + return NULL; + + /* parse the metadata */ + if (sscanf(metadata, HARD_DISK_METADATA_FORMAT, &cylinders, &heads, §ors, §orbytes) != 4) + return NULL; + + /* allocate memory for the hard disk file */ + file = malloc(sizeof(hard_disk_file)); + if (file == NULL) + return NULL; + + /* fill in the data */ + file->chd = chd; + file->info.cylinders = cylinders; + file->info.heads = heads; + file->info.sectors = sectors; + file->info.sectorbytes = sectorbytes; + file->hunksectors = chd_get_header(chd)->hunkbytes / file->info.sectorbytes; + file->cachehunk = -1; + + /* allocate a cache */ + file->cache = malloc(chd_get_header(chd)->hunkbytes); + if (file->cache == NULL) + { + free(file); + return NULL; + } + + return file; +} + + +/*------------------------------------------------- + hard_disk_close - close a hard disk handle +-------------------------------------------------*/ + +void hard_disk_close(hard_disk_file *file) +{ + /* free the cache */ + if (file->cache != NULL) + free(file->cache); + free(file); +} + + +/*------------------------------------------------- + hard_disk_get_chd - get a handle to a CHD + from a hard disk +-------------------------------------------------*/ + +chd_file *hard_disk_get_chd(hard_disk_file *file) +{ + return file->chd; +} + + +/*------------------------------------------------- + hard_disk_get_info - return information about + a hard disk +-------------------------------------------------*/ + +hard_disk_info *hard_disk_get_info(hard_disk_file *file) +{ + return &file->info; +} + + +/*------------------------------------------------- + hard_disk_read - read sectors from a hard + disk +-------------------------------------------------*/ + +UINT32 hard_disk_read(hard_disk_file *file, UINT32 lbasector, void *buffer) +{ + UINT32 hunknum = lbasector / file->hunksectors; + UINT32 sectoroffs = lbasector % file->hunksectors; + + /* if we haven't cached this hunk, read it now */ + if (file->cachehunk != hunknum) + { + chd_error err = chd_read(file->chd, hunknum, file->cache); + if (err != CHDERR_NONE) + return 0; + file->cachehunk = hunknum; + } + + /* copy out the requested sector */ + memcpy(buffer, &file->cache[sectoroffs * file->info.sectorbytes], file->info.sectorbytes); + return 1; +} + + +/*------------------------------------------------- + hard_disk_write - write sectors to a hard + disk +-------------------------------------------------*/ + +UINT32 hard_disk_write(hard_disk_file *file, UINT32 lbasector, const void *buffer) +{ + UINT32 hunknum = lbasector / file->hunksectors; + UINT32 sectoroffs = lbasector % file->hunksectors; + chd_error err; + + /* if we haven't cached this hunk, read it now */ + if (file->cachehunk != hunknum) + { + err = chd_read(file->chd, hunknum, file->cache); + if (err != CHDERR_NONE) + return 0; + file->cachehunk = hunknum; + } + + /* copy in the requested data */ + memcpy(&file->cache[sectoroffs * file->info.sectorbytes], buffer, file->info.sectorbytes); + + /* write it back out */ + err = chd_write(file->chd, hunknum, file->cache); + return (err == CHDERR_NONE) ? 1 : 0; +} |