#include #include #include #include namespace weee::core { mem::mem() : vi(*this), pi(*this), mi(*this), dsp(*this), ai(*this), exi(*this) { mem1.resize(24_mib); std::fill(mem1.begin(), mem1.end(), 0); ipl.resize(1_mib); std::fill(ipl.begin(), ipl.end(), 0); register_read8_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr) { return mem1[addr]; }); register_read16_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr) { return ircolib::read_access(mem1, addr); }); register_read32_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr) { return ircolib::read_access(mem1, addr); }); register_read64_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr) { return ircolib::read_access(mem1, addr); }); register_write8_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr, ircolib::u8 value) { mem1[addr] = value; }); register_write16_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr, ircolib::u16 value) { ircolib::write_access(mem1, addr, value); }); register_write32_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr, ircolib::u32 value) { ircolib::write_access(mem1, addr, value); }); register_write64_handler(0x00000000, 0x0fffffff, [&](ircolib::u32 addr, ircolib::u32 value) { ircolib::write_access(mem1, addr, value); }); register_read8_handler(0x0ff00000, 0x0fffffff, [&](ircolib::u32 addr) { return ipl[addr]; }); register_read16_handler(0x0ff00000, 0x0fffffff, [&](ircolib::u32 addr) { return ircolib::read_access(ipl, addr); }); register_read32_handler(0x0ff00000, 0x0fffffff, [&](ircolib::u32 addr) { return ircolib::read_access(ipl, addr); }); register_read64_handler(0x0ff00000, 0x0fffffff, [&](ircolib::u32 addr) { return ircolib::read_access(ipl, addr); }); register_write8_handler(0x0ff00000, 0x0fffffff, [&](ircolib::u32 addr, ircolib::u8 value) { ipl[addr] = value; }); register_write16_handler(0x0ff00000, 0x0fffffff, [&](ircolib::u32 addr, ircolib::u16 value) { ircolib::write_access(ipl, addr, value); }); register_write32_handler(0x0ff00000, 0x0fffffff, [&](ircolib::u32 addr, ircolib::u32 value) { ircolib::write_access(ipl, addr, value); }); register_write64_handler(0x0ff00000, 0x0fffffff, [&](ircolib::u32 addr, ircolib::u32 value) { ircolib::write_access(ipl, addr, value); }); } void mem::copy(std::vector &src, const ircolib::u32 offset) { if (offset + src.size() >= mem1.size()) ircolib::panic("mem::copy outside mem1 range (src @ 0x{:08} for size 0x{:08X})", offset, src.size()); ircolib::swap_buffer(src); std::copy(src.begin(), src.end(), mem1.begin() + offset); } void mem::copy(ircolib::u8 *src, const ircolib::u32 size, const ircolib::u32 offset) { if (offset + size >= mem1.size()) ircolib::panic("mem::copy outside mem1 range (src @ 0x{:08} for size 0x{:08X})", offset, size); ircolib::swap_buffer(src, size); memcpy(&mem1[offset], src, size); } void mem::set(const ircolib::u8 val, const ircolib::u32 size, const ircolib::u32 offset) { if (offset + size >= mem1.size()) ircolib::panic("mem::set outside mem1 range (@ 0x{:08} for size 0x{:08X})", offset, size); memset(&mem1[offset], val, size); } std::expected mem::read8(ircolib::u32 addr) { addr &= 0x0FFFFFFF; for (const auto &handler : read8_handlers) { if (ircolib::is_inside_range(addr, handler.start, handler.end)) { return handler.func(addr - handler.start); } } return std::unexpected(std::format("mem::read8 unimplemented addr 0x{:08X}", addr)); } std::expected mem::read16(ircolib::u32 addr) { addr &= 0x0FFFFFFF; for (const auto &handler : read16_handlers) { if (ircolib::is_inside_range(addr, handler.start, handler.end)) { return handler.func(addr - handler.start); } } return std::unexpected(std::format("mem::read16 unimplemented addr 0x{:08X}", addr)); } std::expected mem::read32(ircolib::u32 addr) { addr &= 0x0FFFFFFF; for (const auto &handler : read32_handlers) { if (ircolib::is_inside_range(addr, handler.start, handler.end)) { return handler.func(addr - handler.start); } } return std::unexpected(std::format("mem::read32 unimplemented addr 0x{:08X}", addr)); } std::expected mem::read64(ircolib::u32 addr) { addr &= 0x0FFFFFFF; for (const auto &handler : read64_handlers) { if (ircolib::is_inside_range(addr, handler.start, handler.end)) { return handler.func(addr - handler.start); } } return std::unexpected(std::format("mem::read64 unimplemented addr 0x{:08X}", addr)); } std::expected mem::write8(ircolib::u32 addr, ircolib::u8 value) { addr &= 0x0FFFFFFF; for (const auto &handler : write8_handlers) { if (ircolib::is_inside_range(addr, handler.start, handler.end)) { handler.func(addr - handler.start, value); return std::expected(); } } return std::unexpected(std::format("mem::write8 unimplemented addr 0x{:08X} = 0x{:02X}", addr, value)); } std::expected mem::write16(ircolib::u32 addr, ircolib::u16 value) { addr &= 0x0FFFFFFF; for (const auto &handler : write16_handlers) { if (ircolib::is_inside_range(addr, handler.start, handler.end)) { handler.func(addr - handler.start, value); return std::expected(); } } return std::unexpected(std::format("mem::write16 unimplemented addr 0x{:08X} = 0x{:04X}", addr, value)); } std::expected mem::write32(ircolib::u32 addr, ircolib::u32 value) { addr &= 0x0FFFFFFF; for (const auto &handler : write32_handlers) { if (ircolib::is_inside_range(addr, handler.start, handler.end)) { handler.func(addr - handler.start, value); return std::expected(); } } return std::unexpected(std::format("mem::write32 unimplemented addr 0x{:08X} = 0x{:08X}", addr, value)); } std::expected mem::write64(ircolib::u32 addr, ircolib::u64 value) { addr &= 0x0FFFFFFF; for (const auto &handler : write64_handlers) { if (ircolib::is_inside_range(addr, handler.start, handler.end)) { handler.func(addr - handler.start, value); return std::expected(); } } return std::unexpected(std::format("mem::write64 unimplemented addr 0x{:08X} = 0x{:016X}", addr, value)); } } // namespace weee::core