mirror of
https://github.com/transistorfet/moa.git
synced 2025-01-23 08:32:36 +00:00
Modified the read interface yet again
This commit is contained in:
parent
1ad7ad1807
commit
8bbffbe34c
@ -39,19 +39,25 @@ pub trait Interruptable {
|
||||
/// 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 read(&mut self, addr: Address, data: &mut [u8]) -> Result<(), 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])
|
||||
let mut data = [0; 1];
|
||||
self.read(addr, &mut data)?;
|
||||
Ok(data[0])
|
||||
}
|
||||
|
||||
fn read_beu16(&mut self, addr: Address) -> Result<u16, Error> {
|
||||
Ok(read_beu16(&self.read(addr, 2)?))
|
||||
let mut data = [0; 2];
|
||||
self.read(addr, &mut data)?;
|
||||
Ok(read_beu16(&data))
|
||||
}
|
||||
|
||||
fn read_beu32(&mut self, addr: Address) -> Result<u32, Error> {
|
||||
Ok(read_beu32(&self.read(addr, 4)?))
|
||||
let mut data = [0; 4];
|
||||
self.read(addr, &mut data)?;
|
||||
Ok(read_beu32(&data))
|
||||
}
|
||||
|
||||
fn write_u8(&mut self, addr: Address, value: u8) -> Result<(), Error> {
|
||||
|
@ -42,13 +42,11 @@ impl Addressable for MemoryBlock {
|
||||
self.contents.len()
|
||||
}
|
||||
|
||||
fn read(&mut self, addr: Address, count: usize) -> Result<[u8; MAX_READ], Error> {
|
||||
let mut data = [0; MAX_READ];
|
||||
//self.contents[(addr as usize) .. (addr as usize + 4)].clone_from_slice(&data);
|
||||
for i in 0..std::cmp::min(count, MAX_READ) {
|
||||
fn read(&mut self, addr: Address, data: &mut [u8]) -> Result<(), Error> {
|
||||
for i in 0..data.len() {
|
||||
data[i] = self.contents[(addr as usize) + i];
|
||||
}
|
||||
Ok(data)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write(&mut self, mut addr: Address, data: &[u8]) -> Result<(), Error> {
|
||||
@ -76,21 +74,21 @@ pub struct Block {
|
||||
|
||||
pub struct Bus {
|
||||
pub blocks: Vec<Block>,
|
||||
pub mask: Address,
|
||||
pub address_mask: Address,
|
||||
}
|
||||
|
||||
impl Bus {
|
||||
pub fn new() -> Bus {
|
||||
Bus {
|
||||
blocks: vec!(),
|
||||
mask: !0,
|
||||
address_mask: !0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn address_limit(&mut self, bits: u8) {
|
||||
self.mask = 0;
|
||||
pub fn set_address_bits(&mut self, bits: u8) {
|
||||
self.address_mask = 0;
|
||||
for _ in 0..bits {
|
||||
self.mask = (self.mask << 1) | 0x01;
|
||||
self.address_mask = (self.address_mask << 1) | 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,7 +104,7 @@ impl Bus {
|
||||
}
|
||||
|
||||
pub fn get_device_at(&self, addr: Address, count: usize) -> Result<(TransmutableBox, Address), Error> {
|
||||
let addr = addr & self.mask;
|
||||
let addr = addr & self.address_mask;
|
||||
for block in &self.blocks {
|
||||
if addr >= block.base && addr <= (block.base + block.length as Address) {
|
||||
let relative_addr = addr - block.base;
|
||||
@ -146,9 +144,9 @@ impl Addressable for Bus {
|
||||
(block.base as usize) + block.length
|
||||
}
|
||||
|
||||
fn read(&mut self, addr: Address, count: usize) -> Result<[u8; MAX_READ], Error> {
|
||||
let (dev, relative_addr) = self.get_device_at(addr, count)?;
|
||||
let result = dev.borrow_mut().as_addressable().unwrap().read(relative_addr, count);
|
||||
fn read(&mut self, addr: Address, data: &mut [u8]) -> Result<(), Error> {
|
||||
let (dev, relative_addr) = self.get_device_at(addr, data.len())?;
|
||||
let result = dev.borrow_mut().as_addressable().unwrap().read(relative_addr, data);
|
||||
result
|
||||
}
|
||||
|
||||
@ -159,4 +157,3 @@ impl Addressable for Bus {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,9 +67,7 @@ impl Addressable for AtaDevice {
|
||||
0x30
|
||||
}
|
||||
|
||||
fn read(&mut self, addr: Address, _count: usize) -> Result<[u8; MAX_READ], Error> {
|
||||
let mut data = [0; MAX_READ];
|
||||
|
||||
fn read(&mut self, addr: Address, data: &mut [u8]) -> Result<(), Error> {
|
||||
match addr {
|
||||
ATA_REG_DATA_WORD => {
|
||||
self.selected_count -= 2;
|
||||
@ -99,7 +97,7 @@ impl Addressable for AtaDevice {
|
||||
_ => { debug!("{}: reading from {:0x}", DEV_NAME, addr); },
|
||||
}
|
||||
|
||||
Ok(data)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> {
|
||||
|
@ -261,9 +261,7 @@ impl Addressable for MC68681 {
|
||||
0x30
|
||||
}
|
||||
|
||||
fn read(&mut self, addr: Address, _count: usize) -> Result<[u8; MAX_READ], Error> {
|
||||
let mut data = [0; MAX_READ];
|
||||
|
||||
fn read(&mut self, addr: Address, data: &mut [u8]) -> Result<(), Error> {
|
||||
match addr {
|
||||
REG_SRA_RD => {
|
||||
data[0] = self.port_a.status
|
||||
@ -312,7 +310,7 @@ impl Addressable for MC68681 {
|
||||
debug!("{}: read from {:0x} of {:0x}", DEV_NAME, addr, data[0]);
|
||||
}
|
||||
|
||||
Ok(data)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> {
|
||||
|
8
todo.txt
8
todo.txt
@ -1,4 +1,12 @@
|
||||
|
||||
* each device that can make a bus request should have a BusPort which is used to access the bus. Not sure how it'll be created or passed to the device, since
|
||||
the offset should be set by the builder or system, and the mask and data size should be sent by the CPU (although I suppose some systems could hook it up differently)
|
||||
* what about even vs odd accesses? If you access a byte, should the bus port possible turn it into a word access, and return only the byte portion?
|
||||
this would be more accurate for the 68000 which doesn't have an A0 address pin
|
||||
* there is clearly an issue with the ROM writing 4 bytes to the data port when the autoincrement is only 2. This might be an issue with the fact that the CPU
|
||||
is making full long word requests even though the 68000 shouldn't be able to (a long word would be 2 word accesses)
|
||||
|
||||
|
||||
* make devices nameable, using a hashmap to store them
|
||||
* can you eventually make the system connections all configurable via a config file?
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user