| 1 |
/*************************************************************************** |
| 2 |
|
| 3 |
Generic MAME hard disk implementation, with differencing files |
| 4 |
|
| 5 |
***************************************************************************/ |
| 6 |
|
| 7 |
#include "driver.h" |
| 8 |
|
| 9 |
|
| 10 |
/*************************************************************************** |
| 11 |
|
| 12 |
MAME compressed hard disk header format. All numbers are stored in |
| 13 |
Motorola (big-endian) byte ordering. The header is 76 bytes long. |
| 14 |
|
| 15 |
[ 0] char tag[8]; // 'MComprHD' |
| 16 |
[ 8] UINT32 length; // length of header (including tag and length fields) |
| 17 |
[ 12] UINT32 version; // drive format version |
| 18 |
[ 16] UINT32 flags; // flags (see below) |
| 19 |
[ 20] UINT32 compression; // compression type |
| 20 |
[ 24] UINT32 blocksize; // sectors per block |
| 21 |
[ 28] UINT32 totalblocks; // total # of block represented |
| 22 |
[ 32] UINT32 cylinders; // number of cylinders on hard disk |
| 23 |
[ 36] UINT32 heads; // number of heads on hard disk |
| 24 |
[ 40] UINT32 sectors; // number of sectors on hard disk |
| 25 |
[ 44] UINT8 md5[16]; // MD5 checksum for this drive |
| 26 |
[ 60] UINT8 parentmd5[16]; // MD5 checksum for parent drive |
| 27 |
[ 76] (header length) |
| 28 |
|
| 29 |
Flags: |
| 30 |
0x00000001 - set if this drive has a parent |
| 31 |
0x00000002 - set if this drive allows writes |
| 32 |
|
| 33 |
***************************************************************************/ |
| 34 |
|
| 35 |
/************************************* |
| 36 |
* |
| 37 |
* Constants |
| 38 |
* |
| 39 |
*************************************/ |
| 40 |
|
| 41 |
#define HARD_DISK_HEADER_SIZE 76 |
| 42 |
#define HARD_DISK_HEADER_VERSION 1 |
| 43 |
|
| 44 |
#define HARD_DISK_SECTOR_SIZE 512 |
| 45 |
|
| 46 |
#define HDFLAGS_HAS_PARENT 0x00000001 |
| 47 |
#define HDFLAGS_IS_WRITEABLE 0x00000002 |
| 48 |
|
| 49 |
#define HDCOMPRESSION_NONE 0 |
| 50 |
#define HDCOMPRESSION_ZLIB 1 |
| 51 |
#define HDCOMPRESSION_MAX 2 |
| 52 |
|
| 53 |
enum |
| 54 |
{ |
| 55 |
HDERR_NONE, |
| 56 |
HDERR_NO_INTERFACE, |
| 57 |
HDERR_OUT_OF_MEMORY, |
| 58 |
HDERR_INVALID_FILE, |
| 59 |
HDERR_INVALID_PARAMETER, |
| 60 |
HDERR_INVALID_DATA, |
| 61 |
HDERR_FILE_NOT_FOUND, |
| 62 |
HDERR_REQUIRES_PARENT, |
| 63 |
HDERR_FILE_NOT_WRITEABLE, |
| 64 |
HDERR_READ_ERROR, |
| 65 |
HDERR_WRITE_ERROR, |
| 66 |
HDERR_CODEC_ERROR, |
| 67 |
HDERR_INVALID_PARENT, |
| 68 |
HDERR_SECTOR_OUT_OF_RANGE, |
| 69 |
HDERR_DECOMPRESSION_ERROR, |
| 70 |
HDERR_COMPRESSION_ERROR, |
| 71 |
HDERR_CANT_CREATE_FILE |
| 72 |
}; |
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
/************************************* |
| 77 |
* |
| 78 |
* Type definitions |
| 79 |
* |
| 80 |
*************************************/ |
| 81 |
|
| 82 |
struct hard_disk_header |
| 83 |
{ |
| 84 |
UINT32 length; /* length of header data */ |
| 85 |
UINT32 version; /* drive format version */ |
| 86 |
UINT32 flags; /* flags field */ |
| 87 |
UINT32 compression; /* compression type */ |
| 88 |
UINT32 blocksize; /* sectors per block */ |
| 89 |
UINT32 totalblocks; /* total # of blocks represented */ |
| 90 |
UINT32 cylinders; /* number of cylinders on hard disk */ |
| 91 |
UINT32 heads; /* number of heads on hard disk */ |
| 92 |
UINT32 sectors; /* number of sectors on hard disk */ |
| 93 |
UINT8 md5[16]; /* MD5 checksum for this drive */ |
| 94 |
UINT8 parentmd5[16]; /* MD5 checksum for parent drive */ |
| 95 |
}; |
| 96 |
|
| 97 |
|
| 98 |
struct hard_disk_interface |
| 99 |
{ |
| 100 |
void *(*open)(const char *filename, const char *mode); |
| 101 |
void (*close)(void *file); |
| 102 |
UINT32 (*read)(void *file, UINT64 offset, UINT32 count, void *buffer); |
| 103 |
UINT32 (*write)(void *file, UINT64 offset, UINT32 count, const void *buffer); |
| 104 |
}; |
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
/************************************* |
| 109 |
* |
| 110 |
* Prototypes |
| 111 |
* |
| 112 |
*************************************/ |
| 113 |
|
| 114 |
void hard_disk_set_interface(struct hard_disk_interface *interface); |
| 115 |
|
| 116 |
int hard_disk_create(const char *filename, const struct hard_disk_header *header); |
| 117 |
void *hard_disk_open(const char *filename, int writeable, void *parent); |
| 118 |
void hard_disk_close(void *disk); |
| 119 |
void hard_disk_close_all(void); |
| 120 |
|
| 121 |
UINT32 hard_disk_read(void *disk, UINT32 lbasector, UINT32 numsectors, void *buffer); |
| 122 |
UINT32 hard_disk_write(void *disk, UINT32 lbasector, UINT32 numsectors, const void *buffer); |
| 123 |
|
| 124 |
int hard_disk_get_last_error(void); |
| 125 |
const struct hard_disk_header *hard_disk_get_header(void *disk); |
| 126 |
|
| 127 |
int hard_disk_compress(const char *rawfile, UINT32 offset, const char *newfile, const struct hard_disk_header *header, const char *difffile, void (*progress)(const char *, ...)); |