#pragma once #include #include // 0x1F000000 - 0x1FFFFFFF // 0xFF000000 - 0xFFFFFFFF struct memory_access { uint8_t (* read_memory8 )(void * mem, uint32_t address); uint16_t (* read_memory16 )(void * mem, uint32_t address); uint32_t (* read_memory32 )(void * mem, uint32_t address); void (* write_memory8 )(void * mem, uint32_t address, uint8_t value); void (* write_memory16)(void * mem, uint32_t address, uint16_t value); void (* write_memory32)(void * mem, uint32_t address, uint32_t value); }; struct memory_map_entry { uint32_t start; uint32_t size; void * mem; struct memory_access access; }; #define memory_map_max_length 16 struct memory_map { uint32_t length; struct memory_map_entry entry[memory_map_max_length]; }; static inline uint32_t physical_address(uint32_t address) { if (address < 0xe0000000) return address & (~(0b111 << 29)); // P0 P1 P2 P3 region else return address; // P4 region } static inline struct memory_map_entry * find_entry(struct memory_map * map, uint32_t address) { uint32_t physical = physical_address(address); assert(map->length <= memory_map_max_length); for (int i = 0; i < map->length; i++) { uint32_t entry_start = map->entry[i].start; uint32_t entry_end = map->entry[i].start + map->entry[i].size; if (physical >= entry_start && physical < entry_end) return &map->entry[i]; } return (struct memory_map_entry *)0; } #undef memory_map_max_length