⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memory.c

📁 唯一公开源代码的GBA模拟器
💻 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 ;)
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -