mirror of
https://github.com/transistorfet/moa.git
synced 2024-12-23 03:29:24 +00:00
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:
parent
93c9307829
commit
4bdbe7c7f0
@ -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;
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
use crate::system::System;
|
||||
use crate::memory::Address;
|
||||
use crate::devices::Address;
|
||||
use crate::timers::CpuTimer;
|
||||
|
||||
use super::decode::M68kDecoder;
|
||||
|
@ -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]
|
||||
|
@ -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
3
src/host/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
pub mod ttys;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user