--- nono/vm/lance.cpp 2026/04/29 17:05:14 1.1.1.12 +++ nono/vm/lance.cpp 2026/04/29 17:05:17 1.1.1.13 @@ -10,20 +10,20 @@ #include "lance.h" #include "bitops.h" -#include "bus.h" -#include "config.h" #include "interrupt.h" +#include "mainbus.h" #include "scheduler.h" -#include "zram.h" +#include "subram.h" // コンストラクタ LanceDevice::LanceDevice() - : inherited("Lance") + : inherited() { + SetName("Lance"); + ClearAlias(); + AddAlias("Lance"); AddAlias("Ethernet"); - devaddr = 0xf1000000; - // func, time は都度設定する rx_event.Regist("Lance RX"); tx_event.Regist("Lance TX"); @@ -38,35 +38,20 @@ LanceDevice::~LanceDevice() { } +// 初期化 bool LanceDevice::Init() { - // ホストからの受信コールバックを登録 - gScheduler->ConnectMessage(MessageID::HOSTNET_RX, this, - ToMessageCallback(&LanceDevice::HostRxCallback)); + if (inherited::Init() == false) { + return false; + } - const ConfigItem& item = gConfig->Find("ethernet-macaddr"); - const std::string& config_macaddr = item.AsString(); - if (config_macaddr == "rom") { - // ROM に書いてあるのを使うので、ここでは何もしなくていい - } else { - if (config_macaddr == "auto") { - // 自動生成 - // すでに記録されていれば使う。なければ生成して記録したい - if (0) { - } else { - macaddr.Generate(); - } - } else { - // ユーザ指定 - if (macaddr.FromString(config_macaddr) == false) { - item.Err("invalid MAC address"); - return false; - } - } + interrupt = GetInterruptDevice(); + subram = GetSubRAMDevice(); - putmsg(1, "macaddr=%s", macaddr.ToString(':').c_str()); - } + // ホストからの受信コールバックを登録 + scheduler->ConnectMessage(MessageID::HOSTNET_RX, this, + ToMessageCallback(&LanceDevice::HostRxCallback)); return true; } @@ -93,7 +78,8 @@ LanceDevice::Read(uint32 offset) putlog(2, "RAP -> %d", reg.rap); return data; default: - __unreachable(); + VMPANIC("corrupted offset=%d", offset); + return 0xff; } } @@ -108,7 +94,8 @@ LanceDevice::Write(uint32 offset, uint32 reg.rap = data & 3; return 0; default: - __unreachable(); + VMPANIC("corrupted offset=%d", offset); + return 0; } } @@ -129,14 +116,15 @@ LanceDevice::Peek(uint32 offset) case 3: return reg.csr3; default: - __unreachable(); + break; } break; case 1: // RAP return reg.rap; default: - __unreachable(); + break; } + return 0xff; } void @@ -419,7 +407,9 @@ LanceDevice::ReadData() } break; default: - __unreachable(); + VMPANIC("corrupted reg.rap=%d", reg.rap); + data = 0xff; + break; } return data; } @@ -506,7 +496,7 @@ LanceDevice::WriteData(uint32 data) #if 0 // IADR 設定時にパフォーマンス測定用実時間表示 - gScheduler->PutlogRealtime(); + scheduler->PutlogRealtime(); #endif } break; @@ -530,20 +520,20 @@ LanceDevice::WriteData(uint32 data) break; default: - __unreachable(); + VMPANIC("corrupted reg.rap=%d", reg.rap); } } // メモリアクセスについて。 // LANCE(AM7990) から見たメモリは、メインメモリではなく 3ポートSRAM -// (ここでは ZRAM デバイス)。 -// LANCE のメモリバスは 16bit で、DAL15..8 が ZRAM の偶数アドレス、 -// DAL7..0 が ZRAM の奇数アドレスに接続されている。 +// (ここでは SubRAM デバイス)。 +// LANCE のメモリバスは 16bit で、DAL15..8 が SubRAM の偶数アドレス、 +// DAL7..0 が SubRAM の奇数アドレスに接続されている。 // -// LANCE | DAL15..DAL8 | DAL7..DAL0 -// ------+-------------+------------ -// ZRAM | +0 byte | +1 byte -// | +2 byte | +3 byte +// LANCE | DAL15..DAL8 | DAL7..DAL0 +// -------+-------------+------------ +// SubRAM | +0 byte | +1 byte +// | +2 byte | +3 byte // // メモリアクセスは常にこの構成で、CSR3.BSWP はこの1ワードを SILO(FIFO) に // 書き込む/から読み出す順序を入れ替えるもの。 @@ -557,7 +547,7 @@ LanceDevice::ReadMem(uint32 paddr) assertmsg((paddr & 1) == 0, "paddr=$%x", paddr); // XXX 所要クロックを考察すること - data = gZRAM->Read16(paddr); + data = subram->Read16(paddr); return data; } @@ -568,7 +558,7 @@ LanceDevice::WriteMem(uint32 paddr, uint assertmsg((paddr & 1) == 0, "paddr=$%x", paddr); // XXX 所要クロックを考察すること - gZRAM->Write16(paddr, data); + subram->Write16(paddr, data); return 0; } @@ -578,13 +568,9 @@ LanceDevice::PeekMem(uint32 paddr) { uint64 data; - // XXX なんでここ gZRAM->Peek() じゃないんだっけ? - - paddr &= 0x1ffff; - paddr += 0x71000000; // XXX 定数にしたほうがいい + data = subram->Peek8(paddr) << 8; + data |= subram->Peek8(paddr + 1); - data = vm_phys_peek_8(paddr) << 8; - data |= vm_phys_peek_8(paddr + 1); return data; } @@ -717,9 +703,9 @@ void LanceDevice::ChangeInterrupt() { if (reg.IsINTR() && (reg.csr0 & AM7990::CSR0_INEA)) { - gInterrupt->AssertINT(this); + interrupt->AssertINT(this); } else { - gInterrupt->NegateINT(this); + interrupt->NegateINT(this); } } @@ -794,7 +780,7 @@ LanceDevice::TXCopy() uint8 *dst = &tx_packet[tx_packet.length]; tx_packet.length += copycnt; - // ここから、ZRAM からローカルの送信バッファにコピー + // ここから、SubRAM からローカルの送信バッファにコピー // XXX バーストコピー未対応 const uint32 srcend = src + bcnt; const uint8 *dstend = dst + copycnt; @@ -837,7 +823,7 @@ LanceDevice::TXCopy() src += 2; } - // tx_packet が一杯になったら後はディスクリプタが終わるまで ZRAM から + // tx_packet が一杯になったら後はディスクリプタが終わるまで SubRAM から // 読み捨てる。tx_packet の長さに上限があるのはこっち(エミュレータ)の // 都合であって LANCE はディスクリプタが終わるまで延々読み込んでは出力を // 続けるようだ。ここでは同じだけ読み込むところ、それにかかる時間を求める @@ -939,7 +925,7 @@ LanceDevice::ChangePhase(TXPhase new_pha tx_event.time = time; switch (new_phase) { case TXPhase::STOP: - gScheduler->StopEvent(tx_event); + scheduler->StopEvent(tx_event); return; case TXPhase::IDLE: tx_event.func = ToEventCallback(&LanceDevice::TXIdle); @@ -953,7 +939,7 @@ LanceDevice::ChangePhase(TXPhase new_pha default: assertmsg(false, "phase %d", (int)new_phase); } - gScheduler->RestartEvent(tx_event); + scheduler->RestartEvent(tx_event); } // 受信フェーズ遷移図 @@ -1218,7 +1204,7 @@ LanceDevice::ChangePhase(RXPhase new_pha rx_event.time = time; switch (new_phase) { case RXPhase::STOP: - gScheduler->StopEvent(rx_event); + scheduler->StopEvent(rx_event); return; case RXPhase::IDLE: rx_event.func = ToEventCallback(&LanceDevice::RXIdle); @@ -1229,7 +1215,7 @@ LanceDevice::ChangePhase(RXPhase new_pha default: assertmsg(false, "phase %d", (int)new_phase); } - gScheduler->RestartEvent(rx_event); + scheduler->RestartEvent(rx_event); }