--- nono/vm/vm_x68k.cpp 2026/04/29 17:04:32 1.1 +++ nono/vm/vm_x68k.cpp 2026/04/29 17:05:20 1.1.1.11 @@ -1,37 +1,66 @@ // // nono -// Copyright (C) 2020 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt +// + +// +// VM (X68030) // #include "vm_x68k.h" +#include "config.h" +#include "dmac.h" +#include "extram.h" +#include "fdc.h" #include "human68k.h" +#include "interrupt.h" +#include "mainapp.h" +#include "mainbus.h" +#include "mfp.h" +#include "mpu680x0.h" +#include "nmi.h" +#include "pedec.h" +#include "pluto.h" +#include "pio.h" +#include "power.h" #include "renderer.h" #include "rp5c15.h" +#include "romimg_x68k.h" #include "scheduler.h" +#include "spc.h" +#include "x68kio.h" #include "x68kkbd.h" -#include "xiospace.h" - -// -// X68030 VM -// // コンストラクタ VM_X68030::VM_X68030() { + // 機種固有パラメータ + // MPU クロックの初期値は機種ごとに異なる。単位は MHz + gConfig->SetDefault("mpu-clock", 25); + // RAM 初期値は MAX にしておく + gConfig->SetDefault("ram-size", 12); + // SPC の入力クロック (5MHz = 200ns) + gConfig->Add("!spc-tCLF", 200); + // デバイス (順序に注意) - // Scheduler (と BusErrDevice) は親コンストラクタで作成済み。 - gMPU.reset(new MPU680x0Device(0xff0000)); - gRAM.reset(new RAMDevice()); // required by XIOSpace - xiospace.reset(new XIOSpaceDevice()); - - gKeyboard.reset(new X68030Keyboard()); - gRenderer.reset(new X68030Renderer()); - - // 割り当て - // 今は拡張メモリがないので、今は上位8ビット全領域がミラーになっている。 - for (int i = 0; i < countof(::devtable); i++) { - ::devtable[i] = xiospace.get(); + // BusErrDevice は親コンストラクタで作成済み。 + NEWDV(MPU, new MPU680x0Device()); + NEWDV(Interrupt, new X68030Interrupt()); + NEWDV(MainRAM, new MainRAMDevice()); // req. by X68kIO,Human68k + NEWDV(X68kIO, new X68kIODevice()); + NEWDV(IPLROM0, new IPLROM0Device()); + NEWDV(ExtRAM, new ExtRAMDevice()); + + NEWDV(NMI, new NMIDevice()); + NEWDV(Keyboard, new X68030Keyboard()); + NEWDV(Renderer, new X68030Renderer()); + + if (gMainApp.human_mode) { + NEWDV(Human68k, new Human68k()); } + + // デバイスの割り当ては Init() で行っている。 } // デストラクタ @@ -39,53 +68,115 @@ VM_X68030::~VM_X68030() { } -// X68030 の電源ボタンを押します。 -void -VM_X68030::PowerButton() +bool +VM_X68030::Init() { - // 電源 ボタン - // ON OFF->ON 電源オフ割り込みをネゲート? - // ON ON ->OFF 電源オフ割り込みをアサート? - // OFF OFF->ON 電源オン - // OFF ON ->OFF (通常はあり得ないはず) + if (inherited::Init() == false) { + return false; + } - // ボタンの状態を更新して.. - power_button = !power_button; + // 拡張メモリのサイズが確定したので、ここで配置。 + auto mainbus = dynamic_cast(pMainbus.get()); + auto xiospace = dynamic_cast(pX68kIO.get()); + auto extram = dynamic_cast(pExtRAM.get()); + int extsize = extram->GetSizeMB(); + + // 上位8ビット全域を一旦全部ミラーで埋めてから + for (int i = 0; i < mainbus->devtable.size(); i++) { + mainbus->SetDevice(i, xiospace); + } + if (extsize == 16) { + // TS-6BE16 互換 (16MB) なら、 + // $01: ExtRAM + mainbus->SetDevice(1, extram); + } else { + // 060turbo 互換。とりあえず 128MB/256MB のみ。この場合は + // $10..$17: ExtRAM (128MB) + // $18..$1f: ExtRAM (256MB) + for (int i = 0x10, end = i + (extsize / 16); i < end; i++) { + mainbus->SetDevice(i, extram); + } + } - // デバイスに指示 - DevicePowerOn(); + return true; } - -// -// RXZ .r .x .z human68k console emulator -// - -// コンストラクタ -VM_RXZ::VM_RXZ() +// ブートページを切り替える。 +void +VM_X68030::SwitchBootPage(Device *parent, bool isrom) { - // デバイス (順序に注意) - // Scheduler (と BusErrDevice) は親コンストラクタで作成済み。 - gMPU.reset(new MPU680x0Device(0)); - gRAM.reset(new RAMDevice()); // required by Human68k - gRTC.reset(new RP5C15Device()); - human68k.reset(new Human68k()); -} + if (gMainApp.human_mode) { + // Human モードではブートページを RAM に見せる。 + // 今のところ。 + return; + } -// デストラクタ -VM_RXZ::~VM_RXZ() -{ -} + // 共通処理 + inherited::SwitchBootPage(parent, isrom); + // X68030 では X68kIO が担当している + auto xiospace = dynamic_cast(pX68kIO.get()); + xiospace->SwitchBootPage(isrom); +} + +// リセットについて +// +// PWRRESET +// 電源オン ----------+--> VIPS +// (7505) +--> VideoCtlr +// +--> OSCIAN2 +// | +// | +------+ +// +-->| | +// 本体 SWRESET | YUKI | +// リセット ------------->| | +// スイッチ +------+ +// | IPLRESET +// | +// +--> FPU +// | +// ▽ +// RESET | +// |<-> MPU (68030) +// +--> PPI (8255) +// +--> SPC (MB89352) +// +--> ADPCM (MSM6258) +// +--> FDC (uPD72065B) +// +--> MFP (MC68901) +// | +// | +-------+ +// +-->| PEDEC | +// | +-------+ +// | | +// | +-- OPMIC -----> OPM(YM2151) +// | +-- SCCRD/WR --> SCC(Z8530) +// | +// | EXRESET +// +---|>-----------> 外部バス +// ▽ +// SYSRESET | +// |<-> SAKI ---+ +// | | BEC0,BEC1 +// +--> DMAC <--+ +// +--> CYNTHIA +// リセットされない? +// o CACHY + +// MPU の RESET 命令によるリセット void -VM_RXZ::PowerButton() +VM_X68030::ResetByMPU() { - // RXZ の電源ボタンは電源オンにしか使わない。 - // - // 電源 ボタン - // ON PUSH (何も起きない) - // OFF PUSH 電源オン - - // デバイスに指示 - DevicePowerOn(); + std::vector ids { + OBJ_DMAC, + OBJ_FDC, + OBJ_MFP, + OBJ_PEDEC, + OBJ_PLUTO, + OBJ_PPI, + OBJ_SPC, + }; + for (auto id : ids) { + auto dev = gMainApp.GetObject(id); + dev->ResetHard(false); + } }