src/main.c

changeset 30
3190629004b2
parent 29
d73d07c1d492
child 32
a44afcf2354c
     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