|
|
1.1.1.2 ! root 1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */ 1.1 root 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" 1.1.1.2 ! root 11: #include "gensoundi.h" 1.1 root 12: #include "ui.h" 13: 1.1.1.2 ! root 14: #undef DEBUG_VDP 1.1 root 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: 1.1.1.2 ! root 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; 1.1 root 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: 1.1.1.2 ! root 119: { 0xA00, 0xA10, mem68k_memptr_bad, /* note overlaps blocks below */ 1.1 root 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: 1.1.1.2 ! root 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: 1.1 root 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: 1.1.1.2 ! root 147: { 0xE00, 0x1000, mem68k_memptr_ram, 1.1 root 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)); 1.1.1.2 ! root 182: mem68k_cont1ctrl = 0; ! 183: mem68k_cont2ctrl = 0; ! 184: mem68k_contEctrl = 0; ! 185: mem68k_cont1output = 0; ! 186: mem68k_cont2output = 0; ! 187: mem68k_contEoutput = 0; 1.1 root 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, 1.1.1.2 ! root 206: addr)); 1.1 root 207: return cpu68k_rom; 208: } 209: 210: uint8 *mem68k_memptr_ram(uint32 addr) 211: { 1.1.1.2 ! root 212: /* LOG_USER(("%08X [MEM] Executing code from RAM 0x%X", regs.pc, addr)); */ ! 213: addr&= 0xffff; 1.1 root 214: return(cpu68k_ram+addr); 215: } 216: 217: 218: /*** BAD fetch/store ***/ 219: 220: uint8 mem68k_fetch_bad_byte(uint32 addr) 221: { 1.1.1.2 ! root 222: LOG_CRITICAL(("%08X [MEM] Invalid memory fetch (byte) 0x%X", regs.pc, addr)); 1.1 root 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 1.1.1.2 ! root 323: addr&= 0x1fff; 1.1 root 324: return (*(uint8 *)(cpuz80_ram+addr)); 325: } 326: 327: uint16 mem68k_fetch_sram_word(uint32 addr) 328: { 1.1.1.2 ! root 329: uint8 data; 1.1 root 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 1.1.1.2 ! root 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); 1.1 root 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 1.1.1.2 ! root 356: addr&= 0x1fff; 1.1 root 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 1.1.1.2 ! root 370: addr&= 0x1fff; 1.1 root 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 1.1.1.2 ! root 386: addr&= 0x1fff; ! 387: /* word writes are stored with low byte cleared */ ! 388: *(uint8 *)(cpuz80_ram+addr) = data >> 8; 1.1 root 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 1.1.1.2 ! root 403: addr&= 0x1fff; 1.1 root 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) { 1.1.1.2 ! root 421: return soundi_ym2612fetch(addr); 1.1 root 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) 1.1.1.2 ! root 461: soundi_ym2612store(addr, data); 1.1 root 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, 1.1.1.2 ! root 498: addr)); 1.1 root 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, 1.1.1.2 ! root 506: addr)); 1.1 root 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, 1.1.1.2 ! root 514: addr)); 1.1 root 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, 1.1.1.2 ! root 528: addr)); 1.1 root 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, 1.1.1.2 ! root 542: addr)); 1.1 root 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, 1.1.1.2 ! root 551: addr)); 1.1 root 552: } 553: 554: 555: /*** I/O fetch/store ***/ 556: 557: uint8 mem68k_fetch_io_byte(uint32 addr) 558: { 1.1.1.2 ! root 559: uint8 in; ! 560: 1.1 root 561: addr-= 0xA10000; 1.1.1.2 ! root 562: if ((addr & 1) == 0) { 1.1 root 563: LOG_CRITICAL(("%08X [IO] Invalid memory fetch (byte) 0x%X", 1.1.1.2 ! root 564: regs.pc, addr)); 1.1 root 565: return 0; 1.1.1.2 ! root 566: } ! 567: switch (addr>>1) { ! 568: case 0: /* 0x1 */ 1.1 root 569: /* version */ 570: return (1<<5 | vdp_pal<<6 | vdp_overseas<<7); 1.1.1.2 ! root 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; 1.1 root 600: default: 601: LOG_CRITICAL(("%08X [IO] Invalid memory fetch (byte) 0x%X", 1.1.1.2 ! root 602: regs.pc, addr)); 1.1 root 603: return 0; 604: } 605: } 606: 607: uint16 mem68k_fetch_io_word(uint32 addr) 608: { 1.1.1.2 ! root 609: return mem68k_fetch_io_byte(addr+1); 1.1 root 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: 1.1.1.2 ! root 622: mem68k_cont1output = data; 1.1 root 623: return; 624: case 0x5: 1.1.1.2 ! root 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)); 1.1 root 630: return; 631: case 0x9: 1.1.1.2 ! root 632: mem68k_cont1ctrl = data; 1.1 root 633: if (data != 0x40) { 1.1.1.2 ! root 634: LOG_CRITICAL(("%08X [IO] Unknown controller 1 setting (0x%X)", ! 635: regs.pc, data)); 1.1 root 636: } 637: return; 638: case 0xB: 1.1.1.2 ! root 639: mem68k_cont2ctrl = data; 1.1 root 640: if (data != 0x40) { 1.1.1.2 ! root 641: LOG_CRITICAL(("%08X [IO] Unknown controller 2 setting (0x%X)", ! 642: regs.pc, data)); 1.1 root 643: } 644: return; 645: case 0xD: 1.1.1.2 ! root 646: mem68k_contEctrl = data; ! 647: LOG_NORMAL(("%08X [IO] EXT port ctrl set to %X", regs.pc, data)); ! 648: return; 1.1 root 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: 1.1.1.2 ! root 658: /* return; */ 1.1 root 659: default: 660: LOG_CRITICAL(("%08X [IO] Invalid memory store (byte) 0x%X", 1.1.1.2 ! root 661: regs.pc, addr)); 1.1 root 662: return; 663: } 664: } 665: 666: void mem68k_store_io_word(uint32 addr, uint16 data) 667: { 1.1.1.2 ! root 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); 1.1 root 671: } 672: 673: void mem68k_store_io_long(uint32 addr, uint32 data) 674: { 1.1.1.2 ! root 675: mem68k_store_io_word(addr, (uint16)(data>>16)); 1.1 root 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", 1.1.1.2 ! root 691: regs.pc, addr)); 1.1 root 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", 1.1.1.2 ! root 703: regs.pc, addr)); 1.1 root 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", 1.1.1.2 ! root 712: regs.pc, addr)); 1.1 root 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", 1.1.1.2 ! root 748: regs.pc, addr)); 1.1 root 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", 1.1.1.2 ! root 780: regs.pc, addr)); 1.1 root 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", 1.1.1.2 ! root 789: regs.pc, addr)); 1.1 root 790: } 791: 792: 793: /*** VDP fetch/store ***/ 794: 795: uint8 mem68k_fetch_vdp_byte(uint32 addr) 796: { 1.1.1.2 ! root 797: return (mem68k_fetch_vdp_word(addr) >> 8) & 0xff; 1.1 root 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", 1.1.1.2 ! root 815: regs.pc, addr)); 1.1 root 816: #endif 1.1.1.2 ! root 817: return vdp_fetchdata(); 1.1 root 818: case 2: 819: case 3: 820: /* control port */ 821: #ifdef DEBUG_VDP 822: LOG_VERBOSE(("%08X [VDP] Word fetch from control port " 1.1.1.2 ! root 823: "(status) 0x%X", regs.pc, addr)); 1.1 root 824: #endif 825: return vdp_status(); 826: case 4: 827: /* hv counter */ 1.1.1.2 ! root 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: 1.1 root 835: #ifdef DEBUG_VDP 1.1.1.2 ! root 836: LOG_VERBOSE(("%08X [VDP] Word fetch from hv counter 0x%X", ! 837: regs.pc, addr)); 1.1 root 838: #endif 1.1.1.2 ! root 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: } 1.1 root 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", 1.1.1.2 ! root 856: regs.pc, addr)); 1.1 root 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", 1.1.1.2 ! root 875: regs.pc, addr)); 1.1 root 876: #endif 1.1.1.2 ! root 877: return (vdp_fetchdata()<<16) | vdp_fetchdata(); 1.1 root 878: case 2: 879: /* control port */ 880: #ifdef DEBUG_VDP 881: LOG_VERBOSE(("%08X [VDP] Long fetch from control port 0x%X", 1.1.1.2 ! root 882: regs.pc, addr)); ! 883: LOG_CRITICAL(("%08X [VDP] Long fetch from control port 0x%X", ! 884: regs.pc, addr)); 1.1 root 885: #endif 886: return 0; 887: case 4: 888: /* hv counter ish */ 889: LOG_CRITICAL(("%08X [VDP] Long fetch from hv/prohibited 0x%X", 1.1.1.2 ! root 890: regs.pc, addr)); 1.1 root 891: return 0; 892: default: 893: LOG_CRITICAL(("%08X [VDP] Invalid memory fetch (word) 0x%X", 1.1.1.2 ! root 894: regs.pc, addr)); 1.1 root 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 1.1.1.2 ! root 909: LOG_VERBOSE(("%08X [VDP] Byte store to DATA of %X [%d][%X]", regs.pc, ! 910: data, vdp_reg[23]>>6, vdp_reg[1])); 1.1 root 911: #endif 1.1.1.2 ! root 912: vdp_storedata(data | (data << 8)); 1.1 root 913: return; 914: case 4: 915: case 5: 916: case 6: 917: case 7: 1.1.1.2 ! root 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 1.1 root 923: /* control port */ 1.1.1.2 ! root 924: vdp_storectrl(data | (data << 8)); 1.1 root 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", 1.1.1.2 ! root 936: regs.pc, addr)); 1.1 root 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 1.1.1.2 ! root 955: LOG_CRITICAL(("%08X [VDP] Word store to DATA of %X [%d][%X]", regs.pc, ! 956: data, vdp_reg[23]>>6, vdp_reg[1])); 1.1 root 957: #endif 1.1.1.2 ! root 958: vdp_storedata(data); 1.1 root 959: return; 960: case 2: 961: case 3: 962: #ifdef DEBUG_VDP 1.1.1.2 ! root 963: LOG_VERBOSE(("%08X [VDP] Word store to CONTROL of %X [%d][%X]", regs.pc, ! 964: data, vdp_reg[23]>>6, vdp_reg[1])); 1.1 root 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, 1.1.1.2 ! root 978: addr)); 1.1 root 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 1.1.1.2 ! root 996: LOG_VERBOSE(("%08X [VDP] Long store to DATA of %X [%d][%X]", regs.pc, ! 997: data, vdp_reg[23]>>6, vdp_reg[1])); 1.1 root 998: #endif 1.1.1.2 ! root 999: vdp_storedata((uint16)(data>>16)); ! 1000: vdp_storedata((uint16)(data)); 1.1 root 1001: return; 1002: case 2: 1003: /* control port */ 1004: #ifdef DEBUG_VDP 1.1.1.2 ! root 1005: LOG_VERBOSE(("%08X [VDP] Long store to CONTROL of %X [%d][%X]", regs.pc, ! 1006: data, vdp_reg[23]>>6, vdp_reg[1])); 1.1 root 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, 1.1.1.2 ! root 1014: addr)); 1.1 root 1015: return; 1016: default: 1017: LOG_CRITICAL(("%08X [VDP] Invalid memory store (long) 0x%X", regs.pc, 1.1.1.2 ! root 1018: addr)); 1.1 root 1019: return; 1020: } 1021: } 1022: 1023: 1024: /*** RAM fetch/store ***/ 1025: 1026: uint8 mem68k_fetch_ram_byte(uint32 addr) 1027: { 1.1.1.2 ! root 1028: addr&= 0xffff; 1.1 root 1029: return (*(uint8 *)(cpu68k_ram+addr)); 1030: } 1031: 1032: uint16 mem68k_fetch_ram_word(uint32 addr) 1033: { 1.1.1.2 ! root 1034: addr&= 0xffff; 1.1 root 1035: return LOCENDIAN16(*(uint16 *)(cpu68k_ram+addr)); 1036: } 1037: 1038: uint32 mem68k_fetch_ram_long(uint32 addr) 1039: { 1.1.1.2 ! root 1040: addr&= 0xffff; 1.1 root 1041: #ifdef ALIGNLONGS 1042: return (LOCENDIAN16(*(uint16 *)(cpu68k_ram+addr))<<16) | 1043: LOCENDIAN16(*(uint16 *)(cpu68k_ram+addr+2)); 1044: #else 1045: return LOCENDIAN32(*(uint32 *)(cpu68k_ram+addr)); 1046: #endif 1047: } 1048: 1049: void mem68k_store_ram_byte(uint32 addr, uint8 data) 1050: { 1.1.1.2 ! root 1051: addr&= 0xffff; 1.1 root 1052: *(uint8 *)(cpu68k_ram+addr) = data; 1053: return; 1054: } 1055: 1056: void mem68k_store_ram_word(uint32 addr, uint16 data) 1057: { 1.1.1.2 ! root 1058: addr&= 0xffff; 1.1 root 1059: *(uint16 *)(cpu68k_ram+addr) = LOCENDIAN16(data); 1060: return; 1061: } 1062: 1063: void mem68k_store_ram_long(uint32 addr, uint32 data) 1064: { 1.1.1.2 ! root 1065: addr&= 0xffff; 1.1 root 1066: #ifdef ALIGNLONGS 1067: *(uint16 *)(cpu68k_ram+addr) = LOCENDIAN16((uint16)(data>>16)); 1068: *(uint16 *)(cpu68k_ram+addr+2) = LOCENDIAN16((uint16)(data)); 1069: #else 1070: *(uint32 *)(cpu68k_ram+addr) = LOCENDIAN32(data); 1071: #endif 1072: return; 1073: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.