--- nono/vm/human68k.cpp 2026/04/29 17:05:18 1.1.1.11 +++ nono/vm/human68k.cpp 2026/04/29 17:05:25 1.1.1.12 @@ -25,6 +25,7 @@ #include "iodevstream.h" #include "mainapp.h" #include "mainbus.h" +#include "mainram.h" #include "mpu680x0.h" #include "power.h" #include "scheduler.h" @@ -34,17 +35,13 @@ static bool human68k_fline_callback(MPU680x0Device *, void *arg); -#define RegD(n) mpu->reg.D[n] -#define RegA(n) mpu->reg.A[n] +#define RegD(n) mpu680x0->reg.D[n] +#define RegA(n) mpu680x0->reg.A[n] // コンストラクタ -Human68k::Human68k() +Human68kDevice::Human68kDevice() : inherited(OBJ_HUMAN68K) { - assert(gMainApp.exec_file); - human68k_file = gMainApp.exec_file; - human68k_arg = gMainApp.exec_arg; - Files[0].fd = 0; Files[0].filename = "|stdin"; Files[1].fd = 1; @@ -54,13 +51,13 @@ Human68k::Human68k() } // デストラクタ -Human68k::~Human68k() +Human68kDevice::~Human68kDevice() { } // 初期化 bool -Human68k::Init() +Human68kDevice::Init() { bool r; uint32 psp_base; @@ -70,17 +67,22 @@ Human68k::Init() return false; } + assert(gMainApp.exec_file); + human68k_file = gMainApp.exec_file; + human68k_arg = gMainApp.exec_arg; + + mainbus = GetMainbusDevice(); ram = GetMainRAMDevice(); - mpu = GetMPU680x0Device(); + mpu680x0 = GetMPU680x0Device(mpu); // Fライン命令をこちらで処理する - mpu->SetFLineCallback(human68k_fline_callback, this); + mpu680x0->SetFLineCallback(human68k_fline_callback, this); // ワークを用意 (どこでやるか) // $CBC.B MPU 種別 (3:68030) ram->Write8(0x0cbc, 3); // $CBD.B FPU 有無 (0xff:あり) - if (mpu->HaveFPU()) { + if (mpu680x0->HaveFPU()) { ram->Write8(0x0cbd, 0xff); } @@ -210,7 +212,7 @@ Human68k::Init() } bool -Human68k::LoadR(uint8 *file, uint size) +Human68kDevice::LoadR(uint8 *file, uint size) { // リロケータブルなのでどこでもいい load_addr = default_load_addr; @@ -225,7 +227,7 @@ Human68k::LoadR(uint8 *file, uint size) } bool -Human68k::LoadX(uint8 *file, uint size) +Human68kDevice::LoadX(uint8 *file, uint size) { XFileHeader *hdr = (XFileHeader *)file; uint hdr_size = sizeof(*hdr); @@ -288,7 +290,7 @@ Human68k::LoadX(uint8 *file, uint size) } bool -Human68k::LoadZ(uint8 *file, uint size) +Human68kDevice::LoadZ(uint8 *file, uint size) { ZFileHeader *hdr = (ZFileHeader *)file; uint32 hdr_size = sizeof(*hdr); @@ -316,10 +318,10 @@ Human68k::LoadZ(uint8 *file, uint size) // なぜか m68k ELF .o が読める bool -Human68k::LoadELF(uint8 *file, uint size) +Human68kDevice::LoadELF(uint8 *file, uint size) { LoadInfo info(human68k_file, file, size); - if (ram->LoadFromData(&info) == false) { + if (ram->LoadExec(&info) == false) { return false; } @@ -333,7 +335,7 @@ Human68k::LoadELF(uint8 *file, uint size } bool -Human68k::LoadMem(uint32 addr, uint8 *src, uint size) +Human68kDevice::LoadMem(uint32 addr, uint8 *src, uint size) { if (addr + size >= ram->GetSize()) { errx(EXIT_FAILURE, "file too large"); @@ -348,7 +350,7 @@ Human68k::LoadMem(uint32 addr, uint8 *sr // file の拡張子が ext なら true を返す。ext は '.' を含む。 bool -Human68k::isext(const char *file, const char *ext) +Human68kDevice::isext(const char *file, const char *ext) { size_t len_file = strlen(file); size_t len_ext = strlen(ext); @@ -367,11 +369,11 @@ Human68k::isext(const char *file, const // (MSXDOSDevice からも終了時に呼ぶ) // XXX code は未対応。 /*static*/ void -Human68k::RequestExit(int code) +Human68kDevice::RequestExit(int code) { // 電源を即切る auto power = GetPowerDevice(); - power->PowerButton(); + power->PushPowerButton(); power->SetSystemPowerOn(false); } @@ -380,12 +382,12 @@ Human68k::RequestExit(int code) // mode: unix open mode // return: Human68k fileno int32 -Human68k::OpenFile(uint32 fileaddr, uint16 atr, int mode) +Human68kDevice::OpenFile(uint32 fileaddr, uint16 atr, int mode) { // XXX: unix host only int32 fileno {}; - Human68k::File *f = NULL; + Human68kDevice::File *f = NULL; // 開いているエントリを検索して Human fileno を取得 for (int i = 0; i < FilesCount; i++) { @@ -433,9 +435,9 @@ Human68k::OpenFile(uint32 fileaddr, uint // fileno: Human68k fileno int32 -Human68k::CloseFile(int32 fileno) +Human68kDevice::CloseFile(int32 fileno) { - Human68k::File *f; + Human68kDevice::File *f; if (fileno <= 0 || fileno >= FilesCount) { warnx("CloseFile: unopened fileno=%d", fileno); @@ -456,9 +458,9 @@ Human68k::CloseFile(int32 fileno) // dataaddr: data addr (guest VA) // size: data length int32 -Human68k::WriteFile(int32 fileno, uint32 dataaddr, uint32 size) +Human68kDevice::WriteFile(int32 fileno, uint32 dataaddr, uint32 size) { - Human68k::File *f; + Human68kDevice::File *f; if (fileno <= 0 || fileno >= FilesCount) { warnx("WriteFile: unopened fileno=%d", fileno); @@ -483,9 +485,9 @@ Human68k::WriteFile(int32 fileno, uint32 // fileno: Human68k fileno // dataaddr: data addr (guest VA) void -Human68k::FputsFile(int32 fileno, uint32 dataaddr) +Human68kDevice::FputsFile(int32 fileno, uint32 dataaddr) { - Human68k::File *f; + Human68kDevice::File *f; if (fileno <= 0 || fileno >= FilesCount) { return; @@ -521,9 +523,9 @@ Human68k::FputsFile(int32 fileno, uint32 // Human68k DOSCALL Host Emulation void -Human68k::IOCS() +Human68kDevice::IOCS() { - // XXX mpu->{read,write}_*() はアクセス中にバスエラーが起きると + // XXX mpu680x0->{read,write}_*() はアクセス中にバスエラーが起きると // C++ 例外をスローするので本当は catch しなければいけない。 switch (RegD(0) & 0xff) { @@ -546,7 +548,7 @@ Human68k::IOCS() } case 0x82: // _B_BPEEK { - uint32 data = mpu->read_8(RegA(1)); + uint32 data = mainbus->HVRead8(RegA(1)); RegD(0) = (RegD(0) & 0xffffff00) | data; RegA(1)++; break; @@ -557,7 +559,7 @@ Human68k::IOCS() // MPU 状態の取得 RegD(0) = ((250) << 16) // 25.0MHz - | ((mpu->HaveFPU() ? 1 : 0) << 15) // FPU + | ((mpu680x0->HaveFPU() ? 1 : 0) << 15) // FPU | ((0) << 14) // MMU | ((3) << 0); // MPU Type break; @@ -593,15 +595,15 @@ Human68k::IOCS() bool human68k_fline_callback(MPU680x0Device *, void *arg) { - auto *human68k = (Human68k *)arg; + auto *human68k = (Human68kDevice *)arg; return human68k->FLineOp(); } // F-Line 命令 bool -Human68k::FLineOp() +Human68kDevice::FLineOp() { - switch (mpu->GetIR()) { + switch (mpu680x0->GetIR()) { case 0xf600: // IOCS call emulation IOCS(); break; @@ -610,40 +612,40 @@ Human68k::FLineOp() putmsg(1, "DOS EXIT"); // XXX CPU の実行を止める。方式自体を I/O 方式に見直したときには // ちゃんとした方法を取る予定。 - mpu->SetSR(mpu->GetSR() | 0x2000); - mpu->reg.pc = 0x1010; + mpu680x0->SetSR(mpu680x0->GetSR() | 0x2000); + mpu680x0->reg.pc = 0x1010; RequestExit(0); break; case 0xff09: // PRINT { - uint32 dataptr = mpu->read_32(RegA(7)); + uint32 dataptr = mainbus->HVRead32(RegA(7)); DOS_PRINT(dataptr); break; } case 0xff1e: // FPUTS { - uint32 mesptr = mpu->read_32(RegA(7)); - uint16 fileno = mpu->read_16(RegA(7) + 4); + uint32 mesptr = mainbus->HVRead32(RegA(7)); + uint16 fileno = mainbus->HVRead16(RegA(7) + 4); FputsFile(fileno, mesptr); break; } case 0xff20: // SUPER { - uint32 data = mpu->read_32(RegA(7)); + uint32 data = mainbus->HVRead32(RegA(7)); if (data == 0) { - mpu->SetSR(mpu->GetSR() | 0x2000); - data = mpu->reg.usp; + mpu680x0->SetSR(mpu680x0->GetSR() | 0x2000); + data = mpu680x0->reg.usp; RegD(0) = RegA(7); RegA(7) = data; putmsg(1, "SUPERVISOR MODE"); } else { - mpu->SetSR(mpu->GetSR() | 0x2000); + mpu680x0->SetSR(mpu680x0->GetSR() | 0x2000); RegA(7) = data; - mpu->SetSR(mpu->GetSR() & ~0x2000); + mpu680x0->SetSR(mpu680x0->GetSR() & ~0x2000); putmsg(1, "USER MODE"); } break; @@ -651,18 +653,18 @@ Human68k::FLineOp() case 0xff25: // INTVCS { - uint16 intno = mpu->read_16(RegA(7)); - uint32 addr = mpu->read_32(RegA(7) + 2); + uint16 intno = mainbus->HVRead16(RegA(7)); + uint32 addr = mainbus->HVRead32(RegA(7) + 2); uint32 vecaddr = (intno & 0xff) * 4; if (intno <= 0xff) { - RegD(0) = mpu->read_32(vecaddr); - mpu->write_32(vecaddr, addr); + RegD(0) = mainbus->HVRead32(vecaddr); + mainbus->HVWrite32(vecaddr, addr); } else { vecaddr += 0xd000; - RegD(0) = mpu->read_32(vecaddr); - mpu->write_32(vecaddr, addr); + RegD(0) = mainbus->HVRead32(vecaddr); + mainbus->HVWrite32(vecaddr, addr); } break; } @@ -689,23 +691,23 @@ Human68k::FLineOp() case 0xff35: // INTVCG { - uint16 intno = mpu->read_16(RegA(7)); + uint16 intno = mainbus->HVRead16(RegA(7)); uint32 vecaddr = (intno & 0xff) * 4; if (intno <= 0xff) { - RegD(0) = mpu->read_32(vecaddr); + RegD(0) = mainbus->HVRead32(vecaddr); } else { vecaddr += 0xd000; - RegD(0) = mpu->read_32(vecaddr); + RegD(0) = mainbus->HVRead32(vecaddr); } break; } case 0xff3c: // CREATE { - uint32 file = mpu->read_32(RegA(7)); - uint16 atr = mpu->read_32(RegA(7) + 4); + uint32 file = mainbus->HVRead32(RegA(7)); + uint16 atr = mainbus->HVRead32(RegA(7) + 4); int32 fileno = OpenFile(file, atr, O_CREAT | O_TRUNC | O_RDWR | O_SYNC); @@ -715,7 +717,7 @@ Human68k::FLineOp() case 0xff3e: // CLOSE { - uint16 fileno = mpu->read_16(RegA(7)); + uint16 fileno = mainbus->HVRead16(RegA(7)); CloseFile(fileno); RegD(0) = 0; @@ -724,10 +726,10 @@ Human68k::FLineOp() case 0xff40: // WRITE { -// putmsg(1, "DOS _WRITE at %08x", mpu->GetPPC()); - uint16 fileno = mpu->read_16(RegA(7)); - uint32 dataptr = mpu->read_32(RegA(7) + 2); - uint32 size = mpu->read_32(RegA(7) + 6); +// putmsg(1, "DOS _WRITE at %08x", mpu680x0->GetPPC()); + uint16 fileno = mainbus->HVRead16(RegA(7)); + uint32 dataptr = mainbus->HVRead32(RegA(7) + 2); + uint32 size = mainbus->HVRead32(RegA(7) + 6); // putmsg(1, "WRITE(%d, 0x%08x, 0x%08x)\n", fileno, dataptr, size); RegD(0) = WriteFile(fileno, dataptr, size); break; @@ -735,11 +737,11 @@ Human68k::FLineOp() case 0xff44: // IOCTRL { - uint32 mode = mpu->read_16(RegA(7)); + uint32 mode = mainbus->HVRead16(RegA(7)); uint32 fileno; switch (mode) { case 0: - fileno = mpu->read_16(RegA(7) + 2); + fileno = mainbus->HVRead16(RegA(7) + 2); putmsg(1, "DOS IOCTRL(mode=%d, fileno=%d)", mode, fileno); if (fileno == 0) { // STDIN RegD(0) = 0x8081; // 100u'uuuu'100u'0001; @@ -762,17 +764,17 @@ Human68k::FLineOp() case 0xff4a: // SETBLOCK { - uint32 memptr = mpu->read_32(RegA(7)); - uint32 len = mpu->read_32(RegA(7) + 4); + uint32 memptr = mainbus->HVRead32(RegA(7)); + uint32 len = mainbus->HVRead32(RegA(7) + 4); putmsg(1, "DOS SETBLOCK(memptr=$%x len=$%x)", memptr, len); // なにもせずに、できたという - RegD(0) = mpu->read_32(RegA(7) + 4); + RegD(0) = mainbus->HVRead32(RegA(7) + 4); break; } case 0xff4c: // EXIT2 { - uint32 data = mpu->read_16(RegA(7)); + uint32 data = mainbus->HVRead16(RegA(7)); putmsg(1, "DOS EXIT2(%d)", data); RequestExit(data); break; @@ -780,7 +782,7 @@ Human68k::FLineOp() case 0xffac: // GETFCB { - uint32 fileno = mpu->read_16(RegA(7)); + uint32 fileno = mainbus->HVRead16(RegA(7)); putmsg(1, "DOS GETFCB(fileno=%d)", fileno); if (fileno <= 4) { RegD(0) = 0x8000 + fileno * 0x60; @@ -792,20 +794,20 @@ Human68k::FLineOp() case 0xfff7: // BUS_ERR { - uint32 p1 = mpu->read_32(RegA(7)); - uint32 p2 = mpu->read_32(RegA(7) + 4); - uint16 size = mpu->read_16(RegA(7) + 8); + uint32 p1 = mainbus->HVRead32(RegA(7)); + uint32 p2 = mainbus->HVRead32(RegA(7) + 4); + uint16 size = mainbus->HVRead16(RegA(7) + 8); putmsg(1, "DOS BUS_ERR(size=%d p1=$%x p2=$%x)", size, p1, p2); RegD(0) = -1; uint32 data; try { if (size == 1) { - data = mpu->read_8(p1); + data = mainbus->HVRead8(p1); } else if (size == 2 && ((p1 & 1) == 0)) { - data = mpu->read_16(p1); + data = mainbus->HVRead16(p1); } else if (size == 4 && ((p1 & 1) == 0)) { - data = mpu->read_32(p1); + data = mainbus->HVRead32(p1); } else { break; } @@ -820,11 +822,11 @@ Human68k::FLineOp() try { if (size == 1) { - mpu->write_8(p2, data); + mainbus->HVWrite8(p2, data); } else if (size == 2 && ((p2 & 1) == 0)) { - mpu->write_16(p2, data); + mainbus->HVWrite16(p2, data); } else if (size == 4 && ((p2 & 1) == 0)) { - mpu->write_32(p2, data); + mainbus->HVWrite32(p2, data); } else { break; } @@ -842,7 +844,7 @@ Human68k::FLineOp() default: printf("DOSCALL $%02x at $%08X (NOT IMPLEMENTED)\n", - mpu->GetIR(), mpu->GetPPC()); + mpu680x0->GetIR(), mpu680x0->GetPPC()); RequestExit(1); break; } @@ -850,10 +852,10 @@ Human68k::FLineOp() } void -Human68k::DOS_PRINT(uint32 dataptr) +Human68kDevice::DOS_PRINT(uint32 dataptr) { int c; - while ((c = mpu->read_8(dataptr++)) != 0) { + while ((c = mainbus->HVRead8(dataptr++)) != 0) { printf("%c", c); } RegD(0) = 0;