1.1 diff -r cab49f90c3b9 -r 239bc48590ba src/main.c 1.2 --- a/src/main.c Thu Dec 02 22:40:13 2010 +0000 1.3 +++ b/src/main.c Thu Dec 02 23:03:13 2010 +0000 1.4 @@ -10,6 +10,7 @@ 1.5 #include "musashi/m68k.h" 1.6 #include "version.h" 1.7 #include "state.h" 1.8 +#include "memory.h" 1.9 1.10 void FAIL(char *err) 1.11 { 1.12 @@ -18,1222 +19,6 @@ 1.13 exit(EXIT_FAILURE); 1.14 } 1.15 1.16 -/*********************************** 1.17 - * Array read/write utility macros 1.18 - * "Don't Repeat Yourself" :) 1.19 - ***********************************/ 1.20 - 1.21 -/// Array read, 32-bit 1.22 -#define RD32(array, address, andmask) \ 1.23 - (((uint32_t)array[(address + 0) & (andmask)] << 24) | \ 1.24 - ((uint32_t)array[(address + 1) & (andmask)] << 16) | \ 1.25 - ((uint32_t)array[(address + 2) & (andmask)] << 8) | \ 1.26 - ((uint32_t)array[(address + 3) & (andmask)])) 1.27 - 1.28 -/// Array read, 16-bit 1.29 -#define RD16(array, address, andmask) \ 1.30 - (((uint32_t)array[(address + 0) & (andmask)] << 8) | \ 1.31 - ((uint32_t)array[(address + 1) & (andmask)])) 1.32 - 1.33 -/// Array read, 8-bit 1.34 -#define RD8(array, address, andmask) \ 1.35 - ((uint32_t)array[(address + 0) & (andmask)]) 1.36 - 1.37 -/// Array write, 32-bit 1.38 -#define WR32(array, address, andmask, value) { \ 1.39 - array[(address + 0) & (andmask)] = (value >> 24) & 0xff; \ 1.40 - array[(address + 1) & (andmask)] = (value >> 16) & 0xff; \ 1.41 - array[(address + 2) & (andmask)] = (value >> 8) & 0xff; \ 1.42 - array[(address + 3) & (andmask)] = value & 0xff; \ 1.43 -} 1.44 - 1.45 -/// Array write, 16-bit 1.46 -#define WR16(array, address, andmask, value) { \ 1.47 - array[(address + 0) & (andmask)] = (value >> 8) & 0xff; \ 1.48 - array[(address + 1) & (andmask)] = value & 0xff; \ 1.49 -} 1.50 - 1.51 -/// Array write, 8-bit 1.52 -#define WR8(array, address, andmask, value) \ 1.53 - array[(address + 0) & (andmask)] = value & 0xff; 1.54 - 1.55 -/****************** 1.56 - * Memory mapping 1.57 - ******************/ 1.58 - 1.59 -#define MAPRAM(addr) (((uint16_t)state.map[addr*2] << 8) + ((uint16_t)state.map[(addr*2)+1])) 1.60 - 1.61 -uint32_t mapAddr(uint32_t addr, bool writing) 1.62 -{ 1.63 - if (addr < 0x400000) { 1.64 - // RAM access. Check against the Map RAM 1.65 - // Start by getting the original page address 1.66 - uint16_t page = (addr >> 12) & 0x3FF; 1.67 - 1.68 - // Look it up in the map RAM and get the physical page address 1.69 - uint32_t new_page_addr = MAPRAM(page) & 0x3FF; 1.70 - 1.71 - // Update the Page Status bits 1.72 - uint8_t pagebits = (MAPRAM(page) >> 13) & 0x03; 1.73 - if (pagebits != 0) { 1.74 - if (writing) 1.75 - state.map[page*2] |= 0x60; // Page written to (dirty) 1.76 - else 1.77 - state.map[page*2] |= 0x40; // Page accessed but not written 1.78 - } 1.79 - 1.80 - // Return the address with the new physical page spliced in 1.81 - return (new_page_addr << 12) + (addr & 0xFFF); 1.82 - } else { 1.83 - // I/O, VRAM or MapRAM space; no mapping is performed or required 1.84 - // TODO: assert here? 1.85 - return addr; 1.86 - } 1.87 -} 1.88 - 1.89 -typedef enum { 1.90 - MEM_ALLOWED = 0, 1.91 - MEM_PAGEFAULT, // Page fault -- page not present 1.92 - MEM_PAGE_NO_WE, // Page not write enabled 1.93 - MEM_KERNEL, // User attempted to access kernel memory 1.94 - MEM_UIE // User Nonmemory Location Access 1.95 -} MEM_STATUS; 1.96 - 1.97 -// check memory access permissions 1.98 -MEM_STATUS checkMemoryAccess(uint32_t addr, bool writing) 1.99 -{ 1.100 - // Are we in Supervisor mode? 1.101 - if (m68k_get_reg(NULL, M68K_REG_SR) & 0x2000) 1.102 - // Yes. We can do anything we like. 1.103 - return MEM_ALLOWED; 1.104 - 1.105 - // If we're here, then we must be in User mode. 1.106 - // Check that the user didn't access memory outside of the RAM area 1.107 - if (addr >= 0x400000) 1.108 - return MEM_UIE; 1.109 - 1.110 - // This leaves us with Page Fault checking. Get the page bits for this page. 1.111 - uint16_t page = (addr >> 12) & 0x3FF; 1.112 - uint8_t pagebits = (MAPRAM(page) >> 13) & 0x07; 1.113 - 1.114 - // Check page is present 1.115 - if ((pagebits & 0x03) == 0) 1.116 - return MEM_PAGEFAULT; 1.117 - 1.118 - // User attempt to access the kernel 1.119 - // A19, A20, A21, A22 low (kernel access): RAM addr before paging; not in Supervisor mode 1.120 - if (((addr >> 19) & 0x0F) == 0) 1.121 - return MEM_KERNEL; 1.122 - 1.123 - // Check page is write enabled 1.124 - if ((pagebits & 0x04) == 0) 1.125 - return MEM_PAGE_NO_WE; 1.126 - 1.127 - // Page access allowed. 1.128 - return MEM_ALLOWED; 1.129 -} 1.130 - 1.131 -#undef MAPRAM 1.132 - 1.133 -/******************************************************** 1.134 - * m68k memory read/write support functions for Musashi 1.135 - ********************************************************/ 1.136 - 1.137 -/** 1.138 - * @brief Check memory access permissions for a write operation. 1.139 - * @note This used to be a single macro (merged with ACCESS_CHECK_RD), but 1.140 - * gcc throws warnings when you have a return-with-value in a void 1.141 - * function, even if the return-with-value is completely unreachable. 1.142 - * Similarly it doesn't like it if you have a return without a value 1.143 - * in a non-void function, even if it's impossible to ever reach the 1.144 - * return-with-no-value. UGH! 1.145 - */ 1.146 -#define ACCESS_CHECK_WR(address, bits) do { \ 1.147 - bool fault = false; \ 1.148 - /* MEM_STATUS st; */ \ 1.149 - switch (checkMemoryAccess(address, true)) { \ 1.150 - case MEM_ALLOWED: \ 1.151 - /* Access allowed */ \ 1.152 - break; \ 1.153 - case MEM_PAGEFAULT: \ 1.154 - /* Page fault */ \ 1.155 - state.genstat = 0x8FFF; \ 1.156 - fault = true; \ 1.157 - break; \ 1.158 - case MEM_UIE: \ 1.159 - /* User access to memory above 4MB */ \ 1.160 - state.genstat = 0x9EFF; \ 1.161 - fault = true; \ 1.162 - break; \ 1.163 - case MEM_KERNEL: \ 1.164 - case MEM_PAGE_NO_WE: \ 1.165 - /* kernel access or page not write enabled */ \ 1.166 - /* TODO: which regs need setting? */ \ 1.167 - fault = true; \ 1.168 - break; \ 1.169 - } \ 1.170 - \ 1.171 - if (fault) { \ 1.172 - if (bits >= 16) \ 1.173 - state.bsr0 = 0x7F00; \ 1.174 - else \ 1.175 - state.bsr0 = (address & 1) ? 0x7D00 : 0x7E00; \ 1.176 - state.bsr0 |= (address >> 16); \ 1.177 - state.bsr1 = address & 0xffff; \ 1.178 - printf("ERR: BusError WR\n"); \ 1.179 - m68k_pulse_bus_error(); \ 1.180 - return; \ 1.181 - } \ 1.182 - } while (false) 1.183 - 1.184 -/** 1.185 - * @brief Check memory access permissions for a read operation. 1.186 - * @note This used to be a single macro (merged with ACCESS_CHECK_WR), but 1.187 - * gcc throws warnings when you have a return-with-value in a void 1.188 - * function, even if the return-with-value is completely unreachable. 1.189 - * Similarly it doesn't like it if you have a return without a value 1.190 - * in a non-void function, even if it's impossible to ever reach the 1.191 - * return-with-no-value. UGH! 1.192 - */ 1.193 -#define ACCESS_CHECK_RD(address, bits) do { \ 1.194 - bool fault = false; \ 1.195 - /* MEM_STATUS st; */ \ 1.196 - switch (checkMemoryAccess(address, false)) { \ 1.197 - case MEM_ALLOWED: \ 1.198 - /* Access allowed */ \ 1.199 - break; \ 1.200 - case MEM_PAGEFAULT: \ 1.201 - /* Page fault */ \ 1.202 - state.genstat = 0x8FFF; \ 1.203 - fault = true; \ 1.204 - break; \ 1.205 - case MEM_UIE: \ 1.206 - /* User access to memory above 4MB */ \ 1.207 - state.genstat = 0x9EFF; \ 1.208 - fault = true; \ 1.209 - break; \ 1.210 - case MEM_KERNEL: \ 1.211 - case MEM_PAGE_NO_WE: \ 1.212 - /* kernel access or page not write enabled */ \ 1.213 - /* TODO: which regs need setting? */ \ 1.214 - fault = true; \ 1.215 - break; \ 1.216 - } \ 1.217 - \ 1.218 - if (fault) { \ 1.219 - if (bits >= 16) \ 1.220 - state.bsr0 = 0x7F00; \ 1.221 - else \ 1.222 - state.bsr0 = (address & 1) ? 0x7D00 : 0x7E00; \ 1.223 - state.bsr0 |= (address >> 16); \ 1.224 - state.bsr1 = address & 0xffff; \ 1.225 - printf("ERR: BusError RD\n"); \ 1.226 - m68k_pulse_bus_error(); \ 1.227 - return 0xFFFFFFFF; \ 1.228 - } \ 1.229 - } while (false) 1.230 - 1.231 -// Logging macros 1.232 -#define LOG_NOT_HANDLED_R(bits) \ 1.233 - do { \ 1.234 - if (!handled) \ 1.235 - printf("unhandled read%02d, addr=0x%08X\n", bits, address); \ 1.236 - } while (0); 1.237 - 1.238 -#define LOG_NOT_HANDLED_W(bits) \ 1.239 - do { \ 1.240 - if (!handled) \ 1.241 - printf("unhandled write%02d, addr=0x%08X, data=0x%08X\n", bits, address, value); \ 1.242 - } while (0); 1.243 - 1.244 -/** 1.245 - * @brief Read M68K memory, 32-bit 1.246 - */ 1.247 -uint32_t m68k_read_memory_32(uint32_t address) 1.248 -{ 1.249 - uint32_t data = 0xFFFFFFFF; 1.250 - bool handled = false; 1.251 - 1.252 - // If ROMLMAP is set, force system to access ROM 1.253 - if (!state.romlmap) 1.254 - address |= 0x800000; 1.255 - 1.256 - // Check access permissions 1.257 - ACCESS_CHECK_RD(address, 32); 1.258 - 1.259 - if ((address >= 0x800000) && (address <= 0xBFFFFF)) { 1.260 - // ROM access 1.261 - data = RD32(state.rom, address, ROM_SIZE - 1); 1.262 - handled = true; 1.263 - } else if (address <= (state.ram_size - 1)) { 1.264 - // RAM access 1.265 - data = RD32(state.ram, mapAddr(address, false), state.ram_size - 1); 1.266 - handled = true; 1.267 - } else if ((address >= 0x400000) && (address <= 0x7FFFFF)) { 1.268 - // I/O register space, zone A 1.269 - switch (address & 0x0F0000) { 1.270 - case 0x000000: // Map RAM access 1.271 - if (address > 0x4007FF) fprintf(stderr, "NOTE: RD32 from MapRAM mirror, addr=0x%08X\n", address); 1.272 - data = RD32(state.map, address, 0x7FF); 1.273 - handled = true; 1.274 - break; 1.275 - case 0x010000: // General Status Register 1.276 - data = ((uint32_t)state.genstat << 16) + (uint32_t)state.genstat; 1.277 - handled = true; 1.278 - break; 1.279 - case 0x020000: // Video RAM 1.280 - if (address > 0x427FFF) fprintf(stderr, "NOTE: RD32 from VideoRAM mirror, addr=0x%08X\n", address); 1.281 - data = RD32(state.vram, address, 0x7FFF); 1.282 - handled = true; 1.283 - break; 1.284 - case 0x030000: // Bus Status Register 0 1.285 - data = ((uint32_t)state.bsr0 << 16) + (uint32_t)state.bsr0; 1.286 - handled = true; 1.287 - break; 1.288 - case 0x040000: // Bus Status Register 1 1.289 - data = ((uint32_t)state.bsr1 << 16) + (uint32_t)state.bsr1; 1.290 - handled = true; 1.291 - break; 1.292 - case 0x050000: // Phone status 1.293 - break; 1.294 - case 0x060000: // DMA Count 1.295 - break; 1.296 - case 0x070000: // Line Printer Status Register 1.297 - break; 1.298 - case 0x080000: // Real Time Clock 1.299 - break; 1.300 - case 0x090000: // Phone registers 1.301 - switch (address & 0x0FF000) { 1.302 - case 0x090000: // Handset relay 1.303 - case 0x098000: 1.304 - break; 1.305 - case 0x091000: // Line select 2 1.306 - case 0x099000: 1.307 - break; 1.308 - case 0x092000: // Hook relay 1 1.309 - case 0x09A000: 1.310 - break; 1.311 - case 0x093000: // Hook relay 2 1.312 - case 0x09B000: 1.313 - break; 1.314 - case 0x094000: // Line 1 hold 1.315 - case 0x09C000: 1.316 - break; 1.317 - case 0x095000: // Line 2 hold 1.318 - case 0x09D000: 1.319 - break; 1.320 - case 0x096000: // Line 1 A-lead 1.321 - case 0x09E000: 1.322 - break; 1.323 - case 0x097000: // Line 2 A-lead 1.324 - case 0x09F000: 1.325 - break; 1.326 - } 1.327 - break; 1.328 - case 0x0A0000: // Miscellaneous Control Register 1.329 - break; 1.330 - case 0x0B0000: // TM/DIALWR 1.331 - break; 1.332 - case 0x0C0000: // CSR 1.333 - break; 1.334 - case 0x0D0000: // DMA Address Register 1.335 - break; 1.336 - case 0x0E0000: // Disk Control Register 1.337 - break; 1.338 - case 0x0F0000: // Line Printer Data Register 1.339 - break; 1.340 - } 1.341 - } else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) { 1.342 - // I/O register space, zone B 1.343 - switch (address & 0xF00000) { 1.344 - case 0xC00000: // Expansion slots 1.345 - case 0xD00000: 1.346 - switch (address & 0xFC0000) { 1.347 - case 0xC00000: // Expansion slot 0 1.348 - case 0xC40000: // Expansion slot 1 1.349 - case 0xC80000: // Expansion slot 2 1.350 - case 0xCC0000: // Expansion slot 3 1.351 - case 0xD00000: // Expansion slot 4 1.352 - case 0xD40000: // Expansion slot 5 1.353 - case 0xD80000: // Expansion slot 6 1.354 - case 0xDC0000: // Expansion slot 7 1.355 - fprintf(stderr, "NOTE: RD32 from expansion card space, addr=0x%08X\n", address); 1.356 - break; 1.357 - } 1.358 - break; 1.359 - case 0xE00000: // HDC, FDC, MCR2 and RTC data bits 1.360 - case 0xF00000: 1.361 - switch (address & 0x070000) { 1.362 - case 0x000000: // [ef][08]xxxx ==> WD1010 hard disc controller 1.363 - break; 1.364 - case 0x010000: // [ef][19]xxxx ==> WD2797 floppy disc controller 1.365 - break; 1.366 - case 0x020000: // [ef][2a]xxxx ==> Miscellaneous Control Register 2 1.367 - break; 1.368 - case 0x030000: // [ef][3b]xxxx ==> Real Time Clock data bits 1.369 - break; 1.370 - case 0x040000: // [ef][4c]xxxx ==> General Control Register 1.371 - switch (address & 0x077000) { 1.372 - case 0x040000: // [ef][4c][08]xxx ==> EE 1.373 - break; 1.374 - case 0x041000: // [ef][4c][19]xxx ==> P1E 1.375 - break; 1.376 - case 0x042000: // [ef][4c][2A]xxx ==> BP 1.377 - break; 1.378 - case 0x043000: // [ef][4c][3B]xxx ==> ROMLMAP 1.379 - break; 1.380 - case 0x044000: // [ef][4c][4C]xxx ==> L1 MODEM 1.381 - break; 1.382 - case 0x045000: // [ef][4c][5D]xxx ==> L2 MODEM 1.383 - break; 1.384 - case 0x046000: // [ef][4c][6E]xxx ==> D/N CONNECT 1.385 - break; 1.386 - case 0x047000: // [ef][4c][7F]xxx ==> Whole screen reverse video 1.387 - break; 1.388 - } 1.389 - break; 1.390 - case 0x050000: // [ef][5d]xxxx ==> 8274 1.391 - break; 1.392 - case 0x060000: // [ef][6e]xxxx ==> Control regs 1.393 - switch (address & 0x07F000) { 1.394 - default: 1.395 - break; 1.396 - } 1.397 - break; 1.398 - case 0x070000: // [ef][7f]xxxx ==> 6850 Keyboard Controller 1.399 - break; 1.400 - } 1.401 - } 1.402 - } 1.403 - 1.404 - LOG_NOT_HANDLED_R(32); 1.405 - return data; 1.406 -} 1.407 - 1.408 -/** 1.409 - * @brief Read M68K memory, 16-bit 1.410 - */ 1.411 -uint32_t m68k_read_memory_16(uint32_t address) 1.412 -{ 1.413 - uint16_t data = 0xFFFF; 1.414 - bool handled = false; 1.415 - 1.416 - // If ROMLMAP is set, force system to access ROM 1.417 - if (!state.romlmap) 1.418 - address |= 0x800000; 1.419 - 1.420 - // Check access permissions 1.421 - ACCESS_CHECK_RD(address, 16); 1.422 - 1.423 - if ((address >= 0x800000) && (address <= 0xBFFFFF)) { 1.424 - // ROM access 1.425 - data = RD16(state.rom, address, ROM_SIZE - 1); 1.426 - handled = true; 1.427 - } else if (address <= (state.ram_size - 1)) { 1.428 - // RAM access 1.429 - data = RD16(state.ram, mapAddr(address, false), state.ram_size - 1); 1.430 - handled = true; 1.431 - } else if ((address >= 0x400000) && (address <= 0x7FFFFF)) { 1.432 - // I/O register space, zone A 1.433 - switch (address & 0x0F0000) { 1.434 - case 0x000000: // Map RAM access 1.435 - if (address > 0x4007FF) fprintf(stderr, "NOTE: RD16 from MapRAM mirror, addr=0x%08X\n", address); 1.436 - data = RD16(state.map, address, 0x7FF); 1.437 - handled = true; 1.438 - break; 1.439 - case 0x010000: // General Status Register 1.440 - data = state.genstat; 1.441 - handled = true; 1.442 - break; 1.443 - case 0x020000: // Video RAM 1.444 - if (address > 0x427FFF) fprintf(stderr, "NOTE: RD16 from VideoRAM mirror, addr=0x%08X\n", address); 1.445 - data = RD16(state.vram, address, 0x7FFF); 1.446 - handled = true; 1.447 - break; 1.448 - case 0x030000: // Bus Status Register 0 1.449 - data = state.bsr0; 1.450 - handled = true; 1.451 - break; 1.452 - case 0x040000: // Bus Status Register 1 1.453 - data = state.bsr1; 1.454 - handled = true; 1.455 - break; 1.456 - case 0x050000: // Phone status 1.457 - break; 1.458 - case 0x060000: // DMA Count 1.459 - break; 1.460 - case 0x070000: // Line Printer Status Register 1.461 - break; 1.462 - case 0x080000: // Real Time Clock 1.463 - break; 1.464 - case 0x090000: // Phone registers 1.465 - switch (address & 0x0FF000) { 1.466 - case 0x090000: // Handset relay 1.467 - case 0x098000: 1.468 - break; 1.469 - case 0x091000: // Line select 2 1.470 - case 0x099000: 1.471 - break; 1.472 - case 0x092000: // Hook relay 1 1.473 - case 0x09A000: 1.474 - break; 1.475 - case 0x093000: // Hook relay 2 1.476 - case 0x09B000: 1.477 - break; 1.478 - case 0x094000: // Line 1 hold 1.479 - case 0x09C000: 1.480 - break; 1.481 - case 0x095000: // Line 2 hold 1.482 - case 0x09D000: 1.483 - break; 1.484 - case 0x096000: // Line 1 A-lead 1.485 - case 0x09E000: 1.486 - break; 1.487 - case 0x097000: // Line 2 A-lead 1.488 - case 0x09F000: 1.489 - break; 1.490 - } 1.491 - break; 1.492 - case 0x0A0000: // Miscellaneous Control Register 1.493 - break; 1.494 - case 0x0B0000: // TM/DIALWR 1.495 - break; 1.496 - case 0x0C0000: // CSR 1.497 - break; 1.498 - case 0x0D0000: // DMA Address Register 1.499 - break; 1.500 - case 0x0E0000: // Disk Control Register 1.501 - break; 1.502 - case 0x0F0000: // Line Printer Data Register 1.503 - break; 1.504 - } 1.505 - } else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) { 1.506 - // I/O register space, zone B 1.507 - switch (address & 0xF00000) { 1.508 - case 0xC00000: // Expansion slots 1.509 - case 0xD00000: 1.510 - switch (address & 0xFC0000) { 1.511 - case 0xC00000: // Expansion slot 0 1.512 - case 0xC40000: // Expansion slot 1 1.513 - case 0xC80000: // Expansion slot 2 1.514 - case 0xCC0000: // Expansion slot 3 1.515 - case 0xD00000: // Expansion slot 4 1.516 - case 0xD40000: // Expansion slot 5 1.517 - case 0xD80000: // Expansion slot 6 1.518 - case 0xDC0000: // Expansion slot 7 1.519 - fprintf(stderr, "NOTE: RD16 from expansion card space, addr=0x%08X\n", address); 1.520 - break; 1.521 - } 1.522 - break; 1.523 - case 0xE00000: // HDC, FDC, MCR2 and RTC data bits 1.524 - case 0xF00000: 1.525 - switch (address & 0x070000) { 1.526 - case 0x000000: // [ef][08]xxxx ==> WD1010 hard disc controller 1.527 - break; 1.528 - case 0x010000: // [ef][19]xxxx ==> WD2797 floppy disc controller 1.529 - break; 1.530 - case 0x020000: // [ef][2a]xxxx ==> Miscellaneous Control Register 2 1.531 - break; 1.532 - case 0x030000: // [ef][3b]xxxx ==> Real Time Clock data bits 1.533 - break; 1.534 - case 0x040000: // [ef][4c]xxxx ==> General Control Register 1.535 - switch (address & 0x077000) { 1.536 - case 0x040000: // [ef][4c][08]xxx ==> EE 1.537 - break; 1.538 - case 0x041000: // [ef][4c][19]xxx ==> P1E 1.539 - break; 1.540 - case 0x042000: // [ef][4c][2A]xxx ==> BP 1.541 - break; 1.542 - case 0x043000: // [ef][4c][3B]xxx ==> ROMLMAP 1.543 - break; 1.544 - case 0x044000: // [ef][4c][4C]xxx ==> L1 MODEM 1.545 - break; 1.546 - case 0x045000: // [ef][4c][5D]xxx ==> L2 MODEM 1.547 - break; 1.548 - case 0x046000: // [ef][4c][6E]xxx ==> D/N CONNECT 1.549 - break; 1.550 - case 0x047000: // [ef][4c][7F]xxx ==> Whole screen reverse video 1.551 - break; 1.552 - } 1.553 - break; 1.554 - case 0x050000: // [ef][5d]xxxx ==> 8274 1.555 - break; 1.556 - case 0x060000: // [ef][6e]xxxx ==> Control regs 1.557 - switch (address & 0x07F000) { 1.558 - default: 1.559 - break; 1.560 - } 1.561 - break; 1.562 - case 0x070000: // [ef][7f]xxxx ==> 6850 Keyboard Controller 1.563 - break; 1.564 - } 1.565 - } 1.566 - } 1.567 - 1.568 - LOG_NOT_HANDLED_R(32); 1.569 - return data; 1.570 -} 1.571 - 1.572 -/** 1.573 - * @brief Read M68K memory, 8-bit 1.574 - */ 1.575 -uint32_t m68k_read_memory_8(uint32_t address) 1.576 -{ 1.577 - uint8_t data = 0xFF; 1.578 - bool handled = false; 1.579 - 1.580 - // If ROMLMAP is set, force system to access ROM 1.581 - if (!state.romlmap) 1.582 - address |= 0x800000; 1.583 - 1.584 - // Check access permissions 1.585 - ACCESS_CHECK_RD(address, 8); 1.586 - 1.587 - if ((address >= 0x800000) && (address <= 0xBFFFFF)) { 1.588 - // ROM access 1.589 - data = RD8(state.rom, address, ROM_SIZE - 1); 1.590 - handled = true; 1.591 - } else if (address <= (state.ram_size - 1)) { 1.592 - // RAM access 1.593 - data = RD8(state.ram, mapAddr(address, false), state.ram_size - 1); 1.594 - handled = true; 1.595 - } else if ((address >= 0x400000) && (address <= 0x7FFFFF)) { 1.596 - // I/O register space, zone A 1.597 - switch (address & 0x0F0000) { 1.598 - case 0x000000: // Map RAM access 1.599 - if (address > 0x4007FF) fprintf(stderr, "NOTE: RD8 from MapRAM mirror, addr=0x%08X\n", address); 1.600 - data = RD8(state.map, address, 0x7FF); 1.601 - handled = true; 1.602 - break; 1.603 - case 0x010000: // General Status Register 1.604 - if ((address & 1) == 0) 1.605 - data = (state.genstat >> 8) & 0xff; 1.606 - else 1.607 - data = (state.genstat) & 0xff; 1.608 - handled = true; 1.609 - break; 1.610 - case 0x020000: // Video RAM 1.611 - if (address > 0x427FFF) fprintf(stderr, "NOTE: RD8 from VideoRAM mirror, addr=0x%08X\n", address); 1.612 - data = RD8(state.vram, address, 0x7FFF); 1.613 - handled = true; 1.614 - break; 1.615 - case 0x030000: // Bus Status Register 0 1.616 - if ((address & 1) == 0) 1.617 - data = (state.bsr0 >> 8) & 0xff; 1.618 - else 1.619 - data = (state.bsr0) & 0xff; 1.620 - handled = true; 1.621 - break; 1.622 - case 0x040000: // Bus Status Register 1 1.623 - if ((address & 1) == 0) 1.624 - data = (state.bsr1 >> 8) & 0xff; 1.625 - else 1.626 - data = (state.bsr1) & 0xff; 1.627 - handled = true; 1.628 - break; 1.629 - case 0x050000: // Phone status 1.630 - break; 1.631 - case 0x060000: // DMA Count 1.632 - break; 1.633 - case 0x070000: // Line Printer Status Register 1.634 - break; 1.635 - case 0x080000: // Real Time Clock 1.636 - break; 1.637 - case 0x090000: // Phone registers 1.638 - switch (address & 0x0FF000) { 1.639 - case 0x090000: // Handset relay 1.640 - case 0x098000: 1.641 - break; 1.642 - case 0x091000: // Line select 2 1.643 - case 0x099000: 1.644 - break; 1.645 - case 0x092000: // Hook relay 1 1.646 - case 0x09A000: 1.647 - break; 1.648 - case 0x093000: // Hook relay 2 1.649 - case 0x09B000: 1.650 - break; 1.651 - case 0x094000: // Line 1 hold 1.652 - case 0x09C000: 1.653 - break; 1.654 - case 0x095000: // Line 2 hold 1.655 - case 0x09D000: 1.656 - break; 1.657 - case 0x096000: // Line 1 A-lead 1.658 - case 0x09E000: 1.659 - break; 1.660 - case 0x097000: // Line 2 A-lead 1.661 - case 0x09F000: 1.662 - break; 1.663 - } 1.664 - break; 1.665 - case 0x0A0000: // Miscellaneous Control Register 1.666 - break; 1.667 - case 0x0B0000: // TM/DIALWR 1.668 - break; 1.669 - case 0x0C0000: // CSR 1.670 - break; 1.671 - case 0x0D0000: // DMA Address Register 1.672 - break; 1.673 - case 0x0E0000: // Disk Control Register 1.674 - break; 1.675 - case 0x0F0000: // Line Printer Data Register 1.676 - break; 1.677 - } 1.678 - } else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) { 1.679 - // I/O register space, zone B 1.680 - switch (address & 0xF00000) { 1.681 - case 0xC00000: // Expansion slots 1.682 - case 0xD00000: 1.683 - switch (address & 0xFC0000) { 1.684 - case 0xC00000: // Expansion slot 0 1.685 - case 0xC40000: // Expansion slot 1 1.686 - case 0xC80000: // Expansion slot 2 1.687 - case 0xCC0000: // Expansion slot 3 1.688 - case 0xD00000: // Expansion slot 4 1.689 - case 0xD40000: // Expansion slot 5 1.690 - case 0xD80000: // Expansion slot 6 1.691 - case 0xDC0000: // Expansion slot 7 1.692 - fprintf(stderr, "NOTE: RD8 from expansion card space, addr=0x%08X\n", address); 1.693 - break; 1.694 - } 1.695 - break; 1.696 - case 0xE00000: // HDC, FDC, MCR2 and RTC data bits 1.697 - case 0xF00000: 1.698 - switch (address & 0x070000) { 1.699 - case 0x000000: // [ef][08]xxxx ==> WD1010 hard disc controller 1.700 - break; 1.701 - case 0x010000: // [ef][19]xxxx ==> WD2797 floppy disc controller 1.702 - break; 1.703 - case 0x020000: // [ef][2a]xxxx ==> Miscellaneous Control Register 2 1.704 - break; 1.705 - case 0x030000: // [ef][3b]xxxx ==> Real Time Clock data bits 1.706 - break; 1.707 - case 0x040000: // [ef][4c]xxxx ==> General Control Register 1.708 - switch (address & 0x077000) { 1.709 - case 0x040000: // [ef][4c][08]xxx ==> EE 1.710 - break; 1.711 - case 0x041000: // [ef][4c][19]xxx ==> P1E 1.712 - break; 1.713 - case 0x042000: // [ef][4c][2A]xxx ==> BP 1.714 - break; 1.715 - case 0x043000: // [ef][4c][3B]xxx ==> ROMLMAP 1.716 - break; 1.717 - case 0x044000: // [ef][4c][4C]xxx ==> L1 MODEM 1.718 - break; 1.719 - case 0x045000: // [ef][4c][5D]xxx ==> L2 MODEM 1.720 - break; 1.721 - case 0x046000: // [ef][4c][6E]xxx ==> D/N CONNECT 1.722 - break; 1.723 - case 0x047000: // [ef][4c][7F]xxx ==> Whole screen reverse video 1.724 - break; 1.725 - } 1.726 - case 0x050000: // [ef][5d]xxxx ==> 8274 1.727 - break; 1.728 - case 0x060000: // [ef][6e]xxxx ==> Control regs 1.729 - switch (address & 0x07F000) { 1.730 - default: 1.731 - break; 1.732 - } 1.733 - break; 1.734 - case 0x070000: // [ef][7f]xxxx ==> 6850 Keyboard Controller 1.735 - break; 1.736 - } 1.737 - } 1.738 - } 1.739 - 1.740 - LOG_NOT_HANDLED_R(8); 1.741 - 1.742 - return data; 1.743 -} 1.744 - 1.745 -/** 1.746 - * @brief Write M68K memory, 32-bit 1.747 - */ 1.748 -void m68k_write_memory_32(uint32_t address, uint32_t value) 1.749 -{ 1.750 - bool handled = false; 1.751 - 1.752 - // If ROMLMAP is set, force system to access ROM 1.753 - if (!state.romlmap) 1.754 - address |= 0x800000; 1.755 - 1.756 - // Check access permissions 1.757 - ACCESS_CHECK_WR(address, 32); 1.758 - 1.759 - if ((address >= 0x800000) && (address <= 0xBFFFFF)) { 1.760 - // ROM access 1.761 - handled = true; 1.762 - } else if (address <= (state.ram_size - 1)) { 1.763 - // RAM access 1.764 - WR32(state.ram, mapAddr(address, false), state.ram_size - 1, value); 1.765 - handled = true; 1.766 - } else if ((address >= 0x400000) && (address <= 0x7FFFFF)) { 1.767 - // I/O register space, zone A 1.768 - switch (address & 0x0F0000) { 1.769 - case 0x000000: // Map RAM access 1.770 - if (address > 0x4007FF) fprintf(stderr, "NOTE: WR32 to MapRAM mirror, addr=0x%08X, data=0x%08X\n", address, value); 1.771 - WR32(state.map, address, 0x7FF, value); 1.772 - handled = true; 1.773 - break; 1.774 - case 0x010000: // General Status Register 1.775 - state.genstat = (value & 0xffff); 1.776 - handled = true; 1.777 - break; 1.778 - case 0x020000: // Video RAM 1.779 - if (address > 0x427FFF) fprintf(stderr, "NOTE: WR32 to VideoRAM mirror, addr=0x%08X, data=0x%08X\n", address, value); 1.780 - WR32(state.vram, address, 0x7FFF, value); 1.781 - handled = true; 1.782 - break; 1.783 - case 0x030000: // Bus Status Register 0 1.784 - break; 1.785 - case 0x040000: // Bus Status Register 1 1.786 - break; 1.787 - case 0x050000: // Phone status 1.788 - break; 1.789 - case 0x060000: // DMA Count 1.790 - break; 1.791 - case 0x070000: // Line Printer Status Register 1.792 - break; 1.793 - case 0x080000: // Real Time Clock 1.794 - break; 1.795 - case 0x090000: // Phone registers 1.796 - switch (address & 0x0FF000) { 1.797 - case 0x090000: // Handset relay 1.798 - case 0x098000: 1.799 - break; 1.800 - case 0x091000: // Line select 2 1.801 - case 0x099000: 1.802 - break; 1.803 - case 0x092000: // Hook relay 1 1.804 - case 0x09A000: 1.805 - break; 1.806 - case 0x093000: // Hook relay 2 1.807 - case 0x09B000: 1.808 - break; 1.809 - case 0x094000: // Line 1 hold 1.810 - case 0x09C000: 1.811 - break; 1.812 - case 0x095000: // Line 2 hold 1.813 - case 0x09D000: 1.814 - break; 1.815 - case 0x096000: // Line 1 A-lead 1.816 - case 0x09E000: 1.817 - break; 1.818 - case 0x097000: // Line 2 A-lead 1.819 - case 0x09F000: 1.820 - break; 1.821 - } 1.822 - break; 1.823 - case 0x0A0000: // Miscellaneous Control Register 1.824 - break; 1.825 - case 0x0B0000: // TM/DIALWR 1.826 - break; 1.827 - case 0x0C0000: // CSR 1.828 - break; 1.829 - case 0x0D0000: // DMA Address Register 1.830 - break; 1.831 - case 0x0E0000: // Disk Control Register 1.832 - break; 1.833 - case 0x0F0000: // Line Printer Data Register 1.834 - break; 1.835 - } 1.836 - } else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) { 1.837 - // I/O register space, zone B 1.838 - switch (address & 0xF00000) { 1.839 - case 0xC00000: // Expansion slots 1.840 - case 0xD00000: 1.841 - switch (address & 0xFC0000) { 1.842 - case 0xC00000: // Expansion slot 0 1.843 - case 0xC40000: // Expansion slot 1 1.844 - case 0xC80000: // Expansion slot 2 1.845 - case 0xCC0000: // Expansion slot 3 1.846 - case 0xD00000: // Expansion slot 4 1.847 - case 0xD40000: // Expansion slot 5 1.848 - case 0xD80000: // Expansion slot 6 1.849 - case 0xDC0000: // Expansion slot 7 1.850 - fprintf(stderr, "NOTE: WR32 to expansion card space, addr=0x%08X, data=0x%08X\n", address, value); 1.851 - handled = true; 1.852 - break; 1.853 - } 1.854 - break; 1.855 - case 0xE00000: // HDC, FDC, MCR2 and RTC data bits 1.856 - case 0xF00000: 1.857 - switch (address & 0x070000) { 1.858 - case 0x000000: // [ef][08]xxxx ==> WD1010 hard disc controller 1.859 - break; 1.860 - case 0x010000: // [ef][19]xxxx ==> WD2797 floppy disc controller 1.861 - break; 1.862 - case 0x020000: // [ef][2a]xxxx ==> Miscellaneous Control Register 2 1.863 - break; 1.864 - case 0x030000: // [ef][3b]xxxx ==> Real Time Clock data bits 1.865 - break; 1.866 - case 0x040000: // [ef][4c]xxxx ==> General Control Register 1.867 - switch (address & 0x077000) { 1.868 - case 0x040000: // [ef][4c][08]xxx ==> EE 1.869 - break; 1.870 - case 0x041000: // [ef][4c][19]xxx ==> P1E 1.871 - break; 1.872 - case 0x042000: // [ef][4c][2A]xxx ==> BP 1.873 - break; 1.874 - case 0x043000: // [ef][4c][3B]xxx ==> ROMLMAP 1.875 - state.romlmap = ((value & 0x8000) == 0x8000); 1.876 - break; 1.877 - case 0x044000: // [ef][4c][4C]xxx ==> L1 MODEM 1.878 - break; 1.879 - case 0x045000: // [ef][4c][5D]xxx ==> L2 MODEM 1.880 - break; 1.881 - case 0x046000: // [ef][4c][6E]xxx ==> D/N CONNECT 1.882 - break; 1.883 - case 0x047000: // [ef][4c][7F]xxx ==> Whole screen reverse video 1.884 - break; 1.885 - } 1.886 - case 0x050000: // [ef][5d]xxxx ==> 8274 1.887 - break; 1.888 - case 0x060000: // [ef][6e]xxxx ==> Control regs 1.889 - switch (address & 0x07F000) { 1.890 - default: 1.891 - break; 1.892 - } 1.893 - break; 1.894 - case 0x070000: // [ef][7f]xxxx ==> 6850 Keyboard Controller 1.895 - break; 1.896 - } 1.897 - } 1.898 - } 1.899 - 1.900 - LOG_NOT_HANDLED_W(32); 1.901 -} 1.902 - 1.903 -/** 1.904 - * @brief Write M68K memory, 16-bit 1.905 - */ 1.906 -void m68k_write_memory_16(uint32_t address, uint32_t value) 1.907 -{ 1.908 - bool handled = false; 1.909 - 1.910 - // If ROMLMAP is set, force system to access ROM 1.911 - if (!state.romlmap) 1.912 - address |= 0x800000; 1.913 - 1.914 - // Check access permissions 1.915 - ACCESS_CHECK_WR(address, 16); 1.916 - 1.917 - if ((address >= 0x800000) && (address <= 0xBFFFFF)) { 1.918 - // ROM access 1.919 - handled = true; 1.920 - } else if (address <= (state.ram_size - 1)) { 1.921 - // RAM access 1.922 - WR16(state.ram, mapAddr(address, false), state.ram_size - 1, value); 1.923 - handled = true; 1.924 - } else if ((address >= 0x400000) && (address <= 0x7FFFFF)) { 1.925 - // I/O register space, zone A 1.926 - switch (address & 0x0F0000) { 1.927 - case 0x000000: // Map RAM access 1.928 - if (address > 0x4007FF) fprintf(stderr, "NOTE: WR16 to MapRAM mirror, addr=0x%08X, data=0x%04X\n", address, value); 1.929 - WR16(state.map, address, 0x7FF, value); 1.930 - handled = true; 1.931 - break; 1.932 - case 0x010000: // General Status Register (read only) 1.933 - handled = true; 1.934 - break; 1.935 - case 0x020000: // Video RAM 1.936 - if (address > 0x427FFF) fprintf(stderr, "NOTE: WR16 to VideoRAM mirror, addr=0x%08X, data=0x%04X\n", address, value); 1.937 - WR16(state.vram, address, 0x7FFF, value); 1.938 - handled = true; 1.939 - break; 1.940 - case 0x030000: // Bus Status Register 0 (read only) 1.941 - handled = true; 1.942 - break; 1.943 - case 0x040000: // Bus Status Register 1 (read only) 1.944 - handled = true; 1.945 - break; 1.946 - case 0x050000: // Phone status 1.947 - break; 1.948 - case 0x060000: // DMA Count 1.949 - break; 1.950 - case 0x070000: // Line Printer Status Register 1.951 - break; 1.952 - case 0x080000: // Real Time Clock 1.953 - break; 1.954 - case 0x090000: // Phone registers 1.955 - switch (address & 0x0FF000) { 1.956 - case 0x090000: // Handset relay 1.957 - case 0x098000: 1.958 - break; 1.959 - case 0x091000: // Line select 2 1.960 - case 0x099000: 1.961 - break; 1.962 - case 0x092000: // Hook relay 1 1.963 - case 0x09A000: 1.964 - break; 1.965 - case 0x093000: // Hook relay 2 1.966 - case 0x09B000: 1.967 - break; 1.968 - case 0x094000: // Line 1 hold 1.969 - case 0x09C000: 1.970 - break; 1.971 - case 0x095000: // Line 2 hold 1.972 - case 0x09D000: 1.973 - break; 1.974 - case 0x096000: // Line 1 A-lead 1.975 - case 0x09E000: 1.976 - break; 1.977 - case 0x097000: // Line 2 A-lead 1.978 - case 0x09F000: 1.979 - break; 1.980 - } 1.981 - break; 1.982 - case 0x0A0000: // Miscellaneous Control Register 1.983 - break; 1.984 - case 0x0B0000: // TM/DIALWR 1.985 - break; 1.986 - case 0x0C0000: // CSR 1.987 - break; 1.988 - case 0x0D0000: // DMA Address Register 1.989 - break; 1.990 - case 0x0E0000: // Disk Control Register 1.991 - break; 1.992 - case 0x0F0000: // Line Printer Data Register 1.993 - break; 1.994 - } 1.995 - } else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) { 1.996 - // I/O register space, zone B 1.997 - switch (address & 0xF00000) { 1.998 - case 0xC00000: // Expansion slots 1.999 - case 0xD00000: 1.1000 - switch (address & 0xFC0000) { 1.1001 - case 0xC00000: // Expansion slot 0 1.1002 - case 0xC40000: // Expansion slot 1 1.1003 - case 0xC80000: // Expansion slot 2 1.1004 - case 0xCC0000: // Expansion slot 3 1.1005 - case 0xD00000: // Expansion slot 4 1.1006 - case 0xD40000: // Expansion slot 5 1.1007 - case 0xD80000: // Expansion slot 6 1.1008 - case 0xDC0000: // Expansion slot 7 1.1009 - fprintf(stderr, "NOTE: WR16 to expansion card space, addr=0x%08X, data=0x%04X\n", address, value); 1.1010 - break; 1.1011 - } 1.1012 - break; 1.1013 - case 0xE00000: // HDC, FDC, MCR2 and RTC data bits 1.1014 - case 0xF00000: 1.1015 - switch (address & 0x070000) { 1.1016 - case 0x000000: // [ef][08]xxxx ==> WD1010 hard disc controller 1.1017 - break; 1.1018 - case 0x010000: // [ef][19]xxxx ==> WD2797 floppy disc controller 1.1019 - break; 1.1020 - case 0x020000: // [ef][2a]xxxx ==> Miscellaneous Control Register 2 1.1021 - break; 1.1022 - case 0x030000: // [ef][3b]xxxx ==> Real Time Clock data bits 1.1023 - break; 1.1024 - case 0x040000: // [ef][4c]xxxx ==> General Control Register 1.1025 - switch (address & 0x077000) { 1.1026 - case 0x040000: // [ef][4c][08]xxx ==> EE 1.1027 - break; 1.1028 - case 0x041000: // [ef][4c][19]xxx ==> P1E 1.1029 - break; 1.1030 - case 0x042000: // [ef][4c][2A]xxx ==> BP 1.1031 - break; 1.1032 - case 0x043000: // [ef][4c][3B]xxx ==> ROMLMAP 1.1033 - state.romlmap = ((value & 0x8000) == 0x8000); 1.1034 - handled = true; 1.1035 - break; 1.1036 - case 0x044000: // [ef][4c][4C]xxx ==> L1 MODEM 1.1037 - break; 1.1038 - case 0x045000: // [ef][4c][5D]xxx ==> L2 MODEM 1.1039 - break; 1.1040 - case 0x046000: // [ef][4c][6E]xxx ==> D/N CONNECT 1.1041 - break; 1.1042 - case 0x047000: // [ef][4c][7F]xxx ==> Whole screen reverse video 1.1043 - break; 1.1044 - } 1.1045 - case 0x050000: // [ef][5d]xxxx ==> 8274 1.1046 - break; 1.1047 - case 0x060000: // [ef][6e]xxxx ==> Control regs 1.1048 - switch (address & 0x07F000) { 1.1049 - default: 1.1050 - break; 1.1051 - } 1.1052 - break; 1.1053 - case 0x070000: // [ef][7f]xxxx ==> 6850 Keyboard Controller 1.1054 - break; 1.1055 - } 1.1056 - } 1.1057 - } 1.1058 - 1.1059 - LOG_NOT_HANDLED_W(16); 1.1060 -} 1.1061 - 1.1062 -/** 1.1063 - * @brief Write M68K memory, 8-bit 1.1064 - */ 1.1065 -void m68k_write_memory_8(uint32_t address, uint32_t value) 1.1066 -{ 1.1067 - bool handled = false; 1.1068 - 1.1069 - // If ROMLMAP is set, force system to access ROM 1.1070 - if (!state.romlmap) 1.1071 - address |= 0x800000; 1.1072 - 1.1073 - // Check access permissions 1.1074 - ACCESS_CHECK_WR(address, 8); 1.1075 - 1.1076 - if ((address >= 0x800000) && (address <= 0xBFFFFF)) { 1.1077 - // ROM access (read only!) 1.1078 - handled = true; 1.1079 - } else if (address <= (state.ram_size - 1)) { 1.1080 - // RAM access 1.1081 - WR8(state.ram, mapAddr(address, false), state.ram_size - 1, value); 1.1082 - handled = true; 1.1083 - } else if ((address >= 0x400000) && (address <= 0x7FFFFF)) { 1.1084 - // I/O register space, zone A 1.1085 - switch (address & 0x0F0000) { 1.1086 - case 0x000000: // Map RAM access 1.1087 - if (address > 0x4007FF) fprintf(stderr, "NOTE: WR8 to MapRAM mirror, addr=%08X, data=%02X\n", address, value); 1.1088 - WR8(state.map, address, 0x7FF, value); 1.1089 - handled = true; 1.1090 - break; 1.1091 - case 0x010000: // General Status Register 1.1092 - handled = true; 1.1093 - break; 1.1094 - case 0x020000: // Video RAM 1.1095 - if (address > 0x427FFF) fprintf(stderr, "NOTE: WR8 to VideoRAM mirror, addr=%08X\n, data=0x%02X", address, value); 1.1096 - WR8(state.vram, address, 0x7FFF, value); 1.1097 - handled = true; 1.1098 - break; 1.1099 - case 0x030000: // Bus Status Register 0 1.1100 - handled = true; 1.1101 - break; 1.1102 - case 0x040000: // Bus Status Register 1 1.1103 - handled = true; 1.1104 - break; 1.1105 - case 0x050000: // Phone status 1.1106 - break; 1.1107 - case 0x060000: // DMA Count 1.1108 - break; 1.1109 - case 0x070000: // Line Printer Status Register 1.1110 - break; 1.1111 - case 0x080000: // Real Time Clock 1.1112 - break; 1.1113 - case 0x090000: // Phone registers 1.1114 - switch (address & 0x0FF000) { 1.1115 - case 0x090000: // Handset relay 1.1116 - case 0x098000: 1.1117 - break; 1.1118 - case 0x091000: // Line select 2 1.1119 - case 0x099000: 1.1120 - break; 1.1121 - case 0x092000: // Hook relay 1 1.1122 - case 0x09A000: 1.1123 - break; 1.1124 - case 0x093000: // Hook relay 2 1.1125 - case 0x09B000: 1.1126 - break; 1.1127 - case 0x094000: // Line 1 hold 1.1128 - case 0x09C000: 1.1129 - break; 1.1130 - case 0x095000: // Line 2 hold 1.1131 - case 0x09D000: 1.1132 - break; 1.1133 - case 0x096000: // Line 1 A-lead 1.1134 - case 0x09E000: 1.1135 - break; 1.1136 - case 0x097000: // Line 2 A-lead 1.1137 - case 0x09F000: 1.1138 - break; 1.1139 - } 1.1140 - break; 1.1141 - case 0x0A0000: // Miscellaneous Control Register 1.1142 - break; 1.1143 - case 0x0B0000: // TM/DIALWR 1.1144 - break; 1.1145 - case 0x0C0000: // CSR 1.1146 - break; 1.1147 - case 0x0D0000: // DMA Address Register 1.1148 - break; 1.1149 - case 0x0E0000: // Disk Control Register 1.1150 - break; 1.1151 - case 0x0F0000: // Line Printer Data Register 1.1152 - break; 1.1153 - } 1.1154 - } else if ((address >= 0xC00000) && (address <= 0xFFFFFF)) { 1.1155 - // I/O register space, zone B 1.1156 - switch (address & 0xF00000) { 1.1157 - case 0xC00000: // Expansion slots 1.1158 - case 0xD00000: 1.1159 - switch (address & 0xFC0000) { 1.1160 - case 0xC00000: // Expansion slot 0 1.1161 - case 0xC40000: // Expansion slot 1 1.1162 - case 0xC80000: // Expansion slot 2 1.1163 - case 0xCC0000: // Expansion slot 3 1.1164 - case 0xD00000: // Expansion slot 4 1.1165 - case 0xD40000: // Expansion slot 5 1.1166 - case 0xD80000: // Expansion slot 6 1.1167 - case 0xDC0000: // Expansion slot 7 1.1168 - fprintf(stderr, "NOTE: WR8 to expansion card space, addr=0x%08X, data=0x%08X\n", address, value); 1.1169 - break; 1.1170 - } 1.1171 - break; 1.1172 - case 0xE00000: // HDC, FDC, MCR2 and RTC data bits 1.1173 - case 0xF00000: 1.1174 - switch (address & 0x070000) { 1.1175 - case 0x000000: // [ef][08]xxxx ==> WD1010 hard disc controller 1.1176 - break; 1.1177 - case 0x010000: // [ef][19]xxxx ==> WD2797 floppy disc controller 1.1178 - break; 1.1179 - case 0x020000: // [ef][2a]xxxx ==> Miscellaneous Control Register 2 1.1180 - break; 1.1181 - case 0x030000: // [ef][3b]xxxx ==> Real Time Clock data bits 1.1182 - break; 1.1183 - case 0x040000: // [ef][4c]xxxx ==> General Control Register 1.1184 - switch (address & 0x077000) { 1.1185 - case 0x040000: // [ef][4c][08]xxx ==> EE 1.1186 - break; 1.1187 - case 0x041000: // [ef][4c][19]xxx ==> P1E 1.1188 - break; 1.1189 - case 0x042000: // [ef][4c][2A]xxx ==> BP 1.1190 - break; 1.1191 - case 0x043000: // [ef][4c][3B]xxx ==> ROMLMAP 1.1192 - if ((address & 1) == 0) 1.1193 - state.romlmap = ((value & 0x80) == 0x80); 1.1194 - handled = true; 1.1195 - break; 1.1196 - case 0x044000: // [ef][4c][4C]xxx ==> L1 MODEM 1.1197 - break; 1.1198 - case 0x045000: // [ef][4c][5D]xxx ==> L2 MODEM 1.1199 - break; 1.1200 - case 0x046000: // [ef][4c][6E]xxx ==> D/N CONNECT 1.1201 - break; 1.1202 - case 0x047000: // [ef][4c][7F]xxx ==> Whole screen reverse video 1.1203 - break; 1.1204 - } 1.1205 - case 0x050000: // [ef][5d]xxxx ==> 8274 1.1206 - break; 1.1207 - case 0x060000: // [ef][6e]xxxx ==> Control regs 1.1208 - switch (address & 0x07F000) { 1.1209 - default: 1.1210 - break; 1.1211 - } 1.1212 - break; 1.1213 - case 0x070000: // [ef][7f]xxxx ==> 6850 Keyboard Controller 1.1214 - break; 1.1215 - default: 1.1216 - fprintf(stderr, "NOTE: WR8 to undefined E/F-block space, addr=0x%08X, data=0x%08X\n", address, value); 1.1217 - break; 1.1218 - } 1.1219 - } 1.1220 - } 1.1221 - 1.1222 - LOG_NOT_HANDLED_W(8); 1.1223 -} 1.1224 - 1.1225 - 1.1226 -// for the disassembler 1.1227 -uint32_t m68k_read_disassembler_32(uint32_t addr) { return m68k_read_memory_32(addr); } 1.1228 -uint32_t m68k_read_disassembler_16(uint32_t addr) { return m68k_read_memory_16(addr); } 1.1229 -uint32_t m68k_read_disassembler_8 (uint32_t addr) { return m68k_read_memory_8 (addr); } 1.1230 - 1.1231 - 1.1232 /**************************** 1.1233 * blessed be thy main()... 1.1234 ****************************/