diff --git a/src/cpu/arm/exec.cc b/src/cpu/arm/exec.cc index 806455b..a6c2048 100644 --- a/src/cpu/arm/exec.cc +++ b/src/cpu/arm/exec.cc @@ -282,17 +282,18 @@ Instruction::exec(Cpu& cpu) { cpu.is_flushed = true; }, [&cpu, pc_error](BlockDataTransfer& data) { - uint32_t address = cpu.gpr[data.rn]; - Mode mode = cpu.cpsr.mode(); - uint8_t alignment = 4; // word - uint8_t i = 0; - uint8_t n_regs = std::popcount(data.regs); + static constexpr uint8_t alignment = 4; // word + + uint32_t address = cpu.gpr[data.rn]; + Mode mode = cpu.cpsr.mode(); + uint8_t i = 0; + uint8_t n_regs = std::popcount(data.regs); pc_error(data.rn); if (cpu.cpsr.mode() == Mode::User && data.s) { - glogger.error("Bit S is set outside priviliged modes in {}", - typeid(data).name()); + glogger.error("Bit S is set outside priviliged modes in block " + "data transfer"); } // we just change modes to load user registers @@ -301,9 +302,8 @@ Instruction::exec(Cpu& cpu) { cpu.chg_mode(Mode::User); if (data.write) { - glogger.error( - "Write-back enable for user bank registers in {}", - typeid(data).name()); + glogger.error("Write-back enable for user bank registers " + "in block data transfer"); } } diff --git a/src/cpu/thumb/exec.cc b/src/cpu/thumb/exec.cc index 8e43b98..b8bf328 100644 --- a/src/cpu/thumb/exec.cc +++ b/src/cpu/thumb/exec.cc @@ -286,47 +286,51 @@ Instruction::exec(Cpu& cpu) { }, [&cpu](AddOffsetStackPointer& data) { cpu.sp += data.word; }, [&cpu](PushPopRegister& data) { + static constexpr uint8_t alignment = 4; + if (data.load) { for (uint8_t i = 0; i < 8; i++) { if (get_bit(data.regs, i)) { cpu.gpr[i] = cpu.bus->read_word(cpu.sp); - cpu.sp += 4; + cpu.sp += alignment; } } if (data.pclr) { cpu.pc = cpu.bus->read_word(cpu.sp); - cpu.sp += 4; + cpu.sp += alignment; cpu.is_flushed = true; } } else { if (data.pclr) { - cpu.sp -= 4; + cpu.sp -= alignment; cpu.bus->write_word(cpu.sp, cpu.lr); } for (int8_t i = 7; i >= 0; i--) { if (get_bit(data.regs, i)) { - cpu.sp -= 4; + cpu.sp -= alignment; cpu.bus->write_word(cpu.sp, cpu.gpr[i]); } } } }, [&cpu](MultipleLoad& data) { + static constexpr uint8_t alignment = 4; + uint32_t rb = cpu.gpr[data.rb]; if (data.load) { for (uint8_t i = 0; i < 8; i++) { if (get_bit(data.regs, i)) { cpu.gpr[i] = cpu.bus->read_word(rb); - rb += 4; + rb += alignment; } } } else { for (int8_t i = 7; i >= 0; i--) { if (get_bit(data.regs, i)) { - rb -= 4; + rb -= alignment; cpu.bus->write_word(rb, cpu.gpr[i]); } } diff --git a/src/memory.cc b/src/memory.cc index e96bfc9..380e500 100644 --- a/src/memory.cc +++ b/src/memory.cc @@ -64,23 +64,17 @@ Memory::write(size_t address, uint8_t byte) { return; \ } - MATCHES(BIOS, bios) MATCHES(BOARD_WRAM, board_wram) MATCHES(CHIP_WRAM, chip_wram) MATCHES(PALETTE_RAM, palette_ram) MATCHES(VRAM, vram) MATCHES(OAM_OBJ_ATTR, oam_obj_attr) - MATCHES(ROM_0, rom) - MATCHES(ROM_1, rom) - MATCHES(ROM_2, rom) glogger.error("Invalid memory region accessed"); #undef MATCHES } -#undef MATCHES - void Memory::parse_header() { if (rom.size() < header.HEADER_SIZE) { diff --git a/tests/bus.cc b/tests/bus.cc index b565b56..1210cd7 100644 --- a/tests/bus.cc +++ b/tests/bus.cc @@ -16,30 +16,30 @@ class BusFixture { }; TEST_CASE_METHOD(BusFixture, "Byte", TAG) { - CHECK(bus.read_byte(3349) == 0); + CHECK(bus.read_byte(0x30001A9) == 0); - bus.write_byte(3349, 0xEC); - CHECK(bus.read_byte(3349) == 0xEC); - CHECK(bus.read_word(3349) == 0xEC); - CHECK(bus.read_halfword(3349) == 0xEC); + bus.write_byte(0x30001A9, 0xEC); + CHECK(bus.read_byte(0x30001A9) == 0xEC); + CHECK(bus.read_word(0x30001A9) == 0xEC); + CHECK(bus.read_halfword(0x30001A9) == 0xEC); } TEST_CASE_METHOD(BusFixture, "Halfword", TAG) { - CHECK(bus.read_halfword(33750745) == 0); + CHECK(bus.read_halfword(0x202FED9) == 0); - bus.write_halfword(33750745, 0x1A4A); - CHECK(bus.read_halfword(33750745) == 0x1A4A); - CHECK(bus.read_word(33750745) == 0x1A4A); - CHECK(bus.read_byte(33750745) == 0x4A); + bus.write_halfword(0x202FED9, 0x1A4A); + CHECK(bus.read_halfword(0x202FED9) == 0x1A4A); + CHECK(bus.read_word(0x202FED9) == 0x1A4A); + CHECK(bus.read_byte(0x202FED9) == 0x4A); } TEST_CASE_METHOD(BusFixture, "Word", TAG) { - CHECK(bus.read_word(100724276) == 0); + CHECK(bus.read_word(0x600EE34) == 0); - bus.write_word(100724276, 0x3ACC491D); - CHECK(bus.read_word(100724276) == 0x3ACC491D); - CHECK(bus.read_halfword(100724276) == 0x491D); - CHECK(bus.read_byte(100724276) == 0x1D); + bus.write_word(0x600EE34, 0x3ACC491D); + CHECK(bus.read_word(0x600EE34) == 0x3ACC491D); + CHECK(bus.read_halfword(0x600EE34) == 0x491D); + CHECK(bus.read_byte(0x600EE34) == 0x1D); } #undef TAG diff --git a/tests/cpu/arm/exec.cc b/tests/cpu/arm/exec.cc index 48239a8..579f04d 100644 --- a/tests/cpu/arm/exec.cc +++ b/tests/cpu/arm/exec.cc @@ -1,6 +1,8 @@ +#include "cpu/arm/instruction.hh" #include "cpu/cpu-fixture.hh" #include "util/bits.hh" #include +#include using namespace matar; @@ -170,7 +172,7 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Swap", TAG) { SingleDataSwap{ .rm = 3, .rd = 4, .rn = 9, .byte = false }; SingleDataSwap* swap = std::get_if(&data); - setr(9, 0x3FED); + setr(9, 0x3003FED); setr(3, 94235087); setr(3, -259039045); bus.write_word(getr(9), 3241011111); @@ -210,14 +212,14 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { .pre = true }; SingleDataTransfer* data_transfer = std::get_if(&data); - setr(3, 1596); - setr(7, 6); + setr(3, 0x63C); + setr(7, 0x3000004); setr(5, -911111); // shifted register (immediate) { - // 12768 + 6 - bus.write_word(12774, 95995); + // 0x31E + 0x3000004 + bus.write_word(0x30031E4, 95995); exec(data); CHECK(getr(5) == 95995); @@ -234,8 +236,8 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { } }; setr(12, 2); - // 6384 + 6 - bus.write_word(6390, 3948123487); + // 6384 + 0x3000004 + bus.write_word(0x30018F4, 3948123487); exec(data); CHECK(getr(5) == 3948123487); @@ -243,9 +245,9 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { // immediate { - data_transfer->offset = static_cast(3489); - // 6 + 3489 - bus.write_word(3495, 68795467); + data_transfer->offset = static_cast(0xDA1); + // 0xDA1 + 0x3000004 + bus.write_word(0x3000DA5, 68795467); exec(data); @@ -254,41 +256,42 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { // down { - setr(7, 18044); + setr(7, 0x3005E0D); data_transfer->up = false; - // 18044 - 3489 - bus.write_word(14555, 5949595); + // 0x3005E0D - 0xDA1 + bus.write_word(0x300506C, 5949595); exec(data); CHECK(getr(5) == 5949595); // no write back - CHECK(getr(7) == 18044); + CHECK(getr(7) == 0x3005E0D); } // write { data_transfer->write = true; - bus.write_word(14555, 967844); + // 0x3005E0D - 0xDA1 + bus.write_word(0x300506C, 967844); exec(data); CHECK(getr(5) == 967844); - // 18044 - 3489 - CHECK(getr(7) == 14555); + // 0x3005E0D - 0xDA1 + CHECK(getr(7) == 0x300506C); } // post { data_transfer->write = false; data_transfer->pre = false; - bus.write_word(14555, 61119); + bus.write_word(0x300506C, 61119); exec(data); CHECK(getr(5) == 61119); - // 14555 - 3489 - CHECK(getr(7) == 11066); + // 0x300506C - 0xDA1 + CHECK(getr(7) == 0x30042CB); } // store @@ -297,21 +300,21 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { exec(data); - CHECK(bus.read_word(11066) == 61119); - // 11066 - 3489 - CHECK(getr(7) == 7577); + CHECK(bus.read_word(0x30042CB) == 61119); + // 0x30042CB - 0xDA1 + CHECK(getr(7) == 0x300352A); } // r15 as rn { data_transfer->rn = 15; - setr(15, 7577); + setr(15, 0x300352A); exec(data); - CHECK(bus.read_word(7577 - 2 * INSTRUCTION_SIZE) == 61119); - // 7577 - 3489 - CHECK(getr(15) == 4088 - 2 * INSTRUCTION_SIZE); + CHECK(bus.read_word(0x300352A - 2 * INSTRUCTION_SIZE) == 61119); + // 0x300352A - 0xDA1 + CHECK(getr(15) == 0x3002789 - 2 * INSTRUCTION_SIZE); // cleanup data_transfer->rn = 7; @@ -319,15 +322,14 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { // r15 as rd { - // 4088 data_transfer->rd = 15; setr(15, 444444); exec(data); - CHECK(bus.read_word(7577 + INSTRUCTION_SIZE) == 444444); - // 7577 - 3489 - CHECK(getr(7) == 4088 + INSTRUCTION_SIZE); + CHECK(bus.read_word(0x300352A + INSTRUCTION_SIZE) == 444444); + // 0x300352A - 0xDA1 + CHECK(getr(7) == 0x3002789 + INSTRUCTION_SIZE); // cleanup data_transfer->rd = 5; @@ -342,9 +344,9 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { exec(data); - CHECK(bus.read_word(4088) == (458267584 & 0xFF)); - // 4088 - 3489 - CHECK(getr(7) == 599); + CHECK(bus.read_word(0x3002789) == (458267584 & 0xFF)); + // 0x3002789 - 0xDA1 + CHECK(getr(7) == 0x30019E8); } } @@ -361,14 +363,14 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { .pre = true }; HalfwordTransfer* hw_transfer = std::get_if(&data); - setr(12, 8404); + setr(12, 0x384); setr(11, 459058287); - setr(10, 900); + setr(10, 0x300611E); // register offset { - // 900 + 8404 - bus.write_word(9304, 3948123487); + // 0x300611E + 0x384 + bus.write_word(0x30064A2, 3948123487); exec(data); CHECK(getr(11) == (3948123487 & 0xFFFF)); @@ -377,9 +379,9 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { // immediate offset { hw_transfer->imm = true; - hw_transfer->offset = 167; - // 900 + 167 - bus.write_word(1067, 594633302); + hw_transfer->offset = 0xA7; + // 0x300611E + 0xA7 + bus.write_word(0x30061C5, 594633302); exec(data); CHECK(getr(11) == (594633302 & 0xFFFF)); @@ -388,40 +390,39 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { // down { hw_transfer->up = false; - // 900 - 167 - bus.write_word(733, 222221); + // 0x300611E - 0xA7 + bus.write_word(0x3006077, 222221); exec(data); CHECK(getr(11) == (222221 & 0xFFFF)); // no write back - CHECK(getr(10) == 900); + CHECK(getr(10) == 0x300611E); } // write { hw_transfer->write = true; - // 900 - 167 - bus.write_word(733, 100000005); + // 0x300611E - 0xA7 + bus.write_word(0x3006077, 100000005); exec(data); CHECK(getr(11) == (100000005 & 0xFFFF)); - // 900 - 167 - CHECK(getr(10) == 733); + CHECK(getr(10) == 0x3006077); } // post { hw_transfer->pre = false; hw_transfer->write = false; - bus.write_word(733, 6111909); + bus.write_word(0x3006077, 6111909); exec(data); CHECK(getr(11) == (6111909 & 0xFFFF)); - // 733 - 167 - CHECK(getr(10) == 566); + // 0x3006077 - 0xA7 + CHECK(getr(10) == 0x3005FD0); } // store @@ -430,22 +431,22 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { exec(data); - CHECK(bus.read_halfword(566) == (6111909 & 0xFFFF)); - // 566 - 167 - CHECK(getr(10) == 399); + CHECK(bus.read_halfword(0x3005FD0) == (6111909 & 0xFFFF)); + // 0x3005FD0 - 0xA7 + CHECK(getr(10) == 0x3005F29); } // r15 as rn { hw_transfer->rn = 15; - setr(15, 399); + setr(15, 0x3005F29); exec(data); - CHECK(bus.read_halfword(399 - 2 * INSTRUCTION_SIZE) == + CHECK(bus.read_halfword(0x3005F29 - 2 * INSTRUCTION_SIZE) == (6111909 & 0xFFFF)); - // 399 - 167 - CHECK(getr(15) == 232 - 2 * INSTRUCTION_SIZE); + // 0x3005F29 - 0xA7 + CHECK(getr(15) == 0x3005E82 - 2 * INSTRUCTION_SIZE); // cleanup hw_transfer->rn = 10; @@ -458,38 +459,38 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { exec(data); - CHECK(bus.read_halfword(399 + INSTRUCTION_SIZE) == 224); - // 399 - 167 - CHECK(getr(10) == 232 + INSTRUCTION_SIZE); + CHECK(bus.read_halfword(0x3005F29 + INSTRUCTION_SIZE) == 224); + // 0x3005F29 - 0xA7 + CHECK(getr(10) == 0x3005E82 + INSTRUCTION_SIZE); // cleanup hw_transfer->rd = 11; - setr(10, 399); + setr(10, getr(10) - INSTRUCTION_SIZE); } // signed halfword { hw_transfer->load = true; hw_transfer->sign = true; - bus.write_halfword(399, -12345); + bus.write_halfword(0x3005E82, -12345); exec(data); CHECK(getr(11) == static_cast(-12345)); - // 399 - 167 - CHECK(getr(10) == 232); + // 0x3005E82 - 0xA7 + CHECK(getr(10) == 0x3005DDB); } // signed byte { hw_transfer->half = false; - bus.write_byte(232, -56); + bus.write_byte(0x3005DDB, -56); exec(data); CHECK(getr(11) == static_cast(-56)); - // 232 - 167 - CHECK(getr(10) == 65); + // 0x3005DDB - 0xA7 + CHECK(getr(10) == 0x3005D34); } } @@ -502,19 +503,21 @@ TEST_CASE_METHOD(CpuFixture, "Block Data Transfer", TAG) { .up = true, .pre = true }; - BlockDataTransfer* block_transfer = std::get_if(&data); + BlockDataTransfer* block_transfer = std::get_if(&data); + static constexpr uint8_t alignment = 4; // load SECTION("load") { + static constexpr uint32_t address = 0x3000D78; // populate memory - bus.write_word(3448, 38947234); - bus.write_word(3452, 237164); - bus.write_word(3456, 679785111); - bus.write_word(3460, 905895898); - bus.write_word(3464, 131313333); - bus.write_word(3468, 131); - bus.write_word(3472, 989231); - bus.write_word(3476, 6); + bus.write_word(address, 38947234); + bus.write_word(address + alignment, 237164); + bus.write_word(address + alignment * 2, 679785111); + bus.write_word(address + alignment * 3, 905895898); + bus.write_word(address + alignment * 4, 131313333); + bus.write_word(address + alignment * 5, 131); + bus.write_word(address + alignment * 6, 989231); + bus.write_word(address + alignment * 7, 6); auto checker = [this](uint32_t rnval = 0) { CHECK(getr(0) == 237164); @@ -539,45 +542,45 @@ TEST_CASE_METHOD(CpuFixture, "Block Data Transfer", TAG) { } }; - setr(10, 3448); + setr(10, address); exec(data); - checker(3448); + checker(address); // with write - setr(10, 3448); + setr(10, address); block_transfer->write = true; exec(data); - checker(3448 + INSTRUCTION_SIZE); + checker(address + alignment); // decrement block_transfer->write = false; block_transfer->up = false; // adjust rn - setr(10, 3480); + setr(10, address + alignment * 8); exec(data); - checker(3480); + checker(address + alignment * 8); // with write - setr(10, 3480); + setr(10, 0x3000D98); block_transfer->write = true; exec(data); - checker(3480 - INSTRUCTION_SIZE); + checker(address + alignment * 7); // post increment block_transfer->write = false; block_transfer->up = true; block_transfer->pre = false; // adjust rn - setr(10, 3452); + setr(10, address + alignment); exec(data); - checker(3452 + INSTRUCTION_SIZE); + checker(address + alignment * 2); // post decrement block_transfer->up = false; // adjust rn - setr(10, 3476); + setr(10, address + alignment * 7); exec(data); - checker(3476 - INSTRUCTION_SIZE); + checker(address + alignment * 6); // with s bit cpu.chg_mode(Mode::Fiq); @@ -589,6 +592,8 @@ TEST_CASE_METHOD(CpuFixture, "Block Data Transfer", TAG) { // store SECTION("store") { + static constexpr uint32_t address = 0x30015A8; + block_transfer->load = false; // populate registers @@ -601,19 +606,19 @@ TEST_CASE_METHOD(CpuFixture, "Block Data Transfer", TAG) { setr(15, 6); auto checker = [this]() { - CHECK(bus.read_word(5548) == 237164); - CHECK(bus.read_word(5552) == 679785111); - CHECK(bus.read_word(5556) == 905895898); - CHECK(bus.read_word(5560) == 131313333); - CHECK(bus.read_word(5564) == 131); - CHECK(bus.read_word(5568) == 989231); - CHECK(bus.read_word(5572) == 6); + CHECK(bus.read_word(address + alignment) == 237164); + CHECK(bus.read_word(address + alignment * 2) == 679785111); + CHECK(bus.read_word(address + alignment * 3) == 905895898); + CHECK(bus.read_word(address + alignment * 4) == 131313333); + CHECK(bus.read_word(address + alignment * 5) == 131); + CHECK(bus.read_word(address + alignment * 6) == 989231); + CHECK(bus.read_word(address + alignment * 7) == 6); - for (uint8_t i = 0; i < 8; i++) - bus.write_word(5548 + i * 4, 0); + for (uint8_t i = 1; i < 8; i++) + bus.write_word(address + alignment * i, 0); }; - setr(10, 5544); // base + setr(10, address); // base exec(data); checker(); @@ -621,7 +626,7 @@ TEST_CASE_METHOD(CpuFixture, "Block Data Transfer", TAG) { block_transfer->write = false; block_transfer->up = false; // adjust rn - setr(10, 5576); + setr(10, address + alignment * 8); exec(data); checker(); @@ -629,24 +634,23 @@ TEST_CASE_METHOD(CpuFixture, "Block Data Transfer", TAG) { block_transfer->up = true; block_transfer->pre = false; // adjust rn - setr(10, 5548); + setr(10, address + alignment); exec(data); checker(); // post decrement block_transfer->up = false; // adjust rn - setr(10, 5572); + setr(10, address + alignment * 7); exec(data); checker(); // with s bit cpu.chg_mode(Mode::Fiq); block_transfer->s = true; - cpu.chg_mode(Mode::Supervisor); - // User's R13 is different (unset at this point) - CHECK(bus.read_word(5568) == 0); exec(data); + // User's R13 is different (unset at this point) + CHECK(bus.read_word(address + alignment * 6) == 0); } } diff --git a/tests/cpu/cpu-fixture.cc b/tests/cpu/cpu-fixture.cc index 08fd050..c08dacd 100644 --- a/tests/cpu/cpu-fixture.cc +++ b/tests/cpu/cpu-fixture.cc @@ -41,17 +41,17 @@ CpuFixture::set_psr(Psr psr, bool spsr) { // matters is that the public API is correct. uint32_t CpuFixture::getr_(uint8_t r, Cpu& cpu) { - size_t addr = 13000; - size_t offset = r == 15 ? 4 : 0; - uint32_t word = bus.read_word(addr + offset); - Cpu tmp = cpu; - uint32_t ret = 0xFFFFFFFF; - uint8_t base = r ? 0 : 1; + uint32_t addr = 0x02000000; + uint8_t offset = r == 15 ? 4 : 0; + uint32_t word = bus.read_word(addr + offset); + Cpu tmp = cpu; + uint32_t ret = 0xFFFFFFFF; + uint8_t base = r ? 0 : 1; - // set R0/R1 = 0 + // set R0/R1 = addr arm::Instruction zero( Condition::AL, - arm::DataProcessing{ .operand = 0u, + arm::DataProcessing{ .operand = addr, .rd = base, .rn = 0, .set = false, @@ -60,7 +60,7 @@ CpuFixture::getr_(uint8_t r, Cpu& cpu) { // get register arm::Instruction get( Condition::AL, - arm::SingleDataTransfer{ .offset = static_cast(addr), + arm::SingleDataTransfer{ .offset = static_cast(0), .rd = r, .rn = base, .load = false, diff --git a/tests/cpu/thumb/exec.cc b/tests/cpu/thumb/exec.cc index 6feabad..6227966 100644 --- a/tests/cpu/thumb/exec.cc +++ b/tests/cpu/thumb/exec.cc @@ -528,11 +528,11 @@ TEST_CASE_METHOD(CpuFixture, "Hi Register Operations/Branch Exchange", TAG) { } TEST_CASE_METHOD(CpuFixture, "PC Relative Load", TAG) { - InstructionData data = PcRelativeLoad{ .word = 380, .rd = 0 }; + InstructionData data = PcRelativeLoad{ .word = 0x578, .rd = 0 }; - setr(15, 13804); - // 13804 + 380 - bus.write_word(14184, 489753492); + setr(15, 0x3003FD5); + // 0x3003FD5 + 0x578 + bus.write_word(0x300454D, 489753492); CHECK(getr(0) == 0); exec(data); @@ -545,26 +545,26 @@ TEST_CASE_METHOD(CpuFixture, "Load/Store with Register Offset", TAG) { }; LoadStoreRegisterOffset* load = std::get_if(&data); - setr(7, 9910); - setr(0, 1034); + setr(7, 0x3003000); + setr(0, 0x332); setr(3, 389524259); SECTION("store") { - // 9910 + 1034 - CHECK(bus.read_word(10944) == 0); + // 0x3003000 + 0x332 + CHECK(bus.read_word(0x3003332) == 0); exec(data); - CHECK(bus.read_word(10944) == 389524259); + CHECK(bus.read_word(0x3003332) == 389524259); // byte load->byte = true; - bus.write_word(10944, 0); + bus.write_word(0x3003332, 0); exec(data); - CHECK(bus.read_word(10944) == 35); + CHECK(bus.read_word(0x3003332) == 35); } SECTION("load") { load->load = true; - bus.write_word(10944, 11123489); + bus.write_word(0x3003332, 11123489); exec(data); CHECK(getr(3) == 11123489); @@ -582,27 +582,27 @@ TEST_CASE_METHOD(CpuFixture, "Load/Store Sign Extended Byte/Halfword", TAG) { LoadStoreSignExtendedHalfword* load = std::get_if(&data); - setr(7, 9910); - setr(0, 1034); + setr(7, 0x3003000); + setr(0, 0x332); setr(3, 389524259); SECTION("SH = 00") { - // 9910 + 1034 - CHECK(bus.read_word(10944) == 0); + // 0x3003000 + 0x332 + CHECK(bus.read_word(0x3003332) == 0); exec(data); - CHECK(bus.read_word(10944) == 43811); + CHECK(bus.read_word(0x3003332) == 43811); } SECTION("SH = 01") { load->h = true; - bus.write_word(10944, 11123489); + bus.write_word(0x3003332, 11123489); exec(data); CHECK(getr(3) == 47905); } SECTION("SH = 10") { load->s = true; - bus.write_word(10944, 34521594); + bus.write_word(0x3003332, 34521594); exec(data); // sign extended 250 byte (0xFA) CHECK(getr(3) == 4294967290); @@ -611,7 +611,7 @@ TEST_CASE_METHOD(CpuFixture, "Load/Store Sign Extended Byte/Halfword", TAG) { SECTION("SH = 11") { load->s = true; load->h = true; - bus.write_word(10944, 11123489); + bus.write_word(0x3003332, 11123489); // sign extended 47905 halfword (0xBB21) exec(data); CHECK(getr(3) == 4294949665); @@ -620,30 +620,30 @@ TEST_CASE_METHOD(CpuFixture, "Load/Store Sign Extended Byte/Halfword", TAG) { TEST_CASE_METHOD(CpuFixture, "Load/Store with Immediate Offset", TAG) { InstructionData data = LoadStoreImmediateOffset{ - .rd = 3, .rb = 0, .offset = 110, .load = false, .byte = false + .rd = 3, .rb = 0, .offset = 0x6E, .load = false, .byte = false }; LoadStoreImmediateOffset* load = std::get_if(&data); - setr(0, 1034); + setr(0, 0x300666A); setr(3, 389524259); SECTION("store") { - // 110 + 1034 - CHECK(bus.read_word(1144) == 0); + // 0x30066A + 0x6E + CHECK(bus.read_word(0x30066D8) == 0); exec(data); - CHECK(bus.read_word(1144) == 389524259); + CHECK(bus.read_word(0x30066D8) == 389524259); // byte load->byte = true; - bus.write_word(1144, 0); + bus.write_word(0x30066D8, 0); exec(data); - CHECK(bus.read_word(1144) == 35); + CHECK(bus.read_word(0x30066D8) == 35); } SECTION("load") { load->load = true; - bus.write_word(1144, 11123489); + bus.write_word(0x30066D8, 11123489); exec(data); CHECK(getr(3) == 11123489); @@ -656,22 +656,22 @@ TEST_CASE_METHOD(CpuFixture, "Load/Store with Immediate Offset", TAG) { TEST_CASE_METHOD(CpuFixture, "Load/Store Halfword", TAG) { InstructionData data = - LoadStoreHalfword{ .rd = 3, .rb = 0, .offset = 110, .load = false }; + LoadStoreHalfword{ .rd = 3, .rb = 0, .offset = 0x6E, .load = false }; LoadStoreHalfword* load = std::get_if(&data); - setr(0, 1034); + setr(0, 0x300666A); setr(3, 389524259); SECTION("store") { - // 110 + 1034 - CHECK(bus.read_word(1144) == 0); + // 0x300666A + 0x6E + CHECK(bus.read_word(0x30066D8) == 0); exec(data); - CHECK(bus.read_word(1144) == 43811); + CHECK(bus.read_word(0x30066D8) == 43811); } SECTION("load") { load->load = true; - bus.write_word(1144, 11123489); + bus.write_word(0x30066D8, 11123489); exec(data); CHECK(getr(3) == 47905); } @@ -679,23 +679,23 @@ TEST_CASE_METHOD(CpuFixture, "Load/Store Halfword", TAG) { TEST_CASE_METHOD(CpuFixture, "SP Relative Load", TAG) { InstructionData data = - SpRelativeLoad{ .word = 808, .rd = 1, .load = false }; + SpRelativeLoad{ .word = 0x328, .rd = 1, .load = false }; SpRelativeLoad* load = std::get_if(&data); setr(1, 2349505744); // sp - setr(13, 336); + setr(13, 0x3004A8A); SECTION("store") { - // 110 + 1034 - CHECK(bus.read_word(1144) == 0); + // 0x3004A8A + 0x328 + CHECK(bus.read_word(0x3004DB2) == 0); exec(data); - CHECK(bus.read_word(1144) == 2349505744); + CHECK(bus.read_word(0x3004DB2) == 2349505744); } SECTION("load") { load->load = true; - bus.write_word(1144, 11123489); + bus.write_word(0x3004DB2, 11123489); exec(data); CHECK(getr(1) == 11123489); } @@ -745,8 +745,11 @@ TEST_CASE_METHOD(CpuFixture, "Push/Pop Registers", TAG) { InstructionData data = PushPopRegister{ .regs = 0b11010011, .pclr = false, .load = false }; PushPopRegister* push = std::get_if(&data); - // registers = 0, 1, 4, 6, 7 + static constexpr uint8_t alignment = 4; + static constexpr uint32_t address = 0x30015AC; + + // registers = 0, 1, 4, 6, 7 SECTION("push (store)") { // populate registers @@ -758,33 +761,33 @@ TEST_CASE_METHOD(CpuFixture, "Push/Pop Registers", TAG) { auto checker = [this]() { // address - CHECK(bus.read_word(5548) == 237164); - CHECK(bus.read_word(5552) == 679785111); - CHECK(bus.read_word(5556) == 905895898); - CHECK(bus.read_word(5560) == 131313333); - CHECK(bus.read_word(5564) == 131); + CHECK(bus.read_word(address) == 237164); + CHECK(bus.read_word(address + alignment) == 679785111); + CHECK(bus.read_word(address + alignment * 2) == 905895898); + CHECK(bus.read_word(address + alignment * 3) == 131313333); + CHECK(bus.read_word(address + alignment * 4) == 131); }; // set stack pointer to top of stack - setr(13, 5568); + setr(13, address + alignment * 5); SECTION("without LR") { exec(data); checker(); - CHECK(getr(13) == 5548); + CHECK(getr(13) == address); } SECTION("with LR") { push->pclr = true; // populate lr setr(14, 999304); - // add another word on stack (5568 + 4) - setr(13, 5572); + // add another word on stack (top + 4) + setr(13, address + alignment * 6); exec(data); - CHECK(bus.read_word(5568) == 999304); + CHECK(bus.read_word(address + alignment * 5) == 999304); checker(); - CHECK(getr(13) == 5548); + CHECK(getr(13) == address); } } @@ -792,11 +795,11 @@ TEST_CASE_METHOD(CpuFixture, "Push/Pop Registers", TAG) { push->load = true; // populate memory - bus.write_word(5548, 237164); - bus.write_word(5552, 679785111); - bus.write_word(5556, 905895898); - bus.write_word(5560, 131313333); - bus.write_word(5564, 131); + bus.write_word(address, 237164); + bus.write_word(address + alignment, 679785111); + bus.write_word(address + alignment * 2, 905895898); + bus.write_word(address + alignment * 3, 131313333); + bus.write_word(address + alignment * 4, 131); auto checker = [this]() { CHECK(getr(0) == 237164); @@ -814,23 +817,23 @@ TEST_CASE_METHOD(CpuFixture, "Push/Pop Registers", TAG) { }; // set stack pointer to bottom of stack - setr(13, 5548); + setr(13, address); SECTION("without SP") { exec(data); checker(); - CHECK(getr(13) == 5568); + CHECK(getr(13) == address + alignment * 5); } SECTION("with SP") { push->pclr = true; // populate next address - bus.write_word(5568, 93333912); + bus.write_word(address + alignment * 5, 93333912); exec(data); CHECK(getr(15) == 93333912); checker(); - CHECK(getr(13) == 5572); + CHECK(getr(13) == address + alignment * 6); } } } @@ -841,7 +844,10 @@ TEST_CASE_METHOD(CpuFixture, "Multiple Load/Store", TAG) { MultipleLoad* push = std::get_if(&data); // registers = 0, 1, 4, 6, 7 - SECTION("push (store)") { + static constexpr uint8_t alignment = 4; + static constexpr uint32_t address = 0x30015AC; + + SECTION("store") { // populate registers setr(0, 237164); @@ -850,36 +856,36 @@ TEST_CASE_METHOD(CpuFixture, "Multiple Load/Store", TAG) { setr(7, 131); // set R2 (base) to top of stack - setr(2, 5568); + setr(2, address + alignment * 5); exec(data); - CHECK(bus.read_word(5548) == 237164); - CHECK(bus.read_word(5552) == 5568); - CHECK(bus.read_word(5556) == 905895898); - CHECK(bus.read_word(5560) == 131313333); - CHECK(bus.read_word(5564) == 131); + CHECK(bus.read_word(address) == 237164); + CHECK(bus.read_word(address + alignment) == address + alignment * 5); + CHECK(bus.read_word(address + alignment * 2) == 905895898); + CHECK(bus.read_word(address + alignment * 3) == 131313333); + CHECK(bus.read_word(address + alignment * 4) == 131); // write back - CHECK(getr(2) == 5548); + CHECK(getr(2) == address); } - SECTION("pop (load)") { + SECTION("load") { push->load = true; // populate memory - bus.write_word(5548, 237164); - bus.write_word(5552, 679785111); - bus.write_word(5556, 905895898); - bus.write_word(5560, 131313333); - bus.write_word(5564, 131); + bus.write_word(address, 237164); + bus.write_word(address + alignment, 679785111); + bus.write_word(address + alignment * 2, 905895898); + bus.write_word(address + alignment * 3, 131313333); + bus.write_word(address + alignment * 4, 131); // base - setr(2, 5548); + setr(2, address); exec(data); CHECK(getr(0) == 237164); CHECK(getr(1) == 0); - CHECK(getr(2) == 5568); // write back + CHECK(getr(2) == address + alignment * 5); // write back CHECK(getr(3) == 0); CHECK(getr(4) == 905895898); CHECK(getr(5) == 0); diff --git a/tests/memory.cc b/tests/memory.cc index 5c94fa2..0e69d04 100644 --- a/tests/memory.cc +++ b/tests/memory.cc @@ -15,14 +15,18 @@ class MemFixture { Memory memory; }; -TEST_CASE_METHOD(MemFixture, "bios", TAG) { - memory.write(0, 0xAC); +TEST_CASE("bios", TAG) { + std::array bios = { 0 }; + + // populate bios + bios[0] = 0xAC; + bios[0x3FFF] = 0x48; + bios[0x2A56] = 0x10; + + Memory memory(std::move(bios), std::vector(Header::HEADER_SIZE)); + CHECK(memory.read(0) == 0xAC); - - memory.write(0x3FFF, 0x48); CHECK(memory.read(0x3FFF) == 0x48); - - memory.write(0x2A56, 0x10); CHECK(memory.read(0x2A56) == 0x10); } @@ -82,40 +86,31 @@ TEST_CASE_METHOD(MemFixture, "oam obj ram", TAG) { } TEST_CASE("rom", TAG) { + std::vector rom(32 * 1024 * 1024, 0); + + // populate rom + rom[0] = 0xAC; + rom[0x1FFFFFF] = 0x48; + rom[0x0EF0256] = 0x10; + // 32 megabyte ROM - Memory memory(std::array(), - std::vector(32 * 1024 * 1024)); + Memory memory(std::array(), std::move(rom)); SECTION("ROM1") { - memory.write(0x8000000, 0xAC); CHECK(memory.read(0x8000000) == 0xAC); - - memory.write(0x9FFFFFF, 0x48); CHECK(memory.read(0x9FFFFFF) == 0x48); - - memory.write(0x8ef0256, 0x10); - CHECK(memory.read(0x8ef0256) == 0x10); + CHECK(memory.read(0x8EF0256) == 0x10); } SECTION("ROM2") { - memory.write(0xA000000, 0xAC); CHECK(memory.read(0xA000000) == 0xAC); - - memory.write(0xBFFFFFF, 0x48); CHECK(memory.read(0xBFFFFFF) == 0x48); - - memory.write(0xAEF0256, 0x10); CHECK(memory.read(0xAEF0256) == 0x10); } SECTION("ROM3") { - memory.write(0xC000000, 0xAC); CHECK(memory.read(0xC000000) == 0xAC); - - memory.write(0xDFFFFFF, 0x48); CHECK(memory.read(0xDFFFFFF) == 0x48); - - memory.write(0xCEF0256, 0x10); CHECK(memory.read(0xCEF0256) == 0x10); } }