From 9397140473ae43182ca9cb571f2593243c000fc6 Mon Sep 17 00:00:00 2001 From: Amneesh Singh Date: Fri, 14 Jun 2024 05:37:10 +0530 Subject: [PATCH] get rid of memory.cc/.hh also fix bus' shared pointer in cpu TODO: put cpu in bus not the other way around Signed-off-by: Amneesh Singh --- apps/target/main.cc | 10 +- include/bus.hh | 52 +++++++++- include/cpu/cpu.hh | 2 +- include/memory.hh | 58 ----------- include/meson.build | 3 +- src/bus.cc | 218 ++++++++++++++++++++++++++++++++++++--- src/cpu/cpu.cc | 8 +- src/memory.cc | 181 -------------------------------- src/meson.build | 1 - tests/bus.cc | 107 +++++++++++++++++-- tests/cpu/arm/exec.cc | 80 +++++++------- tests/cpu/cpu-fixture.cc | 6 +- tests/cpu/cpu-fixture.hh | 7 +- tests/cpu/thumb/exec.cc | 88 ++++++++-------- tests/memory.cc | 118 --------------------- tests/meson.build | 3 +- 16 files changed, 456 insertions(+), 486 deletions(-) delete mode 100644 include/memory.hh delete mode 100644 src/memory.cc delete mode 100644 tests/memory.cc diff --git a/apps/target/main.cc b/apps/target/main.cc index 128ac19..a0c26b4 100644 --- a/apps/target/main.cc +++ b/apps/target/main.cc @@ -1,8 +1,8 @@ #include "bus.hh" #include "cpu/cpu.hh" -#include "memory.hh" #include "util/loglevel.hh" #include +#include #include #include #include @@ -15,7 +15,7 @@ int main(int argc, const char* argv[]) { std::vector rom; - std::array bios = { 0 }; + std::array bios = { 0 }; auto usage = [argv]() { std::cerr << "Usage: " << argv[0] << " [-b ]" << std::endl; @@ -65,7 +65,7 @@ main(int argc, const char* argv[]) { ifile.seekg(0, std::ios::end); bios_size = ifile.tellg(); - if (bios_size != matar::Memory::BIOS_SIZE) { + if (bios_size != matar::Bus::BIOS_SIZE) { throw std::ios::failure("BIOS file has invalid size", std::error_code()); } @@ -87,8 +87,8 @@ main(int argc, const char* argv[]) { matar::set_log_level(matar::LogLevel::Debug); try { - matar::Memory memory(std::move(bios), std::move(rom)); - matar::Bus bus(memory); + std::shared_ptr bus( + new matar::Bus(std::move(bios), std::move(rom))); matar::Cpu cpu(bus); while (true) { cpu.step(); diff --git a/include/bus.hh b/include/bus.hh index bcfdb11..61c7cce 100644 --- a/include/bus.hh +++ b/include/bus.hh @@ -1,13 +1,16 @@ #pragma once +#include "header.hh" #include "io/io.hh" -#include "memory.hh" -#include +#include +#include +#include namespace matar { class Bus { public: - Bus(const Memory& memory); + static constexpr uint32_t BIOS_SIZE = 1024 * 16; + Bus(std::array&& bios, std::vector&& rom); uint8_t read_byte(uint32_t address); void write_byte(uint32_t address, uint8_t byte); @@ -19,7 +22,48 @@ class Bus { void write_word(uint32_t address, uint32_t word); private: + template + std::optional> read(uint32_t address) const; + + template + std::optional> write(uint32_t address); + +#define MEMORY_REGION(name, start) \ + static constexpr uint32_t name##_START = start; + +#define DECL_MEMORY(name, ident, start, end) \ + MEMORY_REGION(name, start) \ + std::array ident; + + MEMORY_REGION(BIOS, 0x00000000) + std::array bios; + + // board working RAM + DECL_MEMORY(BOARD_WRAM, board_wram, 0x02000000, 0x0203FFFF) + + // chip working RAM + DECL_MEMORY(CHIP_WRAM, chip_wram, 0x03000000, 0x03007FFF) + + // palette RAM + DECL_MEMORY(PALETTE_RAM, palette_ram, 0x05000000, 0x050003FF) + + // video RAM + DECL_MEMORY(VRAM, vram, 0x06000000, 0x06017FFF) + + // OAM OBJ attributes + DECL_MEMORY(OAM_OBJ_ATTR, oam_obj_attr, 0x07000000, 0x070003FF) + +#undef DECL_MEMORY + + MEMORY_REGION(ROM_0, 0x08000000) + MEMORY_REGION(ROM_1, 0x0A000000) + MEMORY_REGION(ROM_2, 0x0C000000) + +#undef MEMORY_REGION + std::vector rom; + Header header; + void parse_header(); + IoDevices io; - std::shared_ptr memory; }; } diff --git a/include/cpu/cpu.hh b/include/cpu/cpu.hh index ddc3117..cb9a78d 100644 --- a/include/cpu/cpu.hh +++ b/include/cpu/cpu.hh @@ -10,7 +10,7 @@ namespace matar { class Cpu { public: - Cpu(const Bus& bus) noexcept; + Cpu(std::shared_ptr) noexcept; void step(); void chg_mode(const Mode to); diff --git a/include/memory.hh b/include/memory.hh deleted file mode 100644 index eedf0a9..0000000 --- a/include/memory.hh +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include "header.hh" -#include -#include -#include -#include -#include - -namespace matar { -class Memory { - public: - static constexpr uint32_t BIOS_SIZE = 1024 * 16; - - Memory(std::array&& bios, std::vector&& rom); - - uint8_t read(uint32_t address) const; - void write(uint32_t address, uint8_t byte); - - private: -#define MEMORY_REGION(name, start) \ - static constexpr uint32_t name##_START = start; - -#define DECL_MEMORY(name, ident, start, end) \ - MEMORY_REGION(name, start) \ - std::array ident; - - MEMORY_REGION(BIOS, 0x00000000) - std::array bios; - - // board working RAM - DECL_MEMORY(BOARD_WRAM, board_wram, 0x02000000, 0x0203FFFF) - - // chip working RAM - DECL_MEMORY(CHIP_WRAM, chip_wram, 0x03000000, 0x03007FFF) - - // palette RAM - DECL_MEMORY(PALETTE_RAM, palette_ram, 0x05000000, 0x050003FF) - - // video RAM - DECL_MEMORY(VRAM, vram, 0x06000000, 0x06017FFF) - - // OAM OBJ attributes - DECL_MEMORY(OAM_OBJ_ATTR, oam_obj_attr, 0x07000000, 0x070003FF) - -#undef DECL_MEMORY - - MEMORY_REGION(ROM_0, 0x08000000) - MEMORY_REGION(ROM_1, 0x0A000000) - MEMORY_REGION(ROM_2, 0x0C000000) - -#undef MEMORY_REGION - std::unordered_map invalid_mem; - std::vector rom; - Header header; - void parse_header(); -}; -} diff --git a/include/meson.build b/include/meson.build index cc26387..2691c0b 100644 --- a/include/meson.build +++ b/include/meson.build @@ -1,5 +1,4 @@ headers = files( - 'memory.hh', 'bus.hh', 'header.hh', ) @@ -10,4 +9,4 @@ subdir('cpu') subdir('util') subdir('io') -install_headers(headers, subdir: meson.project_name(), preserve_path: true) \ No newline at end of file +install_headers(headers, subdir: meson.project_name(), preserve_path: true) diff --git a/src/bus.cc b/src/bus.cc index c55e21c..b3843cb 100644 --- a/src/bus.cc +++ b/src/bus.cc @@ -1,21 +1,87 @@ #include "bus.hh" +#include "util/crypto.hh" #include "util/log.hh" -#include namespace matar { static constexpr uint32_t IO_START = 0x4000000; static constexpr uint32_t IO_END = 0x40003FE; -Bus::Bus(const Memory& memory) - : memory(std::make_shared(memory)) {} +Bus::Bus(std::array&& bios, std::vector&& rom) + : bios(std::move(bios)) + , board_wram({ 0 }) + , chip_wram({ 0 }) + , palette_ram({ 0 }) + , vram({ 0 }) + , oam_obj_attr({ 0 }) + , rom(std::move(rom)) { + std::string bios_hash = crypto::sha256(this->bios); + static constexpr std::string_view expected_hash = + "fd2547724b505f487e6dcb29ec2ecff3af35a841a77ab2e85fd87350abd36570"; + + if (bios_hash != expected_hash) { + glogger.warn("BIOS hash failed to match, run at your own risk" + "\nExpected : {} " + "\nGot : {}", + expected_hash, + bios_hash); + } + + parse_header(); + + glogger.info("Memory successfully initialised"); + glogger.info("Cartridge Title: {}", header.title); +}; + +template +std::optional> +Bus::read(uint32_t address) const { +#define MATCHES(AREA, area) \ + if (address >= AREA##_START && address < AREA##_START + area.size()) \ + return std::span(&area[address - AREA##_START], N); + + 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) + +#undef MATCHES + + glogger.error("Invalid memory region read"); + return {}; +} + +template +std::optional> +Bus::write(uint32_t address) { +#define MATCHES(AREA, area) \ + if (address >= AREA##_START && address < AREA##_START + area.size()) \ + return std::span(&area[address - AREA##_START], N); + + 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) + +#undef MATCHES + + glogger.error("Invalid memory region written"); + return {}; +} uint8_t Bus::read_byte(uint32_t address) { if (address >= IO_START && address <= IO_END) return io.read_byte(address); - return memory->read(address); + auto data = read<1>(address); + return data.transform([](auto value) { return value[0]; }).value_or(0xFF); } void @@ -25,7 +91,10 @@ Bus::write_byte(uint32_t address, uint8_t byte) { return; } - memory->write(address, byte); + auto data = write<1>(address); + + if (data.has_value()) + data.value()[0] = byte; } uint16_t @@ -36,7 +105,9 @@ Bus::read_halfword(uint32_t address) { if (address >= IO_START && address <= IO_END) return io.read_halfword(address); - return read_byte(address) | read_byte(address + 1) << 8; + return read<2>(address) + .transform([](auto value) { return value[0] | value[1] << 8; }) + .value_or(0xFFFF); } void @@ -49,8 +120,13 @@ Bus::write_halfword(uint32_t address, uint16_t halfword) { return; } - write_byte(address, halfword & 0xFF); - write_byte(address + 1, halfword >> 8 & 0xFF); + auto data = write<2>(address); + + if (data.has_value()) { + auto value = data.value(); + value[0] = halfword & 0xFF; + value[1] = halfword >> 8 & 0xFF; + } } uint32_t @@ -61,8 +137,11 @@ Bus::read_word(uint32_t address) { if (address >= IO_START && address <= IO_END) return io.read_word(address); - return read_byte(address) | read_byte(address + 1) << 8 | - read_byte(address + 2) << 16 | read_byte(address + 3) << 24; + return read<4>(address) + .transform([](auto value) { + return value[0] | value[1] << 8 | value[2] << 16 | value[3] << 24; + }) + .value_or(0xFFFFFFFF); } void @@ -75,9 +154,120 @@ Bus::write_word(uint32_t address, uint32_t word) { return; } - write_byte(address, word & 0xFF); - write_byte(address + 1, word >> 8 & 0xFF); - write_byte(address + 2, word >> 16 & 0xFF); - write_byte(address + 3, word >> 24 & 0xFF); + auto data = write<4>(address); + + if (data.has_value()) { + auto value = data.value(); + value[0] = word & 0xFF; + value[1] = word >> 8 & 0xFF; + value[2] = word >> 16 & 0xFF; + value[3] = word >> 24 & 0xFF; + } +} + +void +Bus::parse_header() { + if (rom.size() < header.HEADER_SIZE) { + throw std::out_of_range( + "ROM is not large enough to even have a header"); + } + + // entrypoint + header.entrypoint = + rom[0x00] | rom[0x01] << 8 | rom[0x02] << 16 | rom[0x03] << 24; + + // nintendo logo + if (rom[0x9C] != 0x21) + glogger.info("HEADER: BIOS debugger bits not set to 0"); + + // game info + header.title = std::string(&rom[0xA0], &rom[0xA0 + 12]); + + switch (rom[0xAC]) { + case 'A': + header.unique_code = Header::UniqueCode::Old; + break; + case 'B': + header.unique_code = Header::UniqueCode::New; + break; + case 'C': + header.unique_code = Header::UniqueCode::Newer; + break; + case 'F': + header.unique_code = Header::UniqueCode::Famicom; + break; + case 'K': + header.unique_code = Header::UniqueCode::YoshiKoro; + break; + case 'P': + header.unique_code = Header::UniqueCode::Ereader; + break; + case 'R': + header.unique_code = Header::UniqueCode::Warioware; + break; + case 'U': + header.unique_code = Header::UniqueCode::Boktai; + break; + case 'V': + header.unique_code = Header::UniqueCode::DrillDozer; + break; + + default: + glogger.error("HEADER: invalid unique code: {}", rom[0xAC]); + } + + header.title_code = std::string(&rom[0xAD], &rom[0xAE]); + + switch (rom[0xAF]) { + case 'J': + header.i18n = Header::I18n::Japan; + break; + case 'P': + header.i18n = Header::I18n::Europe; + break; + case 'F': + header.i18n = Header::I18n::French; + break; + case 'S': + header.i18n = Header::I18n::Spanish; + break; + case 'E': + header.i18n = Header::I18n::Usa; + break; + case 'D': + header.i18n = Header::I18n::German; + break; + case 'I': + header.i18n = Header::I18n::Italian; + break; + + default: + glogger.error("HEADER: invalid destination/language: {}", + rom[0xAF]); + } + + if (rom[0xB2] != 0x96) + glogger.error("HEADER: invalid fixed byte at 0xB2"); + + for (uint32_t i = 0xB5; i < 0xBC; i++) { + if (rom[i] != 0x00) + glogger.error("HEADER: invalid fixed bytes at 0xB5"); + } + + header.version = rom[0xBC]; + + // checksum + { + uint32_t i = 0xA0, chk = 0; + while (i <= 0xBC) + chk -= rom[i++]; + chk -= 0x19; + chk &= 0xFF; + + if (chk != rom[0xBD]) + glogger.error("HEADER: checksum does not match"); + } + + // multiboot not required right now } } diff --git a/src/cpu/cpu.cc b/src/cpu/cpu.cc index 1b73b2c..c62a309 100644 --- a/src/cpu/cpu.cc +++ b/src/cpu/cpu.cc @@ -7,8 +7,8 @@ #include namespace matar { -Cpu::Cpu(const Bus& bus) noexcept - : bus(std::make_shared(bus)) +Cpu::Cpu(std::shared_ptr bus) noexcept + : bus(bus) , gpr({ 0 }) , cpsr(0) , spsr(0) @@ -19,6 +19,10 @@ Cpu::Cpu(const Bus& bus) noexcept cpsr.set_irq_disabled(true); cpsr.set_fiq_disabled(true); cpsr.set_state(State::Arm); + uint32_t a = 4444; + dbg(this->bus->read_word(0x2000000)); + this->bus->write_word(0x2000000, a); + dbg(this->bus->read_word(0x2000000)); glogger.info("CPU successfully initialised"); // PC always points to two instructions ahead diff --git a/src/memory.cc b/src/memory.cc deleted file mode 100644 index 668c180..0000000 --- a/src/memory.cc +++ /dev/null @@ -1,181 +0,0 @@ -#include "memory.hh" -#include "header.hh" -#include "util/crypto.hh" -#include "util/log.hh" -#include - -namespace matar { -Memory::Memory(std::array&& bios, - std::vector&& rom) - : bios(std::move(bios)) - , board_wram({ 0 }) - , chip_wram({ 0 }) - , palette_ram({ 0 }) - , vram({ 0 }) - , oam_obj_attr({ 0 }) - , rom(std::move(rom)) { - std::string bios_hash = crypto::sha256(this->bios); - static constexpr std::string_view expected_hash = - "fd2547724b505f487e6dcb29ec2ecff3af35a841a77ab2e85fd87350abd36570"; - - if (bios_hash != expected_hash) { - glogger.warn("BIOS hash failed to match, run at your own risk" - "\nExpected : {} " - "\nGot : {}", - expected_hash, - bios_hash); - } - - parse_header(); - - glogger.info("Memory successfully initialised"); - glogger.info("Cartridge Title: {}", header.title); -}; - -uint8_t -Memory::read(uint32_t address) const { -#define MATCHES(AREA, area) \ - if (address >= AREA##_START && address < AREA##_START + area.size()) \ - return area[address - AREA##_START]; - - 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"); - return 0xFF; - -#undef MATCHES -} - -void -Memory::write(uint32_t address, uint8_t byte) { -#define MATCHES(AREA, area) \ - if (address >= AREA##_START && address < AREA##_START + area.size()) { \ - area[address - AREA##_START] = byte; \ - return; \ - } - - 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) - - glogger.error("Invalid memory region accessed"); - -#undef MATCHES -} - -void -Memory::parse_header() { - if (rom.size() < header.HEADER_SIZE) { - throw std::out_of_range( - "ROM is not large enough to even have a header"); - } - - // entrypoint - header.entrypoint = - rom[0x00] | rom[0x01] << 8 | rom[0x02] << 16 | rom[0x03] << 24; - - // nintendo logo - if (rom[0x9C] != 0x21) - glogger.info("HEADER: BIOS debugger bits not set to 0"); - - // game info - header.title = std::string(&rom[0xA0], &rom[0xA0 + 12]); - - switch (rom[0xAC]) { - case 'A': - header.unique_code = Header::UniqueCode::Old; - break; - case 'B': - header.unique_code = Header::UniqueCode::New; - break; - case 'C': - header.unique_code = Header::UniqueCode::Newer; - break; - case 'F': - header.unique_code = Header::UniqueCode::Famicom; - break; - case 'K': - header.unique_code = Header::UniqueCode::YoshiKoro; - break; - case 'P': - header.unique_code = Header::UniqueCode::Ereader; - break; - case 'R': - header.unique_code = Header::UniqueCode::Warioware; - break; - case 'U': - header.unique_code = Header::UniqueCode::Boktai; - break; - case 'V': - header.unique_code = Header::UniqueCode::DrillDozer; - break; - - default: - glogger.error("HEADER: invalid unique code: {}", rom[0xAC]); - } - - header.title_code = std::string(&rom[0xAD], &rom[0xAE]); - - switch (rom[0xAF]) { - case 'J': - header.i18n = Header::I18n::Japan; - break; - case 'P': - header.i18n = Header::I18n::Europe; - break; - case 'F': - header.i18n = Header::I18n::French; - break; - case 'S': - header.i18n = Header::I18n::Spanish; - break; - case 'E': - header.i18n = Header::I18n::Usa; - break; - case 'D': - header.i18n = Header::I18n::German; - break; - case 'I': - header.i18n = Header::I18n::Italian; - break; - - default: - glogger.error("HEADER: invalid destination/language: {}", - rom[0xAF]); - } - - if (rom[0xB2] != 0x96) - glogger.error("HEADER: invalid fixed byte at 0xB2"); - - for (uint32_t i = 0xB5; i < 0xBC; i++) { - if (rom[i] != 0x00) - glogger.error("HEADER: invalid fixed bytes at 0xB5"); - } - - header.version = rom[0xBC]; - - // checksum - { - uint32_t i = 0xA0, chk = 0; - while (i <= 0xBC) - chk -= rom[i++]; - chk -= 0x19; - chk &= 0xFF; - - if (chk != rom[0xBD]) - glogger.error("HEADER: checksum does not match"); - } - - // multiboot not required right now -} -} diff --git a/src/meson.build b/src/meson.build index e6fc911..e3c3456 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,5 +1,4 @@ lib_sources = files( - 'memory.cc', 'bus.cc', ) diff --git a/tests/bus.cc b/tests/bus.cc index 1210cd7..723a32b 100644 --- a/tests/bus.cc +++ b/tests/bus.cc @@ -8,20 +8,111 @@ using namespace matar; class BusFixture { public: BusFixture() - : bus(Memory(std::array(), - std::vector(Header::HEADER_SIZE))) {} + : bus(std::array(), + std::vector(Header::HEADER_SIZE)) {} protected: Bus bus; }; -TEST_CASE_METHOD(BusFixture, "Byte", TAG) { - CHECK(bus.read_byte(0x30001A9) == 0); +TEST_CASE("bios", TAG) { + std::array bios = { 0 }; - bus.write_byte(0x30001A9, 0xEC); - CHECK(bus.read_byte(0x30001A9) == 0xEC); - CHECK(bus.read_word(0x30001A9) == 0xEC); - CHECK(bus.read_halfword(0x30001A9) == 0xEC); + // populate bios + bios[0] = 0xAC; + bios[0x3FFF] = 0x48; + bios[0x2A56] = 0x10; + + Bus bus(std::move(bios), std::vector(Header::HEADER_SIZE)); + + CHECK(bus.read_byte(0) == 0xAC); + CHECK(bus.read_byte(0x3FFF) == 0x48); + CHECK(bus.read_byte(0x2A56) == 0x10); +} + +TEST_CASE_METHOD(BusFixture, "board wram", TAG) { + bus.write_byte(0x2000000, 0xAC); + CHECK(bus.read_byte(0x2000000) == 0xAC); + + bus.write_byte(0x203FFFF, 0x48); + CHECK(bus.read_byte(0x203FFFF) == 0x48); + + bus.write_byte(0x2022A56, 0x10); + CHECK(bus.read_byte(0x2022A56) == 0x10); +} + +TEST_CASE_METHOD(BusFixture, "chip wram", TAG) { + bus.write_byte(0x3000000, 0xAC); + CHECK(bus.read_byte(0x3000000) == 0xAC); + + bus.write_byte(0x3007FFF, 0x48); + CHECK(bus.read_byte(0x3007FFF) == 0x48); + + bus.write_byte(0x3002A56, 0x10); + CHECK(bus.read_byte(0x3002A56) == 0x10); +} + +TEST_CASE_METHOD(BusFixture, "palette ram", TAG) { + bus.write_byte(0x5000000, 0xAC); + CHECK(bus.read_byte(0x5000000) == 0xAC); + + bus.write_byte(0x50003FF, 0x48); + CHECK(bus.read_byte(0x50003FF) == 0x48); + + bus.write_byte(0x5000156, 0x10); + CHECK(bus.read_byte(0x5000156) == 0x10); +} + +TEST_CASE_METHOD(BusFixture, "video ram", TAG) { + bus.write_byte(0x6000000, 0xAC); + CHECK(bus.read_byte(0x6000000) == 0xAC); + + bus.write_byte(0x6017FFF, 0x48); + CHECK(bus.read_byte(0x6017FFF) == 0x48); + + bus.write_byte(0x6012A56, 0x10); + CHECK(bus.read_byte(0x6012A56) == 0x10); +} + +TEST_CASE_METHOD(BusFixture, "oam obj ram", TAG) { + bus.write_byte(0x7000000, 0xAC); + CHECK(bus.read_byte(0x7000000) == 0xAC); + + bus.write_byte(0x70003FF, 0x48); + CHECK(bus.read_byte(0x70003FF) == 0x48); + + bus.write_byte(0x7000156, 0x10); + CHECK(bus.read_byte(0x7000156) == 0x10); +} + +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 + Bus bus(std::array(), std::move(rom)); + + SECTION("ROM1") { + CHECK(bus.read_byte(0x8000000) == 0xAC); + CHECK(bus.read_byte(0x9FFFFFF) == 0x48); + CHECK(bus.read_byte(0x8EF0256) == 0x10); + } + + SECTION("ROM2") { + CHECK(bus.read_byte(0xA000000) == 0xAC); + CHECK(bus.read_byte(0xBFFFFFF) == 0x48); + CHECK(bus.read_byte(0xAEF0256) == 0x10); + } + + SECTION("ROM3") { + CHECK(bus.read_byte(0xC000000) == 0xAC); + CHECK(bus.read_byte(0xDFFFFFF) == 0x48); + CHECK(bus.read_byte(0xCEF0256) == 0x10); + } } TEST_CASE_METHOD(BusFixture, "Halfword", TAG) { diff --git a/tests/cpu/arm/exec.cc b/tests/cpu/arm/exec.cc index b750153..a8dd4ff 100644 --- a/tests/cpu/arm/exec.cc +++ b/tests/cpu/arm/exec.cc @@ -182,13 +182,13 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Swap", TAG) { setr(9, 0x3003FED); setr(3, 94235087); setr(3, -259039045); - bus.write_word(getr(9), 3241011111); + bus->write_word(getr(9), 3241011111); SECTION("word") { exec(data); CHECK(getr(4) == 3241011111); - CHECK(bus.read_word(getr(9)) == static_cast(-259039045)); + CHECK(bus->read_word(getr(9)) == static_cast(-259039045)); } SECTION("byte") { @@ -196,7 +196,7 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Swap", TAG) { exec(data); CHECK(getr(4) == (3241011111 & 0xFF)); - CHECK(bus.read_byte(getr(9)) == + CHECK(bus->read_byte(getr(9)) == static_cast(-259039045 & 0xFF)); } } @@ -226,7 +226,7 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { // shifted register (immediate) { // 0x31E + 0x3000004 - bus.write_word(0x30031E4, 95995); + bus->write_word(0x30031E4, 95995); exec(data); CHECK(getr(5) == 95995); @@ -244,7 +244,7 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { setr(12, 2); // 6384 + 0x3000004 - bus.write_word(0x30018F4, 3948123487); + bus->write_word(0x30018F4, 3948123487); exec(data); CHECK(getr(5) == 3948123487); @@ -254,7 +254,7 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { { data_transfer->offset = static_cast(0xDA1); // 0xDA1 + 0x3000004 - bus.write_word(0x3000DA5, 68795467); + bus->write_word(0x3000DA5, 68795467); exec(data); @@ -266,7 +266,7 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { setr(7, 0x3005E0D); data_transfer->up = false; // 0x3005E0D - 0xDA1 - bus.write_word(0x300506C, 5949595); + bus->write_word(0x300506C, 5949595); exec(data); @@ -279,7 +279,7 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { { data_transfer->write = true; // 0x3005E0D - 0xDA1 - bus.write_word(0x300506C, 967844); + bus->write_word(0x300506C, 967844); exec(data); @@ -292,7 +292,7 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { { data_transfer->write = false; data_transfer->pre = false; - bus.write_word(0x300506C, 61119); + bus->write_word(0x300506C, 61119); exec(data); @@ -307,7 +307,7 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { exec(data); - CHECK(bus.read_word(0x30042CB) == 61119); + CHECK(bus->read_word(0x30042CB) == 61119); // 0x30042CB - 0xDA1 CHECK(getr(7) == 0x300352A); } @@ -319,7 +319,7 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { exec(data); - CHECK(bus.read_word(0x300352A) == 61119); + CHECK(bus->read_word(0x300352A) == 61119); // 0x300352A - 0xDA1 CHECK(getr(15) == 0x3002789); @@ -334,7 +334,7 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { exec(data); - CHECK(bus.read_word(0x300352A + INSTRUCTION_SIZE) == 444444); + CHECK(bus->read_word(0x300352A + INSTRUCTION_SIZE) == 444444); // 0x300352A - 0xDA1 CHECK(getr(7) == 0x3002789 + INSTRUCTION_SIZE); @@ -351,7 +351,7 @@ TEST_CASE_METHOD(CpuFixture, "Single Data Transfer", TAG) { exec(data); - CHECK(bus.read_word(0x3002789) == (458267584 & 0xFF)); + CHECK(bus->read_word(0x3002789) == (458267584 & 0xFF)); // 0x3002789 - 0xDA1 CHECK(getr(7) == 0x30019E8); } @@ -377,7 +377,7 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { // register offset { // 0x300611E + 0x384 - bus.write_word(0x30064A2, 3948123487); + bus->write_word(0x30064A2, 3948123487); exec(data); CHECK(getr(11) == (3948123487 & 0xFFFF)); @@ -388,7 +388,7 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { hw_transfer->imm = true; hw_transfer->offset = 0xA7; // 0x300611E + 0xA7 - bus.write_word(0x30061C5, 594633302); + bus->write_word(0x30061C5, 594633302); exec(data); CHECK(getr(11) == (594633302 & 0xFFFF)); @@ -398,7 +398,7 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { { hw_transfer->up = false; // 0x300611E - 0xA7 - bus.write_word(0x3006077, 222221); + bus->write_word(0x3006077, 222221); exec(data); @@ -411,7 +411,7 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { { hw_transfer->write = true; // 0x300611E - 0xA7 - bus.write_word(0x3006077, 100000005); + bus->write_word(0x3006077, 100000005); exec(data); @@ -423,7 +423,7 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { { hw_transfer->pre = false; hw_transfer->write = false; - bus.write_word(0x3006077, 6111909); + bus->write_word(0x3006077, 6111909); exec(data); @@ -438,7 +438,7 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { exec(data); - CHECK(bus.read_halfword(0x3005FD0) == (6111909 & 0xFFFF)); + CHECK(bus->read_halfword(0x3005FD0) == (6111909 & 0xFFFF)); // 0x3005FD0 - 0xA7 CHECK(getr(10) == 0x3005F29); } @@ -450,7 +450,7 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { exec(data); - CHECK(bus.read_halfword(0x3005F29 - 2 * INSTRUCTION_SIZE) == + CHECK(bus->read_halfword(0x3005F29 - 2 * INSTRUCTION_SIZE) == (6111909 & 0xFFFF)); // 0x3005F29 - 0xA7 CHECK(getr(15) == 0x3005E82 - 2 * INSTRUCTION_SIZE); @@ -466,7 +466,7 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { exec(data); - CHECK(bus.read_halfword(0x3005F29 + INSTRUCTION_SIZE) == 224); + CHECK(bus->read_halfword(0x3005F29 + INSTRUCTION_SIZE) == 224); // 0x3005F29 - 0xA7 CHECK(getr(10) == 0x3005E82 + INSTRUCTION_SIZE); @@ -479,7 +479,7 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { { hw_transfer->load = true; hw_transfer->sign = true; - bus.write_halfword(0x3005E82, -12345); + bus->write_halfword(0x3005E82, -12345); exec(data); @@ -491,7 +491,7 @@ TEST_CASE_METHOD(CpuFixture, "Halfword Transfer", TAG) { // signed byte { hw_transfer->half = false; - bus.write_byte(0x3005DDB, -56); + bus->write_byte(0x3005DDB, -56); exec(data); @@ -517,14 +517,14 @@ TEST_CASE_METHOD(CpuFixture, "Block Data Transfer", TAG) { SECTION("load") { static constexpr uint32_t address = 0x3000D78; // populate memory - 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); + 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); @@ -613,16 +613,16 @@ TEST_CASE_METHOD(CpuFixture, "Block Data Transfer", TAG) { setr(15, 6); auto checker = [this]() { - 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); + 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 = 1; i < 8; i++) - bus.write_word(address + alignment * i, 0); + bus->write_word(address + alignment * i, 0); }; setr(10, address); // base @@ -657,7 +657,7 @@ TEST_CASE_METHOD(CpuFixture, "Block Data Transfer", TAG) { block_transfer->s = true; exec(data); // User's R13 is different (unset at this point) - CHECK(bus.read_word(address + alignment * 6) == 0); + CHECK(bus->read_word(address + alignment * 6) == 0); } } diff --git a/tests/cpu/cpu-fixture.cc b/tests/cpu/cpu-fixture.cc index c08dacd..6e3663b 100644 --- a/tests/cpu/cpu-fixture.cc +++ b/tests/cpu/cpu-fixture.cc @@ -43,7 +43,7 @@ uint32_t CpuFixture::getr_(uint8_t r, Cpu& cpu) { uint32_t addr = 0x02000000; uint8_t offset = r == 15 ? 4 : 0; - uint32_t word = bus.read_word(addr + offset); + uint32_t word = bus->read_word(addr + offset); Cpu tmp = cpu; uint32_t ret = 0xFFFFFFFF; uint8_t base = r ? 0 : 1; @@ -74,9 +74,9 @@ CpuFixture::getr_(uint8_t r, Cpu& cpu) { addr += offset; - ret = bus.read_word(addr); + ret = bus->read_word(addr); - bus.write_word(addr, word); + bus->write_word(addr, word); return ret; } diff --git a/tests/cpu/cpu-fixture.hh b/tests/cpu/cpu-fixture.hh index fe8fff0..4abef5a 100644 --- a/tests/cpu/cpu-fixture.hh +++ b/tests/cpu/cpu-fixture.hh @@ -5,8 +5,9 @@ using namespace matar; class CpuFixture { public: CpuFixture() - : bus(Memory(std::array(), - std::vector(Header::HEADER_SIZE))) + : bus(std::shared_ptr( + new Bus(std::array(), + std::vector(Header::HEADER_SIZE)))) , cpu(bus) {} protected: @@ -30,7 +31,7 @@ class CpuFixture { void set_psr(Psr psr, bool spsr = false); - Bus bus; + std::shared_ptr bus; Cpu cpu; private: diff --git a/tests/cpu/thumb/exec.cc b/tests/cpu/thumb/exec.cc index ac68cb4..b98d686 100644 --- a/tests/cpu/thumb/exec.cc +++ b/tests/cpu/thumb/exec.cc @@ -532,7 +532,7 @@ TEST_CASE_METHOD(CpuFixture, "PC Relative Load", TAG) { setr(15, 0x3003FD5); // resetting bit 0 for 0x3003FD5, we get 0x3003FD4 // 0x3003FD4 + 0x578 - bus.write_word(0x300454C, 489753492); + bus->write_word(0x300454C, 489753492); CHECK(getr(0) == 0); exec(data); @@ -551,20 +551,20 @@ TEST_CASE_METHOD(CpuFixture, "Load/Store with Register Offset", TAG) { SECTION("store") { // 0x3003000 + 0x332 - CHECK(bus.read_word(0x3003332) == 0); + CHECK(bus->read_word(0x3003332) == 0); exec(data); - CHECK(bus.read_word(0x3003332) == 389524259); + CHECK(bus->read_word(0x3003332) == 389524259); // byte load->byte = true; - bus.write_word(0x3003332, 0); + bus->write_word(0x3003332, 0); exec(data); - CHECK(bus.read_word(0x3003332) == 35); + CHECK(bus->read_word(0x3003332) == 35); } SECTION("load") { load->load = true; - bus.write_word(0x3003332, 11123489); + bus->write_word(0x3003332, 11123489); exec(data); CHECK(getr(3) == 11123489); @@ -588,21 +588,21 @@ TEST_CASE_METHOD(CpuFixture, "Load/Store Sign Extended Byte/Halfword", TAG) { SECTION("SH = 00") { // 0x3003000 + 0x332 - CHECK(bus.read_word(0x3003332) == 0); + CHECK(bus->read_word(0x3003332) == 0); exec(data); - CHECK(bus.read_word(0x3003332) == 43811); + CHECK(bus->read_word(0x3003332) == 43811); } SECTION("SH = 01") { load->h = true; - bus.write_word(0x3003332, 11123489); + bus->write_word(0x3003332, 11123489); exec(data); CHECK(getr(3) == 47905); } SECTION("SH = 10") { load->s = true; - bus.write_word(0x3003332, 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(0x3003332, 11123489); + bus->write_word(0x3003332, 11123489); // sign extended 47905 halfword (0xBB21) exec(data); CHECK(getr(3) == 4294949665); @@ -630,20 +630,20 @@ TEST_CASE_METHOD(CpuFixture, "Load/Store with Immediate Offset", TAG) { SECTION("store") { // 0x30066A + 0x6E - CHECK(bus.read_word(0x30066D8) == 0); + CHECK(bus->read_word(0x30066D8) == 0); exec(data); - CHECK(bus.read_word(0x30066D8) == 389524259); + CHECK(bus->read_word(0x30066D8) == 389524259); // byte load->byte = true; - bus.write_word(0x30066D8, 0); + bus->write_word(0x30066D8, 0); exec(data); - CHECK(bus.read_word(0x30066D8) == 35); + CHECK(bus->read_word(0x30066D8) == 35); } SECTION("load") { load->load = true; - bus.write_word(0x30066D8, 11123489); + bus->write_word(0x30066D8, 11123489); exec(data); CHECK(getr(3) == 11123489); @@ -664,14 +664,14 @@ TEST_CASE_METHOD(CpuFixture, "Load/Store Halfword", TAG) { SECTION("store") { // 0x300666A + 0x6E - CHECK(bus.read_word(0x30066D8) == 0); + CHECK(bus->read_word(0x30066D8) == 0); exec(data); - CHECK(bus.read_word(0x30066D8) == 43811); + CHECK(bus->read_word(0x30066D8) == 43811); } SECTION("load") { load->load = true; - bus.write_word(0x30066D8, 11123489); + bus->write_word(0x30066D8, 11123489); exec(data); CHECK(getr(3) == 47905); } @@ -688,14 +688,14 @@ TEST_CASE_METHOD(CpuFixture, "SP Relative Load", TAG) { SECTION("store") { // 0x3004A8A + 0x328 - CHECK(bus.read_word(0x3004DB2) == 0); + CHECK(bus->read_word(0x3004DB2) == 0); exec(data); - CHECK(bus.read_word(0x3004DB2) == 2349505744); + CHECK(bus->read_word(0x3004DB2) == 2349505744); } SECTION("load") { load->load = true; - bus.write_word(0x3004DB2, 11123489); + bus->write_word(0x3004DB2, 11123489); exec(data); CHECK(getr(1) == 11123489); } @@ -761,11 +761,11 @@ TEST_CASE_METHOD(CpuFixture, "Push/Pop Registers", TAG) { auto checker = [this]() { // address - 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); + 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 @@ -785,7 +785,7 @@ TEST_CASE_METHOD(CpuFixture, "Push/Pop Registers", TAG) { setr(13, address + alignment * 6); exec(data); - CHECK(bus.read_word(address + alignment * 5) == 999304); + CHECK(bus->read_word(address + alignment * 5) == 999304); checker(); CHECK(getr(13) == address); } @@ -795,11 +795,11 @@ TEST_CASE_METHOD(CpuFixture, "Push/Pop Registers", TAG) { push->load = true; // populate memory - 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); + 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); @@ -828,7 +828,7 @@ TEST_CASE_METHOD(CpuFixture, "Push/Pop Registers", TAG) { SECTION("with SP") { push->pclr = true; // populate next address - bus.write_word(address + alignment * 5, 93333912); + bus->write_word(address + alignment * 5, 93333912); exec(data); CHECK(getr(15) == 93333912); @@ -860,11 +860,11 @@ TEST_CASE_METHOD(CpuFixture, "Multiple Load/Store", TAG) { exec(data); - 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); + 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) == address); } @@ -873,11 +873,11 @@ TEST_CASE_METHOD(CpuFixture, "Multiple Load/Store", TAG) { push->load = true; // populate memory - 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); + 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, address); diff --git a/tests/memory.cc b/tests/memory.cc deleted file mode 100644 index 0e69d04..0000000 --- a/tests/memory.cc +++ /dev/null @@ -1,118 +0,0 @@ -#include "memory.hh" -#include - -#define TAG "[memory]" - -using namespace matar; - -class MemFixture { - public: - MemFixture() - : memory(std::array(), - std::vector(Header::HEADER_SIZE)) {} - - protected: - Memory memory; -}; - -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); - CHECK(memory.read(0x3FFF) == 0x48); - CHECK(memory.read(0x2A56) == 0x10); -} - -TEST_CASE_METHOD(MemFixture, "board wram", TAG) { - memory.write(0x2000000, 0xAC); - CHECK(memory.read(0x2000000) == 0xAC); - - memory.write(0x203FFFF, 0x48); - CHECK(memory.read(0x203FFFF) == 0x48); - - memory.write(0x2022A56, 0x10); - CHECK(memory.read(0x2022A56) == 0x10); -} - -TEST_CASE_METHOD(MemFixture, "chip wram", TAG) { - memory.write(0x3000000, 0xAC); - CHECK(memory.read(0x3000000) == 0xAC); - - memory.write(0x3007FFF, 0x48); - CHECK(memory.read(0x3007FFF) == 0x48); - - memory.write(0x3002A56, 0x10); - CHECK(memory.read(0x3002A56) == 0x10); -} - -TEST_CASE_METHOD(MemFixture, "palette ram", TAG) { - memory.write(0x5000000, 0xAC); - CHECK(memory.read(0x5000000) == 0xAC); - - memory.write(0x50003FF, 0x48); - CHECK(memory.read(0x50003FF) == 0x48); - - memory.write(0x5000156, 0x10); - CHECK(memory.read(0x5000156) == 0x10); -} - -TEST_CASE_METHOD(MemFixture, "video ram", TAG) { - memory.write(0x6000000, 0xAC); - CHECK(memory.read(0x6000000) == 0xAC); - - memory.write(0x6017FFF, 0x48); - CHECK(memory.read(0x6017FFF) == 0x48); - - memory.write(0x6012A56, 0x10); - CHECK(memory.read(0x6012A56) == 0x10); -} - -TEST_CASE_METHOD(MemFixture, "oam obj ram", TAG) { - memory.write(0x7000000, 0xAC); - CHECK(memory.read(0x7000000) == 0xAC); - - memory.write(0x70003FF, 0x48); - CHECK(memory.read(0x70003FF) == 0x48); - - memory.write(0x7000156, 0x10); - CHECK(memory.read(0x7000156) == 0x10); -} - -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::move(rom)); - - SECTION("ROM1") { - CHECK(memory.read(0x8000000) == 0xAC); - CHECK(memory.read(0x9FFFFFF) == 0x48); - CHECK(memory.read(0x8EF0256) == 0x10); - } - - SECTION("ROM2") { - CHECK(memory.read(0xA000000) == 0xAC); - CHECK(memory.read(0xBFFFFFF) == 0x48); - CHECK(memory.read(0xAEF0256) == 0x10); - } - - SECTION("ROM3") { - CHECK(memory.read(0xC000000) == 0xAC); - CHECK(memory.read(0xDFFFFFF) == 0x48); - CHECK(memory.read(0xCEF0256) == 0x10); - } -} - -#undef TAG diff --git a/tests/meson.build b/tests/meson.build index e0574ec..a42136d 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -6,8 +6,7 @@ src = include_directories('../src') tests_sources = files( 'main.cc', - 'bus.cc', - 'memory.cc' + 'bus.cc' ) subdir('cpu')