Minor fixes and refactoring

This commit is contained in:
transistor 2021-10-19 11:33:51 -07:00
parent 492027fa7a
commit 3579529764
6 changed files with 91 additions and 75 deletions

View File

@ -499,65 +499,8 @@ impl M68k {
Direction::FromTarget => { self.state.usp = self.get_target_value(system, target, Size::Long)?; },
}
},
Instruction::MOVEM(target, size, dir, mut mask) => {
// TODO moving words requires a sign extension to 32 bits
if size != Size::Long { return Err(Error::new("Unsupported size in MOVEM instruction")); }
let mut addr = self.get_target_address(system, 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 {
match target {
Target::IndirectARegInc(reg) | Target::IndirectARegDec(reg) => {
let a_reg_mut = self.get_a_reg_mut(reg);
*a_reg_mut = addr + (mask.count_ones() * size.in_bytes());
}
_ => { },
}
}
if dir == Direction::ToTarget {
for i in (0..8).rev() {
if (mask & 0x01) != 0 {
let value = *self.get_a_reg_mut(i);
addr -= size.in_bytes();
set_address_sized(system, addr as Address, value, size)?;
}
mask >>= 1;
}
for i in (0..8).rev() {
if (mask & 0x01) != 0 {
addr -= size.in_bytes();
set_address_sized(system, addr as Address, self.state.d_reg[i], size)?;
}
mask >>= 1;
}
} else {
let mut mask = mask;
for i in 0..8 {
if (mask & 0x01) != 0 {
self.state.d_reg[i] = get_address_sized(system, addr as Address, size)?;
addr += size.in_bytes();
}
mask >>= 1;
}
for i in 0..8 {
if (mask & 0x01) != 0 {
*self.get_a_reg_mut(i) = get_address_sized(system, addr as Address, size)?;
addr += size.in_bytes();
}
mask >>= 1;
}
}
// If it was Post-Inc/Pre-Dec target, then update the value
match target {
Target::IndirectARegInc(reg) | Target::IndirectARegDec(reg) => {
let a_reg_mut = self.get_a_reg_mut(reg);
*a_reg_mut = addr;
}
_ => { },
}
Instruction::MOVEM(target, size, dir, mask) => {
self.execute_movem(system, target, size, dir, mask)?;
},
Instruction::MOVEQ(data, reg) => {
let value = sign_extend_to_long(data as u32, Size::Byte) as u32;
@ -708,6 +651,66 @@ 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)?;
// 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 {
match target {
Target::IndirectARegInc(reg) | Target::IndirectARegDec(reg) => {
let a_reg_mut = self.get_a_reg_mut(reg);
*a_reg_mut = addr + (mask.count_ones() * size.in_bytes());
}
_ => { },
}
}
if dir == Direction::ToTarget {
for i in (0..8).rev() {
if (mask & 0x01) != 0 {
let value = *self.get_a_reg_mut(i);
addr -= size.in_bytes();
set_address_sized(system, addr as Address, value, size)?;
}
mask >>= 1;
}
for i in (0..8).rev() {
if (mask & 0x01) != 0 {
addr -= size.in_bytes();
set_address_sized(system, addr as Address, self.state.d_reg[i], size)?;
}
mask >>= 1;
}
} else {
let mut mask = mask;
for i in 0..8 {
if (mask & 0x01) != 0 {
self.state.d_reg[i] = sign_extend_to_long(get_address_sized(system, addr as Address, size)?, size) as u32;
addr += size.in_bytes();
}
mask >>= 1;
}
for i in 0..8 {
if (mask & 0x01) != 0 {
*self.get_a_reg_mut(i) = sign_extend_to_long(get_address_sized(system, addr as Address, size)?, size) as u32;
addr += size.in_bytes();
}
mask >>= 1;
}
}
// If it was Post-Inc/Pre-Dec target, then update the value
match target {
Target::IndirectARegInc(reg) | Target::IndirectARegDec(reg) => {
let a_reg_mut = self.get_a_reg_mut(reg);
*a_reg_mut = addr;
}
_ => { },
}
Ok(())
}
fn push_word(&mut self, system: &System, value: u16) -> Result<(), Error> {
let reg = self.get_stack_pointer_mut();
*reg -= 2;

View File

@ -1,3 +1,3 @@
pub mod ttys;
pub mod tty;

View File

@ -19,9 +19,14 @@ use crate::peripherals::mc68681::MC68681;
use crate::devices::wrap_transmutable;
fn main() {
run_computie();
}
fn run_computie() {
let mut system = System::new();
let monitor = MemoryBlock::load("binaries/monitor.bin").unwrap();
//let monitor = MemoryBlock::load("binaries/monitor-68030.bin").unwrap();
for byte in monitor.contents.iter() {
print!("{:02x} ", byte);
}
@ -29,6 +34,7 @@ fn main() {
let mut ram = MemoryBlock::new(vec![0; 0x00100000]);
ram.load_at(0, "binaries/kernel.bin").unwrap();
//ram.load_at(0, "binaries/kernel-68030.bin").unwrap();
system.add_addressable_device(0x00100000, wrap_transmutable(ram)).unwrap();
let mut ata = AtaDevice::new();
@ -37,7 +43,7 @@ fn main() {
let mut serial = MC68681::new();
launch_terminal_emulator(serial.port_a.open().unwrap());
//launch_slip_connection(serial.port_b.open().unwrap());
launch_slip_connection(serial.port_b.open().unwrap());
system.add_addressable_device(0x00700000, wrap_transmutable(serial)).unwrap();
@ -48,29 +54,22 @@ fn main() {
//cpu.add_breakpoint(0x10781a);
//cpu.add_breakpoint(0x10bc9c);
//cpu.add_breakpoint(0x106a94);
//cpu.add_breakpoint(0x10b79c);
//cpu.add_breakpoint(0x1015b2);
//cpu.add_breakpoint(0x103332);
//cpu.decoder.dump_disassembly(&mut system, 0x100000, 0x2000);
//cpu.decoder.dump_disassembly(&mut system, 0x2ac, 0x200);
system.add_interruptable_device(wrap_transmutable(cpu)).unwrap();
loop {
match system.step() {
Ok(()) => { },
Err(err) => {
system.exit_error();
println!("{:?}", err);
break;
},
}
}
system.run_loop();
}
pub fn launch_terminal_emulator(name: String) {
use nix::unistd::sleep;
use std::thread;
use std::time::Duration;
use std::process::Command;
Command::new("x-terminal-emulator").arg("-e").arg(&format!("pyserial-miniterm {}", name)).spawn().unwrap();
sleep(1);
thread::sleep(Duration::from_secs(1));
}
pub fn launch_slip_connection(name: String) {
@ -84,3 +83,4 @@ pub fn launch_slip_connection(name: String) {
Command::new("sudo").args(["sh", "-c", "echo 1 > /proc/sys/net/ipv4/ip_forward"]).status().unwrap();
}

View File

@ -3,7 +3,7 @@ use crate::error::Error;
use crate::system::System;
use crate::devices::{Clock, Address, Steppable, Addressable, Transmutable, MAX_READ};
use crate::host::ttys::{SimplePty, SharedSimplePty};
use crate::host::tty::{SimplePty, SharedSimplePty};
const REG_MR1A_MR2A: Address = 0x01;

View File

@ -75,5 +75,18 @@ impl System {
}
Ok(())
}
pub fn run_loop(&mut self) {
loop {
match self.step() {
Ok(()) => { },
Err(err) => {
self.exit_error();
println!("{:?}", err);
break;
},
}
}
}
}