📄 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 ;)
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -