trunk/src/emu/imagedev/cartslot.c
r32643 | r32644 | |
1 | | /********************************************************************** |
2 | | |
3 | | cartslot.c |
4 | | |
5 | | Cartridge device |
6 | | |
7 | | **********************************************************************/ |
8 | | |
9 | | #include <ctype.h> |
10 | | #include "emu.h" |
11 | | #include "cartslot.h" |
12 | | |
13 | | |
14 | | // device type definition |
15 | | const device_type CARTSLOT = &device_creator<cartslot_image_device>; |
16 | | |
17 | | //------------------------------------------------- |
18 | | // cartslot_image_device - constructor |
19 | | //------------------------------------------------- |
20 | | |
21 | | cartslot_image_device::cartslot_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
22 | | : device_t(mconfig, CARTSLOT, "Cartslot", tag, owner, clock, "cartslot_image", __FILE__), |
23 | | device_image_interface(mconfig, *this), |
24 | | m_extensions("bin"), |
25 | | m_interface(NULL), |
26 | | m_must_be_loaded(0), |
27 | | m_device_image_partialhash(NULL) |
28 | | { |
29 | | } |
30 | | |
31 | | //------------------------------------------------- |
32 | | // cartslot_image_device - destructor |
33 | | //------------------------------------------------- |
34 | | |
35 | | cartslot_image_device::~cartslot_image_device() |
36 | | { |
37 | | } |
38 | | |
39 | | //------------------------------------------------- |
40 | | // device_config_complete - perform any |
41 | | // operations now that the configuration is |
42 | | // complete |
43 | | //------------------------------------------------- |
44 | | |
45 | | void cartslot_image_device::device_config_complete() |
46 | | { |
47 | | // set brief and instance name |
48 | | update_names(); |
49 | | } |
50 | | |
51 | | /*************************************************************************** |
52 | | IMPLEMENTATION |
53 | | ***************************************************************************/ |
54 | | |
55 | | /*------------------------------------------------- |
56 | | load_cartridge |
57 | | -------------------------------------------------*/ |
58 | | |
59 | | int cartslot_image_device::load_cartridge(const rom_entry *romrgn, const rom_entry *roment, bool load) |
60 | | { |
61 | | const char *region; |
62 | | const char *type; |
63 | | UINT32 flags; |
64 | | offs_t offset, size, read_length, pos = 0, len; |
65 | | UINT8 *ptr; |
66 | | UINT8 clear_val; |
67 | | int datawidth, littleendian, i, j; |
68 | | device_t *cpu; |
69 | | |
70 | | astring regiontag; |
71 | | device().siblingtag(regiontag, ROMREGION_GETTAG(romrgn)); |
72 | | region = regiontag.cstr(); |
73 | | offset = ROM_GETOFFSET(roment); |
74 | | size = ROM_GETLENGTH(roment); |
75 | | flags = ROM_GETFLAGS(roment); |
76 | | ptr = ((UINT8 *) device().machine().root_device().memregion(region)->base()) + offset; |
77 | | |
78 | | if (load) |
79 | | { |
80 | | if (software_entry() == NULL) |
81 | | { |
82 | | /* must this be full size */ |
83 | | if (flags & ROM_FULLSIZE) |
84 | | { |
85 | | if (length() != size) |
86 | | return IMAGE_INIT_FAIL; |
87 | | } |
88 | | |
89 | | /* read the ROM */ |
90 | | pos = read_length = fread(ptr, size); |
91 | | |
92 | | /* reset the ROM to the initial point. */ |
93 | | /* eventually, we could add a flag to allow the ROM to continue instead of restarting whenever a new cart region is present */ |
94 | | fseek(0, SEEK_SET); |
95 | | } |
96 | | else |
97 | | { |
98 | | /* must this be full size */ |
99 | | if (flags & ROM_FULLSIZE) |
100 | | { |
101 | | if (get_software_region_length("rom") != size) |
102 | | return IMAGE_INIT_FAIL; |
103 | | } |
104 | | |
105 | | /* read the ROM */ |
106 | | pos = read_length = get_software_region_length("rom"); |
107 | | memcpy(ptr, get_software_region("rom"), read_length); |
108 | | } |
109 | | |
110 | | /* do we need to mirror the ROM? */ |
111 | | if (flags & ROM_MIRROR) |
112 | | { |
113 | | while(pos < size) |
114 | | { |
115 | | len = MIN(read_length, size - pos); |
116 | | memcpy(ptr + pos, ptr, len); |
117 | | pos += len; |
118 | | } |
119 | | } |
120 | | |
121 | | /* postprocess this region */ |
122 | | type = regiontag.cstr(); |
123 | | littleendian = ROMREGION_ISLITTLEENDIAN(romrgn); |
124 | | datawidth = ROMREGION_GETWIDTH(romrgn) / 8; |
125 | | |
126 | | /* if the region is inverted, do that now */ |
127 | | device_memory_interface *memory; |
128 | | cpu = device().machine().device(type); |
129 | | if (cpu!=NULL && cpu->interface(memory)) |
130 | | { |
131 | | datawidth = cpu->memory().space_config(AS_PROGRAM)->m_databus_width / 8; |
132 | | littleendian = (cpu->memory().space_config()->m_endianness == ENDIANNESS_LITTLE); |
133 | | } |
134 | | |
135 | | /* swap the endianness if we need to */ |
136 | | #ifdef LSB_FIRST |
137 | | if (datawidth > 1 && !littleendian) |
138 | | #else |
139 | | if (datawidth > 1 && littleendian) |
140 | | #endif |
141 | | { |
142 | | for (i = 0; i < size; i += datawidth) |
143 | | { |
144 | | UINT8 temp[8]; |
145 | | memcpy(temp, &ptr[i], datawidth); |
146 | | for (j = datawidth - 1; j >= 0; j--) |
147 | | ptr[i + j] = temp[datawidth - 1 - j]; |
148 | | } |
149 | | } |
150 | | } |
151 | | |
152 | | /* clear out anything that remains */ |
153 | | if (!(flags & ROM_NOCLEAR)) |
154 | | { |
155 | | clear_val = (flags & ROM_FILL_FF) ? 0xFF : 0x00; |
156 | | memset(ptr + pos, clear_val, size - pos); |
157 | | } |
158 | | return IMAGE_INIT_PASS; |
159 | | } |
160 | | |
161 | | |
162 | | |
163 | | /*------------------------------------------------- |
164 | | process_cartridge |
165 | | -------------------------------------------------*/ |
166 | | |
167 | | int cartslot_image_device::process_cartridge(bool load) |
168 | | { |
169 | | const rom_entry *romrgn, *roment; |
170 | | int result = 0; |
171 | | |
172 | | device_iterator deviter(device().mconfig().root_device()); |
173 | | for (device_t *device = deviter.first(); device != NULL; device = deviter.next()) |
174 | | for (romrgn = rom_first_region(*device); romrgn != NULL; romrgn = rom_next_region(romrgn)) |
175 | | { |
176 | | roment = romrgn + 1; |
177 | | while(!ROMENTRY_ISREGIONEND(roment)) |
178 | | { |
179 | | if (ROMENTRY_GETTYPE(roment) == ROMENTRYTYPE_CARTRIDGE) |
180 | | { |
181 | | astring regiontag; |
182 | | this->device().siblingtag(regiontag, roment->_hashdata); |
183 | | |
184 | | if (strcmp(regiontag.cstr(),this->device().tag())==0) |
185 | | { |
186 | | result |= load_cartridge(romrgn, roment, load); |
187 | | |
188 | | /* if loading failed in any cart region, stop loading */ |
189 | | if (result) |
190 | | return result; |
191 | | } |
192 | | } |
193 | | roment++; |
194 | | } |
195 | | } |
196 | | |
197 | | return IMAGE_INIT_PASS; |
198 | | } |
199 | | |
200 | | //------------------------------------------------- |
201 | | // device_start - device-specific startup |
202 | | //------------------------------------------------- |
203 | | |
204 | | void cartslot_image_device::device_start() |
205 | | { |
206 | | } |
207 | | |
208 | | |
209 | | /*------------------------------------------------- |
210 | | call_load |
211 | | -------------------------------------------------*/ |
212 | | |
213 | | bool cartslot_image_device::call_load() |
214 | | { |
215 | | /* if this cartridge has a custom DEVICE_IMAGE_LOAD, use it */ |
216 | | if (!m_device_image_load.isnull()) |
217 | | return m_device_image_load(*this); |
218 | | |
219 | | /* otherwise try the normal route */ |
220 | | return process_cartridge(true); |
221 | | } |
222 | | |
223 | | |
224 | | /*------------------------------------------------- |
225 | | call_unload |
226 | | -------------------------------------------------*/ |
227 | | void cartslot_image_device::call_unload() |
228 | | { |
229 | | /* if this cartridge has a custom DEVICE_IMAGE_UNLOAD, use it */ |
230 | | if (!m_device_image_unload.isnull()) |
231 | | { |
232 | | m_device_image_unload(*this); |
233 | | return; |
234 | | } |
235 | | process_cartridge(false); |
236 | | } |
trunk/src/emu/imagedev/cartslot.h
r32643 | r32644 | |
1 | | /*************************************************************************** |
2 | | |
3 | | Cartrige loading |
4 | | |
5 | | ***************************************************************************/ |
6 | | |
7 | | #ifndef __CARTSLOT_H__ |
8 | | #define __CARTSLOT_H__ |
9 | | |
10 | | |
11 | | |
12 | | /*************************************************************************** |
13 | | MACROS |
14 | | ***************************************************************************/ |
15 | | #define ROM_CART_LOAD(tag,offset,length,flags) \ |
16 | | { NULL, tag, offset, length, ROMENTRYTYPE_CARTRIDGE | (flags) }, |
17 | | |
18 | | #define ROM_MIRROR 0x01000000 |
19 | | #define ROM_NOMIRROR 0x00000000 |
20 | | #define ROM_FULLSIZE 0x02000000 |
21 | | #define ROM_FILL_FF 0x04000000 |
22 | | #define ROM_NOCLEAR 0x08000000 |
23 | | |
24 | | /*************************************************************************** |
25 | | TYPE DEFINITIONS |
26 | | ***************************************************************************/ |
27 | | |
28 | | // ======================> cartslot_image_device |
29 | | |
30 | | class cartslot_image_device : public device_t, |
31 | | public device_image_interface |
32 | | { |
33 | | public: |
34 | | // construction/destruction |
35 | | cartslot_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
36 | | virtual ~cartslot_image_device(); |
37 | | |
38 | | static void static_set_device_load(device_t &device, device_image_load_delegate callback) { downcast<cartslot_image_device &>(device).m_device_image_load = callback; } |
39 | | static void static_set_device_unload(device_t &device, device_image_func_delegate callback) { downcast<cartslot_image_device &>(device).m_device_image_unload = callback; } |
40 | | static void static_set_partialhash(device_t &device, device_image_partialhash_func callback) { downcast<cartslot_image_device &>(device).m_device_image_partialhash = callback; } |
41 | | |
42 | | static void static_set_extensions(device_t &device, const char *_extensions) { downcast<cartslot_image_device &>(device).m_extensions = _extensions; } |
43 | | static void static_set_interface(device_t &device, const char *_interface) { downcast<cartslot_image_device &>(device).m_interface = _interface; } |
44 | | static void static_set_must_be_loaded(device_t &device, bool _must_be_loaded) { downcast<cartslot_image_device &>(device).m_must_be_loaded = _must_be_loaded; } |
45 | | |
46 | | // image-level overrides |
47 | | virtual bool call_load(); |
48 | | virtual void call_unload(); |
49 | | virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) { load_software_part_region( *this, swlist, swname, start_entry ); return TRUE; } |
50 | | virtual device_image_partialhash_func get_partial_hash() const { return m_device_image_partialhash; } |
51 | | |
52 | | virtual iodevice_t image_type() const { return IO_CARTSLOT; } |
53 | | |
54 | | virtual bool is_readable() const { return 1; } |
55 | | virtual bool is_writeable() const { return 0; } |
56 | | virtual bool is_creatable() const { return 0; } |
57 | | virtual bool must_be_loaded() const { return m_must_be_loaded; } |
58 | | virtual bool is_reset_on_load() const { return 1; } |
59 | | virtual const char *image_interface() const { return m_interface; } |
60 | | virtual const char *file_extensions() const { return m_extensions; } |
61 | | virtual const option_guide *create_option_guide() const { return NULL; } |
62 | | |
63 | | protected: |
64 | | // device-level overrides |
65 | | virtual void device_config_complete(); |
66 | | virtual void device_start(); |
67 | | |
68 | | int load_cartridge(const rom_entry *romrgn, const rom_entry *roment, bool load); |
69 | | int process_cartridge(bool load); |
70 | | |
71 | | |
72 | | const char * m_extensions; |
73 | | const char * m_interface; |
74 | | bool m_must_be_loaded; |
75 | | device_image_load_delegate m_device_image_load; |
76 | | device_image_func_delegate m_device_image_unload; |
77 | | device_image_partialhash_func m_device_image_partialhash; |
78 | | }; |
79 | | |
80 | | // device type definition |
81 | | extern const device_type CARTSLOT; |
82 | | |
83 | | /*************************************************************************** |
84 | | DEVICE CONFIGURATION MACROS |
85 | | ***************************************************************************/ |
86 | | |
87 | | #define MCFG_CARTSLOT_ADD(_tag) \ |
88 | | MCFG_DEVICE_ADD(_tag, CARTSLOT, 0) |
89 | | #define MCFG_CARTSLOT_MODIFY(_tag) \ |
90 | | MCFG_DEVICE_MODIFY(_tag) |
91 | | |
92 | | #define MCFG_CARTSLOT_EXTENSION_LIST(_extensions) \ |
93 | | cartslot_image_device::static_set_extensions(*device, _extensions); |
94 | | |
95 | | #define MCFG_CARTSLOT_INTERFACE(_interface) \ |
96 | | cartslot_image_device::static_set_interface(*device, _interface); |
97 | | |
98 | | #define MCFG_CARTSLOT_NOT_MANDATORY \ |
99 | | cartslot_image_device::static_set_must_be_loaded(*device, FALSE); |
100 | | |
101 | | #define MCFG_CARTSLOT_MANDATORY \ |
102 | | cartslot_image_device::static_set_must_be_loaded(*device, TRUE); |
103 | | |
104 | | #define MCFG_CARTSLOT_LOAD(_class,_method) \ |
105 | | cartslot_image_device::static_set_device_load(*device, device_image_load_delegate(&DEVICE_IMAGE_LOAD_NAME(_class,_method), #_class "::device_image_load_" #_method, downcast<_class *>(owner))); |
106 | | |
107 | | #define MCFG_CARTSLOT_UNLOAD(_class,_method) \ |
108 | | cartslot_image_device::static_set_device_unload(*device, device_image_func_delegate(&DEVICE_IMAGE_UNLOAD_NAME(_class,_method), #_class "::device_image_unload_" #_method, downcast<_class *>(owner))); |
109 | | |
110 | | #define MCFG_CARTSLOT_PARTIALHASH(_partialhash) \ |
111 | | cartslot_image_device::static_set_partialhash(*device, _partialhash); |
112 | | |
113 | | #endif /* __CARTSLOT_H__ */ |
trunk/src/mess/drivers/plus4.c
r32643 | r32644 | |
13 | 13 | */ |
14 | 14 | |
15 | 15 | #include "includes/plus4.h" |
16 | | #include "imagedev/cartslot.h" |
17 | 16 | #include "machine/cbm_snqk.h" |
18 | 17 | #include "sound/t6721a.h" |
19 | 18 | |
r32643 | r32644 | |
934 | 933 | ROM_LOAD( "basic-264.bin", 0x0000, 0x4000, CRC(6a2fc8e3) SHA1(473fce23afa07000cdca899fbcffd6961b36a8a0) ) |
935 | 934 | ROM_LOAD( "kernal-264.bin", 0x4000, 0x4000, CRC(8f32abe7) SHA1(d481faf5fcbb331878dc7851c642d04f26a32873) ) |
936 | 935 | |
937 | | ROM_REGION( 0x8000, "function", 0 ) |
938 | | ROM_CART_LOAD( "lo", 0x0000, 0x0000, ROM_NOMIRROR ) |
939 | | ROM_CART_LOAD( "hi", 0x4000, 0x0000, ROM_NOMIRROR ) |
| 936 | ROM_REGION( 0x8000, "function", ROMREGION_ERASE00 ) |
| 937 | // TODO: add cart slots to mount EPROMs here |
940 | 938 | |
941 | 939 | ROM_REGION( 0xf5, PLA_TAG, 0 ) |
942 | 940 | ROM_LOAD( "251641-02", 0x00, 0xf5, NO_DUMP ) |
r32643 | r32644 | |
952 | 950 | ROM_LOAD( "318006-01.u4", 0x0000, 0x4000, CRC(74eaae87) SHA1(161c96b4ad20f3a4f2321808e37a5ded26a135dd) ) |
953 | 951 | ROM_LOAD( "318004-01.u5", 0x4000, 0x4000, CRC(dbdc3319) SHA1(3c77caf72914c1c0a0875b3a7f6935cd30c54201) ) |
954 | 952 | |
955 | | ROM_REGION( 0x8000, "function", 0 ) |
956 | | ROM_CART_LOAD( "lo", 0x0000, 0x0000, ROM_NOMIRROR ) |
957 | | ROM_CART_LOAD( "hi", 0x4000, 0x0000, ROM_NOMIRROR ) |
| 953 | ROM_REGION( 0x8000, "function", ROMREGION_ERASE00 ) |
| 954 | // TODO: add cart slots to mount EPROMs here |
958 | 955 | |
959 | 956 | ROM_REGION( 0xf5, PLA_TAG, 0 ) |
960 | 957 | ROM_LOAD( "251641-02.u7", 0x00, 0xf5, NO_DUMP ) |