|
|
1.1 ! root 1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */ ! 2: ! 3: #include <stdio.h> ! 4: ! 5: #include "generator.h" ! 6: #include "cpu68k.h" ! 7: #include "mem68k.h" ! 8: #include "vdp.h" ! 9: #include "cpuz80.h" ! 10: #include "gensound.h" ! 11: #include "gensoundi.h" ! 12: #include "ui.h" ! 13: ! 14: #undef DEBUG_VDP ! 15: #undef DEBUG_BUS ! 16: #undef DEBUG_SRAM ! 17: #undef DEBUG_RAM ! 18: #undef DEBUG_BANK ! 19: ! 20: /*** forward references ***/ ! 21: ! 22: uint8 *mem68k_memptr_bad(uint32 addr); ! 23: uint8 *mem68k_memptr_rom(uint32 addr); ! 24: uint8 *mem68k_memptr_ram(uint32 addr); ! 25: ! 26: uint8 mem68k_fetch_bad_byte(uint32 addr); ! 27: uint16 mem68k_fetch_bad_word(uint32 addr); ! 28: uint32 mem68k_fetch_bad_long(uint32 addr); ! 29: uint8 mem68k_fetch_rom_byte(uint32 addr); ! 30: uint16 mem68k_fetch_rom_word(uint32 addr); ! 31: uint32 mem68k_fetch_rom_long(uint32 addr); ! 32: uint8 mem68k_fetch_sram_byte(uint32 addr); ! 33: uint16 mem68k_fetch_sram_word(uint32 addr); ! 34: uint32 mem68k_fetch_sram_long(uint32 addr); ! 35: uint8 mem68k_fetch_yam_byte(uint32 addr); ! 36: uint16 mem68k_fetch_yam_word(uint32 addr); ! 37: uint32 mem68k_fetch_yam_long(uint32 addr); ! 38: uint8 mem68k_fetch_bank_byte(uint32 addr); ! 39: uint16 mem68k_fetch_bank_word(uint32 addr); ! 40: uint32 mem68k_fetch_bank_long(uint32 addr); ! 41: uint8 mem68k_fetch_io_byte(uint32 addr); ! 42: uint16 mem68k_fetch_io_word(uint32 addr); ! 43: uint32 mem68k_fetch_io_long(uint32 addr); ! 44: uint8 mem68k_fetch_ctrl_byte(uint32 addr); ! 45: uint16 mem68k_fetch_ctrl_word(uint32 addr); ! 46: uint32 mem68k_fetch_ctrl_long(uint32 addr); ! 47: uint8 mem68k_fetch_vdp_byte(uint32 addr); ! 48: uint16 mem68k_fetch_vdp_word(uint32 addr); ! 49: uint32 mem68k_fetch_vdp_long(uint32 addr); ! 50: uint8 mem68k_fetch_ram_byte(uint32 addr); ! 51: uint16 mem68k_fetch_ram_word(uint32 addr); ! 52: uint32 mem68k_fetch_ram_long(uint32 addr); ! 53: ! 54: void mem68k_store_bad_byte(uint32 addr, uint8 data); ! 55: void mem68k_store_bad_word(uint32 addr, uint16 data); ! 56: void mem68k_store_bad_long(uint32 addr, uint32 data); ! 57: void mem68k_store_rom_byte(uint32 addr, uint8 data); ! 58: void mem68k_store_rom_word(uint32 addr, uint16 data); ! 59: void mem68k_store_rom_long(uint32 addr, uint32 data); ! 60: void mem68k_store_sram_byte(uint32 addr, uint8 data); ! 61: void mem68k_store_sram_word(uint32 addr, uint16 data); ! 62: void mem68k_store_sram_long(uint32 addr, uint32 data); ! 63: void mem68k_store_yam_byte(uint32 addr, uint8 data); ! 64: void mem68k_store_yam_word(uint32 addr, uint16 data); ! 65: void mem68k_store_yam_long(uint32 addr, uint32 data); ! 66: void mem68k_store_bank_byte(uint32 addr, uint8 data); ! 67: void mem68k_store_bank_word(uint32 addr, uint16 data); ! 68: void mem68k_store_bank_long(uint32 addr, uint32 data); ! 69: void mem68k_store_io_byte(uint32 addr, uint8 data); ! 70: void mem68k_store_io_word(uint32 addr, uint16 data); ! 71: void mem68k_store_io_long(uint32 addr, uint32 data); ! 72: void mem68k_store_ctrl_byte(uint32 addr, uint8 data); ! 73: void mem68k_store_ctrl_word(uint32 addr, uint16 data); ! 74: void mem68k_store_ctrl_long(uint32 addr, uint32 data); ! 75: void mem68k_store_vdp_byte(uint32 addr, uint8 data); ! 76: void mem68k_store_vdp_word(uint32 addr, uint16 data); ! 77: void mem68k_store_vdp_long(uint32 addr, uint32 data); ! 78: void mem68k_store_ram_byte(uint32 addr, uint8 data); ! 79: void mem68k_store_ram_word(uint32 addr, uint16 data); ! 80: void mem68k_store_ram_long(uint32 addr, uint32 data); ! 81: ! 82: unsigned int mem68k_cont1_a = 0; ! 83: unsigned int mem68k_cont1_b = 0; ! 84: unsigned int mem68k_cont1_c = 0; ! 85: unsigned int mem68k_cont1_up = 0; ! 86: unsigned int mem68k_cont1_down = 0; ! 87: unsigned int mem68k_cont1_left = 0; ! 88: unsigned int mem68k_cont1_right = 0; ! 89: unsigned int mem68k_cont1_start = 0; ! 90: ! 91: unsigned int mem68k_cont2_a = 0; ! 92: unsigned int mem68k_cont2_b = 0; ! 93: unsigned int mem68k_cont2_c = 0; ! 94: unsigned int mem68k_cont2_up = 0; ! 95: unsigned int mem68k_cont2_down = 0; ! 96: unsigned int mem68k_cont2_left = 0; ! 97: unsigned int mem68k_cont2_right = 0; ! 98: unsigned int mem68k_cont2_start = 0; ! 99: ! 100: static uint8 mem68k_cont1ctrl; ! 101: static uint8 mem68k_cont2ctrl; ! 102: static uint8 mem68k_contEctrl; ! 103: static uint8 mem68k_cont1output; ! 104: static uint8 mem68k_cont2output; ! 105: static uint8 mem68k_contEoutput; ! 106: ! 107: /*** memory map ***/ ! 108: ! 109: t_mem68k_def mem68k_def[] = { ! 110: ! 111: { 0x000, 0x400, mem68k_memptr_rom, ! 112: mem68k_fetch_rom_byte, mem68k_fetch_rom_word, mem68k_fetch_rom_long, ! 113: mem68k_store_rom_byte, mem68k_store_rom_word, mem68k_store_rom_long }, ! 114: ! 115: { 0x400, 0x1000, mem68k_memptr_bad, ! 116: mem68k_fetch_bad_byte, mem68k_fetch_bad_word, mem68k_fetch_bad_long, ! 117: mem68k_store_bad_byte, mem68k_store_bad_word, mem68k_store_bad_long }, ! 118: ! 119: { 0xA00, 0xA10, mem68k_memptr_bad, /* note overlaps blocks below */ ! 120: mem68k_fetch_sram_byte, mem68k_fetch_sram_word, mem68k_fetch_sram_long, ! 121: mem68k_store_sram_byte, mem68k_store_sram_word, mem68k_store_sram_long }, ! 122: ! 123: { 0xA04, 0xA05, mem68k_memptr_bad, ! 124: mem68k_fetch_yam_byte, mem68k_fetch_yam_word, mem68k_fetch_yam_long, ! 125: mem68k_store_yam_byte, mem68k_store_yam_word, mem68k_store_yam_long }, ! 126: ! 127: { 0xA06, 0xA07, mem68k_memptr_bad, ! 128: mem68k_fetch_bank_byte, mem68k_fetch_bank_word, mem68k_fetch_bank_long, ! 129: mem68k_store_bank_byte, mem68k_store_bank_word, mem68k_store_bank_long }, ! 130: ! 131: { 0xA0C, 0xA10, mem68k_memptr_bad, /* this is probably more yam/bank stuff */ ! 132: mem68k_fetch_bad_byte, mem68k_fetch_bad_word, mem68k_fetch_bad_long, ! 133: mem68k_store_bad_byte, mem68k_store_bad_word, mem68k_store_bad_long }, ! 134: ! 135: { 0xA10, 0xA11, mem68k_memptr_bad, ! 136: mem68k_fetch_io_byte, mem68k_fetch_io_word, mem68k_fetch_io_long, ! 137: mem68k_store_io_byte, mem68k_store_io_word, mem68k_store_io_long }, ! 138: ! 139: { 0xA11, 0xA12, mem68k_memptr_bad, ! 140: mem68k_fetch_ctrl_byte, mem68k_fetch_ctrl_word, mem68k_fetch_ctrl_long, ! 141: mem68k_store_ctrl_byte, mem68k_store_ctrl_word, mem68k_store_ctrl_long }, ! 142: ! 143: { 0xC00, 0xC01, mem68k_memptr_bad, ! 144: mem68k_fetch_vdp_byte, mem68k_fetch_vdp_word, mem68k_fetch_vdp_long, ! 145: mem68k_store_vdp_byte, mem68k_store_vdp_word, mem68k_store_vdp_long }, ! 146: ! 147: { 0xE00, 0x1000, mem68k_memptr_ram, ! 148: mem68k_fetch_ram_byte, mem68k_fetch_ram_word, mem68k_fetch_ram_long, ! 149: mem68k_store_ram_byte, mem68k_store_ram_word, mem68k_store_ram_long }, ! 150: ! 151: { 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL } ! 152: ! 153: }; ! 154: ! 155: uint8 *(*mem68k_memptr[0x1000])(uint32 addr); ! 156: uint8 (*mem68k_fetch_byte[0x1000])(uint32 addr); ! 157: uint16 (*mem68k_fetch_word[0x1000])(uint32 addr); ! 158: uint32 (*mem68k_fetch_long[0x1000])(uint32 addr); ! 159: void (*mem68k_store_byte[0x1000])(uint32 addr, uint8 data); ! 160: void (*mem68k_store_word[0x1000])(uint32 addr, uint16 data); ! 161: void (*mem68k_store_long[0x1000])(uint32 addr, uint32 data); ! 162: ! 163: /*** initialise memory tables ***/ ! 164: ! 165: int mem68k_init(void) ! 166: { ! 167: int i = 0; ! 168: int j; ! 169: ! 170: do { ! 171: for (j = mem68k_def[i].start; j < mem68k_def[i].end; j++) { ! 172: mem68k_memptr[j] = mem68k_def[i].memptr; ! 173: mem68k_fetch_byte[j] = mem68k_def[i].fetch_byte; ! 174: mem68k_fetch_word[j] = mem68k_def[i].fetch_word; ! 175: mem68k_fetch_long[j] = mem68k_def[i].fetch_long; ! 176: mem68k_store_byte[j] = mem68k_def[i].store_byte; ! 177: mem68k_store_word[j] = mem68k_def[i].store_word; ! 178: mem68k_store_long[j] = mem68k_def[i].store_long; ! 179: } ! 180: i++; ! 181: } while ((mem68k_def[i].start != 0) || (mem68k_def[i].end != 0)); ! 182: mem68k_cont1ctrl = 0; ! 183: mem68k_cont2ctrl = 0; ! 184: mem68k_contEctrl = 0; ! 185: mem68k_cont1output = 0; ! 186: mem68k_cont2output = 0; ! 187: mem68k_contEoutput = 0; ! 188: return 0; ! 189: } ! 190: ! 191: ! 192: /*** memptr routines - called for IPC generation so speed is not vital ***/ ! 193: ! 194: uint8 *mem68k_memptr_bad(uint32 addr) ! 195: { ! 196: LOG_CRITICAL(("%08X [MEM] Invalid memory access 0x%X", regs.pc, addr)); ! 197: return cpu68k_rom; ! 198: } ! 199: ! 200: uint8 *mem68k_memptr_rom(uint32 addr) ! 201: { ! 202: if (addr < cpu68k_romlen) { ! 203: return(cpu68k_rom+addr); ! 204: } ! 205: LOG_CRITICAL(("%08X [MEM] Invalid memory access to ROM 0x%X", regs.pc, ! 206: addr)); ! 207: return cpu68k_rom; ! 208: } ! 209: ! 210: uint8 *mem68k_memptr_ram(uint32 addr) ! 211: { ! 212: /* LOG_USER(("%08X [MEM] Executing code from RAM 0x%X", regs.pc, addr)); */ ! 213: addr&= 0xffff; ! 214: return(cpu68k_ram+addr); ! 215: } ! 216: ! 217: ! 218: /*** BAD fetch/store ***/ ! 219: ! 220: uint8 mem68k_fetch_bad_byte(uint32 addr) ! 221: { ! 222: LOG_CRITICAL(("%08X [MEM] Invalid memory fetch (byte) 0x%X", regs.pc, addr)); ! 223: return 0; ! 224: } ! 225: ! 226: uint16 mem68k_fetch_bad_word(uint32 addr) ! 227: { ! 228: LOG_CRITICAL(("%08X [MEM] Invalid memory fetch (word) 0x%X", regs.pc, addr)); ! 229: return 0; ! 230: } ! 231: ! 232: uint32 mem68k_fetch_bad_long(uint32 addr) ! 233: { ! 234: LOG_CRITICAL(("%08X [MEM] Invalid memory fetch (long) 0x%X", regs.pc, addr)); ! 235: return 0; ! 236: } ! 237: ! 238: void mem68k_store_bad_byte(uint32 addr, uint8 data) ! 239: { ! 240: LOG_CRITICAL(("%08X [MEM] Invalid memory store (byte) 0x%X", regs.pc, addr)); ! 241: } ! 242: ! 243: void mem68k_store_bad_word(uint32 addr, uint16 data) ! 244: { ! 245: LOG_CRITICAL(("%08X [MEM] Invalid memory store (word) 0x%X", regs.pc, addr)); ! 246: } ! 247: ! 248: void mem68k_store_bad_long(uint32 addr, uint32 data) ! 249: { ! 250: LOG_CRITICAL(("%08X [MEM] Invalid memory store (long) 0x%X", regs.pc, addr)); ! 251: } ! 252: ! 253: ! 254: /*** ROM fetch/store ***/ ! 255: ! 256: uint8 mem68k_fetch_rom_byte(uint32 addr) ! 257: { ! 258: if (addr < cpu68k_romlen) { ! 259: return (*(uint8 *)(cpu68k_rom+addr)); ! 260: } ! 261: LOG_CRITICAL(("%08X [ROM] Invalid memory fetch (byte) 0x%X", regs.pc, addr)); ! 262: return 0; ! 263: } ! 264: ! 265: uint16 mem68k_fetch_rom_word(uint32 addr) ! 266: { ! 267: #ifdef DEBUG_BUS ! 268: if (addr & 1) { ! 269: LOG_CRITICAL(("%08X [ROM] Bus error 0x%X", regs.pc, addr)); ! 270: return 0; ! 271: } ! 272: #endif ! 273: if (addr < cpu68k_romlen) { ! 274: return LOCENDIAN16(*(uint16 *)(cpu68k_rom+addr)); ! 275: } ! 276: LOG_CRITICAL(("%08X [ROM] Invalid memory fetch (word) 0x%X", regs.pc, addr)); ! 277: return 0; ! 278: } ! 279: ! 280: uint32 mem68k_fetch_rom_long(uint32 addr) ! 281: { ! 282: #ifdef DEBUG_BUS ! 283: if (addr & 1) { ! 284: LOG_CRITICAL(("%08X [ROM] Bus error 0x%X", regs.pc, addr)); ! 285: return 0; ! 286: } ! 287: #endif ! 288: if (addr < cpu68k_romlen) { ! 289: #ifdef ALIGNLONGS ! 290: return (LOCENDIAN16(*(uint16 *)(cpu68k_rom+addr))<<16) | ! 291: LOCENDIAN16(*(uint16 *)(cpu68k_rom+addr+2)); ! 292: #else ! 293: return LOCENDIAN32(*(uint32 *)(cpu68k_rom+addr)); ! 294: #endif ! 295: } ! 296: LOG_CRITICAL(("%08X [ROM] Invalid memory fetch (long) 0x%X", regs.pc, addr)); ! 297: return 0; ! 298: } ! 299: ! 300: void mem68k_store_rom_byte(uint32 addr, uint8 data) ! 301: { ! 302: LOG_CRITICAL(("%08X [ROM] Invalid memory store (byte) 0x%X", regs.pc, addr)); ! 303: } ! 304: ! 305: void mem68k_store_rom_word(uint32 addr, uint16 data) ! 306: { ! 307: LOG_CRITICAL(("%08X [ROM] Invalid memory store (word) 0x%X", regs.pc, addr)); ! 308: } ! 309: ! 310: void mem68k_store_rom_long(uint32 addr, uint32 data) ! 311: { ! 312: LOG_CRITICAL(("%08X [ROM] Invalid memory store (long) 0x%X", regs.pc, addr)); ! 313: } ! 314: ! 315: ! 316: /*** SRAM fetch/store ***/ ! 317: ! 318: uint8 mem68k_fetch_sram_byte(uint32 addr) ! 319: { ! 320: #ifdef DEBUG_SRAM ! 321: LOG_VERBOSE(("%08X [SRAM] Fetch byte from %X", regs.pc, addr)); ! 322: #endif ! 323: addr&= 0x1fff; ! 324: return (*(uint8 *)(cpuz80_ram+addr)); ! 325: } ! 326: ! 327: uint16 mem68k_fetch_sram_word(uint32 addr) ! 328: { ! 329: uint8 data; ! 330: #ifdef DEBUG_BUS ! 331: if (addr & 1) { ! 332: LOG_CRITICAL(("%08X [SRAM] Bus error 0x%X", regs.pc, addr)); ! 333: return 0; ! 334: } ! 335: #endif ! 336: #ifdef DEBUG_SRAM ! 337: LOG_VERBOSE(("%08X [SRAM] Fetch word from %X", regs.pc, addr)); ! 338: #endif ! 339: addr&= 0x1fff; ! 340: /* sram word fetches are fetched with duplicated low byte data */ ! 341: data = *(uint8 *)(cpuz80_ram+addr); ! 342: return data | (data<<8); ! 343: } ! 344: ! 345: uint32 mem68k_fetch_sram_long(uint32 addr) ! 346: { ! 347: #ifdef DEBUG_BUS ! 348: if (addr & 1) { ! 349: LOG_CRITICAL(("%08X [SRAM] Bus error 0x%X", regs.pc, addr)); ! 350: return 0; ! 351: } ! 352: #endif ! 353: #ifdef DEBUG_SRAM ! 354: LOG_VERBOSE(("%08X [SRAM] Fetch long from %X", regs.pc, addr)); ! 355: #endif ! 356: addr&= 0x1fff; ! 357: #ifdef ALIGNLONGS ! 358: return (LOCENDIAN16(*(uint16 *)(cpuz80_ram+addr))<<16) | ! 359: LOCENDIAN16(*(uint16 *)(cpuz80_ram+addr+2)); ! 360: #else ! 361: return LOCENDIAN32(*(uint32 *)(cpuz80_ram+addr)); ! 362: #endif ! 363: } ! 364: ! 365: void mem68k_store_sram_byte(uint32 addr, uint8 data) ! 366: { ! 367: #ifdef DEBUG_SRAM ! 368: LOG_VERBOSE(("%08X [SRAM] Store byte to %X", regs.pc, addr)); ! 369: #endif ! 370: addr&= 0x1fff; ! 371: *(uint8 *)(cpuz80_ram+addr) = data; ! 372: return; ! 373: } ! 374: ! 375: void mem68k_store_sram_word(uint32 addr, uint16 data) ! 376: { ! 377: #ifdef DEBUG_BUS ! 378: if (addr & 1) { ! 379: LOG_CRITICAL(("%08X [SRAM] Bus error 0x%X", regs.pc, addr)); ! 380: return; ! 381: } ! 382: #endif ! 383: #ifdef DEBUG_SRAM ! 384: LOG_VERBOSE(("%08X [SRAM] Store word to %X", regs.pc, addr)); ! 385: #endif ! 386: addr&= 0x1fff; ! 387: /* word writes are stored with low byte cleared */ ! 388: *(uint8 *)(cpuz80_ram+addr) = data >> 8; ! 389: return; ! 390: } ! 391: ! 392: void mem68k_store_sram_long(uint32 addr, uint32 data) ! 393: { ! 394: #ifdef DEBUG_BUS ! 395: if (addr & 1) { ! 396: LOG_CRITICAL(("%08X [SRAM] Bus error 0x%X", regs.pc, addr)); ! 397: return; ! 398: } ! 399: #endif ! 400: #ifdef DEBUG_SRAM ! 401: LOG_VERBOSE(("%08X [SRAM] Store byte to %X", regs.pc, addr)); ! 402: #endif ! 403: addr&= 0x1fff; ! 404: #ifdef ALIGNLONGS ! 405: *(uint16 *)(cpuz80_ram+addr) = LOCENDIAN16((uint16)(data>>16)); ! 406: *(uint16 *)(cpuz80_ram+addr+2) = LOCENDIAN16((uint16)(data)); ! 407: #else ! 408: *(uint32 *)(cpuz80_ram+addr) = LOCENDIAN32(data); ! 409: #endif ! 410: return; ! 411: } ! 412: ! 413: ! 414: /*** YAM fetch/store ***/ ! 415: ! 416: uint8 mem68k_fetch_yam_byte(uint32 addr) ! 417: { ! 418: addr-= 0xA04000; ! 419: /* LOG_USER(("%08X [YAM] fetch (byte) 0x%X", regs.pc, addr)); */ ! 420: if (addr < 4) { ! 421: return soundi_ym2612fetch(addr); ! 422: } else { ! 423: LOG_CRITICAL(("%08X [YAM] Invalid YAM fetch (byte) 0x%X", regs.pc, addr)); ! 424: return 0; ! 425: } ! 426: } ! 427: ! 428: uint16 mem68k_fetch_yam_word(uint32 addr) ! 429: { ! 430: #ifdef DEBUG_BUS ! 431: if (addr & 1) { ! 432: LOG_CRITICAL(("%08X [YAM] Bus error 0x%X", regs.pc, addr)); ! 433: return 0; ! 434: } ! 435: #endif ! 436: addr-= 0xA04000; ! 437: LOG_CRITICAL(("%08X [YAM] Invalid memory fetch (word) 0x%X", regs.pc, addr)); ! 438: return 0; ! 439: } ! 440: ! 441: uint32 mem68k_fetch_yam_long(uint32 addr) ! 442: { ! 443: #ifdef DEBUG_BUS ! 444: if (addr & 1) { ! 445: LOG_CRITICAL(("%08X [YAM] Bus error 0x%X", regs.pc, addr)); ! 446: return 0; ! 447: } ! 448: #endif ! 449: addr-= 0xA04000; ! 450: /* no longs please */ ! 451: LOG_CRITICAL(("%08X [YAM] Invalid memory fetch (long) 0x%X", regs.pc, addr)); ! 452: return 0; ! 453: } ! 454: ! 455: void mem68k_store_yam_byte(uint32 addr, uint8 data) ! 456: { ! 457: addr-= 0xA04000; ! 458: /* LOG_USER(("%08X [YAM] (68k) store (byte) 0x%X (%d)", regs.pc, addr, ! 459: data)); */ ! 460: if (addr < 4) ! 461: soundi_ym2612store(addr, data); ! 462: else ! 463: LOG_CRITICAL(("%08X [YAM] Invalid YAM store (byte) 0x%X", regs.pc, addr)); ! 464: } ! 465: ! 466: void mem68k_store_yam_word(uint32 addr, uint16 data) ! 467: { ! 468: #ifdef DEBUG_BUS ! 469: if (addr & 1) { ! 470: LOG_CRITICAL(("%08X [YAM] Bus error 0x%X", regs.pc, addr)); ! 471: return; ! 472: } ! 473: #endif ! 474: addr-= 0xA04000; ! 475: LOG_CRITICAL(("%08X [YAM] Invalid memory store (word) 0x%X", regs.pc, addr)); ! 476: } ! 477: ! 478: void mem68k_store_yam_long(uint32 addr, uint32 data) ! 479: { ! 480: #ifdef DEBUG_BUS ! 481: if (addr & 1) { ! 482: LOG_CRITICAL(("%08X [YAM] Bus error 0x%X", regs.pc, addr)); ! 483: return; ! 484: } ! 485: #endif ! 486: addr-= 0xA04000; ! 487: /* no longs please */ ! 488: LOG_CRITICAL(("%08X [YAM] Invalid memory store (long) 0x%X", regs.pc, addr)); ! 489: } ! 490: ! 491: ! 492: /*** BANK fetch/store ***/ ! 493: ! 494: uint8 mem68k_fetch_bank_byte(uint32 addr) ! 495: { ! 496: /* write only */ ! 497: LOG_CRITICAL(("%08X [BANK] Invalid memory fetch (byte) 0x%X", regs.pc, ! 498: addr)); ! 499: return 0; ! 500: } ! 501: ! 502: uint16 mem68k_fetch_bank_word(uint32 addr) ! 503: { ! 504: /* write only */ ! 505: LOG_CRITICAL(("%08X [BANK] Invalid memory fetch (word) 0x%X", regs.pc, ! 506: addr)); ! 507: return 0; ! 508: } ! 509: ! 510: uint32 mem68k_fetch_bank_long(uint32 addr) ! 511: { ! 512: /* write only */ ! 513: LOG_CRITICAL(("%08X [BANK] Invalid memory fetch (long) 0x%X", regs.pc, ! 514: addr)); ! 515: return 0; ! 516: } ! 517: ! 518: void mem68k_store_bank_byte(uint32 addr, uint8 data) ! 519: { ! 520: addr-= 0xA06000; ! 521: if (addr == 0x000) { ! 522: #ifdef DEBUG_SRAM ! 523: LOG_VERBOSE(("%08X [BANK] Store byte to %X", regs.pc, addr)); ! 524: #endif ! 525: cpuz80_bankwrite(data); ! 526: } else { ! 527: LOG_CRITICAL(("%08X [BANK] Invalid memory store (byte) 0x%X", regs.pc, ! 528: addr)); ! 529: } ! 530: } ! 531: ! 532: void mem68k_store_bank_word(uint32 addr, uint16 data) ! 533: { ! 534: addr-= 0xA06000; ! 535: if (addr == 0x000) { ! 536: #ifdef DEBUG_SRAM ! 537: LOG_VERBOSE(("%08X [BANK] Store word to %X", regs.pc, addr)); ! 538: #endif ! 539: cpuz80_bankwrite(data>>8); ! 540: } else { ! 541: LOG_CRITICAL(("%08X [BANK] Invalid memory store (word) 0x%X", regs.pc, ! 542: addr)); ! 543: } ! 544: } ! 545: ! 546: void mem68k_store_bank_long(uint32 addr, uint32 data) ! 547: { ! 548: addr-= 0xA06000; ! 549: /* no longs please */ ! 550: LOG_CRITICAL(("%08X [BANK] Invalid memory store (long) 0x%X", regs.pc, ! 551: addr)); ! 552: } ! 553: ! 554: ! 555: /*** I/O fetch/store ***/ ! 556: ! 557: uint8 mem68k_fetch_io_byte(uint32 addr) ! 558: { ! 559: uint8 in; ! 560: ! 561: addr-= 0xA10000; ! 562: if ((addr & 1) == 0) { ! 563: LOG_CRITICAL(("%08X [IO] Invalid memory fetch (byte) 0x%X", ! 564: regs.pc, addr)); ! 565: return 0; ! 566: } ! 567: switch (addr>>1) { ! 568: case 0: /* 0x1 */ ! 569: /* version */ ! 570: return (1<<5 | vdp_pal<<6 | vdp_overseas<<7); ! 571: case 1: /* 0x3 */ ! 572: /* get input state */ ! 573: in = ((mem68k_cont1output & 1<<6) ! 574: ? ((1-mem68k_cont1_up) | (1-mem68k_cont1_down)<<1 | ! 575: (1-mem68k_cont1_left)<<2 | (1-mem68k_cont1_right)<<3 | ! 576: (1-mem68k_cont1_b)<<4 | (1-mem68k_cont1_c)<<5) ! 577: : ((1-mem68k_cont1_up) | (1-mem68k_cont1_down)<<1 | ! 578: (1-mem68k_cont1_a)<<4 | (1-mem68k_cont1_start)<<5)); ! 579: return (in & ~mem68k_cont1ctrl) | (mem68k_cont1output & mem68k_cont1ctrl); ! 580: case 2: /* 0x5 */ ! 581: /* get input state */ ! 582: in = ((mem68k_cont2output & 1<<6) ! 583: ? ((1-mem68k_cont2_up) | (1-mem68k_cont2_down)<<1 | ! 584: (1-mem68k_cont2_left)<<2 | (1-mem68k_cont2_right)<<3 | ! 585: (1-mem68k_cont2_b)<<4 | (1-mem68k_cont2_c)<<5) ! 586: : ((1-mem68k_cont2_up) | (1-mem68k_cont2_down)<<1 | ! 587: (1-mem68k_cont2_a)<<4 | (1-mem68k_cont2_start)<<5)); ! 588: return (in & ~mem68k_cont2ctrl) | (mem68k_cont2output & mem68k_cont2ctrl); ! 589: case 3: /* 0x7 */ ! 590: LOG_NORMAL(("%08X [IO] EXT port read", regs.pc)); ! 591: /* get input state */ ! 592: in = 0; /* BUG: unsupported */ ! 593: return (in & ~mem68k_cont1ctrl) | (mem68k_cont1output & mem68k_cont1ctrl); ! 594: case 4: /* 0x9 */ ! 595: return mem68k_cont1ctrl; ! 596: case 5: /* 0xB */ ! 597: return mem68k_cont2ctrl; ! 598: case 6: /* 0xD */ ! 599: return mem68k_contEctrl; ! 600: default: ! 601: LOG_CRITICAL(("%08X [IO] Invalid memory fetch (byte) 0x%X", ! 602: regs.pc, addr)); ! 603: return 0; ! 604: } ! 605: } ! 606: ! 607: uint16 mem68k_fetch_io_word(uint32 addr) ! 608: { ! 609: return mem68k_fetch_io_byte(addr+1); ! 610: } ! 611: ! 612: uint32 mem68k_fetch_io_long(uint32 addr) ! 613: { ! 614: return (mem68k_fetch_io_word(addr)<<16) | mem68k_fetch_io_word(addr+2); ! 615: } ! 616: ! 617: void mem68k_store_io_byte(uint32 addr, uint8 data) ! 618: { ! 619: addr-= 0xA10000; ! 620: switch (addr) { ! 621: case 0x3: ! 622: mem68k_cont1output = data; ! 623: return; ! 624: case 0x5: ! 625: mem68k_cont2output = data; ! 626: return; ! 627: case 0x7: ! 628: mem68k_contEoutput = data; ! 629: LOG_NORMAL(("%08X [IO] EXT port output set to %X", regs.pc, data)); ! 630: return; ! 631: case 0x9: ! 632: mem68k_cont1ctrl = data; ! 633: if (data != 0x40) { ! 634: LOG_CRITICAL(("%08X [IO] Unknown controller 1 setting (0x%X)", ! 635: regs.pc, data)); ! 636: } ! 637: return; ! 638: case 0xB: ! 639: mem68k_cont2ctrl = data; ! 640: if (data != 0x40) { ! 641: LOG_CRITICAL(("%08X [IO] Unknown controller 2 setting (0x%X)", ! 642: regs.pc, data)); ! 643: } ! 644: return; ! 645: case 0xD: ! 646: mem68k_contEctrl = data; ! 647: LOG_NORMAL(("%08X [IO] EXT port ctrl set to %X", regs.pc, data)); ! 648: return; ! 649: case 0xF: ! 650: case 0x11: ! 651: case 0x13: ! 652: case 0x15: ! 653: case 0x17: ! 654: case 0x19: ! 655: case 0x1B: ! 656: case 0x1D: ! 657: case 0x1F: ! 658: /* return; */ ! 659: default: ! 660: LOG_CRITICAL(("%08X [IO] Invalid memory store (byte) 0x%X", ! 661: regs.pc, addr)); ! 662: return; ! 663: } ! 664: } ! 665: ! 666: void mem68k_store_io_word(uint32 addr, uint16 data) ! 667: { ! 668: if (data >> 8) ! 669: LOG_CRITICAL(("%08X [IO] Word store to %X of %X", addr, data)); ! 670: mem68k_store_io_byte(addr+1, data & 0xff); ! 671: } ! 672: ! 673: void mem68k_store_io_long(uint32 addr, uint32 data) ! 674: { ! 675: mem68k_store_io_word(addr, (uint16)(data>>16)); ! 676: mem68k_store_io_word(addr+2, (uint16)data); ! 677: return; ! 678: } ! 679: ! 680: ! 681: /*** CTRL fetch/store ***/ ! 682: ! 683: uint8 mem68k_fetch_ctrl_byte(uint32 addr) ! 684: { ! 685: addr-= 0xA11000; ! 686: /* 0x000 mode (write only), 0x100 z80 busreq, 0x200 z80 reset (write only) */ ! 687: if (addr == 0x100) { ! 688: return cpuz80_active ? 1 : 0; ! 689: } ! 690: LOG_CRITICAL(("%08X [CTRL] Invalid memory fetch (byte) 0x%X", ! 691: regs.pc, addr)); ! 692: return 0; ! 693: } ! 694: ! 695: uint16 mem68k_fetch_ctrl_word(uint32 addr) ! 696: { ! 697: addr-= 0xA11000; ! 698: /* 0x000 mode (write only), 0x100 z80 busreq, 0x200 z80 reset (write only) */ ! 699: if (addr == 0x100) { ! 700: return cpuz80_active ? 0x100 : 0; ! 701: } ! 702: LOG_CRITICAL(("%08X [CTRL] Invalid memory fetch (word) 0x%X", ! 703: regs.pc, addr)); ! 704: return 0; ! 705: } ! 706: ! 707: uint32 mem68k_fetch_ctrl_long(uint32 addr) ! 708: { ! 709: addr-= 0xA11000; ! 710: /* no long access allowed */ ! 711: LOG_CRITICAL(("%08X [CTRL] Invalid memory fetch (long) 0x%X", ! 712: regs.pc, addr)); ! 713: return 0; ! 714: } ! 715: ! 716: void mem68k_store_ctrl_byte(uint32 addr, uint8 data) ! 717: { ! 718: addr-= 0xA11000; ! 719: if (addr == 0x000 || addr == 0x001) { ! 720: /* z80 memory mode - not applicable for production carts */ ! 721: return; ! 722: } else if (addr == 0x100) { ! 723: /* bus request */ ! 724: if (data & 1) { ! 725: cpuz80_stop(); ! 726: LOG_DEBUG1(("%08X Z80 stopped", regs.pc)); ! 727: } else { ! 728: cpuz80_start(); ! 729: LOG_DEBUG1(("%08X Z80 started", regs.pc)); ! 730: } ! 731: } else if (addr == 0x101) { ! 732: return; /* ignore low byte */ ! 733: } else if (addr == 0x200) { ! 734: /* z80 reset request */ ! 735: if (!(data & 1)) { ! 736: /* cpuz80_stop(); */ ! 737: cpuz80_resetcpu(); ! 738: sound_genreset(); ! 739: LOG_DEBUG1(("%08X Z80 reset", regs.pc)); ! 740: } else { ! 741: cpuz80_unresetcpu(); ! 742: LOG_DEBUG1(("%08X Z80 un-reset", regs.pc)); ! 743: } ! 744: } else if (addr == 0x201) { ! 745: return; /* ignore low byte */ ! 746: } else { ! 747: LOG_CRITICAL(("%08X [CTRL] Invalid memory store (byte) 0x%X", ! 748: regs.pc, addr)); ! 749: } ! 750: } ! 751: ! 752: void mem68k_store_ctrl_word(uint32 addr, uint16 data) ! 753: { ! 754: addr-= 0xA11000; ! 755: if (addr == 0x000) { ! 756: /* z80 memory mode - not applicable for production carts */ ! 757: return; ! 758: } else if (addr == 0x100) { ! 759: /* bus request */ ! 760: if (data == 0x100) { ! 761: cpuz80_stop(); ! 762: LOG_DEBUG1(("%08X Z80 stopped", regs.pc)); ! 763: } else { ! 764: cpuz80_start(); ! 765: LOG_DEBUG1(("%08X Z80 started", regs.pc)); ! 766: } ! 767: } else if (addr == 0x200) { ! 768: /* z80 reset request */ ! 769: if (!(data & 0x100)) { ! 770: /* cpuz80_stop(); */ ! 771: cpuz80_resetcpu(); ! 772: sound_genreset(); ! 773: LOG_DEBUG1(("%08X Z80 reset", regs.pc)); ! 774: } else { ! 775: cpuz80_unresetcpu(); ! 776: LOG_DEBUG1(("%08X Z80 un-reset", regs.pc)); ! 777: } ! 778: } else { ! 779: LOG_CRITICAL(("%08X [CTRL] Invalid memory store (word) 0x%X", ! 780: regs.pc, addr)); ! 781: } ! 782: } ! 783: ! 784: void mem68k_store_ctrl_long(uint32 addr, uint32 data) ! 785: { ! 786: addr-= 0xA11000; ! 787: /* no long access allowed */ ! 788: LOG_CRITICAL(("%08X [CTRL] Invalid memory store (long) 0x%X", ! 789: regs.pc, addr)); ! 790: } ! 791: ! 792: ! 793: /*** VDP fetch/store ***/ ! 794: ! 795: uint8 mem68k_fetch_vdp_byte(uint32 addr) ! 796: { ! 797: return (mem68k_fetch_vdp_word(addr) >> 8) & 0xff; ! 798: } ! 799: ! 800: uint16 mem68k_fetch_vdp_word(uint32 addr) ! 801: { ! 802: #ifdef DEBUG_BUS ! 803: if (addr & 1) { ! 804: LOG_CRITICAL(("%08X [VDP] Bus error 0x%X", regs.pc, addr)); ! 805: return 0; ! 806: } ! 807: #endif ! 808: addr-= 0xC00000; ! 809: switch(addr>>1) { ! 810: case 0: ! 811: case 1: ! 812: /* data port */ ! 813: #ifdef DEBUG_VDP ! 814: LOG_VERBOSE(("%08X [VDP] Word fetch from data port 0x%X", ! 815: regs.pc, addr)); ! 816: #endif ! 817: return vdp_fetchdata(); ! 818: case 2: ! 819: case 3: ! 820: /* control port */ ! 821: #ifdef DEBUG_VDP ! 822: LOG_VERBOSE(("%08X [VDP] Word fetch from control port " ! 823: "(status) 0x%X", regs.pc, addr)); ! 824: #endif ! 825: return vdp_status(); ! 826: case 4: ! 827: /* hv counter */ ! 828: { ! 829: uint8 line8; ! 830: uint16 hvcount; ! 831: ! 832: /* line counter advances at H-int */ ! 833: line8 = (vdp_line - vdp_visstartline + (vdp_event > 2 ? 1 : 0)) & 0xff; ! 834: ! 835: #ifdef DEBUG_VDP ! 836: LOG_VERBOSE(("%08X [VDP] Word fetch from hv counter 0x%X", ! 837: regs.pc, addr)); ! 838: #endif ! 839: if ((vdp_reg[12] >> 1) & 3) { ! 840: /* interlace mode - replace lowest bit with highest bit */ ! 841: hvcount = ((line8 & ~1)<<8) | (line8 & 0x100) | vdp_gethpos(); ! 842: LOG_DEBUG1(("Interlace mode HV read - check this: %04X", hvcount)); ! 843: return hvcount; ! 844: } else { ! 845: /* non-interlace mode */ ! 846: hvcount = (line8 << 8) | vdp_gethpos(); ! 847: LOG_DEBUG1(("%08X H/V counter read = %04X", regs.pc, hvcount)); ! 848: return hvcount; ! 849: } ! 850: } ! 851: case 8: ! 852: LOG_CRITICAL(("%08X [VDP] PSG/prohibited word fetch.", regs.pc)); ! 853: return 0; ! 854: default: ! 855: LOG_CRITICAL(("%08X [VDP] Invalid memory fetch (word) 0x%X", ! 856: regs.pc, addr)); ! 857: return 0; ! 858: } ! 859: } ! 860: ! 861: uint32 mem68k_fetch_vdp_long(uint32 addr) ! 862: { ! 863: #ifdef DEBUG_BUS ! 864: if (addr & 1) { ! 865: LOG_CRITICAL(("%08X [VDP] Bus error 0x%X", regs.pc, addr)); ! 866: return 0; ! 867: } ! 868: #endif ! 869: addr-= 0xC00000; ! 870: switch(addr>>1) { ! 871: case 0: ! 872: /* data port */ ! 873: #ifdef DEBUG_VDP ! 874: LOG_VERBOSE(("%08X [VDP] Long fetch from data port 0x%X", ! 875: regs.pc, addr)); ! 876: #endif ! 877: return (vdp_fetchdata()<<16) | vdp_fetchdata(); ! 878: case 2: ! 879: /* control port */ ! 880: #ifdef DEBUG_VDP ! 881: LOG_VERBOSE(("%08X [VDP] Long fetch from control port 0x%X", ! 882: regs.pc, addr)); ! 883: LOG_CRITICAL(("%08X [VDP] Long fetch from control port 0x%X", ! 884: regs.pc, addr)); ! 885: #endif ! 886: return 0; ! 887: case 4: ! 888: /* hv counter ish */ ! 889: LOG_CRITICAL(("%08X [VDP] Long fetch from hv/prohibited 0x%X", ! 890: regs.pc, addr)); ! 891: return 0; ! 892: default: ! 893: LOG_CRITICAL(("%08X [VDP] Invalid memory fetch (word) 0x%X", ! 894: regs.pc, addr)); ! 895: return 0; ! 896: } ! 897: } ! 898: ! 899: void mem68k_store_vdp_byte(uint32 addr, uint8 data) ! 900: { ! 901: addr-= 0xC00000; ! 902: switch(addr) { ! 903: case 0: ! 904: case 1: ! 905: case 2: ! 906: case 3: ! 907: /* data port */ ! 908: #ifdef DEBUG_VDP ! 909: LOG_VERBOSE(("%08X [VDP] Byte store to DATA of %X [%d][%X]", regs.pc, ! 910: data, vdp_reg[23]>>6, vdp_reg[1])); ! 911: #endif ! 912: vdp_storedata(data | (data << 8)); ! 913: return; ! 914: case 4: ! 915: case 5: ! 916: case 6: ! 917: case 7: ! 918: ! 919: #ifdef DEBUG_VDP ! 920: LOG_VERBOSE(("%08X [VDP] Byte store to CONTROL of %X [%d][%X]", regs.pc, ! 921: data, vdp_reg[23]>>6, vdp_reg[1])); ! 922: #endif ! 923: /* control port */ ! 924: vdp_storectrl(data | (data << 8)); ! 925: return; ! 926: case 8: ! 927: case 9: ! 928: /* hv counter */ ! 929: LOG_CRITICAL(("%08X [VDP] Byte store to hv counter 0x%X", regs.pc, addr)); ! 930: return; ! 931: case 17: ! 932: sound_psgwrite(data); ! 933: return; ! 934: default: ! 935: LOG_CRITICAL(("%08X [VDP] Invalid memory store (byte) 0x%X", ! 936: regs.pc, addr)); ! 937: return; ! 938: } ! 939: } ! 940: ! 941: void mem68k_store_vdp_word(uint32 addr, uint16 data) ! 942: { ! 943: #ifdef DEBUG_BUS ! 944: if (addr & 1) { ! 945: LOG_CRITICAL(("%08X [VDP] Bus error 0x%X", regs.pc, addr)); ! 946: return; ! 947: } ! 948: #endif ! 949: addr-= 0xC00000; ! 950: switch(addr>>1) { ! 951: case 0: ! 952: case 1: ! 953: /* data port */ ! 954: #ifdef DEBUG_VDP ! 955: LOG_CRITICAL(("%08X [VDP] Word store to DATA of %X [%d][%X]", regs.pc, ! 956: data, vdp_reg[23]>>6, vdp_reg[1])); ! 957: #endif ! 958: vdp_storedata(data); ! 959: return; ! 960: case 2: ! 961: case 3: ! 962: #ifdef DEBUG_VDP ! 963: LOG_VERBOSE(("%08X [VDP] Word store to CONTROL of %X [%d][%X]", regs.pc, ! 964: data, vdp_reg[23]>>6, vdp_reg[1])); ! 965: #endif ! 966: /* control port */ ! 967: vdp_storectrl(data); ! 968: return; ! 969: case 4: ! 970: /* hv counter */ ! 971: LOG_CRITICAL(("%08X [VDP] Word store to hv counter 0x%X", regs.pc, addr)); ! 972: return; ! 973: case 8: ! 974: LOG_CRITICAL(("%08X [VDP] PSG/prohibited word store.", regs.pc)); ! 975: return; ! 976: default: ! 977: LOG_CRITICAL(("%08X [VDP] Invalid memory store (word) 0x%X", regs.pc, ! 978: addr)); ! 979: return; ! 980: } ! 981: } ! 982: ! 983: void mem68k_store_vdp_long(uint32 addr, uint32 data) ! 984: { ! 985: #ifdef DEBUG_BUS ! 986: if (addr & 1) { ! 987: LOG_CRITICAL(("%08X [VDP] Bus error 0x%X", regs.pc, addr)); ! 988: return; ! 989: } ! 990: #endif ! 991: addr-= 0xC00000; ! 992: switch(addr>>1) { ! 993: case 0: ! 994: /* data port */ ! 995: #ifdef DEBUG_VDP ! 996: LOG_VERBOSE(("%08X [VDP] Long store to DATA of %X [%d][%X]", regs.pc, ! 997: data, vdp_reg[23]>>6, vdp_reg[1])); ! 998: #endif ! 999: vdp_storedata((uint16)(data>>16)); ! 1000: vdp_storedata((uint16)(data)); ! 1001: return; ! 1002: case 2: ! 1003: /* control port */ ! 1004: #ifdef DEBUG_VDP ! 1005: LOG_VERBOSE(("%08X [VDP] Long store to CONTROL of %X [%d][%X]", regs.pc, ! 1006: data, vdp_reg[23]>>6, vdp_reg[1])); ! 1007: #endif ! 1008: vdp_storectrl((uint16)(data>>16)); ! 1009: vdp_storectrl((uint16)(data)); ! 1010: return; ! 1011: case 4: ! 1012: /* hv counter */ ! 1013: LOG_CRITICAL(("%08X [VDP] Long store to hv/prohibited 0x%X", regs.pc, ! 1014: addr)); ! 1015: return; ! 1016: default: ! 1017: LOG_CRITICAL(("%08X [VDP] Invalid memory store (long) 0x%X", regs.pc, ! 1018: addr)); ! 1019: return; ! 1020: } ! 1021: } ! 1022: ! 1023: /*** RAM fetch/store ***/ ! 1024: ! 1025: uint8 mem68k_fetch_ram_byte(uint32 addr) ! 1026: { ! 1027: addr&= 0xffff; ! 1028: return (*(uint8 *)(cpu68k_ram+addr)); ! 1029: } ! 1030: ! 1031: uint16 mem68k_fetch_ram_word(uint32 addr) ! 1032: { ! 1033: addr&= 0xffff; ! 1034: return LOCENDIAN16(*(uint16 *)(cpu68k_ram+addr)); ! 1035: } ! 1036: ! 1037: uint32 mem68k_fetch_ram_long(uint32 addr) ! 1038: { ! 1039: addr&= 0xffff; ! 1040: #ifdef ALIGNLONGS ! 1041: return (LOCENDIAN16(*(uint16 *)(cpu68k_ram+addr))<<16) | ! 1042: LOCENDIAN16(*(uint16 *)(cpu68k_ram+addr+2)); ! 1043: #else ! 1044: return LOCENDIAN32(*(uint32 *)(cpu68k_ram+addr)); ! 1045: #endif ! 1046: } ! 1047: ! 1048: void mem68k_store_ram_byte(uint32 addr, uint8 data) ! 1049: { ! 1050: addr&= 0xffff; ! 1051: *(uint8 *)(cpu68k_ram+addr) = data; ! 1052: return; ! 1053: } ! 1054: ! 1055: void mem68k_store_ram_word(uint32 addr, uint16 data) ! 1056: { ! 1057: addr&= 0xffff; ! 1058: *(uint16 *)(cpu68k_ram+addr) = LOCENDIAN16(data); ! 1059: return; ! 1060: } ! 1061: ! 1062: void mem68k_store_ram_long(uint32 addr, uint32 data) ! 1063: { ! 1064: addr&= 0xffff; ! 1065: #ifdef ALIGNLONGS ! 1066: *(uint16 *)(cpu68k_ram+addr) = LOCENDIAN16((uint16)(data>>16)); ! 1067: *(uint16 *)(cpu68k_ram+addr+2) = LOCENDIAN16((uint16)(data)); ! 1068: #else ! 1069: *(uint32 *)(cpu68k_ram+addr) = LOCENDIAN32(data); ! 1070: #endif ! 1071: return; ! 1072: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.