|
|
1.1 ! root 1: #include "main.h" ! 2: #include "configuration.h" ! 3: #include "m68000.h" ! 4: #include "sysdeps.h" ! 5: #include "dimension.hpp" ! 6: #include "nd_mem.hpp" ! 7: #include "log.h" ! 8: ! 9: /* --------- NEXTDIMENSION MEMORY ---------- */ ! 10: ! 11: /* NeXTdimension board memory */ ! 12: #define ND_RAM_START 0xF8000000 ! 13: #define ND_RAM_SIZE 0x04000000 ! 14: #define ND_RAM_MASK 0x03FFFFFF ! 15: ! 16: #define ND_VRAM_START 0xFE000000 ! 17: #define ND_VRAM_SIZE 0x00400000 ! 18: #define ND_VRAM_MASK 0x003FFFFF ! 19: ! 20: #define ND_EEPROM_START 0xFFF00000 ! 21: #define ND_EEPROM_SIZE 0x00020000 ! 22: #define ND_EEPROM_MASK 0x0001FFFF ! 23: ! 24: /* RAM banks */ ! 25: #define ND_RAM_BANKSIZE 0x01000000 ! 26: #define ND_RAM_BANKMASK 0x03000000 ! 27: ! 28: /* NeXTdimension dither memory */ ! 29: #define ND_DMEM_START 0xFF000000 ! 30: #define ND_DMEM_SIZE 0x00000200 ! 31: #define ND_DMEM_MASK 0x000001FF ! 32: ! 33: /* NeXTdimension board devices */ ! 34: #define ND_IO_START 0xFF800000 ! 35: #define ND_IO_SIZE 0x00004000 ! 36: #define ND_IO_MASK 0x00003FFF ! 37: ! 38: /* NeXTdimension board RAMDAC */ ! 39: #define ND_RAMDAC_START 0xFF200000 ! 40: #define ND_RAMDAC_SIZE 0x00001000 ! 41: #define ND_RAMDAC_MASK 0x00000FFF ! 42: ! 43: /* NeXTdimension board data path */ ! 44: #define ND_DP_START 0xF0000000 ! 45: #define ND_DP_SIZE 0x00001000 ! 46: #define ND_DP_MASK 0x00000FFF ! 47: ! 48: /* NeXTdimension unknown registers */ ! 49: #define ND_CSR_START 0xFF400000 ! 50: #define ND_CSR_SIZE 0x00000200 ! 51: #define ND_CSR_MASK 0x000001FF ! 52: ! 53: /* Function to fix address for ROM access */ ! 54: static uaecptr nd_rom_addr_fix(uaecptr addr) ! 55: { ! 56: #if ND_STEP ! 57: addr >>= 2; ! 58: #else ! 59: addr &= ~3; ! 60: addr |= (addr>>17)&3; ! 61: #endif ! 62: addr &= ND_EEPROM_MASK; ! 63: return addr; ! 64: } ! 65: ! 66: /* Memory banks */ ! 67: ! 68: /* NeXTdimension RAM */ ! 69: ! 70: class ND_RAM : public ND_Addrbank { ! 71: Uint8* base; ! 72: Uint32 mask; ! 73: public: ! 74: ND_RAM(NextDimension* nd, int bank) : ND_Addrbank(nd), base(nd->ram), mask(nd->bankmask[bank]) {} ! 75: ! 76: Uint32 lget(Uint32 addr) { ! 77: addr &= mask; ! 78: return do_get_mem_long(base + addr); ! 79: } ! 80: ! 81: Uint32 wget(Uint32 addr) { ! 82: addr &= mask; ! 83: return do_get_mem_word(base + addr); ! 84: } ! 85: ! 86: Uint32 bget(Uint32 addr) { ! 87: addr &= mask; ! 88: return base[addr]; ! 89: } ! 90: ! 91: void lput(Uint32 addr, Uint32 l) { ! 92: addr &= mask; ! 93: do_put_mem_long(base + addr, l); ! 94: } ! 95: ! 96: void wput(Uint32 addr, Uint32 w) { ! 97: addr &= mask; ! 98: do_put_mem_word(base + addr, w); ! 99: } ! 100: ! 101: void bput(Uint32 addr, Uint32 b) { ! 102: addr &= mask; ! 103: base[addr] = b; ! 104: } ! 105: }; ! 106: ! 107: class ND_Empty : public ND_Addrbank { ! 108: public: ! 109: ND_Empty(NextDimension* nd) : ND_Addrbank(nd) {} ! 110: ! 111: Uint32 lget(Uint32 addr) { ! 112: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: empty memory bank lget at %08X\n", nd->slot,addr); ! 113: return 0; ! 114: } ! 115: ! 116: Uint32 wget(Uint32 addr) { ! 117: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: empty memory bank wget at %08X\n", nd->slot,addr); ! 118: return 0; ! 119: } ! 120: ! 121: Uint32 bget(Uint32 addr) { ! 122: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: empty memory bank bget at %08X\n", nd->slot,addr); ! 123: return 0; ! 124: } ! 125: ! 126: void lput(Uint32 addr, Uint32 l) { ! 127: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: empty memory bank lput at %08X\n", nd->slot,addr); ! 128: } ! 129: ! 130: void wput(Uint32 addr, Uint32 w) { ! 131: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: empty memory bank wput at %08X\n", nd->slot,addr); ! 132: } ! 133: ! 134: void bput(Uint32 addr, Uint32 b) { ! 135: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: empty memory bank bput at %08X\n",nd->slot,addr); ! 136: } ! 137: }; ! 138: ! 139: /* NeXTdimension VRAM */ ! 140: /* stored as ARGB for faster blitting, assuming aligned access for 32 bit */ ! 141: ! 142: class ND_VRAM : public ND_Addrbank { ! 143: Uint8* base; ! 144: public: ! 145: ND_VRAM(NextDimension* nd) : ND_Addrbank(nd), base(nd->vram) { ! 146: // sanity checks for ARGB mem access ! 147: lput(0, 0x12345678); ! 148: if(lget(0) != 0x12345678) {fprintf(stderr, "ND_VRAM: 32 bit access check failed\n"); goto error;} ! 149: ! 150: if(bget(0) != 0x12) {fprintf(stderr, "ND_VRAM: 8 bit access 0 check failed\n"); goto error;} ! 151: if(bget(1) != 0x34) {fprintf(stderr, "ND_VRAM: 8 bit access 1 check failed\n"); goto error;} ! 152: if(bget(2) != 0x56) {fprintf(stderr, "ND_VRAM: 8 bit access 2 check failed\n"); goto error;} ! 153: if(bget(3) != 0x78) {fprintf(stderr, "ND_VRAM: 8 bit access 3 check failed\n"); goto error;} ! 154: ! 155: if(wget(0) != 0x1234) {fprintf(stderr, "ND_VRAM: 16 bit access 0 check failed\n"); goto error;} ! 156: if(wget(2) != 0x5678) {fprintf(stderr, "ND_VRAM: 16 bit access 2 check failed\n"); goto error;} ! 157: ! 158: wput(0, 0x7654); ! 159: wput(2, 0x3210); ! 160: if(lget(0) != 0x76543210) {fprintf(stderr, "ND_VRAM: 32 bit access check failed (wput)\n"); goto error;} ! 161: ! 162: bput(0, 0x12); ! 163: bput(1, 0x34); ! 164: bput(2, 0x56); ! 165: bput(3, 0x78); ! 166: if(lget(0) != 0x12345678) {fprintf(stderr, "ND_VRAM: 32 bit access check failed (bput)\n"); goto error;} ! 167: ! 168: return; ! 169: error: ! 170: exit(1); ! 171: } ! 172: ! 173: Uint32 lget(Uint32 addr) { ! 174: addr &= ND_VRAM_MASK; ! 175: return ! 176: base[addr+3] | ! 177: (base[addr+0] << 8) | ! 178: (base[addr+1] << 16) | ! 179: (base[addr+2] << 24); ! 180: } ! 181: ! 182: void lput(Uint32 addr, Uint32 l) { ! 183: addr &= ND_VRAM_MASK; ! 184: base[addr+3] = l; ! 185: base[addr+0] = l >> 8; ! 186: base[addr+1] = l >> 16; ! 187: base[addr+2] = l >> 24; ! 188: } ! 189: ! 190: Uint32 wget(Uint32 addr) { ! 191: addr &= ND_VRAM_MASK; ! 192: return (bget(addr) << 8) | bget(addr+1); ! 193: } ! 194: ! 195: void wput(Uint32 addr, Uint32 w) { ! 196: addr &= ND_VRAM_MASK; ! 197: bput(addr, w >> 8); ! 198: bput(addr+1, w); ! 199: } ! 200: ! 201: Uint32 bget(Uint32 addr) { ! 202: addr &= ND_VRAM_MASK; ! 203: switch(addr&3) { ! 204: case 0: return base[(addr&~3)+2]; ! 205: case 1: return base[(addr&~3)+1]; ! 206: case 2: return base[(addr&~3)+0]; ! 207: case 3: return base[(addr&~3)+3]; ! 208: } ! 209: return 0; ! 210: } ! 211: ! 212: void bput(Uint32 addr, Uint32 b) { ! 213: addr &= ND_VRAM_MASK; ! 214: switch(addr&3) { ! 215: case 0: base[(addr&~3)+2] = b; break; ! 216: case 1: base[(addr&~3)+1] = b; break; ! 217: case 2: base[(addr&~3)+0] = b; break; ! 218: case 3: base[(addr&~3)+3] = b; break; ! 219: } ! 220: } ! 221: }; ! 222: ! 223: /* NeXTdimension ROM */ ! 224: ! 225: class ND_ROM : public ND_Addrbank { ! 226: public: ! 227: ND_ROM(NextDimension* nd) : ND_Addrbank(nd) {} ! 228: ! 229: Uint32 lget(Uint32 addr) { ! 230: addr = nd_rom_addr_fix(addr); ! 231: return (nd->rom_read(addr) << 24); /* byte lane at msb */ ! 232: } ! 233: ! 234: Uint32 wget(Uint32 addr) { ! 235: addr = nd_rom_addr_fix(addr); ! 236: return (nd->rom_read(addr) << 8); /* byte lane at msb */ ! 237: } ! 238: ! 239: Uint32 bget(Uint32 addr) { ! 240: addr = nd_rom_addr_fix(addr); ! 241: return nd->rom_read(addr); ! 242: } ! 243: ! 244: Uint32 cs8get(Uint32 addr) { ! 245: addr &= ND_EEPROM_MASK; ! 246: return nd->rom[addr]; ! 247: } ! 248: ! 249: void lput(Uint32 addr, Uint32 l) { ! 250: addr = nd_rom_addr_fix(addr); ! 251: nd->rom_write(addr, l >> 24); ! 252: } ! 253: ! 254: void wput(Uint32 addr, Uint32 w) { ! 255: addr = nd_rom_addr_fix(addr); ! 256: nd->rom_write(addr, w >> 8); ! 257: } ! 258: ! 259: void bput(Uint32 addr, Uint32 b) { ! 260: addr = nd_rom_addr_fix(addr); ! 261: nd->rom_write(addr, b); ! 262: } ! 263: }; ! 264: ! 265: /* Unknown register access functions (memory controller step 1) */ ! 266: #if ND_STEP ! 267: ! 268: class ND_CSR : public ND_Addrbank { ! 269: public: ! 270: ND_CSR(NextDimension* nd) : ND_Addrbank(nd) {} ! 271: ! 272: Uint32 lget(Uint32 addr) { ! 273: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Board CSR lget at %08X\n", nd->slot,addr); ! 274: return 0; ! 275: } ! 276: ! 277: Uint32 wget(Uint32 addr) { ! 278: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Board CSR wget at %08X\n",nd->slot,addr); ! 279: return 0; ! 280: } ! 281: ! 282: Uint32 bget(Uint32 addr) { ! 283: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Board CSR bget at %08X\n",nd->slot,addr); ! 284: return 0; ! 285: } ! 286: ! 287: void lput(Uint32 addr, Uint32 l) { ! 288: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Board CSR lput at %08X: %08X\n",nd->slot,addr,l); ! 289: } ! 290: ! 291: void wput(Uint32 addr, Uint32 w) { ! 292: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Board CSR wput at %08X: %04X\n",nd->slot,addr,w); ! 293: } ! 294: ! 295: void bput(Uint32 addr, Uint32 b) { ! 296: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Board CSR bput at %08X: %02X\n",nd->slot,addr,b); ! 297: } ! 298: }; ! 299: #endif ! 300: ! 301: /* NeXTdimension dither memory & datapath */ ! 302: ! 303: class ND_DMEM : public ND_Addrbank { ! 304: public: ! 305: ND_DMEM(NextDimension* nd) : ND_Addrbank(nd) {} ! 306: ! 307: Uint32 lget(Uint32 addr) { ! 308: addr &= ND_DP_MASK; ! 309: return addr < ND_DMEM_SIZE ? do_get_mem_long(nd->dmem + addr) : nd->dp.lget(addr); ! 310: } ! 311: ! 312: Uint32 wget(Uint32 addr) { ! 313: addr &= ND_DP_MASK; ! 314: return addr < ND_DMEM_SIZE ? do_get_mem_word(nd->dmem + addr) : nd->dp.lget(addr); ! 315: } ! 316: ! 317: Uint32 bget(Uint32 addr) { ! 318: addr &= ND_DP_MASK; ! 319: return addr < ND_DMEM_SIZE ? do_get_mem_byte(nd->dmem + addr) : nd->dp.lget(addr); ! 320: } ! 321: ! 322: void lput(Uint32 addr, Uint32 l) { ! 323: addr &= ND_DP_MASK; ! 324: if(addr < ND_DMEM_SIZE) ! 325: do_put_mem_long(nd->dmem + addr, l); ! 326: else ! 327: nd->dp.lput(addr, l); ! 328: } ! 329: ! 330: void wput(Uint32 addr, Uint32 w) { ! 331: addr &= ND_DP_MASK; ! 332: if(addr < ND_DMEM_SIZE) ! 333: do_put_mem_word(nd->dmem + addr, w); ! 334: else ! 335: nd->dp.lput(addr, w); ! 336: } ! 337: ! 338: void bput(Uint32 addr, Uint32 b) { ! 339: addr &= ND_DP_MASK; ! 340: if(addr < ND_DMEM_SIZE) ! 341: do_put_mem_byte(nd->dmem + addr, b); ! 342: else ! 343: nd->dp.lput(addr, b); ! 344: } ! 345: }; ! 346: ! 347: /* Illegal access functions */ ! 348: ! 349: ND_Addrbank::ND_Addrbank(NextDimension* nd) : nd(nd) {} ! 350: ! 351: Uint32 ND_Addrbank::lget(Uint32 addr) { ! 352: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal lget at %08X\n",nd->slot,addr); ! 353: return 0; ! 354: } ! 355: ! 356: Uint32 ND_Addrbank::wget(Uint32 addr) { ! 357: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal wget at %08X\n",nd->slot,addr); ! 358: return 0; ! 359: } ! 360: ! 361: Uint32 ND_Addrbank::bget(Uint32 addr) { ! 362: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal bget at %08X\n",nd->slot,addr); ! 363: return 0; ! 364: } ! 365: ! 366: Uint32 ND_Addrbank::cs8get(Uint32 addr) { ! 367: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal cs8get at %08X\n",nd->slot,addr); ! 368: return 0; ! 369: } ! 370: ! 371: void ND_Addrbank::lput(Uint32 addr, Uint32 l) { ! 372: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal lput at %08X\n",nd->slot,addr); ! 373: } ! 374: ! 375: void ND_Addrbank::wput(Uint32 addr, Uint32 w) { ! 376: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal wput at %08X\n",nd->slot,addr); ! 377: } ! 378: ! 379: void ND_Addrbank::bput(Uint32 addr, Uint32 b) { ! 380: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal bput at %08X\n",nd->slot,addr); ! 381: } ! 382: ! 383: /* NeXTdimension device space */ ! 384: ! 385: class ND_IO : public ND_Addrbank { ! 386: public: ! 387: ND_IO(NextDimension* nd) : ND_Addrbank(nd) {} ! 388: ! 389: Uint32 lget(Uint32 addr) { ! 390: return nd->mc.read(addr); ! 391: } ! 392: ! 393: Uint32 wget(Uint32 addr) {return 0;} ! 394: ! 395: Uint32 bget(Uint32 addr) {return 0;} ! 396: ! 397: void lput(Uint32 addr, Uint32 l) { ! 398: nd->mc.write(addr, l); ! 399: } ! 400: ! 401: void wput(Uint32 addr, Uint32 w) {} ! 402: void bput(Uint32 addr, Uint32 b) {} ! 403: }; ! 404: ! 405: /* NeXTdimension RAMDAC */ ! 406: ! 407: class ND_RAMDAC : public ND_Addrbank { ! 408: public: ! 409: ND_RAMDAC(NextDimension* nd) : ND_Addrbank(nd) {} ! 410: ! 411: Uint32 lget(Uint32 addr) { ! 412: return bt463_bget(&nd->ramdac, addr) << 24; ! 413: } ! 414: ! 415: Uint32 wget(Uint32 addr) { ! 416: return bt463_bget(&nd->ramdac, addr) << 8; ! 417: } ! 418: ! 419: Uint32 bget(Uint32 addr) { ! 420: return bt463_bget(&nd->ramdac, addr); ! 421: } ! 422: ! 423: void lput(Uint32 addr, Uint32 l) { ! 424: bt463_bput(&nd->ramdac, addr, l >> 24); ! 425: } ! 426: ! 427: void wput(Uint32 addr, Uint32 w) { ! 428: bt463_bput(&nd->ramdac, addr, w >> 8); ! 429: } ! 430: ! 431: void bput(Uint32 addr, Uint32 b) { ! 432: bt463_bput(&nd->ramdac, addr, b); ! 433: } ! 434: }; ! 435: ! 436: void NextDimension::map_banks (ND_Addrbank *bank, int start, int size) { ! 437: for (int bnr = start; bnr < start + size; bnr++) ! 438: nd_put_mem_bank (bnr << 16, bank); ! 439: return; ! 440: } ! 441: ! 442: void NextDimension::init_mem_banks(void) { ! 443: ND_Addrbank* nd_illegal_bank = new ND_Addrbank(this); ! 444: for (int i = 0; i < 65536; i++) ! 445: nd_put_mem_bank(i<<16, nd_illegal_bank); ! 446: } ! 447: ! 448: #define write_log printf ! 449: ! 450: void NextDimension::mem_init(void) { ! 451: write_log("[ND] Slot %i: Memory init: Memory size: %iMB\n", slot, ! 452: Configuration_CheckDimensionMemory(ConfigureParams.Dimension.board[ND_NUM(slot)].nMemoryBankSize)); ! 453: ! 454: /* Initialize banks with error memory */ ! 455: init_mem_banks(); ! 456: ! 457: /* Clear first 4k of memory for m68k ROM polling code */ ! 458: memset(ram, 0, 4096 * sizeof(Uint8)); ! 459: ! 460: /* Map main memory */ ! 461: ! 462: for(int bank = 0; bank < 4; bank++) { ! 463: if (ConfigureParams.Dimension.board[ND_NUM(slot)].nMemoryBankSize[bank]) { ! 464: bankmask[bank] = ND_RAM_BANKMASK|((ConfigureParams.Dimension.board[ND_NUM(slot)].nMemoryBankSize[bank]<<20)-1); ! 465: map_banks(new ND_RAM(this, bank), (ND_RAM_START+(bank*ND_RAM_BANKSIZE))>>16, ND_RAM_BANKSIZE >> 16); ! 466: write_log("[ND] Slot %i: Mapping main memory bank%d at $%08x: %iMB\n", slot, bank, ! 467: (ND_RAM_START+(bank*ND_RAM_BANKSIZE)), ConfigureParams.Dimension.board[ND_NUM(slot)].nMemoryBankSize[0]); ! 468: } else { ! 469: bankmask[bank] = 0; ! 470: map_banks(new ND_Empty(this), (ND_RAM_START+(bank*ND_RAM_BANKSIZE))>>16, ND_RAM_BANKSIZE >> 16); ! 471: write_log("[ND] Slot %i: Mapping main memory bank%d at $%08x: empty\n", slot, bank, ! 472: (ND_RAM_START+(bank*ND_RAM_BANKSIZE))); ! 473: } ! 474: } ! 475: ! 476: write_log("[ND] Slot %i: Mapping video memory at $%08x: %iMB\n", slot, ! 477: ND_VRAM_START, ND_VRAM_SIZE/(1024*1024)); ! 478: map_banks(new ND_VRAM(this), ND_VRAM_START>>16, (4*ND_VRAM_SIZE)>>16); ! 479: ! 480: write_log("[ND] Slot %i: Mapping ROM at $%08x: %ikB\n", slot, ! 481: ND_EEPROM_START, ND_EEPROM_SIZE/1024); ! 482: map_banks(new ND_ROM(this), ND_EEPROM_START>>16, (ND_EEPROM_SIZE*8)>>16); ! 483: rom_load(); ! 484: ! 485: write_log("[ND] Slot %i: Mapping dither memory and data path at $%08x: %ibyte\n", slot, ! 486: ND_DMEM_START, ND_DMEM_SIZE); ! 487: map_banks(new ND_DMEM(this), ND_DMEM_START>>16, 1); ! 488: ! 489: write_log("[ND] Slot %i: Mapping IO memory at $%08x\n", slot, ND_IO_START); ! 490: map_banks(new ND_IO(this), ND_IO_START>>16, 1); ! 491: ! 492: write_log("[ND] Slot %i: Mapping RAMDAC registers at $%08x\n", slot, ND_RAMDAC_START); ! 493: map_banks(new ND_RAMDAC(this), ND_RAMDAC_START>>16, 1); ! 494: #if ND_STEP ! 495: write_log("[ND] Slot %i: Mapping board CSR at $%08x\n", slot, ND_CSR_START); ! 496: map_banks(new ND_CSR(this), ND_CSR_START>>16, 1); ! 497: #endif ! 498: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.