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