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