trunk/src/emu/imagedev/harddriv.c
| r17722 | r17723 | |
| 2 | 2 | |
| 3 | 3 | Code to interface the image code with harddisk core. |
| 4 | 4 | |
| 5 | | We do not support diff files as it will involve some changes in |
| 6 | | the image code. Additionally, the need for diff files comes |
| 7 | | from MAME's need for "canonical" hard drive images. |
| 8 | | |
| 9 | 5 | Raphael Nabet 2003 |
| 10 | 6 | |
| 11 | 7 | Update: 23-Feb-2004 - Unlike floppy disks, for which we support |
| r17722 | r17723 | |
| 16 | 12 | *********************************************************************/ |
| 17 | 13 | |
| 18 | 14 | #include "emu.h" |
| 15 | #include "emuopts.h" |
| 19 | 16 | #include "harddisk.h" |
| 20 | 17 | #include "harddriv.h" |
| 21 | 18 | |
| r17722 | r17723 | |
| 140 | 137 | |
| 141 | 138 | /* create the CHD file */ |
| 142 | 139 | chd_codec_type compression[4] = { CHD_CODEC_NONE }; |
| 143 | | err = m_self_chd.create(*image_core_file(), (UINT64)totalsectors * (UINT64)sectorsize, hunksize, sectorsize, compression); |
| 140 | err = m_origchd.create(*image_core_file(), (UINT64)totalsectors * (UINT64)sectorsize, hunksize, sectorsize, compression); |
| 144 | 141 | if (err != CHDERR_NONE) |
| 145 | 142 | goto error; |
| 146 | 143 | |
| 147 | 144 | /* if we created the image and hence, have metadata to set, set the metadata */ |
| 148 | 145 | metadata.format(HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize); |
| 149 | | err = m_self_chd.write_metadata(HARD_DISK_METADATA_TAG, 0, metadata); |
| 150 | | m_self_chd.close(); |
| 146 | err = m_origchd.write_metadata(HARD_DISK_METADATA_TAG, 0, metadata); |
| 147 | m_origchd.close(); |
| 151 | 148 | |
| 152 | 149 | if (err != CHDERR_NONE) |
| 153 | 150 | goto error; |
| r17722 | r17723 | |
| 172 | 169 | m_hard_disk_handle = NULL; |
| 173 | 170 | } |
| 174 | 171 | |
| 175 | | if (m_chd != NULL) |
| 172 | m_origchd.close(); |
| 173 | m_diffchd.close(); |
| 174 | m_chd = NULL; |
| 175 | } |
| 176 | |
| 177 | /*------------------------------------------------- |
| 178 | open_disk_diff - open a DISK diff file |
| 179 | -------------------------------------------------*/ |
| 180 | |
| 181 | static chd_error open_disk_diff(emu_options &options, const char *name, chd_file &source, chd_file &diff_chd) |
| 182 | { |
| 183 | astring fname(name, ".dif"); |
| 184 | |
| 185 | /* try to open the diff */ |
| 186 | //printf("Opening differencing image file: %s\n", fname.cstr()); |
| 187 | emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE); |
| 188 | file_error filerr = diff_file.open(fname); |
| 189 | if (filerr == FILERR_NONE) |
| 176 | 190 | { |
| 177 | | if (m_self_chd.opened()) |
| 178 | | m_self_chd.close(); |
| 179 | | m_chd = NULL; |
| 191 | astring fullpath(diff_file.fullpath()); |
| 192 | diff_file.close(); |
| 193 | |
| 194 | //printf("Opening differencing image file: %s\n", fullpath.cstr()); |
| 195 | return diff_chd.open(fullpath, true, &source); |
| 180 | 196 | } |
| 197 | |
| 198 | /* didn't work; try creating it instead */ |
| 199 | //printf("Creating differencing image: %s\n", fname.cstr()); |
| 200 | diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); |
| 201 | filerr = diff_file.open(fname); |
| 202 | if (filerr == FILERR_NONE) |
| 203 | { |
| 204 | astring fullpath(diff_file.fullpath()); |
| 205 | diff_file.close(); |
| 206 | |
| 207 | /* create the CHD */ |
| 208 | //printf("Creating differencing image file: %s\n", fullpath.cstr()); |
| 209 | chd_codec_type compression[4] = { CHD_CODEC_NONE }; |
| 210 | chd_error err = diff_chd.create(fullpath, source.logical_bytes(), source.hunk_bytes(), compression, source); |
| 211 | if (err != CHDERR_NONE) |
| 212 | return err; |
| 213 | |
| 214 | return diff_chd.clone_all_metadata(source); |
| 215 | } |
| 216 | |
| 217 | return CHDERR_FILE_NOT_FOUND; |
| 181 | 218 | } |
| 182 | 219 | |
| 183 | 220 | int harddisk_image_device::internal_load_hd() |
| 184 | 221 | { |
| 185 | | chd_error err = (chd_error)0; |
| 186 | | int is_writeable; |
| 187 | 222 | astring tempstring; |
| 223 | chd_error err = CHDERR_NONE; |
| 188 | 224 | |
| 225 | m_chd = NULL; |
| 226 | |
| 189 | 227 | /* open the CHD file */ |
| 190 | 228 | if (software_entry() != NULL) |
| 191 | 229 | { |
| 192 | 230 | m_chd = get_disk_handle(device().machine(), device().subtag(tempstring,"harddriv")); |
| 193 | | } else { |
| 194 | | do |
| 231 | } |
| 232 | else |
| 233 | { |
| 234 | err = m_origchd.open(*image_core_file(), true); |
| 235 | if (err == CHDERR_NONE) |
| 195 | 236 | { |
| 196 | | is_writeable = !is_readonly(); |
| 197 | | err = m_self_chd.open(*image_core_file(), is_writeable); |
| 237 | m_chd = &m_origchd; |
| 238 | } |
| 239 | else if (err == CHDERR_FILE_NOT_WRITEABLE) |
| 240 | { |
| 241 | err = m_origchd.open(*image_core_file(), false); |
| 198 | 242 | if (err == CHDERR_NONE) |
| 199 | | m_chd = &m_self_chd; |
| 200 | | |
| 201 | | /* special case; if we get CHDERR_FILE_NOT_WRITEABLE, make the |
| 202 | | * image read only and repeat */ |
| 203 | | if (err == CHDERR_FILE_NOT_WRITEABLE) |
| 204 | | make_readonly(); |
| 243 | { |
| 244 | err = open_disk_diff(device().machine().options(), basename_noext(), m_origchd, m_diffchd); |
| 245 | if (err == CHDERR_NONE) |
| 246 | { |
| 247 | m_chd = &m_diffchd; |
| 248 | } |
| 249 | } |
| 205 | 250 | } |
| 206 | | while(!m_chd && is_writeable && (err == CHDERR_FILE_NOT_WRITEABLE)); |
| 207 | 251 | } |
| 208 | | if (!m_chd) |
| 209 | | goto done; |
| 210 | 252 | |
| 211 | | /* open the hard disk file */ |
| 212 | | m_hard_disk_handle = hard_disk_open(m_chd); |
| 213 | | if (!m_hard_disk_handle) |
| 214 | | goto done; |
| 215 | | |
| 216 | | done: |
| 217 | | if (err) |
| 253 | if (m_chd != NULL) |
| 218 | 254 | { |
| 219 | | /* if we had an error, close out the CHD */ |
| 220 | | if (m_chd != NULL) |
| 221 | | { |
| 222 | | if (m_self_chd.opened()) |
| 223 | | m_self_chd.close(); |
| 224 | | m_chd = NULL; |
| 225 | | } |
| 226 | | seterror(IMAGE_ERROR_UNSPECIFIED, chd_file::error_string(err)); |
| 255 | /* open the hard disk file */ |
| 256 | m_hard_disk_handle = hard_disk_open(m_chd); |
| 257 | if (m_hard_disk_handle != NULL) |
| 258 | return IMAGE_INIT_PASS; |
| 227 | 259 | } |
| 228 | | return err ? IMAGE_INIT_FAIL : IMAGE_INIT_PASS; |
| 260 | |
| 261 | /* if we had an error, close out the CHD */ |
| 262 | m_origchd.close(); |
| 263 | m_diffchd.close(); |
| 264 | m_chd = NULL; |
| 265 | seterror(IMAGE_ERROR_UNSPECIFIED, chd_file::error_string(err)); |
| 266 | |
| 267 | return IMAGE_INIT_FAIL; |
| 229 | 268 | } |
| 230 | 269 | |
| 231 | 270 | /************************************* |