Fixed warnings

This commit is contained in:
transistor 2021-11-13 11:39:20 -08:00
parent 674f03c3b8
commit a00d7b2f26
26 changed files with 300 additions and 251 deletions

View File

@ -68,7 +68,7 @@ impl Debuggable for M68k {
decoder.dump_disassembly(&mut self.port, addr as u32, count as u32);
}
fn execute_command(&mut self, system: &System, args: &[&str]) -> Result<bool, Error> {
fn execute_command(&mut self, _system: &System, args: &[&str]) -> Result<bool, Error> {
match args[0] {
"ds" | "stack" | "dumpstack" => {
println!("Stack:");

View File

@ -1,6 +1,5 @@
use crate::error::Error;
use crate::system::System;
use crate::devices::{Address, Addressable};
use super::state::{M68kType, Exceptions};

View File

@ -62,7 +62,7 @@ impl M68k {
pub fn step_internal(&mut self, system: &System) -> Result<(), Error> {
match self.state.status {
Status::Init => self.init(system),
Status::Init => self.init(),
Status::Stopped => Err(Error::new("CPU stopped")),
Status::Running => {
match self.cycle_one(system) {
@ -70,7 +70,7 @@ impl M68k {
//Err(Error { err: ErrorType::Processor, native, .. }) => {
// TODO match arm conditional is temporary: illegal instructions generate a top level error in order to debug and fix issues with decode
Err(Error { err: ErrorType::Processor, native, .. }) if native != Exceptions::IllegalInstruction as u32 => {
self.exception(system, native as u8, false)?;
self.exception(native as u8, false)?;
Ok(())
},
Err(err) => Err(err),
@ -79,7 +79,7 @@ impl M68k {
}
}
pub fn init(&mut self, system: &System) -> Result<(), Error> {
pub fn init(&mut self) -> Result<(), Error> {
self.state.msp = self.port.read_beu32(0)?;
self.state.pc = self.port.read_beu32(4)?;
self.state.status = Status::Running;
@ -88,8 +88,8 @@ impl M68k {
pub fn cycle_one(&mut self, system: &System) -> Result<(), Error> {
self.timer.cycle.start();
self.decode_next(system)?;
self.execute_current(system)?;
self.decode_next()?;
self.execute_current()?;
self.timer.cycle.end();
//if (self.timer.cycle.events % 500) == 0 {
@ -117,7 +117,7 @@ impl M68k {
debug!("{} interrupt: {} {}", DEV_NAME, pending_ipl, priority_mask);
self.state.current_ipl = self.state.pending_ipl;
let ack_num = system.get_interrupt_controller().acknowledge(self.state.current_ipl as u8)?;
self.exception(system, ack_num, true)?;
self.exception(ack_num, true)?;
return Ok(());
}
}
@ -129,14 +129,14 @@ impl M68k {
Ok(())
}
pub fn exception(&mut self, system: &System, number: u8, is_interrupt: bool) -> Result<(), Error> {
pub fn exception(&mut self, number: u8, is_interrupt: bool) -> Result<(), Error> {
debug!("{}: raising exception {}", DEV_NAME, number);
let offset = (number as u16) << 2;
if self.cputype >= M68kType::MC68010 {
self.push_word(system, offset)?;
self.push_word(offset)?;
}
self.push_long(system, self.state.pc)?;
self.push_word(system, self.state.sr)?;
self.push_long(self.state.pc)?;
self.push_word(self.state.sr)?;
// Changes to the flags must happen after the previous value has been pushed to the stack
self.set_flag(Flags::Supervisor, true);
@ -150,7 +150,7 @@ impl M68k {
Ok(())
}
pub fn decode_next(&mut self, system: &System) -> Result<(), Error> {
pub fn decode_next(&mut self) -> Result<(), Error> {
self.timer.decode.start();
self.decoder.decode_at(&mut self.port, self.state.pc)?;
self.timer.decode.end();
@ -164,22 +164,22 @@ impl M68k {
Ok(())
}
pub fn execute_current(&mut self, system: &System) -> Result<(), Error> {
pub fn execute_current(&mut self) -> Result<(), Error> {
self.timer.execute.start();
match self.decoder.instruction {
//Instruction::ABCD(Target) => {
//},
Instruction::ADD(src, dest, size) => {
let value = self.get_target_value(system, src, size)?;
let existing = self.get_target_value(system, dest, size)?;
let value = self.get_target_value(src, size)?;
let existing = self.get_target_value(dest, size)?;
let (result, carry) = overflowing_add_sized(existing, value, size);
let overflow = get_add_overflow(existing, value, result, size);
self.set_compare_flags(result, size, carry, overflow);
self.set_flag(Flags::Extend, carry);
self.set_target_value(system, dest, result, size)?;
self.set_target_value(dest, result, size)?;
},
Instruction::ADDA(src, dest, size) => {
let value = sign_extend_to_long(self.get_target_value(system, src, size)?, size) as u32;
let value = sign_extend_to_long(self.get_target_value(src, size)?, size) as u32;
let existing = *self.get_a_reg_mut(dest);
let (result, _) = overflowing_add_sized(existing, value, Size::Long);
*self.get_a_reg_mut(dest) = result;
@ -187,10 +187,10 @@ impl M68k {
//Instruction::ADDX(Target) => {
//},
Instruction::AND(src, dest, size) => {
let value = self.get_target_value(system, src, size)?;
let existing = self.get_target_value(system, dest, size)?;
let value = self.get_target_value(src, size)?;
let existing = self.get_target_value(dest, size)?;
let result = get_value_sized(existing & value, size);
self.set_target_value(system, dest, result, size)?;
self.set_target_value(dest, result, size)?;
self.set_logic_flags(result, size);
},
Instruction::ANDtoCCR(value) => {
@ -201,8 +201,8 @@ impl M68k {
self.state.sr = self.state.sr & value;
},
Instruction::ASd(count, target, size, shift_dir) => {
let count = self.get_target_value(system, count, size)? % 64;
let mut pair = (self.get_target_value(system, target, size)?, false);
let count = self.get_target_value(count, size)? % 64;
let mut pair = (self.get_target_value(target, size)?, false);
let original = pair.0;
for _ in 0..count {
pair = shift_operation(pair.0, size, shift_dir, true);
@ -215,7 +215,7 @@ impl M68k {
if get_msb(pair.0, size) != get_msb(original, size) {
self.set_flag(Flags::Overflow, true);
}
self.set_target_value(system, target, pair.0, size)?;
self.set_target_value(target, pair.0, size)?;
},
Instruction::Bcc(cond, offset) => {
let should_branch = self.get_current_condition(cond);
@ -227,57 +227,57 @@ impl M68k {
self.state.pc = (self.decoder.start + 2).wrapping_add(offset as u32);
},
Instruction::BSR(offset) => {
self.push_long(system, self.state.pc)?;
self.push_long(self.state.pc)?;
let sp = *self.get_stack_pointer_mut();
self.debugger.stack_tracer.push_return(sp);
self.state.pc = (self.decoder.start + 2).wrapping_add(offset as u32);
},
Instruction::BCHG(bitnum, target, size) => {
let bitnum = self.get_target_value(system, bitnum, Size::Byte)?;
let mut value = self.get_target_value(system, target, size)?;
let bitnum = self.get_target_value(bitnum, Size::Byte)?;
let mut value = self.get_target_value(target, size)?;
let mask = self.set_bit_test_flags(value, bitnum, size);
value = (value & !mask) | (!(value & mask) & mask);
self.set_target_value(system, target, value, size)?;
self.set_target_value(target, value, size)?;
},
Instruction::BCLR(bitnum, target, size) => {
let bitnum = self.get_target_value(system, bitnum, Size::Byte)?;
let mut value = self.get_target_value(system, target, size)?;
let bitnum = self.get_target_value(bitnum, Size::Byte)?;
let mut value = self.get_target_value(target, size)?;
let mask = self.set_bit_test_flags(value, bitnum, size);
value = value & !mask;
self.set_target_value(system, target, value, size)?;
self.set_target_value(target, value, size)?;
},
Instruction::BSET(bitnum, target, size) => {
let bitnum = self.get_target_value(system, bitnum, Size::Byte)?;
let mut value = self.get_target_value(system, target, size)?;
let bitnum = self.get_target_value(bitnum, Size::Byte)?;
let mut value = self.get_target_value(target, size)?;
let mask = self.set_bit_test_flags(value, bitnum, size);
value = value | mask;
self.set_target_value(system, target, value, size)?;
self.set_target_value(target, value, size)?;
},
Instruction::BTST(bitnum, target, size) => {
let bitnum = self.get_target_value(system, bitnum, Size::Byte)?;
let value = self.get_target_value(system, target, size)?;
let bitnum = self.get_target_value(bitnum, Size::Byte)?;
let value = self.get_target_value(target, size)?;
self.set_bit_test_flags(value, bitnum, size);
},
Instruction::BFCHG(target, offset, width) => {
let (offset, width) = self.get_bit_field_args(offset, width);
let mask = get_bit_field_mask(offset, width);
let value = self.get_target_value(system, target, Size::Long)?;
let value = self.get_target_value(target, Size::Long)?;
let field = value & mask;
self.set_bit_field_test_flags(field, get_bit_field_msb(offset));
self.set_target_value(system, target, (value & !mask) | (!field & mask), Size::Long)?;
self.set_target_value(target, (value & !mask) | (!field & mask), Size::Long)?;
},
Instruction::BFCLR(target, offset, width) => {
let (offset, width) = self.get_bit_field_args(offset, width);
let mask = get_bit_field_mask(offset, width);
let value = self.get_target_value(system, target, Size::Long)?;
let value = self.get_target_value(target, Size::Long)?;
let field = value & mask;
self.set_bit_field_test_flags(field, get_bit_field_msb(offset));
self.set_target_value(system, target, value & !mask, Size::Long)?;
self.set_target_value(target, value & !mask, Size::Long)?;
},
Instruction::BFEXTS(target, offset, width, reg) => {
let (offset, width) = self.get_bit_field_args(offset, width);
let mask = get_bit_field_mask(offset, width);
let value = self.get_target_value(system, target, Size::Long)?;
let value = self.get_target_value(target, Size::Long)?;
let field = value & mask;
self.set_bit_field_test_flags(field, get_bit_field_msb(offset));
@ -291,7 +291,7 @@ impl M68k {
Instruction::BFEXTU(target, offset, width, reg) => {
let (offset, width) = self.get_bit_field_args(offset, width);
let mask = get_bit_field_mask(offset, width);
let value = self.get_target_value(system, target, Size::Long)?;
let value = self.get_target_value(target, Size::Long)?;
let field = value & mask;
self.set_bit_field_test_flags(field, get_bit_field_msb(offset));
self.state.d_reg[reg as usize] = field >> (32 - offset - width);
@ -303,15 +303,15 @@ impl M68k {
Instruction::BFSET(target, offset, width) => {
let (offset, width) = self.get_bit_field_args(offset, width);
let mask = get_bit_field_mask(offset, width);
let value = self.get_target_value(system, target, Size::Long)?;
let value = self.get_target_value(target, Size::Long)?;
let field = value & mask;
self.set_bit_field_test_flags(field, get_bit_field_msb(offset));
self.set_target_value(system, target, value | mask, Size::Long)?;
self.set_target_value(target, value | mask, Size::Long)?;
},
Instruction::BFTST(target, offset, width) => {
let (offset, width) = self.get_bit_field_args(offset, width);
let mask = get_bit_field_mask(offset, width);
let value = self.get_target_value(system, target, Size::Long)?;
let value = self.get_target_value(target, Size::Long)?;
let field = value & mask;
self.set_bit_field_test_flags(field, get_bit_field_msb(offset));
},
@ -320,19 +320,19 @@ impl M68k {
//Instruction::CHK(Target, Size) => {
//},
Instruction::CLR(target, size) => {
self.set_target_value(system, target, 0, size)?;
self.set_target_value(target, 0, size)?;
// Clear flags except Zero flag
self.state.sr = (self.state.sr & 0xFFF0) | (Flags::Zero as u16);
},
Instruction::CMP(src, dest, size) => {
let value = self.get_target_value(system, src, size)?;
let existing = self.get_target_value(system, dest, size)?;
let value = self.get_target_value(src, size)?;
let existing = self.get_target_value(dest, size)?;
let (result, carry) = overflowing_sub_sized(existing, value, size);
let overflow = get_sub_overflow(existing, value, result, size);
self.set_compare_flags(result, size, carry, overflow);
},
Instruction::CMPA(src, reg, size) => {
let value = sign_extend_to_long(self.get_target_value(system, src, size)?, size) as u32;
let value = sign_extend_to_long(self.get_target_value(src, size)?, size) as u32;
let existing = *self.get_a_reg_mut(reg);
let (result, carry) = overflowing_sub_sized(existing, value, Size::Long);
let overflow = get_sub_overflow(existing, value, result, size);
@ -349,9 +349,9 @@ impl M68k {
}
},
Instruction::DIVW(src, dest, sign) => {
let value = self.get_target_value(system, src, Size::Word)?;
let value = self.get_target_value(src, Size::Word)?;
if value == 0 {
self.exception(system, Exceptions::ZeroDivide as u8, false)?;
self.exception(Exceptions::ZeroDivide as u8, false)?;
return Ok(());
}
@ -368,9 +368,9 @@ impl M68k {
self.state.d_reg[dest as usize] = (remainder << 16) | (0xFFFF & quotient);
},
Instruction::DIVL(src, dest_h, dest_l, sign) => {
let value = self.get_target_value(system, src, Size::Long)?;
let value = self.get_target_value(src, Size::Long)?;
if value == 0 {
self.exception(system, Exceptions::ZeroDivide as u8, false)?;
self.exception(Exceptions::ZeroDivide as u8, false)?;
return Ok(());
}
@ -399,10 +399,10 @@ impl M68k {
self.state.d_reg[dest_l as usize] = quotient as u32;
},
Instruction::EOR(src, dest, size) => {
let value = self.get_target_value(system, src, size)?;
let existing = self.get_target_value(system, dest, size)?;
let value = self.get_target_value(src, size)?;
let existing = self.get_target_value(dest, size)?;
let result = get_value_sized(existing ^ value, size);
self.set_target_value(system, dest, result, size)?;
self.set_target_value(dest, result, size)?;
self.set_logic_flags(result, size);
},
Instruction::EORtoCCR(value) => {
@ -413,10 +413,10 @@ impl M68k {
self.state.sr = self.state.sr ^ value;
},
Instruction::EXG(target1, target2) => {
let value1 = self.get_target_value(system, target1, Size::Long)?;
let value2 = self.get_target_value(system, target2, Size::Long)?;
self.set_target_value(system, target1, value2, Size::Long)?;
self.set_target_value(system, target2, value1, Size::Long)?;
let value1 = self.get_target_value(target1, Size::Long)?;
let value2 = self.get_target_value(target2, Size::Long)?;
self.set_target_value(target1, value2, Size::Long)?;
self.set_target_value(target2, value1, Size::Long)?;
},
Instruction::EXT(reg, from_size, to_size) => {
let input = get_value_sized(self.state.d_reg[reg as usize], from_size);
@ -432,30 +432,30 @@ impl M68k {
//Instruction::ILLEGAL => {
//},
Instruction::JMP(target) => {
self.state.pc = self.get_target_address(system, target)?;
self.state.pc = self.get_target_address(target)?;
},
Instruction::JSR(target) => {
self.push_long(system, self.state.pc)?;
self.push_long(self.state.pc)?;
let sp = *self.get_stack_pointer_mut();
self.debugger.stack_tracer.push_return(sp);
self.state.pc = self.get_target_address(system, target)?;
self.state.pc = self.get_target_address(target)?;
},
Instruction::LEA(target, reg) => {
let value = self.get_target_address(system, target)?;
let value = self.get_target_address(target)?;
let addr = self.get_a_reg_mut(reg);
*addr = value;
},
Instruction::LINK(reg, offset) => {
let value = *self.get_a_reg_mut(reg);
self.push_long(system, value)?;
self.push_long(value)?;
let sp = *self.get_stack_pointer_mut();
let addr = self.get_a_reg_mut(reg);
*addr = sp;
*self.get_stack_pointer_mut() = sp.wrapping_add((offset as i32) as u32);
},
Instruction::LSd(count, target, size, shift_dir) => {
let count = self.get_target_value(system, count, size)? % 64;
let mut pair = (self.get_target_value(system, target, size)?, false);
let count = self.get_target_value(count, size)? % 64;
let mut pair = (self.get_target_value(target, size)?, false);
for _ in 0..count {
pair = shift_operation(pair.0, size, shift_dir, false);
}
@ -464,48 +464,48 @@ impl M68k {
self.set_flag(Flags::Carry, true);
self.set_flag(Flags::Extend, true);
}
self.set_target_value(system, target, pair.0, size)?;
self.set_target_value(target, pair.0, size)?;
},
Instruction::MOVE(src, dest, size) => {
let value = self.get_target_value(system, src, size)?;
let value = self.get_target_value(src, size)?;
self.set_logic_flags(value, size);
self.set_target_value(system, dest, value, size)?;
self.set_target_value(dest, value, size)?;
},
Instruction::MOVEA(src, reg, size) => {
let value = self.get_target_value(system, src, size)?;
let value = self.get_target_value(src, size)?;
let value = sign_extend_to_long(value, size) as u32;
let addr = self.get_a_reg_mut(reg);
*addr = value;
},
Instruction::MOVEfromSR(target) => {
self.require_supervisor()?;
self.set_target_value(system, target, self.state.sr as u32, Size::Word)?;
self.set_target_value(target, self.state.sr as u32, Size::Word)?;
},
Instruction::MOVEtoSR(target) => {
self.require_supervisor()?;
self.state.sr = self.get_target_value(system, target, Size::Word)? as u16;
self.state.sr = self.get_target_value(target, Size::Word)? as u16;
},
Instruction::MOVEtoCCR(target) => {
let value = self.get_target_value(system, target, Size::Word)? as u16;
let value = self.get_target_value(target, Size::Word)? as u16;
self.state.sr = (self.state.sr & 0xFF00) | (value & 0x00FF);
},
Instruction::MOVEC(target, control_reg, dir) => {
self.require_supervisor()?;
match dir {
Direction::FromTarget => {
let value = self.get_target_value(system, target, Size::Long)?;
let value = self.get_target_value(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(system, target, value, Size::Long)?;
self.set_target_value(target, value, Size::Long)?;
},
}
},
Instruction::MOVEM(target, size, dir, mask) => {
self.execute_movem(system, target, size, dir, mask)?;
self.execute_movem(target, size, dir, mask)?;
},
//Instruction::MOVEP(reg, target, size, dir) => {
//},
@ -517,12 +517,12 @@ impl M68k {
Instruction::MOVEUSP(target, dir) => {
self.require_supervisor()?;
match dir {
Direction::ToTarget => self.set_target_value(system, target, self.state.usp, Size::Long)?,
Direction::FromTarget => { self.state.usp = self.get_target_value(system, target, Size::Long)?; },
Direction::ToTarget => self.set_target_value(target, self.state.usp, Size::Long)?,
Direction::FromTarget => { self.state.usp = self.get_target_value(target, Size::Long)?; },
}
},
Instruction::MULW(src, dest, sign) => {
let value = self.get_target_value(system, src, Size::Word)?;
let value = self.get_target_value(src, Size::Word)?;
let existing = get_value_sized(self.state.d_reg[dest as usize], Size::Word);
let result = match sign {
Sign::Signed => ((((existing as u16) as i16) as i64) * (((value as u16) as i16) as i64)) as u64,
@ -533,7 +533,7 @@ impl M68k {
self.state.d_reg[dest as usize] = result as u32;
},
Instruction::MULL(src, dest_h, dest_l, sign) => {
let value = self.get_target_value(system, src, Size::Long)?;
let value = self.get_target_value(src, Size::Long)?;
let existing = get_value_sized(self.state.d_reg[dest_l as usize], Size::Long);
let result = match sign {
Sign::Signed => (((existing as i32) as i64) * ((value as i32) as i64)) as u64,
@ -549,10 +549,10 @@ impl M68k {
//Instruction::NBCD(Target) => {
//},
Instruction::NEG(target, size) => {
let original = self.get_target_value(system, target, size)?;
let original = self.get_target_value(target, size)?;
let (result, overflow) = overflowing_sub_signed_sized(0, original, size);
let carry = result != 0;
self.set_target_value(system, target, result, size)?;
self.set_target_value(target, result, size)?;
self.set_compare_flags(result, size, carry, overflow);
self.set_flag(Flags::Extend, carry);
},
@ -560,16 +560,16 @@ impl M68k {
//},
Instruction::NOP => { },
Instruction::NOT(target, size) => {
let mut value = self.get_target_value(system, target, size)?;
let mut value = self.get_target_value(target, size)?;
value = get_value_sized(!value, size);
self.set_target_value(system, target, value, size)?;
self.set_target_value(target, value, size)?;
self.set_logic_flags(value, size);
},
Instruction::OR(src, dest, size) => {
let value = self.get_target_value(system, src, size)?;
let existing = self.get_target_value(system, dest, size)?;
let value = self.get_target_value(src, size)?;
let existing = self.get_target_value(dest, size)?;
let result = get_value_sized(existing | value, size);
self.set_target_value(system, dest, result, size)?;
self.set_target_value(dest, result, size)?;
self.set_logic_flags(result, size);
},
Instruction::ORtoCCR(value) => {
@ -580,15 +580,15 @@ impl M68k {
self.state.sr = self.state.sr | value;
},
Instruction::PEA(target) => {
let value = self.get_target_address(system, target)?;
self.push_long(system, value)?;
let value = self.get_target_address(target)?;
self.push_long(value)?;
},
//Instruction::RESET => {
// self.require_supervisor()?;
//},
Instruction::ROd(count, target, size, shift_dir) => {
let count = self.get_target_value(system, count, size)? % 64;
let mut pair = (self.get_target_value(system, target, size)?, false);
let count = self.get_target_value(count, size)? % 64;
let mut pair = (self.get_target_value(target, size)?, false);
for _ in 0..count {
pair = rotate_operation(pair.0, size, shift_dir, None);
}
@ -596,11 +596,11 @@ impl M68k {
if pair.1 {
self.set_flag(Flags::Carry, true);
}
self.set_target_value(system, target, pair.0, size)?;
self.set_target_value(target, pair.0, size)?;
},
Instruction::ROXd(count, target, size, shift_dir) => {
let count = self.get_target_value(system, count, size)? % 64;
let mut pair = (self.get_target_value(system, target, size)?, false);
let count = self.get_target_value(count, size)? % 64;
let mut pair = (self.get_target_value(target, size)?, false);
for _ in 0..count {
pair = rotate_operation(pair.0, size, shift_dir, Some(self.get_flag(Flags::Extend)));
self.set_flag(Flags::Extend, pair.1);
@ -609,30 +609,30 @@ impl M68k {
if pair.1 {
self.set_flag(Flags::Carry, true);
}
self.set_target_value(system, target, pair.0, size)?;
self.set_target_value(target, pair.0, size)?;
},
Instruction::RTE => {
self.require_supervisor()?;
self.state.sr = self.pop_word(system)?;
self.state.pc = self.pop_long(system)?;
self.state.sr = self.pop_word()?;
self.state.pc = self.pop_long()?;
if self.cputype >= M68kType::MC68010 {
let _ = self.pop_word(system)?;
let _ = self.pop_word()?;
}
},
//Instruction::RTR => {
//},
Instruction::RTS => {
self.debugger.stack_tracer.pop_return();
self.state.pc = self.pop_long(system)?;
self.state.pc = self.pop_long()?;
},
//Instruction::RTD(i16) => {
//},
Instruction::Scc(cond, target) => {
let condition_true = self.get_current_condition(cond);
if condition_true {
self.set_target_value(system, target, 0xFF, Size::Byte)?;
self.set_target_value(target, 0xFF, Size::Byte)?;
} else {
self.set_target_value(system, target, 0x00, Size::Byte)?;
self.set_target_value(target, 0x00, Size::Byte)?;
}
},
Instruction::STOP(flags) => {
@ -643,16 +643,16 @@ impl M68k {
//Instruction::SBCD(Target) => {
//},
Instruction::SUB(src, dest, size) => {
let value = self.get_target_value(system, src, size)?;
let existing = self.get_target_value(system, dest, size)?;
let value = self.get_target_value(src, size)?;
let existing = self.get_target_value(dest, size)?;
let (result, carry) = overflowing_sub_sized(existing, value, size);
let overflow = get_sub_overflow(existing, value, result, size);
self.set_compare_flags(result, size, carry, overflow);
self.set_flag(Flags::Extend, carry);
self.set_target_value(system, dest, result, size)?;
self.set_target_value(dest, result, size)?;
},
Instruction::SUBA(src, dest, size) => {
let value = sign_extend_to_long(self.get_target_value(system, src, size)?, size) as u32;
let value = sign_extend_to_long(self.get_target_value(src, size)?, size) as u32;
let existing = *self.get_a_reg_mut(dest);
let (result, _) = overflowing_sub_sized(existing, value, Size::Long);
*self.get_a_reg_mut(dest) = result;
@ -666,21 +666,21 @@ impl M68k {
//Instruction::TAS(Target) => {
//},
Instruction::TST(target, size) => {
let value = self.get_target_value(system, target, size)?;
let value = self.get_target_value(target, size)?;
self.set_logic_flags(value, size);
},
Instruction::TRAP(number) => {
self.exception(system, 32 + number, false)?;
self.exception(32 + number, false)?;
},
Instruction::TRAPV => {
if self.get_flag(Flags::Overflow) {
self.exception(system, Exceptions::TrapvInstruction as u8, false)?;
self.exception(Exceptions::TrapvInstruction as u8, false)?;
}
},
Instruction::UNLK(reg) => {
let value = *self.get_a_reg_mut(reg);
*self.get_stack_pointer_mut() = value;
let new_value = self.pop_long(system)?;
let new_value = self.pop_long()?;
let addr = self.get_a_reg_mut(reg);
*addr = new_value;
},
@ -691,8 +691,8 @@ impl M68k {
Ok(())
}
fn execute_movem(&mut self, system: &System, target: Target, size: Size, dir: Direction, mut mask: u16) -> Result<(), Error> {
let mut addr = self.get_target_address(system, target)?;
fn execute_movem(&mut self, target: Target, size: Size, dir: Direction, mut mask: u16) -> Result<(), Error> {
let mut addr = self.get_target_address(target)?;
// If we're using a MC68020 or higher, and it was Post-Inc/Pre-Dec target, then update the value before it's stored
if self.cputype >= M68kType::MC68020 {
@ -751,33 +751,33 @@ impl M68k {
Ok(())
}
fn push_word(&mut self, system: &System, value: u16) -> Result<(), Error> {
fn push_word(&mut self, value: u16) -> Result<(), Error> {
*self.get_stack_pointer_mut() -= 2;
let addr = *self.get_stack_pointer_mut();
self.port.write_beu16(addr as Address, value)
}
fn pop_word(&mut self, system: &System) -> Result<u16, Error> {
fn pop_word(&mut self) -> Result<u16, Error> {
let addr = *self.get_stack_pointer_mut();
let value = self.port.read_beu16(addr as Address)?;
*self.get_stack_pointer_mut() += 2;
Ok(value)
}
fn push_long(&mut self, system: &System, value: u32) -> Result<(), Error> {
fn push_long(&mut self, value: u32) -> Result<(), Error> {
*self.get_stack_pointer_mut() -= 4;
let addr = *self.get_stack_pointer_mut();
self.port.write_beu32(addr as Address, value)
}
fn pop_long(&mut self, system: &System) -> Result<u32, Error> {
fn pop_long(&mut self) -> Result<u32, Error> {
let addr = *self.get_stack_pointer_mut();
let value = self.port.read_beu32(addr as Address)?;
*self.get_stack_pointer_mut() += 4;
Ok(value)
}
pub fn get_target_value(&mut self, system: &System, target: Target, size: Size) -> Result<u32, Error> {
pub fn get_target_value(&mut self, target: Target, size: Size) -> Result<u32, Error> {
match target {
Target::Immediate(value) => Ok(value),
Target::DirectDReg(reg) => Ok(get_value_sized(self.state.d_reg[reg as usize], size)),
@ -820,7 +820,7 @@ impl M68k {
}
}
pub fn set_target_value(&mut self, system: &System, target: Target, value: u32, size: Size) -> Result<(), Error> {
pub fn set_target_value(&mut self, target: Target, value: u32, size: Size) -> Result<(), Error> {
match target {
Target::DirectDReg(reg) => {
set_value_sized(&mut self.state.d_reg[reg as usize], value, size);
@ -869,7 +869,7 @@ impl M68k {
Ok(())
}
pub fn get_target_address(&mut self, system: &System, target: Target) -> Result<u32, Error> {
pub fn get_target_address(&mut self, target: Target) -> Result<u32, Error> {
let addr = match target {
Target::IndirectAReg(reg) | Target::IndirectARegInc(reg) | Target::IndirectARegDec(reg) => *self.get_a_reg_mut(reg),
Target::IndirectRegOffset(base_reg, index_reg, displacement) => {
@ -1187,10 +1187,6 @@ fn get_sub_overflow(operand1: u32, operand2: u32, result: u32, size: Size) -> bo
(msb1 && msb2 && !msb_res) || (!msb1 && !msb2 && msb_res)
}
fn get_twos_complement(value: u32, size: Size) -> u32 {
get_value_sized(!value + 1, size)
}
#[inline(always)]
fn get_msb(value: u32, size: Size) -> bool {
match size {

View File

@ -148,7 +148,7 @@ impl M68k {
self.debugger = M68kDebugger::new();
}
pub fn dump_state(&mut self, system: &System) {
pub fn dump_state(&mut self, _system: &System) {
println!("Status: {:?}", self.state.status);
println!("PC: {:#010x}", self.state.pc);
println!("SR: {:#06x}", self.state.sr);

View File

@ -70,7 +70,7 @@ mod decode_tests {
BusPort::new(0, 24, 16, system.bus.clone())
};
let mut cpu = M68k::new(cputype, 10_000_000, port);
cpu.init(&system).unwrap();
cpu.init().unwrap();
assert_eq!(cpu.state.pc, INIT_ADDR as u32);
assert_eq!(cpu.state.msp, INIT_STACK as u32);
@ -93,11 +93,11 @@ mod decode_tests {
load_memory(&system, case.data);
match &case.ins {
Some(ins) => {
cpu.decode_next(&system).unwrap();
cpu.decode_next().unwrap();
assert_eq!(cpu.decoder.instruction, ins.clone());
},
None => {
assert_eq!(cpu.decode_next(&system).is_err(), true);
assert_eq!(cpu.decode_next().is_err(), true);
},
}
}
@ -119,7 +119,6 @@ mod decode_tests {
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
let size = Size::Word;
let expected = 0x1234;
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b000, 0b001, Some(size)).unwrap();
assert_eq!(target, Target::DirectDReg(1));
@ -130,7 +129,6 @@ mod decode_tests {
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
let size = Size::Word;
let expected = 0x1234;
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b001, 0b010, Some(size)).unwrap();
assert_eq!(target, Target::DirectAReg(2));
@ -141,7 +139,6 @@ mod decode_tests {
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
let size = Size::Long;
let expected_addr = INIT_ADDR;
let expected = 0x12345678;
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
@ -155,7 +152,6 @@ mod decode_tests {
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
let size = Size::Long;
let expected_addr = INIT_ADDR;
let expected = 0x12345678;
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
@ -169,7 +165,6 @@ mod decode_tests {
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
let size = Size::Long;
let expected_addr = INIT_ADDR + 4;
let expected = 0x12345678;
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
@ -433,15 +428,15 @@ mod execute_tests {
let (mut cpu, system) = init_execute_test(case.cputype);
let init_state = build_state(&case.init);
let mut expected_state = build_state(&case.fini);
let expected_state = build_state(&case.fini);
load_memory(&system, case.data);
cpu.state = init_state;
cpu.decode_next(&system).unwrap();
cpu.decode_next().unwrap();
assert_eq!(cpu.decoder.instruction, case.ins);
cpu.execute_current(&system).unwrap();
cpu.execute_current().unwrap();
assert_eq!(cpu.state, expected_state);
}
@ -709,73 +704,70 @@ mod execute_tests {
#[test]
fn target_value_direct_d() {
let (mut cpu, system) = init_execute_test(M68kType::MC68010);
let (mut cpu, _) = init_execute_test(M68kType::MC68010);
let size = Size::Word;
let expected = 0x1234;
let target = Target::DirectDReg(1);
cpu.state.d_reg[1] = expected;
let result = cpu.get_target_value(&system, target, size).unwrap();
let result = cpu.get_target_value(target, size).unwrap();
assert_eq!(result, expected);
}
#[test]
fn target_value_direct_a() {
let (mut cpu, system) = init_execute_test(M68kType::MC68010);
let (mut cpu, _) = init_execute_test(M68kType::MC68010);
let size = Size::Word;
let expected = 0x1234;
let target = Target::DirectAReg(2);
cpu.state.a_reg[2] = expected;
let result = cpu.get_target_value(&system, target, size).unwrap();
let result = cpu.get_target_value(target, size).unwrap();
assert_eq!(result, expected);
}
#[test]
fn target_value_indirect_a() {
let (mut cpu, system) = init_execute_test(M68kType::MC68010);
let (mut cpu, _) = init_execute_test(M68kType::MC68010);
let size = Size::Long;
let expected_addr = INIT_ADDR;
let expected = 0x12345678;
let target = Target::IndirectAReg(2);
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
cpu.port.write_beu32(INIT_ADDR, expected).unwrap();
cpu.state.a_reg[2] = INIT_ADDR as u32;
let result = cpu.get_target_value(&system, target, size).unwrap();
let result = cpu.get_target_value(target, size).unwrap();
assert_eq!(result, expected);
}
#[test]
fn target_value_indirect_a_inc() {
let (mut cpu, system) = init_execute_test(M68kType::MC68010);
let (mut cpu, _) = init_execute_test(M68kType::MC68010);
let size = Size::Long;
let expected_addr = INIT_ADDR;
let expected = 0x12345678;
let target = Target::IndirectARegInc(2);
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
cpu.port.write_beu32(INIT_ADDR, expected).unwrap();
cpu.state.a_reg[2] = INIT_ADDR as u32;
let result = cpu.get_target_value(&system, target, size).unwrap();
let result = cpu.get_target_value(target, size).unwrap();
assert_eq!(result, expected);
assert_eq!(cpu.state.a_reg[2], (INIT_ADDR as u32) + 4);
}
#[test]
fn target_value_indirect_a_dec() {
let (mut cpu, system) = init_execute_test(M68kType::MC68010);
let (mut cpu, _) = init_execute_test(M68kType::MC68010);
let size = Size::Long;
let expected_addr = INIT_ADDR + 4;
let expected = 0x12345678;
let target = Target::IndirectARegDec(2);
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
cpu.port.write_beu32(INIT_ADDR, expected).unwrap();
cpu.state.a_reg[2] = (INIT_ADDR as u32) + 4;
let result = cpu.get_target_value(&system, target, size).unwrap();
let result = cpu.get_target_value(target, size).unwrap();
assert_eq!(result, expected);
assert_eq!(cpu.state.a_reg[2], INIT_ADDR as u32);
}
@ -783,14 +775,14 @@ mod execute_tests {
#[test]
fn target_value_immediate() {
let (mut cpu, system) = init_execute_test(M68kType::MC68010);
let (mut cpu, _) = init_execute_test(M68kType::MC68010);
let size = Size::Word;
let expected = 0x1234;
let target = Target::Immediate(expected);
let result = cpu.get_target_value(&system, target, size).unwrap();
let result = cpu.get_target_value(target, size).unwrap();
assert_eq!(result, expected);
}
}

View File

@ -30,10 +30,10 @@ impl Debuggable for Z80 {
}
}
fn print_current_step(&mut self, system: &System) -> Result<(), Error> {
fn print_current_step(&mut self, _system: &System) -> Result<(), Error> {
self.decoder.decode_at(&mut self.port, self.state.pc)?;
self.decoder.dump_decoded(&mut self.port);
self.dump_state(system);
self.dump_state();
Ok(())
}
@ -42,7 +42,7 @@ impl Debuggable for Z80 {
decoder.dump_disassembly(&mut self.port, addr as u16, count as u16);
}
fn execute_command(&mut self, system: &System, args: &[&str]) -> Result<bool, Error> {
fn execute_command(&mut self, _system: &System, args: &[&str]) -> Result<bool, Error> {
match args[0] {
"l" => {
use super::state::Register;

View File

@ -2,7 +2,7 @@
use crate::error::Error;
use crate::devices::{Address, Addressable};
use super::state::{Z80, Z80Type, Register};
use super::state::Register;
#[derive(Copy, Clone, Debug, PartialEq)]

View File

@ -3,14 +3,12 @@ use crate::system::System;
use crate::error::{ErrorType, Error};
use crate::devices::{ClockElapsed, Address, Steppable, Addressable, Interruptable, Debuggable, Transmutable, read_beu16, write_beu16};
use super::decode::{Condition, Instruction, LoadTarget, Target, RegisterPair, IndexRegister, IndexRegisterHalf, Size, Direction, UndocumentedCopy};
use super::decode::{Condition, Instruction, LoadTarget, Target, RegisterPair, IndexRegister, IndexRegisterHalf, Size};
use super::state::{Z80, Status, Flags, Register};
const DEV_NAME: &'static str = "z80-cpu";
const FLAGS_ALL: u8 = 0xFF;
const FLAGS_ALL_BUT_CARRY: u8 = 0xFE;
const FLAGS_NUMERIC: u8 = 0xC0;
const FLAGS_ARITHMETIC: u8 = 0x17;
const FLAGS_CARRY_HALF_CARRY: u8 = 0x11;
@ -28,8 +26,8 @@ impl Steppable for Z80 {
Ok((1_000_000_000 / self.frequency as u64) * 4)
}
fn on_error(&mut self, system: &System) {
self.dump_state(system);
fn on_error(&mut self, _system: &System) {
self.dump_state();
}
}
@ -55,13 +53,13 @@ impl Transmutable for Z80 {
impl Z80 {
pub fn step_internal(&mut self, system: &System) -> Result<(), Error> {
match self.state.status {
Status::Init => self.init(system),
Status::Init => self.init(),
Status::Halted => Err(Error::new("CPU stopped")),
Status::Running => {
match self.cycle_one(system) {
Ok(()) => Ok(()),
//Err(Error { err: ErrorType::Processor, native, .. }) => {
Err(Error { err: ErrorType::Processor, native, .. }) => {
Err(Error { err: ErrorType::Processor, .. }) => {
//self.exception(system, native as u8, false)?;
Ok(())
},
@ -71,17 +69,16 @@ impl Z80 {
}
}
pub fn init(&mut self, system: &System) -> Result<(), Error> {
//self.state.msp = self.port.read_beu32(0)?;
//self.state.pc = self.port.read_beu32(4)?;
pub fn init(&mut self) -> Result<(), Error> {
self.state.pc = 0;
self.state.status = Status::Running;
Ok(())
}
pub fn cycle_one(&mut self, system: &System) -> Result<(), Error> {
//self.timer.cycle.start();
self.decode_next(system)?;
self.execute_current(system)?;
self.decode_next()?;
self.execute_current()?;
//self.timer.cycle.end();
//if (self.timer.cycle.events % 500) == 0 {
@ -93,21 +90,21 @@ impl Z80 {
Ok(())
}
pub fn decode_next(&mut self, system: &System) -> Result<(), Error> {
pub fn decode_next(&mut self) -> Result<(), Error> {
//self.timer.decode.start();
self.decoder.decode_at(&mut self.port, self.state.pc)?;
//self.timer.decode.end();
//if self.debugger.use_tracing {
//self.decoder.dump_decoded(&mut self.port);
//self.dump_state(system);
//self.dump_state();
//}
self.state.pc = self.decoder.end;
Ok(())
}
pub fn execute_current(&mut self, system: &System) -> Result<(), Error> {
pub fn execute_current(&mut self) -> Result<(), Error> {
match self.decoder.instruction {
Instruction::ADCa(target) => {
let src = self.get_target_value(target)?;
@ -204,14 +201,14 @@ impl Z80 {
Instruction::DEC16(regpair) => {
let value = self.get_register_pair_value(regpair);
let (result, carry, overflow) = sub_words(value, 1);
let (result, _, _) = sub_words(value, 1);
self.set_register_pair_value(regpair, result);
},
Instruction::DEC8(target) => {
let value = self.get_target_value(target)?;
let (result, carry, overflow) = sub_bytes(value, 1);
let (result, _, overflow) = sub_bytes(value, 1);
let carry = self.get_flag(Flags::Carry); // Preserve the carry bit, according to Z80 reference
self.set_arithmetic_op_flags(result as u16, Size::Byte, true, carry, overflow, (result & 0x10) != 0);
@ -620,7 +617,7 @@ impl Z80 {
}
fn pop_word(&mut self) -> Result<u16, Error> {
let mut value = 0;
let mut value;
value = self.port.read_u8(self.state.sp as Address)? as u16;
self.state.sp = self.state.sp.wrapping_add(1);
value |= (self.port.read_u8(self.state.sp as Address)? as u16) << 8;

View File

@ -1,5 +1,4 @@
use crate::system::System;
use crate::devices::Address;
use crate::memory::BusPort;
@ -122,7 +121,7 @@ impl Z80 {
self.debugger = Z80Debugger::new();
}
pub fn dump_state(&mut self, system: &System) {
pub fn dump_state(&mut self) {
println!("Status: {:?}", self.state.status);
println!("PC: {:#06x}", self.state.pc);
println!("SP: {:#06x}", self.state.sp);

View File

@ -19,7 +19,7 @@ mod decode_tests {
// Initialize the CPU and make sure it's in the expected state
let mut cpu = Z80::new(Z80Type::Z80, 4_000_000, BusPort::new(0, 16, 8, system.bus.clone()));
cpu.init(&system).unwrap();
cpu.init().unwrap();
(cpu, system)
}
@ -33,7 +33,7 @@ mod decode_tests {
fn run_decode_test(data: &[u8]) -> Instruction {
let (mut cpu, system) = init_decode_test();
load_memory(&system, data);
cpu.decode_next(&system).unwrap();
cpu.decode_next().unwrap();
cpu.decoder.instruction
}
@ -84,7 +84,7 @@ mod execute_tests {
use super::super::{Z80, Z80Type};
use super::super::state::{Z80State, Register};
use super::super::decode::{Instruction, LoadTarget, Target, RegisterPair, IndexRegister, IndexRegisterHalf, Condition};
use super::super::decode::{Instruction, LoadTarget, Target, RegisterPair, Condition};
struct TestState {
pc: u16,
@ -571,7 +571,7 @@ mod execute_tests {
// Initialize the CPU and make sure it's in the expected state
let mut cpu = Z80::new(Z80Type::Z80, 4_000_000, BusPort::new(0, 16, 8, system.bus.clone()));
cpu.init(&system).unwrap();
cpu.init().unwrap();
(cpu, system)
}
@ -608,10 +608,10 @@ mod execute_tests {
load_memory(&system, case.data);
cpu.state = init_state;
cpu.decode_next(&system).unwrap();
cpu.decode_next().unwrap();
assert_eq!(cpu.decoder.instruction, case.ins);
cpu.execute_current(&system).unwrap();
cpu.execute_current().unwrap();
// TODO this is a hack to ignore the functioning of the F5, F3 flags for now
cpu.state.reg[Register::F as usize] &= 0xD7;

View File

@ -67,7 +67,7 @@ impl Debugger {
loop {
let mut buffer = String::new();
std::io::stdout().write_all(b"> ");
std::io::stdout().write_all(b"> ").unwrap();
std::io::stdin().read_line(&mut buffer).unwrap();
let args: Vec<&str> = buffer.split_whitespace().collect();
match self.run_debugger_command(system, debug_obj, &args) {

View File

@ -6,8 +6,6 @@ use crate::error::Error;
use crate::system::System;
pub const MAX_READ: usize = 4;
/// The time in nanoseconds that have elapsed since the start of the simulation
pub type Clock = u64;

View File

@ -65,7 +65,7 @@ impl WindowUpdater for FrameSwapper {
(self.current.width, self.current.height)
}
fn update_frame(&mut self, width: u32, height: u32, bitmap: &mut [u32]) {
fn update_frame(&mut self, width: u32, _height: u32, bitmap: &mut [u32]) {
std::mem::swap(&mut self.current, &mut self.previous);
for y in 0..self.current.height {
@ -84,7 +84,9 @@ impl WindowUpdater for FrameSwapperWrapper {
}
fn update_frame(&mut self, width: u32, height: u32, bitmap: &mut [u32]) {
self.0.lock().map(|mut swapper| swapper.update_frame(width, height, bitmap));
if let Ok(mut swapper) = self.0.lock() {
swapper.update_frame(width, height, bitmap);
}
}
}

View File

@ -1,6 +1,4 @@
use std::sync::{Arc, Mutex};
use crate::error::Error;
use crate::host::keys::Key;
@ -15,8 +13,8 @@ pub enum JoystickDevice {
pub trait Host {
//fn create_pty(&self) -> Result<Box<dyn Tty>, Error>;
fn add_window(&mut self, updater: Box<dyn WindowUpdater>) -> Result<(), Error>;
fn register_joystick(&mut self, device: JoystickDevice, input: Box<dyn JoystickUpdater>) -> Result<(), Error> { Err(Error::new("Not supported")) }
fn register_keyboard(&mut self, input: Box<dyn KeyboardUpdater>) -> Result<(), Error> { Err(Error::new("Not supported")) }
fn register_joystick(&mut self, _device: JoystickDevice, _input: Box<dyn JoystickUpdater>) -> Result<(), Error> { Err(Error::new("Not supported")) }
fn register_keyboard(&mut self, _input: Box<dyn KeyboardUpdater>) -> Result<(), Error> { Err(Error::new("Not supported")) }
}
pub trait Tty {

View File

@ -3,7 +3,6 @@ use std::thread;
use std::sync::mpsc;
use std::time::Duration;
use std::io::{Read, Write};
use std::sync::{Arc, Mutex};
use std::os::unix::io::AsRawFd;
use nix::fcntl::OFlag;
@ -55,7 +54,7 @@ impl SimplePty {
loop {
match pty.read(&mut buf) {
Ok(_) => {
input_tx.send(buf[0]);
input_tx.send(buf[0]).unwrap();
},
Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => { },
Err(err) => { println!("ERROR: {:?}", err); }
@ -84,7 +83,7 @@ impl Tty for SimplePty {
}
fn write(&mut self, output: u8) -> bool {
self.output.send(output);
self.output.send(output).unwrap();
true
}
}

View File

@ -1,6 +1,4 @@
use std::iter;
use crate::error::Error;
use crate::devices::TransmutableBox;

View File

@ -1,13 +1,17 @@
use std::rc::Rc;
use std::cell::RefCell;
use crate::error::Error;
use crate::system::System;
use crate::memory::{MemoryBlock, BusPort};
use crate::memory::{MemoryBlock, Bus, BusPort};
use crate::devices::{wrap_transmutable, Debuggable};
use crate::cpus::m68k::{M68k, M68kType};
use crate::cpus::z80::{Z80, Z80Type};
use crate::peripherals::genesis;
use crate::host::traits::{Host, WindowUpdater};
use crate::host::traits::{Host};
pub fn build_genesis<H: Host>(host: &mut H) -> Result<System, Error> {
@ -28,12 +32,17 @@ pub fn build_genesis<H: Host>(host: &mut H) -> Result<System, Error> {
system.add_addressable_device(0x00000000, wrap_transmutable(rom)).unwrap();
let ram = MemoryBlock::new(vec![0; 0x00010000]);
system.add_addressable_device(0x00FF0000, wrap_transmutable(ram)).unwrap();
system.add_addressable_device(0x00ff0000, wrap_transmutable(ram)).unwrap();
let coproc_bus = Rc::new(RefCell::new(Bus::new()));
let coproc_shared_mem = wrap_transmutable(MemoryBlock::new(vec![0; 0x00010000]));
coproc_bus.borrow_mut().insert(0x0000, coproc_shared_mem.borrow_mut().as_addressable().unwrap().len(), coproc_shared_mem.clone());
let mut coproc = Z80::new(Z80Type::Z80, 3_579_545, BusPort::new(0, 16, 8, coproc_bus.clone()));
system.add_addressable_device(0x00a00000, coproc_shared_mem)?;
//system.add_device("coproc", wrap_transmutable(coproc))?;
let coproc_shared_mem = MemoryBlock::new(vec![0; 0x00010000]);
system.add_addressable_device(0x00A00000, wrap_transmutable(coproc_shared_mem)).unwrap();
let controllers = genesis::controllers::GenesisController::create(host)?;

View File

@ -4,7 +4,7 @@ use std::rc::Rc;
use std::cell::RefCell;
use crate::error::Error;
use crate::devices::{Address, Addressable, Transmutable, TransmutableBox, MAX_READ};
use crate::devices::{Address, Addressable, Transmutable, TransmutableBox};
pub struct MemoryBlock {
@ -75,6 +75,41 @@ impl Transmutable for MemoryBlock {
}
pub struct MemoryAdapter {
pub subdevice: TransmutableBox,
pub shift: u8,
}
impl MemoryAdapter {
pub fn new(subdevice: TransmutableBox, shift: u8) -> Self {
Self {
subdevice,
shift,
}
}
}
impl Addressable for MemoryAdapter {
fn len(&self) -> usize {
let len = self.subdevice.borrow_mut().as_addressable().unwrap().len();
len << self.shift
}
fn read(&mut self, addr: Address, data: &mut [u8]) -> Result<(), Error> {
self.subdevice.borrow_mut().as_addressable().unwrap().read(addr >> self.shift, data)
}
fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> {
self.subdevice.borrow_mut().as_addressable().unwrap().write(addr >> self.shift, data)
}
}
impl Transmutable for MemoryAdapter {
fn as_addressable(&mut self) -> Option<&mut dyn Addressable> {
Some(self)
}
}
pub struct Block {
pub base: Address,

View File

@ -2,7 +2,7 @@
use std::fs;
use crate::error::Error;
use crate::devices::{Address, Addressable, Transmutable, MAX_READ};
use crate::devices::{Address, Addressable, Transmutable};
const ATA_REG_DATA_WORD: Address = 0x20;

View File

@ -1,9 +1,7 @@
use std::sync::{Arc, Mutex};
use crate::error::Error;
use crate::signals::{Signal, SyncSignal};
use crate::devices::{Address, Addressable, Transmutable, MAX_READ};
use crate::signals::SyncSignal;
use crate::devices::{Address, Addressable, Transmutable};
use crate::host::traits::{Host, JoystickDevice, JoystickUpdater};

View File

@ -1,6 +1,6 @@
use crate::error::Error;
use crate::devices::{Address, Addressable, Transmutable, MAX_READ};
use crate::devices::{Address, Addressable, Transmutable};
const DEV_NAME: &'static str = "coprocessor";

View File

@ -5,7 +5,7 @@ use std::sync::{Arc, Mutex};
use crate::error::Error;
use crate::system::System;
use crate::signals::SyncSignal;
use crate::devices::{Clock, ClockElapsed, Address, Addressable, Steppable, Transmutable, MAX_READ, read_beu16, read_beu32, write_beu16};
use crate::devices::{Clock, ClockElapsed, Address, Addressable, Steppable, Transmutable, read_beu16, read_beu32, write_beu16};
use crate::host::traits::{Host, BlitableSurface};
use crate::host::gfx::{Frame, FrameSwapper};
@ -251,17 +251,20 @@ impl Ym7101State {
}
pub fn draw_frame(&mut self, frame: &mut Frame) {
let bg_colour = self.get_palette_colour((self.regs[REG_BACKGROUND] & 0x30) >> 4, self.regs[REG_BACKGROUND] & 0x0f);
for i in 0..(frame.width as usize * frame.height as usize) {
frame.bitmap[i] = bg_colour;
}
self.draw_background(frame);
self.draw_cell_table(frame, self.get_vram_scroll_b_addr());
self.draw_cell_table(frame, self.get_vram_scroll_a_addr());
//self.draw_window(frame);
self.draw_sprites(frame);
}
pub fn draw_background(&mut self, frame: &mut Frame) {
let bg_colour = self.get_palette_colour((self.regs[REG_BACKGROUND] & 0x30) >> 4, self.regs[REG_BACKGROUND] & 0x0f);
for i in 0..(frame.width as usize * frame.height as usize) {
frame.bitmap[i] = bg_colour;
}
}
pub fn draw_cell_table(&mut self, frame: &mut Frame, cell_table: u32) {
let (scroll_h, scroll_v) = self.get_scroll_size();
let (cells_h, cells_v) = self.get_screen_size();
@ -411,14 +414,10 @@ pub struct Ym7101 {
}
impl Ym7101 {
pub fn new<H: Host>(host: &H, external_interrupt: SyncSignal<bool>) -> Ym7101 {
let swapper = FrameSwapper::new_shared();
swapper.lock().map(|mut swapper| {
swapper.current.set_size(320, 224);
swapper.previous.set_size(320, 224);
});
pub fn new<H: Host>(host: &mut H, external_interrupt: SyncSignal<bool>) -> Ym7101 {
let swapper = FrameSwapper::new_shared(320, 224);
host.add_window(FrameSwapper::to_boxed(swapper.clone()));
host.add_window(FrameSwapper::to_boxed(swapper.clone())).unwrap();
Ym7101 {
swapper,
@ -490,16 +489,48 @@ impl Steppable for Ym7101 {
/*
// Print Pattern Table
let mut swapper = self.swapper.lock().unwrap();
let coords = self.state.get_window_coords();
for cell_y in coords.0.1..coords.1.1 {
for cell_x in coords.0.0..coords.1.0 {
let pattern_addr = (cell_x + (cell_y * 40)) * 32;
let iter = PatternIterator::new(&self.state, pattern_addr as u32, 0);
let (cells_h, cells_v) = self.state.get_screen_size();
for cell_y in 0..cells_v {
for cell_x in 0..cells_h {
let pattern_addr = (cell_x + (cell_y * cells_h)) * 32;
let iter = PatternIterator::new(&self.state, pattern_addr as u32, 0, false, false);
swapper.current.blit((cell_x << 3) as u32, (cell_y << 3) as u32, iter, 8, 8);
}
}
*/
/*
// Print Sprite
let mut swapper = self.swapper.lock().unwrap();
self.state.draw_background(&mut swapper.current);
let sprite_table = (self.state.regs[REG_SPRITES_ADDR] as usize) << 9;
let (cells_h, cells_v) = self.state.get_screen_size();
let sprite = 0;
println!("{:?}", &self.state.vram[(sprite_table + (sprite * 8))..(sprite_table + (sprite * 8) + 8)].iter().map(|byte| format!("{:02x}", byte)).collect::<Vec<String>>());
let size = self.state.vram[sprite_table + (sprite * 8) + 2];
let (size_h, size_v) = (((size >> 2) & 0x03) as u16 + 1, (size & 0x03) as u16 + 1);
let pattern_name = ((self.state.vram[sprite_table + (sprite * 8) + 4] as u16) << 8) | (self.state.vram[sprite_table + (sprite * 8) + 5] as u16);
let pattern_gen = pattern_name & 0x7FF;
println!("{:x}", pattern_name);
for cell_y in 0..size_v {
for cell_x in 0..size_h {
let pattern_addr = (pattern_gen + (cell_y * size_h) + cell_x) as u32;
println!("pattern: ({}, {}) {:x}", cell_x, cell_y, pattern_addr);
let iter = PatternIterator::new(&self.state, pattern_addr * 32, 3, true, true);
swapper.current.blit((cell_x << 3) as u32, (cell_y << 3) as u32, iter, 8, 8);
}
}
*/
//let mut swapper = self.swapper.lock().unwrap();
//swapper.current.blit(0, 0, PatternIterator::new(&self.state, 0x408 * 32, 3, false, false), 8, 8);
//swapper.current.blit(0, 8, PatternIterator::new(&self.state, 0x409 * 32, 3, false, false), 8, 8);
//swapper.current.blit(8, 0, PatternIterator::new(&self.state, 0x402 * 32, 3, false, false), 8, 8);
//swapper.current.blit(8, 8, PatternIterator::new(&self.state, 0x403 * 32, 3, false, false), 8, 8);
//swapper.current.blit(16, 0, PatternIterator::new(&self.state, 0x404 * 32, 3, false, false), 8, 8);
//swapper.current.blit(16, 8, PatternIterator::new(&self.state, 0x405 * 32, 3, false, false), 8, 8);
}
if self.state.transfer_run != DmaType::None {
@ -525,7 +556,7 @@ impl Steppable for Ym7101 {
{
let addr = self.state.transfer_addr;
let mut target = self.state.get_transfer_target_mut();
let target = self.state.get_transfer_target_mut();
target[addr as usize] = data[0];
target[addr as usize + 1] = data[1];
}

View File

@ -1,7 +1,7 @@
use crate::error::Error;
use crate::system::System;
use crate::devices::{ClockElapsed, Address, Steppable, Addressable, Transmutable, MAX_READ};
use crate::devices::{ClockElapsed, Address, Steppable, Addressable, Transmutable};
use crate::host::traits::Tty;

View File

@ -1,5 +1,4 @@
use std::slice::Iter;
use std::sync::{Arc, Mutex};
use crate::error::Error;
@ -7,7 +6,7 @@ use crate::system::System;
use crate::devices::{ClockElapsed, Address, Addressable, Steppable, Transmutable};
use crate::host::keys::Key;
use crate::host::gfx::{Frame, FrameSwapper};
use crate::host::gfx::{FrameSwapper};
use crate::host::traits::{Host, BlitableSurface, KeyboardUpdater};
use super::keymap;
@ -48,7 +47,7 @@ impl KeyboardUpdater for Model1KeyboardUpdater {
}
impl Steppable for Model1Peripherals {
fn step(&mut self, system: &System) -> Result<ClockElapsed, Error> {
fn step(&mut self, _system: &System) -> Result<ClockElapsed, Error> {
let mut swapper = self.swapper.lock().unwrap();
swapper.current.clear(0);
for y in 0..16 {

View File

@ -7,7 +7,7 @@ use crate::memory::Bus;
use crate::debugger::Debugger;
use crate::error::{Error, ErrorType};
use crate::interrupts::InterruptController;
use crate::devices::{Clock, ClockElapsed, Address, TransmutableBox};
use crate::devices::{Clock, Address, TransmutableBox};
pub struct System {
@ -45,11 +45,17 @@ impl System {
self.interrupt_controller.borrow_mut()
}
pub fn add_device(&mut self, name: &str, device: TransmutableBox) -> Result<(), Error> {
self.try_queue_device(device.clone());
self.devices.insert(name.to_string(), device);
Ok(())
}
pub fn add_addressable_device(&mut self, addr: Address, device: TransmutableBox) -> Result<(), Error> {
let length = device.borrow_mut().as_addressable().unwrap().len();
self.bus.borrow_mut().insert(addr, length, device.clone());
self.try_queue_device(device.clone());
self.devices.insert(format!("ram{:x}", addr), device);
self.devices.insert(format!("mem{:x}", addr), device);
Ok(())
}
@ -108,7 +114,7 @@ impl System {
}
pub fn run_loop(&mut self) {
self.run_for(u64::MAX);
self.run_for(u64::MAX).unwrap();
}
pub fn exit_error(&mut self) {

View File

@ -1,25 +1,19 @@
* the overflow bit is only correct for addition but not subtraction... in subtraction, two positives can result in a negative and vice versa
* we need better m68k tests. Can we do what we did for Z80, with maybe a reduced test state and/or different states for different types of tests
* maybe see about a Mac 128k or something
* could have a remapper device, which takes a big swath of addresses in and maps them to another set of addresses (for Mac VIA generic to bus-hookup-in-mac adapter)
* how can you do devices that change their address map during operation, like mac which puts rom at 0 and ram at 600000 temporarily
* i need a better way of handling disperate reads/writes to I/O spaces, rather than having multiple devices or having a massive chunk of address space allocated, continuously
* should you modify Addressable to also take the absolute address as input? I'm thinking of how the same device could be mapped to multiple addresses in memory instead
of taking up a whole range of addresses
* could you use a generic sharable signal thing for sharing data, such as the VIA in mac128 where a single output bit determines the video mode (which would be a separate device)
So both could share the same Signal, one setting it and the other reading it, but how would you actually configure/build that?
* make it possible to specify the rom on the command line. Would this be machine specific?
* make the frontend resize its window based on the frame swapper
* make it possible to set the frame sizes when creating the frame swapper
* should you rename devices.rs traits.rs?
* maybe see about a Mac 128k or something
* how can you do devices that change their address map during operation, like mac which puts rom at 0 and ram at 600000 temporarily
* i need a better way of handling disperate reads/writes to I/O spaces, rather than having multiple devices or having a massive chunk of address space allocated, continuously
* should you modify Addressable to also take the absolute address as input? I'm thinking of how the same device could be mapped to multiple addresses in memory instead
of taking up a whole range of addresses
* could have a remapper device, which takes a big swath of addresses in and maps them to another set of addresses (for Mac VIA generic to bus-hookup-in-mac adapter)
* could you use a generic sharable signal thing for sharing data, such as the VIA in mac128 where a single output bit determines the video mode (which would be a separate device)
So both could share the same Signal, one setting it and the other reading it, but how would you actually configure/build that?
* you could modify read()/write() in Addressable to return the number of bytes read or written for dynamic bus sizing used by the MC68020+
@ -50,6 +44,5 @@ Z80:
* how can you have multiple CPUs
* each device that can make a bus request should have a BusPort which is used to access the bus
* can you eventually make the system connections all configurable via a config file?