1.1 --- a/src/main.c Thu Dec 02 01:31:05 2010 +0000 1.2 +++ b/src/main.c Thu Dec 02 02:43:49 2010 +0000 1.3 @@ -57,6 +57,83 @@ 1.4 #define WR8(array, address, andmask, value) \ 1.5 array[(address + 0) & (andmask)] = value & 0xff; 1.6 1.7 +/****************** 1.8 + * Memory mapping 1.9 + ******************/ 1.10 + 1.11 +#define MAPRAM(addr) (((uint16_t)state.map[addr*2] << 8) + ((uint16_t)state.map[(addr*2)+1])) 1.12 + 1.13 +uint32_t mapAddr(uint32_t addr, bool writing) 1.14 +{ 1.15 + if (addr < 0x400000) { 1.16 + // RAM access. Check against the Map RAM 1.17 + // Start by getting the original page address 1.18 + uint16_t page = (addr >> 12) & 0x3FF; 1.19 + 1.20 + // Look it up in the map RAM and get the physical page address 1.21 + uint32_t new_page_addr = MAPRAM(page) & 0x3FF; 1.22 + 1.23 + // Update the Page Status bits 1.24 + uint8_t pagebits = (MAPRAM(page) >> 13) & 0x03; 1.25 + if (pagebits != 0) { 1.26 + if (writing) 1.27 + state.map[addr*2] |= 0x60; // Page written to (dirty) 1.28 + else 1.29 + state.map[addr*2] |= 0x40; // Page accessed but not written 1.30 + } 1.31 + 1.32 + // Return the address with the new physical page spliced in 1.33 + return (new_page_addr << 12) + (addr & 0xFFF); 1.34 + } else { 1.35 + // I/O, VRAM or MapRAM space; no mapping is performed or required 1.36 + // TODO: assert here? 1.37 + return addr; 1.38 + } 1.39 +} 1.40 + 1.41 +typedef enum { 1.42 + MEM_ALLOWED = 0, 1.43 + MEM_PAGEFAULT, // Page fault -- page not present 1.44 + MEM_PAGE_NO_WE, // Page not write enabled 1.45 + MEM_KERNEL, // User attempted to access kernel memory 1.46 + MEM_UIE // User Nonmemory Location Access 1.47 +} MEM_STATUS; 1.48 + 1.49 +// check memory access permissions 1.50 +MEM_STATUS checkMemoryAccess(uint32_t addr, bool writing) 1.51 +{ 1.52 + // Are we in Supervisor mode? 1.53 + if (m68k_get_reg(NULL, M68K_REG_SR) & 0x2000) 1.54 + // Yes. We can do anything we like. 1.55 + return MEM_ALLOWED; 1.56 + 1.57 + // If we're here, then we must be in User mode. 1.58 + // Check that the user didn't access memory outside of the RAM area 1.59 + if (addr >= 0x400000) 1.60 + return MEM_UIE; 1.61 + 1.62 + // This leaves us with Page Fault checking. Get the page bits for this page. 1.63 + uint16_t page = (addr >> 12) & 0x3FF; 1.64 + uint8_t pagebits = (MAPRAM(page) >> 13) & 0x07; 1.65 + 1.66 + // Check page is present 1.67 + if ((pagebits & 0x03) == 0) 1.68 + return MEM_PAGEFAULT; 1.69 + 1.70 + // User attempt to access the kernel 1.71 + // A19, A20, A21, A22 low (kernel access): RAM addr before paging; not in Supervisor mode 1.72 + if (((addr >> 19) & 0x0F) == 0) 1.73 + return MEM_KERNEL; 1.74 + 1.75 + // Check page is write enabled 1.76 + if ((pagebits & 0x04) == 0) 1.77 + return MEM_PAGE_NO_WE; 1.78 + 1.79 + // Page access allowed. 1.80 + return MEM_ALLOWED; 1.81 +} 1.82 + 1.83 +#undef MAPRAM 1.84 1.85 /******************************************************** 1.86 * m68k memory read/write support functions for Musashi