#include "mapinc.h" static int PA; uint8 FASTCALL Mapper218_PPURead(uint32 A) { 	extern uint8 PALRAM[0x20]; 	extern uint8 UPALRAM[0x03]; 	uint32 tmp = A; 	if (tmp < 0x3f00) { 		return NTARAM[(((tmp>>PA)&1)<<10)|(tmp&0x03ff)]; 	} else { 		if (tmp & 0x03) { 			return PALRAM[tmp & 0x1f] & ((PPU[1] & 0x01) ? 0x30 : 0xFF); 		} else if (tmp & 0x0c) { 			return UPALRAM[tmp & 0x0c] & ((PPU[1] & 0x01) ? 0x30 : 0xFF); 		} else { 			return PALRAM[0x00] & ((PPU[1] & 0x01) ? 0x30 : 0xFF); 		} 	} } static void Mapper218_PPUWrite(uint32 A, uint8 V) { 	extern uint8 PALRAM[0x20]; 	extern uint8 UPALRAM[0x03]; 	uint32 tmp = A; 	if (tmp < 0x3f00) { 		switch (PA) { 		case 10: 			if ((tmp>>PA)&1) { 				if (PPUCHRRAM & 0x02) VPage[1][0x0400|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x08) VPage[3][0x0c00|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x20) VPage[5][0x1400|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x80) VPage[7][0x1c00|(tmp&0x03ff)] = V; 			} else { 				if (PPUCHRRAM & 0x01) VPage[0][0x0000|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x04) VPage[2][0x0800|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x10) VPage[4][0x1000|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x40) VPage[6][0x1800|(tmp&0x03ff)] = V; 			} 			break; 		case 11: 			if ((tmp>>PA)&1) { 				if (PPUCHRRAM & 0x04) VPage[2][0x0800|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x08) VPage[3][0x0c00|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x40) VPage[6][0x1800|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x80) VPage[7][0x1c00|(tmp&0x03ff)] = V; 			} else { 				if (PPUCHRRAM & 0x01) VPage[0][0x0000|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x02) VPage[1][0x0400|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x10) VPage[4][0x1000|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x20) VPage[5][0x1400|(tmp&0x03ff)] = V; 			} 			break; 		case 12: 			if ((tmp>>PA)&1) { 				if (PPUCHRRAM & 0x10) VPage[4][0x1000|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x20) VPage[5][0x1400|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x80) VPage[7][0x1800|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x40) VPage[6][0x1c00|(tmp&0x03ff)] = V; 			} else { 				if (PPUCHRRAM & 0x01) VPage[0][0x0000|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x02) VPage[1][0x0400|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x04) VPage[2][0x1800|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x08) VPage[3][0x1c00|(tmp&0x03ff)] = V; 			} 			break; 		case 13: 			if ((tmp>>PA)&1) { 				/* nothing */ 			} else { 				if (PPUCHRRAM & 0x01) VPage[0][0x0000|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x02) VPage[1][0x0400|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x04) VPage[2][0x0800|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x08) VPage[3][0x0c00|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x10) VPage[4][0x1000|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x20) VPage[5][0x1400|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x80) VPage[7][0x1800|(tmp&0x03ff)] = V; 				if (PPUCHRRAM & 0x40) VPage[6][0x1c00|(tmp&0x03ff)] = V; 			} 			break; 		} 		NTARAM[(((tmp>>PA)&1)<<10)|(tmp&0x03ff)] = V; 	} else { 		if (tmp & 0x03) { 			PALRAM[tmp & 0x1f] = V & 0x3f; 		} else if (tmp & 0x0c) { 			UPALRAM[((tmp & 0x0c) >> 2)-1] = V & 0x3f; 		} else { 			PALRAM[0x00] = PALRAM[0x04] = PALRAM[0x08] = PALRAM[0x0c] = V & 0x3f; 			PALRAM[0x10] = PALRAM[0x14] = PALRAM[0x18] = PALRAM[0x1c] = V & 0x3f; 		} 	} } void Mapper218_Power(void) { 	uint8 mir = FCEU_ReadRomByte(6); 	// Register a handler for memory access. 	SetReadHandler(0x8000, 0xffff, CartBR); 	// Bank settings for fixed area. 	setprg16(0x8000, ~1); 	setprg16(0xC000, ~0); 	setchr8(0); 	// Nametable milloring settings at startup. 	switch (mir & 0x9) { 	case 0x00: 		PA = 11; 		setmirror(MI_H); 		break; 	case 0x01: 		PA = 10; 		setmirror(MI_V); 		break; 	case 0x08: 		PA = 12; 		setmirror(MI_0); 		break; 	case 0x09: 		PA = 13; 		setmirror(MI_1); 		break; 	} } void Mapper218_Init(CartInfo *info) { 	// Register callback. 	info->Power = Mapper218_Power; 	FFCEUX_PPURead = Mapper218_PPURead; 	FFCEUX_PPUWrite = Mapper218_PPUWrite; 	PA = 10; }