--- np2/i386c/ia32/paging.c 2004/03/23 18:38:07 1.18 +++ np2/i386c/ia32/paging.c 2004/03/23 19:32:37 1.19 @@ -1,4 +1,4 @@ -/* $Id: paging.c,v 1.18 2004/03/23 18:38:07 yui Exp $ */ +/* $Id: paging.c,v 1.19 2004/03/23 19:32:37 yui Exp $ */ /* * Copyright (c) 2003-2004 NONAKA Kimihiro @@ -312,6 +312,142 @@ cpu_memory_access_la_RMW(UINT32 laddr, U return value; } + +#if defined(IA32_PAGING_EACHSIZE) +UINT8 MEMCALL +cpu_linear_memory_read_b(UINT32 laddr, const int crw, const int user_mode) +{ + UINT32 addr; + + addr = paging(laddr, crw, user_mode); + return(cpu_memoryread(addr)); +} + +UINT16 MEMCALL +cpu_linear_memory_read_w(UINT32 laddr, const int crw, const int user_mode) +{ + UINT32 addr; + UINT32 addr2; + UINT16 value; + + addr = paging(laddr, crw, user_mode); + if ((laddr + 1) & 0x00000fff) { + return(cpu_memoryread_w(addr)); + } + else { + addr2 = paging(laddr + 1, crw, user_mode); + value = cpu_memoryread_b(addr); + value += (UINT16)cpu_memoryread_b(addr2) << 8; + return(value); + } +} + +UINT32 MEMCALL +cpu_linear_memory_read_d(UINT32 laddr, const int crw, const int user_mode) +{ + UINT32 addr; + UINT remain; + UINT32 addr2; + UINT32 value; + + addr = paging(laddr, crw, user_mode); + remain = 0x1000 - (laddr & 0x00000fff); + if (remain >= 4) { + return(cpu_memoryread_d(addr)); + } + else { + addr2 = paging(laddr + remain, crw, user_mode); + switch (remain) { + case 3: + value = cpu_memoryread(addr); + value += (UINT32)cpu_memoryread_w(addr + 1) << 8; + value += (UINT32)cpu_memoryread(addr2) << 24; + break; + + case 2: + value = cpu_memoryread_w(addr); + value += (UINT32)cpu_memoryread_w(addr2) << 16; + break; + + case 1: + value = cpu_memoryread(addr); + value += (UINT32)cpu_memoryread(addr2) << 8; + value += (UINT32)cpu_memoryread_w(addr2 + 1) << 16; + break; + + default: + ia32_panic("cpu_linear_memory_read_d(): out of range (remain = %d)\n", remain); + value = 0; /* compiler happy */ + break; + } + return value; + } +} + +void MEMCALL +cpu_linear_memory_write_b(UINT32 laddr, UINT8 value, const int user_mode) +{ + const int crw = (CPU_PAGE_WRITE|CPU_PAGE_DATA); + UINT32 addr; + + addr = paging(laddr, crw, user_mode); + cpu_memorywrite(addr, value); +} + +void MEMCALL +cpu_linear_memory_write_w(UINT32 laddr, UINT16 value, const int user_mode) +{ + const int crw = (CPU_PAGE_WRITE|CPU_PAGE_DATA); + UINT32 addr; + UINT32 addr2; + + addr = paging(laddr, crw, user_mode); + if ((laddr + 1) & 0x00000fff) { + cpu_memorywrite_w(addr, value); + } + else { + addr2 = paging(laddr + 1, crw, user_mode); + cpu_memorywrite(addr, (UINT8)value); + cpu_memorywrite(addr2, (UINT8)(value >> 8)); + } +} + +void MEMCALL +cpu_linear_memory_write_d(UINT32 laddr, UINT32 value, const int user_mode) +{ + const int crw = (CPU_PAGE_WRITE|CPU_PAGE_DATA); + UINT32 addr; + UINT remain; + UINT32 addr2; + + addr = paging(laddr, crw, user_mode); + remain = 0x1000 - (laddr & 0x00000fff); + if (remain >= 4) { + cpu_memorywrite_d(addr, value); + } + else { + addr2 = paging(laddr + remain, crw, user_mode); + switch (remain) { + case 3: + cpu_memorywrite(addr, (UINT8)value); + cpu_memorywrite_w(addr + 1, (UINT16)(value >> 8)); + cpu_memorywrite(addr2, (UINT8)(value >> 24)); + break; + + case 2: + cpu_memorywrite_w(addr, (UINT16)value); + cpu_memorywrite_w(addr2, (UINT16)(value >> 16)); + break; + + case 1: + cpu_memorywrite(addr, (UINT8)value); + cpu_memorywrite(addr2, (UINT8)(value >> 8)); + cpu_memorywrite_w(addr2 + 1, (UINT16)(value >> 16)); + break; + } + } +} +#else // IA32_PAGING_EACHSIZE UINT32 MEMCALL cpu_linear_memory_read(UINT32 laddr, UINT length, const int crw, const int user_mode) { @@ -432,6 +568,7 @@ cpu_linear_memory_write(UINT32 laddr, UI break; } } +#endif // IA32_PAGING_EACHSIZE void MEMCALL paging_check(UINT32 laddr, UINT length, const int crw, const int user_mode)