src/memory.c

changeset 59
d2e3b9e5d082
parent 57
feb84193a43a
child 60
96f3df0b3cbb
     1.1 diff -r 85cc6101b587 -r d2e3b9e5d082 src/memory.c
     1.2 --- a/src/memory.c	Wed Dec 15 01:20:57 2010 +0000
     1.3 +++ b/src/memory.c	Tue Dec 28 16:59:40 2010 +0000
     1.4 @@ -2,6 +2,7 @@
     1.5  #include <stdlib.h>
     1.6  #include <stdint.h>
     1.7  #include <stdbool.h>
     1.8 +#include <assert.h>
     1.9  #include "musashi/m68k.h"
    1.10  #include "state.h"
    1.11  #include "memory.h"
    1.12 @@ -12,7 +13,7 @@
    1.13  
    1.14  #define MAPRAM(addr) (((uint16_t)state.map[addr*2] << 8) + ((uint16_t)state.map[(addr*2)+1]))
    1.15  
    1.16 -uint32_t mapAddr(uint32_t addr, bool writing)
    1.17 +uint32_t mapAddr(uint32_t addr, bool writing)/*{{{*/
    1.18  {
    1.19  	if (addr < 0x400000) {
    1.20  		// RAM access. Check against the Map RAM
    1.21 @@ -38,9 +39,9 @@
    1.22  		// TODO: assert here?
    1.23  		return addr;
    1.24  	}
    1.25 -}
    1.26 +}/*}}}*/
    1.27  
    1.28 -MEM_STATUS checkMemoryAccess(uint32_t addr, bool writing)
    1.29 +MEM_STATUS checkMemoryAccess(uint32_t addr, bool writing)/*{{{*/
    1.30  {
    1.31  	// Are we in Supervisor mode?
    1.32  	if (m68k_get_reg(NULL, M68K_REG_SR) & 0x2000)
    1.33 @@ -71,7 +72,7 @@
    1.34  
    1.35  	// Page access allowed.
    1.36  	return MEM_ALLOWED;
    1.37 -}
    1.38 +}/*}}}*/
    1.39  
    1.40  #undef MAPRAM
    1.41  
    1.42 @@ -89,7 +90,9 @@
    1.43   * 			in a non-void function, even if it's impossible to ever reach the
    1.44   * 			return-with-no-value. UGH!
    1.45   */
    1.46 -#define ACCESS_CHECK_WR(address, bits) do {							\
    1.47 +/*{{{ macro: ACCESS_CHECK_WR(address, bits)*/
    1.48 +#define ACCESS_CHECK_WR(address, bits)								\
    1.49 +	do {															\
    1.50  		bool fault = false;											\
    1.51  		/* MEM_STATUS st; */										\
    1.52  		switch (checkMemoryAccess(address, true)) {					\
    1.53 @@ -126,6 +129,7 @@
    1.54  			return;													\
    1.55  		}															\
    1.56  	} while (false)
    1.57 +/*}}}*/
    1.58  
    1.59  /**
    1.60   * @brief Check memory access permissions for a read operation.
    1.61 @@ -136,7 +140,9 @@
    1.62   * 			in a non-void function, even if it's impossible to ever reach the
    1.63   * 			return-with-no-value. UGH!
    1.64   */
    1.65 -#define ACCESS_CHECK_RD(address, bits) do {							\
    1.66 +/*{{{ macro: ACCESS_CHECK_RD(address, bits)*/
    1.67 +#define ACCESS_CHECK_RD(address, bits)								\
    1.68 +	do {															\
    1.69  		bool fault = false;											\
    1.70  		/* MEM_STATUS st; */										\
    1.71  		switch (checkMemoryAccess(address, false)) {				\
    1.72 @@ -173,81 +179,256 @@
    1.73  			return 0xFFFFFFFF;										\
    1.74  		}															\
    1.75  	} while (false)
    1.76 +/*}}}*/
    1.77  
    1.78  // Logging macros
    1.79 -#define LOG_NOT_HANDLED_R(bits)																	\
    1.80 -	do {																						\
    1.81 -		if (!handled)																			\
    1.82 -			printf("unhandled read%02d, addr=0x%08X\n", bits, address);							\
    1.83 -	} while (0);
    1.84 +#define LOG_NOT_HANDLED_R(bits)															\
    1.85 +	printf("unhandled read%02d, addr=0x%08X\n", bits, address);
    1.86  
    1.87 -#define LOG_NOT_HANDLED_W(bits)																	\
    1.88 -	do {																						\
    1.89 -		if (!handled)																			\
    1.90 -			printf("unhandled write%02d, addr=0x%08X, data=0x%08X\n", bits, address, value);	\
    1.91 -	} while (0);
    1.92 +#define LOG_NOT_HANDLED_W(bits)															\
    1.93 +	printf("unhandled write%02d, addr=0x%08X, data=0x%08X\n", bits, address, value);
    1.94 +
    1.95 +/********************************************************
    1.96 + * I/O read/write functions
    1.97 + ********************************************************/
    1.98  
    1.99  /**
   1.100 - * @brief Read M68K memory, 32-bit
   1.101 + * Issue a warning if a read operation is made with an invalid size
   1.102   */
   1.103 -uint32_t m68k_read_memory_32(uint32_t address)
   1.104 +inline static void ENFORCE_SIZE(int bits, uint32_t address, int allowed, char *regname)
   1.105  {
   1.106 -	uint32_t data = 0xFFFFFFFF;
   1.107 +	assert((bits == 8) || (bits == 16) || (bits == 32));
   1.108 +	if ((bits & allowed) == 0) {
   1.109 +		printf("WARNING: write to 0x%08X (%s) with invalid size %d!\n", address, regname, bits);
   1.110 +	}
   1.111 +}
   1.112 +
   1.113 +void IoWrite(uint32_t address, uint32_t data, int bits)/*{{{*/
   1.114 +{
   1.115  	bool handled = false;
   1.116  
   1.117 -	// If ROMLMAP is set, force system to access ROM
   1.118 -	if (!state.romlmap)
   1.119 -		address |= 0x800000;
   1.120 -
   1.121 -	// Check access permissions
   1.122 -	ACCESS_CHECK_RD(address, 32);
   1.123 -
   1.124 -	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.125 -		// ROM access
   1.126 -		data = RD32(state.rom, address, ROM_SIZE - 1);
   1.127 -		handled = true;
   1.128 -	} else if (address <= (state.ram_size - 1)) {
   1.129 -		// RAM access
   1.130 -		data = RD32(state.ram, mapAddr(address, false), state.ram_size - 1);
   1.131 -		handled = true;
   1.132 -	} else if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
   1.133 +	if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
   1.134  		// I/O register space, zone A
   1.135  		switch (address & 0x0F0000) {
   1.136 -			case 0x000000:				// Map RAM access
   1.137 -				if (address > 0x4007FF) fprintf(stderr, "NOTE: RD32 from MapRAM mirror, addr=0x%08X\n", address);
   1.138 -				data = RD32(state.map, address, 0x7FF);
   1.139 -				handled = true;
   1.140 -				break;
   1.141  			case 0x010000:				// General Status Register
   1.142 -				data = ((uint32_t)state.genstat << 16) + (uint32_t)state.genstat;
   1.143 -				handled = true;
   1.144 -				break;
   1.145 -			case 0x020000:				// Video RAM
   1.146 -				if (address > 0x427FFF) fprintf(stderr, "NOTE: RD32 from VideoRAM mirror, addr=0x%08X\n", address);
   1.147 -				data = RD32(state.vram, address, 0x7FFF);
   1.148 +				if (bits == 16)
   1.149 +					state.genstat = (data & 0xffff);
   1.150 +				else if (bits == 8) {
   1.151 +					if (address & 0)
   1.152 +						state.genstat = data;
   1.153 +					else
   1.154 +						state.genstat = data << 8;
   1.155 +				}
   1.156  				handled = true;
   1.157  				break;
   1.158  			case 0x030000:				// Bus Status Register 0
   1.159 -				data = ((uint32_t)state.bsr0 << 16) + (uint32_t)state.bsr0;
   1.160 -				handled = true;
   1.161  				break;
   1.162  			case 0x040000:				// Bus Status Register 1
   1.163 -				data = ((uint32_t)state.bsr1 << 16) + (uint32_t)state.bsr1;
   1.164 -				handled = true;
   1.165  				break;
   1.166  			case 0x050000:				// Phone status
   1.167  				break;
   1.168  			case 0x060000:				// DMA Count
   1.169 +				ENFORCE_SIZE(bits, address, 16, "DMACOUNT");
   1.170 +				state.dma_count = (data & 0x3FFF);
   1.171 +				state.idmarw = ((data & 0x4000) == 0x4000);
   1.172 +				state.dmaen = ((data & 0x8000) == 0x8000);
   1.173 +				// This handles the "dummy DMA transfer" mentioned in the docs
   1.174 +				// TODO: access check, peripheral access
   1.175 +				if (!state.idmarw)
   1.176 +					WR32(state.ram, mapAddr(address, false), state.ram_size - 1, 0xDEAD);
   1.177 +				state.dma_count++;
   1.178 +				handled = true;
   1.179 +				break;
   1.180 +			case 0x070000:				// Line Printer Status Register
   1.181 +				break;
   1.182 +			case 0x080000:				// Real Time Clock
   1.183 +				break;
   1.184 +			case 0x090000:				// Phone registers
   1.185 +				switch (address & 0x0FF000) {
   1.186 +					case 0x090000:		// Handset relay
   1.187 +					case 0x098000:
   1.188 +						break;
   1.189 +					case 0x091000:		// Line select 2
   1.190 +					case 0x099000:
   1.191 +						break;
   1.192 +					case 0x092000:		// Hook relay 1
   1.193 +					case 0x09A000:
   1.194 +						break;
   1.195 +					case 0x093000:		// Hook relay 2
   1.196 +					case 0x09B000:
   1.197 +						break;
   1.198 +					case 0x094000:		// Line 1 hold
   1.199 +					case 0x09C000:
   1.200 +						break;
   1.201 +					case 0x095000:		// Line 2 hold
   1.202 +					case 0x09D000:
   1.203 +						break;
   1.204 +					case 0x096000:		// Line 1 A-lead
   1.205 +					case 0x09E000:
   1.206 +						break;
   1.207 +					case 0x097000:		// Line 2 A-lead
   1.208 +					case 0x09F000:
   1.209 +						break;
   1.210 +				}
   1.211 +				break;
   1.212 +			case 0x0A0000:				// Miscellaneous Control Register
   1.213 +				ENFORCE_SIZE(bits, address, 16, "MISCCON");
   1.214 +				// TODO: handle the ctrl bits properly
   1.215 +				// TODO: &0x8000 --> dismiss 60hz intr
   1.216 +				state.dma_reading = (data & 0x4000);
   1.217 +				state.leds = (~data & 0xF00) >> 8;
   1.218 +				printf("LEDs: %s %s %s %s\n",
   1.219 +						(state.leds & 8) ? "R" : "-",
   1.220 +						(state.leds & 4) ? "G" : "-",
   1.221 +						(state.leds & 2) ? "Y" : "-",
   1.222 +						(state.leds & 1) ? "R" : "-");
   1.223 +				handled = true;
   1.224 +				break;
   1.225 +			case 0x0B0000:				// TM/DIALWR
   1.226 +				break;
   1.227 +			case 0x0C0000:				// Clear Status Register
   1.228 +				state.genstat = 0xFFFF;
   1.229 +				state.bsr0 = 0xFFFF;
   1.230 +				state.bsr1 = 0xFFFF;
   1.231 +				handled = true;
   1.232 +				break;
   1.233 +			case 0x0D0000:				// DMA Address Register
   1.234 +				if (address & 0x004000) {
   1.235 +					// A14 high -- set most significant bits
   1.236 +					state.dma_address = (state.dma_address & 0x1fe) | ((address & 0x3ffe) << 8);
   1.237 +				} else {
   1.238 +					// A14 low -- set least significant bits
   1.239 +					state.dma_address = (state.dma_address & 0x3ffe00) | (address & 0x1fe);
   1.240 +				}
   1.241 +				handled = true;
   1.242 +				break;
   1.243 +			case 0x0E0000:				// Disk Control Register
   1.244 +				ENFORCE_SIZE(bits, address, 16, "DISKCON");
   1.245 +				// B7 = FDD controller reset
   1.246 +				if ((data & 0x80) == 0) wd2797_reset(&state.fdc_ctx);
   1.247 +				// B6 = drive 0 select -- TODO
   1.248 +				// B5 = motor enable -- TODO
   1.249 +				// B4 = HDD controller reset -- TODO
   1.250 +				// B3 = HDD0 select -- TODO
   1.251 +				// B2,1,0 = HDD0 head select
   1.252 +				handled = true;
   1.253 +				break;
   1.254 +			case 0x0F0000:				// Line Printer Data Register
   1.255 +				break;
   1.256 +		}
   1.257 +	} else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) {
   1.258 +		// I/O register space, zone B
   1.259 +		switch (address & 0xF00000) {
   1.260 +			case 0xC00000:				// Expansion slots
   1.261 +			case 0xD00000:
   1.262 +				switch (address & 0xFC0000) {
   1.263 +					case 0xC00000:		// Expansion slot 0
   1.264 +					case 0xC40000:		// Expansion slot 1
   1.265 +					case 0xC80000:		// Expansion slot 2
   1.266 +					case 0xCC0000:		// Expansion slot 3
   1.267 +					case 0xD00000:		// Expansion slot 4
   1.268 +					case 0xD40000:		// Expansion slot 5
   1.269 +					case 0xD80000:		// Expansion slot 6
   1.270 +					case 0xDC0000:		// Expansion slot 7
   1.271 +						fprintf(stderr, "NOTE: WR%d to expansion card space, addr=0x%08X, data=0x%08X\n", bits, address, data);
   1.272 +						handled = true;
   1.273 +						break;
   1.274 +				}
   1.275 +				break;
   1.276 +			case 0xE00000:				// HDC, FDC, MCR2 and RTC data bits
   1.277 +			case 0xF00000:
   1.278 +				switch (address & 0x070000) {
   1.279 +					case 0x000000:		// [ef][08]xxxx ==> WD1010 hard disc controller
   1.280 +						break;
   1.281 +					case 0x010000:		// [ef][19]xxxx ==> WD2797 floppy disc controller
   1.282 +						ENFORCE_SIZE(bits, address, 16, "FDC REGISTERS");
   1.283 +						wd2797_write_reg(&state.fdc_ctx, (address >> 1) & 3, data);
   1.284 +						handled = true;
   1.285 +						break;
   1.286 +					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
   1.287 +						break;
   1.288 +					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
   1.289 +						break;
   1.290 +					case 0x040000:		// [ef][4c]xxxx ==> General Control Register
   1.291 +						switch (address & 0x077000) {
   1.292 +							case 0x040000:		// [ef][4c][08]xxx ==> EE
   1.293 +								break;
   1.294 +							case 0x041000:		// [ef][4c][19]xxx ==> PIE
   1.295 +								ENFORCE_SIZE(bits, address, 16, "PIE");
   1.296 +								state.pie = ((data & 0x8000) == 0x8000);
   1.297 +								handled = true;
   1.298 +								break;
   1.299 +							case 0x042000:		// [ef][4c][2A]xxx ==> BP
   1.300 +								break;
   1.301 +							case 0x043000:		// [ef][4c][3B]xxx ==> ROMLMAP
   1.302 +								ENFORCE_SIZE(bits, address, 16, "ROMLMAP");
   1.303 +								state.romlmap = ((data & 0x8000) == 0x8000);
   1.304 +								handled = true;
   1.305 +								break;
   1.306 +							case 0x044000:		// [ef][4c][4C]xxx ==> L1 MODEM
   1.307 +								ENFORCE_SIZE(bits, address, 16, "L1 MODEM");
   1.308 +								break;
   1.309 +							case 0x045000:		// [ef][4c][5D]xxx ==> L2 MODEM
   1.310 +								ENFORCE_SIZE(bits, address, 16, "L2 MODEM");
   1.311 +								break;
   1.312 +							case 0x046000:		// [ef][4c][6E]xxx ==> D/N CONNECT
   1.313 +								ENFORCE_SIZE(bits, address, 16, "D/N CONNECT");
   1.314 +								break;
   1.315 +							case 0x047000:		// [ef][4c][7F]xxx ==> Whole screen reverse video
   1.316 +								ENFORCE_SIZE(bits, address, 16, "WHOLE SCREEN REVERSE VIDEO");
   1.317 +								break;
   1.318 +						}
   1.319 +					case 0x050000:		// [ef][5d]xxxx ==> 8274
   1.320 +						break;
   1.321 +					case 0x060000:		// [ef][6e]xxxx ==> Control regs
   1.322 +						switch (address & 0x07F000) {
   1.323 +							default:
   1.324 +								break;
   1.325 +						}
   1.326 +						break;
   1.327 +					case 0x070000:		// [ef][7f]xxxx ==> 6850 Keyboard Controller
   1.328 +						break;
   1.329 +				}
   1.330 +		}
   1.331 +	}
   1.332 +}/*}}}*/
   1.333 +
   1.334 +uint32_t IoRead(uint32_t address, int bits)/*{{{*/
   1.335 +{
   1.336 +	bool handled = false;
   1.337 +	uint32_t data = 0xFFFFFFFF;
   1.338 +
   1.339 +	if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
   1.340 +		// I/O register space, zone A
   1.341 +		switch (address & 0x0F0000) {
   1.342 +			case 0x010000:				// General Status Register
   1.343 +				ENFORCE_SIZE(bits, address, 16, "GENSTAT");
   1.344 +				return ((uint32_t)state.genstat << 16) + (uint32_t)state.genstat;
   1.345 +				break;
   1.346 +			case 0x030000:				// Bus Status Register 0
   1.347 +				ENFORCE_SIZE(bits, address, 16, "BSR0");
   1.348 +				return ((uint32_t)state.bsr0 << 16) + (uint32_t)state.bsr0;
   1.349 +				break;
   1.350 +			case 0x040000:				// Bus Status Register 1
   1.351 +				ENFORCE_SIZE(bits, address, 16, "BSR1");
   1.352 +				return ((uint32_t)state.bsr1 << 16) + (uint32_t)state.bsr1;
   1.353 +				break;
   1.354 +			case 0x050000:				// Phone status
   1.355 +				ENFORCE_SIZE(bits, address, 16, "PHONE STATUS");
   1.356 +				break;
   1.357 +			case 0x060000:				// DMA Count
   1.358  				// TODO: U/OERR- is always inactive (bit set)... or should it be = DMAEN+?
   1.359  				// Bit 14 is always unused, so leave it set
   1.360 -				data = (state.dma_count & 0x3fff) | 0xC000;
   1.361 -				handled = true;
   1.362 +				ENFORCE_SIZE(bits, address, 16, "DMACOUNT");
   1.363 +				return (state.dma_count & 0x3fff) | 0xC000;
   1.364  				break;
   1.365  			case 0x070000:				// Line Printer Status Register
   1.366  				data = 0x00120012;	// no parity error, no line printer error, no irqs from FDD or HDD
   1.367  				data |= (state.fdc_ctx.irql) ? 0x00080008 : 0;	// FIXME! HACKHACKHACK! shouldn't peek inside FDC structs like this
   1.368 +				return data;
   1.369  				break;
   1.370  			case 0x080000:				// Real Time Clock
   1.371 +				printf("READ NOTIMP: Realtime Clock\n");
   1.372  				break;
   1.373  			case 0x090000:				// Phone registers
   1.374  				switch (address & 0x0FF000) {
   1.375 @@ -316,9 +497,8 @@
   1.376  					case 0x000000:		// [ef][08]xxxx ==> WD1010 hard disc controller
   1.377  						break;
   1.378  					case 0x010000:		// [ef][19]xxxx ==> WD2797 floppy disc controller
   1.379 -						data = wd2797_read_reg(&state.fdc_ctx, (address >> 1) & 3);
   1.380 -						printf("WD279X: rd32 %02X ==> %02X\n", (address >> 1) & 3, data);
   1.381 -						handled = true;
   1.382 +						ENFORCE_SIZE(bits, address, 16, "FDC REGISTERS");
   1.383 +						return wd2797_read_reg(&state.fdc_ctx, (address >> 1) & 3);
   1.384  						break;
   1.385  					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
   1.386  						break;
   1.387 @@ -353,18 +533,61 @@
   1.388  				}
   1.389  		}
   1.390  	}
   1.391 +	return data;
   1.392 +}/*}}}*/
   1.393  
   1.394 -	LOG_NOT_HANDLED_R(32);
   1.395 +
   1.396 +/********************************************************
   1.397 + * m68k memory read/write support functions for Musashi
   1.398 + ********************************************************/
   1.399 +
   1.400 +/**
   1.401 + * @brief Read M68K memory, 32-bit
   1.402 + */
   1.403 +uint32_t m68k_read_memory_32(uint32_t address)/*{{{*/
   1.404 +{
   1.405 +	uint32_t data = 0xFFFFFFFF;
   1.406 +
   1.407 +	// If ROMLMAP is set, force system to access ROM
   1.408 +	if (!state.romlmap)
   1.409 +		address |= 0x800000;
   1.410 +
   1.411 +	// Check access permissions
   1.412 +	ACCESS_CHECK_RD(address, 32);
   1.413 +
   1.414 +	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.415 +		// ROM access
   1.416 +		data = RD32(state.rom, address, ROM_SIZE - 1);
   1.417 +	} else if (address <= (state.ram_size - 1)) {
   1.418 +		// RAM access
   1.419 +		data = RD32(state.ram, mapAddr(address, false), state.ram_size - 1);
   1.420 +	} else if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
   1.421 +		// I/O register space, zone A
   1.422 +		switch (address & 0x0F0000) {
   1.423 +			case 0x000000:				// Map RAM access
   1.424 +				if (address > 0x4007FF) fprintf(stderr, "NOTE: RD32 from MapRAM mirror, addr=0x%08X\n", address);
   1.425 +				data = RD32(state.map, address, 0x7FF);
   1.426 +				break;
   1.427 +			case 0x020000:				// Video RAM
   1.428 +				if (address > 0x427FFF) fprintf(stderr, "NOTE: RD32 from VideoRAM mirror, addr=0x%08X\n", address);
   1.429 +				data = RD32(state.vram, address, 0x7FFF);
   1.430 +				break;
   1.431 +			default:
   1.432 +				data = IoRead(address, 32);
   1.433 +		}
   1.434 +	} else {
   1.435 +		data = IoRead(address, 32);
   1.436 +	}
   1.437 +
   1.438  	return data;
   1.439 -}
   1.440 +}/*}}}*/
   1.441  
   1.442  /**
   1.443   * @brief Read M68K memory, 16-bit
   1.444   */
   1.445 -uint32_t m68k_read_memory_16(uint32_t address)
   1.446 +uint32_t m68k_read_memory_16(uint32_t address)/*{{{*/
   1.447  {
   1.448  	uint16_t data = 0xFFFF;
   1.449 -	bool handled = false;
   1.450  
   1.451  	// If ROMLMAP is set, force system to access ROM
   1.452  	if (!state.romlmap)
   1.453 @@ -376,166 +599,36 @@
   1.454  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.455  		// ROM access
   1.456  		data = RD16(state.rom, address, ROM_SIZE - 1);
   1.457 -		handled = true;
   1.458  	} else if (address <= (state.ram_size - 1)) {
   1.459  		// RAM access
   1.460  		data = RD16(state.ram, mapAddr(address, false), state.ram_size - 1);
   1.461 -		handled = true;
   1.462  	} else if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
   1.463  		// I/O register space, zone A
   1.464  		switch (address & 0x0F0000) {
   1.465  			case 0x000000:				// Map RAM access
   1.466  				if (address > 0x4007FF) fprintf(stderr, "NOTE: RD16 from MapRAM mirror, addr=0x%08X\n", address);
   1.467  				data = RD16(state.map, address, 0x7FF);
   1.468 -				handled = true;
   1.469 -				break;
   1.470 -			case 0x010000:				// General Status Register
   1.471 -				data = state.genstat;
   1.472 -				handled = true;
   1.473  				break;
   1.474  			case 0x020000:				// Video RAM
   1.475  				if (address > 0x427FFF) fprintf(stderr, "NOTE: RD16 from VideoRAM mirror, addr=0x%08X\n", address);
   1.476  				data = RD16(state.vram, address, 0x7FFF);
   1.477 -				handled = true;
   1.478  				break;
   1.479 -			case 0x030000:				// Bus Status Register 0
   1.480 -				data = state.bsr0;
   1.481 -				handled = true;
   1.482 -				break;
   1.483 -			case 0x040000:				// Bus Status Register 1
   1.484 -				data = state.bsr1;
   1.485 -				handled = true;
   1.486 -				break;
   1.487 -			case 0x050000:				// Phone status
   1.488 -				break;
   1.489 -			case 0x060000:				// DMA Count
   1.490 -				// TODO: U/OERR- is always inactive (bit set)... or should it be = DMAEN+?
   1.491 -				// Bit 14 is always unused, so leave it set
   1.492 -				data = (state.dma_count & 0x3fff) | 0xC000;
   1.493 -				handled = true;
   1.494 -				break;
   1.495 -			case 0x070000:				// Line Printer Status Register
   1.496 -				data = 0x0012;	// no parity error, no line printer error, no irqs from FDD or HDD
   1.497 -				data |= (state.fdc_ctx.irql) ? 0x0008 : 0;	// FIXME! HACKHACKHACK! shouldn't peek inside FDC structs like this
   1.498 -				break;
   1.499 -			case 0x080000:				// Real Time Clock
   1.500 -				break;
   1.501 -			case 0x090000:				// Phone registers
   1.502 -				switch (address & 0x0FF000) {
   1.503 -					case 0x090000:		// Handset relay
   1.504 -					case 0x098000:
   1.505 -						break;
   1.506 -					case 0x091000:		// Line select 2
   1.507 -					case 0x099000:
   1.508 -						break;
   1.509 -					case 0x092000:		// Hook relay 1
   1.510 -					case 0x09A000:
   1.511 -						break;
   1.512 -					case 0x093000:		// Hook relay 2
   1.513 -					case 0x09B000:
   1.514 -						break;
   1.515 -					case 0x094000:		// Line 1 hold
   1.516 -					case 0x09C000:
   1.517 -						break;
   1.518 -					case 0x095000:		// Line 2 hold
   1.519 -					case 0x09D000:
   1.520 -						break;
   1.521 -					case 0x096000:		// Line 1 A-lead
   1.522 -					case 0x09E000:
   1.523 -						break;
   1.524 -					case 0x097000:		// Line 2 A-lead
   1.525 -					case 0x09F000:
   1.526 -						break;
   1.527 -				}
   1.528 -				break;
   1.529 -			case 0x0A0000:				// Miscellaneous Control Register -- write only!
   1.530 -				handled = true;
   1.531 -				break;
   1.532 -			case 0x0B0000:				// TM/DIALWR
   1.533 -				break;
   1.534 -			case 0x0C0000:				// Clear Status Register -- write only!
   1.535 -				handled = true;
   1.536 -				break;
   1.537 -			case 0x0D0000:				// DMA Address Register
   1.538 -				break;
   1.539 -			case 0x0E0000:				// Disk Control Register
   1.540 -				break;
   1.541 -			case 0x0F0000:				// Line Printer Data Register
   1.542 -				break;
   1.543 +			default:
   1.544 +				data = IoRead(address, 16);
   1.545  		}
   1.546 -	} else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) {
   1.547 -		// I/O register space, zone B
   1.548 -		switch (address & 0xF00000) {
   1.549 -			case 0xC00000:				// Expansion slots
   1.550 -			case 0xD00000:
   1.551 -				switch (address & 0xFC0000) {
   1.552 -					case 0xC00000:		// Expansion slot 0
   1.553 -					case 0xC40000:		// Expansion slot 1
   1.554 -					case 0xC80000:		// Expansion slot 2
   1.555 -					case 0xCC0000:		// Expansion slot 3
   1.556 -					case 0xD00000:		// Expansion slot 4
   1.557 -					case 0xD40000:		// Expansion slot 5
   1.558 -					case 0xD80000:		// Expansion slot 6
   1.559 -					case 0xDC0000:		// Expansion slot 7
   1.560 -						fprintf(stderr, "NOTE: RD16 from expansion card space, addr=0x%08X\n", address);
   1.561 -						break;
   1.562 -				}
   1.563 -				break;
   1.564 -			case 0xE00000:				// HDC, FDC, MCR2 and RTC data bits
   1.565 -			case 0xF00000:
   1.566 -				switch (address & 0x070000) {
   1.567 -					case 0x000000:		// [ef][08]xxxx ==> WD1010 hard disc controller
   1.568 -						break;
   1.569 -					case 0x010000:		// [ef][19]xxxx ==> WD2797 floppy disc controller
   1.570 -						data = wd2797_read_reg(&state.fdc_ctx, (address >> 1) & 3);
   1.571 -						printf("WD279X: rd16 %02X ==> %02X\n", (address >> 1) & 3, data);
   1.572 -						handled = true;
   1.573 -						break;
   1.574 -					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
   1.575 -						break;
   1.576 -					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
   1.577 -						break;
   1.578 -					case 0x040000:		// [ef][4c]xxxx ==> General Control Register
   1.579 -						switch (address & 0x077000) {
   1.580 -							case 0x040000:		// [ef][4c][08]xxx ==> EE
   1.581 -							case 0x041000:		// [ef][4c][19]xxx ==> PIE
   1.582 -							case 0x042000:		// [ef][4c][2A]xxx ==> BP
   1.583 -							case 0x043000:		// [ef][4c][3B]xxx ==> ROMLMAP
   1.584 -							case 0x044000:		// [ef][4c][4C]xxx ==> L1 MODEM
   1.585 -							case 0x045000:		// [ef][4c][5D]xxx ==> L2 MODEM
   1.586 -							case 0x046000:		// [ef][4c][6E]xxx ==> D/N CONNECT
   1.587 -								// All write-only registers... TODO: bus error?
   1.588 -								handled = true;
   1.589 -								break;
   1.590 -							case 0x047000:		// [ef][4c][7F]xxx ==> Whole screen reverse video
   1.591 -								break;
   1.592 -						}
   1.593 -						break;
   1.594 -					case 0x050000:		// [ef][5d]xxxx ==> 8274
   1.595 -						break;
   1.596 -					case 0x060000:		// [ef][6e]xxxx ==> Control regs
   1.597 -						switch (address & 0x07F000) {
   1.598 -							default:
   1.599 -								break;
   1.600 -						}
   1.601 -						break;
   1.602 -					case 0x070000:		// [ef][7f]xxxx ==> 6850 Keyboard Controller
   1.603 -						break;
   1.604 -				}
   1.605 -		}
   1.606 +	} else {
   1.607 +		data = IoRead(address, 16);
   1.608  	}
   1.609  
   1.610 -	LOG_NOT_HANDLED_R(16);
   1.611  	return data;
   1.612 -}
   1.613 +}/*}}}*/
   1.614  
   1.615  /**
   1.616   * @brief Read M68K memory, 8-bit
   1.617   */
   1.618 -uint32_t m68k_read_memory_8(uint32_t address)
   1.619 +uint32_t m68k_read_memory_8(uint32_t address)/*{{{*/
   1.620  {
   1.621  	uint8_t data = 0xFF;
   1.622 -	bool handled = false;
   1.623  
   1.624  	// If ROMLMAP is set, force system to access ROM
   1.625  	if (!state.romlmap)
   1.626 @@ -547,179 +640,35 @@
   1.627  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.628  		// ROM access
   1.629  		data = RD8(state.rom, address, ROM_SIZE - 1);
   1.630 -		handled = true;
   1.631  	} else if (address <= (state.ram_size - 1)) {
   1.632  		// RAM access
   1.633  		data = RD8(state.ram, mapAddr(address, false), state.ram_size - 1);
   1.634 -		handled = true;
   1.635  	} else if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
   1.636  		// I/O register space, zone A
   1.637  		switch (address & 0x0F0000) {
   1.638  			case 0x000000:				// Map RAM access
   1.639  				if (address > 0x4007FF) fprintf(stderr, "NOTE: RD8 from MapRAM mirror, addr=0x%08X\n", address);
   1.640  				data = RD8(state.map, address, 0x7FF);
   1.641 -				handled = true;
   1.642 -				break;
   1.643 -			case 0x010000:				// General Status Register
   1.644 -				if ((address & 1) == 0)
   1.645 -					data = (state.genstat >> 8) & 0xff;
   1.646 -				else
   1.647 -					data = (state.genstat)      & 0xff;
   1.648 -				handled = true;
   1.649  				break;
   1.650  			case 0x020000:				// Video RAM
   1.651  				if (address > 0x427FFF) fprintf(stderr, "NOTE: RD8 from VideoRAM mirror, addr=0x%08X\n", address);
   1.652  				data = RD8(state.vram, address, 0x7FFF);
   1.653 -				handled = true;
   1.654  				break;
   1.655 -			case 0x030000:				// Bus Status Register 0
   1.656 -				if ((address & 1) == 0)
   1.657 -					data = (state.bsr0 >> 8) & 0xff;
   1.658 -				else
   1.659 -					data = (state.bsr0)      & 0xff;
   1.660 -				handled = true;
   1.661 -				break;
   1.662 -			case 0x040000:				// Bus Status Register 1
   1.663 -				if ((address & 1) == 0)
   1.664 -					data = (state.bsr1 >> 8) & 0xff;
   1.665 -				else
   1.666 -					data = (state.bsr1)      & 0xff;
   1.667 -				handled = true;
   1.668 -				break;
   1.669 -			case 0x050000:				// Phone status
   1.670 -				break;
   1.671 -			case 0x060000:				// DMA Count
   1.672 -				// TODO: how to handle this in 8bit mode?
   1.673 -				break;
   1.674 -			case 0x070000:				// Line Printer Status Register
   1.675 -				printf("\tLPSR RD8 fdc irql=%d, irqe=%d\n", state.fdc_ctx.irql, state.fdc_ctx.irqe);
   1.676 -				if (address & 1) {
   1.677 -					data = 0x12;	// no parity error, no line printer error, no irqs from FDD or HDD
   1.678 -					data |= (state.fdc_ctx.irql) ? 0x08 : 0;	// FIXME! HACKHACKHACK! shouldn't peek inside FDC structs like this
   1.679 -//					data |= 0x04; // HDD interrupt, i.e. command complete -- HACKHACKHACK!
   1.680 -				} else {
   1.681 -					data = 0;
   1.682 -				}
   1.683 -				handled = true;
   1.684 -				break;
   1.685 -			case 0x080000:				// Real Time Clock
   1.686 -				break;
   1.687 -			case 0x090000:				// Phone registers
   1.688 -				switch (address & 0x0FF000) {
   1.689 -					case 0x090000:		// Handset relay
   1.690 -					case 0x098000:
   1.691 -						break;
   1.692 -					case 0x091000:		// Line select 2
   1.693 -					case 0x099000:
   1.694 -						break;
   1.695 -					case 0x092000:		// Hook relay 1
   1.696 -					case 0x09A000:
   1.697 -						break;
   1.698 -					case 0x093000:		// Hook relay 2
   1.699 -					case 0x09B000:
   1.700 -						break;
   1.701 -					case 0x094000:		// Line 1 hold
   1.702 -					case 0x09C000:
   1.703 -						break;
   1.704 -					case 0x095000:		// Line 2 hold
   1.705 -					case 0x09D000:
   1.706 -						break;
   1.707 -					case 0x096000:		// Line 1 A-lead
   1.708 -					case 0x09E000:
   1.709 -						break;
   1.710 -					case 0x097000:		// Line 2 A-lead
   1.711 -					case 0x09F000:
   1.712 -						break;
   1.713 -				}
   1.714 -				break;
   1.715 -			case 0x0A0000:				// Miscellaneous Control Register -- write only!
   1.716 -				handled = true;
   1.717 -				break;
   1.718 -			case 0x0B0000:				// TM/DIALWR
   1.719 -				break;
   1.720 -			case 0x0C0000:				// Clear Status Register -- write only!
   1.721 -				handled = true;
   1.722 -				break;
   1.723 -			case 0x0D0000:				// DMA Address Register
   1.724 -				break;
   1.725 -			case 0x0E0000:				// Disk Control Register
   1.726 -				break;
   1.727 -			case 0x0F0000:				// Line Printer Data Register
   1.728 -				break;
   1.729 +			default:
   1.730 +				data = IoRead(address, 8);
   1.731  		}
   1.732 -	} else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) {
   1.733 -		// I/O register space, zone B
   1.734 -		switch (address & 0xF00000) {
   1.735 -			case 0xC00000:				// Expansion slots
   1.736 -			case 0xD00000:
   1.737 -				switch (address & 0xFC0000) {
   1.738 -					case 0xC00000:		// Expansion slot 0
   1.739 -					case 0xC40000:		// Expansion slot 1
   1.740 -					case 0xC80000:		// Expansion slot 2
   1.741 -					case 0xCC0000:		// Expansion slot 3
   1.742 -					case 0xD00000:		// Expansion slot 4
   1.743 -					case 0xD40000:		// Expansion slot 5
   1.744 -					case 0xD80000:		// Expansion slot 6
   1.745 -					case 0xDC0000:		// Expansion slot 7
   1.746 -						fprintf(stderr, "NOTE: RD8 from expansion card space, addr=0x%08X\n", address);
   1.747 -						break;
   1.748 -				}
   1.749 -				break;
   1.750 -			case 0xE00000:				// HDC, FDC, MCR2 and RTC data bits
   1.751 -			case 0xF00000:
   1.752 -				switch (address & 0x070000) {
   1.753 -					case 0x000000:		// [ef][08]xxxx ==> WD1010 hard disc controller
   1.754 -						break;
   1.755 -					case 0x010000:		// [ef][19]xxxx ==> WD2797 floppy disc controller
   1.756 -						data = wd2797_read_reg(&state.fdc_ctx, (address >> 1) & 3);
   1.757 -						printf("WD279X: rd8 %02X ==> %02X\n", (address >> 1) & 3, data);
   1.758 -						handled = true;
   1.759 -						break;
   1.760 -					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
   1.761 -						break;
   1.762 -					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
   1.763 -						break;
   1.764 -					case 0x040000:		// [ef][4c]xxxx ==> General Control Register
   1.765 -						switch (address & 0x077000) {
   1.766 -							case 0x040000:		// [ef][4c][08]xxx ==> EE
   1.767 -							case 0x041000:		// [ef][4c][19]xxx ==> PIE
   1.768 -							case 0x042000:		// [ef][4c][2A]xxx ==> BP
   1.769 -							case 0x043000:		// [ef][4c][3B]xxx ==> ROMLMAP
   1.770 -							case 0x044000:		// [ef][4c][4C]xxx ==> L1 MODEM
   1.771 -							case 0x045000:		// [ef][4c][5D]xxx ==> L2 MODEM
   1.772 -							case 0x046000:		// [ef][4c][6E]xxx ==> D/N CONNECT
   1.773 -								// All write-only registers... TODO: bus error?
   1.774 -								handled = true;
   1.775 -								break;
   1.776 -							case 0x047000:		// [ef][4c][7F]xxx ==> Whole screen reverse video
   1.777 -								break;
   1.778 -						}
   1.779 -					case 0x050000:		// [ef][5d]xxxx ==> 8274
   1.780 -						break;
   1.781 -					case 0x060000:		// [ef][6e]xxxx ==> Control regs
   1.782 -						switch (address & 0x07F000) {
   1.783 -							default:
   1.784 -								break;
   1.785 -						}
   1.786 -						break;
   1.787 -					case 0x070000:		// [ef][7f]xxxx ==> 6850 Keyboard Controller
   1.788 -						break;
   1.789 -				}
   1.790 -		}
   1.791 +	} else {
   1.792 +		data = IoRead(address, 8);
   1.793  	}
   1.794  
   1.795 -	LOG_NOT_HANDLED_R(8);
   1.796 -
   1.797  	return data;
   1.798 -}
   1.799 +}/*}}}*/
   1.800  
   1.801  /**
   1.802   * @brief Write M68K memory, 32-bit
   1.803   */
   1.804 -void m68k_write_memory_32(uint32_t address, uint32_t value)
   1.805 +void m68k_write_memory_32(uint32_t address, uint32_t value)/*{{{*/
   1.806  {
   1.807 -	bool handled = false;
   1.808 -
   1.809  	// If ROMLMAP is set, force system to access ROM
   1.810  	if (!state.romlmap)
   1.811  		address |= 0x800000;
   1.812 @@ -729,203 +678,33 @@
   1.813  
   1.814  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.815  		// ROM access
   1.816 -		handled = true;
   1.817  	} else if (address <= (state.ram_size - 1)) {
   1.818  		// RAM access
   1.819  		WR32(state.ram, mapAddr(address, false), state.ram_size - 1, value);
   1.820 -		handled = true;
   1.821  	} else if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
   1.822  		// I/O register space, zone A
   1.823  		switch (address & 0x0F0000) {
   1.824  			case 0x000000:				// Map RAM access
   1.825 -				if (address > 0x4007FF) fprintf(stderr, "NOTE: WR32 to MapRAM mirror, addr=0x%08X, data=0x%08X\n", address, value);
   1.826 +				if (address > 0x4007FF) fprintf(stderr, "NOTE: RD32 from MapRAM mirror, addr=0x%08X\n", address);
   1.827  				WR32(state.map, address, 0x7FF, value);
   1.828 -				handled = true;
   1.829 -				break;
   1.830 -			case 0x010000:				// General Status Register
   1.831 -				state.genstat = (value & 0xffff);
   1.832 -				handled = true;
   1.833  				break;
   1.834  			case 0x020000:				// Video RAM
   1.835 -				if (address > 0x427FFF) fprintf(stderr, "NOTE: WR32 to VideoRAM mirror, addr=0x%08X, data=0x%08X\n", address, value);
   1.836 +				if (address > 0x427FFF) fprintf(stderr, "NOTE: RD32 from VideoRAM mirror, addr=0x%08X\n", address);
   1.837  				WR32(state.vram, address, 0x7FFF, value);
   1.838 -				handled = true;
   1.839 -				break;
   1.840 -			case 0x030000:				// Bus Status Register 0
   1.841 -				break;
   1.842 -			case 0x040000:				// Bus Status Register 1
   1.843 -				break;
   1.844 -			case 0x050000:				// Phone status
   1.845 -				break;
   1.846 -			case 0x060000:				// DMA Count
   1.847 -				printf("WR32 dmacount %08X\n", value);
   1.848 -				state.dma_count = (value & 0x3FFF);
   1.849 -				state.idmarw = ((value & 0x4000) == 0x4000);
   1.850 -				state.dmaen = ((value & 0x8000) == 0x8000);
   1.851 -				printf("\tcount %04X, idmarw %d, dmaen %d\n", state.dma_count, state.idmarw, state.dmaen);
   1.852 -				// This handles the "dummy DMA transfer" mentioned in the docs
   1.853 -				// TODO: access check, peripheral access
   1.854 -				if (!state.idmarw)
   1.855 -					WR32(state.ram, mapAddr(address, false), state.ram_size - 1, 0xDEAD);
   1.856 -				state.dma_count++;
   1.857 -				handled = true;
   1.858 -				break;
   1.859 -			case 0x070000:				// Line Printer Status Register
   1.860 -				break;
   1.861 -			case 0x080000:				// Real Time Clock
   1.862 -				break;
   1.863 -			case 0x090000:				// Phone registers
   1.864 -				switch (address & 0x0FF000) {
   1.865 -					case 0x090000:		// Handset relay
   1.866 -					case 0x098000:
   1.867 -						break;
   1.868 -					case 0x091000:		// Line select 2
   1.869 -					case 0x099000:
   1.870 -						break;
   1.871 -					case 0x092000:		// Hook relay 1
   1.872 -					case 0x09A000:
   1.873 -						break;
   1.874 -					case 0x093000:		// Hook relay 2
   1.875 -					case 0x09B000:
   1.876 -						break;
   1.877 -					case 0x094000:		// Line 1 hold
   1.878 -					case 0x09C000:
   1.879 -						break;
   1.880 -					case 0x095000:		// Line 2 hold
   1.881 -					case 0x09D000:
   1.882 -						break;
   1.883 -					case 0x096000:		// Line 1 A-lead
   1.884 -					case 0x09E000:
   1.885 -						break;
   1.886 -					case 0x097000:		// Line 2 A-lead
   1.887 -					case 0x09F000:
   1.888 -						break;
   1.889 -				}
   1.890 -				break;
   1.891 -			case 0x0A0000:				// Miscellaneous Control Register
   1.892 -				// TODO: handle the ctrl bits properly
   1.893 -				// TODO: &0x8000 --> dismiss 60hz intr
   1.894 -				state.dma_reading = (value & 0x4000);
   1.895 -				state.leds = (~value & 0xF00) >> 8;
   1.896 -				printf("LEDs: %s %s %s %s\n",
   1.897 -						(state.leds & 8) ? "R" : "-",
   1.898 -						(state.leds & 4) ? "G" : "-",
   1.899 -						(state.leds & 2) ? "Y" : "-",
   1.900 -						(state.leds & 1) ? "R" : "-");
   1.901 -				handled = true;
   1.902 -				break;
   1.903 -			case 0x0B0000:				// TM/DIALWR
   1.904 -				break;
   1.905 -			case 0x0C0000:				// Clear Status Register
   1.906 -				state.genstat = 0xFFFF;
   1.907 -				state.bsr0 = 0xFFFF;
   1.908 -				state.bsr1 = 0xFFFF;
   1.909 -				handled = true;
   1.910 -				break;
   1.911 -			case 0x0D0000:				// DMA Address Register
   1.912 -				if (address & 0x004000) {
   1.913 -					// A14 high -- set most significant bits
   1.914 -					state.dma_address = (state.dma_address & 0x1fe) | ((address & 0x3ffe) << 8);
   1.915 -				} else {
   1.916 -					// A14 low -- set least significant bits
   1.917 -					state.dma_address = (state.dma_address & 0x3ffe00) | (address & 0x1fe);
   1.918 -				}
   1.919 -				printf("WR32 DMA_ADDR %s, now %08X\n", address & 0x004000 ? "HI" : "LO", state.dma_address);
   1.920 -				handled = true;
   1.921  				break;
   1.922 -			case 0x0E0000:				// Disk Control Register
   1.923 -				// B7 = FDD controller reset
   1.924 -				if ((value & 0x80) == 0) wd2797_reset(&state.fdc_ctx);
   1.925 -				// B6 = drive 0 select -- TODO
   1.926 -				// B5 = motor enable -- TODO
   1.927 -				// B4 = HDD controller reset -- TODO
   1.928 -				// B3 = HDD0 select -- TODO
   1.929 -				// B2,1,0 = HDD0 head select
   1.930 -				handled = true;
   1.931 -				break;
   1.932 -			case 0x0F0000:				// Line Printer Data Register
   1.933 -				break;
   1.934 +			default:
   1.935 +				IoWrite(address, value, 32);
   1.936  		}
   1.937 -	} else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) {
   1.938 -		// I/O register space, zone B
   1.939 -		switch (address & 0xF00000) {
   1.940 -			case 0xC00000:				// Expansion slots
   1.941 -			case 0xD00000:
   1.942 -				switch (address & 0xFC0000) {
   1.943 -					case 0xC00000:		// Expansion slot 0
   1.944 -					case 0xC40000:		// Expansion slot 1
   1.945 -					case 0xC80000:		// Expansion slot 2
   1.946 -					case 0xCC0000:		// Expansion slot 3
   1.947 -					case 0xD00000:		// Expansion slot 4
   1.948 -					case 0xD40000:		// Expansion slot 5
   1.949 -					case 0xD80000:		// Expansion slot 6
   1.950 -					case 0xDC0000:		// Expansion slot 7
   1.951 -						fprintf(stderr, "NOTE: WR32 to expansion card space, addr=0x%08X, data=0x%08X\n", address, value);
   1.952 -						handled = true;
   1.953 -						break;
   1.954 -				}
   1.955 -				break;
   1.956 -			case 0xE00000:				// HDC, FDC, MCR2 and RTC data bits
   1.957 -			case 0xF00000:
   1.958 -				switch (address & 0x070000) {
   1.959 -					case 0x000000:		// [ef][08]xxxx ==> WD1010 hard disc controller
   1.960 -						break;
   1.961 -					case 0x010000:		// [ef][19]xxxx ==> WD2797 floppy disc controller
   1.962 -						printf("WD279X: wr32 %02X ==> %02X\n", (address >> 1) & 3, value);
   1.963 -						wd2797_write_reg(&state.fdc_ctx, (address >> 1) & 3, value);
   1.964 -						handled = true;
   1.965 -						break;
   1.966 -					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
   1.967 -						break;
   1.968 -					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
   1.969 -						break;
   1.970 -					case 0x040000:		// [ef][4c]xxxx ==> General Control Register
   1.971 -						switch (address & 0x077000) {
   1.972 -							case 0x040000:		// [ef][4c][08]xxx ==> EE
   1.973 -								break;
   1.974 -							case 0x041000:		// [ef][4c][19]xxx ==> PIE
   1.975 -								state.pie = ((value & 0x8000) == 0x8000);
   1.976 -								handled = true;
   1.977 -								break;
   1.978 -							case 0x042000:		// [ef][4c][2A]xxx ==> BP
   1.979 -								break;
   1.980 -							case 0x043000:		// [ef][4c][3B]xxx ==> ROMLMAP
   1.981 -								state.romlmap = ((value & 0x8000) == 0x8000);
   1.982 -								handled = true;
   1.983 -								break;
   1.984 -							case 0x044000:		// [ef][4c][4C]xxx ==> L1 MODEM
   1.985 -								break;
   1.986 -							case 0x045000:		// [ef][4c][5D]xxx ==> L2 MODEM
   1.987 -								break;
   1.988 -							case 0x046000:		// [ef][4c][6E]xxx ==> D/N CONNECT
   1.989 -								break;
   1.990 -							case 0x047000:		// [ef][4c][7F]xxx ==> Whole screen reverse video
   1.991 -								break;
   1.992 -						}
   1.993 -					case 0x050000:		// [ef][5d]xxxx ==> 8274
   1.994 -						break;
   1.995 -					case 0x060000:		// [ef][6e]xxxx ==> Control regs
   1.996 -						switch (address & 0x07F000) {
   1.997 -							default:
   1.998 -								break;
   1.999 -						}
  1.1000 -						break;
  1.1001 -					case 0x070000:		// [ef][7f]xxxx ==> 6850 Keyboard Controller
  1.1002 -						break;
  1.1003 -				}
  1.1004 -		}
  1.1005 +	} else {
  1.1006 +		IoWrite(address, value, 32);
  1.1007  	}
  1.1008 -
  1.1009 -	LOG_NOT_HANDLED_W(32);
  1.1010 -}
  1.1011 +}/*}}}*/
  1.1012  
  1.1013  /**
  1.1014   * @brief Write M68K memory, 16-bit
  1.1015   */
  1.1016 -void m68k_write_memory_16(uint32_t address, uint32_t value)
  1.1017 +void m68k_write_memory_16(uint32_t address, uint32_t value)/*{{{*/
  1.1018  {
  1.1019 -	bool handled = false;
  1.1020 -
  1.1021  	// If ROMLMAP is set, force system to access ROM
  1.1022  	if (!state.romlmap)
  1.1023  		address |= 0x800000;
  1.1024 @@ -935,203 +714,33 @@
  1.1025  
  1.1026  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
  1.1027  		// ROM access
  1.1028 -		handled = true;
  1.1029  	} else if (address <= (state.ram_size - 1)) {
  1.1030  		// RAM access
  1.1031  		WR16(state.ram, mapAddr(address, false), state.ram_size - 1, value);
  1.1032 -		handled = true;
  1.1033  	} else if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
  1.1034  		// I/O register space, zone A
  1.1035  		switch (address & 0x0F0000) {
  1.1036  			case 0x000000:				// Map RAM access
  1.1037  				if (address > 0x4007FF) fprintf(stderr, "NOTE: WR16 to MapRAM mirror, addr=0x%08X, data=0x%04X\n", address, value);
  1.1038  				WR16(state.map, address, 0x7FF, value);
  1.1039 -				handled = true;
  1.1040 -				break;
  1.1041 -			case 0x010000:				// General Status Register (read only)
  1.1042 -				handled = true;
  1.1043  				break;
  1.1044  			case 0x020000:				// Video RAM
  1.1045  				if (address > 0x427FFF) fprintf(stderr, "NOTE: WR16 to VideoRAM mirror, addr=0x%08X, data=0x%04X\n", address, value);
  1.1046  				WR16(state.vram, address, 0x7FFF, value);
  1.1047 -				handled = true;
  1.1048  				break;
  1.1049 -			case 0x030000:				// Bus Status Register 0 (read only)
  1.1050 -				handled = true;
  1.1051 -				break;
  1.1052 -			case 0x040000:				// Bus Status Register 1 (read only)
  1.1053 -				handled = true;
  1.1054 -				break;
  1.1055 -			case 0x050000:				// Phone status
  1.1056 -				break;
  1.1057 -			case 0x060000:				// DMA Count
  1.1058 -				printf("WR16 dmacount %08X\n", value);
  1.1059 -				state.dma_count = (value & 0x3FFF);
  1.1060 -				state.idmarw = ((value & 0x4000) == 0x4000);
  1.1061 -				state.dmaen = ((value & 0x8000) == 0x8000);
  1.1062 -				printf("\tcount %04X, idmarw %d, dmaen %d\n", state.dma_count, state.idmarw, state.dmaen);
  1.1063 -				// This handles the "dummy DMA transfer" mentioned in the docs
  1.1064 -				// TODO: access check, peripheral access
  1.1065 -				if (!state.idmarw)
  1.1066 -					WR32(state.ram, mapAddr(address, false), state.ram_size - 1, 0xDEAD);
  1.1067 -				state.dma_count++;
  1.1068 -				handled = true;
  1.1069 -				break;
  1.1070 -			case 0x070000:				// Line Printer Status Register
  1.1071 -				break;
  1.1072 -			case 0x080000:				// Real Time Clock
  1.1073 -				break;
  1.1074 -			case 0x090000:				// Phone registers
  1.1075 -				switch (address & 0x0FF000) {
  1.1076 -					case 0x090000:		// Handset relay
  1.1077 -					case 0x098000:
  1.1078 -						break;
  1.1079 -					case 0x091000:		// Line select 2
  1.1080 -					case 0x099000:
  1.1081 -						break;
  1.1082 -					case 0x092000:		// Hook relay 1
  1.1083 -					case 0x09A000:
  1.1084 -						break;
  1.1085 -					case 0x093000:		// Hook relay 2
  1.1086 -					case 0x09B000:
  1.1087 -						break;
  1.1088 -					case 0x094000:		// Line 1 hold
  1.1089 -					case 0x09C000:
  1.1090 -						break;
  1.1091 -					case 0x095000:		// Line 2 hold
  1.1092 -					case 0x09D000:
  1.1093 -						break;
  1.1094 -					case 0x096000:		// Line 1 A-lead
  1.1095 -					case 0x09E000:
  1.1096 -						break;
  1.1097 -					case 0x097000:		// Line 2 A-lead
  1.1098 -					case 0x09F000:
  1.1099 -						break;
  1.1100 -				}
  1.1101 -				break;
  1.1102 -			case 0x0A0000:				// Miscellaneous Control Register
  1.1103 -				// TODO: handle the ctrl bits properly
  1.1104 -				// TODO: &0x8000 --> dismiss 60hz intr
  1.1105 -				state.dma_reading = (value & 0x4000);
  1.1106 -				state.leds = (~value & 0xF00) >> 8;
  1.1107 -				printf("LEDs: %s %s %s %s\n",
  1.1108 -						(state.leds & 8) ? "R" : "-",
  1.1109 -						(state.leds & 4) ? "G" : "-",
  1.1110 -						(state.leds & 2) ? "Y" : "-",
  1.1111 -						(state.leds & 1) ? "R" : "-");
  1.1112 -				handled = true;
  1.1113 -				break;
  1.1114 -			case 0x0B0000:				// TM/DIALWR
  1.1115 -				break;
  1.1116 -			case 0x0C0000:				// Clear Status Register
  1.1117 -				state.genstat = 0xFFFF;
  1.1118 -				state.bsr0 = 0xFFFF;
  1.1119 -				state.bsr1 = 0xFFFF;
  1.1120 -				handled = true;
  1.1121 -				break;
  1.1122 -			case 0x0D0000:				// DMA Address Register
  1.1123 -				if (address & 0x004000) {
  1.1124 -					// A14 high -- set most significant bits
  1.1125 -					state.dma_address = (state.dma_address & 0x1fe) | ((address & 0x3ffe) << 8);
  1.1126 -				} else {
  1.1127 -					// A14 low -- set least significant bits
  1.1128 -					state.dma_address = (state.dma_address & 0x3ffe00) | (address & 0x1fe);
  1.1129 -				}
  1.1130 -				printf("WR16 DMA_ADDR %s, now %08X\n", address & 0x004000 ? "HI" : "LO", state.dma_address);
  1.1131 -				handled = true;
  1.1132 -				break;
  1.1133 -			case 0x0E0000:				// Disk Control Register
  1.1134 -				// B7 = FDD controller reset
  1.1135 -				if ((value & 0x80) == 0) wd2797_reset(&state.fdc_ctx);
  1.1136 -				// B6 = drive 0 select -- TODO
  1.1137 -				// B5 = motor enable -- TODO
  1.1138 -				// B4 = HDD controller reset -- TODO
  1.1139 -				// B3 = HDD0 select -- TODO
  1.1140 -				// B2,1,0 = HDD0 head select
  1.1141 -				handled = true;
  1.1142 -				break;
  1.1143 -			case 0x0F0000:				// Line Printer Data Register
  1.1144 -				break;
  1.1145 +			default:
  1.1146 +				IoWrite(address, value, 16);
  1.1147  		}
  1.1148 -	} else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) {
  1.1149 -		// I/O register space, zone B
  1.1150 -		switch (address & 0xF00000) {
  1.1151 -			case 0xC00000:				// Expansion slots
  1.1152 -			case 0xD00000:
  1.1153 -				switch (address & 0xFC0000) {
  1.1154 -					case 0xC00000:		// Expansion slot 0
  1.1155 -					case 0xC40000:		// Expansion slot 1
  1.1156 -					case 0xC80000:		// Expansion slot 2
  1.1157 -					case 0xCC0000:		// Expansion slot 3
  1.1158 -					case 0xD00000:		// Expansion slot 4
  1.1159 -					case 0xD40000:		// Expansion slot 5
  1.1160 -					case 0xD80000:		// Expansion slot 6
  1.1161 -					case 0xDC0000:		// Expansion slot 7
  1.1162 -						fprintf(stderr, "NOTE: WR16 to expansion card space, addr=0x%08X, data=0x%04X\n", address, value);
  1.1163 -						break;
  1.1164 -				}
  1.1165 -				break;
  1.1166 -			case 0xE00000:				// HDC, FDC, MCR2 and RTC data bits
  1.1167 -			case 0xF00000:
  1.1168 -				switch (address & 0x070000) {
  1.1169 -					case 0x000000:		// [ef][08]xxxx ==> WD1010 hard disc controller
  1.1170 -						break;
  1.1171 -					case 0x010000:		// [ef][19]xxxx ==> WD2797 floppy disc controller
  1.1172 -						printf("WD279X: wr16 %02X ==> %02X\n", (address >> 1) & 3, value);
  1.1173 -						wd2797_write_reg(&state.fdc_ctx, (address >> 1) & 3, value);
  1.1174 -						handled = true;
  1.1175 -						break;
  1.1176 -					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
  1.1177 -						break;
  1.1178 -					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
  1.1179 -						break;
  1.1180 -					case 0x040000:		// [ef][4c]xxxx ==> General Control Register
  1.1181 -						switch (address & 0x077000) {
  1.1182 -							case 0x040000:		// [ef][4c][08]xxx ==> EE
  1.1183 -								break;
  1.1184 -							case 0x041000:		// [ef][4c][19]xxx ==> PIE
  1.1185 -								state.pie = ((value & 0x8000) == 0x8000);
  1.1186 -								handled = true;
  1.1187 -								break;
  1.1188 -							case 0x042000:		// [ef][4c][2A]xxx ==> BP
  1.1189 -								break;
  1.1190 -							case 0x043000:		// [ef][4c][3B]xxx ==> ROMLMAP
  1.1191 -								state.romlmap = ((value & 0x8000) == 0x8000);
  1.1192 -								handled = true;
  1.1193 -								break;
  1.1194 -							case 0x044000:		// [ef][4c][4C]xxx ==> L1 MODEM
  1.1195 -								break;
  1.1196 -							case 0x045000:		// [ef][4c][5D]xxx ==> L2 MODEM
  1.1197 -								break;
  1.1198 -							case 0x046000:		// [ef][4c][6E]xxx ==> D/N CONNECT
  1.1199 -								break;
  1.1200 -							case 0x047000:		// [ef][4c][7F]xxx ==> Whole screen reverse video
  1.1201 -								break;
  1.1202 -						}
  1.1203 -					case 0x050000:		// [ef][5d]xxxx ==> 8274
  1.1204 -						break;
  1.1205 -					case 0x060000:		// [ef][6e]xxxx ==> Control regs
  1.1206 -						switch (address & 0x07F000) {
  1.1207 -							default:
  1.1208 -								break;
  1.1209 -						}
  1.1210 -						break;
  1.1211 -					case 0x070000:		// [ef][7f]xxxx ==> 6850 Keyboard Controller
  1.1212 -						break;
  1.1213 -				}
  1.1214 -		}
  1.1215 +	} else {
  1.1216 +		IoWrite(address, value, 16);
  1.1217  	}
  1.1218 -
  1.1219 -	LOG_NOT_HANDLED_W(16);
  1.1220 -}
  1.1221 +}/*}}}*/
  1.1222  
  1.1223  /**
  1.1224   * @brief Write M68K memory, 8-bit
  1.1225   */
  1.1226 -void m68k_write_memory_8(uint32_t address, uint32_t value)
  1.1227 +void m68k_write_memory_8(uint32_t address, uint32_t value)/*{{{*/
  1.1228  {
  1.1229 -	bool handled = false;
  1.1230 -
  1.1231  	// If ROMLMAP is set, force system to access ROM
  1.1232  	if (!state.romlmap)
  1.1233  		address |= 0x800000;
  1.1234 @@ -1141,198 +750,27 @@
  1.1235  
  1.1236  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
  1.1237  		// ROM access (read only!)
  1.1238 -		handled = true;
  1.1239  	} else if (address <= (state.ram_size - 1)) {
  1.1240  		// RAM access
  1.1241  		WR8(state.ram, mapAddr(address, false), state.ram_size - 1, value);
  1.1242 -		handled = true;
  1.1243  	} else if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
  1.1244  		// I/O register space, zone A
  1.1245  		switch (address & 0x0F0000) {
  1.1246  			case 0x000000:				// Map RAM access
  1.1247 -				if (address > 0x4007FF) fprintf(stderr, "NOTE: WR8 to MapRAM mirror, addr=%08X, data=%02X\n", address, value);
  1.1248 +				if (address > 0x4007FF) fprintf(stderr, "NOTE: WR8 to MapRAM mirror, addr=0x%08X, data=0x%04X\n", address, value);
  1.1249  				WR8(state.map, address, 0x7FF, value);
  1.1250 -				handled = true;
  1.1251 -				break;
  1.1252 -			case 0x010000:				// General Status Register
  1.1253 -				handled = true;
  1.1254  				break;
  1.1255  			case 0x020000:				// Video RAM
  1.1256 -				if (address > 0x427FFF) fprintf(stderr, "NOTE: WR8 to VideoRAM mirror, addr=%08X, data=0x%02X\n", address, value);
  1.1257 +				if (address > 0x427FFF) fprintf(stderr, "NOTE: WR8 to VideoRAM mirror, addr=0x%08X, data=0x%04X\n", address, value);
  1.1258  				WR8(state.vram, address, 0x7FFF, value);
  1.1259 -				handled = true;
  1.1260 -				break;
  1.1261 -			case 0x030000:				// Bus Status Register 0
  1.1262 -				handled = true;
  1.1263 -				break;
  1.1264 -			case 0x040000:				// Bus Status Register 1
  1.1265 -				handled = true;
  1.1266 -				break;
  1.1267 -			case 0x050000:				// Phone status
  1.1268 -				break;
  1.1269 -			case 0x060000:				// DMA Count
  1.1270 -				// TODO: how to handle this in 8bit mode?
  1.1271 -				break;
  1.1272 -			case 0x070000:				// Line Printer Status Register
  1.1273 -				break;
  1.1274 -			case 0x080000:				// Real Time Clock
  1.1275 -				break;
  1.1276 -			case 0x090000:				// Phone registers
  1.1277 -				switch (address & 0x0FF000) {
  1.1278 -					case 0x090000:		// Handset relay
  1.1279 -					case 0x098000:
  1.1280 -						break;
  1.1281 -					case 0x091000:		// Line select 2
  1.1282 -					case 0x099000:
  1.1283 -						break;
  1.1284 -					case 0x092000:		// Hook relay 1
  1.1285 -					case 0x09A000:
  1.1286 -						break;
  1.1287 -					case 0x093000:		// Hook relay 2
  1.1288 -					case 0x09B000:
  1.1289 -						break;
  1.1290 -					case 0x094000:		// Line 1 hold
  1.1291 -					case 0x09C000:
  1.1292 -						break;
  1.1293 -					case 0x095000:		// Line 2 hold
  1.1294 -					case 0x09D000:
  1.1295 -						break;
  1.1296 -					case 0x096000:		// Line 1 A-lead
  1.1297 -					case 0x09E000:
  1.1298 -						break;
  1.1299 -					case 0x097000:		// Line 2 A-lead
  1.1300 -					case 0x09F000:
  1.1301 -						break;
  1.1302 -				}
  1.1303 -				break;
  1.1304 -			case 0x0A0000:				// Miscellaneous Control Register
  1.1305 -				// TODO: how to handle this in 8bit mode?
  1.1306 -/*
  1.1307 -				// TODO: handle the ctrl bits properly
  1.1308 -				if ((address & 1) == 0) {
  1.1309 -					// low byte
  1.1310 -				} else {
  1.1311 -					// hight byte
  1.1312 -					// TODO: &0x8000 --> dismiss 60hz intr
  1.1313 -					state.dma_reading = (value & 0x40);
  1.1314 -					state.leds = (~value & 0xF);
  1.1315 -				}
  1.1316 -				printf("LEDs: %s %s %s %s\n",
  1.1317 -						(state.leds & 8) ? "R" : "-",
  1.1318 -						(state.leds & 4) ? "G" : "-",
  1.1319 -						(state.leds & 2) ? "Y" : "-",
  1.1320 -						(state.leds & 1) ? "R" : "-");
  1.1321 -				handled = true;
  1.1322 -*/
  1.1323 -				break;
  1.1324 -			case 0x0B0000:				// TM/DIALWR
  1.1325 -				break;
  1.1326 -			case 0x0C0000:				// Clear Status Register
  1.1327 -				state.genstat = 0xFFFF;
  1.1328 -				state.bsr0 = 0xFFFF;
  1.1329 -				state.bsr1 = 0xFFFF;
  1.1330 -				handled = true;
  1.1331 -				break;
  1.1332 -			case 0x0D0000:				// DMA Address Register
  1.1333 -				if (address & 0x004000) {
  1.1334 -					// A14 high -- set most significant bits
  1.1335 -					state.dma_address = (state.dma_address & 0x1fe) | ((address & 0x3ffe) << 8);
  1.1336 -				} else {
  1.1337 -					// A14 low -- set least significant bits
  1.1338 -					state.dma_address = (state.dma_address & 0x3ffe00) | (address & 0x1fe);
  1.1339 -				}
  1.1340 -				printf("WR08 DMA_ADDR %s, now %08X\n", address & 0x004000 ? "HI" : "LO", state.dma_address);
  1.1341 -				handled = true;
  1.1342  				break;
  1.1343 -			case 0x0E0000:				// Disk Control Register
  1.1344 -				// B7 = FDD controller reset
  1.1345 -				if ((value & 0x80) == 0) wd2797_reset(&state.fdc_ctx);
  1.1346 -				// B6 = drive 0 select -- TODO
  1.1347 -				// B5 = motor enable -- TODO
  1.1348 -				// B4 = HDD controller reset -- TODO
  1.1349 -				// B3 = HDD0 select -- TODO
  1.1350 -				// B2,1,0 = HDD0 head select
  1.1351 -				handled = true;
  1.1352 -				break;
  1.1353 -			case 0x0F0000:				// Line Printer Data Register
  1.1354 -				break;
  1.1355 +			default:
  1.1356 +				IoWrite(address, value, 8);
  1.1357  		}
  1.1358 -	} else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) {
  1.1359 -		// I/O register space, zone B
  1.1360 -		switch (address & 0xF00000) {
  1.1361 -			case 0xC00000:				// Expansion slots
  1.1362 -			case 0xD00000:
  1.1363 -				switch (address & 0xFC0000) {
  1.1364 -					case 0xC00000:		// Expansion slot 0
  1.1365 -					case 0xC40000:		// Expansion slot 1
  1.1366 -					case 0xC80000:		// Expansion slot 2
  1.1367 -					case 0xCC0000:		// Expansion slot 3
  1.1368 -					case 0xD00000:		// Expansion slot 4
  1.1369 -					case 0xD40000:		// Expansion slot 5
  1.1370 -					case 0xD80000:		// Expansion slot 6
  1.1371 -					case 0xDC0000:		// Expansion slot 7
  1.1372 -						fprintf(stderr, "NOTE: WR8 to expansion card space, addr=0x%08X, data=0x%08X\n", address, value);
  1.1373 -						break;
  1.1374 -				}
  1.1375 -				break;
  1.1376 -			case 0xE00000:				// HDC, FDC, MCR2 and RTC data bits
  1.1377 -			case 0xF00000:
  1.1378 -				switch (address & 0x070000) {
  1.1379 -					case 0x000000:		// [ef][08]xxxx ==> WD1010 hard disc controller
  1.1380 -						break;
  1.1381 -					case 0x010000:		// [ef][19]xxxx ==> WD2797 floppy disc controller
  1.1382 -						printf("WD279X: wr8 %02X ==> %02X\n", (address >> 1) & 3, value);
  1.1383 -						wd2797_write_reg(&state.fdc_ctx, (address >> 1) & 3, value);
  1.1384 -						handled = true;
  1.1385 -						break;
  1.1386 -					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
  1.1387 -						break;
  1.1388 -					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
  1.1389 -						break;
  1.1390 -					case 0x040000:		// [ef][4c]xxxx ==> General Control Register
  1.1391 -						switch (address & 0x077000) {
  1.1392 -							case 0x040000:		// [ef][4c][08]xxx ==> EE
  1.1393 -								break;
  1.1394 -							case 0x041000:		// [ef][4c][19]xxx ==> PIE
  1.1395 -								if ((address & 1) == 0)
  1.1396 -									state.pie = ((value & 0x80) == 0x80);
  1.1397 -								handled = true;
  1.1398 -								break;
  1.1399 -							case 0x042000:		// [ef][4c][2A]xxx ==> BP
  1.1400 -								break;
  1.1401 -							case 0x043000:		// [ef][4c][3B]xxx ==> ROMLMAP
  1.1402 -								if ((address & 1) == 0)
  1.1403 -									state.romlmap = ((value & 0x80) == 0x80);
  1.1404 -								handled = true;
  1.1405 -								break;
  1.1406 -							case 0x044000:		// [ef][4c][4C]xxx ==> L1 MODEM
  1.1407 -								break;
  1.1408 -							case 0x045000:		// [ef][4c][5D]xxx ==> L2 MODEM
  1.1409 -								break;
  1.1410 -							case 0x046000:		// [ef][4c][6E]xxx ==> D/N CONNECT
  1.1411 -								break;
  1.1412 -							case 0x047000:		// [ef][4c][7F]xxx ==> Whole screen reverse video
  1.1413 -								break;
  1.1414 -						}
  1.1415 -					case 0x050000:		// [ef][5d]xxxx ==> 8274
  1.1416 -						break;
  1.1417 -					case 0x060000:		// [ef][6e]xxxx ==> Control regs
  1.1418 -						switch (address & 0x07F000) {
  1.1419 -							default:
  1.1420 -								break;
  1.1421 -						}
  1.1422 -						break;
  1.1423 -					case 0x070000:		// [ef][7f]xxxx ==> 6850 Keyboard Controller
  1.1424 -						break;
  1.1425 -					default:
  1.1426 -						fprintf(stderr, "NOTE: WR8 to undefined E/F-block space, addr=0x%08X, data=0x%08X\n", address, value);
  1.1427 -						break;
  1.1428 -				}
  1.1429 -		}
  1.1430 +	} else {
  1.1431 +		IoWrite(address, value, 8);
  1.1432  	}
  1.1433 -
  1.1434 -	LOG_NOT_HANDLED_W(8);
  1.1435 -}
  1.1436 +}/*}}}*/
  1.1437  
  1.1438  
  1.1439  // for the disassembler
  1.1440 @@ -1340,4 +778,3 @@
  1.1441  uint32_t m68k_read_disassembler_16(uint32_t addr) { return m68k_read_memory_16(addr); }
  1.1442  uint32_t m68k_read_disassembler_8 (uint32_t addr) { return m68k_read_memory_8 (addr); }
  1.1443  
  1.1444 -