Refactored a bit

Now all traits are in the devices file, and host adapters will be
in under src/host/.
This commit is contained in:
transistor 2021-10-16 20:30:50 -07:00
parent 93c9307829
commit 4bdbe7c7f0
13 changed files with 98 additions and 99 deletions

View File

@ -1,7 +1,7 @@
use crate::error::Error;
use crate::system::System;
use crate::memory::{Address, Addressable};
use crate::devices::{Address, Addressable};
use super::state::M68k;
use super::decode::M68kDecoder;

View File

@ -3,8 +3,7 @@ use std::fmt;
use crate::error::Error;
use crate::system::System;
use crate::memory::{Address, Addressable};
use crate::devices::AddressableDeviceRefMut;
use crate::devices::{Address, Addressable, AddressableDeviceRefMut};
use super::state::{M68kType, Exceptions};

View File

@ -1,8 +1,7 @@
use crate::system::System;
use crate::error::{ErrorType, Error};
use crate::memory::{Address, Addressable};
use crate::devices::{Clock, Steppable, Interruptable};
use crate::devices::{Clock, Address, Steppable, Interruptable, Addressable};
use super::decode::{
Instruction,

View File

@ -1,6 +1,6 @@
use crate::system::System;
use crate::memory::Address;
use crate::devices::Address;
use crate::timers::CpuTimer;
use super::decode::M68kDecoder;

View File

@ -2,11 +2,11 @@
#[cfg(test)]
mod decode_tests {
use crate::system::System;
use crate::devices::{Steppable, AddressableDeviceBox, wrap_addressable};
use crate::memory::{Address, Addressable, MemoryBlock};
use crate::memory::MemoryBlock;
use crate::devices::{Address, Addressable, Steppable, AddressableDeviceBox, wrap_addressable, MAX_READ};
use crate::cpus::m68k::{M68k, M68kType};
use crate::cpus::m68k::decode::{Instruction, Target, Size, Sign, RegisterType, ShiftDirection};
use crate::cpus::m68k::decode::{Instruction, Target, Size, Sign, XRegister, ShiftDirection};
const INIT_STACK: Address = 0x00002000;
const INIT_ADDR: Address = 0x00000010;
@ -136,7 +136,7 @@ mod decode_tests {
let memory = get_decode_memory(&mut cpu, &system);
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b110, 0b010, Some(size)).unwrap();
assert_eq!(target, Target::IndirectARegXRegOffset(2, RegisterType::Data, 3, offset, size));
assert_eq!(target, Target::IndirectARegXRegOffset(2, XRegister::Data(3), offset, 0, size));
}
#[test]
@ -194,7 +194,7 @@ mod decode_tests {
let memory = get_decode_memory(&mut cpu, &system);
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b111, 0b011, Some(size)).unwrap();
assert_eq!(target, Target::IndirectPCXRegOffset(RegisterType::Data, 3, offset, size));
assert_eq!(target, Target::IndirectPCXRegOffset(XRegister::Data(3), offset, 0, size));
}
#[test]
@ -331,8 +331,8 @@ mod decode_tests {
#[cfg(test)]
mod execute_tests {
use crate::system::System;
use crate::devices::{Steppable, wrap_addressable};
use crate::memory::{Address, Addressable, MemoryBlock};
use crate::memory::MemoryBlock;
use crate::devices::{Address, Addressable, Steppable, wrap_addressable};
use crate::cpus::m68k::{M68k, M68kType};
use crate::cpus::m68k::decode::{Instruction, Target, Size, Sign, ShiftDirection};
@ -419,22 +419,22 @@ mod execute_tests {
fn instruction_andi_sr() {
let (mut cpu, system) = init_test();
cpu.state.sr = 0x87AA;
cpu.state.sr = 0xA7AA;
cpu.decoder.instruction = Instruction::ANDtoSR(0xF8FF);
cpu.execute_current(&system).unwrap();
assert_eq!(cpu.state.sr, 0x80AA);
assert_eq!(cpu.state.sr, 0xA0AA);
}
#[test]
fn instruction_ori_sr() {
let (mut cpu, system) = init_test();
cpu.state.sr = 0x8755;
cpu.state.sr = 0xA755;
cpu.decoder.instruction = Instruction::ORtoSR(0x00AA);
cpu.execute_current(&system).unwrap();
assert_eq!(cpu.state.sr, 0x87FF);
assert_eq!(cpu.state.sr, 0xA7FF);
}
#[test]

View File

@ -4,10 +4,12 @@ use std::cell::{RefCell, RefMut};
use crate::error::Error;
use crate::system::System;
use crate::memory::{Addressable};
pub const MAX_READ: usize = 4;
pub type Clock = u64;
pub type Address = u64;
/// A device that can change state over time. The `step()` method will be called
/// by the containing `System` when the system clock advances. If an error occurs
@ -25,6 +27,40 @@ pub trait Interruptable {
fn interrupt_state_change(&mut self, state: bool, priority: u8, number: u8) -> Result<(), Error>;
}
/// A device that can be addressed to read data from or write data to the device.
pub trait Addressable {
fn len(&self) -> usize;
fn read(&mut self, addr: Address, count: usize) -> Result<[u8; MAX_READ], Error>;
fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error>;
fn read_u8(&mut self, addr: Address) -> Result<u8, Error> {
Ok(self.read(addr, 1)?[0])
}
fn read_beu16(&mut self, addr: Address) -> Result<u16, Error> {
Ok(read_beu16(&self.read(addr, 2)?))
}
fn read_beu32(&mut self, addr: Address) -> Result<u32, Error> {
Ok(read_beu32(&self.read(addr, 4)?))
}
fn write_u8(&mut self, addr: Address, value: u8) -> Result<(), Error> {
let data = [value];
self.write(addr, &data)
}
fn write_beu16(&mut self, addr: Address, value: u16) -> Result<(), Error> {
let data = write_beu16(value);
self.write(addr, &data)
}
fn write_beu32(&mut self, addr: Address, value: u32) -> Result<(), Error> {
let data = write_beu32(value);
self.write(addr, &data)
}
}
pub trait AddressableDevice: Addressable + Steppable { }
pub trait InterruptableDevice: Interruptable + Steppable { }
@ -52,3 +88,36 @@ pub enum Device {
}
#[inline(always)]
pub fn read_beu16(data: &[u8]) -> u16 {
(data[0] as u16) << 8 |
(data[1] as u16)
}
#[inline(always)]
pub fn read_beu32(data: &[u8]) -> u32 {
(data[0] as u32) << 24 |
(data[1] as u32) << 16 |
(data[2] as u32) << 8 |
(data[3] as u32)
}
#[inline(always)]
pub fn write_beu16(value: u16) -> [u8; 2] {
[
(value >> 8) as u8,
value as u8,
]
}
#[inline(always)]
pub fn write_beu32(value: u32) -> [u8; 4] {
[
(value >> 24) as u8,
(value >> 16) as u8,
(value >> 8) as u8,
value as u8,
]
}

3
src/host/mod.rs Normal file
View File

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

View File

@ -4,11 +4,12 @@ mod error;
mod memory;
mod timers;
mod devices;
mod ttys;
mod interrupts;
mod system;
mod host;
mod cpus;
mod peripherals;
mod system;
use crate::system::System;
use crate::memory::MemoryBlock;

View File

@ -3,46 +3,7 @@ use std::fs;
use crate::error::Error;
use crate::system::System;
use crate::devices::{Clock, Steppable, AddressableDeviceBox};
pub const MAX_READ: usize = 4;
pub type Address = u64;
/// A device that can be addressed to read data from or write data to the device.
pub trait Addressable {
fn len(&self) -> usize;
fn read(&mut self, addr: Address, count: usize) -> Result<[u8; MAX_READ], Error>;
fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error>;
fn read_u8(&mut self, addr: Address) -> Result<u8, Error> {
Ok(self.read(addr, 1)?[0])
}
fn read_beu16(&mut self, addr: Address) -> Result<u16, Error> {
Ok(read_beu16(&self.read(addr, 2)?))
}
fn read_beu32(&mut self, addr: Address) -> Result<u32, Error> {
Ok(read_beu32(&self.read(addr, 4)?))
}
fn write_u8(&mut self, addr: Address, value: u8) -> Result<(), Error> {
let data = [value];
self.write(addr, &data)
}
fn write_beu16(&mut self, addr: Address, value: u16) -> Result<(), Error> {
let data = write_beu16(value);
self.write(addr, &data)
}
fn write_beu32(&mut self, addr: Address, value: u32) -> Result<(), Error> {
let data = write_beu32(value);
self.write(addr, &data)
}
}
use crate::devices::{Clock, Address, Steppable, Addressable, AddressableDeviceBox, MAX_READ};
pub struct MemoryBlock {
@ -189,35 +150,3 @@ impl Addressable for Bus {
}
#[inline(always)]
pub fn read_beu16(data: &[u8]) -> u16 {
(data[0] as u16) << 8 |
(data[1] as u16)
}
#[inline(always)]
pub fn read_beu32(data: &[u8]) -> u32 {
(data[0] as u32) << 24 |
(data[1] as u32) << 16 |
(data[2] as u32) << 8 |
(data[3] as u32)
}
#[inline(always)]
pub fn write_beu16(value: u16) -> [u8; 2] {
[
(value >> 8) as u8,
value as u8,
]
}
#[inline(always)]
pub fn write_beu32(value: u32) -> [u8; 4] {
[
(value >> 24) as u8,
(value >> 16) as u8,
(value >> 8) as u8,
value as u8,
]
}

View File

@ -3,8 +3,7 @@ use std::fs;
use crate::error::Error;
use crate::system::System;
use crate::memory::{Address, Addressable, MAX_READ};
use crate::devices::{Clock, Steppable};
use crate::devices::{Clock, Address, Steppable, Addressable, MAX_READ};
const ATA_REG_DATA_WORD: Address = 0x20;

View File

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

View File

@ -2,9 +2,9 @@
use std::cell::{RefCell, RefMut};
use crate::error::Error;
use crate::memory::Bus;
use crate::interrupts::InterruptController;
use crate::memory::{Address, Bus};
use crate::devices::{Device, AddressableDeviceBox, InterruptableDeviceBox, Clock};
use crate::devices::{Address, Device, AddressableDeviceBox, InterruptableDeviceBox, Clock};
pub struct System {