/// Represents a mapped MMIO region with read/write callbacks.
/// Instead of trapping access violations (as the C++ JIT does), the interpreter
/// explicitly checks each memory access against registered MMIO regions.
pub struct MmioRegion {
    pub base_address: u32,
    pub mask: u32,
    pub size: u32,
    pub read_callback: Box<dyn Fn(u32) -> u32 + Send + Sync>,
    pub write_callback: Box<dyn Fn(u32, u32) + Send + Sync>,
}

impl MmioRegion {
    pub fn contains(&self, addr: u32) -> bool {
        let masked = addr & self.mask;
        masked >= self.base_address && masked < self.base_address + self.size
    }
}

impl std::fmt::Debug for MmioRegion {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("MmioRegion")
            .field("base_address", &format_args!("{:#010x}", self.base_address))
            .field("mask", &format_args!("{:#010x}", self.mask))
            .field("size", &format_args!("{:#x}", self.size))
            .finish()
    }
}
