From fbb51531217a2cfda41c02d8b7b3d646aa15a89c Mon Sep 17 00:00:00 2001 From: transistor Date: Sat, 9 Oct 2021 17:35:23 -0700 Subject: [PATCH] Refactored mc68681 to make a common port struct and fixed a bug in DIV --- binaries/kernel.bin | Bin 58036 -> 58320 bytes src/cpus/m68k/execute.rs | 7 +- src/main.rs | 39 ++++++- src/peripherals/mc68681.rs | 223 +++++++++++++++++++------------------ src/system.rs | 7 +- 5 files changed, 162 insertions(+), 114 deletions(-) diff --git a/binaries/kernel.bin b/binaries/kernel.bin index 48554d4c0b88f4cb1a034f35a6ae8912d849c673..fc35300e5c43d00ba5d2ca79176cb0478bf132fb 100755 GIT binary patch delta 9898 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 B{{jF2 diff --git a/src/cpus/m68k/execute.rs b/src/cpus/m68k/execute.rs index 2d072f8..0c259ef 100644 --- a/src/cpus/m68k/execute.rs +++ b/src/cpus/m68k/execute.rs @@ -261,8 +261,11 @@ impl MC68010 { let value = self.get_target_value(system, src, size)?; let existing = self.get_target_value(system, dest, Size::Long)?; let result = match sign { - Sign::Signed => ((existing as i16 % value as i16) as u32) << 16 | (0xFFFF & (existing as i16 / value as i16) as u32), - Sign::Unsigned => ((existing as u16 % value as u16) as u32) << 16 | (0xFFFF & (existing as u16 / value as u16) as u32), + Sign::Signed => { + let value = sign_extend_to_long(value, size) as u32; + ((existing % value) << 16) | (0xFFFF & (existing / value)) + }, + Sign::Unsigned => ((existing % value) << 16) | (0xFFFF & (existing / value)), }; self.set_target_value(system, dest, result, Size::Long)?; }, diff --git a/src/main.rs b/src/main.rs index 0e8e3d4..daf52f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,7 +34,8 @@ fn main() { system.add_addressable_device(0x00600000, wrap_addressable(ata)).unwrap(); let mut serial = MC68681::new(); - serial.open().unwrap(); + launch_terminal_emulator(serial.port_a.open().unwrap()); + launch_slip_connection(serial.port_b.open().unwrap()); system.add_addressable_device(0x00700000, wrap_addressable(serial)).unwrap(); @@ -44,6 +45,7 @@ fn main() { //cpu.add_breakpoint(0x10781a); //cpu.add_breakpoint(0x10bc9c); //cpu.add_breakpoint(0x106a94); + //cpu.add_breakpoint(0x10d0c6); system.add_interruptable_device(wrap_interruptable(cpu)).unwrap(); loop { @@ -72,3 +74,38 @@ fn main() { */ } +pub fn launch_terminal_emulator(name: String) { + use nix::unistd::sleep; + use std::process::Command; + + Command::new("x-terminal-emulator").arg("-e").arg(&format!("pyserial-miniterm {}", name)).spawn().unwrap(); + sleep(1); +} + +pub fn launch_slip_connection(name: String) { + use nix::unistd::sleep; + use std::process::Command; + + //Command::new("x-terminal-emulator").arg("-e").arg(&format!("pyserial-miniterm {}", name)).spawn().unwrap(); + + Command::new("sudo").args(["slattach", "-s", "38400", "-p", "slip", &name]).spawn().unwrap(); + Command::new("sudo").args(["ifconfig", "sl0", "192.168.1.2", "pointopoint", "192.168.1.200", "up"]).status().unwrap(); + Command::new("sudo").args(["arp", "-Ds", "192.168.1.200", "enp4s0", "pub"]).status().unwrap(); + Command::new("sudo").args(["iptables", "-A", "FORWARD", "-i", "sl0", "-j", "ACCEPT"]).status().unwrap(); + Command::new("sudo").args(["iptables", "-A", "FORWARD", "-o", "sl0", "-j", "ACCEPT"]).status().unwrap(); + Command::new("sudo").args(["sh", "-c", "echo 1 > /proc/sys/net/ipv4/ip_forward"]).status().unwrap(); + /* + */ + /* + sudo slattach -s 38400 -p slip /dev/ttyUSB1 + sudo ifconfig sl0 192.168.1.2 pointopoint 192.168.1.200 up + // (this is automatically added on my machine) >> sudo route add -host 192.168.1.200 sl0 + sudo arp -Ds 192.168.1.200 enp3s0 pub + sudo iptables -A FORWARD -i sl0 -j ACCEPT + sudo iptables -A FORWARD -o sl0 -j ACCEPT + sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" + */ + + sleep(1); +} + diff --git a/src/peripherals/mc68681.rs b/src/peripherals/mc68681.rs index ab5d371..48e236a 100644 --- a/src/peripherals/mc68681.rs +++ b/src/peripherals/mc68681.rs @@ -1,10 +1,8 @@ -use std::process::Command; use std::io::{Read, Write}; use std::os::unix::io::AsRawFd; use nix::fcntl::OFlag; -use nix::unistd::sleep; use nix::pty::{self, PtyMaster}; use nix::fcntl::{fcntl, FcntlArg}; @@ -21,12 +19,12 @@ const REG_CRA_WR: Address = 0x05; const REG_TBA_WR: Address = 0x07; const REG_RBA_RD: Address = 0x07; -const REG_MR1B_MR2B: Address = 0x700011; -const REG_SRB_RD: Address = 0x700013; -const REG_CSRB_WR: Address = 0x700013; -const REG_CRB_WR: Address = 0x700015; -const REG_TBB_WR: Address = 0x700017; -const REG_RBB_RD: Address = 0x700017; +const REG_MR1B_MR2B: Address = 0x11; +const REG_SRB_RD: Address = 0x13; +const REG_CSRB_WR: Address = 0x13; +const REG_CRB_WR: Address = 0x15; +const REG_TBB_WR: Address = 0x17; +const REG_RBB_RD: Address = 0x17; const REG_ACR_WR: Address = 0x09; @@ -70,21 +68,95 @@ const ISR_CH_A_TX_READY: u8 = 0x01; const DEV_NAME: &'static str = "mc68681"; -pub struct MC68681 { +pub struct MC68681Port { pub tty: Option, + pub status: u8, + pub input: u8, + pub tx_enabled: bool, + pub rx_enabled: bool, +} + +impl MC68681Port { + pub fn new() -> MC68681Port { + MC68681Port { + tty: None, + status: 0, + input: 0, + tx_enabled: false, + rx_enabled: false, + } + } + + pub fn open(&mut self) -> Result { + let master = pty::posix_openpt(OFlag::O_RDWR).and_then(|master| { + pty::grantpt(&master)?; + pty::unlockpt(&master)?; + fcntl(master.as_raw_fd(), FcntlArg::F_SETFL(OFlag::O_NONBLOCK))?; + Ok(master) + }).map_err(|_| Error::new("Error opening new pseudoterminal"))?; + + let name = unsafe { pty::ptsname(&master).map_err(|_| Error::new("Unable to get pty name"))? }; + println!("{}: opening pts {}", DEV_NAME, name); + self.tty = Some(master); + Ok(name) + } + + pub fn rx_ready(&self) -> bool { + (self.status & SR_RX_READY) != 0 + } + + pub fn check_read(&mut self) -> Result { + if self.rx_enabled && !self.rx_ready() && self.tty.is_some() { + let mut buf = [0; 1]; + let tty = self.tty.as_mut().unwrap(); + match tty.read(&mut buf) { + Ok(count) => { + println!("READ {:?}", count); + self.input = buf[0]; + self.status |= SR_RX_READY; + return Ok(true); + }, + Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => { }, + Err(err) => { + println!("ERROR: {:?}", err); + } + } + } + Ok(false) + } + + pub fn handle_command(&mut self, data: u8) -> Option { + let rx_cmd = data& 0x03; + if rx_cmd == 0b01 { + self.rx_enabled = true; + } else if rx_cmd == 0b10 { + self.rx_enabled = false; + } + + let tx_cmd = (data & 0x0C) >> 2; + if tx_cmd == 0b01 { + self.tx_enabled = true; + self.status |= SR_TX_READY | SR_TX_EMPTY; + return Some(true); + } else if tx_cmd == 0b10 { + self.tx_enabled = false; + self.status &= !(SR_TX_READY | SR_TX_EMPTY); + return Some(false); + } + + None + } +} + +pub struct MC68681 { pub acr: u8, - pub status_a: u8, - pub input_a: u8, - pub tx_a_enabled: bool, - pub rx_a_enabled: bool, - pub status_b: u8, - pub input_b: u8, - pub tx_b_enabled: bool, - pub rx_b_enabled: bool, + pub port_a: MC68681Port, + pub port_b: MC68681Port, + pub int_mask: u8, pub int_status: u8, pub int_vector: u8, - pub is_interrupt: bool, + pub timer_preload: u16, pub timer_count: u16, pub is_timing: bool, @@ -93,22 +165,13 @@ pub struct MC68681 { impl MC68681 { pub fn new() -> Self { MC68681 { - tty: None, acr: 0, - - status_a: 0, - input_a: 0, - tx_a_enabled: false, - rx_a_enabled: false, - status_b: 0, - input_b: 0, - tx_b_enabled: false, - rx_b_enabled: false, + port_a: MC68681Port::new(), + port_b: MC68681Port::new(), int_mask: 0, int_status: 0, int_vector: 0, - is_interrupt: false, timer_preload: 0, timer_count: 0, @@ -116,46 +179,13 @@ impl MC68681 { } } - pub fn open(&mut self) -> Result<(), Error> { - let result = pty::posix_openpt(OFlag::O_RDWR).and_then(|master| { - pty::grantpt(&master).and_then(|_| pty::unlockpt(&master)).and_then(|_| Ok(master)) - }); - - match result { - Ok(master) => { - let name = unsafe { pty::ptsname(&master).map_err(|_| Error::new("Unable to get pty name"))? }; - println!("Open {}", name); - fcntl(master.as_raw_fd(), FcntlArg::F_SETFL(OFlag::O_NONBLOCK)).unwrap(); - self.tty = Some(master); - - Command::new("x-terminal-emulator").arg("-e").arg(&format!("pyserial-miniterm {}", name)).spawn().unwrap(); - sleep(1); - Ok(()) - }, - Err(_) => Err(Error::new("Error opening new pseudoterminal")), - } - } - - pub fn rx_ready(&self) -> bool { - (self.status_a & SR_RX_READY) != 0 - } - pub fn step_internal(&mut self, system: &System) -> Result<(), Error> { - if self.rx_a_enabled && !self.rx_ready() && self.tty.is_some() { - let mut buf = [0; 1]; - let tty = self.tty.as_mut().unwrap(); - match tty.read(&mut buf) { - Ok(count) => { - println!("READ {:?}", count); - self.input_a = buf[0]; - self.status_a |= SR_RX_READY; - self.int_status |= ISR_CH_A_RX_READY_FULL; - }, - Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => { }, - Err(err) => { - println!("ERROR: {:?}", err); - } - } + if self.port_a.check_read()? { + self.int_status |= ISR_CH_A_RX_READY_FULL; + } + + if self.port_b.check_read()? { + self.int_status |= ISR_CH_B_RX_READY_FULL; } if self.is_timing { @@ -176,6 +206,10 @@ impl MC68681 { Ok(()) } + fn set_interrupt_flag(&mut self, flag: u8, value: bool) { + self.int_status = (self.int_status & !flag) | (if value { flag } else { 0 }); + } + fn check_interrupt_state(&mut self, system: &System) -> Result<(), Error> { system.get_interrupt_controller().set((self.int_status & self.int_mask) != 0, 4, self.int_vector) } @@ -195,19 +229,19 @@ impl Addressable for MC68681 { match addr { REG_SRA_RD => { - data[0] = self.status_a + data[0] = self.port_a.status }, REG_RBA_RD => { - data[0] = self.input_a; - self.status_a &= !SR_RX_READY; + data[0] = self.port_a.input; + self.port_a.status &= !SR_RX_READY; self.int_status &= !ISR_CH_A_RX_READY_FULL; }, REG_SRB_RD => { - data[0] = self.status_b + data[0] = self.port_b.status }, REG_RBB_RD => { - data[0] = self.input_b; - self.status_b &= !SR_RX_READY; + data[0] = self.port_b.input; + self.port_b.status &= !SR_RX_READY; self.int_status &= !ISR_CH_B_RX_READY_FULL; }, REG_ISR_RD => { @@ -245,47 +279,22 @@ impl Addressable for MC68681 { } REG_TBA_WR => { println!("{}a: write {}", DEV_NAME, data[0] as char); - self.tty.as_mut().map(|tty| tty.write_all(&[data[0]])); + self.port_a.tty.as_mut().map(|tty| tty.write_all(&[data[0]])); }, REG_CRA_WR => { - let rx_cmd = (data[0] & 0x03); - if rx_cmd == 0b01 { - self.rx_a_enabled = true; - } else if rx_cmd == 0b10 { - self.rx_a_enabled = false; - } - - let tx_cmd = ((data[0] & 0x0C) >> 2); - if tx_cmd == 0b01 { - self.tx_a_enabled = true; - self.status_a |= SR_TX_READY | SR_TX_EMPTY; - self.int_status |= ISR_CH_A_TX_READY; - } else if tx_cmd == 0b10 { - self.tx_a_enabled = false; - self.status_a &= !(SR_TX_READY | SR_TX_EMPTY); - self.int_status &= !ISR_CH_A_TX_READY; + match self.port_a.handle_command(data[0]) { + Some(value) => self.set_interrupt_flag(ISR_CH_A_TX_READY, value), + None => { }, } }, REG_TBB_WR => { println!("{}b: write {:x}", DEV_NAME, data[0]); + self.port_b.tty.as_mut().map(|tty| tty.write_all(&[data[0]])); }, REG_CRB_WR => { - let rx_cmd = (data[0] & 0x03); - if rx_cmd == 0b01 { - self.rx_b_enabled = true; - } else if rx_cmd == 0b10 { - self.rx_b_enabled = false; - } - - let tx_cmd = ((data[0] & 0x0C) >> 2); - if tx_cmd == 0b01 { - self.tx_b_enabled = true; - self.status_b |= SR_TX_READY | SR_TX_EMPTY; - self.int_status |= ISR_CH_B_TX_READY; - } else if tx_cmd == 0b10 { - self.tx_b_enabled = false; - self.status_b &= !(SR_TX_READY | SR_TX_EMPTY); - self.int_status &= !ISR_CH_B_TX_READY; + match self.port_b.handle_command(data[0]) { + Some(value) => self.set_interrupt_flag(ISR_CH_B_TX_READY, value), + None => { }, } }, REG_CTUR_WR => { diff --git a/src/system.rs b/src/system.rs index cd397cc..7fbd421 100644 --- a/src/system.rs +++ b/src/system.rs @@ -1,11 +1,10 @@ -use std::rc::Rc; use std::cell::{RefCell, RefMut}; use crate::error::Error; use crate::interrupts::InterruptController; -use crate::memory::{Address, Addressable, Bus}; -use crate::devices::{Device, Steppable, AddressableDeviceBox, InterruptableDeviceBox, Clock}; +use crate::memory::{Address, Bus}; +use crate::devices::{Device, AddressableDeviceBox, InterruptableDeviceBox, Clock}; pub struct System { @@ -42,7 +41,7 @@ impl System { } pub fn add_interruptable_device(&mut self, device: InterruptableDeviceBox) -> Result<(), Error> { - self.interrupt_controller.borrow_mut().set_target(device.clone()); + self.interrupt_controller.borrow_mut().set_target(device.clone())?; self.devices.push(Device::Interruptable(device)); Ok(()) }