|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2017 [email protected] ! 4: // ! 5: ! 6: #include "vm.h" ! 7: #include "bitmap.h" ! 8: #include "bt454.h" ! 9: #include "bus.h" ! 10: #include "crtc2.h" ! 11: #include "ethernet.h" ! 12: #include "human68k.h" ! 13: #include "lance.h" ! 14: #include "lcd.h" ! 15: #include "lunakbd.h" ! 16: #include "lunarom.h" ! 17: #include "mk48t02.h" ! 18: #include "mpu.h" ! 19: #include "ppi.h" ! 20: #include "ram.h" ! 21: #include "renderer.h" ! 22: #include "rp5c15.h" ! 23: #include "scsitarget.h" ! 24: #include "sio.h" ! 25: #include "spc.h" ! 26: #include "sysclk.h" ! 27: #include "scheduler.h" ! 28: #include "x68kkbd.h" ! 29: #include "xiospace.h" ! 30: #include "zram.h" ! 31: ! 32: VM *gVM; ! 33: ! 34: // コンストラクタ ! 35: VM::VM(vmtype_t type) ! 36: { ! 37: vmtype = type; ! 38: ! 39: // どこでやるのがいいかわからんけど、このコンストラクタはメインスレッドで ! 40: // 作られるので、ここでメインスレッドの名前を設定。 ! 41: pthread_setname_np("Main"); ! 42: ! 43: // Scheduler は必ず先頭。(Scheduler::Init のコメント参照) ! 44: gScheduler = new Scheduler(); ! 45: buserr = new BusErrDevice(); ! 46: ! 47: // まず全域をバスエラーで初期化。 ! 48: // この後継承先で必要に応じて上書きする。 ! 49: for (int i = 0; i < countof(::devtable); i++) { ! 50: ::devtable[i] = buserr; ! 51: } ! 52: } ! 53: ! 54: // デストラクタ ! 55: VM::~VM() ! 56: { ! 57: } ! 58: ! 59: // コンストラクタ後の初期化 ! 60: bool ! 61: VM::Create() ! 62: { ! 63: for (const auto& d : gDevices) { ! 64: if (!d->Create()) { ! 65: return false; ! 66: } ! 67: } ! 68: ! 69: return true; ! 70: } ! 71: ! 72: // 初期化 ! 73: bool ! 74: VM::Init() ! 75: { ! 76: for (const auto& d : gDevices) { ! 77: if (!d->Init()) { ! 78: return false; ! 79: } ! 80: } ! 81: ! 82: return true; ! 83: } ! 84: ! 85: // 設定の適用 ! 86: bool ! 87: VM::Apply() ! 88: { ! 89: for (const auto& d : gDevices) { ! 90: if (!d->Apply()) { ! 91: return false; ! 92: } ! 93: } ! 94: ! 95: return true; ! 96: } ! 97: ! 98: // VM の全デバイスの電源をオン ! 99: bool ! 100: VM::DevicePowerOn() ! 101: { ! 102: for (const auto& d : gDevices) { ! 103: if (!d->PowerOn()) { ! 104: return false; ! 105: } ! 106: } ! 107: ! 108: // ハードウェアリセット ! 109: ResetHard(); ! 110: ! 111: // スケジューラを開始 ! 112: // (ResetMPU より後で起動時に1回だけ呼び出す) ! 113: gScheduler->Run(); ! 114: ! 115: return true; ! 116: } ! 117: ! 118: // VM の全デバイスの電源をオフ ! 119: // (Scheduler から呼ばれる) ! 120: bool ! 121: VM::DevicePowerOff() ! 122: { ! 123: for (const auto& d : gDevices) { ! 124: if (!d->PowerOff()) { ! 125: return false; ! 126: } ! 127: } ! 128: // GUI に通知 ! 129: if (poweroff_callback) { ! 130: poweroff_callback(); ! 131: } ! 132: return true; ! 133: } ! 134: ! 135: // VM 電源オフ時のコールバックを設定する ! 136: void ! 137: VM::SetPowerOffCallback(void (*callback)()) ! 138: { ! 139: poweroff_callback = callback; ! 140: } ! 141: ! 142: // ハードウェアリセット ! 143: void ! 144: VM::ResetHard() ! 145: { ! 146: for (const auto& d : gDevices) { ! 147: d->ResetHard(); ! 148: } ! 149: } ! 150: ! 151: // MPU の RESET 命令によるリセット ! 152: void ! 153: VM::ResetSoft() ! 154: { ! 155: for (const auto& d : gDevices) { ! 156: d->ResetSoft(); ! 157: } ! 158: } ! 159: ! 160: ! 161: // ! 162: // X68030 VM ! 163: // ! 164: ! 165: // コンストラクタ ! 166: VM_X68030::VM_X68030() ! 167: : VM(TYPE_X68030) ! 168: { ! 169: // デバイス (順序に注意) ! 170: // Scheduler (と BusErrDevice) は親コンストラクタで作成済み。 ! 171: gMPU = new MPUDevice(0xff0000); ! 172: gRAM = new RAMDevice(); // required by XIOSpace ! 173: xiospace = new XIOSpaceDevice(); ! 174: ! 175: gKeyboard = new X68030Keyboard(); ! 176: gRenderer = new X68030Renderer(); ! 177: ! 178: // 割り当て ! 179: // 今は拡張メモリがないので、今は上位8ビット全領域がミラーになっている。 ! 180: for (int i = 0; i < countof(::devtable); i++) { ! 181: ::devtable[i] = xiospace; ! 182: } ! 183: } ! 184: ! 185: // デストラクタ ! 186: VM_X68030::~VM_X68030() ! 187: { ! 188: } ! 189: ! 190: // X68030 の電源ボタンを押します。 ! 191: void ! 192: VM_X68030::PowerButton() ! 193: { ! 194: // 電源 ボタン ! 195: // ON OFF->ON 電源オフ割り込みをネゲート? ! 196: // ON ON ->OFF 電源オフ割り込みをアサート? ! 197: // OFF OFF->ON 電源オン ! 198: // OFF ON ->OFF (通常はあり得ないはず) ! 199: ! 200: // ボタンの状態を更新して.. ! 201: power_button = !power_button; ! 202: ! 203: // デバイスに指示 ! 204: DevicePowerOn(); ! 205: } ! 206: ! 207: ! 208: // ! 209: // LUNA ! 210: // ! 211: ! 212: // コンストラクタ ! 213: VM_LUNA::VM_LUNA() ! 214: : VM(TYPE_LUNA) ! 215: { ! 216: // デバイス (順序に注意) ! 217: // Scheduler (と BusErrDevice) は親コンストラクタで作成済み。 ! 218: gMPU = new MPUDevice(0x41000000); ! 219: gRAM = new RAMDevice(); ! 220: gPROM = new PROMDevice(); ! 221: mk48 = new MK48T02Device(); ! 222: gRTC = (RTCDevice *)mk48; // MK48T02 は NVRAM でも RTC でもある… ! 223: pio0 = new PIO0Device(); ! 224: pio1 = new PIO1Device(); ! 225: gSIO = new SIODevice(); ! 226: sysclk = new SysClkDevice(); ! 227: gZRAM = new ZRAMDevice(); ! 228: maskrom = new MaskROMDevice(); ! 229: gBitmap = new BitmapDevice(); // required by BT454 ! 230: gBT454 = new BT454Device(); ! 231: crtc2 = new CRTC2Device(); ! 232: gSPC = new SPCDevice(0xe1000000); ! 233: gLance = new LanceDevice(); ! 234: nulldev = new NullDevice(); ! 235: ! 236: gEthernet = gLance; ! 237: gLCD = new LCDDevice(); ! 238: gKeyboard = new LunaKeyboard(); ! 239: gRenderer = new LunaRenderer(); ! 240: ! 241: // デバイスマップから devtable を作成 ! 242: for (uint i = 0; i < countof(::devtable); i++) { ! 243: IODevice *d; ! 244: switch (maptable[i]) { ! 245: case NONE: d = nulldev; break; ! 246: case BUSERR: d = buserr; break; ! 247: case RAM: d = gRAM; break; ! 248: case PROM: d = gPROM; break; ! 249: case MK48: d = mk48; break; ! 250: case PIO0: d = pio0; break; ! 251: case PIO1: d = pio1; break; ! 252: case SIO: d = gSIO; break; ! 253: case TAS: d = gZRAM; break; ! 254: case SYSCLK: d = sysclk; break; ! 255: case ZRAM: d = gZRAM; break; ! 256: case MROM: d = maskrom; break; ! 257: case BITMAP: d = gBitmap; break; ! 258: case BT454: d = gBT454; break; ! 259: case CRTC2: d = crtc2; break; ! 260: case SCSI: d = gSPC; break; ! 261: case LANCE: d = gLance; break; ! 262: default: ! 263: __unreachable(); ! 264: } ! 265: ::devtable[i] = d; ! 266: } ! 267: } ! 268: ! 269: // デストラクタ ! 270: VM_LUNA::~VM_LUNA() ! 271: { ! 272: } ! 273: ! 274: void ! 275: VM_LUNA::PowerButton() ! 276: { ! 277: // LUNA の電源ボタンは電源オンにしか使わない。 ! 278: // ! 279: // 電源 ボタン ! 280: // ON PUSH (何も起きない) ! 281: // OFF PUSH 電源オン ! 282: ! 283: // デバイスに指示 ! 284: DevicePowerOn(); ! 285: } ! 286: ! 287: // LUNA のデバイス割り当て表 (上位8ビット) ! 288: // ! 289: // 仕様 実際 ! 290: // 00 00 メインメモリ ! 291: // -- 01..03 二重バスフォールトするようだ ! 292: // -- 04..0f 何かよく分からないものが読める ! 293: // -- 10..3f BUSERR ! 294: // 41 40..43 PROM ! 295: // 45 44..47 mk48t02 ! 296: // 49 48..4b pio0 ! 297: // 4d 4c..4f pio1 ! 298: // 51 50..53 sio ! 299: // -- 54..5f 0x7f が読めるようだ ! 300: // 61 60..61 TAS ! 301: // 63 62..63 システムクロック ! 302: // -- 64..6f 61 (TAS) と同じパターンのように見えるけど不詳 ! 303: // 71 70..7f 3ポートRAM ! 304: // 81 80.. BUSERR (オンボード拡張スロットA) ! 305: // 83 ..8f BUSERR (オンボード拡張スロットB) ! 306: // 91 90..9f 0xff が読めるようだ (PC-9000 拡張スロット) ! 307: // ! 308: // a1 マスクROM ! 309: // a0,a2,a4,... BUSERR ! 310: // a1,a3,a5,... マスクROM ! 311: // b1 ビットマップ ! 312: // b0/b1 で同様 ! 313: // c1 パレット ! 314: // c0/c1 で同様 ! 315: // d1 CRTC-II ! 316: // d0/d1 で同様 ! 317: // ! 318: // e1 e0..e3 SCSI ! 319: // -- e4..ef 不詳だけど、同じパターンが読めるようだ ! 320: // f1 f0..f3 LANCE ! 321: // -- f4..ff 0xff が読めるようだ ! 322: ! 323: /*static*/ const uint8 ! 324: VM_LUNA::maptable[256] = { ! 325: RAM, NONE, NONE, NONE, // 00 (二重バスフォールト領域は未対応) ! 326: NONE, NONE, NONE, NONE, // 04 ! 327: NONE, NONE, NONE, NONE, // 08 ! 328: NONE, NONE, NONE, NONE, // 0c ! 329: #if 1 ! 330: BUSERR, BUSERR, BUSERR, BUSERR, // 10 ! 331: BUSERR, BUSERR, BUSERR, BUSERR, // 14 ! 332: BUSERR, BUSERR, BUSERR, BUSERR, // 18 ! 333: BUSERR, BUSERR, BUSERR, BUSERR, // 1c ! 334: BUSERR, BUSERR, BUSERR, BUSERR, // 20 ! 335: BUSERR, BUSERR, BUSERR, BUSERR, // 24 ! 336: BUSERR, BUSERR, BUSERR, BUSERR, // 28 ! 337: BUSERR, BUSERR, BUSERR, BUSERR, // 2c ! 338: BUSERR, BUSERR, BUSERR, BUSERR, // 30 ! 339: BUSERR, BUSERR, BUSERR, BUSERR, // 34 ! 340: BUSERR, BUSERR, BUSERR, BUSERR, // 38 ! 341: BUSERR, BUSERR, BUSERR, BUSERR, // 3c ! 342: ! 343: PROM, PROM, PROM, PROM, // 40 ! 344: #else ! 345: // ROM が搭載メモリ量を調べる際の終了条件はここでいう NONE デバイス ! 346: // なので、256MB(-32KB) 以上実装する場合は少なくとも実装メモリの直後を ! 347: // NONE にしておく必要がある。 ! 348: NONE, NONE, NONE, NONE, // 10 ! 349: NONE, NONE, NONE, NONE, // 14 ! 350: NONE, NONE, NONE, NONE, // 18 ! 351: NONE, NONE, NONE, NONE, // 1c ! 352: NONE, NONE, NONE, NONE, // 20 ! 353: NONE, NONE, NONE, NONE, // 24 ! 354: NONE, NONE, NONE, NONE, // 28 ! 355: NONE, NONE, NONE, NONE, // 2c ! 356: NONE, NONE, NONE, NONE, // 30 ! 357: NONE, NONE, NONE, NONE, // 34 ! 358: NONE, NONE, NONE, NONE, // 38 ! 359: NONE, NONE, NONE, NONE, // 3c ! 360: ! 361: NONE, PROM, PROM, PROM, // 40 ! 362: #endif ! 363: MK48, MK48, MK48, MK48, // 44 ! 364: PIO0, PIO0, PIO0, PIO0, // 48 ! 365: PIO1, PIO1, PIO1, PIO1, // 4c ! 366: SIO, SIO, SIO, SIO, // 50 ! 367: NONE, NONE, NONE, NONE, // 54 ! 368: NONE, NONE, NONE, NONE, // 58 ! 369: NONE, NONE, NONE, NONE, // 5c ! 370: TAS, TAS, SYSCLK, SYSCLK, // 60 ! 371: NONE, NONE, NONE, NONE, // 64 ! 372: NONE, NONE, NONE, NONE, // 68 ! 373: NONE, NONE, NONE, NONE, // 6c ! 374: ZRAM, ZRAM, ZRAM, ZRAM, // 70 ! 375: ZRAM, ZRAM, ZRAM, ZRAM, // 74 ! 376: ZRAM, ZRAM, ZRAM, ZRAM, // 78 ! 377: ZRAM, ZRAM, ZRAM, ZRAM, // 7c ! 378: ! 379: BUSERR, BUSERR, BUSERR, BUSERR, // 80 ! 380: BUSERR, BUSERR, BUSERR, BUSERR, // 84 ! 381: BUSERR, BUSERR, BUSERR, BUSERR, // 88 ! 382: BUSERR, BUSERR, BUSERR, BUSERR, // 8c ! 383: NONE, NONE, NONE, NONE, // 90 ! 384: NONE, NONE, NONE, NONE, // 94 ! 385: NONE, NONE, NONE, NONE, // 98 ! 386: NONE, NONE, NONE, NONE, // 9c ! 387: BUSERR, MROM, BUSERR, MROM, // a0 ! 388: BUSERR, MROM, BUSERR, MROM, // a4 ! 389: BUSERR, MROM, BUSERR, MROM, // a8 ! 390: BUSERR, MROM, BUSERR, MROM, // ac ! 391: BUSERR, BITMAP, BUSERR, BITMAP, // b0 ! 392: BUSERR, BITMAP, BUSERR, BITMAP, // b4 ! 393: BUSERR, BITMAP, BUSERR, BITMAP, // b8 ! 394: BUSERR, BITMAP, BUSERR, BITMAP, // bc ! 395: ! 396: BUSERR, BT454, BUSERR, BT454, // c0 ! 397: BUSERR, BT454, BUSERR, BT454, // c4 ! 398: BUSERR, BT454, BUSERR, BT454, // c8 ! 399: BUSERR, BT454, BUSERR, BT454, // cc ! 400: BUSERR, CRTC2, BUSERR, CRTC2, // d0 ! 401: BUSERR, CRTC2, BUSERR, CRTC2, // d4 ! 402: BUSERR, CRTC2, BUSERR, CRTC2, // d8 ! 403: BUSERR, CRTC2, BUSERR, CRTC2, // dc ! 404: SCSI, SCSI, SCSI, SCSI, // e0 ! 405: NONE, NONE, NONE, NONE, // e4 ! 406: NONE, NONE, NONE, NONE, // e8 ! 407: NONE, NONE, NONE, NONE, // ec ! 408: LANCE, LANCE, LANCE, LANCE, // f0 ! 409: NONE, NONE, NONE, NONE, // f4 ! 410: NONE, NONE, NONE, NONE, // f8 ! 411: NONE, NONE, NONE, NONE, // fc ! 412: }; ! 413: ! 414: ! 415: // ! 416: // RXZ .r .x .z human68k console emulator ! 417: // ! 418: ! 419: // コンストラクタ ! 420: VM_RXZ::VM_RXZ(const char *file, const char *arg) ! 421: : VM(TYPE_RXZ) ! 422: { ! 423: // デバイス (順序に注意) ! 424: // Scheduler (と BusErrDevice) は親コンストラクタで作成済み。 ! 425: gMPU = new MPUDevice(0); ! 426: gRAM = new RAMDevice(); // required by Human68k ! 427: gRTC = new RP5C15Device(); ! 428: human68k = new Human68k(file, arg); ! 429: } ! 430: ! 431: // デストラクタ ! 432: VM_RXZ::~VM_RXZ() ! 433: { ! 434: } ! 435: ! 436: void ! 437: VM_RXZ::PowerButton() ! 438: { ! 439: // RXZ の電源ボタンは電源オンにしか使わない。 ! 440: // ! 441: // 電源 ボタン ! 442: // ON PUSH (何も起きない) ! 443: // OFF PUSH 電源オン ! 444: ! 445: // デバイスに指示 ! 446: DevicePowerOn(); ! 447: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.