Exemple #1
0
static int plus4_crt_load( device_image_interface &image )
{
	UINT8 *mem = image.device().machine().root_device().memregion("maincpu")->base();
	int size = image.length(), test;
	const char *filetype;
	int address = 0;

	/* magic lowrom at offset 7: $43 $42 $4d */
	/* if at offset 6 stands 1 it will immediatly jumped to offset 0 (0x8000) */
	static const unsigned char magic[] = {0x43, 0x42, 0x4d};
	unsigned char buffer[sizeof (magic)];

	image.fseek(7, SEEK_SET);
	image.fread( buffer, sizeof (magic));
	image.fseek(0, SEEK_SET);

	/* Check if our cart has the magic string, and set its loading address */
	if (!memcmp(buffer, magic, sizeof (magic)))
		address = 0x20000;

	/* Give a loading address to non .bin / non .rom carts as well */
	filetype = image.filetype();

	/* We would support .hi and .lo files, but currently I'm not sure where to load them.
       We simply load them at 0x20000 at this stage, even if it's probably wrong!
       It could also well be that they both need to be loaded at the same time, but this
       is now impossible since I reduced to 1 the number of cart slots.
       More investigations are in order if any .hi, .lo dump would surface!              */
	if (!mame_stricmp(filetype, "hi"))
		address = 0x20000;	/* FIX ME! */

	else if (!mame_stricmp(filetype, "lo"))
		address = 0x20000;	/* FIX ME! */

	/* As a last try, give a reasonable loading address also to .bin/.rom without the magic string */
	else if (!address)
	{
		logerror("Cart %s does not contain the magic string: it may be loaded at the wrong memory address!\n", image.filename());
		address = 0x20000;
	}

	logerror("Loading cart %s at %.5x size:%.4x\n", image.filename(), address, size);

	/* Finally load the cart */
	test = image.fread( mem + address, size);

	if (test != size)
		return IMAGE_INIT_FAIL;

	return IMAGE_INIT_PASS;
}
Exemple #2
0
static int c64_crt_load( device_image_interface &image )
{
	legacy_c64_state *state = image.device().machine().driver_data<legacy_c64_state>();
	int size = image.length(), test, i = 0, ii;
	int _80_loaded = 0, _90_loaded = 0, a0_loaded = 0, b0_loaded = 0, e0_loaded = 0, f0_loaded = 0;
	const char *filetype = image.filetype();
	int address = 0, new_start = 0;
	// int lbank_end_addr = 0, hbank_end_addr = 0;
	UINT8 *cart_cpy = state->memregion("user1")->base();

	/* We support .crt files */
	if (!mame_stricmp(filetype, "crt"))
	{
		int j;
		unsigned short c64_cart_type;

		if (i >= C64_MAX_ROMBANK)
			return IMAGE_INIT_FAIL;

		/* Start to parse the .crt header */
		/* 0x16-0x17 is Hardware type */
		image.fseek(0x16, SEEK_SET);
		image.fread(&c64_cart_type, 2);
		state->m_cart.mapper = BIG_ENDIANIZE_INT16(c64_cart_type);

		/* If it is unsupported cart type, warn the user */
		switch (state->m_cart.mapper)
		{
			case SIMONS_BASIC:	/* Type #  4 */
			case OCEAN_1:		/* Type #  5 */
			case FUN_PLAY:		/* Type #  7 */
			case SUPER_GAMES:		/* Type #  8 */
			case EPYX_FASTLOAD:	/* Type # 10 */
			case REX:			/* Type # 12 */
			case C64GS:			/* Type # 15 */
			case DINAMIC:		/* Type # 17 */
			case ZAXXON:		/* Type # 18 */
			case DOMARK:		/* Type # 19 */
			case COMAL_80:		/* Type # 21 */
			case GENERIC_CRT:		/* Type #  0 */
				printf("Currently supported cart type (Type %d)\n", state->m_cart.mapper);
				break;

			default:
			case ACTION_REPLAY:	/* Type #  1 */
			case KCS_PC:		/* Type #  2 */
			case FINAL_CART_III:	/* Type #  3 */
			case EXPERT:		/* Type #  6 */
			case ATOMIC_POWER:	/* Type #  9 */
			case WESTERMANN:		/* Type # 11 */
			case FINAL_CART_I:	/* Type # 13 */
			case MAGIC_FORMEL:	/* Type # 14 */
			case SUPER_SNAP_5:	/* Type # 20 */
				printf("Currently unsupported cart type (Type %d)\n", state->m_cart.mapper);
				break;
		}

		/* 0x18 is EXROM */
		image.fseek(0x18, SEEK_SET);
		image.fread(&state->m_cart.exrom, 1);

		/* 0x19 is GAME */
		image.fread(&state->m_cart.game, 1);

		/* We can pass to the data: it starts from 0x40 */
		image.fseek(0x40, SEEK_SET);
		j = 0x40;

		logerror("Loading cart %s size:%.4x\n", image.filename(), size);
		logerror("Header info: EXROM %d, GAME %d, Cart Type %d \n", state->m_cart.exrom, state->m_cart.game, c64_cart_type);


		/* Data in a .crt image are organized in blocks called 'CHIP':
           each 'CHIP' consists of a 0x10 header, which contains the
           actual size of the block, the loading address and info on
           the bankswitch, followed by the actual data                  */
		while (j < size)
		{
			unsigned short chip_size, chip_bank_index, chip_data_size;
			unsigned char buffer[10];

			/* Start to parse the CHIP header */
			/* First 4 bytes are the string 'CHIP' */
			image.fread(buffer, 6);

			/* 0x06-0x07 is the size of the CHIP block (header + data) */
			image.fread(&chip_size, 2);
			chip_size = BIG_ENDIANIZE_INT16(chip_size);

			/* 0x08-0x09 chip type (ROM, RAM + no ROM, Flash ROM) */
			image.fread(buffer + 6, 2);

			/* 0x0a-0x0b is the bank number of the CHIP block */
			image.fread(&chip_bank_index, 2);
			chip_bank_index = BIG_ENDIANIZE_INT16(chip_bank_index);

			/* 0x0c-0x0d is the loading address of the CHIP block */
			image.fread(&address, 2);
			address = BIG_ENDIANIZE_INT16(address);

			/* 0x0e-0x0f is the data size of the CHIP block (without header) */
			image.fread(&chip_data_size, 2);
			chip_data_size = BIG_ENDIANIZE_INT16(chip_data_size);

			/* Print out the CHIP header! */
			logerror("%.4s %.2x %.2x %.4x %.2x %.2x %.4x %.4x:%.4x\n",
				buffer, buffer[4], buffer[5], chip_size,
				buffer[6], buffer[7], chip_bank_index,
				address, chip_data_size);
			logerror("Loading CHIP data at %.4x size:%.4x\n", address, chip_data_size);

			/* Store data, address & size of the CHIP block */
			state->m_cart.bank[i].addr = address;
			state->m_cart.bank[i].index = chip_bank_index;
			state->m_cart.bank[i].size = chip_data_size;
			state->m_cart.bank[i].start = new_start;

			test = image.fread(cart_cpy + new_start, state->m_cart.bank[i].size);
			new_start += state->m_cart.bank[i].size;

			/* Does CHIP contain any data? */
			if (test != state->m_cart.bank[i].size)
				return IMAGE_INIT_FAIL;

			/* Advance to the next CHIP block */
			i++;
			j += chip_size;
		}
	}
	else /* We also support .80 files for c64 & .e0/.f0 for max */
	{
		/* Assign loading address according to extension */
		if (!mame_stricmp(filetype, "80"))
			address = 0x8000;

		if (!mame_stricmp(filetype, "e0"))
			address = 0xe000;

		if (!mame_stricmp(filetype, "f0"))
			address = 0xf000;

		logerror("loading %s rom at %.4x size:%.4x\n", image.filename(), address, size);

		/* Store data, address & size */
		state->m_cart.bank[0].addr = address;
		state->m_cart.bank[0].size = size;
		state->m_cart.bank[0].start = new_start;

		test = image.fread(cart_cpy + new_start, state->m_cart.bank[0].size);
		new_start += state->m_cart.bank[0].size;

		/* Does cart contain any data? */
		if (test != state->m_cart.bank[0].size)
			return IMAGE_INIT_FAIL;
	}

	state->m_cart.n_banks = i; // this is also needed so that we only set mappers if a cart is present!

	/* If we load a .crt file, use EXROM & GAME from the header! */
	if ((state->m_cart.exrom != -1) && (state->m_cart.game != -1))
	{
		state->m_exrom = state->m_cart.exrom;
		state->m_game  = state->m_cart.game;
	}

	/* Finally load the cart */
	state->m_roml = state->m_c64_roml;
	state->m_romh = state->m_c64_romh;

	memset(state->m_roml, 0, 0x2000);
	memset(state->m_romh, 0, 0x2000);

	switch (state->m_cart.mapper)
	{
	default:
		if (!state->m_game && state->m_exrom && (state->m_cart.n_banks == 1))
		{
			memcpy(state->m_romh, cart_cpy, 0x2000);
		}
		else
		{
			// we first attempt to load the first 'CHIPs' with address 0x8000-0xb000 and 0xe000-0xf000, otherwise we load the first (or first two) 'CHIPs' of the image
			for (ii = 0; ii < state->m_cart.n_banks; ii++)
			{
				if (state->m_cart.bank[ii].addr == 0x8000 && !_80_loaded)
				{
					memcpy(state->m_roml, cart_cpy + state->m_cart.bank[ii].start, state->m_cart.bank[ii].size);
					_80_loaded = 1;
					if (state->m_cart.bank[ii].size > 0x1000)
						_90_loaded = 1;
					if (state->m_cart.bank[ii].size > 0x2000)
						a0_loaded = 1;
					if (state->m_cart.bank[ii].size > 0x3000)
						b0_loaded = 1;
//                  printf("addr 0x8000: 80 %d, 90 %d, a0 %d, b0 %d\n", _80_loaded, _90_loaded, a0_loaded, b0_loaded);
				}

				if (state->m_cart.bank[ii].addr == 0x9000 && !_90_loaded)
				{
					memcpy(state->m_roml + 0x1000, cart_cpy + state->m_cart.bank[ii].start, state->m_cart.bank[ii].size);
					_90_loaded = 1;
					if (state->m_cart.bank[ii].size > 0x1000)
						a0_loaded = 1;
					if (state->m_cart.bank[ii].size > 0x2000)
						b0_loaded = 1;
//                  printf("addr 0x9000: 80 %d, 90 %d, a0 %d, b0 %d\n", _80_loaded, _90_loaded, a0_loaded, b0_loaded);
				}

				if (state->m_cart.bank[ii].addr == 0xa000 && !a0_loaded)
				{
					memcpy(state->m_roml + 0x2000, cart_cpy + state->m_cart.bank[ii].start, state->m_cart.bank[ii].size);
					a0_loaded = 1;
					if (state->m_cart.bank[ii].size > 0x1000)
						b0_loaded = 1;
//                  printf("addr 0xa000: 80 %d, 90 %d, a0 %d, b0 %d\n", _80_loaded, _90_loaded, a0_loaded, b0_loaded);
				}

				if (state->m_cart.bank[ii].addr == 0xb000 && !b0_loaded)
				{
					memcpy(state->m_roml + 0x3000, cart_cpy + state->m_cart.bank[ii].start, state->m_cart.bank[ii].size);
					b0_loaded = 1;
//                  printf("addr 0xb000: 80 %d, 90 %d, a0 %d, b0 %d\n", _80_loaded, _90_loaded, a0_loaded, b0_loaded);
				}

				if (state->m_cart.bank[ii].addr == 0xe000 && !e0_loaded)
				{
					memcpy(state->m_romh, cart_cpy + state->m_cart.bank[ii].start, state->m_cart.bank[ii].size);
					e0_loaded = 1;
					if (state->m_cart.bank[ii].size > 0x1000)
						f0_loaded = 1;
//                  printf("addr 0xe000: e0 %d, f0 %d\n", e0_loaded, f0_loaded);
				}

				if (state->m_cart.bank[ii].addr == 0xf000 && !f0_loaded)
				{
					memcpy(state->m_romh + 0x1000, cart_cpy + state->m_cart.bank[ii].start, state->m_cart.bank[ii].size);
					f0_loaded = 1;
//                  printf("addr 0xe000: e0 %d, f0 %d\n", e0_loaded, f0_loaded);
				}
			}
		}
	}

	return IMAGE_INIT_PASS;
}
Exemple #3
0
static void atari_load_proc(device_image_interface &image)
{
	atari_fdc_t *fdc = get_safe_token(image.device().owner());
	int id = floppy_get_drive(image);
	int size, i;
	const char *ext;

	fdc->drv[id].image = auto_alloc_array(image.device().machine(),UINT8,MAXSIZE);
	if (!fdc->drv[id].image)
		return;

	/* tell whether the image is writable */
	fdc->drv[id].mode = !image.is_readonly();
	/* set up image if it has been created */
	if (image.has_been_created())
	{
		int sector;
		char buff[256];
		memset(buff, 0, sizeof(buff));
		/* default to 720 sectors */
		for( sector = 0; sector < 720; sector++ )
			image.fwrite(buff, 256);
		image.fseek(0, SEEK_SET);
	}

	size = image.fread(fdc->drv[id].image, MAXSIZE);

	if( size <= 0 )
	{
		fdc->drv[id].image = NULL;
		return;
	}


	/* re allocate the buffer; we don't want to be too lazy ;) */
	//fdc->drv[id].image = (UINT8*)image.image_realloc(fdc->drv[id].image, size);

	ext = image.filetype();

	// hack alert, this means we can only load ATR via the softlist at the moment, image.filetype reutrns NULL :/
	if (image.software_entry() != NULL) ext="ATR";

	/* no extension: assume XFD format (no header) */
	if (!ext)
	{
		fdc->drv[id].type = FORMAT_XFD;
		fdc->drv[id].header_skip = 0;
	}
	else
	/* XFD extension */
	if( toupper(ext[0])=='X' && toupper(ext[1])=='F' && toupper(ext[2])=='D' )
	{
		fdc->drv[id].type = FORMAT_XFD;
		fdc->drv[id].header_skip = 0;
	}
	else
	/* ATR extension */
	if( toupper(ext[0])=='A' && toupper(ext[1])=='T' && toupper(ext[2])=='R' )
	{
		fdc->drv[id].type = FORMAT_ATR;
		fdc->drv[id].header_skip = 16;
	}
	else
	/* DSK extension */
	if( toupper(ext[0])=='D' && toupper(ext[1])=='S' && toupper(ext[2])=='K' )
	{
		fdc->drv[id].type = FORMAT_DSK;
		fdc->drv[id].header_skip = sizeof(dsk_format);
	}
	else
	{
		fdc->drv[id].type = FORMAT_XFD;
		fdc->drv[id].header_skip = 0;
	}

	if( fdc->drv[id].type == FORMAT_ATR &&
		(fdc->drv[id].image[0] != 0x96 || fdc->drv[id].image[1] != 0x02) )
	{
		fdc->drv[id].type = FORMAT_XFD;
		fdc->drv[id].header_skip = 0;
	}


	switch (fdc->drv[id].type)
	{
	/* XFD or unknown format: find a matching size from the table */
	case FORMAT_XFD:
		for( i = 0; xfd_formats[i].size; i++ )
		{
			if( size == xfd_formats[i].size )
			{
				fdc->drv[id].density = xfd_formats[i].dsk.density;
				fdc->drv[id].tracks = xfd_formats[i].dsk.tracks;
				fdc->drv[id].spt = xfd_formats[i].dsk.spt;
				fdc->drv[id].heads = (xfd_formats[i].dsk.doublesided) ? 2 : 1;
				fdc->drv[id].bseclen = 128;
				fdc->drv[id].seclen = 256 * xfd_formats[i].dsk.seclen_hi + xfd_formats[i].dsk.seclen_lo;
				fdc->drv[id].sectors = fdc->drv[id].tracks * fdc->drv[id].heads * fdc->drv[id].spt;
				break;
			}
		}
		break;
	/* ATR format: find a size including the 16 bytes header */
	case FORMAT_ATR:
		{
			int s;
			fdc->drv[id].bseclen = 128;
			/* get sectors from ATR header */
			s = (size - 16) / 128;
			/* 3 + odd number of sectors ? */
			if ( fdc->drv[id].image[4] == 128 || (s % 18) == 0 || (s % 26) == 0 || ((s - 3) % 1) != 0 )
			{
				fdc->drv[id].sectors = s;
				fdc->drv[id].seclen = 128;
				/* sector size 128 or count not evenly dividable by 26 ? */
				if( fdc->drv[id].seclen == 128 || (s % 26) != 0 )
				{
					/* yup! single density */
					fdc->drv[id].density = 0;
					fdc->drv[id].spt = 18;
					fdc->drv[id].heads = 1;
					fdc->drv[id].tracks = s / 18;
					if( s % 18 != 0 )
						fdc->drv[id].tracks += 1;
					if( fdc->drv[id].tracks % 2 == 0 && fdc->drv[id].tracks > 80 )
					{
						fdc->drv[id].heads = 2;
						fdc->drv[id].tracks /= 2;
					}
				}
				else
				{
					/* yes: medium density */
					fdc->drv[id].density = 0;
					fdc->drv[id].spt = 26;
					fdc->drv[id].heads = 1;
					fdc->drv[id].tracks = s / 26;
					if( s % 26 != 0 )
						fdc->drv[id].tracks += 1;
					if( fdc->drv[id].tracks % 2 == 0 && fdc->drv[id].tracks > 80 )
					{
						fdc->drv[id].heads = 2;
						fdc->drv[id].tracks /= 2;
					}
				}
			}
			else
			{
				/* it's double density */
				s = (s - 3) / 2 + 3;
				fdc->drv[id].sectors = s;
				fdc->drv[id].density = 2;
				fdc->drv[id].seclen = 256;
				fdc->drv[id].spt = 18;
				fdc->drv[id].heads = 1;
				fdc->drv[id].tracks = s / 18;
				if( s % 18 != 0 )
					fdc->drv[id].tracks += 1;
				if( fdc->drv[id].tracks % 2 == 0 && fdc->drv[id].tracks > 80 )
				{
					fdc->drv[id].heads = 2;
					fdc->drv[id].tracks /= 2;
				}
			}
		}
		break;
	/* DSK format: it's all in the header */
	case FORMAT_DSK:
		{
			dsk_format *dsk = (dsk_format *) fdc->drv[id].image;

			fdc->drv[id].tracks = dsk->tracks;
			fdc->drv[id].spt = dsk->spt;
			fdc->drv[id].heads = (dsk->doublesided) ? 2 : 1;
			fdc->drv[id].seclen = 256 * dsk->seclen_hi + dsk->seclen_lo;
			fdc->drv[id].bseclen = fdc->drv[id].seclen;
			fdc->drv[id].sectors = fdc->drv[id].tracks * fdc->drv[id].heads * fdc->drv[id].spt;
		}
		break;
	}
	logerror("atari opened floppy '%s', %d sectors (%d %s%s) %d bytes/sector\n",
			image.filename(),
			fdc->drv[id].sectors,
			fdc->drv[id].tracks,
			(fdc->drv[id].heads == 1) ? "SS" : "DS",
			(fdc->drv[id].density == 0) ? "SD" : (fdc->drv[id].density == 1) ? "MD" : "DD",
			fdc->drv[id].seclen);
	return;
}