--- nono/vm/gvram.cpp 2026/04/29 17:04:28 1.1 +++ nono/vm/gvram.cpp 2026/04/29 17:05:29 1.1.1.9 @@ -1,67 +1,76 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // -#include "gvram.h" -#include "vicon.h" - // // GVRAM // + // GVRAM はワード単位でホストバイトオーダ配置なので、 // バイトアクセス時は HB() マクロを使用のこと。 -// -GVRAMDevice *gGVRAM; +#include "gvram.h" +#include "videoctlr.h" + +// InsideOut p.135 +static const busdata wait = busdata::Wait(9 * 40_nsec); +// コンストラクタ GVRAMDevice::GVRAMDevice() + : inherited(OBJ_GVRAM) { - logname = "gvram"; - devname = "GVRAM"; - devaddr = 0xc00000; - devlen = 0x200000; // XXX とりあえず + uint devlen = 0x20'0000; // XXX とりあえず - mem = new uint8[devlen]; + mem.reset(new uint8[devlen]); } +// デストラクタ GVRAMDevice::~GVRAMDevice() { - delete[] mem; } -uint64 -GVRAMDevice::Read8(uint32 addr) +inline uint32 +GVRAMDevice::Decoder(uint32 addr) const { - uint32 offset = addr - devaddr; - return mem[HB(offset)]; + return addr - baseaddr; } -uint64 -GVRAMDevice::Read16(uint32 addr) +busdata +GVRAMDevice::Read(busaddr addr) { - uint32 offset = addr - devaddr; - return *(uint16 *)&mem[offset]; -} + uint32 offset = Decoder(addr.Addr()); + busdata data; -uint64 -GVRAMDevice::Write8(uint32 addr, uint32 data) -{ - uint32 offset = addr - devaddr; - mem[HB(offset)] = data; - return 0; + data = *(uint16 *)&mem[offset & ~1U]; + data |= wait; + data |= BusData::Size2; + return data; } -uint64 -GVRAMDevice::Write16(uint32 addr, uint32 data) +busdata +GVRAMDevice::Write(busaddr addr, uint32 data) { - uint32 offset = addr - devaddr; - *(uint16 *)&mem[offset] = data; - return 0; + uint32 offset = Decoder(addr.Addr()); + uint32 reqsize = addr.GetSize(); + uint32 datasize = std::min(2 - (offset & 1U), reqsize); + data >>= (reqsize - datasize) * 8; + + if (datasize == 1) { + mem[HB(offset)] = data; + } else { + *(uint16 *)&mem[offset] = data; + } + + busdata r = wait; + r |= busdata::Size(datasize); + return r; } -uint64 -GVRAMDevice::Peek8(uint32 addr) +busdata +GVRAMDevice::Peek1(uint32 addr) { - return mem[HB(addr - devaddr)]; + uint32 offset = Decoder(addr); + return mem[HB(offset)]; }