rewrite memory access routines

Thu, 02 Dec 2010 19:30:46 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Thu, 02 Dec 2010 19:30:46 +0000
changeset 34
e8ebd433270a
parent 33
ae97a3146978
child 35
391318413bb2

rewrite memory access routines

src/main.c file | annotate | diff | revisions
     1.1 --- a/src/main.c	Thu Dec 02 17:12:28 2010 +0000
     1.2 +++ b/src/main.c	Thu Dec 02 19:30:46 2010 +0000
     1.3 @@ -227,15 +227,90 @@
     1.4  	} else if (address <= (state.ram_size - 1)) {
     1.5  		// RAM access
     1.6  		data = RD32(state.ram, mapAddr(address, false), state.ram_size - 1);
     1.7 -	} else if ((address >= 0x420000) && (address <= 0x427FFF)) {
     1.8 -		// VRAM access
     1.9 -		data = RD32(state.vram, address, 0x7FFF);
    1.10 -	} else if ((address >= 0x400000) && (address <= 0x4007FF)) {
    1.11 -		// Map RAM access
    1.12 -		data = RD32(state.map, address, 0x7FF);
    1.13 -	} else {
    1.14 -		// I/O register -- TODO
    1.15 +	} else if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
    1.16 +		// I/O register space, zone A
    1.17  		printf("RD32 0x%08X ==> ??? %s\n", address, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : "");
    1.18 +		switch (address & 0x0F0000) {
    1.19 +			case 0x000000:				// Map RAM access
    1.20 +				if (address > 0x4007FF) fprintf(stderr, "NOTE: RD32 from MapRAM mirror, addr=0x%08X\n", address);
    1.21 +				data = RD32(state.map, address, 0x7FF);
    1.22 +				break;
    1.23 +			case 0x010000:				// General Status Register
    1.24 +				data = ((uint32_t)state.genstat << 16) + (uint32_t)state.genstat;
    1.25 +				break;
    1.26 +			case 0x020000:				// Video RAM
    1.27 +				if (address > 0x427FFF) fprintf(stderr, "NOTE: RD32 from VideoRAM mirror, addr=0x%08X\n", address);
    1.28 +				data = RD32(state.vram, address, 0x7FFF);
    1.29 +				break;
    1.30 +			case 0x030000:				// Bus Status Register 0
    1.31 +			case 0x040000:				// Bus Status Register 1
    1.32 +			case 0x050000:				// Phone status
    1.33 +			case 0x060000:				// DMA Count
    1.34 +			case 0x070000:				// Line Printer Status Register
    1.35 +			case 0x080000:				// Real Time Clock
    1.36 +			case 0x090000:				// Phone registers
    1.37 +				switch (address & 0x0FF000) {
    1.38 +					case 0x090000:		// Handset relay
    1.39 +					case 0x098000:
    1.40 +					case 0x091000:		// Line select 2
    1.41 +					case 0x099000:
    1.42 +					case 0x092000:		// Hook relay 1
    1.43 +					case 0x09A000:
    1.44 +					case 0x093000:		// Hook relay 2
    1.45 +					case 0x09B000:
    1.46 +					case 0x094000:		// Line 1 hold
    1.47 +					case 0x09C000:
    1.48 +					case 0x095000:		// Line 2 hold
    1.49 +					case 0x09D000:
    1.50 +					case 0x096000:		// Line 1 A-lead
    1.51 +					case 0x09E000:
    1.52 +					case 0x097000:		// Line 2 A-lead
    1.53 +					case 0x09F000:
    1.54 +						break;
    1.55 +				}
    1.56 +				break;
    1.57 +			case 0x0A0000:				// Miscellaneous Control Register
    1.58 +			case 0x0B0000:				// TM/DIALWR
    1.59 +			case 0x0C0000:				// CSR
    1.60 +			case 0x0D0000:				// DMA Address Register
    1.61 +			case 0x0E0000:				// Disk Control Register
    1.62 +			case 0x0F0000:				// Line Printer Data Register
    1.63 +				break;
    1.64 +		}
    1.65 +	} else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) {
    1.66 +		// I/O register space, zone B
    1.67 +		printf("RD32 0x%08X ==> ??? %s\n", address, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : "");
    1.68 +		switch (address & 0xF00000) {
    1.69 +			case 0xC00000:				// Expansion slots
    1.70 +			case 0xD00000:
    1.71 +				switch (address & 0xFC0000) {
    1.72 +					case 0xC00000:		// Expansion slot 0
    1.73 +					case 0xC40000:		// Expansion slot 1
    1.74 +					case 0xC80000:		// Expansion slot 2
    1.75 +					case 0xCC0000:		// Expansion slot 3
    1.76 +					case 0xD00000:		// Expansion slot 4
    1.77 +					case 0xD40000:		// Expansion slot 5
    1.78 +					case 0xD80000:		// Expansion slot 6
    1.79 +					case 0xDC0000:		// Expansion slot 7
    1.80 +						fprintf(stderr, "NOTE: RD32 from expansion card space, addr=0x%08X\n", address);
    1.81 +						break;
    1.82 +				}
    1.83 +				break;
    1.84 +			case 0xE00000:				// HDC, FDC, MCR2 and RTC data bits
    1.85 +			case 0xF00000:
    1.86 +				switch (address & 0x070000) {
    1.87 +					case 0x000000:		// [ef][08]xxxx ==> WD1010 hard disc controller
    1.88 +						break;
    1.89 +					case 0x010000:		// [ef][19]xxxx ==> WD2797 floppy disc controller
    1.90 +						break;
    1.91 +					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
    1.92 +						break;
    1.93 +					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
    1.94 +						break;
    1.95 +					default:
    1.96 +						fprintf(stderr, "NOTE: RD32 from undefined E/F-block address 0x%08X", address);
    1.97 +				}
    1.98 +		}
    1.99  	}
   1.100  	return data;
   1.101  }
   1.102 @@ -260,17 +335,91 @@
   1.103  	} else if (address <= (state.ram_size - 1)) {
   1.104  		// RAM access
   1.105  		data = RD16(state.ram, mapAddr(address, false), state.ram_size - 1);
   1.106 -	} else if ((address >= 0x420000) && (address <= 0x427FFF)) {
   1.107 -		// VRAM access
   1.108 -		data = RD16(state.vram, address, 0x7FFF);
   1.109 -	} else if ((address >= 0x400000) && (address <= 0x4007FF)) {
   1.110 -		// Map RAM access
   1.111 -		data = RD16(state.map, address, 0x7FF);
   1.112 -	} else {
   1.113 -		// I/O register -- TODO
   1.114 +	} else if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
   1.115 +		// I/O register space, zone A
   1.116  		printf("RD16 0x%08X ==> ??? %s\n", address, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : "");
   1.117 +		switch (address & 0x0F0000) {
   1.118 +			case 0x000000:				// Map RAM access
   1.119 +				if (address > 0x4007FF) fprintf(stderr, "NOTE: RD16 from MapRAM mirror, addr=0x%08X\n", address);
   1.120 +				data = RD16(state.map, address, 0x7FF);
   1.121 +				break;
   1.122 +			case 0x010000:				// General Status Register
   1.123 +				data = state.genstat;
   1.124 +				break;
   1.125 +			case 0x020000:				// Video RAM
   1.126 +				if (address > 0x427FFF) fprintf(stderr, "NOTE: RD16 from VideoRAM mirror, addr=0x%08X\n", address);
   1.127 +				data = RD16(state.vram, address, 0x7FFF);
   1.128 +				break;
   1.129 +			case 0x030000:				// Bus Status Register 0
   1.130 +			case 0x040000:				// Bus Status Register 1
   1.131 +			case 0x050000:				// Phone status
   1.132 +			case 0x060000:				// DMA Count
   1.133 +			case 0x070000:				// Line Printer Status Register
   1.134 +			case 0x080000:				// Real Time Clock
   1.135 +			case 0x090000:				// Phone registers
   1.136 +				switch (address & 0x0FF000) {
   1.137 +					case 0x090000:		// Handset relay
   1.138 +					case 0x098000:
   1.139 +					case 0x091000:		// Line select 2
   1.140 +					case 0x099000:
   1.141 +					case 0x092000:		// Hook relay 1
   1.142 +					case 0x09A000:
   1.143 +					case 0x093000:		// Hook relay 2
   1.144 +					case 0x09B000:
   1.145 +					case 0x094000:		// Line 1 hold
   1.146 +					case 0x09C000:
   1.147 +					case 0x095000:		// Line 2 hold
   1.148 +					case 0x09D000:
   1.149 +					case 0x096000:		// Line 1 A-lead
   1.150 +					case 0x09E000:
   1.151 +					case 0x097000:		// Line 2 A-lead
   1.152 +					case 0x09F000:
   1.153 +						break;
   1.154 +				}
   1.155 +				break;
   1.156 +			case 0x0A0000:				// Miscellaneous Control Register
   1.157 +			case 0x0B0000:				// TM/DIALWR
   1.158 +			case 0x0C0000:				// CSR
   1.159 +			case 0x0D0000:				// DMA Address Register
   1.160 +			case 0x0E0000:				// Disk Control Register
   1.161 +			case 0x0F0000:				// Line Printer Data Register
   1.162 +				break;
   1.163 +		}
   1.164 +	} else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) {
   1.165 +		// I/O register space, zone B
   1.166 +		printf("RD16 0x%08X ==> ??? %s\n", address, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : "");
   1.167 +		switch (address & 0xF00000) {
   1.168 +			case 0xC00000:				// Expansion slots
   1.169 +			case 0xD00000:
   1.170 +				switch (address & 0xFC0000) {
   1.171 +					case 0xC00000:		// Expansion slot 0
   1.172 +					case 0xC40000:		// Expansion slot 1
   1.173 +					case 0xC80000:		// Expansion slot 2
   1.174 +					case 0xCC0000:		// Expansion slot 3
   1.175 +					case 0xD00000:		// Expansion slot 4
   1.176 +					case 0xD40000:		// Expansion slot 5
   1.177 +					case 0xD80000:		// Expansion slot 6
   1.178 +					case 0xDC0000:		// Expansion slot 7
   1.179 +						fprintf(stderr, "NOTE: RD16 from expansion card space, addr=0x%08X\n", address);
   1.180 +						break;
   1.181 +				}
   1.182 +				break;
   1.183 +			case 0xE00000:				// HDC, FDC, MCR2 and RTC data bits
   1.184 +			case 0xF00000:
   1.185 +				switch (address & 0x070000) {
   1.186 +					case 0x000000:		// [ef][08]xxxx ==> WD1010 hard disc controller
   1.187 +						break;
   1.188 +					case 0x010000:		// [ef][19]xxxx ==> WD2797 floppy disc controller
   1.189 +						break;
   1.190 +					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
   1.191 +						break;
   1.192 +					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
   1.193 +						break;
   1.194 +					default:
   1.195 +						fprintf(stderr, "NOTE: RD16 to undefined E/F-block address 0x%08X", address);
   1.196 +				}
   1.197 +		}
   1.198  	}
   1.199 -
   1.200  	return data;
   1.201  }
   1.202  
   1.203 @@ -294,17 +443,94 @@
   1.204  	} else if (address <= (state.ram_size - 1)) {
   1.205  		// RAM access
   1.206  		data = RD8(state.ram, mapAddr(address, false), state.ram_size - 1);
   1.207 -	} else if ((address >= 0x420000) && (address <= 0x427FFF)) {
   1.208 -		// VRAM access
   1.209 -		data = RD8(state.vram, address, 0x7FFF);
   1.210 -	} else if ((address >= 0x400000) && (address <= 0x4007FF)) {
   1.211 -		// Map RAM access
   1.212 -		data = RD8(state.map, address, 0x7FF);
   1.213 -	} else {
   1.214 -		// I/O register -- TODO
   1.215 -		printf("RD08 0x%08X ==> ??? %s\n", address, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : "");
   1.216 +	} else if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
   1.217 +		// I/O register space, zone A
   1.218 +		printf("RD8 0x%08X ==> ??? %s\n", address, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : "");
   1.219 +		switch (address & 0x0F0000) {
   1.220 +			case 0x000000:				// Map RAM access
   1.221 +				if (address > 0x4007FF) fprintf(stderr, "NOTE: RD8 from MapRAM mirror, addr=0x%08X\n", address);
   1.222 +				data = RD8(state.map, address, 0x7FF);
   1.223 +				break;
   1.224 +			case 0x010000:				// General Status Register
   1.225 +				if ((address & 1) == 0)
   1.226 +					data = (state.genstat >> 8) & 0xff;
   1.227 +				else
   1.228 +					data = (state.genstat)      & 0xff;
   1.229 +				break;
   1.230 +			case 0x020000:				// Video RAM
   1.231 +				if (address > 0x427FFF) fprintf(stderr, "NOTE: RD8 from VideoRAM mirror, addr=0x%08X\n", address);
   1.232 +				data = RD8(state.vram, address, 0x7FFF);
   1.233 +				break;
   1.234 +			case 0x030000:				// Bus Status Register 0
   1.235 +			case 0x040000:				// Bus Status Register 1
   1.236 +			case 0x050000:				// Phone status
   1.237 +			case 0x060000:				// DMA Count
   1.238 +			case 0x070000:				// Line Printer Status Register
   1.239 +			case 0x080000:				// Real Time Clock
   1.240 +			case 0x090000:				// Phone registers
   1.241 +				switch (address & 0x0FF000) {
   1.242 +					case 0x090000:		// Handset relay
   1.243 +					case 0x098000:
   1.244 +					case 0x091000:		// Line select 2
   1.245 +					case 0x099000:
   1.246 +					case 0x092000:		// Hook relay 1
   1.247 +					case 0x09A000:
   1.248 +					case 0x093000:		// Hook relay 2
   1.249 +					case 0x09B000:
   1.250 +					case 0x094000:		// Line 1 hold
   1.251 +					case 0x09C000:
   1.252 +					case 0x095000:		// Line 2 hold
   1.253 +					case 0x09D000:
   1.254 +					case 0x096000:		// Line 1 A-lead
   1.255 +					case 0x09E000:
   1.256 +					case 0x097000:		// Line 2 A-lead
   1.257 +					case 0x09F000:
   1.258 +						break;
   1.259 +				}
   1.260 +				break;
   1.261 +			case 0x0A0000:				// Miscellaneous Control Register
   1.262 +			case 0x0B0000:				// TM/DIALWR
   1.263 +			case 0x0C0000:				// CSR
   1.264 +			case 0x0D0000:				// DMA Address Register
   1.265 +			case 0x0E0000:				// Disk Control Register
   1.266 +			case 0x0F0000:				// Line Printer Data Register
   1.267 +				break;
   1.268 +		}
   1.269 +	} else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) {
   1.270 +		// I/O register space, zone B
   1.271 +		printf("RD32 0x%08X ==> ??? %s\n", address, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : "");
   1.272 +		switch (address & 0xF00000) {
   1.273 +			case 0xC00000:				// Expansion slots
   1.274 +			case 0xD00000:
   1.275 +				switch (address & 0xFC0000) {
   1.276 +					case 0xC00000:		// Expansion slot 0
   1.277 +					case 0xC40000:		// Expansion slot 1
   1.278 +					case 0xC80000:		// Expansion slot 2
   1.279 +					case 0xCC0000:		// Expansion slot 3
   1.280 +					case 0xD00000:		// Expansion slot 4
   1.281 +					case 0xD40000:		// Expansion slot 5
   1.282 +					case 0xD80000:		// Expansion slot 6
   1.283 +					case 0xDC0000:		// Expansion slot 7
   1.284 +						fprintf(stderr, "NOTE: RD8 from expansion card address 0x%08X\n", address);
   1.285 +						break;
   1.286 +				}
   1.287 +				break;
   1.288 +			case 0xE00000:				// HDC, FDC, MCR2 and RTC data bits
   1.289 +			case 0xF00000:
   1.290 +				switch (address & 0x070000) {
   1.291 +					case 0x000000:		// [ef][08]xxxx ==> WD1010 hard disc controller
   1.292 +						break;
   1.293 +					case 0x010000:		// [ef][19]xxxx ==> WD2797 floppy disc controller
   1.294 +						break;
   1.295 +					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
   1.296 +						break;
   1.297 +					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
   1.298 +						break;
   1.299 +					default:
   1.300 +						fprintf(stderr, "NOTE: RD8 from undefined E/F-block address 0x%08X", address);
   1.301 +				}
   1.302 +		}
   1.303  	}
   1.304 -
   1.305  	return data;
   1.306  }
   1.307  
   1.308 @@ -322,21 +548,93 @@
   1.309  
   1.310  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.311  		// ROM access
   1.312 -		// According to HwNote15 (John B. Milton), there is no write protection
   1.313 -		// here. You can write to ROM, but nothing happens.
   1.314 +		WR32(state.rom, address, ROM_SIZE - 1, value);
   1.315  	} else if (address <= (state.ram_size - 1)) {
   1.316  		// RAM access
   1.317 -		WR32(state.ram, mapAddr(address, true), state.ram_size - 1, value);
   1.318 -	} else if ((address >= 0x420000) && (address <= 0x427FFF)) {
   1.319 -		// VRAM access
   1.320 -		WR32(state.vram, address, 0x7fff, value);
   1.321 -	} else if ((address >= 0x400000) && (address <= 0x4007FF)) {
   1.322 -		// Map RAM access
   1.323 -		WR32(state.map, address, 0x7FF, value);
   1.324 -	} else {
   1.325 -		switch (address) {
   1.326 -			case 0xE43000:	state.romlmap = ((value & 0x8000) == 0x8000); break;	// GCR3: ROMLMAP
   1.327 -			default:		printf("WR32 0x%08X ==> 0x%08X %s\n", address, value, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : ""); break;
   1.328 +		WR32(state.ram, mapAddr(address, false), state.ram_size - 1, value);
   1.329 +	} else if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
   1.330 +		// I/O register space, zone A
   1.331 +		printf("WR32 0x%08X ==> ??? %s\n", address, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : "");
   1.332 +		switch (address & 0x0F0000) {
   1.333 +			case 0x000000:				// Map RAM access
   1.334 +				if (address > 0x4007FF) fprintf(stderr, "NOTE: WR32 to MapRAM mirror, addr=0x%08X, data=0x%08X\n", address, value);
   1.335 +				WR32(state.map, address, 0x7FF, value);
   1.336 +				break;
   1.337 +			case 0x010000:				// General Status Register
   1.338 +				state.genstat = (value & 0xffff);
   1.339 +				break;
   1.340 +			case 0x020000:				// Video RAM
   1.341 +				if (address > 0x427FFF) fprintf(stderr, "NOTE: WR32 to VideoRAM mirror, addr=0x%08X, data=0x%08X\n", address, value);
   1.342 +				WR32(state.vram, address, 0x7FFF, value);
   1.343 +				break;
   1.344 +			case 0x030000:				// Bus Status Register 0
   1.345 +			case 0x040000:				// Bus Status Register 1
   1.346 +			case 0x050000:				// Phone status
   1.347 +			case 0x060000:				// DMA Count
   1.348 +			case 0x070000:				// Line Printer Status Register
   1.349 +			case 0x080000:				// Real Time Clock
   1.350 +			case 0x090000:				// Phone registers
   1.351 +				switch (address & 0x0FF000) {
   1.352 +					case 0x090000:		// Handset relay
   1.353 +					case 0x098000:
   1.354 +					case 0x091000:		// Line select 2
   1.355 +					case 0x099000:
   1.356 +					case 0x092000:		// Hook relay 1
   1.357 +					case 0x09A000:
   1.358 +					case 0x093000:		// Hook relay 2
   1.359 +					case 0x09B000:
   1.360 +					case 0x094000:		// Line 1 hold
   1.361 +					case 0x09C000:
   1.362 +					case 0x095000:		// Line 2 hold
   1.363 +					case 0x09D000:
   1.364 +					case 0x096000:		// Line 1 A-lead
   1.365 +					case 0x09E000:
   1.366 +					case 0x097000:		// Line 2 A-lead
   1.367 +					case 0x09F000:
   1.368 +						break;
   1.369 +				}
   1.370 +				break;
   1.371 +			case 0x0A0000:				// Miscellaneous Control Register
   1.372 +			case 0x0B0000:				// TM/DIALWR
   1.373 +			case 0x0C0000:				// CSR
   1.374 +			case 0x0D0000:				// DMA Address Register
   1.375 +			case 0x0E0000:				// Disk Control Register
   1.376 +			case 0x0F0000:				// Line Printer Data Register
   1.377 +				break;
   1.378 +		}
   1.379 +	} else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) {
   1.380 +		// I/O register space, zone B
   1.381 +		printf("WR32 0x%08X ==> 0x%08X %s\n", address, value, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : "");
   1.382 +		switch (address & 0xF00000) {
   1.383 +			case 0xC00000:				// Expansion slots
   1.384 +			case 0xD00000:
   1.385 +				switch (address & 0xFC0000) {
   1.386 +					case 0xC00000:		// Expansion slot 0
   1.387 +					case 0xC40000:		// Expansion slot 1
   1.388 +					case 0xC80000:		// Expansion slot 2
   1.389 +					case 0xCC0000:		// Expansion slot 3
   1.390 +					case 0xD00000:		// Expansion slot 4
   1.391 +					case 0xD40000:		// Expansion slot 5
   1.392 +					case 0xD80000:		// Expansion slot 6
   1.393 +					case 0xDC0000:		// Expansion slot 7
   1.394 +						fprintf(stderr, "NOTE: WR32 to expansion card space, addr=0x%08X, data=0x%08X\n", address, value);
   1.395 +						break;
   1.396 +				}
   1.397 +				break;
   1.398 +			case 0xE00000:				// HDC, FDC, MCR2 and RTC data bits
   1.399 +			case 0xF00000:
   1.400 +				switch (address & 0x070000) {
   1.401 +					case 0x000000:		// [ef][08]xxxx ==> WD1010 hard disc controller
   1.402 +						break;
   1.403 +					case 0x010000:		// [ef][19]xxxx ==> WD2797 floppy disc controller
   1.404 +						break;
   1.405 +					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
   1.406 +						break;
   1.407 +					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
   1.408 +						break;
   1.409 +					default:
   1.410 +						fprintf(stderr, "NOTE: WR32 to undefined E/F-block space, addr=0x%08X, data=0x%08X\n", address, value);
   1.411 +				}
   1.412  		}
   1.413  	}
   1.414  }
   1.415 @@ -355,29 +653,93 @@
   1.416  
   1.417  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.418  		// ROM access
   1.419 -		// According to HwNote15 (John B. Milton), there is no write protection
   1.420 -		// here. You can write to ROM, but nothing happens.
   1.421 +		WR16(state.rom, address, ROM_SIZE - 1, value);
   1.422  	} else if (address <= (state.ram_size - 1)) {
   1.423  		// RAM access
   1.424 -		WR16(state.ram, mapAddr(address, true), state.ram_size - 1, value);
   1.425 -	} else if ((address >= 0x420000) && (address <= 0x427FFF)) {
   1.426 -		// VRAM access
   1.427 -		WR16(state.vram, address, 0x7fff, value);
   1.428 -	} else if ((address >= 0x400000) && (address <= 0x4007FF)) {
   1.429 -		// Map RAM access
   1.430 -		WR16(state.map, address, 0x7FF, value);
   1.431 -	} else {
   1.432 -		switch (address) {
   1.433 -			case 0xE43000:	state.romlmap = ((value & 0x8000) == 0x8000); break;	// GCR3: ROMLMAP
   1.434 -			default:		printf("WR16 0x%08X ==> 0x%04X %s\n", address, value, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : ""); break;
   1.435 +		WR16(state.ram, mapAddr(address, false), state.ram_size - 1, value);
   1.436 +	} else if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
   1.437 +		// I/O register space, zone A
   1.438 +		printf("WR16 0x%08X ==> ??? %s\n", address, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : "");
   1.439 +		switch (address & 0x0F0000) {
   1.440 +			case 0x000000:				// Map RAM access
   1.441 +				if (address > 0x4007FF) fprintf(stderr, "NOTE: WR16 to MapRAM mirror, addr=0x%08X, data=0x%04X\n", address, value);
   1.442 +				WR16(state.map, address, 0x7FF, value);
   1.443 +				break;
   1.444 +			case 0x010000:				// General Status Register
   1.445 +				state.genstat = (value & 0xffff);
   1.446 +				break;
   1.447 +			case 0x020000:				// Video RAM
   1.448 +				if (address > 0x427FFF) fprintf(stderr, "NOTE: WR16 to VideoRAM mirror, addr=0x%08X, data=0x%04X\n", address, value);
   1.449 +				WR16(state.vram, address, 0x7FFF, value);
   1.450 +				break;
   1.451 +			case 0x030000:				// Bus Status Register 0
   1.452 +			case 0x040000:				// Bus Status Register 1
   1.453 +			case 0x050000:				// Phone status
   1.454 +			case 0x060000:				// DMA Count
   1.455 +			case 0x070000:				// Line Printer Status Register
   1.456 +			case 0x080000:				// Real Time Clock
   1.457 +			case 0x090000:				// Phone registers
   1.458 +				switch (address & 0x0FF000) {
   1.459 +					case 0x090000:		// Handset relay
   1.460 +					case 0x098000:
   1.461 +					case 0x091000:		// Line select 2
   1.462 +					case 0x099000:
   1.463 +					case 0x092000:		// Hook relay 1
   1.464 +					case 0x09A000:
   1.465 +					case 0x093000:		// Hook relay 2
   1.466 +					case 0x09B000:
   1.467 +					case 0x094000:		// Line 1 hold
   1.468 +					case 0x09C000:
   1.469 +					case 0x095000:		// Line 2 hold
   1.470 +					case 0x09D000:
   1.471 +					case 0x096000:		// Line 1 A-lead
   1.472 +					case 0x09E000:
   1.473 +					case 0x097000:		// Line 2 A-lead
   1.474 +					case 0x09F000:
   1.475 +						break;
   1.476 +				}
   1.477 +				break;
   1.478 +			case 0x0A0000:				// Miscellaneous Control Register
   1.479 +			case 0x0B0000:				// TM/DIALWR
   1.480 +			case 0x0C0000:				// CSR
   1.481 +			case 0x0D0000:				// DMA Address Register
   1.482 +			case 0x0E0000:				// Disk Control Register
   1.483 +			case 0x0F0000:				// Line Printer Data Register
   1.484 +				break;
   1.485  		}
   1.486 -		if (address == 0x4A0000) {
   1.487 -			printf("\tLED WRITE: %s %s %s %s\n",
   1.488 -					value & 0x800 ? "-" : "R",
   1.489 -					value & 0x400 ? "-" : "G",
   1.490 -					value & 0x200 ? "-" : "Y",
   1.491 -					value & 0x100 ? "-" : "R"
   1.492 -					);
   1.493 +	} else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) {
   1.494 +		// I/O register space, zone B
   1.495 +		printf("WR16 0x%08X ==> 0x%04X %s\n", address, value, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : "");
   1.496 +		switch (address & 0xF00000) {
   1.497 +			case 0xC00000:				// Expansion slots
   1.498 +			case 0xD00000:
   1.499 +				switch (address & 0xFC0000) {
   1.500 +					case 0xC00000:		// Expansion slot 0
   1.501 +					case 0xC40000:		// Expansion slot 1
   1.502 +					case 0xC80000:		// Expansion slot 2
   1.503 +					case 0xCC0000:		// Expansion slot 3
   1.504 +					case 0xD00000:		// Expansion slot 4
   1.505 +					case 0xD40000:		// Expansion slot 5
   1.506 +					case 0xD80000:		// Expansion slot 6
   1.507 +					case 0xDC0000:		// Expansion slot 7
   1.508 +						fprintf(stderr, "NOTE: WR16 to expansion card space, addr=0x%08X, data=0x%04X\n", address, value);
   1.509 +						break;
   1.510 +				}
   1.511 +				break;
   1.512 +			case 0xE00000:				// HDC, FDC, MCR2 and RTC data bits
   1.513 +			case 0xF00000:
   1.514 +				switch (address & 0x070000) {
   1.515 +					case 0x000000:		// [ef][08]xxxx ==> WD1010 hard disc controller
   1.516 +						break;
   1.517 +					case 0x010000:		// [ef][19]xxxx ==> WD2797 floppy disc controller
   1.518 +						break;
   1.519 +					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
   1.520 +						break;
   1.521 +					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
   1.522 +						break;
   1.523 +					default:
   1.524 +						fprintf(stderr, "NOTE: WR16 to undefined E/F-block space, addr=0x%08X, data=0x%04X\n", address, value);
   1.525 +				}
   1.526  		}
   1.527  	}
   1.528  }
   1.529 @@ -396,25 +758,98 @@
   1.530  
   1.531  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.532  		// ROM access
   1.533 -		// According to HwNote15 (John B. Milton), there is no write protection
   1.534 -		// here. You can write to ROM, but nothing happens.
   1.535 +		WR8(state.rom, address, ROM_SIZE - 1, value);
   1.536  	} else if (address <= (state.ram_size - 1)) {
   1.537  		// RAM access
   1.538 -		WR8(state.ram, mapAddr(address, true), state.ram_size - 1, value);
   1.539 -	} else if ((address >= 0x420000) && (address <= 0x427FFF)) {
   1.540 -		// VRAM access
   1.541 -		WR8(state.vram, address, 0x7fff, value);
   1.542 -	} else if ((address >= 0x400000) && (address <= 0x4007FF)) {
   1.543 -		// Map RAM access
   1.544 -		WR8(state.map, address, 0x7FF, value);
   1.545 -	} else {
   1.546 -		switch (address) {
   1.547 -			case 0xE43000:	state.romlmap = ((value & 0x80) == 0x80); break;	// GCR3: ROMLMAP
   1.548 -			default:		printf("WR08 0x%08X ==> 0x%02X %s\n", address, value, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : ""); break;
   1.549 +		WR8(state.ram, mapAddr(address, false), state.ram_size - 1, value);
   1.550 +	} else if ((address >= 0x400000) && (address <= 0x7FFFFF)) {
   1.551 +		// I/O register space, zone A
   1.552 +		printf("WR8 0x%08X ==> ??? %s\n", address, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : "");
   1.553 +		switch (address & 0x0F0000) {
   1.554 +			case 0x000000:				// Map RAM access
   1.555 +				if (address > 0x4007FF) fprintf(stderr, "NOTE: WR8 to MapRAM mirror, addr=%08X, data=%02X\n", address, value);
   1.556 +				WR8(state.map, address, 0x7FF, value);
   1.557 +				break;
   1.558 +			case 0x010000:				// General Status Register
   1.559 +				state.genstat = (value & 0xffff);
   1.560 +				break;
   1.561 +			case 0x020000:				// Video RAM
   1.562 +				if (address > 0x427FFF) fprintf(stderr, "NOTE: WR8 to VideoRAM mirror, addr=%08X\n, data=0x%02X", address, value);
   1.563 +				WR8(state.vram, address, 0x7FFF, value);
   1.564 +				break;
   1.565 +			case 0x030000:				// Bus Status Register 0
   1.566 +			case 0x040000:				// Bus Status Register 1
   1.567 +			case 0x050000:				// Phone status
   1.568 +			case 0x060000:				// DMA Count
   1.569 +			case 0x070000:				// Line Printer Status Register
   1.570 +			case 0x080000:				// Real Time Clock
   1.571 +			case 0x090000:				// Phone registers
   1.572 +				switch (address & 0x0FF000) {
   1.573 +					case 0x090000:		// Handset relay
   1.574 +					case 0x098000:
   1.575 +					case 0x091000:		// Line select 2
   1.576 +					case 0x099000:
   1.577 +					case 0x092000:		// Hook relay 1
   1.578 +					case 0x09A000:
   1.579 +					case 0x093000:		// Hook relay 2
   1.580 +					case 0x09B000:
   1.581 +					case 0x094000:		// Line 1 hold
   1.582 +					case 0x09C000:
   1.583 +					case 0x095000:		// Line 2 hold
   1.584 +					case 0x09D000:
   1.585 +					case 0x096000:		// Line 1 A-lead
   1.586 +					case 0x09E000:
   1.587 +					case 0x097000:		// Line 2 A-lead
   1.588 +					case 0x09F000:
   1.589 +						break;
   1.590 +				}
   1.591 +				break;
   1.592 +			case 0x0A0000:				// Miscellaneous Control Register
   1.593 +			case 0x0B0000:				// TM/DIALWR
   1.594 +			case 0x0C0000:				// CSR
   1.595 +			case 0x0D0000:				// DMA Address Register
   1.596 +			case 0x0E0000:				// Disk Control Register
   1.597 +			case 0x0F0000:				// Line Printer Data Register
   1.598 +				break;
   1.599 +		}
   1.600 +	} else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) {
   1.601 +		// I/O register space, zone B
   1.602 +		printf("WR8 0x%08X ==> 0x%08X %s\n", address, value, m68k_get_reg(NULL, M68K_REG_SR) & 0x2000 ? "[SV]" : "");
   1.603 +		switch (address & 0xF00000) {
   1.604 +			case 0xC00000:				// Expansion slots
   1.605 +			case 0xD00000:
   1.606 +				switch (address & 0xFC0000) {
   1.607 +					case 0xC00000:		// Expansion slot 0
   1.608 +					case 0xC40000:		// Expansion slot 1
   1.609 +					case 0xC80000:		// Expansion slot 2
   1.610 +					case 0xCC0000:		// Expansion slot 3
   1.611 +					case 0xD00000:		// Expansion slot 4
   1.612 +					case 0xD40000:		// Expansion slot 5
   1.613 +					case 0xD80000:		// Expansion slot 6
   1.614 +					case 0xDC0000:		// Expansion slot 7
   1.615 +						fprintf(stderr, "NOTE: WR8 to expansion card space, addr=0x%08X, data=0x%08X\n", address, value);
   1.616 +						break;
   1.617 +				}
   1.618 +				break;
   1.619 +			case 0xE00000:				// HDC, FDC, MCR2 and RTC data bits
   1.620 +			case 0xF00000:
   1.621 +				switch (address & 0x070000) {
   1.622 +					case 0x000000:		// [ef][08]xxxx ==> WD1010 hard disc controller
   1.623 +						break;
   1.624 +					case 0x010000:		// [ef][19]xxxx ==> WD2797 floppy disc controller
   1.625 +						break;
   1.626 +					case 0x020000:		// [ef][2a]xxxx ==> Miscellaneous Control Register 2
   1.627 +						break;
   1.628 +					case 0x030000:		// [ef][3b]xxxx ==> Real Time Clock data bits
   1.629 +						break;
   1.630 +					default:
   1.631 +						fprintf(stderr, "NOTE: WR8 to undefined E/F-block space, addr=0x%08X, data=0x%08X\n", address, value);
   1.632 +				}
   1.633  		}
   1.634  	}
   1.635  }
   1.636  
   1.637 +
   1.638  // for the disassembler
   1.639  uint32_t m68k_read_disassembler_32(uint32_t addr) { return m68k_read_memory_32(addr); }
   1.640  uint32_t m68k_read_disassembler_16(uint32_t addr) { return m68k_read_memory_16(addr); }