1 // license:BSD-3-Clause
2 // copyright-holders:Nicola Salmoria,Aaron Giles
3 /*********************************************************************
4 
5     romentry.h
6 
7     ROM loading functions.
8 
9 *********************************************************************/
10 
11 #ifndef __EMU_H__
12 #error Dont include this file directly; include emu.h instead.
13 #endif
14 
15 #ifndef MAME_EMU_ROMENTRY_H
16 #define MAME_EMU_ROMENTRY_H
17 
18 #include "emucore.h"
19 #include "osdcomm.h"
20 
21 #include <string>
22 
23 
24 /***************************************************************************
25 CONSTANTS
26 ***************************************************************************/
27 
28 /* ----- type constants ----- */
29 #define ROMENTRY_TYPEMASK           0x0000000f          /* type of entry */
30 enum
31 {
32 	ROMENTRYTYPE_ROM = 0,       /* this entry is an actual ROM definition */
33 	ROMENTRYTYPE_REGION,        /* this entry marks the start of a region */
34 	ROMENTRYTYPE_END,           /* this entry marks the end of a region */
35 	ROMENTRYTYPE_RELOAD,        /* this entry reloads the previous ROM */
36 	ROMENTRYTYPE_CONTINUE,      /* this entry continues loading the previous ROM */
37 	ROMENTRYTYPE_FILL,          /* this entry fills an area with a constant value */
38 	ROMENTRYTYPE_COPY,          /* this entry copies data from another region/offset */
39 	ROMENTRYTYPE_CARTRIDGE,     /* this entry specifies a cartridge (MESS) */
40 	ROMENTRYTYPE_IGNORE,        /* this entry continues loading the previous ROM but throws the data away */
41 	ROMENTRYTYPE_SYSTEM_BIOS,   /* this entry specifies a bios */
42 	ROMENTRYTYPE_DEFAULT_BIOS,  /* this entry specifies a default bios */
43 	ROMENTRYTYPE_PARAMETER,     /* this entry specifies a per-game parameter */
44 	ROMENTRYTYPE_COUNT
45 };
46 
47 /* ----- per-region constants ----- */
48 #define ROMREGION_WIDTHMASK         0x00000300          /* native width of region, as power of 2 */
49 #define     ROMREGION_8BIT          0x00000000          /*    (non-CPU regions only) */
50 #define     ROMREGION_16BIT         0x00000100
51 #define     ROMREGION_32BIT         0x00000200
52 #define     ROMREGION_64BIT         0x00000300
53 
54 #define ROMREGION_ENDIANMASK        0x00000400          /* endianness of the region */
55 #define     ROMREGION_LE            0x00000000          /*    (non-CPU regions only) */
56 #define     ROMREGION_BE            0x00000400
57 
58 #define ROMREGION_INVERTMASK        0x00000800          /* invert the bits of the region */
59 #define     ROMREGION_NOINVERT      0x00000000
60 #define     ROMREGION_INVERT        0x00000800
61 
62 #define ROMREGION_ERASEMASK         0x00002000          /* erase the region before loading */
63 #define     ROMREGION_NOERASE       0x00000000
64 #define     ROMREGION_ERASE         0x00002000
65 
66 #define ROMREGION_DATATYPEMASK      0x00004000          /* type of region (ROM versus disk) */
67 #define     ROMREGION_DATATYPEROM   0x00000000
68 #define     ROMREGION_DATATYPEDISK  0x00004000
69 
70 #define ROMREGION_ERASEVALMASK      0x00ff0000          /* value to erase the region to */
71 #define     ROMREGION_ERASEVAL(x)   ((((x) & 0xff) << 16) | ROMREGION_ERASE)
72 #define     ROMREGION_ERASE00       ROMREGION_ERASEVAL(0)
73 #define     ROMREGION_ERASEFF       ROMREGION_ERASEVAL(0xff)
74 
75 
76 	/* ----- per-ROM constants ----- */
77 #define DISK_READONLYMASK           0x00000010          /* is the disk read-only? */
78 #define     DISK_READWRITE          0x00000000
79 #define     DISK_READONLY           0x00000010
80 
81 #define ROM_OPTIONALMASK            0x00000020          /* optional - won't hurt if it's not there */
82 #define     ROM_REQUIRED            0x00000000
83 #define     ROM_OPTIONAL            0x00000020
84 
85 #define ROM_REVERSEMASK             0x00000040          /* reverse the byte order within a group */
86 #define     ROM_NOREVERSE           0x00000000
87 #define     ROM_REVERSE             0x00000040
88 
89 #define ROM_INHERITFLAGSMASK        0x00000080          /* inherit all flags from previous definition */
90 #define     ROM_INHERITFLAGS        0x00000080
91 
92 #define ROM_GROUPMASK               0x00000f00          /* load data in groups of this size + 1 */
93 #define     ROM_GROUPSIZE(n)        ((((n) - 1) & 15) << 8)
94 #define     ROM_GROUPBYTE           ROM_GROUPSIZE(1)
95 #define     ROM_GROUPWORD           ROM_GROUPSIZE(2)
96 #define     ROM_GROUPDWORD          ROM_GROUPSIZE(4)
97 
98 #define ROM_SKIPMASK                0x0000f000          /* skip this many bytes after each group */
99 #define     ROM_SKIP(n)             (((n) & 15) << 12)
100 #define     ROM_NOSKIP              ROM_SKIP(0)
101 
102 #define ROM_BITWIDTHMASK            0x000f0000          /* width of data in bits */
103 #define     ROM_BITWIDTH(n)         (((n) & 15) << 16)
104 #define     ROM_NIBBLE              ROM_BITWIDTH(4)
105 #define     ROM_FULLBYTE            ROM_BITWIDTH(8)
106 
107 #define ROM_BITSHIFTMASK            0x00f00000          /* left-shift count for the bits */
108 #define     ROM_BITSHIFT(n)         (((n) & 15) << 20)
109 #define     ROM_NOSHIFT             ROM_BITSHIFT(0)
110 #define     ROM_SHIFT_NIBBLE_LO     ROM_BITSHIFT(0)
111 #define     ROM_SHIFT_NIBBLE_HI     ROM_BITSHIFT(4)
112 
113 #define ROM_BIOSFLAGSMASK           0xff000000          /* only loaded if value matches device bios value */
114 #define     ROM_BIOS(n)             ((((n) + 1) & 255) << 24)
115 
116 #define ROM_INHERITEDFLAGS          (ROM_GROUPMASK | ROM_SKIPMASK | ROM_REVERSEMASK | ROM_BITWIDTHMASK | ROM_BITSHIFTMASK | ROM_BIOSFLAGSMASK)
117 
118 
119 /* ----- start/stop macros ----- */
120 #define ROM_NAME(name)                              rom_##name
121 #define ROM_START(name)                             static const tiny_rom_entry ROM_NAME(name)[] = {
122 #define ROM_END                                     { nullptr, nullptr, 0, 0, ROMENTRYTYPE_END } };
123 
124 
125 /* ----- ROM region macros ----- */
126 #define ROM_REGION(length,tag,flags)                { tag, nullptr, 0, length, ROMENTRYTYPE_REGION | (flags) },
127 #define ROM_REGION16_LE(length,tag,flags)           ROM_REGION(length, tag, (flags) | ROMREGION_16BIT | ROMREGION_LE)
128 #define ROM_REGION16_BE(length,tag,flags)           ROM_REGION(length, tag, (flags) | ROMREGION_16BIT | ROMREGION_BE)
129 #define ROM_REGION32_LE(length,tag,flags)           ROM_REGION(length, tag, (flags) | ROMREGION_32BIT | ROMREGION_LE)
130 #define ROM_REGION32_BE(length,tag,flags)           ROM_REGION(length, tag, (flags) | ROMREGION_32BIT | ROMREGION_BE)
131 #define ROM_REGION64_LE(length,tag,flags)           ROM_REGION(length, tag, (flags) | ROMREGION_64BIT | ROMREGION_LE)
132 #define ROM_REGION64_BE(length,tag,flags)           ROM_REGION(length, tag, (flags) | ROMREGION_64BIT | ROMREGION_BE)
133 
134 
135 /* ----- core ROM loading macros ----- */
136 #define ROMX_LOAD(name,offset,length,hash,flags)    { name, hash, offset, length, ROMENTRYTYPE_ROM | (flags) },
137 #define ROM_LOAD(name,offset,length,hash)           ROMX_LOAD(name, offset, length, hash, 0)
138 #define ROM_LOAD_OPTIONAL(name,offset,length,hash)  ROMX_LOAD(name, offset, length, hash, ROM_OPTIONAL)
139 
140 
141 /* ----- specialized loading macros ----- */
142 #define ROM_LOAD_NIB_HIGH(name,offset,length,hash)      ROMX_LOAD(name, offset, length, hash, ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI)
143 #define ROM_LOAD_NIB_LOW(name,offset,length,hash)       ROMX_LOAD(name, offset, length, hash, ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO)
144 #define ROM_LOAD16_BYTE(name,offset,length,hash)        ROMX_LOAD(name, offset, length, hash, ROM_SKIP(1))
145 #define ROM_LOAD16_WORD(name,offset,length,hash)        ROM_LOAD(name, offset, length, hash)
146 #define ROM_LOAD16_WORD_SWAP(name,offset,length,hash)   ROMX_LOAD(name, offset, length, hash, ROM_GROUPWORD | ROM_REVERSE)
147 #define ROM_LOAD32_BYTE(name,offset,length,hash)        ROMX_LOAD(name, offset, length, hash, ROM_SKIP(3))
148 #define ROM_LOAD32_WORD(name,offset,length,hash)        ROMX_LOAD(name, offset, length, hash, ROM_GROUPWORD | ROM_SKIP(2))
149 #define ROM_LOAD32_WORD_SWAP(name,offset,length,hash)   ROMX_LOAD(name, offset, length, hash, ROM_GROUPWORD | ROM_REVERSE | ROM_SKIP(2))
150 #define ROM_LOAD32_DWORD(name,offset,length,hash)       ROMX_LOAD(name, offset, length, hash, ROM_GROUPDWORD)
151 #define ROM_LOAD64_BYTE(name,offset,length,hash)        ROMX_LOAD(name, offset, length, hash, ROM_SKIP(7))
152 #define ROM_LOAD64_WORD(name,offset,length,hash)        ROMX_LOAD(name, offset, length, hash, ROM_GROUPWORD | ROM_SKIP(6))
153 #define ROM_LOAD64_WORD_SWAP(name,offset,length,hash)   ROMX_LOAD(name, offset, length, hash, ROM_GROUPWORD | ROM_REVERSE | ROM_SKIP(6))
154 #define ROM_LOAD64_DWORD_SWAP(name,offset,length,hash)  ROMX_LOAD(name, offset, length, hash, ROM_GROUPDWORD | ROM_REVERSE | ROM_SKIP(4))
155 
156 
157 /* ----- ROM_RELOAD related macros ----- */
158 #define ROM_RELOAD(offset,length)                   { nullptr, nullptr, offset, length, ROMENTRYTYPE_RELOAD | ROM_INHERITFLAGS },
159 #define ROM_RELOAD_PLAIN(offset,length)             { nullptr, nullptr, offset, length, ROMENTRYTYPE_RELOAD },
160 
161 /* ----- additional ROM-related macros ----- */
162 #define ROM_CONTINUE(offset,length)                 { nullptr,  nullptr,                 (offset), (length), ROMENTRYTYPE_CONTINUE | ROM_INHERITFLAGS },
163 #define ROM_IGNORE(length)                          { nullptr,  nullptr,                 0,        (length), ROMENTRYTYPE_IGNORE | ROM_INHERITFLAGS },
164 #define ROM_FILL(offset,length,value)               { nullptr,  (const char *)(value),   (offset), (length), ROMENTRYTYPE_FILL },
165 #define ROMX_FILL(offset,length,value,flags)        { nullptr,  (const char *)(value),   (offset), (length), ROMENTRYTYPE_FILL | flags },
166 #define ROM_COPY(srctag,srcoffs,offset,length)      { (srctag), (const char *)(srcoffs), (offset), (length), ROMENTRYTYPE_COPY },
167 
168 
169 /* ----- system BIOS macros ----- */
170 #define ROM_SYSTEM_BIOS(value,name,description)     { name, description, 0, 0, ROMENTRYTYPE_SYSTEM_BIOS | ROM_BIOS(value) },
171 #define ROM_DEFAULT_BIOS(name)                      { name, nullptr,     0, 0, ROMENTRYTYPE_DEFAULT_BIOS },
172 
173 
174 /* ----- game parameter macro ----- */
175 #define ROM_PARAMETER(tag, value)                   { tag, value, 0, 0, ROMENTRYTYPE_PARAMETER },
176 
177 /* ----- disk loading macros ----- */
178 #define DISK_REGION(tag)                            ROM_REGION(1, tag, ROMREGION_DATATYPEDISK)
179 #define DISK_IMAGE(name,idx,hash)                   ROMX_LOAD(name, idx, 0, hash, DISK_READWRITE)
180 #define DISK_IMAGE_READONLY(name,idx,hash)          ROMX_LOAD(name, idx, 0, hash, DISK_READONLY)
181 #define DISK_IMAGE_READONLY_OPTIONAL(name,idx,hash) ROMX_LOAD(name, idx, 0, hash, DISK_READONLY | ROM_OPTIONAL)
182 
183 
184 
185 //**************************************************************************
186 //  TYPE DEFINITIONS
187 //**************************************************************************
188 
189 // ======================> tiny_rom_entry
190 
191 struct tiny_rom_entry
192 {
193 	char const *name;
194 	char const *hashdata;
195 	u32         offset;
196 	u32         length;
197 	u32         flags;
198 
get_offsettiny_rom_entry199 	constexpr u32 get_offset() const { return offset; }
get_lengthtiny_rom_entry200 	constexpr u32 get_length() const { return length; }
get_flagstiny_rom_entry201 	constexpr u32 get_flags() const { return flags; }
202 };
203 
204 
205 // ======================> rom_entry
206 
207 class rom_entry
208 {
209 public:
210 	rom_entry(const tiny_rom_entry &ent);
211 	rom_entry(std::string &&name, std::string &&hashdata, u32 offset, u32 length, u32 flags);
212 	rom_entry(rom_entry const &) = default;
213 	rom_entry(rom_entry &&) = default;
214 	rom_entry &operator=(rom_entry const &) = default;
215 	rom_entry &operator=(rom_entry &&) = default;
216 
217 	// accessors
name()218 	std::string const &name() const { return m_name; }
hashdata()219 	std::string const &hashdata() const { return m_hashdata; }
get_offset()220 	u32 get_offset() const { return m_offset; }
get_length()221 	u32 get_length() const { return m_length; }
get_flags()222 	u32 get_flags() const { return m_flags; }
set_flags(u32 flags)223 	void set_flags(u32 flags) { m_flags = flags; }
224 
225 private:
226 	std::string     m_name;
227 	std::string     m_hashdata;
228 	u32             m_offset;
229 	u32             m_length;
230 	u32             m_flags;
231 };
232 
233 
234 #endif // MAME_EMU_ROMENTRY_H
235