mirror of
https://github.com/transistorfet/moa.git
synced 2025-01-11 05:29:42 +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::error::Error;
|
||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
use crate::memory::{Address, Addressable};
|
use crate::devices::{Address, Addressable};
|
||||||
|
|
||||||
use super::state::M68k;
|
use super::state::M68k;
|
||||||
use super::decode::M68kDecoder;
|
use super::decode::M68kDecoder;
|
||||||
|
@ -3,8 +3,7 @@ use std::fmt;
|
|||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
use crate::memory::{Address, Addressable};
|
use crate::devices::{Address, Addressable, AddressableDeviceRefMut};
|
||||||
use crate::devices::AddressableDeviceRefMut;
|
|
||||||
|
|
||||||
use super::state::{M68kType, Exceptions};
|
use super::state::{M68kType, Exceptions};
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
|
|
||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
use crate::error::{ErrorType, Error};
|
use crate::error::{ErrorType, Error};
|
||||||
use crate::memory::{Address, Addressable};
|
use crate::devices::{Clock, Address, Steppable, Interruptable, Addressable};
|
||||||
use crate::devices::{Clock, Steppable, Interruptable};
|
|
||||||
|
|
||||||
use super::decode::{
|
use super::decode::{
|
||||||
Instruction,
|
Instruction,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
use crate::memory::Address;
|
use crate::devices::Address;
|
||||||
use crate::timers::CpuTimer;
|
use crate::timers::CpuTimer;
|
||||||
|
|
||||||
use super::decode::M68kDecoder;
|
use super::decode::M68kDecoder;
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod decode_tests {
|
mod decode_tests {
|
||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
use crate::devices::{Steppable, AddressableDeviceBox, wrap_addressable};
|
use crate::memory::MemoryBlock;
|
||||||
use crate::memory::{Address, Addressable, MemoryBlock};
|
use crate::devices::{Address, Addressable, Steppable, AddressableDeviceBox, wrap_addressable, MAX_READ};
|
||||||
|
|
||||||
use crate::cpus::m68k::{M68k, M68kType};
|
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_STACK: Address = 0x00002000;
|
||||||
const INIT_ADDR: Address = 0x00000010;
|
const INIT_ADDR: Address = 0x00000010;
|
||||||
@ -136,7 +136,7 @@ mod decode_tests {
|
|||||||
|
|
||||||
let memory = get_decode_memory(&mut cpu, &system);
|
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();
|
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]
|
#[test]
|
||||||
@ -194,7 +194,7 @@ mod decode_tests {
|
|||||||
|
|
||||||
let memory = get_decode_memory(&mut cpu, &system);
|
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();
|
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]
|
#[test]
|
||||||
@ -331,8 +331,8 @@ mod decode_tests {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod execute_tests {
|
mod execute_tests {
|
||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
use crate::devices::{Steppable, wrap_addressable};
|
use crate::memory::MemoryBlock;
|
||||||
use crate::memory::{Address, Addressable, MemoryBlock};
|
use crate::devices::{Address, Addressable, Steppable, wrap_addressable};
|
||||||
|
|
||||||
use crate::cpus::m68k::{M68k, M68kType};
|
use crate::cpus::m68k::{M68k, M68kType};
|
||||||
use crate::cpus::m68k::decode::{Instruction, Target, Size, Sign, ShiftDirection};
|
use crate::cpus::m68k::decode::{Instruction, Target, Size, Sign, ShiftDirection};
|
||||||
@ -419,22 +419,22 @@ mod execute_tests {
|
|||||||
fn instruction_andi_sr() {
|
fn instruction_andi_sr() {
|
||||||
let (mut cpu, system) = init_test();
|
let (mut cpu, system) = init_test();
|
||||||
|
|
||||||
cpu.state.sr = 0x87AA;
|
cpu.state.sr = 0xA7AA;
|
||||||
cpu.decoder.instruction = Instruction::ANDtoSR(0xF8FF);
|
cpu.decoder.instruction = Instruction::ANDtoSR(0xF8FF);
|
||||||
|
|
||||||
cpu.execute_current(&system).unwrap();
|
cpu.execute_current(&system).unwrap();
|
||||||
assert_eq!(cpu.state.sr, 0x80AA);
|
assert_eq!(cpu.state.sr, 0xA0AA);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn instruction_ori_sr() {
|
fn instruction_ori_sr() {
|
||||||
let (mut cpu, system) = init_test();
|
let (mut cpu, system) = init_test();
|
||||||
|
|
||||||
cpu.state.sr = 0x8755;
|
cpu.state.sr = 0xA755;
|
||||||
cpu.decoder.instruction = Instruction::ORtoSR(0x00AA);
|
cpu.decoder.instruction = Instruction::ORtoSR(0x00AA);
|
||||||
|
|
||||||
cpu.execute_current(&system).unwrap();
|
cpu.execute_current(&system).unwrap();
|
||||||
assert_eq!(cpu.state.sr, 0x87FF);
|
assert_eq!(cpu.state.sr, 0xA7FF);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -4,10 +4,12 @@ use std::cell::{RefCell, RefMut};
|
|||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
use crate::memory::{Addressable};
|
|
||||||
|
|
||||||
|
|
||||||
|
pub const MAX_READ: usize = 4;
|
||||||
|
|
||||||
pub type Clock = u64;
|
pub type Clock = u64;
|
||||||
|
pub type Address = u64;
|
||||||
|
|
||||||
/// A device that can change state over time. The `step()` method will be called
|
/// 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
|
/// 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>;
|
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 AddressableDevice: Addressable + Steppable { }
|
||||||
pub trait InterruptableDevice: Interruptable + 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 memory;
|
||||||
mod timers;
|
mod timers;
|
||||||
mod devices;
|
mod devices;
|
||||||
mod ttys;
|
|
||||||
mod interrupts;
|
mod interrupts;
|
||||||
|
mod system;
|
||||||
|
|
||||||
|
mod host;
|
||||||
mod cpus;
|
mod cpus;
|
||||||
mod peripherals;
|
mod peripherals;
|
||||||
mod system;
|
|
||||||
|
|
||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
use crate::memory::MemoryBlock;
|
use crate::memory::MemoryBlock;
|
||||||
|
@ -3,46 +3,7 @@ use std::fs;
|
|||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
use crate::devices::{Clock, Steppable, AddressableDeviceBox};
|
use crate::devices::{Clock, Address, Steppable, Addressable, AddressableDeviceBox, MAX_READ};
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub struct MemoryBlock {
|
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::error::Error;
|
||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
use crate::memory::{Address, Addressable, MAX_READ};
|
use crate::devices::{Clock, Address, Steppable, Addressable, MAX_READ};
|
||||||
use crate::devices::{Clock, Steppable};
|
|
||||||
|
|
||||||
|
|
||||||
const ATA_REG_DATA_WORD: Address = 0x20;
|
const ATA_REG_DATA_WORD: Address = 0x20;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::system::System;
|
use crate::system::System;
|
||||||
use crate::devices::{Clock, Steppable};
|
use crate::devices::{Clock, Address, Steppable, Addressable, MAX_READ};
|
||||||
use crate::memory::{Address, Addressable, MAX_READ};
|
|
||||||
use crate::ttys::{SimplePty, SharedSimplePty};
|
use crate::host::ttys::{SimplePty, SharedSimplePty};
|
||||||
|
|
||||||
|
|
||||||
const REG_MR1A_MR2A: Address = 0x01;
|
const REG_MR1A_MR2A: Address = 0x01;
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
use std::cell::{RefCell, RefMut};
|
use std::cell::{RefCell, RefMut};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
use crate::memory::Bus;
|
||||||
use crate::interrupts::InterruptController;
|
use crate::interrupts::InterruptController;
|
||||||
use crate::memory::{Address, Bus};
|
use crate::devices::{Address, Device, AddressableDeviceBox, InterruptableDeviceBox, Clock};
|
||||||
use crate::devices::{Device, AddressableDeviceBox, InterruptableDeviceBox, Clock};
|
|
||||||
|
|
||||||
|
|
||||||
pub struct System {
|
pub struct System {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user