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