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 ) |