src/memory.c

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