From 9095333793e1d012360df5b9ef44e47a769a87f4 Mon Sep 17 00:00:00 2001 From: transistor Date: Wed, 29 Sep 2021 17:11:48 -0700 Subject: [PATCH] Reorganized and started working on the execution code --- src/{m68k.rs => cpus/m68k/decode.rs} | 216 ++++---------- src/cpus/m68k/execute.rs | 407 +++++++++++++++++++++++++++ src/cpus/m68k/mod.rs | 6 + src/cpus/mod.rs | 3 + src/main.rs | 6 +- src/memory.rs | 11 + 6 files changed, 487 insertions(+), 162 deletions(-) rename src/{m68k.rs => cpus/m68k/decode.rs} (85%) create mode 100644 src/cpus/m68k/execute.rs create mode 100644 src/cpus/m68k/mod.rs create mode 100644 src/cpus/mod.rs diff --git a/src/m68k.rs b/src/cpus/m68k/decode.rs similarity index 85% rename from src/m68k.rs rename to src/cpus/m68k/decode.rs index 3f3637d..e339341 100644 --- a/src/m68k.rs +++ b/src/cpus/m68k/decode.rs @@ -2,72 +2,47 @@ use crate::error::Error; use crate::memory::{Address, AddressSpace}; -pub trait Processor { - fn reset(); - fn step(); -} - - +use super::execute::MC68010; +use super::execute::ERR_ILLEGAL_INSTRUCTION; #[derive(Copy, Clone, Debug, PartialEq)] -pub enum State { - Init, - Running, - Halted, -} - -pub struct MC68010 { - pub state: State, - - pub pc: u32, - pub msp: u32, - pub usp: u32, - pub flags: u16, - pub d_reg: [u32; 8], - pub a_reg: [u32; 8], - - pub vbr: u32, -} - -const FLAGS_ON_RESET: u16 = 0x2700; - -const FLAGS_SUPERVISOR: u16 = 0x2000; - -const ERR_BUS_ERROR: u32 = 2; -const ERR_ADDRESS_ERROR: u32 = 3; -const ERR_ILLEGAL_INSTRUCTION: u32 = 4; - -#[derive(Copy, Clone, Debug, PartialEq)] -enum Sign { +pub enum Sign { Signed, Unsigned, } #[derive(Copy, Clone, Debug, PartialEq)] -enum Direction { +pub enum Direction { FromTarget, ToTarget, } #[derive(Copy, Clone, Debug, PartialEq)] -enum ShiftDirection { +pub enum ShiftDirection { Right, Left, } + #[derive(Copy, Clone, Debug, PartialEq)] -enum ControlRegister { +pub enum RegisterType { + Data, + Address, +} + +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum ControlRegister { VBR, } #[derive(Copy, Clone, Debug, PartialEq)] -enum Size { +pub enum Size { Byte, Word, Long, } #[derive(Copy, Clone, Debug, PartialEq)] -enum Condition { +pub enum Condition { True, False, High, @@ -87,22 +62,22 @@ enum Condition { } #[derive(Clone, Debug, PartialEq)] -enum Target { +pub enum Target { Immediate(u32), DirectDReg(u8), DirectAReg(u8), IndirectAReg(u8), IndirectARegInc(u8), IndirectARegDec(u8), - IndirectARegOffset(u8, u16), - IndirectARegXRegOffset(u8, Box, u16, Size), + IndirectARegOffset(u8, i32), + IndirectARegXRegOffset(u8, RegisterType, u8, i32, Size), IndirectMemory(u32), - IndirectPCOffset(u16), - IndirectPCXRegOffset(Box, u16, Size), + IndirectPCOffset(i32), + IndirectPCXRegOffset(RegisterType, u8, i32, Size), } #[derive(Clone, Debug, PartialEq)] -enum Instruction { +pub enum Instruction { //ABCD ADD(Target, Target, Size), AND(Target, Target, Size), @@ -110,9 +85,9 @@ enum Instruction { ANDtoSR(u16), ASd(Target, Target, Size, ShiftDirection), - Bcc(Condition, u16), - BRA(u16), - BSR(u16), + Bcc(Condition, i16), + BRA(i16), + BSR(i16), BTST(Target, Target, Size), BCHG(Target, Target, Size), BCLR(Target, Target, Size), @@ -203,57 +178,6 @@ const OPCG_RESERVED2: u8 = 0xF; impl MC68010 { - pub fn new() -> MC68010 { - MC68010 { - state: State::Init, - pc: 0, - msp: 0, - usp: 0, - flags: FLAGS_ON_RESET, - d_reg: [0; 8], - a_reg: [0; 8], - vbr: 0, - } - } - - pub fn reset(&mut self) { - self.state = State::Init; - self.pc = 0; - self.msp = 0; - self.usp = 0; - self.flags = FLAGS_ON_RESET; - self.d_reg = [0; 8]; - self.a_reg = [0; 8]; - self.vbr = 0; - } - - pub fn is_running(&self) -> bool { - self.state != State::Halted - } - - - pub fn init(&mut self, space: &mut AddressSpace) -> Result<(), Error> { - println!("Initializing CPU"); - - self.msp = space.read_beu32(0)?; - self.pc = space.read_beu32(4)?; - self.state = State::Running; - - Ok(()) - } - - pub fn step(&mut self, space: &mut AddressSpace) -> Result<(), Error> { - match self.state { - State::Init => self.init(space), - State::Halted => Err(Error::new("CPU halted")), - State::Running => self.execute_one(space), - } - } - - fn is_supervisor(&self) -> bool { - self.flags & FLAGS_SUPERVISOR != 0 - } - fn read_instruction_word(&mut self, space: &mut AddressSpace) -> Result { let word = space.read_beu16(self.pc as Address)?; println!("{:08x} {:04x?}", self.pc, word); @@ -268,39 +192,7 @@ impl MC68010 { Ok(word) } - fn push_long(&mut self, space: &mut AddressSpace, value: u32) -> Result<(), Error> { - let reg = if self.is_supervisor() { &mut self.msp } else { &mut self.usp }; - *reg -= 4; - space.write_beu32(*reg as Address, value) - } - - fn execute_one(&mut self, space: &mut AddressSpace) -> Result<(), Error> { - let addr = self.pc; - let ins = self.decode_one(space)?; - - println!("{:08x}: {:?}", addr, ins); - match ins { - /* - Instruction::JSR(target) => { - self.push_long(space, self.pc)?; - self.pc = self.get_target_value(space, target)?; - }, - */ - _ => { /* panic!(""); */ }, - } - - Ok(()) - } - - fn get_target_value(&mut self, space: &mut AddressSpace, target: Target) -> Result { - match target { - Target::Immediate(value) => Ok(value), - Target::DirectDReg(reg) => Ok(self.d_reg[reg as usize]), - _ => Err(Error::new(&format!("Unimplemented addressing target: {:?}", target))), - } - } - - fn decode_one(&mut self, space: &mut AddressSpace) -> Result { + pub fn decode_one(&mut self, space: &mut AddressSpace) -> Result { let ins = self.read_instruction_word(space)?; match ((ins & 0xF000) >> 12) as u8 { @@ -355,7 +247,7 @@ impl MC68010 { let target = self.decode_lower_effective_address(space, ins, size)?; let data = match size { Some(Size::Long) => self.read_instruction_long(space)?, - Some(size) => self.read_instruction_word(space)? as u32, + Some(_) => self.read_instruction_word(space)? as u32, None => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)), }; @@ -444,14 +336,14 @@ impl MC68010 { (0b011, 0b000) => { Ok(Instruction::EXT(get_low_reg(ins), Size::Long)) }, - (0b000, mode) => { + (0b000, _) => { let target = self.decode_lower_effective_address(space, ins, Some(Size::Byte))?; Ok(Instruction::NBCD(target)) }, (0b001, 0b000) => { Ok(Instruction::SWAP(get_low_reg(ins))) }, - (0b001, mode) => { + (0b001, _) => { let target = self.decode_lower_effective_address(space, ins, None)?; Ok(Instruction::PEA(target)) }, @@ -464,6 +356,8 @@ impl MC68010 { } else { Ok(Instruction::JMP(target)) } + } else if (ins & 0b111111110000) == 0b111001000000 { + Ok(Instruction::TRAP((ins & 0x000F) as u8)) } else if (ins & 0b111111110000) == 0b111001010000 { let reg = get_low_reg(ins); if (ins & 0b1000) == 0 { @@ -525,15 +419,15 @@ impl MC68010 { } }, OPCG_BRANCH => { - let mut disp = (ins & 0xFF); + let mut disp = ins & 0xFF; if disp == 0 { disp = self.read_instruction_word(space)?; } let condition = get_condition(ins); match condition { - Condition::True => Ok(Instruction::BRA(disp)), - Condition::False => Ok(Instruction::BSR(disp)), - _ => Ok(Instruction::Bcc(condition, disp)), + Condition::True => Ok(Instruction::BRA(disp as i16)), + Condition::False => Ok(Instruction::BSR(disp as i16)), + _ => Ok(Instruction::Bcc(condition, disp as i16)), } }, OPCG_MOVEQ => { @@ -595,7 +489,7 @@ impl MC68010 { let target = self.decode_lower_effective_address(space, ins, Some(size))?; Ok(Instruction::CMP(Target::DirectDReg(reg), target, size)) }, - (size, None) => { + (_, None) => { let size = if optype == 0 { Size::Word } else { Size::Long }; let target = self.decode_lower_effective_address(space, ins, Some(size))?; Ok(Instruction::CMP(target, Target::DirectAReg(reg), size)) @@ -692,18 +586,14 @@ impl MC68010 { self.get_mode_as_target(space, mode, reg, size) } - fn decode_brief_extension_word(&self, brief_extension: u16) -> (Target, u16, Size) { + fn decode_brief_extension_word(&self, brief_extension: u16) -> (RegisterType, u8, u16, Size) { let data = brief_extension & 0x00FF; - let reg = ((brief_extension & 0x7000) >> 12) as u8; + let xreg = ((brief_extension & 0x7000) >> 12) as u8; let size = if (brief_extension & 0x0800) == 0 { Size::Word } else { Size::Long }; - let target = if (brief_extension & 0x8000) == 0 { - Target::DirectDReg(reg) - } else { - Target::DirectAReg(reg) - }; + let rtype = if (brief_extension & 0x8000) == 0 { RegisterType::Data } else { RegisterType::Address }; - (target, data, size) + (rtype, xreg, data, size) } fn get_mode_as_target(&mut self, space: &mut AddressSpace, mode: u8, reg: u8, size: Option) -> Result { @@ -714,13 +604,13 @@ impl MC68010 { 0b011 => Target::IndirectARegInc(reg), 0b100 => Target::IndirectARegDec(reg), 0b101 => { - let d16 = self.read_instruction_word(space)?; - Target::IndirectARegOffset(reg, d16) + let data = self.read_instruction_word(space)?; + Target::IndirectARegOffset(reg, (data as i16) as i32) }, 0b110 => { let brief_extension = self.read_instruction_word(space)?; - let (target, data, size) = self.decode_brief_extension_word(brief_extension); - Target::IndirectARegXRegOffset(reg, Box::new(target), data, size) + let (rtype, xreg, data, size) = self.decode_brief_extension_word(brief_extension); + Target::IndirectARegXRegOffset(reg, rtype, xreg, (data as i16) as i32, size) }, 0b111 => { match reg { @@ -733,13 +623,13 @@ impl MC68010 { Target::IndirectMemory(value) }, 0b010 => { - let d16 = self.read_instruction_word(space)?; - Target::IndirectPCOffset(d16) + let data = self.read_instruction_word(space)?; + Target::IndirectPCOffset((data as i16) as i32) }, 0b011 => { let brief_extension = self.read_instruction_word(space)?; - let (target, data, size) = self.decode_brief_extension_word(brief_extension); - Target::IndirectPCXRegOffset(Box::new(target), data, size) + let (rtype, xreg, data, size) = self.decode_brief_extension_word(brief_extension); + Target::IndirectPCXRegOffset(rtype, xreg, (data as i16) as i32, size) }, 0b100 => { let data = match size { @@ -813,8 +703,14 @@ fn get_condition(ins: u16) -> Condition { } } -/* -impl Processor for MC68010 { +impl Size { + pub fn in_bytes(&self) -> u32 { + match self { + Size::Byte => 1, + Size::Word => 2, + Size::Long => 4, + } + } } -*/ + diff --git a/src/cpus/m68k/execute.rs b/src/cpus/m68k/execute.rs new file mode 100644 index 0000000..090ab9b --- /dev/null +++ b/src/cpus/m68k/execute.rs @@ -0,0 +1,407 @@ + +use crate::error::Error; +use crate::memory::{Address, AddressSpace}; + +use super::decode::{Instruction, Target, Size, Direction, ControlRegister, RegisterType}; + +pub trait Processor { + fn reset(); + fn step(); +} + + + +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum State { + Init, + Running, + Halted, +} + +pub struct MC68010 { + pub state: State, + + pub pc: u32, + pub sr: u16, + pub d_reg: [u32; 8], + pub a_reg: [u32; 7], + pub msp: u32, + pub usp: u32, + + pub vbr: u32, +} + +const FLAGS_ON_RESET: u16 = 0x2700; + +pub const FLAGS_SUPERVISOR: u16 = 0x2000; + +pub const ERR_BUS_ERROR: u32 = 2; +pub const ERR_ADDRESS_ERROR: u32 = 3; +pub const ERR_ILLEGAL_INSTRUCTION: u32 = 4; + +impl MC68010 { + pub fn new() -> MC68010 { + MC68010 { + state: State::Init, + + pc: 0, + sr: FLAGS_ON_RESET, + d_reg: [0; 8], + a_reg: [0; 7], + msp: 0, + usp: 0, + + vbr: 0, + } + } + + pub fn reset(&mut self) { + self.state = State::Init; + self.pc = 0; + self.sr = FLAGS_ON_RESET; + self.d_reg = [0; 8]; + self.a_reg = [0; 7]; + self.msp = 0; + self.usp = 0; + + self.vbr = 0; + } + + pub fn is_running(&self) -> bool { + self.state != State::Halted + } + + + pub fn init(&mut self, space: &mut AddressSpace) -> Result<(), Error> { + println!("Initializing CPU"); + + self.msp = space.read_beu32(0)?; + self.pc = space.read_beu32(4)?; + self.state = State::Running; + + Ok(()) + } + + pub fn step(&mut self, space: &mut AddressSpace) -> Result<(), Error> { + match self.state { + State::Init => self.init(space), + State::Halted => Err(Error::new("CPU halted")), + State::Running => self.execute_one(space), + } + } + + fn is_supervisor(&self) -> bool { + self.sr & FLAGS_SUPERVISOR != 0 + } + + fn push_long(&mut self, space: &mut AddressSpace, value: u32) -> Result<(), Error> { + let reg = if self.is_supervisor() { &mut self.msp } else { &mut self.usp }; + *reg -= 4; + space.write_beu32(*reg as Address, value) + } + + fn execute_one(&mut self, space: &mut AddressSpace) -> Result<(), Error> { + let addr = self.pc; + let ins = self.decode_one(space)?; + + println!("{:08x}: {:?}", addr, ins); + match ins { + //Instruction::ADD(Target, Target, Size) => { + //}, + //Instruction::AND(Target, Target, Size) => { + //}, + //Instruction::ANDtoCCR(u8) => { + //}, + //Instruction::ANDtoSR(u16) => { + //}, + //Instruction::ASd(Target, Target, Size, ShiftDirection) => { + //}, + //Instruction::Bcc(Condition, u16) => { + //}, + Instruction::BRA(offset) => { + self.pc = self.pc.wrapping_add(offset as u32) - 2; + }, + Instruction::BSR(offset) => { + self.push_long(space, self.pc)?; + self.pc = self.pc.wrapping_add(offset as u32) - 2; + }, + //Instruction::BTST(Target, Target, Size) => { + //}, + //Instruction::BCHG(Target, Target, Size) => { + //}, + //Instruction::BCLR(Target, Target, Size) => { + //}, + //Instruction::BSET(Target, Target, Size) => { + //}, + Instruction::CLR(target, size) => { + self.set_target_value(space, target, 0, size)?; + }, + //Instruction::CMP(Target, Target, Size) => { + //}, + //Instruction::DBcc(Condition, u16) => { + //}, + //Instruction::DIV(Target, Target, Size, Sign) => { + //}, + //Instruction::EOR(Target, Target, Size) => { + //}, + //Instruction::EORtoCCR(u8) => { + //}, + //Instruction::EORtoSR(u16) => { + //}, + //Instruction::EXG(Target, Target) => { + //}, + //Instruction::EXT(u8, Size) => { + //}, + //Instruction::ILLEGAL => { + //}, + Instruction::JMP(target) => { + self.pc = self.get_target_address(target)?; + }, + Instruction::JSR(target) => { + self.push_long(space, self.pc)?; + self.pc = self.get_target_address(target)?; + }, + Instruction::LEA(target, reg) => { + let value = self.get_target_address(target)?; + let addr = self.get_a_reg(reg); + *addr = value; + }, + //Instruction::LINK(u8, u16) => { + //}, + //Instruction::LSd(Target, Target, Size, ShiftDirection) => { + //}, + Instruction::MOVE(src, dest, size) => { + let value = self.get_target_value(space, src, size)?; + self.set_target_value(space, dest, value, size)?; + }, + Instruction::MOVEfromSR(target) => { + self.set_target_value(space, target, self.sr as u32, Size::Word)?; + }, + Instruction::MOVEtoSR(target) => { + self.sr = self.get_target_value(space, target, Size::Word)? as u16; + }, + //Instruction::MOVEtoCCR(Target) => { + //}, + Instruction::MOVEC(target, control_reg, dir) => { + match dir { + Direction::FromTarget => { + let value = self.get_target_value(space, target, Size::Long)?; + let addr = self.get_control_reg_mut(control_reg); + *addr = value; + }, + Direction::ToTarget => { + let addr = self.get_control_reg_mut(control_reg); + let value = *addr; + self.set_target_value(space, target, value, Size::Long)?; + }, + } + }, + //Instruction::MOVEUSP(Target, Direction) => { + //}, + //Instruction::MOVEM(Target, Size, Direction, u16) => { + //}, + //Instruction::MOVEQ(u8, u8) => { + //}, + //Instruction::MUL(Target, Target, Size, Sign) => { + //}, + //Instruction::NBCD(Target) => { + //}, + //Instruction::NEG(Target, Size) => { + //}, + //Instruction::NEGX(Target, Size) => { + //}, + Instruction::NOP => { }, + //Instruction::NOT(Target, Size) => { + //}, + //Instruction::OR(Target, Target, Size) => { + //}, + //Instruction::ORtoCCR(u8) => { + //}, + Instruction::ORtoSR(value) => { + self.sr = self.sr | value; + }, + //Instruction::PEA(Target) => { + //}, + //Instruction::RESET => { + //}, + //Instruction::ROd(Target, Target, Size, ShiftDirection) => { + //}, + //Instruction::ROXd(Target, Target, Size, ShiftDirection) => { + //}, + //Instruction::RTE => { + //}, + //Instruction::RTR => { + //}, + //Instruction::RTS => { + //}, + //Instruction::STOP(u16) => { + //}, + //Instruction::SUB(Target, Target, Size) => { + //}, + //Instruction::SWAP(u8) => { + //}, + //Instruction::TAS(Target) => { + //}, + //Instruction::TST(Target, Size) => { + //}, + //Instruction::TRAP(u8) => { + //}, + //Instruction::TRAPV => { + //}, + //Instruction::UNLK(u8) => { + //}, + _ => { panic!(""); }, + } + + Ok(()) + } + + fn get_target_value(&mut self, space: &mut AddressSpace, target: Target, size: Size) -> Result { + match target { + Target::Immediate(value) => Ok(value), + Target::DirectDReg(reg) => Ok(get_value_sized(self.d_reg[reg as usize], size)), + Target::DirectAReg(reg) => Ok(get_value_sized(*self.get_a_reg(reg), size)), + Target::IndirectAReg(reg) => get_address_sized(space, *self.get_a_reg(reg) as Address, size), + Target::IndirectARegInc(reg) => { + let addr = self.get_a_reg(reg); + let value = get_address_sized(space, *addr as Address, size); + *addr += size.in_bytes(); + value + }, + Target::IndirectARegDec(reg) => { + let addr = self.get_a_reg(reg); + *addr -= size.in_bytes(); + get_address_sized(space, *addr as Address, size) + }, + Target::IndirectARegOffset(reg, offset) => { + let addr = self.get_a_reg(reg); + get_address_sized(space, (*addr).wrapping_add(offset as u32) as Address, size) + }, + Target::IndirectARegXRegOffset(reg, rtype, xreg, offset, target_size) => { + let reg_offset = get_value_sized(self.get_x_reg_value(rtype, xreg), target_size); + let addr = self.get_a_reg(reg); + get_address_sized(space, (*addr).wrapping_add(reg_offset).wrapping_add(offset as u32) as Address, size) + }, + Target::IndirectMemory(addr) => { + get_address_sized(space, addr as Address, size) + }, + Target::IndirectPCOffset(offset) => { + get_address_sized(space, self.pc.wrapping_add(offset as u32) as Address, size) + }, + Target::IndirectPCXRegOffset(rtype, xreg, offset, target_size) => { + let reg_offset = get_value_sized(self.get_x_reg_value(rtype, xreg), target_size); + get_address_sized(space, self.pc.wrapping_add(reg_offset).wrapping_add(offset as u32) as Address, size) + }, + _ => Err(Error::new(&format!("Unimplemented addressing target: {:?}", target))), + } + } + + fn set_target_value(&mut self, space: &mut AddressSpace, target: Target, value: u32, size: Size) -> Result<(), Error> { + match target { + Target::DirectDReg(reg) => { + set_value_sized(&mut self.d_reg[reg as usize], value, size); + }, + Target::DirectAReg(reg) => { + set_value_sized(self.get_a_reg(reg), value, size); + }, + Target::IndirectAReg(reg) => { + set_address_sized(space, *self.get_a_reg(reg) as Address, value, size)?; + }, + _ => return Err(Error::new(&format!("Unimplemented addressing target: {:?}", target))), + } + Ok(()) + } + + fn get_target_address(&mut self, target: Target) -> Result { + let addr = match target { + Target::IndirectAReg(reg) => *self.get_a_reg(reg), + Target::IndirectARegOffset(reg, offset) => { + let addr = self.get_a_reg(reg); + (*addr).wrapping_add(offset as u32) + }, + Target::IndirectARegXRegOffset(reg, rtype, xreg, offset, target_size) => { + let reg_offset = get_value_sized(self.get_x_reg_value(rtype, xreg), target_size); + let addr = self.get_a_reg(reg); + (*addr).wrapping_add(reg_offset).wrapping_add(offset as u32) + }, + Target::IndirectMemory(addr) => { + addr + }, + Target::IndirectPCOffset(offset) => { + self.pc.wrapping_add(offset as u32) + }, + Target::IndirectPCXRegOffset(rtype, xreg, offset, target_size) => { + let reg_offset = get_value_sized(self.get_x_reg_value(rtype, xreg), target_size); + self.pc.wrapping_add(reg_offset).wrapping_add(offset as u32) + }, + _ => return Err(Error::new(&format!("Unimplemented addressing target: {:?}", target))), + }; + Ok(addr) + } + + fn get_control_reg_mut(&mut self, control_reg: ControlRegister) -> &mut u32 { + match control_reg { + ControlRegister::VBR => &mut self.vbr, + } + } + + #[inline(always)] + fn get_stack_pointer(&mut self) -> &mut u32 { + if self.is_supervisor() { &mut self.msp } else { &mut self.usp } + } + + #[inline(always)] + fn get_a_reg(&mut self, reg: u8) -> &mut u32 { + if reg == 7 { + if self.is_supervisor() { &mut self.msp } else { &mut self.usp } + } else { + &mut self.a_reg[reg as usize] + } + } + + fn get_x_reg_value(&self, rtype: RegisterType, reg: u8) -> u32 { + match rtype { + RegisterType::Data => self.d_reg[reg as usize], + RegisterType::Address => self.d_reg[reg as usize], + } + } +} + +fn get_value_sized(value: u32, size: Size) -> u32 { + match size { + Size::Byte => { 0x000000FF & value }, + Size::Word => { 0x0000FFFF & value }, + Size::Long => { value }, + } +} + +fn get_address_sized(space: &mut AddressSpace, addr: Address, size: Size) -> Result { + match size { + Size::Byte => space.read_u8(addr).map(|value| value as u32), + Size::Word => space.read_beu16(addr).map(|value| value as u32), + Size::Long => space.read_beu32(addr), + } +} + +fn set_value_sized(addr: &mut u32, value: u32, size: Size) { + match size { + Size::Byte => { *addr = (*addr & 0xFFFFFF00) | (0x000000FF & value); } + Size::Word => { *addr = (*addr & 0xFFFF0000) | (0x0000FFFF & value); } + Size::Long => { *addr = value; } + } +} + +fn set_address_sized(space: &mut AddressSpace, addr: Address, value: u32, size: Size) -> Result<(), Error> { + match size { + Size::Byte => space.write_u8(addr, value as u8), + Size::Word => space.write_beu16(addr, value as u16), + Size::Long => space.write_beu32(addr, value), + } +} + + +/* +impl Processor for MC68010 { + +} +*/ diff --git a/src/cpus/m68k/mod.rs b/src/cpus/m68k/mod.rs new file mode 100644 index 0000000..c4f401f --- /dev/null +++ b/src/cpus/m68k/mod.rs @@ -0,0 +1,6 @@ + +mod decode; +mod execute; + +pub use self::execute::MC68010; + diff --git a/src/cpus/mod.rs b/src/cpus/mod.rs new file mode 100644 index 0000000..58eaa30 --- /dev/null +++ b/src/cpus/mod.rs @@ -0,0 +1,3 @@ + +pub mod m68k; + diff --git a/src/main.rs b/src/main.rs index 4e08f22..faa9620 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,10 +2,10 @@ #[macro_use] mod error; mod memory; -mod m68k; +mod cpus; use crate::memory::{AddressSpace, Segment}; -use crate::m68k::MC68010; +use crate::cpus::m68k::MC68010; fn main() { let mut space = AddressSpace::new(); @@ -15,6 +15,8 @@ fn main() { } space.insert(monitor); + let ram = Segment::new(0x00100000, vec![0; 0x00100000]); + space.insert(ram); let mut cpu = MC68010::new(); while cpu.is_running() { diff --git a/src/memory.rs b/src/memory.rs index f1aa502..2777f37 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -88,6 +88,11 @@ impl AddressSpace { } + pub fn read_u8(&self, addr: Address) -> Result { + let seg = self.get_segment(addr)?; + Ok(*seg.read(addr).next().unwrap()) + } + pub fn read_beu16(&self, addr: Address) -> Result { let seg = self.get_segment(addr)?; Ok(read_beu16(seg.read(addr))) @@ -98,6 +103,12 @@ impl AddressSpace { Ok(read_beu32(seg.read(addr))) } + pub fn write_u8(&mut self, addr: Address, value: u8) -> Result<(), Error> { + let seg = self.get_segment_mut(addr)?; + let data = [value]; + Ok(seg.write(addr, &data)) + } + pub fn write_beu16(&mut self, addr: Address, value: u16) -> Result<(), Error> { let seg = self.get_segment_mut(addr)?; let data = [