1 // license:BSD-3-Clause
2 // copyright-holders:Fabio Priuli,Cowering
3 /***********************************************************************************************************
4 
5 
6     SNES cart emulation
7     (through slot devices)
8 
9 
10     Carts can be mapped in memory in several different ways and accesses to carts depend
11     on the presence of add-on chips (which map their I/O to diff memory areas)
12 
13     Hence, carts can interface with the main system through the following handlers
14     * read_l : typically used to read ROM from memory range [00-7f][0000-ffff]
15     * read_h : typically used to read ROM from memory range [80-ff][0000-ffff]
16     * read_ram : used to read (NV)RAM at the appropriate offset (masks has to be applied
17                  *before* calling it, if dealing with >32K RAM)
18     * write_ram : used to write (NV)RAM at the appropriate offset
19     * read_chip : used to read add-on chip registers
20     * write_chip : used to write to add-on chip registers
21 
22     Also, we define two additional ROM access handlers, write_l & write_h for carts with
23     subslots (e.g. BS-X compatible ones), that need to write to subslot (NV)RAM independently
24     to accesses to their own (NV)RAM.
25 
26     Notes about add-on detection and handling (useful for future addition of st018, cx4, etc.)
27     ===============================================================================================
28     When loading from softlist, m_type would be enough to take care of add-on chips, because
29     the ones needing a CPU dump have it in the zipfile. However, to support these games also
30     from fullpath, both with files having DSP data appended to the .sfc and with older dumps
31     missing DSP data, a second variable is present in the SNES slot: m_addon.
32     From fullpath, support works as follows
33     - get_default_card_software needs to decide whether to use the main devices or the legacy
34       ones containing DSP dump as device roms, so it gets m_type as the main device should be
35       used and if m_addon is ADDON_DSP* or ADDON_ST*, then it checks if the DSP data is appended
36       or if m_type has to be switched to legacy type
37     - call_load needs to detect faulty dumps too, to alloc m_addon_bios and copy the data from
38       the correct place, so if m_addon is ADDON_DSP* or ADDON_ST* it checks whether DSP data is
39       appended or not: if it is, this data is copied to m_addon_bios; if not, then we are in
40       the legacy device case and data is copied from the device rom
41     After the cart has been loaded and emulation has started, only m_type is needed to later
42     handlers installation and cart accesses
43 
44     Also notice that, from softlist, DSP1, 1B, 2, 3 are treated as the same device, because they
45     all have the same I/O and the only difference (i.e. the DSP data) comes from the zipfile itself.
46     OTOH, to support faulty dumps missing DSP content, we need separate legacy devices...
47 
48 
49  ***********************************************************************************************************/
50 
51 
52 #include "emu.h"
53 #include "snes_slot.h"
54 
55 //**************************************************************************
56 //  GLOBAL VARIABLES
57 //**************************************************************************
58 
59 DEFINE_DEVICE_TYPE(SNS_CART_SLOT,        sns_cart_slot_device,        "sns_cart_slot",        "SNES Cartridge Slot")
60 DEFINE_DEVICE_TYPE(SNS_SUFAMI_CART_SLOT, sns_sufami_cart_slot_device, "sns_sufami_cart_slot", "SNES Sufami Turbo Cartridge Slot")
61 DEFINE_DEVICE_TYPE(SNS_BSX_CART_SLOT,    sns_bsx_cart_slot_device,    "sns_bsx_cart_slot",    "SNES BS-X Cartridge Slot")
62 
63 //**************************************************************************
64 //    SNES Cartridge Interface
65 //**************************************************************************
66 
67 //-------------------------------------------------
68 //  device_sns_cart_interface - constructor
69 //-------------------------------------------------
70 
device_sns_cart_interface(const machine_config & mconfig,device_t & device)71 device_sns_cart_interface::device_sns_cart_interface(const machine_config &mconfig, device_t &device) :
72 	device_interface(device, "snescart"),
73 	m_rom(nullptr),
74 	m_rom_size(0),
75 	m_slot(nullptr)
76 {
77 }
78 
79 
80 //-------------------------------------------------
81 //  ~device_sns_cart_interface - destructor
82 //-------------------------------------------------
83 
~device_sns_cart_interface()84 device_sns_cart_interface::~device_sns_cart_interface()
85 {
86 }
87 
88 //-------------------------------------------------
89 //  rom_alloc - alloc the space for the cart
90 //-------------------------------------------------
91 
rom_alloc(uint32_t size,const char * tag)92 void device_sns_cart_interface::rom_alloc(uint32_t size, const char *tag)
93 {
94 	if (m_rom == nullptr)
95 	{
96 		m_rom = device().machine().memory().region_alloc(std::string(tag).append(SNSSLOT_ROM_REGION_TAG).c_str(), size, 1, ENDIANNESS_LITTLE)->base();
97 		m_rom_size = size;
98 	}
99 }
100 
101 
102 //-------------------------------------------------
103 //  nvram_alloc - alloc the space for the nvram
104 //-------------------------------------------------
105 
nvram_alloc(uint32_t size)106 void device_sns_cart_interface::nvram_alloc(uint32_t size)
107 {
108 	m_nvram.resize(size);
109 }
110 
111 
112 //-------------------------------------------------
113 //  rtc_ram_alloc - alloc the space for the rtc_ram
114 //  (needed to save it to NVRAM, will be removed
115 //  once the RTCs become devices and NVRAM gets
116 //  saved by the device itself)
117 //-------------------------------------------------
118 
rtc_ram_alloc(uint32_t size)119 void device_sns_cart_interface::rtc_ram_alloc(uint32_t size)
120 {
121 	m_rtc_ram.resize(size);
122 }
123 
124 
125 //-------------------------------------------------
126 //  addon_bios_alloc - alloc the space for the
127 //  (optional) add-on CPU bios
128 //-------------------------------------------------
129 
addon_bios_alloc(uint32_t size)130 void device_sns_cart_interface::addon_bios_alloc(uint32_t size)
131 {
132 	m_bios.resize(size);
133 }
134 
135 
136 //-------------------------------------------------
137 //  rom_map_setup - setup map of rom banks in 32K
138 //  blocks, so to simplify ROM access
139 //-------------------------------------------------
140 
rom_map_setup(uint32_t size)141 void device_sns_cart_interface::rom_map_setup(uint32_t size)
142 {
143 	int i;
144 	// setup the rom_bank_map array to faster ROM read
145 	for (i = 0; i < size / 0x8000; i++)
146 		rom_bank_map[i] = i;
147 
148 	// fill up remaining blocks with mirrors
149 	while (i % 256)
150 	{
151 		int j = 0, repeat_banks;
152 		while ((i % (256 >> j)) && j < 8)
153 			j++;
154 		repeat_banks = i % (256 >> (j - 1));
155 		for (int k = 0; k < repeat_banks; k++)
156 			rom_bank_map[i + k] = rom_bank_map[i + k - repeat_banks];
157 		i += repeat_banks;
158 	}
159 
160 // check bank map!
161 //  for (i = 0; i < 256; i++)
162 //  {
163 //      printf("bank %3d = %3d\t", i, rom_bank_map[i]);
164 //      if ((i%8) == 7)
165 //          printf("\n");
166 //  }
167 }
168 
169 
170 //-------------------------------------------------
171 //  write_irq - set the cart IRQ output
172 //-------------------------------------------------
173 
WRITE_LINE_MEMBER(device_sns_cart_interface::write_irq)174 WRITE_LINE_MEMBER(device_sns_cart_interface::write_irq)
175 {
176 	if (m_slot != nullptr)
177 		m_slot->write_irq(state);
178 }
179 
180 //-------------------------------------------------
181 //  read_open_bus - read from the open bus
182 //-------------------------------------------------
183 
read_open_bus()184 uint8_t device_sns_cart_interface::read_open_bus()
185 {
186 	if (m_slot != nullptr)
187 		return m_slot->read_open_bus();
188 
189 	return 0xff;
190 }
191 
192 //**************************************************************************
193 //  LIVE DEVICE
194 //**************************************************************************
195 
196 //-------------------------------------------------
197 //  base_sns_cart_slot_device - constructor
198 //-------------------------------------------------
base_sns_cart_slot_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)199 base_sns_cart_slot_device::base_sns_cart_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
200 	device_t(mconfig, type, tag, owner, clock),
201 	device_image_interface(mconfig, *this),
202 	device_slot_interface(mconfig, *this),
203 	m_addon(ADDON_NONE),
204 	m_type(SNES_MODE20),
205 	m_cart(nullptr),
206 	m_irq_callback(*this),
207 	m_open_bus_callback(*this)
208 {
209 }
210 
sns_cart_slot_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)211 sns_cart_slot_device::sns_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
212 	base_sns_cart_slot_device(mconfig, SNS_CART_SLOT, tag, owner, clock)
213 {
214 }
215 
sns_sufami_cart_slot_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)216 sns_sufami_cart_slot_device::sns_sufami_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
217 	base_sns_cart_slot_device(mconfig, SNS_SUFAMI_CART_SLOT, tag, owner, clock)
218 {
219 }
220 
sns_bsx_cart_slot_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)221 sns_bsx_cart_slot_device::sns_bsx_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
222 	base_sns_cart_slot_device(mconfig, SNS_BSX_CART_SLOT, tag, owner, clock)
223 {
224 }
225 
226 //-------------------------------------------------
227 //  base_sns_cart_slot_device - destructor
228 //-------------------------------------------------
229 
~base_sns_cart_slot_device()230 base_sns_cart_slot_device::~base_sns_cart_slot_device()
231 {
232 }
233 
234 //-------------------------------------------------
235 //  device_start - device-specific startup
236 //-------------------------------------------------
237 
device_start()238 void base_sns_cart_slot_device::device_start()
239 {
240 	m_cart = dynamic_cast<device_sns_cart_interface *>(get_card_device());
241 	if (m_cart != nullptr)
242 		m_cart->m_slot = this;
243 
244 	m_irq_callback.resolve_safe();
245 	m_open_bus_callback.resolve_safe(0xff);
246 }
247 
248 
249 //-------------------------------------------------
250 //  SNES PCB
251 //-------------------------------------------------
252 
253 
254 struct sns_slot
255 {
256 	int                     pcb_id;
257 	const char              *slot_option;
258 };
259 
260 // Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it
261 static const sns_slot slot_list[] =
262 {
263 	{ SNES_MODE20,      "lorom"},
264 	{ SNES_BSXLO,       "lorom_bsx"},
265 	{ SNES_CX4,         "lorom_cx4"},
266 	{ SNES_DSP,         "lorom_dsp"},
267 	{ SNES_DSP4,        "lorom_dsp4"},
268 	{ SNES_OBC1,        "lorom_obc1"},
269 	{ SNES_SA1,         "lorom_sa1"},
270 	{ SNES_SDD1,        "lorom_sdd1"},
271 	{ SNES_GSU1,        "lorom_gsu1"},
272 	{ SNES_GSU2,        "lorom_gsu2"},
273 	{ SNES_Z80GB,       "lorom_sgb"},
274 	{ SNES_ST010,       "lorom_st010"},
275 	{ SNES_ST011,       "lorom_st011"},
276 	{ SNES_ST018,       "lorom_st018"},
277 	{ SNES_SUFAMITURBO, "lorom_sufami"},
278 	{ SNES_MODE21,      "hirom"},
279 	{ SNES_DSP_MODE21,  "hirom_dsp"},
280 	{ SNES_BSXHI,       "hirom_bsx"},
281 	{ SNES_SPC7110,     "hirom_spc7110"},
282 	{ SNES_SPC7110_RTC, "hirom_spcrtc"},
283 	{ SNES_SRTC,        "hirom_srtc"},
284 	{ SNES_BSX,         "bsxrom"},
285 	// BS-X memory packs
286 	{ SNES_BSMEMPAK,    "bsmempak"},
287 	// Sufami Turbo carts
288 	{ SNES_STROM,       "strom"},
289 	// Event carts
290 	{ SNES_PFEST94,     "pfest94" },
291 	// pirate carts
292 	{ SNES_POKEMON,      "lorom_poke"},
293 	{ SNES_TEKKEN2,      "lorom_tekken2"},
294 	{ SNES_SOULBLAD,     "lorom_sbld"},
295 	{ SNES_MCPIR1,       "lorom_mcpir1"},
296 	{ SNES_MCPIR2,       "lorom_mcpir2"},
297 	{ SNES_20COL,        "lorom_20col"},
298 	{ SNES_BANANA,       "lorom_pija"},  // wip
299 	{ SNES_BUGS,         "lorom_bugs"},  // wip
300 	// legacy slots to support DSPx games from fullpath
301 	{ SNES_DSP1_LEG,     "lorom_dsp1leg"},
302 	{ SNES_DSP1B_LEG,    "lorom_dsp1bleg"},
303 	{ SNES_DSP2_LEG,     "lorom_dsp2leg"},
304 	{ SNES_DSP3_LEG,     "lorom_dsp3leg"},
305 	{ SNES_DSP4_LEG,     "lorom_dsp4leg"},
306 	{ SNES_DSP1_MODE21_LEG, "hirom_dsp1leg"},
307 	{ SNES_ST010_LEG,     "lorom_st10leg"},
308 	{ SNES_ST011_LEG,     "lorom_st11leg"}
309 };
310 
sns_get_pcb_id(const char * slot)311 static int sns_get_pcb_id(const char *slot)
312 {
313 	for (auto & elem : slot_list)
314 	{
315 		if (!core_stricmp(elem.slot_option, slot))
316 			return elem.pcb_id;
317 	}
318 
319 	return 0;
320 }
321 
sns_get_slot(int type)322 static const char *sns_get_slot(int type)
323 {
324 	for (auto & elem : slot_list)
325 	{
326 		if (elem.pcb_id == type)
327 			return elem.slot_option;
328 	}
329 
330 	return "lorom";
331 }
332 
333 
334 /*-------------------------------------------------
335  SRAM handling
336  -------------------------------------------------*/
337 
338 /*************************************
339  *  Helper functions
340  *************************************/
341 
342 
343 /* Here we add a couple of cart utilities, to avoid duplicating the code in each DEVICE_IMAGE_LOAD */
snes_skip_header(const uint8_t * ROM,uint32_t rom_size) const344 uint32_t base_sns_cart_slot_device::snes_skip_header(const uint8_t *ROM, uint32_t rom_size) const
345 {
346 	uint8_t header[512];
347 	uint32_t offset = 512;
348 
349 	/* Check for a header (512 bytes) */
350 	memcpy(header, ROM, 512);
351 
352 	if ((header[8] == 0xaa) && (header[9] == 0xbb) && (header[10] == 0x04))
353 	{
354 		/* Found an SWC identifier */
355 		logerror("Found header (SWC) - Skipped\n");
356 	}
357 	else if ((header[0] | (header[1] << 8)) == (((rom_size - 512) / 1024) / 8))
358 	{
359 		/* Some headers have the rom size at the start, if this matches with the actual rom size, we probably have a header */
360 		logerror("Found header (size) - Skipped\n");
361 	}
362 	else if ((rom_size % 0x8000) == 512)
363 	{
364 		/* As a last check we'll see if there's exactly 512 bytes extra to this image. */
365 		logerror("Found header (extra) - Skipped\n");
366 	}
367 	else
368 	{
369 		/* No header found so go back to the start of the file */
370 		logerror("No header found.\n");
371 		offset = 0;
372 	}
373 
374 	return offset;
375 }
376 
377 
378 /* This function assign a 'score' to data immediately after 'offset' to measure how valid they are
379  as information block (to decide if the image is HiRom, LoRom, ExLoRom or ExHiRom) */
380 /* Code from bsnes, courtesy of byuu - http://byuu.org/ , based on previous code by Cowering */
snes_validate_infoblock(const uint8_t * infoblock,uint32_t offset)381 static int snes_validate_infoblock(const uint8_t *infoblock, uint32_t offset)
382 {
383 	int score = 0;
384 	uint16_t reset_vector = infoblock[offset + 0x3c] | (infoblock[offset + 0x3d] << 8);
385 	uint16_t checksum     = infoblock[offset + 0x1e] | (infoblock[offset + 0x1f] << 8);
386 	uint16_t ichecksum    = infoblock[offset + 0x1c] | (infoblock[offset + 0x1d] << 8);
387 	uint8_t reset_opcode  = infoblock[(offset & ~0x7fff) | (reset_vector & 0x7fff)];  //first opcode executed upon reset
388 	uint8_t mapper        = infoblock[offset + 0x15] & ~0x10;                         //mask off irrelevant FastROM-capable bit
389 
390 	/* $00:[000-7fff] contains uninitialized RAM and MMIO.
391 	 reset vector must point to ROM at $00:[8000-ffff] to be considered valid. */
392 	if (reset_vector < 0x8000)
393 		return 0;
394 
395 	/* some images duplicate the header in multiple locations, and others have completely
396 	 invalid header information that cannot be relied upon. The code below will analyze
397 	 the first opcode executed at the specified reset vector to determine the probability
398 	 that this is the correct header. Score is assigned accordingly. */
399 
400 	/* most likely opcodes */
401 	if (reset_opcode == 0x78        //sei
402 		|| reset_opcode == 0x18     //clc (clc; xce)
403 		|| reset_opcode == 0x38     //sec (sec; xce)
404 		|| reset_opcode == 0x9c     //stz $nnnn (stz $4200)
405 		|| reset_opcode == 0x4c     //jmp $nnnn
406 		|| reset_opcode == 0x5c     //jml $nnnnnn
407 		)
408 		score += 8;
409 
410 	/* plausible opcodes */
411 	if (reset_opcode == 0xc2        //rep #$nn
412 		|| reset_opcode == 0xe2     //sep #$nn
413 		|| reset_opcode == 0xad     //lda $nnnn
414 		|| reset_opcode == 0xae     //ldx $nnnn
415 		|| reset_opcode == 0xac     //ldy $nnnn
416 		|| reset_opcode == 0xaf     //lda $nnnnnn
417 		|| reset_opcode == 0xa9     //lda #$nn
418 		|| reset_opcode == 0xa2     //ldx #$nn
419 		|| reset_opcode == 0xa0     //ldy #$nn
420 		|| reset_opcode == 0x20     //jsr $nnnn
421 		|| reset_opcode == 0x22     //jsl $nnnnnn
422 		)
423 		score += 4;
424 
425 	/* implausible opcodes */
426 	if (reset_opcode == 0x40        //rti
427 		|| reset_opcode == 0x60     //rts
428 		|| reset_opcode == 0x6b     //rtl
429 		|| reset_opcode == 0xcd     //cmp $nnnn
430 		|| reset_opcode == 0xec     //cpx $nnnn
431 		|| reset_opcode == 0xcc     //cpy $nnnn
432 		)
433 		score -= 4;
434 
435 	/* least likely opcodes */
436 	if (reset_opcode == 0x00        //brk #$nn
437 		|| reset_opcode == 0x02     //cop #$nn
438 		|| reset_opcode == 0xdb     //stp
439 		|| reset_opcode == 0x42     //wdm
440 		|| reset_opcode == 0xff     //sbc $nnnnnn,x
441 		)
442 		score -= 8;
443 
444 	/* Sometimes, both the header and reset vector's first opcode will match ...
445 	 fallback and rely on info validity in these cases to determine more likely header. */
446 
447 	/* a valid checksum is the biggest indicator of a valid header. */
448 	if ((checksum + ichecksum) == 0xffff && (checksum != 0) && (ichecksum != 0))
449 		score += 4;
450 
451 	/* then there are the expected mapper values */
452 	if (offset == 0x007fc0 && mapper == 0x20)   // 0x20 is usually LoROM
453 		score += 2;
454 
455 	if (offset == 0x00ffc0 && mapper == 0x21)   // 0x21 is usually HiROM
456 		score += 2;
457 
458 	if (offset == 0x007fc0 && mapper == 0x22)   // 0x22 is usually ExLoROM
459 		score += 2;
460 
461 	if (offset == 0x40ffc0 && mapper == 0x25)   // 0x25 is usually ExHiROM
462 		score += 2;
463 
464 	/* finally, there are valid values in the Company, Region etc. fields */
465 	if (infoblock[offset + 0x1a] == 0x33)           // Company field: 0x33 indicates extended header
466 		score += 2;
467 
468 	if (infoblock[offset + 0x16] < 0x08)            // ROM Type field
469 		score++;
470 
471 	if (infoblock[offset + 0x17] < 0x10)            // ROM Size field
472 		score++;
473 
474 	if (infoblock[offset + 0x18] < 0x08)            // SRAM Size field
475 		score++;
476 
477 	if (infoblock[offset + 0x19] < 14)              // Region field
478 		score++;
479 
480 	/* do we still have a positive score? */
481 	if (score < 0)
482 		score = 0;
483 
484 	return score;
485 }
486 
487 /* This determines if a cart is in Mode 20, 21, 22 or 25; sets state->m_cart[0].mode and
488  state->m_cart[0].sram accordingly; and returns the offset of the internal header (needed to
489  detect BSX and ST carts) */
snes_find_hilo_mode(const device_t * device,const uint8_t * buffer,uint32_t buf_len)490 static uint32_t snes_find_hilo_mode(const device_t *device, const uint8_t *buffer, uint32_t buf_len)
491 {
492 	uint8_t valid_mode20 = 0;
493 	uint8_t valid_mode21 = 0;
494 	uint8_t valid_mode25 = 0;
495 	uint32_t retvalue;
496 
497 	/* Now to determine if this is a lo-ROM, a hi-ROM or an extended lo/hi-ROM */
498 	if (buf_len > 0x007fc0)
499 		valid_mode20 = snes_validate_infoblock(buffer, 0x007fc0);
500 	if (buf_len > 0x00ffc0)
501 		valid_mode21 = snes_validate_infoblock(buffer, 0x00ffc0);
502 	if (buf_len > 0x40ffc0)
503 		valid_mode25 = snes_validate_infoblock(buffer, 0x40ffc0);
504 
505 	/* Images larger than 32mbits are likely ExHiRom */
506 	if (valid_mode25)
507 		valid_mode25 += 4;
508 
509 	if ((valid_mode20 >= valid_mode21) && (valid_mode20 >= valid_mode25))
510 		retvalue = 0x007fc0;
511 	else if (valid_mode21 >= valid_mode25)
512 		retvalue = 0x00ffc0;
513 	else
514 		retvalue = 0x40ffc0;
515 
516 	device->logerror( "\t HiROM/LoROM id: %s (LoROM: %d , HiROM: %d, ExHiROM: %d)\n",
517 				(retvalue == 0x007fc0) ? "LoROM" :
518 				(retvalue == 0x00ffc0) ? "HiROM" :
519 				(retvalue == 0x40ffc0) ? "ExHiROM" : "Other",
520 				valid_mode20, valid_mode21, valid_mode25);
521 
522 	return retvalue;
523 }
524 
525 
snes_find_addon_chip(const uint8_t * buffer,uint32_t start_offs,uint32_t len)526 static int snes_find_addon_chip(const uint8_t *buffer, uint32_t start_offs, uint32_t len)
527 {
528 	/* Info mostly taken from http://black-ship.net/~tukuyomi/snesemu/misc/hardware/-from%20nsrt.edgeemu.com-chipinfo.htm */
529 	switch (buffer[start_offs + 0x16])
530 	{
531 		case 0x00:
532 		case 0x01:
533 		case 0x02:
534 			break;
535 
536 		case 0x03:
537 			if (buffer[start_offs + 0x15] == 0x30)
538 				return ADDON_DSP4;
539 			else
540 				return ADDON_DSP1;
541 
542 		case 0x04:
543 			return ADDON_DSP1;
544 
545 		case 0x05:
546 			// DSP2 can be detected by (buffer[start_offs + 0x15] == 0x20)
547 			// DSP3 is harder to detect, and one has to rely on the manufacturer (Bandai)
548 			//      by checking (buffer[start_offs + 0x15] == 0x30) && (buffer[start_offs + 0x1a] == 0xb2)
549 			// in other cases is DSP1, but we do treat all these together...
550 			if (buffer[start_offs + 0x15] == 0x20)
551 				return ADDON_DSP2;
552 			else if ((buffer[start_offs + 0x15] == 0x30) && (buffer[start_offs + 0x1a] == 0xb2))
553 				return ADDON_DSP3;
554 			else
555 				return ADDON_DSP1;
556 
557 		case 0x13:  // Mario Chip 1
558 		case 0x14:  // GSU-x
559 		case 0x15:  // GSU-x
560 		case 0x1a:  // GSU-1 (21 MHz at start)
561 			if (buffer[start_offs + 0x15] == 0x20)
562 			{
563 				if (len > 1048576)
564 					return ADDON_GSU2;
565 				else
566 					return ADDON_GSU1;
567 			}
568 			break;
569 
570 		case 0x25:
571 			return ADDON_OBC1;
572 
573 		case 0x32:  // needed by a Sample game (according to ZSNES)
574 		case 0x34:
575 		case 0x35:
576 			if (buffer[start_offs + 0x15] == 0x23)
577 				return ADDON_SA1;
578 			break;
579 
580 		case 0x43:
581 		case 0x45:
582 			if (buffer[start_offs + 0x15] == 0x32)
583 				return ADDON_SDD1;
584 			break;
585 
586 		case 0x55:
587 			if (buffer[start_offs + 0x15] == 0x35)
588 				return ADDON_SRTC;
589 			break;
590 
591 		case 0xe3:
592 			return ADDON_Z80GB;
593 
594 		case 0xf3:
595 			return ADDON_CX4;
596 
597 		case 0xf5:
598 			if (buffer[start_offs + 0x15] == 0x30)
599 				return ADDON_ST018;
600 			else if (buffer[start_offs + 0x15] == 0x3a)
601 				return ADDON_SPC7110;
602 			break;
603 
604 		case 0xf6:
605 			/* These Seta ST-01X chips have both 0x30 at 0xffd5,
606 			 they only differ for the 'size' at 0xffd7 */
607 			if (buffer[start_offs + 0x17] < 0x0a)
608 				return ADDON_ST011;
609 			else
610 				return ADDON_ST010;
611 
612 		case 0xf9:
613 			if (buffer[start_offs + 0x15] == 0x3a)
614 				return ADDON_SPC7110_RTC;
615 			break;
616 
617 		default:
618 			break;
619 	}
620 	return -1;
621 }
622 
623 
624 /*-------------------------------------------------
625  call load
626  -------------------------------------------------*/
627 
628 
call_load()629 image_init_result base_sns_cart_slot_device::call_load()
630 {
631 	if (m_cart)
632 	{
633 		uint8_t *ROM;
634 		uint32_t len, offset = 0;
635 		const char *slot_name;
636 
637 		/* Check for a header (512 bytes), and skip it if found */
638 		if (!loaded_through_softlist())
639 		{
640 			uint32_t tmplen = length();
641 			std::vector<uint8_t> tmpROM(tmplen);
642 			fread(&tmpROM[0], tmplen);
643 			offset = snes_skip_header(&tmpROM[0], tmplen);
644 			fseek(offset, SEEK_SET);
645 		}
646 
647 		len = !loaded_through_softlist() ? (length() - offset) : get_software_region_length("rom");
648 
649 		m_cart->rom_alloc(len, tag());
650 		ROM = m_cart->get_rom_base();
651 		if (!loaded_through_softlist())
652 			fread(ROM, len);
653 		else
654 			memcpy(ROM, get_software_region("rom"), len);
655 
656 		m_cart->rom_map_setup(len);
657 
658 		// check for on-cart CPU bios
659 		if (loaded_through_softlist())
660 		{
661 			if (get_software_region("addon"))
662 			{
663 				m_cart->addon_bios_alloc(get_software_region_length("addon"));
664 				memcpy(m_cart->get_addon_bios_base(), get_software_region("addon"), get_software_region_length("addon"));
665 			}
666 		}
667 
668 		// get pcb type
669 		if (!loaded_through_softlist())
670 			get_cart_type_addon(ROM, len, m_type, m_addon);
671 		else
672 		{
673 			if ((slot_name = get_feature("slot")) == nullptr)
674 				m_type = SNES_MODE20;
675 			else
676 				m_type = sns_get_pcb_id(slot_name);
677 
678 			if (m_type == SNES_DSP && len > 0x100000)
679 					m_type = SNES_DSP_2MB;
680 		}
681 
682 		if (!loaded_through_softlist())
683 			setup_addon_from_fullpath();
684 
685 		// in carts with an add-on CPU having internal dump, this speeds up access to the internal rom
686 		// by installing read_bank in address space and mapping m_bios there
687 		m_cart->speedup_addon_bios_access();
688 
689 		setup_nvram();
690 
691 		if (m_cart->get_nvram_size() || m_cart->get_rtc_ram_size())
692 		{
693 			uint32_t tot_size = m_cart->get_nvram_size() + m_cart->get_rtc_ram_size();
694 			std::vector<uint8_t> temp_nvram(tot_size);
695 			battery_load(&temp_nvram[0], tot_size, 0xff);
696 			if (m_cart->get_nvram_size())
697 				memcpy(m_cart->get_nvram_base(), &temp_nvram[0], m_cart->get_nvram_size());
698 			if (m_cart->get_rtc_ram_size())
699 				memcpy(m_cart->get_rtc_ram_base(), &temp_nvram[m_cart->get_nvram_size()], m_cart->get_rtc_ram_size());
700 		}
701 
702 		//printf("Type %d\n", m_type);
703 
704 		internal_header_logging(ROM, len);
705 
706 		return image_init_result::PASS;
707 	}
708 
709 	return image_init_result::PASS;
710 }
711 
712 
713 /*-------------------------------------------------
714  call_unload
715  -------------------------------------------------*/
716 
call_unload()717 void base_sns_cart_slot_device::call_unload()
718 {
719 	if (m_cart)
720 	{
721 		if (m_cart->get_nvram_size() || m_cart->get_rtc_ram_size())
722 		{
723 			uint32_t tot_size = m_cart->get_nvram_size() + m_cart->get_rtc_ram_size();
724 			std::vector<uint8_t> temp_nvram(tot_size);
725 			if (m_cart->get_nvram_size())
726 				memcpy(&temp_nvram[0], m_cart->get_nvram_base(), m_cart->get_nvram_size());
727 			if (m_cart->get_rtc_ram_size())
728 				memcpy(&temp_nvram[m_cart->get_nvram_size()], m_cart->get_rtc_ram_base(), m_cart->get_rtc_ram_size());
729 
730 			battery_save(&temp_nvram[0], tot_size);
731 		}
732 	}
733 }
734 
735 
setup_addon_from_fullpath()736 void base_sns_cart_slot_device::setup_addon_from_fullpath()
737 {
738 	// if we already have an add-on bios or if no addon has been detected, we have nothing to do
739 	if (m_cart->get_addon_bios_size() || m_addon == ADDON_NONE)
740 		return;
741 
742 	// check if the add-on dump is appended to the file
743 	// if this is the case, copy it in m_bios and refresh
744 	// the rom_bank_map with correct game rom size
745 	switch (m_addon)
746 	{
747 		case ADDON_DSP1:
748 		case ADDON_DSP1B:
749 		case ADDON_DSP2:
750 		case ADDON_DSP3:
751 		case ADDON_DSP4:
752 			// check for add-on dump
753 			if ((m_cart->get_rom_size() & 0x7fff) == 0x2800)
754 			{
755 				logerror("Found NEC DSP dump at the bottom of the ROM.\n");
756 				m_cart->addon_bios_alloc(0x2800);
757 				memcpy(m_cart->get_addon_bios_base(), m_cart->get_rom_base() + (m_cart->get_rom_size() - 0x2800), 0x2800);
758 				m_cart->rom_map_setup(m_cart->get_rom_size() - 0x2800);
759 			}
760 			// check for byuu's compressed version (swapped order of bytes and stripped fixed 0x00 bytes)
761 			if ((m_cart->get_rom_size() & 0x7fff) == 0x2000)
762 			{
763 				logerror("Found NEC DSP dump (byuu's version) at the bottom of the ROM.\n");
764 				m_cart->addon_bios_alloc(0x2800);
765 				for (int i = 0; i < 0x800; i++)
766 				{
767 					memcpy(m_cart->get_addon_bios_base() + i * 4 + 2, m_cart->get_rom_base() + (m_cart->get_rom_size() - 0x2000) + i * 3 + 0, 1);
768 					memcpy(m_cart->get_addon_bios_base() + i * 4 + 1, m_cart->get_rom_base() + (m_cart->get_rom_size() - 0x2000) + i * 3 + 1, 1);
769 					memcpy(m_cart->get_addon_bios_base() + i * 4 + 0, m_cart->get_rom_base() + (m_cart->get_rom_size() - 0x2000) + i * 3 + 2, 1);
770 					memset(m_cart->get_addon_bios_base() + i * 4 + 3, 0xff, 1);
771 				}
772 				memcpy(m_cart->get_addon_bios_base() + 0x2000, m_cart->get_rom_base() + (m_cart->get_rom_size() - 0x1800), 0x800);
773 				m_cart->rom_map_setup(m_cart->get_rom_size() - 0x2000);
774 			}
775 			break;
776 		case ADDON_ST010:
777 		case ADDON_ST011:
778 			// check for add-on dump
779 			if ((m_cart->get_rom_size() & 0x3ffff) == 0x11000)
780 			{
781 				logerror("Found Seta DSP dump at the bottom of the ROM.\n");
782 				m_cart->addon_bios_alloc(0x11000);
783 				memcpy(m_cart->get_addon_bios_base(), m_cart->get_rom_base() + (m_cart->get_rom_size() - 0x11000), 0x11000);
784 				m_cart->rom_map_setup(m_cart->get_rom_size() - 0x11000);
785 			}
786 			// check for byuu's compressed version (swapped order of bytes and stripped fixed 0x00 bytes)
787 			if ((m_cart->get_rom_size() & 0xffff) == 0xd000)
788 			{
789 				logerror("Found Seta DSP dump (byuu's version) at the bottom of the ROM.\n");
790 				m_cart->addon_bios_alloc(0x11000);
791 				for (int i = 0; i < 0x4000; i++)
792 				{
793 					memcpy(m_cart->get_addon_bios_base() + i * 4 + 2, m_cart->get_rom_base() + (m_cart->get_rom_size() - 0xd000) + i * 3 + 0, 1);
794 					memcpy(m_cart->get_addon_bios_base() + i * 4 + 1, m_cart->get_rom_base() + (m_cart->get_rom_size() - 0xd000) + i * 3 + 1, 1);
795 					memcpy(m_cart->get_addon_bios_base() + i * 4 + 0, m_cart->get_rom_base() + (m_cart->get_rom_size() - 0xd000) + i * 3 + 2, 1);
796 					memset(m_cart->get_addon_bios_base() + i * 4 + 3, 0xff, 1);
797 				}
798 				memcpy(m_cart->get_addon_bios_base() + 0x10000, m_cart->get_rom_base() + (m_cart->get_rom_size() - 0xc000), 0x1000);
799 				m_cart->rom_map_setup(m_cart->get_rom_size() - 0xd000);
800 			}
801 			break;
802 		case ADDON_CX4:
803 			if ((m_cart->get_rom_size() & 0x7fff) == 0x0c00)
804 			{
805 				logerror("Found CX4 dump at the bottom of the ROM.\n");
806 				m_cart->addon_bios_alloc(0x0c00);
807 				memcpy(m_cart->get_addon_bios_base(), m_cart->get_rom_base() + (m_cart->get_rom_size() - 0x0c00), 0x0c00);
808 				m_cart->rom_map_setup(m_cart->get_rom_size() - 0x0c00);
809 			}
810 			break;
811 		case ADDON_ST018:
812 			if ((m_cart->get_rom_size() & 0x3ffff) == 0x28000)
813 			{
814 				logerror("Found ST018 dump at the bottom of the ROM.\n");
815 				m_cart->addon_bios_alloc(0x28000);
816 				memcpy(m_cart->get_addon_bios_base(), m_cart->get_rom_base() + (m_cart->get_rom_size() - 0x28000), 0x28000);
817 				m_cart->rom_map_setup(m_cart->get_rom_size() - 0x28000);
818 			}
819 			break;
820 	}
821 
822 	// otherwise, we need to use the legacy versions including DSP dump in device romset
823 	if (!m_cart->get_addon_bios_size())
824 	{
825 		std::string region = std::string(m_cart->device().tag()).append(":addon");
826 		uint8_t *ROM;
827 
828 		switch (m_addon)
829 		{
830 			case ADDON_DSP1:
831 				ROM = machine().root_device().memregion(region.c_str())->base();
832 				m_cart->addon_bios_alloc(0x2800);
833 				memcpy(m_cart->get_addon_bios_base(), ROM, 0x2800);
834 				break;
835 			case ADDON_DSP1B:
836 				ROM = machine().root_device().memregion(region.c_str())->base();
837 				m_cart->addon_bios_alloc(0x2800);
838 				memcpy(m_cart->get_addon_bios_base(), ROM, 0x2800);
839 				break;
840 			case ADDON_DSP2:
841 				ROM = machine().root_device().memregion(region.c_str())->base();
842 				m_cart->addon_bios_alloc(0x2800);
843 				memcpy(m_cart->get_addon_bios_base(), ROM, 0x2800);
844 				break;
845 			case ADDON_DSP3:
846 				ROM = machine().root_device().memregion(region.c_str())->base();
847 				m_cart->addon_bios_alloc(0x2800);
848 				memcpy(m_cart->get_addon_bios_base(), ROM, 0x2800);
849 				break;
850 			case ADDON_DSP4:
851 				ROM = machine().root_device().memregion(region.c_str())->base();
852 				m_cart->addon_bios_alloc(0x2800);
853 				memcpy(m_cart->get_addon_bios_base(), ROM, 0x2800);
854 				break;
855 			case ADDON_ST010:
856 				ROM = machine().root_device().memregion(region.c_str())->base();
857 				m_cart->addon_bios_alloc(0x11000);
858 				memcpy(m_cart->get_addon_bios_base(), ROM, 0x11000);
859 				break;
860 			case ADDON_ST011:
861 				ROM = machine().root_device().memregion(region.c_str())->base();
862 				m_cart->addon_bios_alloc(0x11000);
863 				memcpy(m_cart->get_addon_bios_base(), ROM, 0x11000);
864 				break;
865 		}
866 	}
867 
868 }
869 
setup_nvram()870 void base_sns_cart_slot_device::setup_nvram()
871 {
872 	uint8_t *ROM = (uint8_t *)m_cart->get_rom_base();
873 	uint32_t size = 0;
874 	if (!loaded_through_softlist())
875 	{
876 		int hilo_mode = snes_find_hilo_mode(this, ROM, m_cart->get_rom_size());
877 		uint8_t sram_size = (m_type == SNES_GSU1 || m_type == SNES_GSU2) ? (ROM[0x00ffbd] & 0x07) : (ROM[hilo_mode + 0x18] & 0x07);
878 		if (sram_size)
879 		{
880 			uint32_t max = (hilo_mode == 0x007fc0) ? 0x80000 : 0x20000;   // MODE20 vs MODE21
881 			size = 1024 << sram_size;
882 			if (size > max)
883 				size = max;
884 		}
885 	}
886 	else
887 	{
888 		if (get_software_region("nvram"))
889 			size = get_software_region_length("nvram");
890 	}
891 
892 	if (size)
893 		m_cart->nvram_alloc(size);
894 
895 	if (m_type == SNES_STROM)
896 		m_cart->nvram_alloc(0x20000);
897 	if (m_type == SNES_BSX)
898 		m_cart->nvram_alloc(0x8000);
899 
900 	// setup also RTC SRAM, when needed (to be removed when RTCs are converted to devices)
901 	if (m_type == SNES_SRTC)
902 		m_cart->rtc_ram_alloc(13);
903 	if (m_type == SNES_SPC7110_RTC)
904 		m_cart->rtc_ram_alloc(16);
905 }
906 
907 
908 
get_cart_type_addon(const uint8_t * ROM,uint32_t len,int & type,int & addon) const909 void base_sns_cart_slot_device::get_cart_type_addon(const uint8_t *ROM, uint32_t len, int &type, int &addon) const
910 {
911 	// First, look if the cart is HiROM or LoROM (and set snes_cart accordingly)
912 	int hilo_mode = snes_find_hilo_mode(this, ROM, len);
913 
914 	switch (hilo_mode)
915 	{
916 		case 0x007fc0: // LoRom & ExLoRom
917 			type = SNES_MODE20;
918 			break;
919 		case 0x00ffc0: // HiRom
920 		case 0x40ffc0: // ExHiRom
921 			type = SNES_MODE21;
922 			break;
923 		default:
924 			break;
925 	}
926 
927 	// detect Sufami Turbo...
928 	if (type == SNES_MODE20 && !memcmp(ROM, "BANDAI SFC-ADX", 14))
929 	{
930 		if (!memcmp(ROM + 16, "SFC-ADX BACKUP", 14))
931 			type = SNES_SUFAMITURBO;
932 		else
933 			type = SNES_STROM;
934 	}
935 
936 	// detect BS-X Base Cart
937 	if (!memcmp(ROM + hilo_mode, "Satellaview BS-X     ", 21))
938 		type = SNES_BSX;
939 	// Detect BS-X Flash Cart
940 	if ((ROM[hilo_mode + 0x13] == 0x00 || ROM[hilo_mode + 0x13] == 0xff) && ROM[hilo_mode + 0x14] == 0x00)
941 	{
942 		uint8_t n15 = ROM[hilo_mode + 0x15];
943 		if (n15 == 0x00 || n15 == 0x80 || n15 == 0x84 || n15 == 0x9c || n15 == 0xbc || n15 == 0xfc)
944 		{
945 			if (ROM[hilo_mode + 0x1a] == 0x33 || ROM[hilo_mode + 0x1a] == 0xff)
946 				type = SNES_BSMEMPAK;
947 		}
948 	}
949 
950 	// check for add-on chips...
951 	if (len >= hilo_mode + 0x1a)
952 	{
953 		addon = snes_find_addon_chip(ROM, hilo_mode, len);
954 		if (addon != -1)
955 		{
956 			// m_type handles DSP1,2,3 in the same way, but snes_add requires them to be separate...
957 			switch (addon)
958 			{
959 				case ADDON_CX4:
960 					type = SNES_CX4;
961 					break;
962 				case ADDON_DSP1:
963 				case ADDON_DSP1B:
964 				case ADDON_DSP2:
965 				case ADDON_DSP3:
966 					if (type == SNES_MODE20 && len > 0x100000)
967 						type = SNES_DSP_2MB;
968 					else if (type == SNES_MODE21)
969 						type = SNES_DSP_MODE21;
970 					else
971 						type = SNES_DSP;
972 					break;
973 				case ADDON_DSP4:
974 					type = SNES_DSP4;
975 					break;
976 				case ADDON_OBC1:
977 					type = SNES_OBC1;
978 					break;
979 				case ADDON_SA1:
980 					type = SNES_SA1;
981 					break;
982 				case ADDON_SDD1:
983 					type = SNES_SDD1;
984 					break;
985 				case ADDON_GSU1:
986 					type = SNES_GSU1;
987 					break;
988 				case ADDON_GSU2:
989 					type = SNES_GSU2;
990 					break;
991 				case ADDON_SPC7110:
992 					type = SNES_SPC7110;
993 					break;
994 				case ADDON_SPC7110_RTC:
995 					type = SNES_SPC7110_RTC;
996 					break;
997 				case ADDON_ST010:
998 					type = SNES_ST010;
999 					break;
1000 				case ADDON_ST011:
1001 					type = SNES_ST011;
1002 					break;
1003 				case ADDON_ST018:
1004 					type = SNES_ST018;
1005 					break;
1006 				case ADDON_SRTC:
1007 					type = SNES_SRTC;
1008 					break;
1009 				case ADDON_Z80GB:
1010 					type = SNES_Z80GB;
1011 					break;
1012 			}
1013 		}
1014 	}
1015 }
1016 
1017 /*-------------------------------------------------
1018  get default card software
1019  -------------------------------------------------*/
1020 
get_default_card_software(get_default_card_software_hook & hook) const1021 std::string base_sns_cart_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
1022 {
1023 	if (hook.image_file())
1024 	{
1025 		const char *slot_string;
1026 		uint32_t offset;
1027 		uint32_t len = hook.image_file()->size();
1028 		std::vector<uint8_t> rom(len);
1029 		int type = 0, addon = 0;
1030 
1031 		hook.image_file()->read(&rom[0], len);
1032 
1033 		offset = snes_skip_header(&rom[0], len);
1034 
1035 		get_cart_type_addon(&rom[offset], len - offset, type, addon);
1036 		// here we're from fullpath, so check if it's a DSP game which needs legacy device (i.e. it has no appended DSP dump)
1037 		switch (addon)
1038 		{
1039 			case ADDON_DSP1:
1040 				if ((len & 0x7fff) != 0x2800 && (len & 0x7fff) != 0x2000)
1041 				{
1042 					if (type == SNES_DSP_MODE21)
1043 						type = SNES_DSP1_MODE21_LEG;
1044 					else
1045 						type = SNES_DSP1_LEG;
1046 				}
1047 				break;
1048 			case ADDON_DSP1B:
1049 				if ((len & 0x7fff) != 0x2800 && (len & 0x7fff) != 0x2000)
1050 					type = SNES_DSP1B_LEG;
1051 				break;
1052 			case ADDON_DSP2:
1053 				if ((len & 0x7fff) != 0x2800 && (len & 0x7fff) != 0x2000)
1054 					type = SNES_DSP2_LEG;
1055 				break;
1056 			case ADDON_DSP3:
1057 				if ((len & 0x7fff) != 0x2800 && (len & 0x7fff) != 0x2000)
1058 					type = SNES_DSP3_LEG;
1059 				break;
1060 			case ADDON_DSP4:
1061 				if ((len & 0x7fff) != 0x2800 && (len & 0x7fff) != 0x2000)
1062 					type = SNES_DSP4_LEG;
1063 				break;
1064 			case ADDON_ST010:
1065 				if ((len & 0x3ffff) != 0x11000 && (len & 0xffff) != 0xd000)
1066 					type = SNES_ST010_LEG;
1067 				break;
1068 			case ADDON_ST011:
1069 				if ((len & 0x3ffff) != 0x11000 && (len & 0xffff) != 0xd000)
1070 					type = SNES_ST011_LEG;
1071 				break;
1072 		}
1073 
1074 		slot_string = sns_get_slot(type);
1075 
1076 		return std::string(slot_string);
1077 	}
1078 
1079 	return software_get_default_slot("lorom");
1080 }
1081 
1082 
1083 /*-------------------------------------------------
1084  read
1085  -------------------------------------------------*/
1086 
read_l(offs_t offset)1087 uint8_t base_sns_cart_slot_device::read_l(offs_t offset)
1088 {
1089 	if (m_cart)
1090 		return m_cart->read_l(offset);
1091 	else
1092 		return 0xff;
1093 }
1094 
read_h(offs_t offset)1095 uint8_t base_sns_cart_slot_device::read_h(offs_t offset)
1096 {
1097 	if (m_cart)
1098 		return m_cart->read_h(offset);
1099 	else
1100 		return 0xff;
1101 }
1102 
read_ram(offs_t offset)1103 uint8_t base_sns_cart_slot_device::read_ram(offs_t offset)
1104 {
1105 	if (m_cart)
1106 		return m_cart->read_ram(offset);
1107 	else
1108 		return 0xff;
1109 }
1110 
chip_read(offs_t offset)1111 uint8_t base_sns_cart_slot_device::chip_read(offs_t offset)
1112 {
1113 	if (m_cart)
1114 		return m_cart->chip_read(offset);
1115 	else
1116 		return 0xff;
1117 }
1118 
1119 /*-------------------------------------------------
1120  write
1121  -------------------------------------------------*/
1122 
write_l(offs_t offset,uint8_t data)1123 void base_sns_cart_slot_device::write_l(offs_t offset, uint8_t data)
1124 {
1125 	if (m_cart)
1126 		m_cart->write_l(offset, data);
1127 }
1128 
write_h(offs_t offset,uint8_t data)1129 void base_sns_cart_slot_device::write_h(offs_t offset, uint8_t data)
1130 {
1131 	if (m_cart)
1132 		m_cart->write_h(offset, data);
1133 }
1134 
write_ram(offs_t offset,uint8_t data)1135 void base_sns_cart_slot_device::write_ram(offs_t offset, uint8_t data)
1136 {
1137 	if (m_cart)
1138 		m_cart->write_ram(offset, data);
1139 }
1140 
chip_write(offs_t offset,uint8_t data)1141 void base_sns_cart_slot_device::chip_write(offs_t offset, uint8_t data)
1142 {
1143 	if (m_cart)
1144 		m_cart->chip_write(offset, data);
1145 }
1146 
1147 
1148 /*-------------------------------------------------
1149  Internal header logging
1150  -------------------------------------------------*/
1151 
1152 /* We use this to convert the company_id in the header to int value to be passed in companies[] */
char_to_int_conv(char id)1153 static int char_to_int_conv( char id )
1154 {
1155 	int value;
1156 
1157 	if (id == '1') value = 0x01;
1158 	else if (id == '2') value = 0x02;
1159 	else if (id == '3') value = 0x03;
1160 	else if (id == '4') value = 0x04;
1161 	else if (id == '5') value = 0x05;
1162 	else if (id == '6') value = 0x06;
1163 	else if (id == '7') value = 0x07;
1164 	else if (id == '8') value = 0x08;
1165 	else if (id == '9') value = 0x09;
1166 	else if (id == 'A') value = 0x0a;
1167 	else if (id == 'B') value = 0x0b;
1168 	else if (id == 'C') value = 0x0c;
1169 	else if (id == 'D') value = 0x0d;
1170 	else if (id == 'E') value = 0x0e;
1171 	else if (id == 'F') value = 0x0f;
1172 	else value = 0x00;
1173 
1174 	return value;
1175 }
1176 
1177 #define UNK  "UNKNOWN"
1178 
internal_header_logging(uint8_t * ROM,uint32_t len)1179 void base_sns_cart_slot_device::internal_header_logging(uint8_t *ROM, uint32_t len)
1180 {
1181 	static const char *const cart_types[] =
1182 	{
1183 		"ROM (LoROM)",
1184 		"ROM (HiROM)",
1185 		"ROM (ExLoROM)",
1186 		"ROM (ExHiROM)",
1187 		"ROM, CX4",
1188 		"ROM, DSP-1,2,3 (LoROM)",
1189 		"ROM, DSP-1 (LoROM 2MB)",
1190 		"ROM, DSP-1 (HiROM)",
1191 		"ROM, DSP-4",
1192 		"ROM, OBC-1",
1193 		"ROM, SA-1",
1194 		"ROM, S-DD1",
1195 		"ROM, Super FX / FX2",
1196 		"ROM, SPC7110",
1197 		"ROM, SPC7110, RTC",
1198 		"ROM, S-RTC",
1199 		"ROM, Seta ST-010",
1200 		"ROM, Seta ST-011",
1201 		"ROM, Seta ST-018",
1202 		"ROM, Z80GB (Super Game Boy)",
1203 		"ROM, BS-X Base cart",
1204 		"ROM, BS-X compatible (LoROM)",
1205 		"ROM, BS-X compatible (HiROM)",
1206 		"BS-X memory pack",
1207 		"ROM, Sufami Turbo",
1208 		"Sufami Turbo cart",
1209 		// pirate cart types which are not recognized from fullpath
1210 		UNK,
1211 		UNK,
1212 		UNK
1213 	};
1214 
1215 	/* Some known countries */
1216 	static const char *const countries[] =
1217 	{
1218 		/* 0*/  "Japan (NTSC)", "USA & Canada (NTSC)", "Europe, Oceania & Asia (PAL)", "Sweden (PAL)",
1219 		/* 4*/  "Finland (PAL)", "Denmark (PAL)", "France (PAL)", "Holland (PAL)",
1220 		/* 8*/  "Spain (PAL)", "Germany, Austria & Switzerland (PAL)", "Italy (PAL)", "Hong Kong & China (PAL)",
1221 		/* c*/  "Indonesia (PAL)", "South Korea (NTSC)", UNK, UNK,
1222 	};
1223 
1224 	/* Some known companies (integrations to the list from Snes9x) */
1225 	static const char *const companies[] =
1226 	{
1227 		/* 0*/  "Invalid", "Nintendo", "Ajinomoto", "Imagineer-Zoom", "Chris Gray Enterprises Inc.", "Zamuse", "Falcom", UNK,
1228 		/* 8*/  "Capcom", "HOT-B", "Jaleco", "Coconuts", "Rage Software", "Micronet", "Technos", "Mebio Software",
1229 		/*10*/  "SHOUEi System", "Starfish", "Gremlin Graphics", "Electronic Arts", "NCS / Masaya", "COBRA Team", "Human/Field", "KOEI",
1230 		/*18*/  "Hudson Soft", "Game Village", "Yanoman", UNK, "Tecmo", UNK, "Open System", "Virgin Games",
1231 		/*20*/  "KSS", "Sunsoft", "POW", "Micro World", UNK, UNK, "Enix", "Loriciel/Electro Brain",
1232 		/*28*/  "Kemco", "Seta Co.,Ltd.", "Culture Brain", "Irem Japan", "Pal Soft", "Visit Co.,Ltd.", "INTEC Inc.", "System Sacom Corp.",
1233 		/*30*/  "Viacom New Media", "Carrozzeria", "Dynamic", "Nintendo", "Magifact", "Hect", UNK, UNK,
1234 		/*38*/  "Capcom Europe", "Accolade Europe", UNK, "Arcade Zone", "Empire Software", "Loriciel", "Gremlin Graphics", UNK,
1235 		/*40*/  "Seika Corp.", "UBI Soft", UNK, UNK, "LifeFitness Exertainment", UNK, "System 3", "Spectrum Holobyte",
1236 		/*48*/  UNK, "Irem", UNK, "Raya Systems/Sculptured Software", "Renovation Products", "Malibu Games/Black Pearl", UNK, "U.S. Gold",
1237 		/*50*/  "Absolute Entertainment", "Acclaim", "Activision", "American Sammy", "GameTek", "Hi Tech Expressions", "LJN Toys", UNK,
1238 		/*58*/  UNK, UNK, "Mindscape", "Romstar, Inc.", UNK, "Tradewest", UNK, "American Softworks Corp.",
1239 		/*60*/  "Titus", "Virgin Interactive Entertainment", "Maxis", "Origin/FCI/Pony Canyon", UNK, UNK, UNK, "Ocean",
1240 		/*68*/  UNK, "Electronic Arts", UNK, "Laser Beam", UNK, UNK, "Elite", "Electro Brain",
1241 		/*70*/  "Infogrames", "Interplay", "LucasArts", "Parker Brothers", "Konami", "STORM", UNK, UNK,
1242 		/*78*/  "THQ Software", "Accolade Inc.", "Triffix Entertainment", UNK, "Microprose", UNK, UNK, "Kemco",
1243 		/*80*/  "Misawa", "Teichio", "Namco Ltd.", "Lozc", "Koei", UNK, "Tokuma Shoten Intermedia", "Tsukuda Original",
1244 		/*88*/  "DATAM-Polystar", UNK, UNK, "Bullet-Proof Software", "Vic Tokai", UNK, "Character Soft", "I\'\'Max",
1245 		/*90*/  "Takara", "CHUN Soft", "Video System Co., Ltd.", "BEC", UNK, "Varie", "Yonezawa / S'Pal Corp.", "Kaneco",
1246 		/*98*/  UNK, "Pack in Video", "Nichibutsu", "TECMO", "Imagineer Co.", UNK, UNK, UNK,
1247 		/*a0*/  "Telenet", "Hori", UNK, UNK, "Konami", "K.Amusement Leasing Co.", UNK, "Takara",
1248 		/*a8*/  UNK, "Technos Jap.", "JVC", UNK, "Toei Animation", "Toho", UNK, "Namco Ltd.",
1249 		/*b0*/  "Media Rings Corp.", "ASCII Co. Activison", "Bandai", UNK, "Enix America", UNK, "Halken", UNK,
1250 		/*b8*/  UNK, UNK, "Culture Brain", "Sunsoft", "Toshiba EMI", "Sony Imagesoft", UNK, "Sammy",
1251 		/*c0*/  "Taito", UNK, "Kemco", "Square", "Tokuma Soft", "Data East", "Tonkin House", UNK,
1252 		/*c8*/  "KOEI", UNK, "Konami USA", "NTVIC", UNK, "Meldac", "Pony Canyon", "Sotsu Agency/Sunrise",
1253 		/*d0*/  "Disco/Taito", "Sofel", "Quest Corp.", "Sigma", "Ask Kodansha Co., Ltd.", UNK, "Naxat", UNK,
1254 		/*d8*/  "Capcom Co., Ltd.", "Banpresto", "Tomy", "Acclaim", UNK, "NCS", "Human Entertainment", "Altron",
1255 		/*e0*/  "Jaleco", UNK, "Yutaka", UNK, "T&ESoft", "EPOCH Co.,Ltd.", UNK, "Athena",
1256 		/*e8*/  "Asmik", "Natsume", "King Records", "Atlus", "Sony Music Entertainment", UNK, "IGS", UNK,
1257 		/*f0*/  UNK, "Motown Software", "Left Field Entertainment", "Beam Software", "Tec Magik", UNK, UNK, UNK,
1258 		/*f8*/  UNK, "Cybersoft", UNK, "Psygnosis", UNK, UNK, "Davidson", UNK,
1259 	};
1260 
1261 	int hilo_mode = snes_find_hilo_mode(this,ROM, len);
1262 	char title[21], rom_id[4], company_id[2];
1263 	int type = 0, company, addon, has_ram = 0, has_sram = 0;
1264 	switch (hilo_mode)
1265 	{
1266 		case 0x007fc0:
1267 			if ((ROM[0x007fd5] == 0x32) || (len > 0x401000))
1268 				type = SNES_MODE22;  // ExLoRom
1269 			else
1270 				type = SNES_MODE20;  // LoRom
1271 			type = SNES_MODE20;  // LoRom & ExLoRom
1272 			break;
1273 		case 0x00ffc0:
1274 			type = SNES_MODE21;  // HiRom
1275 			break;
1276 		case 0x40ffc0:
1277 			type = SNES_MODE25;  // ExHiRom
1278 			break;
1279 		default:
1280 			break;
1281 	}
1282 
1283 	// detect Sufami Turbo...
1284 	if (type == SNES_MODE20 && !memcmp(ROM, "BANDAI SFC-ADX", 14))
1285 	{
1286 		if (!memcmp(ROM + 16, "SFC-ADX BACKUP", 14))
1287 			type = SNES_SUFAMITURBO;
1288 		else
1289 			type = SNES_STROM;
1290 	}
1291 
1292 	// detect BS-X Base Cart
1293 	if (!memcmp(ROM + hilo_mode, "Satellaview BS-X     ", 21))
1294 		type = SNES_BSX;
1295 	// Detect BS-X Flash Cart
1296 	if ((ROM[hilo_mode + 0x13] == 0x00 || ROM[hilo_mode + 0x13] == 0xff) && ROM[hilo_mode + 0x14] == 0x00)
1297 	{
1298 		uint8_t n15 = ROM[hilo_mode + 0x15];
1299 		if (n15 == 0x00 || n15 == 0x80 || n15 == 0x84 || n15 == 0x9c || n15 == 0xbc || n15 == 0xfc)
1300 		{
1301 			if (ROM[hilo_mode + 0x1a] == 0x33 || ROM[hilo_mode + 0x1a] == 0xff)
1302 				type = SNES_BSMEMPAK;
1303 		}
1304 	}
1305 
1306 	addon = snes_find_addon_chip(ROM, hilo_mode, len);
1307 	if (addon != -1)
1308 	{
1309 		if (type == SNES_MODE20 && addon == SNES_DSP)
1310 		{
1311 			if (len > 0x100000)
1312 				type = SNES_DSP_2MB;
1313 			else
1314 				type = SNES_DSP;
1315 		}
1316 		else if (type == SNES_MODE21 && addon == SNES_DSP)
1317 			type = SNES_DSP_MODE21;
1318 		else
1319 			type = addon;
1320 	}
1321 
1322 	/* Company */
1323 	for (int i = 0; i < 2; i++)
1324 		company_id[i] = ROM[hilo_mode - 0x10 + i];
1325 	company = (char_to_int_conv(company_id[0]) << 4) + char_to_int_conv(company_id[1]);
1326 	if (company == 0)
1327 		company = ROM[hilo_mode + 0x1a];
1328 
1329 	/* ROM ID */
1330 	for(int i = 0; i < 4; i++ )
1331 		rom_id[i] = ROM[hilo_mode - 0x0e + i];
1332 
1333 	/* Title */
1334 	for(int i = 0; i < 21; i++ )
1335 		title[i] = ROM[hilo_mode + i];
1336 
1337 	/* RAM */
1338 	if (((ROM[hilo_mode + 0x16] & 0xf) == 1) ||
1339 		((ROM[hilo_mode + 0x16] & 0xf) == 2) ||
1340 		((ROM[hilo_mode + 0x16] & 0xf) == 4) ||
1341 		((ROM[hilo_mode + 0x16] & 0xf) == 5))
1342 		has_ram = 1;
1343 
1344 	/* SRAM */
1345 	if (((ROM[hilo_mode + 0x16] & 0xf) == 2) ||
1346 		((ROM[hilo_mode + 0x16] & 0xf) == 5) ||
1347 		((ROM[hilo_mode + 0x16] & 0xf) == 6))
1348 		has_sram = 1;
1349 
1350 	logerror( "ROM DETAILS\n" );
1351 	logerror( "===========\n\n" );
1352 	logerror( "\tTotal blocks:  0x%x\n", len);
1353 	logerror( "\tROM bank size: %s \n",
1354 				(type == SNES_MODE20) ? "LoROM" :
1355 				(type == SNES_MODE21) ? "HiROM" :
1356 				(type == SNES_MODE22) ? "ExLoROM" :
1357 				(type == SNES_MODE25) ? "ExHiROM" : "Other (BSX or ST)" );
1358 	logerror( "\tCompany:       %s [%.2s]\n", companies[company], company_id );
1359 	logerror( "\tROM ID:        %.4s\n\n", rom_id );
1360 
1361 	logerror( "HEADER DETAILS\n" );
1362 	logerror( "==============\n\n" );
1363 	logerror( "\tName:          %.21s\n", title );
1364 	logerror( "\tSpeed:         %s [%d]\n", (ROM[hilo_mode + 0x15] & 0xf0) ? "FastROM" : "SlowROM", (ROM[hilo_mode + 0x15] & 0xf0) >> 4);
1365 	logerror( "\tBank size:     %s [%d]\n", (ROM[hilo_mode + 0x15] & 0xf) ? "HiROM" : "LoROM", ROM[hilo_mode + 0x15] & 0xf);
1366 
1367 	logerror( "\tType:          %s", cart_types[type]);
1368 	if (has_ram)
1369 		logerror( ", RAM");
1370 	if (has_sram)
1371 		logerror( ", SRAM");
1372 	logerror( " [%d]\n", ROM[hilo_mode + 0x16]);
1373 
1374 	logerror( "\tSize:          %d megabits [%d]\n", 1 << (ROM[hilo_mode + 0x17] - 7), ROM[hilo_mode + 0x17]);
1375 	logerror( "\tSRAM:          %d kilobits [%d]\n", ROM[hilo_mode + 0x18] * 8, ROM[hilo_mode + 0x18] );
1376 	if (ROM[hilo_mode + 0x19] < ARRAY_LENGTH(countries))
1377 		logerror( "\tCountry:       %s [%d]\n", countries[ROM[hilo_mode + 0x19]], ROM[hilo_mode + 0x19]);
1378 	else
1379 		logerror( "\tCountry:       Unknown [%d]\n", ROM[hilo_mode + 0x19]);
1380 	logerror( "\tLicense:       %s [%X]\n", companies[ROM[hilo_mode + 0x1a]], ROM[hilo_mode + 0x1a]);
1381 	logerror( "\tVersion:       1.%d\n", ROM[hilo_mode + 0x1b]);
1382 	logerror( "\tInv Checksum:  %X %X\n", ROM[hilo_mode + 0x1d], ROM[hilo_mode + 0x1c]);
1383 	logerror( "\tChecksum:      %X %X\n", ROM[hilo_mode + 0x1f], ROM[hilo_mode + 0x1e]);
1384 	logerror( "\tNMI Address:   %2X%2Xh\n", ROM[hilo_mode + 0x3b], ROM[hilo_mode + 0x3a]);
1385 	logerror( "\tStart Address: %2X%2Xh\n\n", ROM[hilo_mode + 0x3d], ROM[hilo_mode + 0x3c]);
1386 
1387 	logerror( "\tMode: %d\n", type);
1388 }
1389