1 // license:BSD-3-Clause
2 // copyright-holders:Fabio Priuli,Cowering
3 /***********************************************************************************************************
4 
5 
6     Atari VCS 2600 cart emulation
7     (through slot devices)
8 
9     Emulation of the cartslot for Atari 2600
10     Several banking schemes have been used for larger roms,
11     and some carts contained RAM (so called "Special Chip")
12 
13     Mapper identification routines based on Cowering's code.
14 
15  ***********************************************************************************************************/
16 
17 
18 #include "emu.h"
19 #include "vcs_slot.h"
20 
21 //**************************************************************************
22 //  GLOBAL VARIABLES
23 //**************************************************************************
24 
25 DEFINE_DEVICE_TYPE(VCS_CART_SLOT, vcs_cart_slot_device, "vcs_cart_slot", "Atari VCS 2600 Cartridge Slot")
26 
27 
28 //-------------------------------------------------
29 //  device_vcs_cart_interface - constructor
30 //-------------------------------------------------
31 
device_vcs_cart_interface(const machine_config & mconfig,device_t & device)32 device_vcs_cart_interface::device_vcs_cart_interface(const machine_config &mconfig, device_t &device) :
33 	device_interface(device, "vcscart"),
34 	m_rom(nullptr),
35 	m_rom_size(0)
36 {
37 }
38 
39 
40 //-------------------------------------------------
41 //  ~device_vcs_cart_interface - destructor
42 //-------------------------------------------------
43 
~device_vcs_cart_interface()44 device_vcs_cart_interface::~device_vcs_cart_interface()
45 {
46 }
47 
48 //-------------------------------------------------
49 //  rom_alloc - alloc the space for the cart
50 //-------------------------------------------------
51 
rom_alloc(uint32_t size,const char * tag)52 void device_vcs_cart_interface::rom_alloc(uint32_t size, const char *tag)
53 {
54 	if (m_rom == nullptr)
55 	{
56 		m_rom = device().machine().memory().region_alloc(std::string(tag).append(A26SLOT_ROM_REGION_TAG).c_str(), size, 1, ENDIANNESS_LITTLE)->base();
57 		m_rom_size = size;
58 	}
59 }
60 
61 //-------------------------------------------------
62 //  ram_alloc - alloc the space for the on-cart RAM
63 //-------------------------------------------------
64 
ram_alloc(uint32_t size)65 void device_vcs_cart_interface::ram_alloc(uint32_t size)
66 {
67 	m_ram.resize(size);
68 	device().save_item(NAME(m_ram));
69 }
70 
71 
72 
73 //**************************************************************************
74 //  LIVE DEVICE
75 //**************************************************************************
76 
77 //-------------------------------------------------
78 //  vcs_cart_slot_device - constructor
79 //-------------------------------------------------
vcs_cart_slot_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)80 vcs_cart_slot_device::vcs_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
81 	device_t(mconfig, VCS_CART_SLOT, tag, owner, clock),
82 	device_image_interface(mconfig, *this),
83 	device_single_card_slot_interface<device_vcs_cart_interface>(mconfig, *this),
84 	m_cart(nullptr), m_type(0)
85 {
86 }
87 
88 
89 //-------------------------------------------------
90 //  vcs_cart_slot_device - destructor
91 //-------------------------------------------------
92 
~vcs_cart_slot_device()93 vcs_cart_slot_device::~vcs_cart_slot_device()
94 {
95 }
96 
97 //-------------------------------------------------
98 //  device_start - device-specific startup
99 //-------------------------------------------------
100 
device_start()101 void vcs_cart_slot_device::device_start()
102 {
103 	m_cart = get_card_device();
104 }
105 
106 
107 
108 /*-------------------------------------------------
109  call load
110  -------------------------------------------------*/
111 
112 //-------------------------------------------------
113 //  VCS PCBs
114 //-------------------------------------------------
115 
116 struct vcs_slot
117 {
118 	int                     pcb_id;
119 	const char              *slot_option;
120 };
121 
122 // Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it
123 static const vcs_slot slot_list[] =
124 {
125 	{ A26_2K, "a26_2k" },
126 	{ A26_4K, "a26_4k" },
127 	{ A26_F4, "a26_f4" },
128 	{ A26_F6, "a26_f6" },
129 	{ A26_F8, "a26_f8" },
130 	{ A26_F8SW, "a26_f8sw" },
131 	{ A26_FA, "a26_fa" },
132 	{ A26_FE, "a26_fe" },
133 	{ A26_E0, "a26_e0" },
134 	{ A26_E7, "a26_e7" },
135 	{ A26_3E, "a26_3e" },
136 	{ A26_3F, "a26_3f" },
137 	{ A26_UA, "a26_ua" },
138 	{ A26_CV, "a26_cv" },
139 	{ A26_DC, "a26_dc" },
140 	{ A26_FV, "a26_fv" },
141 	{ A26_JVP, "a26_jvp" },
142 	{ A26_CM, "a26_cm" },
143 	{ A26_SS, "a26_ss" },
144 	{ A26_DPC, "a26_dpc" },
145 	{ A26_4IN1, "a26_4in1" },
146 	{ A26_8IN1, "a26_8in1" },
147 	{ A26_32IN1, "a26_32in1" },
148 	{ A26_X07, "a26_x07" },
149 	{ A26_HARMONY, "a26_harmony" },
150 };
151 
vcs_get_pcb_id(const char * slot)152 static int vcs_get_pcb_id(const char *slot)
153 {
154 	for (auto & elem : slot_list)
155 	{
156 		if (!core_stricmp(elem.slot_option, slot))
157 			return elem.pcb_id;
158 	}
159 
160 	return 0;
161 }
162 
vcs_get_slot(int type)163 static const char *vcs_get_slot(int type)
164 {
165 	for (auto & elem : slot_list)
166 	{
167 		if (elem.pcb_id == type)
168 			return elem.slot_option;
169 	}
170 
171 	return "a26_4k";
172 }
173 
call_load()174 image_init_result vcs_cart_slot_device::call_load()
175 {
176 	if (m_cart)
177 	{
178 		uint8_t *ROM;
179 		uint32_t len;
180 
181 		if (loaded_through_softlist())
182 			len = get_software_region_length("rom");
183 		else
184 			len = length();
185 
186 		//printf("Size: 0x%X\n", len);
187 
188 		// check that filesize is among the supported ones
189 		switch (len)
190 		{
191 			case 0x00800:
192 			case 0x01000:
193 			case 0x02000:
194 			case 0x028ff:
195 			case 0x02900:
196 			case 0x03000:
197 			case 0x04000:
198 			case 0x08000:
199 			case 0x10000:
200 			case 0x80000:
201 				break;
202 
203 			default:
204 				seterror(IMAGE_ERROR_UNSUPPORTED, "Invalid rom file size" );
205 				return image_init_result::FAIL;
206 		}
207 
208 		m_cart->rom_alloc(len, tag());
209 		ROM = m_cart->get_rom_base();
210 
211 		if (loaded_through_softlist())
212 		{
213 			const char *pcb_name;
214 			bool has_ram = get_software_region("ram") ? true : false;
215 			memcpy(ROM, get_software_region("rom"), len);
216 
217 			if ((pcb_name = get_feature("slot")) != nullptr)
218 				m_type = vcs_get_pcb_id(pcb_name);
219 			else
220 			{
221 				// identify type based on size
222 				switch (len)
223 				{
224 					case 0x800:
225 						m_type = A26_2K;
226 						break;
227 					case 0x1000:
228 						m_type = A26_4K;
229 						break;
230 					case 0x2000:
231 						m_type = A26_F8;
232 						break;
233 					case 0x28ff:
234 					case 0x2900:
235 						m_type = A26_DPC;
236 						break;
237 					case 0x3000:
238 						m_type = A26_FA;
239 						break;
240 					case 0x4000:
241 						m_type = A26_F6;
242 						break;
243 					case 0x8000:
244 						m_type = A26_F4;
245 						break;
246 					case 0x10000:
247 						m_type = A26_32IN1;
248 						break;
249 					case 0x80000:
250 						m_type = A26_3F;
251 						break;
252 					default:
253 						m_type = A26_4K;
254 						printf("Unrecognized cart type!\n");
255 						break;
256 				}
257 			}
258 
259 			if (has_ram)
260 				m_cart->ram_alloc(get_software_region_length("ram"));
261 		}
262 		else
263 		{
264 			fread(ROM, len);
265 			m_type = identify_cart_type(ROM, len);
266 
267 			// check for Special Chip (128bytes of RAM)
268 			if (len == 0x2000 || len == 0x4000 || len == 0x8000)
269 				if (detect_super_chip(ROM, len))
270 				{
271 					m_cart->ram_alloc(0x80);
272 					//printf("Super Chip detected!\n");
273 				}
274 			// Super chip games:
275 			// dig dig, crystal castles, millipede, stargate, defender ii, jr. Pac Man,
276 			// desert falcon, dark chambers, super football, sprintmaster, fatal run,
277 			// off the wall, shooting arcade, secret quest, radar lock, save mary, klax
278 
279 			// add CBS RAM+ (256bytes of RAM)
280 			if (m_type == A26_FA)
281 				m_cart->ram_alloc(0x100);
282 			// add M Network RAM
283 			else if (m_type == A26_E7)
284 				m_cart->ram_alloc(0x800);
285 			// add Commavid RAM
286 			else if (m_type == A26_CV)
287 				m_cart->ram_alloc(0x400);
288 			// add Starpath Superchager RAM
289 			else if (m_type == A26_SS)
290 				m_cart->ram_alloc(0x1800);
291 			// add Boulder Dash RAM
292 			else if (m_type == A26_3E)
293 				m_cart->ram_alloc(0x8000);
294 		}
295 
296 		//printf("Type: %s\n", vcs_get_slot(m_type));
297 
298 		// pass a pointer to the now allocated ROM for the DPC chip
299 		if (m_type == A26_DPC)
300 			m_cart->setup_addon_ptr((uint8_t *)m_cart->get_rom_base() + 0x2000);
301 
302 		return image_init_result::PASS;
303 	}
304 
305 	return image_init_result::PASS;
306 }
307 
308 
309 /*-------------------------------------------------
310  call_unload
311  -------------------------------------------------*/
312 
call_unload()313 void vcs_cart_slot_device::call_unload()
314 {
315 }
316 
317 
318 
319 /*-------------------------------------------------
320   detection helper routines
321  -------------------------------------------------*/
322 
detect_modeDC(const uint8_t * cart,uint32_t len)323 bool vcs_cart_slot_device::detect_modeDC(const uint8_t *cart, uint32_t len)
324 {
325 	int numfound = 0;
326 	// signature is also in 'video reflex'.. maybe figure out that controller port someday...
327 	static const unsigned char signature[3] = { 0x8d, 0xf0, 0xff };
328 
329 	if (len == 0x10000)
330 	{
331 		for (int i = 0; i < len - sizeof signature; i++)
332 		{
333 			if (!memcmp(&cart[i], signature, sizeof signature))
334 			{
335 				numfound = 1;
336 			}
337 		}
338 	}
339 	if (numfound)
340 		return 1;
341 	return 0;
342 }
343 
detect_modeF6(const uint8_t * cart,uint32_t len)344 bool vcs_cart_slot_device::detect_modeF6(const uint8_t *cart, uint32_t len)
345 {
346 	int numfound = 0;
347 	static const unsigned char signature[3] = { 0x8d, 0xf6, 0xff };
348 
349 	if (len == 0x4000)
350 	{
351 		for (int i = 0; i < len - sizeof signature; i++)
352 		{
353 			if (!memcmp(&cart[i], signature, sizeof signature))
354 			{
355 				numfound = 1;
356 			}
357 		}
358 	}
359 	if (numfound)
360 		return 1;
361 	return 0;
362 }
363 
detect_snowhite(const uint8_t * cart,uint32_t len)364 bool vcs_cart_slot_device::detect_snowhite(const uint8_t *cart, uint32_t len)
365 {
366 	static const unsigned char snowwhite[] = { 0x10, 0xd0, 0xff, 0xff }; // Snow White Proto
367 
368 	if (len == 0x2000 && !memcmp(&cart[0x1ffc], snowwhite, sizeof(snowwhite)))
369 		return 1;
370 	return 0;
371 }
372 
detect_mode3E(const uint8_t * cart,uint32_t len)373 bool vcs_cart_slot_device::detect_mode3E(const uint8_t *cart, uint32_t len)
374 {
375 	// this one is a little hacky... looks for STY $3e, which is unique to
376 	// 'not boulderdash', but is the only example I have (cow)
377 	// Would have used STA $3e, but 'Alien' and 'Star Raiders' do that for unknown reasons
378 	int numfound = 0;
379 	static const unsigned char signature[3] = { 0x84, 0x3e, 0x9d };
380 
381 	if (len == 0x0800 || len == 0x1000)
382 	{
383 		for (int i = 0; i < len - sizeof signature; i++)
384 		{
385 			if (!memcmp(&cart[i], signature, sizeof signature))
386 			{
387 				numfound = 1;
388 			}
389 		}
390 	}
391 	if (numfound)
392 		return 1;
393 	return 0;
394 }
395 
detect_modeSS(const uint8_t * cart,uint32_t len)396 bool vcs_cart_slot_device::detect_modeSS(const uint8_t *cart, uint32_t len)
397 {
398 	int numfound = 0;
399 	static const unsigned char signature[5] = { 0xbd, 0xe5, 0xff, 0x95, 0x81 };
400 
401 	if (len == 0x0800 || len == 0x1000)
402 	{
403 		for (int i = 0; i < len - sizeof signature; i++)
404 		{
405 			if (!memcmp(&cart[i], signature, sizeof signature))
406 			{
407 				numfound = 1;
408 			}
409 		}
410 	}
411 	if (numfound)
412 		return 1;
413 	return 0;
414 }
415 
detect_modeFE(const uint8_t * cart,uint32_t len)416 bool vcs_cart_slot_device::detect_modeFE(const uint8_t *cart, uint32_t len)
417 {
418 	int numfound = 0;
419 	static const unsigned char signatures[][5] =  {
420 									{ 0x20, 0x00, 0xd0, 0xc6, 0xc5 },
421 									{ 0x20, 0xc3, 0xf8, 0xa5, 0x82 },
422 									{ 0xd0, 0xfb, 0x20, 0x73, 0xfe },
423 									{ 0x20, 0x00, 0xf0, 0x84, 0xd6 }
424 	};
425 
426 	if (len == 0x2000)
427 	{
428 		for (int i = 0; i < len - sizeof signatures[0]; i++)
429 		{
430 			for (int j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++)
431 			{
432 				if (!memcmp(&cart[i], &signatures[j], sizeof signatures[0]))
433 				{
434 					numfound = 1;
435 				}
436 			}
437 		}
438 	}
439 	if (numfound)
440 		return 1;
441 	return 0;
442 }
443 
detect_modeE0(const uint8_t * cart,uint32_t len)444 bool vcs_cart_slot_device::detect_modeE0(const uint8_t *cart, uint32_t len)
445 {
446 	int numfound = 0;
447 	static const unsigned char signatures[][3] =  {
448 									{ 0x8d, 0xe0, 0x1f },
449 									{ 0x8d, 0xe0, 0x5f },
450 									{ 0x8d, 0xe9, 0xff },
451 									{ 0xad, 0xe9, 0xff },
452 									{ 0xad, 0xed, 0xff },
453 									{ 0xad, 0xf3, 0xbf }
454 	};
455 
456 	if (len == 0x2000)
457 	{
458 		for (int i = 0; i < len - sizeof signatures[0]; i++)
459 		{
460 			for (int j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++)
461 			{
462 				if (!memcmp(&cart[i], &signatures[j], sizeof signatures[0]))
463 				{
464 					numfound = 1;
465 				}
466 			}
467 		}
468 	}
469 	if (numfound)
470 		return 1;
471 	return 0;
472 }
473 
detect_modeCV(const uint8_t * cart,uint32_t len)474 bool vcs_cart_slot_device::detect_modeCV(const uint8_t *cart, uint32_t len)
475 {
476 	int numfound = 0;
477 	static const unsigned char signatures[][3] = {
478 									{ 0x9d, 0xff, 0xf3 },
479 									{ 0x99, 0x00, 0xf4 }
480 	};
481 
482 	if (len == 0x0800 || len == 0x1000)
483 	{
484 		for (int i = 0; i < len - sizeof signatures[0]; i++)
485 		{
486 			for (int j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++)
487 			{
488 				if (!memcmp(&cart[i], &signatures[j], sizeof signatures[0]))
489 				{
490 					numfound = 1;
491 				}
492 			}
493 		}
494 	}
495 	if (numfound)
496 		return 1;
497 	return 0;
498 }
499 
detect_modeFV(const uint8_t * cart,uint32_t len)500 bool vcs_cart_slot_device::detect_modeFV(const uint8_t *cart, uint32_t len)
501 {
502 	int numfound = 0;
503 	static const unsigned char signatures[][3] = { { 0x2c, 0xd0, 0xff } };
504 
505 	if (len == 0x2000)
506 	{
507 		for (int i = 0; i < len - sizeof signatures[0]; i++)
508 		{
509 			for (int j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++)
510 			{
511 				if (!memcmp(&cart[i], &signatures[j], sizeof signatures[0]))
512 				{
513 					numfound = 1;
514 				}
515 			}
516 		}
517 	}
518 	if (numfound)
519 		return 1;
520 	return 0;
521 }
522 
detect_modeJVP(const uint8_t * cart,uint32_t len)523 bool vcs_cart_slot_device::detect_modeJVP(const uint8_t *cart, uint32_t len)
524 {
525 	int numfound = 0;
526 	static const unsigned char signatures[][4] = {
527 									{ 0x2c, 0xc0, 0xef, 0x60 },
528 									{ 0x8d, 0xa0, 0x0f, 0xf0 }
529 	};
530 
531 	if (len == 0x4000 || len == 0x2000)
532 	{
533 		for (int i = 0; i < len - sizeof signatures[0]; i++)
534 		{
535 			for (int j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++)
536 			{
537 				if (!memcmp(&cart[i], &signatures[j], sizeof signatures[0]))
538 				{
539 					numfound = 1;
540 				}
541 			}
542 		}
543 	}
544 	if (numfound)
545 		return 1;
546 	return 0;
547 }
548 
detect_modeE7(const uint8_t * cart,uint32_t len)549 bool vcs_cart_slot_device::detect_modeE7(const uint8_t *cart, uint32_t len)
550 {
551 	int numfound = 0;
552 	static const unsigned char signatures[][3] = {
553 									{ 0xad, 0xe5, 0xff },
554 									{ 0x8d, 0xe7, 0xff }
555 	};
556 
557 	if (len == 0x2000 || len == 0x4000)
558 	{
559 		for (int i = 0; i < len - sizeof signatures[0]; i++)
560 		{
561 			for (int j = 0; j < (sizeof signatures/sizeof signatures[0]) && !numfound; j++)
562 			{
563 				if (!memcmp(&cart[i], &signatures[j], sizeof signatures[0]))
564 				{
565 					numfound = 1;
566 				}
567 			}
568 		}
569 	}
570 	if (numfound)
571 		return 1;
572 	return 0;
573 }
574 
detect_modeUA(const uint8_t * cart,uint32_t len)575 bool vcs_cart_slot_device::detect_modeUA(const uint8_t *cart, uint32_t len)
576 {
577 	int numfound = 0;
578 	static const unsigned char signature[3] = { 0x8d, 0x40, 0x02 };
579 
580 	if (len == 0x2000)
581 	{
582 		for (int i = 0; i < len - sizeof signature; i++)
583 		{
584 			if (!memcmp(&cart[i], signature, sizeof signature))
585 			{
586 				numfound = 1;
587 			}
588 		}
589 	}
590 	if (numfound)
591 		return 1;
592 	return 0;
593 }
594 
detect_8K_mode3F(const uint8_t * cart,uint32_t len)595 bool vcs_cart_slot_device::detect_8K_mode3F(const uint8_t *cart, uint32_t len)
596 {
597 	int numfound = 0;
598 	static const unsigned char signature1[4] = { 0xa9, 0x01, 0x85, 0x3f };
599 	static const unsigned char signature2[4] = { 0xa9, 0x02, 0x85, 0x3f };
600 	// have to look for two signatures because 'not boulderdash' gives false positive otherwise
601 
602 	if (len == 0x2000)
603 	{
604 		for (int i = 0; i < len - sizeof signature1; i++)
605 		{
606 			if (!memcmp(&cart[i], signature1, sizeof signature1))
607 			{
608 				numfound |= 0x01;
609 			}
610 			if (!memcmp(&cart[i], signature2, sizeof signature2))
611 			{
612 				numfound |= 0x02;
613 			}
614 		}
615 	}
616 	if (numfound == 0x03)
617 		return 1;
618 	return 0;
619 }
620 
detect_32K_mode3F(const uint8_t * cart,uint32_t len)621 bool vcs_cart_slot_device::detect_32K_mode3F(const uint8_t *cart, uint32_t len)
622 {
623 	int numfound = 0;
624 	static const unsigned char signature[4] = { 0xa9, 0x0e, 0x85, 0x3f };
625 
626 	if (len >= 0x8000)
627 	{
628 		for (int i = 0; i < len - sizeof signature; i++)
629 		{
630 			if (!memcmp(&cart[i], signature, sizeof signature))
631 			{
632 				numfound++;
633 			}
634 		}
635 	}
636 	if (numfound > 1)
637 		return 1;
638 	return 0;
639 }
640 
detect_super_chip(const uint8_t * cart,uint32_t len)641 bool vcs_cart_slot_device::detect_super_chip(const uint8_t *cart, uint32_t len)
642 {
643 	static const unsigned char signatures[][5] = {
644 									{ 0xa2, 0x7f, 0x9d, 0x00, 0xf0 }, // dig dug
645 									{ 0xae, 0xf6, 0xff, 0x4c, 0x00 } // off the wall
646 	};
647 
648 	if (len == 0x4000)
649 	{
650 		for (int i = 0; i < len - sizeof signatures[0]; i++)
651 		{
652 			for (auto & signature : signatures)
653 			{
654 				if (!memcmp(&cart[i], &signature, sizeof signatures[0]))
655 				{
656 					return 1;
657 				}
658 			}
659 		}
660 	}
661 	for (int i = 0x1000; i < len; i += 0x1000)
662 	{
663 		if (memcmp(cart, cart + i, 0x100))
664 		{
665 			return 0;
666 		}
667 	}
668 	/* Check the reset vector does not point into the super chip RAM area */
669 	if ((((cart[0x0ffd] << 8) | cart[0x0ffc]) & 0x0fff) < 0x0100)
670 	{
671 		return 0;
672 	}
673 	return 1;
674 }
675 
676 
677 /*-------------------------------------------------
678  identify_cart_type - code to detect cart type from
679  fullpath
680  -------------------------------------------------*/
681 
682 // 4in1 & 8in1 are not currently detected from fullpath...
identify_cart_type(const uint8_t * ROM,uint32_t len)683 int vcs_cart_slot_device::identify_cart_type(const uint8_t *ROM, uint32_t len)
684 {
685 	int type = 0xff;
686 
687 	// auto-detect bank mode
688 	if (detect_modeDC(ROM, len))
689 		type = A26_DC;
690 	else if (detect_mode3E(ROM, len))
691 		type = A26_3E;
692 	else if (detect_modeFE(ROM, len))
693 		type = A26_FE;
694 	else if (detect_modeSS(ROM, len))
695 		type = A26_SS;
696 	else if (detect_modeE0(ROM, len))
697 		type = A26_E0;
698 	else if (detect_modeCV(ROM, len))
699 		type = A26_CV;
700 	else if (detect_modeFV(ROM, len))
701 		type = A26_FV;
702 	else if (detect_modeJVP(ROM, len))
703 		type = A26_JVP;
704 	else if (detect_modeUA(ROM, len))
705 		type = A26_UA;
706 	else if (detect_8K_mode3F(ROM, len))
707 		type = A26_3F;
708 	else if (detect_32K_mode3F(ROM, len))
709 		type = A26_3F;
710 	else if (detect_modeE7(ROM, len))
711 		type = A26_E7;
712 	else if (detect_snowhite(ROM, len))
713 		type = A26_F8SW;
714 
715 	// otherwise, choose based on size
716 	if (type == 0xff)
717 	{
718 		switch (len)
719 		{
720 			case 0x800:
721 				type = A26_2K;
722 				break;
723 			case 0x1000:
724 				type = A26_4K;
725 				break;
726 			case 0x2000:
727 				type = A26_F8;
728 				break;
729 			case 0x28ff:
730 			case 0x2900:
731 				type = A26_DPC;
732 				break;
733 			case 0x3000:
734 				type = A26_FA;
735 				break;
736 			case 0x4000:
737 				type = A26_F6;
738 				break;
739 			case 0x8000:
740 				type = A26_F4;
741 				break;
742 			case 0x10000:
743 				type = A26_32IN1;
744 				break;
745 			case 0x80000:
746 				type = A26_3F;
747 				break;
748 			default:
749 				type = A26_4K;
750 				printf("Unrecognized cart type!\n");
751 				break;
752 		}
753 	}
754 
755 	return type;
756 }
757 
758 /*-------------------------------------------------
759  get default card software
760  -------------------------------------------------*/
761 
get_default_card_software(get_default_card_software_hook & hook) const762 std::string vcs_cart_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
763 {
764 	if (hook.image_file())
765 	{
766 		const char *slot_string;
767 		uint32_t len = hook.image_file()->size();
768 		std::vector<uint8_t> rom(len);
769 		int type;
770 
771 		hook.image_file()->read(&rom[0], len);
772 
773 		type = identify_cart_type(&rom[0], len);
774 		slot_string = vcs_get_slot(type);
775 
776 		return std::string(slot_string);
777 	}
778 	else
779 		return software_get_default_slot("a26_4k");
780 }
781 
782 
783 /*-------------------------------------------------
784  read
785  -------------------------------------------------*/
786 
read_rom(offs_t offset)787 uint8_t vcs_cart_slot_device::read_rom(offs_t offset)
788 {
789 	if (m_cart)
790 		return m_cart->read_rom(offset);
791 	else
792 		return 0xff;
793 }
794 
read_bank(address_space & space,offs_t offset)795 uint8_t vcs_cart_slot_device::read_bank(address_space &space, offs_t offset)
796 {
797 	if (m_cart)
798 		return m_cart->read_bank(space, offset);
799 	else
800 		return 0xff;
801 }
802 
803 
804 /*-------------------------------------------------
805  write
806  -------------------------------------------------*/
807 
write_bank(address_space & space,offs_t offset,uint8_t data)808 void vcs_cart_slot_device::write_bank(address_space &space, offs_t offset, uint8_t data)
809 {
810 	if (m_cart)
811 		m_cart->write_bank(space, offset, data);
812 }
813 
write_ram(offs_t offset,uint8_t data)814 void vcs_cart_slot_device::write_ram(offs_t offset, uint8_t data)
815 {
816 	if (m_cart)
817 		m_cart->write_ram(offset, data);
818 }
819