1 // license:BSD-3-Clause
2 // copyright-holders:Nicola Salmoria,Aaron Giles,Vas Crabb
3 /*********************************************************************
4
5 romload.h
6
7 ROM loading functions.
8
9 *********************************************************************/
10
11 #ifndef MAME_EMU_ROMLOAD_H
12 #define MAME_EMU_ROMLOAD_H
13
14 #pragma once
15
16 #include "chd.h"
17
18 #include <functional>
19 #include <initializer_list>
20 #include <string>
21 #include <type_traits>
22 #include <vector>
23
24
25 /***************************************************************************
26 TYPE DEFINITIONS
27 ***************************************************************************/
28
29
30 /***************************************************************************
31 MACROS
32 ***************************************************************************/
33
ROMENTRY_UNWRAP(T const & r)34 template <typename T> inline std::enable_if_t<!std::is_pointer<T>::value, T const &> ROMENTRY_UNWRAP(T const &r) { return r; }
ROMENTRY_UNWRAP(T const * r)35 template <typename T> inline T const &ROMENTRY_UNWRAP(T const *r) { return *r; }
36
37 /* ----- per-entry macros ----- */
ROMENTRY_GETTYPE(T const & r)38 template <typename T> inline u32 ROMENTRY_GETTYPE(T const &r) { return ROMENTRY_UNWRAP(r).get_flags() & ROMENTRY_TYPEMASK; }
ROMENTRY_ISSPECIAL(T const & r)39 template <typename T> inline bool ROMENTRY_ISSPECIAL(T const &r) { return ROMENTRY_GETTYPE(r) != ROMENTRYTYPE_ROM; }
ROMENTRY_ISFILE(T const & r)40 template <typename T> inline bool ROMENTRY_ISFILE(T const &r) { return ROMENTRY_GETTYPE(r) == ROMENTRYTYPE_ROM; }
ROMENTRY_ISREGION(T const & r)41 template <typename T> inline bool ROMENTRY_ISREGION(T const &r) { return ROMENTRY_GETTYPE(r) == ROMENTRYTYPE_REGION; }
ROMENTRY_ISEND(T const & r)42 template <typename T> inline bool ROMENTRY_ISEND(T const &r) { return ROMENTRY_GETTYPE(r) == ROMENTRYTYPE_END; }
ROMENTRY_ISRELOAD(T const & r)43 template <typename T> inline bool ROMENTRY_ISRELOAD(T const &r) { return ROMENTRY_GETTYPE(r) == ROMENTRYTYPE_RELOAD; }
ROMENTRY_ISCONTINUE(T const & r)44 template <typename T> inline bool ROMENTRY_ISCONTINUE(T const &r) { return ROMENTRY_GETTYPE(r) == ROMENTRYTYPE_CONTINUE; }
ROMENTRY_ISFILL(T const & r)45 template <typename T> inline bool ROMENTRY_ISFILL(T const &r) { return ROMENTRY_GETTYPE(r) == ROMENTRYTYPE_FILL; }
ROMENTRY_ISCOPY(T const & r)46 template <typename T> inline bool ROMENTRY_ISCOPY(T const &r) { return ROMENTRY_GETTYPE(r) == ROMENTRYTYPE_COPY; }
ROMENTRY_ISIGNORE(T const & r)47 template <typename T> inline bool ROMENTRY_ISIGNORE(T const &r) { return ROMENTRY_GETTYPE(r) == ROMENTRYTYPE_IGNORE; }
ROMENTRY_ISSYSTEM_BIOS(T const & r)48 template <typename T> inline bool ROMENTRY_ISSYSTEM_BIOS(T const &r) { return ROMENTRY_GETTYPE(r) == ROMENTRYTYPE_SYSTEM_BIOS; }
ROMENTRY_ISDEFAULT_BIOS(T const & r)49 template <typename T> inline bool ROMENTRY_ISDEFAULT_BIOS(T const &r) { return ROMENTRY_GETTYPE(r) == ROMENTRYTYPE_DEFAULT_BIOS; }
ROMENTRY_ISPARAMETER(T const & r)50 template <typename T> inline bool ROMENTRY_ISPARAMETER(T const &r) { return ROMENTRY_GETTYPE(r) == ROMENTRYTYPE_PARAMETER; }
ROMENTRY_ISREGIONEND(T const & r)51 template <typename T> inline bool ROMENTRY_ISREGIONEND(T const &r) { return ROMENTRY_ISREGION(r) || ROMENTRY_ISPARAMETER(r) || ROMENTRY_ISEND(r); }
52
53 /* ----- per-region macros ----- */
54 #define ROMREGION_GETTAG(r) ((r)->name().c_str())
ROMREGION_GETLENGTH(T const & r)55 template <typename T> inline u32 ROMREGION_GETLENGTH(T const &r) { return ROMENTRY_UNWRAP(r).get_length(); }
ROMREGION_GETFLAGS(T const & r)56 template <typename T> inline u32 ROMREGION_GETFLAGS(T const &r) { return ROMENTRY_UNWRAP(r).get_flags(); }
ROMREGION_GETWIDTH(T const & r)57 template <typename T> inline u32 ROMREGION_GETWIDTH(T const &r) { return 8 << ((ROMREGION_GETFLAGS(r) & ROMREGION_WIDTHMASK) >> 8); }
ROMREGION_ISLITTLEENDIAN(T const & r)58 template <typename T> inline bool ROMREGION_ISLITTLEENDIAN(T const &r) { return (ROMREGION_GETFLAGS(r) & ROMREGION_ENDIANMASK) == ROMREGION_LE; }
ROMREGION_ISBIGENDIAN(T const & r)59 template <typename T> inline bool ROMREGION_ISBIGENDIAN(T const &r) { return (ROMREGION_GETFLAGS(r) & ROMREGION_ENDIANMASK) == ROMREGION_BE; }
ROMREGION_ISINVERTED(T const & r)60 template <typename T> inline bool ROMREGION_ISINVERTED(T const &r) { return (ROMREGION_GETFLAGS(r) & ROMREGION_INVERTMASK) == ROMREGION_INVERT; }
ROMREGION_ISERASE(T const & r)61 template <typename T> inline bool ROMREGION_ISERASE(T const &r) { return (ROMREGION_GETFLAGS(r) & ROMREGION_ERASEMASK) == ROMREGION_ERASE; }
ROMREGION_GETERASEVAL(T const & r)62 template <typename T> inline u32 ROMREGION_GETERASEVAL(T const &r) { return (ROMREGION_GETFLAGS(r) & ROMREGION_ERASEVALMASK) >> 16; }
ROMREGION_GETDATATYPE(T const & r)63 template <typename T> inline u32 ROMREGION_GETDATATYPE(T const &r) { return ROMREGION_GETFLAGS(r) & ROMREGION_DATATYPEMASK; }
ROMREGION_ISROMDATA(T const & r)64 template <typename T> inline bool ROMREGION_ISROMDATA(T const &r) { return ROMREGION_GETDATATYPE(r) == ROMREGION_DATATYPEROM; }
ROMREGION_ISDISKDATA(T const & r)65 template <typename T> inline bool ROMREGION_ISDISKDATA(T const &r) { return ROMREGION_GETDATATYPE(r) == ROMREGION_DATATYPEDISK; }
66
67
68 /* ----- per-ROM macros ----- */
69 #define ROM_GETNAME(r) ((r)->name().c_str())
70 #define ROM_SAFEGETNAME(r) (ROMENTRY_ISFILL(r) ? "fill" : ROMENTRY_ISCOPY(r) ? "copy" : ROM_GETNAME(r))
ROM_GETOFFSET(T const & r)71 template <typename T> inline u32 ROM_GETOFFSET(T const &r) { return ROMENTRY_UNWRAP(r).get_offset(); }
ROM_GETLENGTH(T const & r)72 template <typename T> inline u32 ROM_GETLENGTH(T const &r) { return ROMENTRY_UNWRAP(r).get_length(); }
ROM_GETFLAGS(T const & r)73 template <typename T> inline u32 ROM_GETFLAGS(T const &r) { return ROMENTRY_UNWRAP(r).get_flags(); }
74 #define ROM_GETHASHDATA(r) ((r)->hashdata().c_str())
ROM_ISOPTIONAL(T const & r)75 template <typename T> inline bool ROM_ISOPTIONAL(T const &r) { return (ROM_GETFLAGS(r) & ROM_OPTIONALMASK) == ROM_OPTIONAL; }
ROM_GETGROUPSIZE(T const & r)76 template <typename T> inline u32 ROM_GETGROUPSIZE(T const &r) { return ((ROM_GETFLAGS(r) & ROM_GROUPMASK) >> 8) + 1; }
ROM_GETSKIPCOUNT(T const & r)77 template <typename T> inline u32 ROM_GETSKIPCOUNT(T const &r) { return (ROM_GETFLAGS(r) & ROM_SKIPMASK) >> 12; }
ROM_ISREVERSED(T const & r)78 template <typename T> inline bool ROM_ISREVERSED(T const &r) { return (ROM_GETFLAGS(r) & ROM_REVERSEMASK) == ROM_REVERSE; }
ROM_GETBITWIDTH(T const & r)79 template <typename T> inline u32 ROM_GETBITWIDTH(T const &r) { return (ROM_GETFLAGS(r) & ROM_BITWIDTHMASK) ? ((ROM_GETFLAGS(r) & ROM_BITWIDTHMASK) >> 16) : 8; }
ROM_GETBITSHIFT(T const & r)80 template <typename T> inline u32 ROM_GETBITSHIFT(T const &r) { return (ROM_GETFLAGS(r) & ROM_BITSHIFTMASK) >> 20; }
ROM_INHERITSFLAGS(T const & r)81 template <typename T> inline bool ROM_INHERITSFLAGS(T const &r) { return (ROM_GETFLAGS(r) & ROM_INHERITFLAGSMASK) == ROM_INHERITFLAGS; }
ROM_GETBIOSFLAGS(T const & r)82 template <typename T> inline u32 ROM_GETBIOSFLAGS(T const &r) { return (ROM_GETFLAGS(r) & ROM_BIOSFLAGSMASK) >> 24; }
83
84
85 /* ----- per-disk macros ----- */
DISK_GETINDEX(T const & r)86 template <typename T> inline u32 DISK_GETINDEX(T const &r) { return ROMENTRY_UNWRAP(r).get_offset(); }
DISK_ISREADONLY(T const & r)87 template <typename T> inline bool DISK_ISREADONLY(T const &r) { return (ROM_GETFLAGS(r) & DISK_READONLYMASK) == DISK_READONLY; }
88
89
90 namespace romload {
91
92 template <typename T>
93 class const_entry_iterator
94 {
95 protected:
96 tiny_rom_entry const *m_data;
97
const_entry_iterator()98 constexpr const_entry_iterator() noexcept : m_data(nullptr) { }
const_entry_iterator(tiny_rom_entry const * data)99 constexpr const_entry_iterator(tiny_rom_entry const *data) noexcept : m_data(data) { }
100 constexpr const_entry_iterator(const_entry_iterator const &) noexcept = default;
101 const_entry_iterator(const_entry_iterator &&) noexcept = default;
102 const_entry_iterator &operator=(const_entry_iterator const &) noexcept = default;
103 const_entry_iterator &operator=(const_entry_iterator &&) noexcept = default;
104
105 public:
106 typedef T value_type;
107 typedef value_type const *pointer;
108 typedef value_type const &reference;
109 typedef std::ptrdiff_t difference_type;
110 typedef std::forward_iterator_tag iterator_category;
111
112 reference operator*() const noexcept { return reinterpret_cast<reference>(*m_data); }
113 pointer operator->() const noexcept { return reinterpret_cast<pointer>(m_data); }
114 };
115
116
117 class file final : tiny_rom_entry
118 {
119 private:
120 file() = default;
121 file(file const &) = delete;
122 file &operator=(file const &) = delete;
123
124 public:
125 // ROM
get_name()126 constexpr char const *get_name() const { return name; }
get_offset()127 constexpr u32 get_offset() const { return offset; }
get_length()128 constexpr u32 get_length() const { return length; }
get_flags()129 constexpr u32 get_flags() const { return flags; }
get_hashdata()130 constexpr char const *get_hashdata() const { return hashdata; }
is_optional()131 constexpr bool is_optional() const { return (flags & ROM_OPTIONALMASK) == ROM_OPTIONAL; }
get_groupsize()132 constexpr u32 get_groupsize() const { return ((flags & ROM_GROUPMASK) >> 8) + 1; }
get_skipcount()133 constexpr u32 get_skipcount() const { return (flags & ROM_SKIPMASK) >> 12; }
is_reversed()134 constexpr bool is_reversed() const { return (flags & ROM_REVERSEMASK) == ROM_REVERSE; }
get_bitwidth()135 constexpr u32 get_bitwidth() const { return (flags & ROM_BITWIDTHMASK) ? ((flags & ROM_BITWIDTHMASK) >> 16) : 8; }
get_bitshift()136 constexpr u32 get_bitshift() const { return (flags & ROM_BITSHIFTMASK) >> 20; }
inherits_flags()137 constexpr bool inherits_flags() const { return (flags & ROM_INHERITFLAGSMASK) == ROM_INHERITFLAGS; }
get_bios_flags()138 constexpr u32 get_bios_flags() const { return (flags & ROM_BIOSFLAGSMASK) >> 24; }
139
140 // disk
get_index()141 constexpr u32 get_index() const { return offset; }
is_readonly()142 constexpr bool is_readonly() const { return (flags & DISK_READONLYMASK) == DISK_READONLY; }
143 };
144
145 class files
146 {
147 private:
148 tiny_rom_entry const *m_data;
149
150 public:
151 class const_iterator : public const_entry_iterator<file>
152 {
153 private:
154 friend class files;
155
const_iterator(tiny_rom_entry const * data)156 constexpr const_iterator(tiny_rom_entry const *data) noexcept : const_entry_iterator<file>(data) { }
157
158 public:
159 constexpr const_iterator() noexcept = default;
160 constexpr const_iterator(const_iterator const &) noexcept = default;
161 const_iterator(const_iterator &&) noexcept = default;
162 const_iterator &operator=(const_iterator const &) noexcept = default;
163 const_iterator &operator=(const_iterator &&) noexcept = default;
164
165 const_iterator &operator++() noexcept
166 {
167 while (m_data)
168 {
169 ++m_data;
170 if (ROMENTRY_ISFILE(m_data))
171 break;
172 else if (ROMENTRY_ISREGIONEND(m_data))
173 m_data = nullptr;
174 }
175 return *this;
176 }
177
178 const_iterator operator++(int) noexcept { const_iterator result(*this); operator++(); return result; }
179
180 constexpr bool operator==(const_iterator const &rhs) const noexcept { return m_data == rhs.m_data; }
181 constexpr bool operator!=(const_iterator const &rhs) const noexcept { return m_data != rhs.m_data; }
182 };
183
files(tiny_rom_entry const * data)184 files(tiny_rom_entry const *data) : m_data(data)
185 {
186 while (m_data && !ROMENTRY_ISFILE(m_data))
187 {
188 if (ROMENTRY_ISREGIONEND(m_data))
189 m_data = nullptr;
190 else
191 ++m_data;
192 }
193 }
194
begin()195 const_iterator begin() const { return const_iterator(m_data); }
cbegin()196 const_iterator cbegin() const { return const_iterator(m_data); }
end()197 const_iterator end() const { return const_iterator(nullptr); }
cend()198 const_iterator cend() const { return const_iterator(nullptr); }
199 };
200
201
202 class region final : tiny_rom_entry
203 {
204 private:
205 region() = default;
206 region(region const &) = delete;
207 region &operator=(region const &) = delete;
208
209 public:
get_tag()210 constexpr char const *get_tag() const { return name; }
get_length()211 constexpr u32 get_length() const { return length; }
get_width()212 constexpr u32 get_width() const { return 8 << ((flags & ROMREGION_WIDTHMASK) >> 8); }
is_littleendian()213 constexpr bool is_littleendian() const { return (flags & ROMREGION_ENDIANMASK) == ROMREGION_LE; }
is_bigendian()214 constexpr bool is_bigendian() const { return (flags & ROMREGION_ENDIANMASK) == ROMREGION_BE; }
is_inverted()215 constexpr bool is_inverted() const { return (flags & ROMREGION_INVERTMASK) == ROMREGION_INVERT; }
is_erase()216 constexpr bool is_erase() const { return (flags & ROMREGION_ERASEMASK) == ROMREGION_ERASE; }
get_eraseval()217 constexpr u32 get_eraseval() const { return (flags & ROMREGION_ERASEVALMASK) >> 16; }
get_datatype()218 constexpr u32 get_datatype() const { return flags & ROMREGION_DATATYPEMASK; }
is_romdata()219 constexpr bool is_romdata() const { return get_datatype() == ROMREGION_DATATYPEROM; }
is_diskdata()220 constexpr bool is_diskdata() const { return get_datatype() == ROMREGION_DATATYPEDISK; }
221
get_files()222 files get_files() const { return files(static_cast<tiny_rom_entry const *>(this) + 1); }
223 };
224
225 class regions
226 {
227 private:
228 tiny_rom_entry const *m_data;
229
230 public:
231 class const_iterator : public const_entry_iterator<region>
232 {
233 private:
234 friend class regions;
235
const_iterator(tiny_rom_entry const * data)236 constexpr const_iterator(tiny_rom_entry const *data) noexcept : const_entry_iterator<region>(data) { }
237
238 public:
239 constexpr const_iterator() noexcept = default;
240 constexpr const_iterator(const_iterator const &) noexcept = default;
241 const_iterator(const_iterator &&) noexcept = default;
242 const_iterator &operator=(const_iterator const &) noexcept = default;
243 const_iterator &operator=(const_iterator &&) noexcept = default;
244
245 const_iterator &operator++() noexcept
246 {
247 while (m_data)
248 {
249 ++m_data;
250 if (ROMENTRY_ISREGION(m_data))
251 break;
252 else if (ROMENTRY_ISEND(m_data))
253 m_data = nullptr;
254 }
255 return *this;
256 }
257
258 const_iterator operator++(int) noexcept { const_iterator result(*this); operator++(); return result; }
259
260 constexpr bool operator==(const_iterator const &rhs) const noexcept { return m_data == rhs.m_data; }
261 constexpr bool operator!=(const_iterator const &rhs) const noexcept { return m_data != rhs.m_data; }
262 };
263
regions(tiny_rom_entry const * data)264 regions(tiny_rom_entry const *data) : m_data(data)
265 {
266 while (m_data && !ROMENTRY_ISREGION(m_data))
267 {
268 if (ROMENTRY_ISEND(m_data))
269 m_data = nullptr;
270 else
271 ++m_data;
272 }
273 }
274
begin()275 const_iterator begin() const { return const_iterator(m_data); }
cbegin()276 const_iterator cbegin() const { return const_iterator(m_data); }
end()277 const_iterator end() const { return const_iterator(nullptr); }
cend()278 const_iterator cend() const { return const_iterator(nullptr); }
279 };
280
281
282 class system_bios final : tiny_rom_entry
283 {
284 private:
285 system_bios() = default;
286 system_bios(system_bios const &) = delete;
287 system_bios &operator=(system_bios const &) = delete;
288
289 public:
get_value()290 constexpr u32 get_value() const { return (flags & ROM_BIOSFLAGSMASK) >> 24; }
get_name()291 constexpr char const *get_name() const { return name; }
get_description()292 constexpr char const *get_description() const { return hashdata; }
293 };
294
295 class system_bioses
296 {
297 private:
298 tiny_rom_entry const *m_data;
299
300 public:
301 class const_iterator : public const_entry_iterator<system_bios>
302 {
303 private:
304 friend class system_bioses;
305
const_iterator(tiny_rom_entry const * data)306 constexpr const_iterator(tiny_rom_entry const *data) noexcept : const_entry_iterator<system_bios>(data) { }
307
308 public:
309 constexpr const_iterator() noexcept = default;
310 constexpr const_iterator(const_iterator const &) noexcept = default;
311 const_iterator(const_iterator &&) noexcept = default;
312 const_iterator &operator=(const_iterator const &) noexcept = default;
313 const_iterator &operator=(const_iterator &&) noexcept = default;
314
315 const_iterator &operator++() noexcept
316 {
317 while (m_data)
318 {
319 ++m_data;
320 if (ROMENTRY_ISSYSTEM_BIOS(m_data))
321 break;
322 else if (ROMENTRY_ISEND(m_data))
323 m_data = nullptr;
324 }
325 return *this;
326 }
327
328 const_iterator operator++(int) noexcept { const_iterator result(*this); operator++(); return result; }
329
330 constexpr bool operator==(const_iterator const &rhs) const noexcept { return m_data == rhs.m_data; }
331 constexpr bool operator!=(const_iterator const &rhs) const noexcept { return m_data != rhs.m_data; }
332 };
333
system_bioses(tiny_rom_entry const * data)334 system_bioses(tiny_rom_entry const *data) : m_data(data)
335 {
336 while (m_data && !ROMENTRY_ISSYSTEM_BIOS(m_data))
337 {
338 if (ROMENTRY_ISEND(m_data))
339 m_data = nullptr;
340 else
341 ++m_data;
342 }
343 }
344
begin()345 const_iterator begin() const { return const_iterator(m_data); }
cbegin()346 const_iterator cbegin() const { return const_iterator(m_data); }
end()347 const_iterator end() const { return const_iterator(nullptr); }
cend()348 const_iterator cend() const { return const_iterator(nullptr); }
349 };
350
351
352 class default_bios final : tiny_rom_entry
353 {
354 private:
355 default_bios() = default;
356 default_bios(default_bios const &) = delete;
357 default_bios &operator=(default_bios const &) = delete;
358
359 public:
get_name()360 constexpr char const *get_name() const { return name; }
361 };
362
363
364 class entries
365 {
366 private:
367 tiny_rom_entry const *m_data;
368
369 public:
entries(tiny_rom_entry const * data)370 constexpr entries(tiny_rom_entry const *data) : m_data(data) { }
371
get_regions()372 regions get_regions() const { return regions(m_data); }
get_system_bioses()373 system_bioses get_system_bioses() const { return system_bioses(m_data); }
374 };
375
376 } // namespace romload
377
378
379 /***************************************************************************
380 TYPE DEFINITIONS
381 ***************************************************************************/
382
383 // ======================> rom_load_manager
384
385 class rom_load_manager
386 {
387 class open_chd
388 {
389 public:
open_chd(const char * region)390 open_chd(const char *region) : m_region(region) { }
391
region()392 const char *region() const { return m_region.c_str(); }
chd()393 chd_file &chd() { return m_diffchd.opened() ? m_diffchd : m_origchd; }
orig_chd()394 chd_file &orig_chd() { return m_origchd; }
diff_chd()395 chd_file &diff_chd() { return m_diffchd; }
396
397 private:
398 std::string m_region; /* disk region we came from */
399 chd_file m_origchd; /* handle to the original CHD */
400 chd_file m_diffchd; /* handle to the diff CHD */
401 };
402
403 public:
404 // construction/destruction
405 rom_load_manager(running_machine &machine);
406
407 // getters
machine()408 running_machine &machine() const { return m_machine; }
409
410 /* return the number of warnings we generated */
warnings()411 int warnings() const { return m_warnings; }
412
software_load_warnings_message()413 std::string& software_load_warnings_message() { return m_softwarningstring; }
414
415 /* return the number of BAD_DUMP/NO_DUMP warnings we generated */
knownbad()416 int knownbad() const { return m_knownbad; }
417
418 /* ----- disk handling ----- */
419
420 /* return a pointer to the CHD file associated with the given region */
421 chd_file *get_disk_handle(const char *region);
422
423 /* set a pointer to the CHD file associated with the given region */
424 int set_disk_handle(const char *region, const char *fullpath);
425
426 void load_software_part_region(device_t &device, software_list_device &swlist, const char *swname, const rom_entry *start_region);
427
428 /* get search path for a software item */
429 static std::vector<std::string> get_software_searchpath(software_list_device &swlist, const software_info &swinfo);
430
431 /* open a disk image, searching up the parent and loading by checksum */
432 static chd_error open_disk_image(const emu_options &options, const device_t &device, const rom_entry *romp, chd_file &image_chd);
433 static chd_error open_disk_image(const emu_options &options, software_list_device &swlist, const software_info &swinfo, const rom_entry *romp, chd_file &image_chd);
434
435 private:
436 void determine_bios_rom(device_t &device, const char *specbios);
437 void count_roms();
438 void fill_random(u8 *base, u32 length);
439 void handle_missing_file(const rom_entry *romp, const std::vector<std::string> &tried_file_names, chd_error chderr);
440 void dump_wrong_and_correct_checksums(const util::hash_collection &hashes, const util::hash_collection &acthashes);
441 void verify_length_and_hash(emu_file *file, const char *name, u32 explength, const util::hash_collection &hashes);
442 void display_loading_rom_message(const char *name, bool from_list);
443 void display_rom_load_results(bool from_list);
444 void region_post_process(memory_region *region, bool invert);
445 std::unique_ptr<emu_file> open_rom_file(std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, const rom_entry *romp, std::vector<std::string> &tried_file_names, bool from_list);
446 std::unique_ptr<emu_file> open_rom_file(const std::vector<std::string> &paths, std::vector<std::string> &tried, bool has_crc, u32 crc, const std::string &name, osd_file::error &filerr);
447 int rom_fread(emu_file *file, u8 *buffer, int length, const rom_entry *parent_region);
448 int read_rom_data(emu_file *file, const rom_entry *parent_region, const rom_entry *romp);
449 void fill_rom_data(const rom_entry *romp);
450 void copy_rom_data(const rom_entry *romp);
451 void process_rom_entries(std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, u8 bios, const rom_entry *parent_region, const rom_entry *romp, bool from_list);
452 chd_error open_disk_diff(emu_options &options, const rom_entry *romp, chd_file &source, chd_file &diff_chd);
453 void process_disk_entries(std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, const char *regiontag, const rom_entry *romp, std::function<const rom_entry * ()> next_parent);
454 void normalize_flags_for_device(const char *rgntag, u8 &width, endianness_t &endian);
455 void process_region_list();
456
457 // internal state
458 running_machine & m_machine; // reference to our machine
459
460 int m_warnings; // warning count during processing
461 int m_knownbad; // BAD_DUMP/NO_DUMP count during processing
462 int m_errors; // error count during processing
463
464 int m_romsloaded; // current ROMs loaded count
465 int m_romstotal; // total number of ROMs to read
466 u64 m_romsloadedsize; // total size of ROMs loaded so far
467 u64 m_romstotalsize; // total size of ROMs to read
468
469 std::vector<std::unique_ptr<open_chd>> m_chd_list; /* disks */
470
471 memory_region * m_region; // info about current region
472
473 std::string m_errorstring; // error string
474 std::string m_softwarningstring; // software warning string
475 };
476
477
478 /* ----- Helpers ----- */
479
480 /* return pointer to the first ROM region within a source */
481 const rom_entry *rom_first_region(const device_t &device);
482 const rom_entry *rom_first_region(const rom_entry *romp);
483
484 /* return pointer to the next ROM region within a source */
485 const rom_entry *rom_next_region(const rom_entry *romp);
486
487 /* return pointer to the first ROM file within a region */
488 const rom_entry *rom_first_file(const rom_entry *romp);
489
490 /* return pointer to the next ROM file within a region */
491 const rom_entry *rom_next_file(const rom_entry *romp);
492
493 /* return the expected size of a file given the ROM description */
494 u32 rom_file_size(const rom_entry *romp);
495
496 /* return pointer to the first per-game parameter */
497 const rom_entry *rom_first_parameter(const device_t &device);
498
499 /* return pointer to the next per-game parameter */
500 const rom_entry *rom_next_parameter(const rom_entry *romp);
501
502 // builds a rom_entry vector from a tiny_rom_entry array
503 std::vector<rom_entry> rom_build_entries(const tiny_rom_entry *tinyentries);
504
505 #endif // MAME_EMU_ROMLOAD_H
506