--- nono/vm/busio.h 2026/04/29 17:04:31 1.1.1.1 +++ nono/vm/busio.h 2026/04/29 17:04:35 1.1.1.2 @@ -1,6 +1,7 @@ // // nono -// Copyright (C) 2020 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // // バスとデバイスとのインタフェース。 @@ -20,15 +21,15 @@ class BusIO_B_Base: public T } public: - virtual uint64 Read8(uint32 addr) { + uint64 Read8(uint32 addr) override { return T::Read(Decoder(addr)); } - virtual uint64 Write8(uint32 addr, uint32 data) { + uint64 Write8(uint32 addr, uint32 data) override { return T::Write(Decoder(addr), data); } - virtual uint64 Peek8(uint32 addr) { + uint64 Peek8(uint32 addr) override { return T::Peek(Decoder(addr)); } }; @@ -55,27 +56,32 @@ class BusIO_W: public T } public: - virtual uint64 Read8(uint32 addr) { + uint64 Read8(uint32 addr) override { if ((addr & 1) == 0) { return T::Read(Decoder(addr)) >> 8; } else { return T::Read(Decoder(addr)) & 0xff; } } - virtual uint64 Read16(uint32 addr) { + uint64 Read16(uint32 addr) override { return T::Read(Decoder(addr)); } - virtual uint64 Write8(uint32 addr, uint32 data) { - PANIC("not implemented\n"); - return (int64)-1; // XXX 未確認 + uint64 Write8(uint32 addr, uint32 data) override { + uint32 offset = Decoder(addr); + uint32 old = T::Read(offset); + if ((addr & 1) == 0) { + return T::Write(offset, ((data << 8) & 0xff00) | (old & 0x00ff)); + } else { + return T::Write(offset, (old & 0xff00) | (data & 0x00ff)); + } } - virtual uint64 Write16(uint32 addr, uint32 data) { + uint64 Write16(uint32 addr, uint32 data) override { return T::Write(Decoder(addr), data); } - virtual uint64 Peek8(uint32 addr) { + uint64 Peek8(uint32 addr) override { if ((addr & 1) == 0) { return T::Peek(Decoder(addr)) >> 8; } else { @@ -98,29 +104,29 @@ class BusIO_BE: public T } public: - virtual uint64 Read8(uint32 addr) { + uint64 Read8(uint32 addr) override { if ((addr & 1) == 0) { return T::Read(Decoder(addr)); } else { return (int64)-1; } } - virtual uint64 Read16(uint32 addr) { + uint64 Read16(uint32 addr) override { return (T::Read(Decoder(addr)) << 8) | 0xff; } - virtual uint64 Write8(uint32 addr, uint32 data) { + uint64 Write8(uint32 addr, uint32 data) override { if ((addr & 1) == 0) { return T::Write(Decoder(addr), data); } else { return (int64)-1; } } - virtual uint64 Write16(uint32 addr, uint32 data) { + uint64 Write16(uint32 addr, uint32 data) override { return T::Write(Decoder(addr), data >> 8); } - virtual uint64 Peek8(uint32 addr) { + uint64 Peek8(uint32 addr) override { if ((addr & 1) == 0) { return T::Peek(Decoder(addr)); } else { @@ -139,29 +145,29 @@ class BusIO_EB: public T } public: - virtual uint64 Read8(uint32 addr) { + uint64 Read8(uint32 addr) override { if ((addr & 1) == 0) { return (int64)-1; } else { return T::Read(Decoder(addr)); } } - virtual uint64 Read16(uint32 addr) { + uint64 Read16(uint32 addr) override { return T::Read(Decoder(addr)) | 0xff00; } - virtual uint64 Write8(uint32 addr, uint32 data) { + uint64 Write8(uint32 addr, uint32 data) override { if ((addr & 1) == 0) { return (int64)-1; } else { return T::Write(Decoder(addr), data); } } - virtual uint64 Write16(uint32 addr, uint32 data) { + uint64 Write16(uint32 addr, uint32 data) override { return T::Write(Decoder(addr), data & 0xff); } - virtual uint64 Peek8(uint32 addr) { + uint64 Peek8(uint32 addr) override { if ((addr & 1) == 0) { return (int64)-1; } else { @@ -170,6 +176,47 @@ class BusIO_EB: public T } }; +// バイトデバイスを奇数アドレスに配置し、偶数アドレスは非接続。 +template +class BusIO_FB: public T +{ + private: + inline uint32 Decoder(uint32 addr) { + return (addr >> 1) & (T::NPORT - 1); + } + + public: + uint64 Read8(uint32 addr) override { + if ((addr & 1) == 0) { + return 0xff; + } else { + return T::Read(Decoder(addr)); + } + } + uint64 Read16(uint32 addr) override { + return T::Read(Decoder(addr)) | 0xff00; + } + + uint64 Write8(uint32 addr, uint32 data) override { + if ((addr & 1) == 0) { + return 0; + } else { + return T::Write(Decoder(addr), data); + } + } + uint64 Write16(uint32 addr, uint32 data) override { + return T::Write(Decoder(addr), data & 0xff); + } + + uint64 Peek8(uint32 addr) override { + if ((addr & 1) == 0) { + return 0xff; + } else { + return T::Peek(Decoder(addr)); + } + } +}; + // バイトデバイスをロングワードの先頭に配置し、他は非接続。 template class BusIO_BFFF: public T @@ -180,43 +227,43 @@ class BusIO_BFFF: public T } public: - virtual uint64 Read8(uint32 addr) { + uint64 Read8(uint32 addr) override { if ((addr & 3) == 0) { return T::Read(Decoder(addr)); } else { return 0xff; } } - virtual uint64 Read16(uint32 addr) { + uint64 Read16(uint32 addr) override { if ((addr & 2) == 0) { return (T::Read(Decoder(addr)) << 8) | 0xff; } else { return 0xffff; } } - virtual uint64 Read32(uint32 addr) { + uint64 Read32(uint32 addr) override { return (T::Read(Decoder(addr)) << 24) | 0x00ffffff; } - virtual uint64 Write8(uint32 addr, uint32 data) { + uint64 Write8(uint32 addr, uint32 data) override { if ((addr & 3) == 0) { return T::Write(Decoder(addr), data); } else { return 0; } } - virtual uint64 Write16(uint32 addr, uint32 data) { + uint64 Write16(uint32 addr, uint32 data) override { if ((addr & 2) == 0) { return T::Write(Decoder(addr), data >> 8); } else { return 0; } } - virtual uint64 Write32(uint32 addr, uint32 data) { + uint64 Write32(uint32 addr, uint32 data) override { return T::Write(Decoder(addr), data >> 24); } - virtual uint64 Peek8(uint32 addr) { + uint64 Peek8(uint32 addr) override { if ((addr & 3) == 0) { return T::Peek(Decoder(addr)); } else { @@ -234,26 +281,26 @@ class BusIO_WW: public T return (addr >> 2) & (T::NPORT - 1); } public: - virtual uint64 Read8(uint32 addr) { + uint64 Read8(uint32 addr) override { if ((addr & 1) == 0) { return T::Read(Decoder(addr)) >> 8; } else { return T::Read(Decoder(addr)) & 0xff; } } - virtual uint64 Read16(uint32 addr) { + uint64 Read16(uint32 addr) override { return T::Read(Decoder(addr)); } - virtual uint64 Write8(uint32 addr, uint32 data) { + uint64 Write8(uint32 addr, uint32 data) override { PANIC("not implemented\n"); return (int64)-1; // XXX 未確認 } - virtual uint64 Write16(uint32 addr, uint32 data) { + uint64 Write16(uint32 addr, uint32 data) override { return T::Write(Decoder(addr), data); } - virtual uint64 Peek8(uint32 addr) { + uint64 Peek8(uint32 addr) override { if ((addr & 1) == 0) { return T::Peek(Decoder(addr)) >> 8; } else { @@ -271,7 +318,7 @@ class BusIO_WF: public T return (addr >> 2) & (T::NPORT - 1); } public: - virtual uint64 Read8(uint32 addr) { + uint64 Read8(uint32 addr) override { switch (addr & 3) { case 0: return T::Read(Decoder(addr)) >> 8; @@ -283,7 +330,7 @@ class BusIO_WF: public T } __unreachable(); } - virtual uint64 Read16(uint32 addr) { + uint64 Read16(uint32 addr) override { if ((addr & 2) == 0) { return T::Read(Decoder(addr)); } else { @@ -291,18 +338,18 @@ class BusIO_WF: public T } } - virtual uint64 Write8(uint32 addr, uint32 data) { + uint64 Write8(uint32 addr, uint32 data) override { PANIC("not implemented\n"); return 0; // XXX 未確認 } - virtual uint64 Write16(uint32 addr, uint32 data) { + uint64 Write16(uint32 addr, uint32 data) override { if ((addr & 2) == 0) { return T::Write(Decoder(addr), data); } else { return 0; } } - virtual uint64 Peek8(uint32 addr) { + uint64 Peek8(uint32 addr) override { switch (addr & 3) { case 0: return T::Peek(Decoder(addr)) >> 8; @@ -331,7 +378,7 @@ class BusIO_X68kSPC : public T } public: - virtual uint64 Read8(uint32 addr) { + uint64 Read8(uint32 addr) override { if ((addr & 1) == 0) { return (uint64)-1; } else { @@ -345,7 +392,7 @@ class BusIO_X68kSPC : public T } } } - virtual uint64 Read16(uint32 addr) { + uint64 Read16(uint32 addr) override { addr = Decoder(addr); if (addr < 0x10) { // 前半16ポートは SASI 跡地 @@ -355,7 +402,7 @@ class BusIO_X68kSPC : public T } } - virtual uint64 Write8(uint32 addr, uint32 data) { + uint64 Write8(uint32 addr, uint32 data) override { if ((addr & 1) == 0) { return (uint64)-1; } else { @@ -370,7 +417,7 @@ class BusIO_X68kSPC : public T } } } - virtual uint64 Write16(uint32 addr, uint32 data) { + uint64 Write16(uint32 addr, uint32 data) override { addr = Decoder(addr); if (addr < 0x10) { // 前半16ポートは SASI 跡地。 @@ -382,7 +429,7 @@ class BusIO_X68kSPC : public T } } - virtual uint64 Peek8(uint32 addr) { + uint64 Peek8(uint32 addr) override { if ((addr & 1) == 0) { return (uint64)-1; } else {