Exemplo n.º 1
0
		Result Cartridge::SetupBoard
		(
			Ram& prg,
			Ram& chr,
			Boards::Board** board,
			const Context* const context,
			Profile& profile,
			const ProfileEx& profileEx,
			dword* const prgCrc,
			const bool readOnly
		)
		{
			NST_ASSERT( bool(board) == bool(context) );

			Boards::Board::Type::Nmt nmt;

			if (profile.board.solderPads & (Profile::Board::SOLDERPAD_H|Profile::Board::SOLDERPAD_V))
			{
				if (profile.board.solderPads & Profile::Board::SOLDERPAD_H)
					nmt = Boards::Board::Type::NMT_VERTICAL;
				else
					nmt = Boards::Board::Type::NMT_HORIZONTAL;
			}
			else switch (profileEx.nmt)
			{
				case ProfileEx::NMT_HORIZONTAL:   nmt = Boards::Board::Type::NMT_HORIZONTAL;   break;
				case ProfileEx::NMT_VERTICAL:     nmt = Boards::Board::Type::NMT_VERTICAL;     break;
				case ProfileEx::NMT_SINGLESCREEN: nmt = Boards::Board::Type::NMT_SINGLESCREEN; break;
				case ProfileEx::NMT_FOURSCREEN:   nmt = Boards::Board::Type::NMT_FOURSCREEN;   break;
				default:                          nmt = Boards::Board::Type::NMT_CONTROLLED;   break;
			}

			Chips chips;

			for (Profile::Board::Chips::const_iterator i(profile.board.chips.begin()), end(profile.board.chips.end()); i != end; ++i)
			{
				Chips::Type& type = chips.Add( i->type.c_str() );

				for (Profile::Board::Pins::const_iterator j(i->pins.begin()), end(i->pins.end()); j != end; ++j)
					type.Pin(j->number) = j->function.c_str();

				for (Profile::Board::Samples::const_iterator j(i->samples.begin()), end(i->samples.end()); j != end; ++j)
					type.Sample(j->id) = j->file.c_str();
			}

			Boards::Board::Context b
			(
				context ? &context->cpu : NULL,
				context ? &context->apu : NULL,
				context ? &context->ppu : NULL,
				prg,
				chr,
				profileEx.trainer,
				nmt,
				profileEx.battery || profile.board.HasWramBattery(),
				profile.board.HasMmcBattery(),
				chips
			);

			if (profile.board.type.empty() || !b.DetectBoard( profile.board.type.c_str(), profile.board.GetWram() ))
			{
				if (profile.board.mapper == Profile::Board::NO_MAPPER || !b.DetectBoard( profile.board.mapper, profile.board.GetWram(), profileEx.wramAuto, profile.board.subMapper ) && board)
					return RESULT_ERR_UNSUPPORTED_MAPPER;

				if (profile.board.type.empty())
					profile.board.type = std::wstring( b.name, b.name + std::strlen(b.name) );
			}

			if (profile.board.mapper == Profile::Board::NO_MAPPER && b.type.GetMapper() != Boards::Board::Type::NMPR)
				profile.board.mapper = b.type.GetMapper();

			for (uint i=0; i < 2; ++i)
			{
				dword size = (i ? b.chr : b.prg).Size();

				if (size != (i ? profile.board.GetChr() : profile.board.GetPrg()))
				{
					Profile::Board::Roms& roms = (i ? profile.board.chr : profile.board.prg);
					roms.clear();

					if (size)
					{
						Profile::Board::Rom rom;
						rom.size = size;
						roms.push_back( rom );
					}
				}

				size = (i ? b.type.GetVram() : b.type.GetWram());

				if (size != (i ? profile.board.GetVram() : profile.board.GetWram()))
				{
					Profile::Board::Rams& rams = (i ? profile.board.vram : profile.board.wram);
					rams.clear();

					for (uint j=0; j < 2; ++j)
					{
						size = i ? (j ? b.type.GetNonSavableVram() : b.type.GetSavableVram()) :
                                   (j ? b.type.GetNonSavableWram() : b.type.GetSavableWram());

						if (size)
						{
							Profile::Board::Ram ram;
							ram.size = size;
							ram.battery = (i == 0 && j == 0 && b.wramBattery);
							rams.push_back( ram );
						}
					}
				}

				Profile::Board::Roms& roms = (i ? profile.board.chr : profile.board.prg);

				for (dword j=0, k=0, n=roms.size(); j < n; k += roms[j].size, ++j)
					roms[j].hash.Compute( (i ? chr : prg).Mem(k), roms[j].size );
			}

			if (!readOnly)
			{
				Checksum checksum;

				checksum.Compute( prg.Mem(), prg.Size() );

				if (prgCrc)
					*prgCrc = checksum.GetCrc();

				checksum.Compute( chr.Mem(), chr.Size() );
				profile.hash.Assign( checksum.GetSha1(), checksum.GetCrc() );
			}

			if (board)
				*board = Boards::Board::Create( b );

			return RESULT_OK;
		}