|
|
1.1 root 1: //
2: // nono
1.1.1.2 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.8 root 7: //
8: // VM (X68030)
9: //
10:
1.1 root 11: #include "vm_x68k.h"
1.1.1.2 root 12: #include "config.h"
1.1.1.5 root 13: #include "dmac.h"
1.1.1.10! root 14: #include "extram.h"
1.1.1.5 root 15: #include "fdc.h"
1.1 root 16: #include "human68k.h"
1.1.1.4 root 17: #include "interrupt.h"
1.1.1.7 root 18: #include "mainapp.h"
1.1.1.10! root 19: #include "mainbus.h"
1.1.1.5 root 20: #include "mfp.h"
1.1.1.2 root 21: #include "mpu680x0.h"
1.1.1.8 root 22: #include "nmi.h"
1.1.1.5 root 23: #include "pedec.h"
24: #include "pluto.h"
25: #include "pio.h"
1.1.1.8 root 26: #include "power.h"
1.1 root 27: #include "renderer.h"
28: #include "rp5c15.h"
1.1.1.6 root 29: #include "romimg_x68k.h"
1.1 root 30: #include "scheduler.h"
1.1.1.5 root 31: #include "spc.h"
1.1.1.10! root 32: #include "x68kio.h"
1.1 root 33: #include "x68kkbd.h"
34:
35: // コンストラクタ
36: VM_X68030::VM_X68030()
37: {
1.1.1.2 root 38: // 機種固有パラメータ
39: // MPU クロックの初期値は機種ごとに異なる。単位は MHz
40: gConfig->SetDefault("mpu-clock", 25);
41: // RAM 初期値は MAX にしておく
42: gConfig->SetDefault("ram-size", 12);
43: // SPC の入力クロック (5MHz = 200ns)
44: gConfig->Add("!spc-tCLF", 200);
45:
1.1 root 46: // デバイス (順序に注意)
1.1.1.2 root 47: // BusErrDevice は親コンストラクタで作成済み。
1.1.1.8 root 48: NEWDV(MPU, new MPU680x0Device());
49: NEWDV(Interrupt, new X68030Interrupt());
1.1.1.10! root 50: NEWDV(MainRAM, new MainRAMDevice()); // req. by X68kIO,Human68k
! 51: NEWDV(X68kIO, new X68kIODevice());
1.1.1.8 root 52: NEWDV(IPLROM0, new IPLROM0Device());
1.1.1.10! root 53: NEWDV(ExtRAM, new ExtRAMDevice());
1.1.1.8 root 54:
55: NEWDV(NMI, new NMIDevice());
56: NEWDV(Keyboard, new X68030Keyboard());
57: NEWDV(Renderer, new X68030Renderer());
1.1 root 58:
1.1.1.7 root 59: if (gMainApp.human_mode) {
1.1.1.8 root 60: NEWDV(Human68k, new Human68k());
1.1.1.7 root 61: }
62:
1.1.1.10! root 63: // デバイスの割り当ては Init() で行っている。
1.1 root 64: }
65:
66: // デストラクタ
67: VM_X68030::~VM_X68030()
68: {
69: }
70:
1.1.1.10! root 71: bool
! 72: VM_X68030::Init()
! 73: {
! 74: if (inherited::Init() == false) {
! 75: return false;
! 76: }
! 77:
! 78: // 拡張メモリのサイズが確定したので、ここで配置。
! 79: auto mainbus = dynamic_cast<MainbusDevice *>(pMainbus.get());
! 80: auto xiospace = dynamic_cast<X68kIODevice *>(pX68kIO.get());
! 81: auto extram = dynamic_cast<ExtRAMDevice *>(pExtRAM.get());
! 82: int extsize = extram->GetSizeMB();
! 83:
! 84: if (extsize == 0) {
! 85: // 拡張メモリがない場合は、上位8ビット全域がミラーになる。
! 86: for (int i = 0; i < mainbus->devtable.size(); i++) {
! 87: mainbus->SetDevice(i, xiospace);
! 88: }
! 89: } else if (extsize == 16) {
! 90: // TS-6BE16 互換 (16MB) なら、
! 91: // $00: X68kIO
! 92: // $01: ExtRAM
! 93: // で、その後ろは?
! 94: mainbus->SetDevice(0, xiospace);
! 95: mainbus->SetDevice(1, extram);
! 96: for (int i = 2; i < mainbus->devtable.size(); i++) {
! 97: mainbus->SetDevice(i, pBusErr.get());
! 98: }
! 99: } else {
! 100: // 060turbo 互換。とりあえず 128MB/256MB のみ。この場合は
! 101: // $00: X68kIO
! 102: // $01..$0f: BusErr?
! 103: // $10..$17: ExtRAM (128MB)
! 104: // $18..$1f: ExtRAM (256MB)
! 105: // で、その後ろは?
! 106: mainbus->SetDevice(0, xiospace);
! 107: for (int i = 1; i < mainbus->devtable.size(); i++) {
! 108: mainbus->SetDevice(i, pBusErr.get());
! 109: }
! 110: for (int i = 0x10, end = i + (extsize / 16); i < end; i++) {
! 111: mainbus->SetDevice(i, extram);
! 112: }
! 113: }
! 114:
! 115: return true;
! 116: }
! 117:
1.1.1.6 root 118: // ブートページを切り替える。
119: void
120: VM_X68030::SwitchBootPage(Device *parent, bool isrom)
121: {
1.1.1.7 root 122: if (gMainApp.human_mode) {
123: // Human モードではブートページを RAM に見せる。
124: // 今のところ。
125: return;
126: }
127:
1.1.1.6 root 128: // 共通処理
129: inherited::SwitchBootPage(parent, isrom);
130:
1.1.1.10! root 131: // X68030 では X68kIO が担当している
! 132: auto xiospace = dynamic_cast<X68kIODevice *>(pX68kIO.get());
! 133: xiospace->SwitchBootPage(isrom);
1.1 root 134: }
135:
1.1.1.5 root 136: // リセットについて
137: //
138: // PWRRESET
139: // 電源オン ----------+--> VIPS
140: // (7505) +--> VideoCtlr
141: // +--> OSCIAN2
142: // |
143: // | +------+
144: // +-->| |
1.1.1.9 root 145: // 本体 SWRESET | YUKI |
146: // リセット ------------->| |
1.1.1.5 root 147: // スイッチ +------+
1.1.1.9 root 148: // | IPLRESET
149: // |
150: // +--> FPU
1.1.1.5 root 151: // |
152: // ▽
153: // RESET |
154: // |<-> MPU (68030)
1.1.1.9 root 155: // +--> PPI (8255)
156: // +--> SPC (MB89352)
157: // +--> ADPCM (MSM6258)
158: // +--> FDC (uPD72065B)
159: // +--> MFP (MC68901)
160: // |
161: // | +-------+
162: // +-->| PEDEC |
163: // | +-------+
164: // | |
165: // | +-- OPMIC -----> OPM(YM2151)
166: // | +-- SCCRD/WR --> SCC(Z8530)
1.1.1.5 root 167: // |
168: // | EXRESET
169: // +---|>-----------> 外部バス
170: // ▽
171: // SYSRESET |
172: // |<-> SAKI ---+
173: // | | BEC0,BEC1
174: // +--> DMAC <--+
175: // +--> CYNTHIA
176: // リセットされない?
177: // o CACHY
178:
179: // MPU の RESET 命令によるリセット
180: void
181: VM_X68030::ResetByMPU()
182: {
1.1.1.10! root 183: std::vector<int> ids {
! 184: OBJ_DMAC,
! 185: OBJ_FDC,
! 186: OBJ_MFP,
! 187: OBJ_PEDEC,
! 188: OBJ_PLUTO,
! 189: OBJ_PPI,
! 190: OBJ_SPC,
! 191: };
! 192: for (auto id : ids) {
! 193: auto dev = gMainApp.GetObject<IODevice>(id);
! 194: dev->ResetHard(false);
! 195: }
1.1.1.5 root 196: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.