www.pudn.com > EloGbaR1.zip > memory.c


#include "gbaemu.h" 
 
__inline void mem_write_u32 (u8 *dest, u32 temp, u32 data) 
{	 
	switch (temp&0x3)  
	{ 
		case 0: 
			((u32*)dest) [temp>>2] = data;	 
			break; 
		case 1: 
			dest [temp++] = (u8)data&0xFF; 
			dest [temp++] = (u8)((data&0xFF00)>>8); 
			dest [temp++] = (u8)((data&0xFF0000)>>16); 
			dest [temp]   = (u8)((data&0xFF000000)>>24); 
			break; 
		case 2: 
			temp = temp>>1; 
			((u16*)dest) [temp++] = (u16)data&0xFFFF;  
			((u16*)dest) [temp]   = (u16)((data&0xFFFF0000)>>16); 
			break; 
		case 3: 
			dest [temp++] = (u8)data&0xFF; 
			dest [temp++] = (u8)((data&0xFF00)>>8); 
			dest [temp++] = (u8)((data&0xFF0000)>>16); 
			dest [temp]   = (u8)((data&0xFF000000)>>24); 
			break; 
	} 
} 
 
__inline u32 mem_read_u32 (u8 *dest, u32 adress) 
{ 
	switch (adress&0x3)  
	{ 
		case 0: 
			return ((u32*)dest) [adress>>2]; 
		case 1: 
			return ((u32)dest[adress++])|(dest[adress++]<<8)|(dest[adress++]<<16)|(dest[adress]<<24); 
		case 2: 
			adress = adress>>1; 
			return (u32)(((u16*)dest) [adress]|(((u16*)dest) [adress+1]<<16)); 
		case 3: 
			return ((u32)dest[adress++])|(dest[adress++]<<8)|(dest[adress++]<<16)|(dest[adress]<<24); 
		default: 
			return 0; 
	} 
} 
 
__inline mem_write_u16 (u8 *dest, u32 adress, u16 data) 
{ 
	if (adress&0x1) { 
		dest [adress++] = (u8)data&0xFF; 
		dest [adress]   = (u8)((data&0xFF00)>>8); 
	} 
	else { 
		((u16*)dest) [adress>>1] = data; 
	} 
} 
 
__inline u16 mem_read_u16 (u8 *dest, u32 adress) 
{ 
	if (adress&0x1) { 
		return (((u16)dest[adress++])|(dest[adress++]<<8)); 
	} 
	else { 
		return (((u16*)dest) [adress>>1]); 
	} 
} 
 
__inline u32 rom_read_u32 (u32 adress) 
{ 
	u8 value1, value2, value3, value4; 
	u16 temp1, temp2; 
 
	switch (adress&0x3)  
	{ 
		case 0: 
			return rom_pages_u32 [(adress>>16)&0x1FF] [(adress>>2)&0x3FFF]; 
		case 1: 
			value1 = rom_pages_u8 [(adress>>16)&0x1FF] [adress&0xFFFF]; 
			value2 = rom_pages_u8 [((adress+1)>>16)&0x1FF] [(adress+1)&0xFFFF]; 
			value3 = rom_pages_u8 [((adress+2)>>16)&0x1FF] [(adress+2)&0xFFFF]; 
			value4 = rom_pages_u8 [((adress+3)>>16)&0x1FF] [(adress+3)&0xFFFF]; 
			return ((u32)value1)|(value2<<8)|(value3<<16)|(value4<<24); 
		case 2: 
			temp1 = rom_pages_u16 [(adress>>16)&0x1FF] [(adress>>1)&0x7FFF]; 
			temp2 = rom_pages_u16 [((adress+2)>>16)&0x1FF] [((adress+2)>>1)&0x7FFF]; 
			return ((u32)temp1)|(temp2<<16); 
		case 3: 
			value1 = rom_pages_u8 [(adress>>16)&0x1FF] [adress&0xFFFF]; 
			value2 = rom_pages_u8 [(adress>>16)&0x1FF] [(adress+1)&0xFFFF]; 
			value3 = rom_pages_u8 [(adress>>16)&0x1FF] [(adress+2)&0xFFFF]; 
			value4 = rom_pages_u8 [(adress>>16)&0x1FF] [(adress+3)&0xFFFF]; 
			return ((u32)value1)|(value2<<8)|(value3<<16)|(value4<<24); 
		default: 
			return 0; 
	} 
} 
 
__inline void rom_write_u32 (u32 adress, u32 data) 
{ 
	switch (adress&0x3)  
	{ 
		case 0: 
			rom_pages_u32 [(adress>>16)&0x1FF] [(adress>>2)&0x3FFF] = data; 
		case 1: 
			rom_pages_u8 [(adress>>16)&0x1FF] [adress&0xFFFF] = (u8)data; 
			rom_pages_u8 [((adress+1)>>16)&0x1FF] [(adress+1)&0xFFFF] = (u8)(data>>8); 
			rom_pages_u8 [((adress+2)>>16)&0x1FF] [(adress+2)&0xFFFF] = (u8)(data>>16); 
			rom_pages_u8 [((adress+3)>>16)&0x1FF] [(adress+3)&0xFFFF] = (u8)(data>>24); 
		case 2: 
			rom_pages_u16 [(adress>>16)&0x1FF] [(adress>>1)&0x7FFF] = (u16)data; 
			rom_pages_u16 [((adress+2)>>16)&0x1FF] [((adress+2)>>1)&0x7FFF] = (u16)(data>>16); 
		case 3: 
			rom_pages_u8 [(adress>>16)&0x1FF] [adress&0xFFFF] = (u8)data; 
			rom_pages_u8 [((adress+1)>>16)&0x1FF] [(adress+1)&0xFFFF] = (u8)(data>>8); 
			rom_pages_u8 [((adress+2)>>16)&0x1FF] [(adress+2)&0xFFFF] = (u8)(data>>16); 
			rom_pages_u8 [((adress+3)>>16)&0x1FF] [(adress+3)&0xFFFF] = (u8)(data>>24); 
	} 
} 
 
__inline void rom_write_u16 (u32 adress, u16 data) 
{ 
	if (adress&0x1) { 
		rom_pages_u8 [(adress>>16)&0x1FF] [adress&0xFFFF] = (u8)data; 
		rom_pages_u8 [((adress+1)>>16)&0x1FF] [(adress+1)&0xFFFF] = (u8)(data>>8); 
	} 
	else { 
		rom_pages_u16 [(adress>>16)&0x1FF] [(adress>>1)&0x7FFF] = data; 
	} 
} 
 
__inline u16 rom_read_u16 (u32 adress) 
{ 
	if (adress&0x1) { 
		return ((u16)rom_pages_u8[(adress>>16)&0x1FF][adress&0xFFFF])|(rom_pages_u8[((adress+1)>>16)&0x1FF][(adress+1)&0xFFFF]<<8); 
	} 
	else { 
		return rom_pages_u16 [(adress>>16)&0x1FF] [(adress>>1)&0x7FFF]; 
	} 
} 
 
/**********************************************************************************************/ 
 
u8 read_byte (u32 adress) 
{ 
	switch ((adress & 0xFF000000)>>24) 
	{ 
		case 0: 
			return zero_page_u8 [adress&0xFF]; 
		case 1: 
			return 0; 
		case 2: 
			return wram_ext_u8 [adress&0x3FFFF]; 
		case 3: 
			return wram_int_u8 [adress&0x7FFF]; 
		case 4: 
			return io_ram_u8 [adress&0x3FF]; 
		case 5: 
			return pal_ram_u8 [adress&0x3FF]; 
		case 6: 
			return vram_u8 [adress&0x1FFFF]; 
		case 7: 
			return oam_u8 [adress&0x3FF]; 
		default: 
			return rom_pages_u8 [(adress>>16)&0x1FF] [adress&0xFFFF]; 
	} 
} 
 
u16 read_hword (u32 adress) 
{	 
	switch ((adress & 0xFF000000)>>24) 
	{ 
		case 0: 
			return mem_read_u16 (zero_page_u8, adress&0xFF); 
		case 1: 
			return 0; 
		case 2: 
			return mem_read_u16 (wram_ext_u8, adress&0x3FFFF); 
		case 3: 
			return mem_read_u16 (wram_int_u8, adress&0x7FFF); 
		case 4: 
			return mem_read_u16 (io_ram_u8, adress&0x3FF); 
		case 5: 
			return mem_read_u16 (pal_ram_u8, adress&0x3FF); 
		case 6: 
			return mem_read_u16 (vram_u8, adress&0x1FFFF); 
		case 7: 
			return mem_read_u16 (oam_u8, adress&0x3FF); 
		default: 
			return rom_read_u16 (adress); 
	} 
} 
 
u32 read_word (u32 adress) 
{ 
	switch ((adress&0xFF000000)>>24) 
	{ 
		case 0:  
				return mem_read_u32 (zero_page_u8, adress&0xFF); 
		case 1: 
				return 0; 
		case 2: 
				return mem_read_u32 (wram_ext_u8, adress&0x3FFFF); 
		case 3: 
				return mem_read_u32 (wram_int_u8, adress&0x7FFF); 
		case 4: 
				return mem_read_u32 (io_ram_u8, adress&0x3FF); 
		case 5: 
				return mem_read_u32 (pal_ram_u8, adress&0x3FF); 
		case 6: 
				return mem_read_u32 (vram_u8, adress&0x1FFFF); 
		case 7: 
				return mem_read_u32 (oam_u8, adress&0x3FF); 
		default: 
				return rom_read_u32 (adress); 
	} 
	return 0; 
} 
 
void write_byte (u32 adress, u8 data) 
{ 
	u16 temp; 
 
	switch ((adress & 0xFF000000)>>24) 
	{ 
		case 0: 
			zero_page_u8 [adress&0xFF] = data; 
			break; 
		case 1: 
			break; 
		case 2: 
			wram_ext_u8 [adress&0x3FFFF] = data; 
			break; 
		case 3: 
			wram_int_u8 [adress&0x7FFF] = data; 
			break; 
		case 4: 
			io_ram_u8 [adress&0x3FF] = data; 
			break; 
		case 5: 
			pal_ram_u8 [adress&0x3FF] = data; 
 
			temp = pal_ram_u16 [(adress&0x3FF)>>1]; 
			translated_palette[(adress&0x3FF)>>1]=(u32)(temp<<19)|((temp&0x3E0)<<6)|((temp&0x7C00)>>7); 
			break; 
		case 6: 
			vram_u8 [adress&0x1FFFF] = data; 
			break; 
		case 7: 
			oam_u8 [adress&0x3FF] = data; 
			break; 
		default: 
			rom_pages_u8 [(adress>>16)&0x1FF] [adress&0xFFFF] = data; 
			break; 
	} 
} 
 
void write_hword (u32 adress, u16 data) 
{ 
	u16 temp; 
 
	switch ((adress & 0xFF000000)>>24) 
	{ 
		case 0: 
			mem_write_u16 (zero_page_u8, adress&0xFF, data); 
			break; 
		case 1: 
			break; 
		case 2: 
			mem_write_u16 (wram_ext_u8, adress&0x3FFFF, data); 
			break; 
		case 3: 
			mem_write_u16 (wram_int_u8, adress&0x7FFF, data); 
			break; 
		case 4: 
			mem_write_u16 (io_ram_u8, adress&0x3FF, data); 
			break; 
		case 5: 
			mem_write_u16 (pal_ram_u8, adress&0x3FF, data); 
 
			temp = pal_ram_u16 [(adress&0x3FF)>>1]; 
			translated_palette[(adress&0x3FF)>>1]=(u32)(temp<<19)|((temp&0x3E0)<<6)|((temp&0x7C00)>>7); 
			temp = pal_ram_u16 [((adress&0x3FF)>>1)+1]; 
			translated_palette [((adress&0x3FF)>>1)+1]=(u32)(temp<<19)|((temp&0x3E0)<<6)|((temp&0x7C00)>>7); 
			break; 
		case 6: 
			mem_write_u16 (vram_u8, adress&0x1FFFF, data); 
			break; 
		case 7: 
			mem_write_u16 (oam_u8, adress&0x3FF, data); 
			break; 
		default: 
			rom_write_u16 (adress, data); 
			break; 
	} 
} 
 
void write_word (u32 adress, u32 data) 
{ 
	u16 temp; 
 
	switch ((adress & 0xFF000000)>>24) 
	{ 
		case 0:	 
			mem_write_u32 (zero_page_u8, adress&0xFF, data); 
			break; 
		case 1:	 
			break; 
		case 2:	 
			mem_write_u32 (wram_ext_u8, adress&0x3FFFF, data); 
			break; 
		case 3: 
			mem_write_u32 (wram_int_u8, adress&0x7FFF, data); 
			break; 
		case 4: 
			mem_write_u32 (io_ram_u8, adress&0x3FF, data); 
			io_write_handles[(adress&0xFFFFFF)](); 
			break; 
		case 5: 
			mem_write_u32 (pal_ram_u8, adress&0x3FF, data); 
 
			temp = pal_ram_u16 [(adress&0x3FF)>>1]; 
			translated_palette[(adress&0x3FF)>>1]=(u32)(temp<<19)|((temp&0x3E0)<<6)|((temp&0x7C00)>>7); 
			temp = pal_ram_u16 [((adress&0x3FF)>>1)+1]; 
			translated_palette [((adress&0x3FF)>>1)+1]=(u32)(temp<<19)|((temp&0x3E0)<<6)|((temp&0x7C00)>>7); 
			temp = pal_ram_u16 [((adress&0x3FF)>>1)+2]; 
			translated_palette [((adress&0x3FF)>>1)+2]=(u32)(temp<<19)|((temp&0x3E0)<<6)|((temp&0x7C00)>>7); 
			temp = pal_ram_u16 [((adress&0x3FF)>>1)+3]; 
			translated_palette [((adress&0x3FF)>>1)+3]=(u32)(temp<<19)|((temp&0x3E0)<<6)|((temp&0x7C00)>>7); 
			break; 
		case 6: 
			mem_write_u32 (vram_u8, adress&0x1FFFF, data); 
			break; 
		case 7: 
			mem_write_u32 (oam_u8, adress&0x3FF, data); 
			break; 
		default: 
			rom_write_u32 (adress, data); 
			break; 
	} 
} 
 
u32 read_aligned_word (u32 adress) 
{ 
	switch ((adress&0xFF000000)>>24) 
	{ 
		case 0:  
				return zero_page_u32 [(adress&0xFF)>>2]; 
		case 1: 
				return 0; 
		case 2: 
				return wram_ext_u32 [(adress&0x3FFFF)>>2]; 
		case 3: 
				return wram_int_u32 [(adress&0x7FFF)>>2]; 
		case 4: 
				return io_ram_u32 [(adress&0x3FF)>>2]; 
		case 5: 
				return pal_ram_u32 [(adress&0x3FF)>>2]; 
		case 6: 
				return vram_u32 [(adress&0x1FFFF)>>2]; 
		case 7: 
				return oam_u32 [(adress&0x3FF)>>2]; 
		default: 
				return rom_pages_u32 [(adress>>16)&0x1FF] [(adress>>2)&0x3FFF]; 
	} 
	return 0; 
} 
 
u16 read_aligned_hword (u32 adress) 
{ 
	return 0; 
	//to do for thumb ;) 
}