--- nono/vm/test_busio.cpp 2026/04/29 17:05:17 1.1.1.5 +++ nono/vm/test_busio.cpp 2026/04/29 17:05:29 1.1.1.7 @@ -4,7 +4,7 @@ // Licensed under nono-license.txt // -#include "header.h" +#include "bus.h" #include #include @@ -14,32 +14,30 @@ class IODevice { public: - IODevice() {} + enum : uint { + Capacity = 8, + }; + public: + IODevice() + { + reg.resize(Capacity); + Reset(); + } virtual ~IODevice(); - virtual uint64 Read8(uint32 addr) { return 0xef; } - virtual uint64 Read16(uint32 addr) { - return (Read8(addr) << 8) | (Read8(addr + 1)); - } - virtual uint64 Read32(uint32 addr) { - return (Read16(addr) << 16) | (Read16(addr + 2)); - } - virtual uint64 Write8(uint32 addr, uint32 data) { return 0; } - virtual uint64 Write16(uint32 addr, uint32 data) { - uint64 r; - r = Write8(addr, data >> 8); - r |= Write8(addr + 1, data & 0xff); - return r; - } - virtual uint64 Write32(uint32 addr, uint32 data) { - uint64 r; - r = Write16(addr, data >> 16); - r |= Write16(addr + 2, data & 0xffff); - return r; - } - virtual uint64 Peek8(uint32 addr) { return 0xff; } - virtual uint64 Poke8(uint32 addr, uint32 data) { return (uint64)-1; } - virtual uint64 Poke(uint32 addr, uint32 data) { return (uint64)-1; } + virtual busdata Read(busaddr addr) { return 0xdf; } + virtual busdata Write(busaddr addr, uint32 data) { return 0; } + virtual busdata Peek1(uint32 addr) { return 0xff; } + virtual bool Poke1(uint32 addr, uint32 data) { return false; } + + void Reset() { + for (int i = 0; i < Capacity; i++) { + reg[i] = i + 0x81; + } + } + + // uint32 だがバイトレジスタとして扱う + std::vector reg {}; }; IODevice::~IODevice() { } @@ -50,23 +48,26 @@ class TestByteDev : public IODevice { public: TestByteDev() {} - virtual ~TestByteDev() override; + ~TestByteDev() override; static const uint32 NPORT = 4; - uint32 reg[NPORT] {}; - uint64 Read(uint32 addr) { - if ((int32)reg[addr] < 0) - return (uint64)-1; - return reg[addr]; - } - uint64 Write(uint32 addr, uint32 data) { - reg[addr] = data; - return 0; - } - uint64 Peek(uint32 addr) { - if ((int32)reg[addr] < 0) - return (uint64)-1; - return reg[addr]; + busdata ReadPort(uint32 offset) { + if ((int32)reg[offset] < 0) + return BusData::BusErr; + return reg[offset] | BusData::Size1; + } + busdata WritePort(uint32 offset, uint32 data) { + assert(data <= 0xff); + reg[offset] = data; + return BusData::Size1; + } + busdata PeekPort(uint32 offset) { + if ((int32)reg[offset] < 0) + return BusData::BusErr; + return reg[offset]; + } + bool PokePort(uint32 offset, uint32 data) { + return false; } }; TestByteDev::~TestByteDev() { } @@ -75,71 +76,62 @@ class TestWordDev : public IODevice { public: TestWordDev() {} - virtual ~TestWordDev() override; + ~TestWordDev() override; static const uint32 NPORT = 4; - uint32 reg[NPORT] {}; - uint64 Read(uint32 addr) { - if ((int32)reg[addr] < 0) - return (uint64)-1; - return reg[addr]; - } - uint64 Write(uint32 addr, uint32 data) { - reg[addr] = data; - return 0; - } - uint64 Peek(uint32 addr) { - if ((int32)reg[addr] < 0) - return (uint64)-1; - return reg[addr]; + busdata ReadPort(uint32 offset) { + busdata data = PeekPort(offset); + data |= BusData::Size2; + return data; + } + busdata WritePort(uint32 offset, uint32 data) { + assert(data <= 0xffff); + reg[offset * 2 + 0] = (uint8)(data >> 8); + reg[offset * 2 + 1] = (uint8)(data & 0xff); + return BusData::Size2; + } + busdata PeekPort(uint32 offset) { + if ((int32)reg[offset] < 0) + return BusData::BusErr; + uint32 data; + data = (uint8)reg[offset * 2 + 0] << 8; + data |= (uint8)reg[offset * 2 + 1]; + return data; } }; TestWordDev::~TestWordDev() { } -// テストデータ -// expected[] の1エントリは1バイトを表す(WordDevの時も同様)。 -#define E ((uint64)-1) -#define F (0xff) -static struct testdata { - const char *name; - std::vector expected; -} testdata_b[] = { - { "BusIO_B", { - 1, 2, 3, 4, 1, 2, 3, 4, - } }, - { "BusIO_BB", { - 1, 1, 2, 2, 3, 3, 4, 4, 1, 1, 2, 2, 3, 3, 4, 4, - } }, - { "BusIO_BBBB", { - 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, - 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, - } }, - { "BusIO_BE", { - 1, E, 2, E, 3, E, 4, E, 1, E, 2, E, 3, E, 4, E, - } }, - { "BusIO_EB", { - E, 1, E, 2, E, 3, E, 4, E, 1, E, 2, E, 3, E, 4, - } }, - { "BusIO_FB", { - F, 1, F, 2, F, 3, F, 4, F, 1, F, 2, F, 3, F, 4, - } }, - { "BusIO_BFFF", { - 1, F, F, F, 2, F, F, F, 3, F, F, F, 4, F, F, F, - 1, F, F, F, 2, F, F, F, 3, F, F, F, 4, F, F, F, - } }, -}, testdata_w[] = { - { "BusIO_W", { - 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, - } }, - { "BusIO_WW", { - 1, 2, 1, 2, 3, 4, 3, 4, 5, 6, 5, 6, 7, 8, 7, 8, - 1, 2, 1, 2, 3, 4, 3, 4, 5, 6, 5, 6, 7, 8, 7, 8, - } }, - { "BusIO_WF", { - 1, 2, F, F, 3, 4, F, F, 5, 6, F, F, 7, 8, F, F, - 1, 2, F, F, 3, 4, F, F, 5, 6, F, F, 7, 8, F, F, - } }, +class TestLongDev : public IODevice +{ + public: + TestLongDev() {} + ~TestLongDev() override; + + static const uint32 NPORT = 4; + busdata ReadPort(uint32 offset) { + busdata data = PeekPort(offset); + data |= BusData::Size4; + return data; + } + busdata WritePort(uint32 offset, uint32 data) { + reg[offset * 4 + 0] = (uint8)(data >> 24); + reg[offset * 4 + 1] = (uint8)(data >> 16); + reg[offset * 4 + 2] = (uint8)(data >> 8); + reg[offset * 4 + 3] = (uint8)(data & 0xff); + return BusData::Size4; + } + busdata PeekPort(uint32 offset) { + if ((int32)reg[offset] < 0) + return BusData::BusErr; + uint32 data; + data = (uint8)reg[offset * 4 + 0] << 24; + data |= (uint8)reg[offset * 4 + 1] << 16; + data |= (uint8)reg[offset * 4 + 2] << 8; + data |= (uint8)reg[offset * 4 + 3]; + return data; + } }; +TestLongDev::~TestLongDev() { } void fail(const char *fmt, ...) __printflike(1, 2); void @@ -153,105 +145,688 @@ fail(const char *fmt, ...) va_end(ap); } -template void -do_test(struct testdata *test, T *dev) +// 入力アドレス(busaddr)と期待値(busdata)を列挙しやすいよう分解したもの。 +struct TestItemR { - printf("%s\n", test->name); + busaddr addr; // 入力アドレス + busdata exp; // 期待値 +}; - // デバイス側に読み出し元データをセット。 - // 元データは常にバイト単位で列挙してあるので、ターゲットデバイスの - // サイズによってセット方法が変わる。 - if (dynamic_cast(dev)) { - for (int i = 0; i < dev->NPORT; i++) { - dev->reg[i] = (i + 1); - } - } else { - for (int i = 0, j = 0; i < dev->NPORT; i++) { - uint32 data; - data = (++j) << 8; - data |= (++j); - dev->reg[i] = data; - } - } - - // Read8 のテスト - for (int i = 0; i < test->expected.size(); i++) { - uint64 act = dev->Read8(i); - uint64 exp = test->expected[i]; - if (act != exp) { - fail("%s::Read8(%d) expects %02" PRIx64 " but %02" PRIx64 "\n", - test->name, i, exp, act); - } - } - // Read16 のテスト - for (int i = 0; i < test->expected.size(); i += 2) { - uint64 act = dev->Read16(i); - uint64 e0 = test->expected[i + 0]; - uint64 e1 = test->expected[i + 1]; - uint64 exp; - if ((int64)e0 < 0 && (int64)e1 < 0) { - // 両方バスエラーならバスエラー? - exp = (int64)-1; - } else { - // そうでなければバスエラー側は 0xff ? - exp = (((uint8)e0) << 8) | ((uint8)e1); - } - if (act != exp) { - fail("%s::Read16(%d) expects %04" PRIx64 " but %04" PRIx64 "\n", - test->name, i, exp, act); - } - } - // Read32 のテスト - for (int i = 0; i < test->expected.size(); i += 4) { - uint64 act = dev->Read32(i); - uint64 e0 = test->expected[i + 0]; - uint64 e1 = test->expected[i + 1]; - uint64 e2 = test->expected[i + 2]; - uint64 e3 = test->expected[i + 3]; - uint64 exp; - if ((int64)e0 < 0 && (int64)e1 < 0 && (int64)e2 < 0 && (int64)e3 < 0) { - // 全部バスエラーならバスエラー? - exp = (int64)-1; - } else { - // そうでなければバスエラー部分だけ 0xff ? - e0 = (uint8)e0 << 24; - e1 = (uint8)e1 << 16; - e2 = (uint8)e2 << 8; - e3 = (uint8)e3; - exp = (uint64)(uint32)(e0 | e1 | e2 | e3); - } - if (act != exp) { - fail("%s::Read32(%d) expects %08" PRIx64 " but %08" PRIx64 "\n", - test->name, i, exp, act); - } - } - // Peek8 のテスト - for (int i = 0; i < test->expected.size(); i++) { - uint64 act = dev->Peek8(i); - uint64 exp = test->expected[i]; - if (act != exp) { - fail("%s::Peek8(%d) expects %02" PRIx64 " but %02" PRIx64 "\n", - test->name, i, exp, act); +struct TestItemW +{ + busaddr addr; // 入力アドレス + uint32 data; // 入力データ + busdata expres; // 応答の期待値 + const char *expmem; // 書き込み後のレジスタの期待値 + + // memexp は表記を圧縮するため、 + // 0x81, 0x82, ... 0x88 を '1', '2', .. '8'、 + // 0xfa, 0xfb, 0xfc, 0xfd を 'A', 'B', 'C', 'D'、 + // 0x00 を '0' + // と置き換えた 8文字の文字列で表現する。 +}; + +struct TestData +{ + const char *name; + std::vector table_read; // Read テスト用データ + std::vector table_write; // Write テスト用データ +}; + +static void +do_test(IODevice *dev, const TestData& testdata) +{ + int failcount = 0; + + printf("%s", testdata.name); + fflush(stdout); + + // Read + for (const auto& item : testdata.table_read) { + busaddr addr = item.addr; + busdata exp = item.exp; + + busdata act = dev->Read(addr); + if (act.Get() != exp.Get()) { + if (failcount == 0) { + printf("\n"); + } + fail("%s::Read($%08x'%08x) expects $%08x'%08x but $%08x'%08x\n", + testdata.name, addr.GetH(), addr.GetL(), + exp.GetH(), exp.GetL(), act.GetH(), act.GetL()); + failcount++; + } else if (0) { + printf(" Read($%08x'%08x) -> $%08x'%08x\n", + addr.GetH(), addr.GetL(), act.GetH(), act.GetL()); } } - // Write 系のテストはちょっと保留。 + // Write + for (const auto& item : testdata.table_write) { + busaddr addr = item.addr; + uint32 srcdata = item.data; + busdata exp = item.expres; + const char *expmem_str = item.expmem; + int memlen = std::min((int)strlen(expmem_str), (int)dev->Capacity); + std::vector expmem(memlen); + + // expmem_str から expmem[] を作成。 + for (int i = 0; i < memlen; i++) { + uint8 ch = expmem_str[i]; + if (ch == '0') { + expmem[i] = 0; + } else if ('1' <= ch && ch <= '9') { + expmem[i] = 0x80 + (ch - '0'); + } else if ('A' <= ch && ch <= 'D') { + expmem[i] = 0xfa + (ch - 'A'); + } else { + errx(1, "invalid char\n"); + } + } + + // 実行 + dev->Reset(); + busdata act = dev->Write(addr, srcdata); + + // 応答を照合 + if (act.Get() != exp.Get()) { + if (failcount == 0) { + printf("\n"); + } + fail("%s::Write($%08x'%08x, $%08x) " + "expects $%08x'%08x but $%08x'%08x\n", + testdata.name, addr.GetH(), addr.GetL(), srcdata, + exp.GetH(), exp.GetL(), act.GetH(), act.GetL()); + failcount++; + } + + // 書き込み結果を照合 + bool ok = true; + for (int i = 0; i < memlen; i++) { + if (dev->reg[i] != expmem[i]) { + ok = false; + break; + } + } + if (!ok) { + if (failcount == 0) { + printf("\n"); + } + fail("%s::Write($%08x'%08x, $%08x) expects " + "mem=$%02x%02x'%02x%02x'%02x%02x'%02x%02x but " + "mem=$%02x%02x'%02x%02x'%02x%02x'%02x%02x\n", + testdata.name, addr.GetH(), addr.GetL(), srcdata, + expmem[0], expmem[1], expmem[2], expmem[3], + expmem[4], expmem[5], expmem[6], expmem[7], + dev->reg[0], dev->reg[1], dev->reg[2], dev->reg[3], + dev->reg[4], dev->reg[5], dev->reg[6], dev->reg[7]); + failcount++; + } + } + + if (failcount == 0) { + printf(" .. OK\n"); + } } +#define Size1 1U +#define Size2 2U +#define Size3 3U +#define Size4 4U +#define BA(addr_, size_) (busaddr(addr_) | busaddr::Size(size_)) +#define BD(data_, size_) (busdata(data_) | busdata::Size(size_)) + +#define BusErr (BusData::BusErr) + +// 書き込みパターン (addr::Size と揃えること) +#define W1 (0xfa) +#define W2 (0xfafb) +#define W3 (0xfafbfc) +#define W4 (0xfafbfcfd) + +static TestData +table_B = { + .name = "BusIO_B", + .table_read = { + { BA(0, Size1), BD(0x00000081, Size1) }, + { BA(1, Size1), BD(0x00000082, Size1) }, + { BA(2, Size1), BD(0x00000083, Size1) }, + { BA(3, Size1), BD(0x00000084, Size1) }, + + { BA(0, Size2), BD(0x00000081, Size1) }, + { BA(1, Size2), BD(0x00000082, Size1) }, + { BA(2, Size2), BD(0x00000083, Size1) }, + { BA(3, Size2), BD(0x00000084, Size1) }, + + { BA(0, Size3), BD(0x00000081, Size1) }, + { BA(1, Size3), BD(0x00000082, Size1) }, + { BA(2, Size3), BD(0x00000083, Size1) }, + { BA(3, Size3), BD(0x00000084, Size1) }, + + { BA(0, Size4), BD(0x00000081, Size1) }, + { BA(1, Size4), BD(0x00000082, Size1) }, + { BA(2, Size4), BD(0x00000083, Size1) }, + { BA(3, Size4), BD(0x00000084, Size1) }, + }, + .table_write = { + { BA(0, Size1), W1, BD(0, Size1), "A2345678" }, + { BA(1, Size1), W1, BD(0, Size1), "1A345678" }, + { BA(2, Size1), W1, BD(0, Size1), "12A45678" }, + { BA(3, Size1), W1, BD(0, Size1), "123A5678" }, + + { BA(0, Size2), W2, BD(0, Size1), "A2345678" }, + { BA(1, Size2), W2, BD(0, Size1), "1A345678" }, + { BA(2, Size2), W2, BD(0, Size1), "12A45678" }, + { BA(3, Size2), W2, BD(0, Size1), "123A5678" }, + + { BA(0, Size3), W3, BD(0, Size1), "A2345678" }, + { BA(1, Size3), W3, BD(0, Size1), "1A345678" }, + { BA(2, Size3), W3, BD(0, Size1), "12A45678" }, + { BA(3, Size3), W3, BD(0, Size1), "123A5678" }, + + { BA(0, Size4), W4, BD(0, Size1), "A2345678" }, + { BA(1, Size4), W4, BD(0, Size1), "1A345678" }, + { BA(2, Size4), W4, BD(0, Size1), "12A45678" }, + { BA(3, Size4), W4, BD(0, Size1), "123A5678" }, + }, +}; + +static TestData +table_BB = { + .name = "BusIO_BB", + .table_read = { + { BA(0, Size1), BD(0x00000081, Size1) }, + { BA(1, Size1), BD(0x00000081, Size1) }, + { BA(2, Size1), BD(0x00000082, Size1) }, + { BA(3, Size1), BD(0x00000082, Size1) }, + + { BA(0, Size2), BD(0x00000081, Size1) }, + { BA(1, Size2), BD(0x00000081, Size1) }, + { BA(2, Size2), BD(0x00000082, Size1) }, + { BA(3, Size2), BD(0x00000082, Size1) }, + + { BA(0, Size3), BD(0x00000081, Size1) }, + { BA(1, Size3), BD(0x00000081, Size1) }, + { BA(2, Size3), BD(0x00000082, Size1) }, + { BA(3, Size3), BD(0x00000082, Size1) }, + + { BA(0, Size4), BD(0x00000081, Size1) }, + { BA(1, Size4), BD(0x00000081, Size1) }, + { BA(2, Size4), BD(0x00000082, Size1) }, + { BA(3, Size4), BD(0x00000082, Size1) }, + }, + .table_write = { + { BA(0, Size1), W1, BD(0, Size1), "A2345678" }, + { BA(1, Size1), W1, BD(0, Size1), "A2345678" }, + { BA(2, Size1), W1, BD(0, Size1), "1A345678" }, + { BA(3, Size1), W1, BD(0, Size1), "1A345678" }, + + { BA(0, Size2), W2, BD(0, Size1), "A2345678" }, + { BA(1, Size2), W2, BD(0, Size1), "A2345678" }, + { BA(2, Size2), W2, BD(0, Size1), "1A345678" }, + { BA(3, Size2), W2, BD(0, Size1), "1A345678" }, + + { BA(0, Size3), W3, BD(0, Size1), "A2345678" }, + { BA(1, Size3), W3, BD(0, Size1), "A2345678" }, + { BA(2, Size3), W3, BD(0, Size1), "1A345678" }, + { BA(3, Size3), W3, BD(0, Size1), "1A345678" }, + + { BA(0, Size4), W4, BD(0, Size1), "A2345678" }, + { BA(1, Size4), W4, BD(0, Size1), "A2345678" }, + { BA(2, Size4), W4, BD(0, Size1), "1A345678" }, + { BA(3, Size4), W4, BD(0, Size1), "1A345678" }, + }, +}; + +static TestData +table_BBBB = { + .name = "BusIO_BBBB", + .table_read = { + { BA(0, Size1), BD(0x00000081, Size1) }, + { BA(1, Size1), BD(0x00000081, Size1) }, + { BA(2, Size1), BD(0x00000081, Size1) }, + { BA(3, Size1), BD(0x00000081, Size1) }, + { BA(4, Size1), BD(0x00000082, Size1) }, + { BA(5, Size1), BD(0x00000082, Size1) }, + { BA(6, Size1), BD(0x00000082, Size1) }, + { BA(7, Size1), BD(0x00000082, Size1) }, + + { BA(0, Size2), BD(0x00000081, Size1) }, + { BA(1, Size2), BD(0x00000081, Size1) }, + { BA(2, Size2), BD(0x00000081, Size1) }, + { BA(3, Size2), BD(0x00000081, Size1) }, + { BA(4, Size2), BD(0x00000082, Size1) }, + { BA(5, Size2), BD(0x00000082, Size1) }, + { BA(6, Size2), BD(0x00000082, Size1) }, + { BA(7, Size2), BD(0x00000082, Size1) }, + + { BA(0, Size3), BD(0x00000081, Size1) }, + { BA(1, Size3), BD(0x00000081, Size1) }, + { BA(2, Size3), BD(0x00000081, Size1) }, + { BA(3, Size3), BD(0x00000081, Size1) }, + { BA(4, Size3), BD(0x00000082, Size1) }, + { BA(5, Size3), BD(0x00000082, Size1) }, + { BA(6, Size3), BD(0x00000082, Size1) }, + { BA(7, Size3), BD(0x00000082, Size1) }, + + { BA(0, Size4), BD(0x00000081, Size1) }, + { BA(1, Size4), BD(0x00000081, Size1) }, + { BA(2, Size4), BD(0x00000081, Size1) }, + { BA(3, Size4), BD(0x00000081, Size1) }, + { BA(4, Size4), BD(0x00000082, Size1) }, + { BA(5, Size4), BD(0x00000082, Size1) }, + { BA(6, Size4), BD(0x00000082, Size1) }, + { BA(7, Size4), BD(0x00000082, Size1) }, + }, + .table_write = { + { BA(0, Size1), W1, BD(0, Size1), "A2345678" }, + { BA(1, Size1), W1, BD(0, Size1), "A2345678" }, + { BA(2, Size1), W1, BD(0, Size1), "A2345678" }, + { BA(3, Size1), W1, BD(0, Size1), "A2345678" }, + { BA(4, Size1), W1, BD(0, Size1), "1A345678" }, + { BA(5, Size1), W1, BD(0, Size1), "1A345678" }, + { BA(6, Size1), W1, BD(0, Size1), "1A345678" }, + { BA(7, Size1), W1, BD(0, Size1), "1A345678" }, + + { BA(0, Size2), W2, BD(0, Size1), "A2345678" }, + { BA(1, Size2), W2, BD(0, Size1), "A2345678" }, + { BA(2, Size2), W2, BD(0, Size1), "A2345678" }, + { BA(3, Size2), W2, BD(0, Size1), "A2345678" }, + { BA(4, Size2), W2, BD(0, Size1), "1A345678" }, + { BA(5, Size2), W2, BD(0, Size1), "1A345678" }, + { BA(6, Size2), W2, BD(0, Size1), "1A345678" }, + { BA(7, Size2), W2, BD(0, Size1), "1A345678" }, + + { BA(0, Size3), W3, BD(0, Size1), "A2345678" }, + { BA(1, Size3), W3, BD(0, Size1), "A2345678" }, + { BA(2, Size3), W3, BD(0, Size1), "A2345678" }, + { BA(3, Size3), W3, BD(0, Size1), "A2345678" }, + { BA(4, Size3), W3, BD(0, Size1), "1A345678" }, + { BA(5, Size3), W3, BD(0, Size1), "1A345678" }, + { BA(6, Size3), W3, BD(0, Size1), "1A345678" }, + { BA(7, Size3), W3, BD(0, Size1), "1A345678" }, + + { BA(0, Size4), W4, BD(0, Size1), "A2345678" }, + { BA(1, Size4), W4, BD(0, Size1), "A2345678" }, + { BA(2, Size4), W4, BD(0, Size1), "A2345678" }, + { BA(3, Size4), W4, BD(0, Size1), "A2345678" }, + { BA(4, Size4), W4, BD(0, Size1), "1A345678" }, + { BA(5, Size4), W4, BD(0, Size1), "1A345678" }, + { BA(6, Size4), W4, BD(0, Size1), "1A345678" }, + { BA(7, Size4), W4, BD(0, Size1), "1A345678" }, + }, +}; + +static TestData +table_BFFF = { + .name = "BusIO_BFFF", + .table_read = { + { BA(0, Size1), BD(0x81ffffff, Size4) }, + { BA(1, Size1), BD(0x81ffffff, Size4) }, + { BA(2, Size1), BD(0x81ffffff, Size4) }, + { BA(3, Size1), BD(0x81ffffff, Size4) }, + { BA(4, Size1), BD(0x82ffffff, Size4) }, + { BA(5, Size1), BD(0x82ffffff, Size4) }, + { BA(6, Size1), BD(0x82ffffff, Size4) }, + { BA(7, Size1), BD(0x82ffffff, Size4) }, + + { BA(0, Size2), BD(0x81ffffff, Size4) }, + { BA(1, Size2), BD(0x81ffffff, Size4) }, + { BA(2, Size2), BD(0x81ffffff, Size4) }, + { BA(3, Size2), BD(0x81ffffff, Size4) }, + { BA(4, Size2), BD(0x82ffffff, Size4) }, + { BA(5, Size2), BD(0x82ffffff, Size4) }, + { BA(6, Size2), BD(0x82ffffff, Size4) }, + { BA(7, Size2), BD(0x82ffffff, Size4) }, + + { BA(0, Size3), BD(0x81ffffff, Size4) }, + { BA(1, Size3), BD(0x81ffffff, Size4) }, + { BA(2, Size3), BD(0x81ffffff, Size4) }, + { BA(3, Size3), BD(0x81ffffff, Size4) }, + { BA(4, Size3), BD(0x82ffffff, Size4) }, + { BA(5, Size3), BD(0x82ffffff, Size4) }, + { BA(6, Size3), BD(0x82ffffff, Size4) }, + { BA(7, Size3), BD(0x82ffffff, Size4) }, + + { BA(0, Size4), BD(0x81ffffff, Size4) }, + { BA(1, Size4), BD(0x81ffffff, Size4) }, + { BA(2, Size4), BD(0x81ffffff, Size4) }, + { BA(3, Size4), BD(0x81ffffff, Size4) }, + { BA(4, Size4), BD(0x82ffffff, Size4) }, + { BA(5, Size4), BD(0x82ffffff, Size4) }, + { BA(6, Size4), BD(0x82ffffff, Size4) }, + { BA(7, Size4), BD(0x82ffffff, Size4) }, + }, + .table_write = { + { BA(0, Size1), W1, BD(0, Size4), "A2345678" }, + { BA(1, Size1), W1, BD(0, Size4), "A2345678" }, + { BA(2, Size1), W1, BD(0, Size4), "A2345678" }, + { BA(3, Size1), W1, BD(0, Size4), "A2345678" }, + { BA(4, Size1), W1, BD(0, Size4), "1A345678" }, + { BA(5, Size1), W1, BD(0, Size4), "1A345678" }, + { BA(6, Size1), W1, BD(0, Size4), "1A345678" }, + { BA(7, Size1), W1, BD(0, Size4), "1A345678" }, + + { BA(0, Size2), W2, BD(0, Size4), "A2345678" }, + { BA(1, Size2), W2, BD(0, Size4), "A2345678" }, + { BA(2, Size2), W2, BD(0, Size4), "A2345678" }, + { BA(3, Size2), W2, BD(0, Size4), "A2345678" }, + { BA(4, Size2), W2, BD(0, Size4), "1A345678" }, + { BA(5, Size2), W2, BD(0, Size4), "1A345678" }, + { BA(6, Size2), W2, BD(0, Size4), "1A345678" }, + { BA(7, Size2), W2, BD(0, Size4), "1A345678" }, + + { BA(0, Size3), W3, BD(0, Size4), "A2345678" }, + { BA(1, Size3), W3, BD(0, Size4), "A2345678" }, + { BA(2, Size3), W3, BD(0, Size4), "A2345678" }, + { BA(3, Size3), W3, BD(0, Size4), "A2345678" }, + { BA(4, Size3), W3, BD(0, Size4), "1A345678" }, + { BA(5, Size3), W3, BD(0, Size4), "1A345678" }, + { BA(6, Size3), W3, BD(0, Size4), "1A345678" }, + { BA(7, Size3), W3, BD(0, Size4), "1A345678" }, + + { BA(0, Size4), W4, BD(0, Size4), "A2345678" }, + { BA(1, Size4), W4, BD(0, Size4), "A2345678" }, + { BA(2, Size4), W4, BD(0, Size4), "A2345678" }, + { BA(3, Size4), W4, BD(0, Size4), "A2345678" }, + { BA(4, Size4), W4, BD(0, Size4), "1A345678" }, + { BA(5, Size4), W4, BD(0, Size4), "1A345678" }, + { BA(6, Size4), W4, BD(0, Size4), "1A345678" }, + { BA(7, Size4), W4, BD(0, Size4), "1A345678" }, + }, +}; + +static TestData +table_EB = { + .name = "BusIO_EB", + .table_read = { + { BA(0, Size1), BusErr }, + { BA(1, Size1), BD(0x0000ff81, Size2) }, + { BA(2, Size1), BusErr }, + { BA(3, Size1), BD(0x0000ff82, Size2) }, + + { BA(0, Size2), BD(0x0000ff81, Size2) }, + { BA(1, Size2), BD(0x0000ff81, Size2) }, + { BA(2, Size2), BD(0x0000ff82, Size2) }, + { BA(3, Size2), BD(0x0000ff82, Size2) }, + + { BA(0, Size3), BD(0x0000ff81, Size2) }, + { BA(1, Size3), BD(0x0000ff81, Size2) }, + { BA(2, Size3), BD(0x0000ff82, Size2) }, + { BA(3, Size3), BD(0x0000ff82, Size2) }, + + { BA(0, Size4), BD(0x0000ff81, Size2) }, + { BA(1, Size4), BD(0x0000ff81, Size2) }, + { BA(2, Size4), BD(0x0000ff82, Size2) }, + { BA(3, Size4), BD(0x0000ff82, Size2) }, + }, + .table_write = { + { BA(0, Size1), W1, BusErr, "12345678" }, + { BA(1, Size1), W1, BD(0, Size2), "A2345678" }, + { BA(2, Size1), W1, BusErr, "12345678" }, + { BA(3, Size1), W1, BD(0, Size2), "1A345678" }, + + { BA(0, Size2), W2, BD(0, Size2), "B2345678" }, + { BA(1, Size2), W2, BD(0, Size2), "A2345678" }, + { BA(2, Size2), W2, BD(0, Size2), "1B345678" }, + { BA(3, Size2), W2, BD(0, Size2), "1A345678" }, + + { BA(0, Size3), W3, BD(0, Size2), "B2345678" }, + { BA(1, Size3), W3, BD(0, Size2), "A2345678" }, + { BA(2, Size3), W3, BD(0, Size2), "1B345678" }, + { BA(3, Size3), W3, BD(0, Size2), "1A345678" }, + + { BA(0, Size4), W4, BD(0, Size2), "B2345678" }, + { BA(1, Size4), W4, BD(0, Size2), "A2345678" }, + { BA(2, Size4), W4, BD(0, Size2), "1B345678" }, + { BA(3, Size4), W4, BD(0, Size2), "1A345678" }, + }, +}; + +static TestData +table_FB = { + .name = "BusIO_FB", + .table_read = { + { BA(0, Size1), BD(0x0000ffff, Size2) }, + { BA(1, Size1), BD(0x0000ff81, Size2) }, + { BA(2, Size1), BD(0x0000ffff, Size2) }, + { BA(3, Size1), BD(0x0000ff82, Size2) }, + + { BA(0, Size2), BD(0x0000ff81, Size2) }, + { BA(1, Size2), BD(0x0000ff81, Size2) }, + { BA(2, Size2), BD(0x0000ff82, Size2) }, + { BA(3, Size2), BD(0x0000ff82, Size2) }, + + { BA(0, Size3), BD(0x0000ff81, Size2) }, + { BA(1, Size3), BD(0x0000ff81, Size2) }, + { BA(2, Size3), BD(0x0000ff82, Size2) }, + { BA(3, Size3), BD(0x0000ff82, Size2) }, + + { BA(0, Size4), BD(0x0000ff81, Size2) }, + { BA(1, Size4), BD(0x0000ff81, Size2) }, + { BA(2, Size4), BD(0x0000ff82, Size2) }, + { BA(3, Size4), BD(0x0000ff82, Size2) }, + }, + .table_write = { + { BA(0, Size1), W1, BD(0, Size2), "12345678" }, + { BA(1, Size1), W1, BD(0, Size2), "A2345678" }, + { BA(2, Size1), W1, BD(0, Size2), "12345678" }, + { BA(3, Size1), W1, BD(0, Size2), "1A345678" }, + + { BA(0, Size2), W2, BD(0, Size2), "B2345678" }, + { BA(1, Size2), W2, BD(0, Size2), "A2345678" }, + { BA(2, Size2), W2, BD(0, Size2), "1B345678" }, + { BA(3, Size2), W2, BD(0, Size2), "1A345678" }, + + { BA(0, Size3), W3, BD(0, Size2), "B2345678" }, + { BA(1, Size3), W3, BD(0, Size2), "A2345678" }, + { BA(2, Size3), W3, BD(0, Size2), "1B345678" }, + { BA(3, Size3), W3, BD(0, Size2), "1A345678" }, + + { BA(0, Size4), W4, BD(0, Size2), "B2345678" }, + { BA(1, Size4), W4, BD(0, Size2), "A2345678" }, + { BA(2, Size4), W4, BD(0, Size2), "1B345678" }, + { BA(3, Size4), W4, BD(0, Size2), "1A345678" }, + }, +}; + +static TestData +table_W = { + .name = "BusIO_W", + .table_read = { + { BA(0, Size1), BD(0x00008182, Size2) }, + { BA(1, Size1), BD(0x00008182, Size2) }, + { BA(2, Size1), BD(0x00008384, Size2) }, + { BA(3, Size1), BD(0x00008384, Size2) }, + + { BA(0, Size2), BD(0x00008182, Size2) }, + { BA(1, Size2), BD(0x00008182, Size2) }, + { BA(2, Size2), BD(0x00008384, Size2) }, + { BA(3, Size2), BD(0x00008384, Size2) }, + + { BA(0, Size3), BD(0x00008182, Size2) }, + { BA(1, Size3), BD(0x00008182, Size2) }, + { BA(2, Size3), BD(0x00008384, Size2) }, + { BA(3, Size3), BD(0x00008384, Size2) }, + + { BA(0, Size4), BD(0x00008182, Size2) }, + { BA(1, Size4), BD(0x00008182, Size2) }, + { BA(2, Size4), BD(0x00008384, Size2) }, + { BA(3, Size4), BD(0x00008384, Size2) }, + }, + .table_write = { + { BA(0, Size1), W1, BD(0, Size2), "AA345678" }, + { BA(1, Size1), W1, BD(0, Size2), "AA345678" }, + { BA(2, Size1), W1, BD(0, Size2), "12AA5678" }, + { BA(3, Size1), W1, BD(0, Size2), "12AA5678" }, + + { BA(0, Size2), W2, BD(0, Size2), "AB345678" }, + { BA(1, Size2), W2, BD(0, Size2), "AA345678" }, + { BA(2, Size2), W2, BD(0, Size2), "12AB5678" }, + { BA(3, Size2), W2, BD(0, Size2), "12AA5678" }, + + { BA(0, Size3), W3, BD(0, Size2), "AB345678" }, + { BA(1, Size3), W3, BD(0, Size2), "AA345678" }, + { BA(2, Size3), W3, BD(0, Size2), "12AB5678" }, + { BA(3, Size3), W3, BD(0, Size2), "12AA5678" }, + + { BA(0, Size4), W4, BD(0, Size2), "AB345678" }, + { BA(1, Size4), W4, BD(0, Size2), "AA345678" }, + { BA(2, Size4), W4, BD(0, Size2), "12AB5678" }, + { BA(3, Size4), W4, BD(0, Size2), "12AA5678" }, + }, +}; + +static TestData +table_WF = { + .name = "BusIO_WF", + .table_read = { + { BA(0, Size1), BD(0x8182ffff, Size4) }, + { BA(1, Size1), BD(0x8182ffff, Size4) }, + { BA(2, Size1), BD(0x8182ffff, Size4) }, + { BA(3, Size1), BD(0x8182ffff, Size4) }, + { BA(4, Size1), BD(0x8384ffff, Size4) }, + { BA(5, Size1), BD(0x8384ffff, Size4) }, + { BA(6, Size1), BD(0x8384ffff, Size4) }, + { BA(7, Size1), BD(0x8384ffff, Size4) }, + + { BA(0, Size2), BD(0x8182ffff, Size4) }, + { BA(1, Size2), BD(0x8182ffff, Size4) }, + { BA(2, Size2), BD(0x8182ffff, Size4) }, + { BA(3, Size2), BD(0x8182ffff, Size4) }, + { BA(4, Size2), BD(0x8384ffff, Size4) }, + { BA(5, Size2), BD(0x8384ffff, Size4) }, + { BA(6, Size2), BD(0x8384ffff, Size4) }, + { BA(7, Size2), BD(0x8384ffff, Size4) }, + + { BA(0, Size3), BD(0x8182ffff, Size4) }, + { BA(1, Size3), BD(0x8182ffff, Size4) }, + { BA(2, Size3), BD(0x8182ffff, Size4) }, + { BA(3, Size3), BD(0x8182ffff, Size4) }, + { BA(4, Size3), BD(0x8384ffff, Size4) }, + { BA(5, Size3), BD(0x8384ffff, Size4) }, + { BA(6, Size3), BD(0x8384ffff, Size4) }, + { BA(7, Size3), BD(0x8384ffff, Size4) }, + + { BA(0, Size4), BD(0x8182ffff, Size4) }, + { BA(1, Size4), BD(0x8182ffff, Size4) }, + { BA(2, Size4), BD(0x8182ffff, Size4) }, + { BA(3, Size4), BD(0x8182ffff, Size4) }, + { BA(4, Size4), BD(0x8384ffff, Size4) }, + { BA(5, Size4), BD(0x8384ffff, Size4) }, + { BA(6, Size4), BD(0x8384ffff, Size4) }, + { BA(7, Size4), BD(0x8384ffff, Size4) }, + }, + .table_write = { + { BA(0, Size1), W1, BD(0, Size4), "AA345678" }, + { BA(1, Size1), W1, BD(0, Size4), "AA345678" }, + { BA(2, Size1), W1, BD(0, Size4), "AA345678" }, + { BA(3, Size1), W1, BD(0, Size4), "AA345678" }, + { BA(4, Size1), W1, BD(0, Size4), "12AA5678" }, + { BA(5, Size1), W1, BD(0, Size4), "12AA5678" }, + { BA(6, Size1), W1, BD(0, Size4), "12AA5678" }, + { BA(7, Size1), W1, BD(0, Size4), "12AA5678" }, + + { BA(0, Size2), W2, BD(0, Size4), "AB345678" }, + { BA(1, Size2), W2, BD(0, Size4), "AB345678" }, + { BA(2, Size2), W2, BD(0, Size4), "AB345678" }, + { BA(3, Size2), W2, BD(0, Size4), "AB345678" }, + { BA(4, Size2), W2, BD(0, Size4), "12AB5678" }, + { BA(5, Size2), W2, BD(0, Size4), "12AB5678" }, + { BA(6, Size2), W2, BD(0, Size4), "12AB5678" }, + { BA(7, Size2), W2, BD(0, Size4), "12AB5678" }, + + // 3バイトは来ないはず? + + { BA(0, Size4), W4, BD(0, Size4), "AB345678" }, + { BA(1, Size4), W4, BD(0, Size4), "AB345678" }, + { BA(2, Size4), W4, BD(0, Size4), "AB345678" }, + { BA(3, Size4), W4, BD(0, Size4), "AB345678" }, + { BA(4, Size4), W4, BD(0, Size4), "12AB5678" }, + { BA(5, Size4), W4, BD(0, Size4), "12AB5678" }, + { BA(6, Size4), W4, BD(0, Size4), "12AB5678" }, + { BA(7, Size4), W4, BD(0, Size4), "12AB5678" }, + }, +}; + +static TestData +table_L = { + .name = "BusIO_L", + .table_read = { + { BA(0, Size1), BD(0x81828384, Size4) }, + { BA(1, Size1), BD(0x81828384, Size4) }, + { BA(2, Size1), BD(0x81828384, Size4) }, + { BA(3, Size1), BD(0x81828384, Size4) }, + { BA(4, Size1), BD(0x85868788, Size4) }, + { BA(5, Size1), BD(0x85868788, Size4) }, + { BA(6, Size1), BD(0x85868788, Size4) }, + { BA(7, Size1), BD(0x85868788, Size4) }, + + { BA(0, Size2), BD(0x81828384, Size4) }, + { BA(1, Size2), BD(0x81828384, Size4) }, + { BA(2, Size2), BD(0x81828384, Size4) }, + { BA(3, Size2), BD(0x81828384, Size4) }, + { BA(4, Size2), BD(0x85868788, Size4) }, + { BA(5, Size2), BD(0x85868788, Size4) }, + { BA(6, Size2), BD(0x85868788, Size4) }, + { BA(7, Size2), BD(0x85868788, Size4) }, + + { BA(0, Size3), BD(0x81828384, Size4) }, + { BA(1, Size3), BD(0x81828384, Size4) }, + { BA(2, Size3), BD(0x81828384, Size4) }, + { BA(3, Size3), BD(0x81828384, Size4) }, + { BA(4, Size3), BD(0x85868788, Size4) }, + { BA(5, Size3), BD(0x85868788, Size4) }, + { BA(6, Size3), BD(0x85868788, Size4) }, + { BA(7, Size3), BD(0x85868788, Size4) }, + + { BA(0, Size4), BD(0x81828384, Size4) }, + { BA(1, Size4), BD(0x81828384, Size4) }, + { BA(2, Size4), BD(0x81828384, Size4) }, + { BA(3, Size4), BD(0x81828384, Size4) }, + { BA(4, Size4), BD(0x85868788, Size4) }, + { BA(5, Size4), BD(0x85868788, Size4) }, + { BA(6, Size4), BD(0x85868788, Size4) }, + { BA(7, Size4), BD(0x85868788, Size4) }, + }, + .table_write = { + { BA(0, Size1), W1, BD(0, Size4), "AAAA5678" }, + { BA(1, Size1), W1, BD(0, Size4), "AAAA5678" }, + { BA(2, Size1), W1, BD(0, Size4), "AAAA5678" }, + { BA(3, Size1), W1, BD(0, Size4), "AAAA5678" }, + + { BA(0, Size2), W2, BD(0, Size4), "ABAB5678" }, + { BA(1, Size2), W2, BD(0, Size4), "AABA5678" }, + { BA(2, Size2), W2, BD(0, Size4), "ABAB5678" }, + { BA(3, Size2), W2, BD(0, Size4), "AABA5678" }, + + { BA(0, Size3), W3, BD(0, Size4), "ABC05678" }, + { BA(1, Size3), W3, BD(0, Size4), "AABC5678" }, + { BA(2, Size3), W3, BD(0, Size4), "ABAB5678" }, + { BA(3, Size3), W3, BD(0, Size4), "AABA5678" }, + + { BA(0, Size4), W4, BD(0, Size4), "ABCD5678" }, + { BA(1, Size4), W4, BD(0, Size4), "AABC5678" }, + { BA(2, Size4), W4, BD(0, Size4), "ABAB5678" }, + { BA(3, Size4), W4, BD(0, Size4), "AABA5678" }, + }, +}; + int main() { - do_test(&testdata_b[0], new BusIO_B()); - do_test(&testdata_b[1], new BusIO_BB()); - do_test(&testdata_b[2], new BusIO_BBBB()); - do_test(&testdata_b[3], new BusIO_BE()); - do_test(&testdata_b[4], new BusIO_EB()); - do_test(&testdata_b[5], new BusIO_FB()); - do_test(&testdata_b[6], new BusIO_BFFF()); - - do_test(&testdata_w[0], new BusIO_W()); - do_test(&testdata_w[1], new BusIO_WW()); - do_test(&testdata_w[2], new BusIO_WF()); + do_test(new BusIO_B(), table_B); + do_test(new BusIO_BB(), table_BB); + do_test(new BusIO_BBBB(), table_BBBB); + do_test(new BusIO_BFFF(), table_BFFF); + do_test(new BusIO_EB(), table_EB); + do_test(new BusIO_FB(), table_FB); + + do_test(new BusIO_W(), table_W); + do_test(new BusIO_WF(), table_WF); + + do_test(new BusIO_L(), table_L); + return 0; }