--- nono/vm/romemu_luna88k.cpp 2026/04/29 17:04:32 1.1.1.1 +++ nono/vm/romemu_luna88k.cpp 2026/04/29 17:04:45 1.1.1.3 @@ -1,13 +1,25 @@ // // nono -// Copyright (C) 2020 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // +// LUNA88K の ROM エミュレーション + +// IODevice +// | +// +----------+----------+ +// v v +// ROMDevice Luna88KPROMEmuDeivce (ROM エミュレーション) +// | +// v +// PROMDevice (実ROM) + +#include "romemu_luna88k.h" #include "aout.h" #include "bt454.h" #include "mainapp.h" #include "memorystream.h" -#include "romemu_luna88k.h" #include "ram.h" #include "spc.h" @@ -15,22 +27,21 @@ Luna88kPROMEmuDevice::Luna88kPROMEmuDevice() { devaddr = baseaddr; - mask = 1024 - 1; // サイズは適当 - mem = new uint8 [mask + 1]; + devlen = 256 * 1024; + + romdatalen = 1024; // サイズは適当 + romdata.reset(new uint8 [romdatalen]); } // デストラクタ Luna88kPROMEmuDevice::~Luna88kPROMEmuDevice() { - if (mem) { - delete[] mem; - } } bool Luna88kPROMEmuDevice::Init() { - MemoryStreamBE ms(mem); + MemoryStreamBE ms(romdata.get()); // リセットベクタは本来2ワードだけだが他のベクタは使わないので // 直接コードを書く。 @@ -54,10 +65,41 @@ Luna88kPROMEmuDevice::ResetHard() inline uint64 Luna88kPROMEmuDevice::Decoder(uint32 addr) const { + // 折り返しなし return addr - baseaddr; } uint64 +Luna88kPROMEmuDevice::Read8(uint32 addr) +{ + // LUNA88K で Read8 呼ばれるんだっけ? + + uint64 offset = Decoder(addr) & (devlen - 1); + + // 謎の IO 空間は(ロング)ワードアクセスのみ + if (offset < romdatalen) { + return romdata[offset]; + } else { + return 0xff; + } +} + +uint64 +Luna88kPROMEmuDevice::Read16(uint32 addr) +{ + // LUNA88K で Read16 呼ばれるんだっけ? + + uint64 offset = Decoder(addr) & (devlen - 1); + + // 謎の IO 空間は(ロング)ワードアクセスのみ + if (offset < romdatalen) { + return be16toh(*(uint16 *)(&romdata[offset])); + } else { + return 0xffff; + } +} + +uint64 Luna88kPROMEmuDevice::Read32(uint32 addr) { uint64 offset = Decoder(addr); @@ -68,11 +110,44 @@ Luna88kPROMEmuDevice::Read32(uint32 addr if (!ipl_done) return IPL(); break; - default: - break; } - return inherited::Read32(addr); + offset &= (devlen - 1); + if (offset < romdatalen) { + return be32toh(*(uint32 *)(&romdata[offset])); + } else { + return 0xffffffff; + } +} + +uint64 +Luna88kPROMEmuDevice::Write8(uint32 addr, uint32 data) +{ + return 0; +} + +uint64 +Luna88kPROMEmuDevice::Write16(uint32 addr, uint32 data) +{ + return 0; +} + +uint64 +Luna88kPROMEmuDevice::Write32(uint32 addr, uint32 data) +{ + return 0; +} + +uint64 +Luna88kPROMEmuDevice::Peek8(uint32 addr) +{ + uint64 offset = Decoder(addr) & (devlen - 1); + + if (offset < romdatalen) { + return romdata[offset]; + } else { + return 0xff; + } } // 起動時の処理を行う。 @@ -108,11 +183,18 @@ Luna88kPROMEmuDevice::IPL() gRAM->Write32(0x00001400, 0xfc001000); // internal inst putc gRAM->Write32(0x00001404, 0xf400c001); // jmp r1 + // XXX このへん romemu_luna と同じところは共通化したほうがいい + // 初期パレット - gBT454->Write8(0, 14 << 4); // select palette - gBT454->Write8(1, 15 << 4); // R=15 - gBT454->Write8(1, 15 << 4); // G=15 - gBT454->Write8(1, 15 << 4); // B=15 + // 偶数番は白(R/G/B=15/15/15)、奇数番は黒(0/0/0)。 + uint8 val = 0xf0; + gBT454->Write8(0, 0); // select palette + for (int i = 0; i < 16; i++) { + gBT454->Write8(1, val); // R + gBT454->Write8(1, val); // G + gBT454->Write8(1, val); // B + val ^= 0xf0; + } // SCSI // BDID の書き込みによってホストデバイスがバスにアタッチされる構造なので。 @@ -122,6 +204,10 @@ Luna88kPROMEmuDevice::IPL() // ホストのファイルを読み込んでエントリポイントアドレスを // この Read アクセスの読み出し値として返す。 entry = gRAM->LoadFile(gMainApp.host_file, AOUT_MID_M88K); + if (entry == 0) { + // XXX まだコンソールがなくて停止できないのでとりあえず終了 + exit(1); + } } return entry;