src/memory.c

branch
experimental_memory_mapper_v2
changeset 128
3246b74d96bc
parent 121
15ae2788e848
child 132
8a7dc9b5b1db
     1.1 diff -r 4c03f6433d0d -r 3246b74d96bc src/memory.c
     1.2 --- a/src/memory.c	Wed Jan 16 00:41:51 2013 +0000
     1.3 +++ b/src/memory.c	Fri Jan 18 17:03:48 2013 +0000
     1.4 @@ -17,100 +17,10 @@
     1.5   * Memory mapping
     1.6   ******************/
     1.7  
     1.8 -#define MAPRAM(addr) (((uint16_t)state.map[addr*2] << 8) + ((uint16_t)state.map[(addr*2)+1]))
     1.9 -
    1.10 -uint32_t mapAddr(uint32_t addr, bool writing)/*{{{*/
    1.11 -{
    1.12 -	if (addr < 0x400000) {
    1.13 -		// RAM access. Check against the Map RAM
    1.14 -		// Start by getting the original page address
    1.15 -		uint16_t page = (addr >> 12) & 0x3FF;
    1.16 -
    1.17 -		// Look it up in the map RAM and get the physical page address
    1.18 -		uint32_t new_page_addr = MAPRAM(page) & 0x3FF;
    1.19 -
    1.20 -		// Update the Page Status bits
    1.21 -		uint8_t pagebits = (MAPRAM(page) >> 13) & 0x03;
    1.22 -		// Pagebits --
    1.23 -		//   0 = not present
    1.24 -		//   1 = present but not accessed
    1.25 -		//   2 = present, accessed (read from)
    1.26 -		//   3 = present, dirty (written to)
    1.27 -		switch (pagebits) {
    1.28 -			case 0:
    1.29 -				// Page not present
    1.30 -				// This should cause a page fault
    1.31 -				LOGS("Whoa! Pagebit update, when the page is not present!");
    1.32 -				break;
    1.33 -
    1.34 -			case 1:
    1.35 -				// Page present -- first access
    1.36 -				state.map[page*2] &= 0x9F;	// turn off "present" bit (but not write enable!)
    1.37 -				if (writing)
    1.38 -					state.map[page*2] |= 0x60;		// Page written to (dirty)
    1.39 -				else
    1.40 -					state.map[page*2] |= 0x40;		// Page accessed but not written
    1.41 -				break;
    1.42 -
    1.43 -			case 2:
    1.44 -			case 3:
    1.45 -				// Page present, 2nd or later access
    1.46 -				if (writing)
    1.47 -					state.map[page*2] |= 0x60;		// Page written to (dirty)
    1.48 -				break;
    1.49 -		}
    1.50 -
    1.51 -		// Return the address with the new physical page spliced in
    1.52 -		return (new_page_addr << 12) + (addr & 0xFFF);
    1.53 -	} else {
    1.54 -		// I/O, VRAM or MapRAM space; no mapping is performed or required
    1.55 -		// TODO: assert here?
    1.56 -		return addr;
    1.57 -	}
    1.58 -}/*}}}*/
    1.59 -
    1.60 -MEM_STATUS checkMemoryAccess(uint32_t addr, bool writing)/*{{{*/
    1.61 -{
    1.62 -	// 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 (but only for RAM zone)
    1.67 -	if ((addr < 0x400000) && ((pagebits & 0x03) == 0)) {
    1.68 -		LOG("Page not mapped in: addr %08X, page %04X, mapbits %04X", addr, page, MAPRAM(page));
    1.69 -		return MEM_PAGEFAULT;
    1.70 -	}
    1.71 -
    1.72 -	// Are we in Supervisor mode?
    1.73 -	if (m68k_get_reg(NULL, M68K_REG_SR) & 0x2000)
    1.74 -		// Yes. We can do anything we like.
    1.75 -		return MEM_ALLOWED;
    1.76 -
    1.77 -	// If we're here, then we must be in User mode.
    1.78 -	// Check that the user didn't access memory outside of the RAM area
    1.79 -	if (addr >= 0x400000) {
    1.80 -		LOGS("User accessed privileged memory");
    1.81 -		return MEM_UIE;
    1.82 -	}
    1.83 -
    1.84 -	// User attempt to access the kernel
    1.85 -	// A19, A20, A21, A22 low (kernel access): RAM addr before paging; not in Supervisor mode
    1.86 -	if (((addr >> 19) & 0x0F) == 0) {
    1.87 -		LOGS("Attempt by user code to access kernel space");
    1.88 -		return MEM_KERNEL;
    1.89 -	}
    1.90 -
    1.91 -	// Check page is write enabled
    1.92 -	if (writing && ((pagebits & 0x04) == 0)) {
    1.93 -		LOG("Page not write enabled: inaddr %08X, page %04X, mapram %04X [%02X %02X], pagebits %d",
    1.94 -				addr, page, MAPRAM(page), state.map[page*2], state.map[(page*2)+1], pagebits);
    1.95 -		return MEM_PAGE_NO_WE;
    1.96 -	}
    1.97 -
    1.98 -	// Page access allowed.
    1.99 -	return MEM_ALLOWED;
   1.100 -}/*}}}*/
   1.101 -
   1.102 +/// Set a page bit
   1.103 +#define MAP_SET_PAGEBIT(addr, bit) state.map[(((addr) >> 12) & 0x3FF)*2] |=  (bit << 2)
   1.104 +/// Clear a page bit
   1.105 +#define MAP_CLR_PAGEBIT(addr, bit) state.map[(((addr) >> 12) & 0x3FF)*2] &= ~(bit << 2)
   1.106  
   1.107  
   1.108  /********************************************************
   1.109 @@ -129,40 +39,7 @@
   1.110  /*{{{ macro: ACCESS_CHECK_WR(address, bits)*/
   1.111  #define ACCESS_CHECK_WR(address, bits)								\
   1.112  	do {															\
   1.113 -		bool fault = false;											\
   1.114 -		MEM_STATUS st;												\
   1.115 -		switch (st = checkMemoryAccess(address, true)) {			\
   1.116 -			case MEM_ALLOWED:										\
   1.117 -				/* Access allowed */								\
   1.118 -				break;												\
   1.119 -			case MEM_PAGEFAULT:										\
   1.120 -				/* Page fault */									\
   1.121 -				state.genstat = 0x8BFF | (state.pie ? 0x0400 : 0);	\
   1.122 -				fault = true;										\
   1.123 -				break;												\
   1.124 -			case MEM_UIE:											\
   1.125 -				/* User access to memory above 4MB */				\
   1.126 -				state.genstat = 0x9AFF | (state.pie ? 0x0400 : 0);	\
   1.127 -				fault = true;										\
   1.128 -				break;												\
   1.129 -			case MEM_KERNEL:										\
   1.130 -			case MEM_PAGE_NO_WE:									\
   1.131 -				/* kernel access or page not write enabled */		\
   1.132 -				/* XXX: is this the correct value? */				\
   1.133 -				state.genstat = 0x9BFF | (state.pie ? 0x0400 : 0);	\
   1.134 -				fault = true;										\
   1.135 -				break;												\
   1.136 -		}															\
   1.137 -																	\
   1.138 -		if (fault) {												\
   1.139 -			if (bits >= 16)											\
   1.140 -				state.bsr0 = 0x7C00;								\
   1.141 -			else													\
   1.142 -				state.bsr0 = (address & 1) ? 0x7E00 : 0x7D00;		\
   1.143 -			state.bsr0 |= (address >> 16);							\
   1.144 -			state.bsr1 = address & 0xffff;							\
   1.145 -			LOG("Bus Error while writing, addr %08X, statcode %d", address, st);		\
   1.146 -			if (state.ee) m68k_pulse_bus_error();					\
   1.147 +		if (access_check_cpu(address, bits, true)) {				\
   1.148  			return;													\
   1.149  		}															\
   1.150  	} while (0)
   1.151 @@ -180,100 +57,220 @@
   1.152  /*{{{ macro: ACCESS_CHECK_RD(address, bits)*/
   1.153  #define ACCESS_CHECK_RD(address, bits)								\
   1.154  	do {															\
   1.155 -		bool fault = false;											\
   1.156 -		MEM_STATUS st;												\
   1.157 -		switch (st = checkMemoryAccess(address, false)) {			\
   1.158 -			case MEM_ALLOWED:										\
   1.159 -				/* Access allowed */								\
   1.160 -				break;												\
   1.161 -			case MEM_PAGEFAULT:										\
   1.162 -				/* Page fault */									\
   1.163 -				state.genstat = 0xCBFF | (state.pie ? 0x0400 : 0);	\
   1.164 -				fault = true;										\
   1.165 -				break;												\
   1.166 -			case MEM_UIE:											\
   1.167 -				/* User access to memory above 4MB */				\
   1.168 -				state.genstat = 0xDAFF | (state.pie ? 0x0400 : 0);	\
   1.169 -				fault = true;										\
   1.170 -				break;												\
   1.171 -			case MEM_KERNEL:										\
   1.172 -			case MEM_PAGE_NO_WE:									\
   1.173 -				/* kernel access or page not write enabled */		\
   1.174 -				/* XXX: is this the correct value? */				\
   1.175 -				state.genstat = 0xDBFF | (state.pie ? 0x0400 : 0);	\
   1.176 -				fault = true;										\
   1.177 -				break;												\
   1.178 -		}															\
   1.179 -																	\
   1.180 -		if (fault) {												\
   1.181 -			if (bits >= 16)											\
   1.182 -				state.bsr0 = 0x7C00;								\
   1.183 +		if (access_check_cpu(address, bits, false)) {				\
   1.184 +			if (bits == 32)											\
   1.185 +				return EMPTY & 0xFFFFFFFF;							\
   1.186  			else													\
   1.187 -				state.bsr0 = (address & 1) ? 0x7E00 : 0x7D00;		\
   1.188 -			state.bsr0 |= (address >> 16);							\
   1.189 -			state.bsr1 = address & 0xffff;							\
   1.190 -			LOG("Bus Error while reading, addr %08X, statcode %d", address, st);		\
   1.191 -			if (state.ee) m68k_pulse_bus_error();					\
   1.192 -			if (bits == 32)											\
   1.193 -				return EMPTY & 0xFFFFFFFF;									\
   1.194 -			else													\
   1.195 -				return EMPTY & ((1UL << bits)-1);								\
   1.196 +				return EMPTY & ((1UL << bits)-1);					\
   1.197  		}															\
   1.198  	} while (0)
   1.199  /*}}}*/
   1.200  
   1.201 -bool access_check_dma(int reading)
   1.202 +
   1.203 +/**
   1.204 + * Update the page bits for a given memory address
   1.205 + *
   1.206 + * @param	addr	Memory address being accessed
   1.207 + * @param	l7intr	Set to <i>true</i> if a level-seven interrupt has been
   1.208 + * 					signalled (even if <b>ENABLE ERROR</b> isn't set).
   1.209 + * @param	write	Set to <i>true</i> if the address is being written to.
   1.210 + */
   1.211 +static void update_page_bits(uint32_t addr, bool l7intr, bool write)
   1.212  {
   1.213 -	// Check memory access permissions
   1.214 -	bool access_ok;
   1.215 -	switch (checkMemoryAccess(state.dma_address, !reading)) {
   1.216 -		case MEM_PAGEFAULT:
   1.217 -			// Page fault
   1.218 -			state.genstat = 0xABFF
   1.219 -				| (reading ? 0x4000 : 0)
   1.220 -				| (state.pie ? 0x0400 : 0);
   1.221 -			access_ok = false;
   1.222 -			break;
   1.223 +	bool ps0_state = false;
   1.224 +
   1.225 +	// Don't try and update pagebits for non-RAM addresses
   1.226 +	if (addr > 0x3FFFFF)
   1.227 +		return;
   1.228 +
   1.229 +	if (l7intr) {
   1.230 +//		if (!(MAP_PAGEBITS(addr) & PAGE_BIT_PS0)) {
   1.231 +			// FIXME FUCKUP The ruddy TRM is wrong AGAIN! If above line is uncommented, Really Bad Things Happen.
   1.232 +		if ((MAP_PAGEBITS(addr) & PAGE_BIT_PS0)) {
   1.233 +			// Level 7 interrupt, PS0 clear, PS1 don't-care. Set PS0.
   1.234 +			ps0_state = true;
   1.235 +		}
   1.236 +	} else {
   1.237 +		// No L7 interrupt
   1.238 +		if ((write && !(MAP_PAGEBITS(addr) & PAGE_BIT_PS1) &&  (MAP_PAGEBITS(addr) & PAGE_BIT_PS0)) ||
   1.239 +			(write &&  (MAP_PAGEBITS(addr) & PAGE_BIT_PS1) && !(MAP_PAGEBITS(addr) & PAGE_BIT_PS0)))
   1.240 +		{
   1.241 +			// No L7 interrupt, PS[1:0] = 0b01, write
   1.242 +			// No L7 interrupt, PS[1:0] = 0b10, write
   1.243 +			ps0_state = true;
   1.244 +		}
   1.245 +	}
   1.246  
   1.247 -		case MEM_UIE:
   1.248 -			// User access to memory above 4MB
   1.249 -			// FIXME? Shouldn't be possible with DMA... assert this?
   1.250 -			state.genstat = 0xBAFF
   1.251 -				| (reading ? 0x4000 : 0)
   1.252 -				| (state.pie ? 0x0400 : 0);
   1.253 -			access_ok = false;
   1.254 -			break;
   1.255 +#ifdef MAPRAM_BIT_TEST
   1.256 +	LOG("Starting Mapram Bit Test");
   1.257 +	state.map[0] = state.map[1] = 0;
   1.258 +	LOG("Start   = %04X %02X", MAPRAM_ADDR(0), MAP_PAGEBITS(0));
   1.259 +	MAP_SET_PAGEBIT(0, PAGE_BIT_WE);
   1.260 +	LOG("Set WE  = %04X %02X", MAPRAM_ADDR(0), MAP_PAGEBITS(0));
   1.261 +	MAP_SET_PAGEBIT(0, PAGE_BIT_PS1);
   1.262 +	LOG("Set PS1 = %04X %02X", MAPRAM_ADDR(0), MAP_PAGEBITS(0));
   1.263 +	MAP_SET_PAGEBIT(0, PAGE_BIT_PS0);
   1.264 +	LOG("Set PS0 = %04X %02X", MAPRAM_ADDR(0), MAP_PAGEBITS(0));
   1.265 +	
   1.266 +	MAP_CLR_PAGEBIT(0, PAGE_BIT_WE);
   1.267 +	LOG("Clr WE  = %04X %02X", MAPRAM_ADDR(0), MAP_PAGEBITS(0));
   1.268 +	MAP_CLR_PAGEBIT(0, PAGE_BIT_PS1);
   1.269 +	LOG("Clr PS1 = %04X %02X", MAPRAM_ADDR(0), MAP_PAGEBITS(0));
   1.270 +	MAP_CLR_PAGEBIT(0, PAGE_BIT_PS0);
   1.271 +	LOG("Clr PS0 = %04X %02X", MAPRAM_ADDR(0), MAP_PAGEBITS(0));
   1.272 +	exit(-1);
   1.273 +#endif
   1.274 +
   1.275 +	uint16_t old_pagebits = MAP_PAGEBITS(addr);
   1.276  
   1.277 -		case MEM_KERNEL:
   1.278 -		case MEM_PAGE_NO_WE:
   1.279 -			// Kernel access or page not write enabled
   1.280 -			/* XXX: is this correct? */
   1.281 -			state.genstat = 0xBBFF
   1.282 -				| (reading ? 0x4000 : 0)
   1.283 -				| (state.pie ? 0x0400 : 0);
   1.284 -			access_ok = false;
   1.285 -			break;
   1.286 +	// PS1 is always set on access
   1.287 +	MAP_SET_PAGEBIT(addr, PAGE_BIT_PS1);
   1.288 +
   1.289 +	uint16_t new_pagebit1 = MAP_PAGEBITS(addr);
   1.290 +
   1.291 +	// Update PS0
   1.292 +	if (ps0_state) {
   1.293 +		MAP_SET_PAGEBIT(addr, PAGE_BIT_PS0);
   1.294 +	} else {
   1.295 +		MAP_CLR_PAGEBIT(addr, PAGE_BIT_PS0);
   1.296 +	}
   1.297  
   1.298 -		case MEM_ALLOWED:
   1.299 -			access_ok = true;
   1.300 +	uint16_t new_pagebit2 = MAP_PAGEBITS(addr);
   1.301 +	switch (addr) {
   1.302 +		case 0x000000:
   1.303 +		case 0x001000:
   1.304 +		case 0x002000:
   1.305 +		case 0x003000:
   1.306 +		case 0x004000:
   1.307 +		case 0x033000:
   1.308 +		case 0x034000:
   1.309 +		case 0x035000:
   1.310 +			LOG("Addr %08X MapNew %04X Pagebit update -- ps0 %d, %02X => %02X => %02X", addr, MAPRAM_ADDR(addr), ps0_state, old_pagebits, new_pagebit1, new_pagebit2);
   1.311 +		default:
   1.312  			break;
   1.313  	}
   1.314 -	if (!access_ok) {
   1.315 +}
   1.316 +
   1.317 +bool access_check_dma(void)
   1.318 +{
   1.319 +	// TODO FIXME BUGBUG Sanity check - Make sure DMAC is only accessing RAM addresses
   1.320 +
   1.321 +	// DMA access check -- make sure the page is mapped in
   1.322 +	if (!(MAP_PAGEBITS(state.dma_address) & PAGE_BIT_PS0) && !(MAP_PAGEBITS(state.dma_address) & PAGE_BIT_PS1)) {
   1.323 +		// DMA access to page which is not mapped in.
   1.324 +		// Level 7 interrupt, page fault, DMA invoked
   1.325 +		state.genstat = 0xABFF
   1.326 +			| (state.dma_reading ? 0x4000 : 0)
   1.327 +			| (state.pie ? 0x0400 : 0);
   1.328 +
   1.329 +		// XXX: Check all this stuff.
   1.330  		state.bsr0 = 0x3C00;
   1.331  		state.bsr0 |= (state.dma_address >> 16);
   1.332  		state.bsr1 = state.dma_address & 0xffff;
   1.333 -		if (state.ee) m68k_set_irq(7);
   1.334 -		printf("BUS ERROR FROM DMA: genstat=%04X, bsr0=%04X, bsr1=%04X\n", state.genstat, state.bsr0, state.bsr1);
   1.335 +
   1.336 +		// Update page bits for this transfer
   1.337 +		update_page_bits(state.dma_address, true, !state.dma_reading);
   1.338 +
   1.339 +		// XXX: is this right?
   1.340 +		// Fire a Level 7 interrupt
   1.341 +		/*if (state.ee)*/ m68k_set_irq(7);
   1.342 +
   1.343 +		LOG("BUS ERROR FROM DMA: genstat=%04X, bsr0=%04X, bsr1=%04X\n", state.genstat, state.bsr0, state.bsr1);
   1.344 +		return false;
   1.345 +	} else {
   1.346 +		// No errors. Just update the page bits.
   1.347 +		update_page_bits(state.dma_address, false, !state.dma_reading);
   1.348 +		return true;
   1.349  	}
   1.350 -	return (access_ok);
   1.351 +}
   1.352 +
   1.353 +/**
   1.354 + * Check memory access permissions for a CPU memory access.
   1.355 + *
   1.356 + * @param	addr	Virtual memory address being accessed (from CPU address bus).
   1.357 + * @param	bits	Word size of this transfer (8, 16 or 32 bits).
   1.358 + * @param	write	<i>true</i> if this is a write operation, <i>false</i> if it is a read operation.
   1.359 + * @return	<i>true</i> if the access was denied and a level-7 interrupt and/or bus error raised.
   1.360 + * 			<i>false</i> if the access was allowed.
   1.361 + */
   1.362 +bool access_check_cpu(uint32_t addr, int bits, bool write)
   1.363 +{
   1.364 +	bool supervisor = (m68k_get_reg(NULL, M68K_REG_SR) & 0x2000);
   1.365 +	bool fault = false;
   1.366 +
   1.367 +	// TODO FIXME BUGBUG? Do we need to check for supervisor access here?
   1.368 +	if ((addr >= 0x000000) && (addr <= 0x3FFFFF) && !(MAP_PAGEBITS(addr) & PAGE_BIT_PS1) && !(MAP_PAGEBITS(addr) & PAGE_BIT_PS0)) {
   1.369 +		// (A) Page Fault -- user access to page which is not mapped in
   1.370 +		// Level 7 Interrupt, Bus Error, regs=PAGEFAULT
   1.371 +		if (write) {
   1.372 +			state.genstat = 0x8BFF | (state.pie ? 0x0400 : 0);
   1.373 +		} else {
   1.374 +			state.genstat = 0xCBFF | (state.pie ? 0x0400 : 0);
   1.375 +		}
   1.376 +		fault = true;
   1.377 +	} else if (!supervisor && (addr >= 0x000000) && (addr <= 0x07FFFF)) {
   1.378 +		// (B) User attempted to access the kernel
   1.379 +		// Level 7 Interrupt, Bus Error, regs=KERNEL
   1.380 +		if (write) {
   1.381 +			// XXX: BUGBUG? Is this correct?
   1.382 +			state.genstat = 0x9BFF | (state.pie ? 0x0400 : 0);
   1.383 +		} else {
   1.384 +			state.genstat = 0xDBFF | (state.pie ? 0x0400 : 0);
   1.385 +		}
   1.386 +		fault = true;
   1.387 +	} else if (!supervisor && write && (addr >= 0x000000) && (addr <= 0x3FFFFF) && !(MAP_PAGEBITS(addr) & PAGE_BIT_WE)) {
   1.388 +		// (C) User attempted to write to a page which is not write enabled
   1.389 +		// Level 7 Interrupt, Bus Error, regs=WRITE_EN
   1.390 +		if (write) {
   1.391 +			// XXX: BUGBUG? Is this correct?
   1.392 +			state.genstat = 0x9BFF | (state.pie ? 0x0400 : 0);
   1.393 +		} else {
   1.394 +			state.genstat = 0xDBFF | (state.pie ? 0x0400 : 0);
   1.395 +		}
   1.396 +		fault = true;
   1.397 +	} else if (!supervisor && (addr >= 0x400000) && (addr <= 0xFFFFFF)) {
   1.398 +		// (D) UIE - user I/O exception
   1.399 +		// Bus Error only, regs=UIE
   1.400 +		if (write) {
   1.401 +			state.genstat = 0x9AFF | (state.pie ? 0x0400 : 0);
   1.402 +		} else {
   1.403 +			state.genstat = 0xDAFF | (state.pie ? 0x0400 : 0);
   1.404 +		}
   1.405 +		fault = true;
   1.406 +	}
   1.407 +
   1.408 +	// Update the page bits first
   1.409 +	update_page_bits(addr, fault, write);
   1.410 +
   1.411 +	if (fault) {
   1.412 +		if (bits >= 16)
   1.413 +			state.bsr0 = 0x7C00;
   1.414 +		else
   1.415 +			state.bsr0 = (addr & 1) ? 0x7E00 : 0x7D00;
   1.416 +		// FIXME? Physical or virtual address here?
   1.417 +		state.bsr0 |= (addr >> 16);
   1.418 +		state.bsr1 = addr & 0xffff;
   1.419 +
   1.420 +		LOG("CPU Bus Error or L7Intr while %s, vaddr %08X, map %08X, pagebits 0x%02X bsr0=%04X bsr1=%04X genstat=%04X", 
   1.421 +				write ? "writing" : "reading", addr,
   1.422 +				MAPRAM_ADDR(addr & 0x3fffff),
   1.423 +				MAP_PAGEBITS(addr & 0x3fffff),
   1.424 +				state.bsr0, state.bsr1, state.genstat);
   1.425 +
   1.426 +		// FIXME? BUGBUG? Does EE disable one or both of these?
   1.427 +		// /*if (state.ee)*/ m68k_set_irq(7);
   1.428 +		/*if (state.ee)*/ m68k_pulse_bus_error();
   1.429 +	}
   1.430 +
   1.431 +	return fault;
   1.432  }
   1.433  
   1.434  // Logging macros
   1.435  #define LOG_NOT_HANDLED_R(bits)															\
   1.436 -	if (!handled) printf("unhandled read%02d, addr=0x%08X\n", bits, address);
   1.437 +	if (!handled) fprintf(stderr, "unhandled read%02d, addr=0x%08X\n", bits, address);
   1.438  
   1.439  #define LOG_NOT_HANDLED_W(bits)															\
   1.440 -	if (!handled) printf("unhandled write%02d, addr=0x%08X, data=0x%08X\n", bits, address, data);
   1.441 +	if (!handled) fprintf(stderr, "unhandled write%02d, addr=0x%08X, data=0x%08X\n", bits, address, data);
   1.442  
   1.443  /********************************************************
   1.444   * I/O read/write functions
   1.445 @@ -286,7 +283,7 @@
   1.446  {
   1.447  	assert((bits == 8) || (bits == 16) || (bits == 32));
   1.448  	if ((bits & allowed) == 0) {
   1.449 -		printf("WARNING: %s 0x%08X (%s) with invalid size %d!\n", read ? "read from" : "write to", address, regname, bits);
   1.450 +		LOG("WARNING: %s 0x%08X (%s) with invalid size %d!\n", read ? "read from" : "write to", address, regname, bits);
   1.451  	}
   1.452  }
   1.453  
   1.454 @@ -349,6 +346,7 @@
   1.455  			case 0x070000:				// Line Printer Status Register
   1.456  				break;
   1.457  			case 0x080000:				// Real Time Clock
   1.458 +				LOGS("REAL TIME CLOCK WRITE");
   1.459  				break;
   1.460  			case 0x090000:				// Phone registers
   1.461  				switch (address & 0x0FF000) {
   1.462 @@ -483,6 +481,7 @@
   1.463  						handled = true;
   1.464  						break;
   1.465  					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
   1.466 +						LOGS("REAL TIME CLOCK DATA WRITE");
   1.467  						break;
   1.468  					case 0x040000:		// [ef][4c]xxxx ==> General Control Register
   1.469  						switch (address & 0x077000) {
   1.470 @@ -529,11 +528,15 @@
   1.471  						// TODO: figure out which sizes are valid (probably just 8 and 16)
   1.472  						// ENFORCE_SIZE_W(bits, address, 16, "KEYBOARD CONTROLLER");
   1.473  						if (bits == 8) {
   1.474 -							printf("KBD WR %02X => %02X\n", (address >> 1) & 3, data);
   1.475 +#ifdef LOG_KEYBOARD_WRITES
   1.476 +							LOG("KBD WR %02X => %02X\n", (address >> 1) & 3, data);
   1.477 +#endif
   1.478  							keyboard_write(&state.kbd, (address >> 1) & 3, data);
   1.479  							handled = true;
   1.480  						} else if (bits == 16) {
   1.481 -							printf("KBD WR %02X => %04X\n", (address >> 1) & 3, data);
   1.482 +#ifdef LOG_KEYBOARD_WRITES
   1.483 +							LOG("KBD WR %02X => %04X\n", (address >> 1) & 3, data);
   1.484 +#endif
   1.485  							keyboard_write(&state.kbd, (address >> 1) & 3, data >> 8);
   1.486  							handled = true;
   1.487  						}
   1.488 @@ -587,7 +590,7 @@
   1.489  				return data;
   1.490  				break;
   1.491  			case 0x080000:				// Real Time Clock
   1.492 -				printf("READ NOTIMP: Realtime Clock\n");
   1.493 +				LOGS("REAL TIME CLOCK READ");
   1.494  				break;
   1.495  			case 0x090000:				// Phone registers
   1.496  				switch (address & 0x0FF000) {
   1.497 @@ -665,6 +668,7 @@
   1.498  					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
   1.499  						break;
   1.500  					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
   1.501 +						LOGS("REAL TIME CLOCK DATA READ");
   1.502  						break;
   1.503  					case 0x040000:		// [ef][4c]xxxx ==> General Control Register
   1.504  						switch (address & 0x077000) {
   1.505 @@ -735,7 +739,8 @@
   1.506  		return RD32(state.rom, address, ROM_SIZE - 1);
   1.507  	} else if (address <= 0x3fffff) {
   1.508  		// RAM access
   1.509 -		uint32_t newAddr = mapAddr(address, false);
   1.510 +		uint32_t newAddr = MAP_ADDR(address);
   1.511 +
   1.512  		if (newAddr <= 0x1fffff) {
   1.513  			if (newAddr >= state.base_ram_size)
   1.514  				return EMPTY & 0xffffffff;
   1.515 @@ -787,7 +792,8 @@
   1.516  		data = RD16(state.rom, address, ROM_SIZE - 1);
   1.517  	} else if (address <= 0x3fffff) {
   1.518  		// RAM access
   1.519 -		uint32_t newAddr = mapAddr(address, false);
   1.520 +		uint32_t newAddr = MAP_ADDR(address);
   1.521 +
   1.522  		if (newAddr <= 0x1fffff) {
   1.523  			if (newAddr >= state.base_ram_size)
   1.524  				return EMPTY & 0xffff;
   1.525 @@ -839,7 +845,8 @@
   1.526  		data = RD8(state.rom, address, ROM_SIZE - 1);
   1.527  	} else if (address <= 0x3fffff) {
   1.528  		// RAM access
   1.529 -		uint32_t newAddr = mapAddr(address, false);
   1.530 +		uint32_t newAddr = MAP_ADDR(address);
   1.531 +
   1.532  		if (newAddr <= 0x1fffff) {
   1.533  			if (newAddr >= state.base_ram_size)
   1.534  				return EMPTY & 0xff;
   1.535 @@ -888,7 +895,8 @@
   1.536  		// ROM access
   1.537  	} else if (address <= 0x3FFFFF) {
   1.538  		// RAM access
   1.539 -		uint32_t newAddr = mapAddr(address, true);
   1.540 +		uint32_t newAddr = MAP_ADDR(address);
   1.541 +
   1.542  		if (newAddr <= 0x1fffff) {
   1.543  			if (newAddr < state.base_ram_size) {
   1.544  				WR32(state.base_ram, newAddr, state.base_ram_size - 1, value);
   1.545 @@ -933,7 +941,7 @@
   1.546  		// ROM access
   1.547  	} else if (address <= 0x3FFFFF) {
   1.548  		// RAM access
   1.549 -		uint32_t newAddr = mapAddr(address, true);
   1.550 +		uint32_t newAddr = MAP_ADDR(address);
   1.551  
   1.552  		if (newAddr <= 0x1fffff) {
   1.553  			if (newAddr < state.base_ram_size) {
   1.554 @@ -979,7 +987,8 @@
   1.555  		// ROM access (read only!)
   1.556  	} else if (address <= 0x3FFFFF) {
   1.557  		// RAM access
   1.558 -		uint32_t newAddr = mapAddr(address, true);
   1.559 +		uint32_t newAddr = MAP_ADDR(address);
   1.560 +
   1.561  		if (newAddr <= 0x1fffff) {
   1.562  			if (newAddr < state.base_ram_size) {
   1.563  				WR8(state.base_ram, newAddr, state.base_ram_size - 1, value);
   1.564 @@ -1013,6 +1022,7 @@
   1.565  uint32_t m68k_read_disassembler_32(uint32_t addr)
   1.566  {
   1.567  	if (addr < 0x400000) {
   1.568 +		// XXX FIXME BUGBUG update this to use the new mapper macros!
   1.569  		uint16_t page = (addr >> 12) & 0x3FF;
   1.570  		uint32_t new_page_addr = MAPRAM(page) & 0x3FF;
   1.571  		uint32_t newAddr = (new_page_addr << 12) + (addr & 0xFFF);
   1.572 @@ -1028,7 +1038,7 @@
   1.573  				return EMPTY;
   1.574  		}
   1.575  	} else {
   1.576 -		printf(">>> WARNING Disassembler RD32 out of range 0x%08X\n", addr);
   1.577 +		LOG("WARNING: Disassembler RD32 out of range 0x%08X\n", addr);
   1.578  		return EMPTY;
   1.579  	}
   1.580  }
   1.581 @@ -1051,7 +1061,7 @@
   1.582  				return EMPTY & 0xffff;
   1.583  		}
   1.584  	} else {
   1.585 -		printf(">>> WARNING Disassembler RD16 out of range 0x%08X\n", addr);
   1.586 +		LOG("WARNING: Disassembler RD16 out of range 0x%08X\n", addr);
   1.587  		return EMPTY & 0xffff;
   1.588  	}
   1.589  }
   1.590 @@ -1074,7 +1084,7 @@
   1.591  				return EMPTY & 0xff;
   1.592  		}
   1.593  	} else {
   1.594 -		printf(">>> WARNING Disassembler RD8 out of range 0x%08X\n", addr);
   1.595 +		LOG("WARNING: Disassembler RD8 out of range 0x%08X\n", addr);
   1.596  		return EMPTY & 0xff;
   1.597  	}
   1.598  }