2024-02-16 23:13:59 +05:30
|
|
|
use crate::emu::mmu::Memory;
|
2024-02-17 09:54:41 +05:30
|
|
|
use crate::misc::emulator_error::EmulatorError;
|
2024-02-17 08:44:14 +05:30
|
|
|
use crate::misc::endian::MemoryOperations;
|
2024-02-17 09:54:41 +05:30
|
|
|
use crate::misc::result::EmulatorResult;
|
2024-02-16 23:13:59 +05:30
|
|
|
|
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
|
|
pub struct MemoryMappedIO {
|
2024-02-17 08:44:14 +05:30
|
|
|
//FIXME use a keyboard
|
2024-02-17 09:54:41 +05:30
|
|
|
keyboard_bytes: [u8; 2],
|
2024-02-16 23:13:59 +05:30
|
|
|
program_counter: [u8; 3],
|
2024-02-17 08:44:14 +05:30
|
|
|
//FIXME use a device
|
2024-02-16 23:13:59 +05:30
|
|
|
pixel_reg: u8,
|
2024-02-17 08:44:14 +05:30
|
|
|
//FIXME use a device
|
2024-02-16 23:13:59 +05:30
|
|
|
audio_sample_address_base: [u8; 2],
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MemoryMappedIO {
|
|
|
|
pub fn new() -> MemoryMappedIO {
|
|
|
|
MemoryMappedIO {
|
2024-02-17 09:54:41 +05:30
|
|
|
keyboard_bytes: [0, 0],
|
2024-02-16 23:13:59 +05:30
|
|
|
program_counter: [0, 0, 0],
|
|
|
|
pixel_reg: 0,
|
|
|
|
audio_sample_address_base: [0, 0],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-02-17 08:44:14 +05:30
|
|
|
// 2 byte keyboard bits
|
2024-02-16 23:13:59 +05:30
|
|
|
|
|
|
|
const KEYBOARD_BIT_START: u32 = 0;
|
|
|
|
const KEYBOARD_BIT_END: u32 = 1;
|
2024-02-17 08:44:14 +05:30
|
|
|
|
|
|
|
// 3 bytes PC
|
2024-02-16 23:13:59 +05:30
|
|
|
const PC_START_ADDR: u32 = 2;
|
|
|
|
const PC_LEN: u32 = 3;
|
|
|
|
const PC_END_ADDR: u32 = PC_START_ADDR + PC_LEN - 1;
|
|
|
|
|
2024-02-17 08:44:14 +05:30
|
|
|
// 1 byte pixel base reg
|
2024-02-16 23:13:59 +05:30
|
|
|
const PIXEL_BASE: u32 = 5;
|
2024-02-17 08:44:14 +05:30
|
|
|
|
|
|
|
// 2 byte audio sample base reg
|
2024-02-16 23:13:59 +05:30
|
|
|
const AUDIO_SAMPLE_BASE_START: u32 = 6;
|
|
|
|
const AUDIO_SAMPLE_BASE_LEN: u32 = 2;
|
|
|
|
const AUDIO_SAMPLE_BASE_END: u32 = AUDIO_SAMPLE_BASE_START + AUDIO_SAMPLE_BASE_LEN - 1;
|
|
|
|
|
|
|
|
impl Memory for MemoryMappedIO {
|
2024-02-17 09:54:41 +05:30
|
|
|
fn try_get_byte(&self, address: u32) -> EmulatorResult<u8> {
|
|
|
|
let byte = match address {
|
2024-02-16 23:13:59 +05:30
|
|
|
KEYBOARD_BIT_START..=KEYBOARD_BIT_END => {
|
|
|
|
let addr_usize = address as usize;
|
2024-02-17 08:44:14 +05:30
|
|
|
let keyboard_byte = self.keyboard_bytes[addr_usize];
|
|
|
|
log::trace!("Fetching keyboard({}) byte segment {} -> {}",MemoryOperations::read_big_endian_u16(&self.keyboard_bytes),address,keyboard_byte);
|
|
|
|
keyboard_byte
|
2024-02-17 09:54:41 +05:30
|
|
|
}
|
2024-02-16 23:13:59 +05:30
|
|
|
PC_START_ADDR..=PC_END_ADDR => {
|
|
|
|
let pc_index = (address - PC_START_ADDR) as usize;
|
2024-02-17 08:44:14 +05:30
|
|
|
let pc_byte = self.program_counter[pc_index];
|
|
|
|
log::trace!("Fetching PC({}) byte segment {} -> {}",MemoryOperations::read_big_endian_u24(&self.program_counter),pc_index,pc_byte);
|
|
|
|
pc_byte
|
2024-02-17 09:54:41 +05:30
|
|
|
}
|
2024-02-16 23:13:59 +05:30
|
|
|
PIXEL_BASE => {
|
|
|
|
log::trace!("Fetching pixel base reg {}",self.pixel_reg);
|
|
|
|
self.pixel_reg
|
2024-02-17 09:54:41 +05:30
|
|
|
}
|
2024-02-16 23:13:59 +05:30
|
|
|
AUDIO_SAMPLE_BASE_START => self.audio_sample_address_base[0],
|
|
|
|
AUDIO_SAMPLE_BASE_END => self.audio_sample_address_base[1],
|
|
|
|
_ => { panic!("Unreachable code") }
|
2024-02-17 09:54:41 +05:30
|
|
|
};
|
|
|
|
Ok(byte)
|
2024-02-16 23:13:59 +05:30
|
|
|
}
|
|
|
|
|
2024-02-17 09:54:41 +05:30
|
|
|
fn try_set_byte(&mut self, address: u32, val: u8) -> EmulatorResult<()> {
|
2024-02-16 23:13:59 +05:30
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|