Initial commit

This commit is contained in:
2025-12-07 11:34:37 -06:00
commit d97a8559ec
17 changed files with 8387 additions and 0 deletions

163
src/mem.rs Normal file
View File

@@ -0,0 +1,163 @@
use crate::hex_view::Memory;
pub enum Value<'a, R> {
Value(u8),
Register { reg: &'a R, offset: u16 },
}
impl<R> Value<'_, R> {
pub fn reg_map(self, f: impl FnOnce(&R, u16) -> u8) -> u8 {
match self {
Value::Value(v) => v,
Value::Register { reg, offset } => f(reg, offset),
}
}
}
pub enum Data<R> {
RAM(Vec<u8>),
ROM(Vec<u8>),
Mirror(usize),
Reg(R),
// Disabled(),
}
pub struct Segment<R> {
name: &'static str,
position: u16,
size: u16,
mem: Data<R>,
}
impl<R> Segment<R> {
pub fn ram(name: &'static str, position: u16, size: u16) -> Self {
Self {
name,
position,
size,
mem: Data::RAM(vec![0u8; size as usize]),
}
}
pub fn rom(name: &'static str, position: u16, raw: &[u8]) -> Self {
Self {
name,
position,
size: raw.len() as u16,
mem: Data::ROM(Vec::from(raw)),
}
}
pub fn reg(name: &'static str, position: u16, size: u16, reg: R) -> Self {
Self {
name,
position,
size,
mem: Data::Reg(reg),
}
}
pub fn mirror(name: &'static str, position: u16, size: u16, of: usize) -> Self {
Self {
name,
position,
size,
mem: Data::Mirror(of),
}
}
}
pub struct MemoryMap<R> {
edit_ver: usize,
segments: Vec<Segment<R>>,
}
impl<R> MemoryMap<R> {
pub fn new(segments: Vec<Segment<R>>) -> Self {
Self { edit_ver: 0, segments }
}
pub fn read(&self, addr: u16) -> Value<'_, R> {
// self.edit_ver += 1;
for segment in &self.segments {
if segment.position <= addr && addr - segment.position < segment.size {
return match &segment.mem {
Data::RAM(items) => Value::Value(items[(addr - segment.position) as usize]),
Data::ROM(items) => Value::Value(items[(addr - segment.position) as usize]),
Data::Reg(reg) => Value::Register {
reg,
offset: addr - segment.position,
},
Data::Mirror(index) => {
let offset = addr - segment.position;
let s = &self.segments[*index];
self.read(s.position + offset % s.size)
}
// Data::Disabled() => todo!(),
};
}
}
todo!("Open bus")
}
pub fn write(&mut self, addr: u16, val: u8, reg_fn: impl FnOnce(&R, u16, u8)) {
self.edit_ver += 1;
for segment in &mut self.segments {
if segment.position <= addr && addr - segment.position < segment.size {
return match &mut segment.mem {
Data::RAM(items) => {
items[(addr - segment.position) as usize] = val;
}
Data::ROM(_items) => (),
Data::Reg(reg) => reg_fn(reg, addr - segment.position, val),
Data::Mirror(index) => {
let offset = addr - segment.position;
let index = *index;
let s = &self.segments[index];
self.write(s.position + offset % s.size, val, reg_fn)
}
// Data::Disabled() => todo!(),
};
}
}
todo!("Open bus")
}
pub fn clear(&mut self) {
for s in &mut self.segments {
match &mut s.mem {
Data::RAM(items) => items.fill(0),
_ => (),
}
}
}
pub(crate) fn rom(&self, idx: usize) -> Option<&[u8]> {
if let Some(Segment { mem: Data::ROM(val), .. }) = self.segments.get(idx) {
Some(val)
} else {
None
}
}
}
impl<R> Memory for MemoryMap<R> {
fn peek(&self, addr: u16) -> Option<u8> {
for segment in &self.segments {
if segment.position <= addr && addr - segment.position < segment.size {
return match &segment.mem {
Data::RAM(items) => Some(items[(addr - segment.position) as usize]),
Data::ROM(items) => Some(items[(addr - segment.position) as usize]),
Data::Reg(_) => None,
Data::Mirror(index) => {
let offset = addr - segment.position;
let s = &self.segments[*index];
self.peek(s.position + offset % s.size)
}
// Data::Disabled() => todo!(),
};
}
}
None
}
fn edit_ver(&self) -> usize {
self.edit_ver
}
}