From 8bbffbe34c384d6d4971b809643bc1d123348f36 Mon Sep 17 00:00:00 2001 From: transistor Date: Tue, 26 Oct 2021 17:33:23 -0700 Subject: [PATCH] Modified the read interface yet again --- src/devices.rs | 14 ++++++++++---- src/memory.rs | 27 ++++++++++++--------------- src/peripherals/ata.rs | 6 ++---- src/peripherals/mc68681.rs | 6 ++---- todo.txt | 8 ++++++++ 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/devices.rs b/src/devices.rs index a4c2032..c8b8c32 100644 --- a/src/devices.rs +++ b/src/devices.rs @@ -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 { - 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 { - 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 { - 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> { diff --git a/src/memory.rs b/src/memory.rs index ebadd03..bc6d856 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -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, - 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 { } } - diff --git a/src/peripherals/ata.rs b/src/peripherals/ata.rs index e388ec6..6e2a826 100644 --- a/src/peripherals/ata.rs +++ b/src/peripherals/ata.rs @@ -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> { diff --git a/src/peripherals/mc68681.rs b/src/peripherals/mc68681.rs index 016d4f1..a665152 100644 --- a/src/peripherals/mc68681.rs +++ b/src/peripherals/mc68681.rs @@ -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> { diff --git a/todo.txt b/todo.txt index 9636f4c..9fe0df5 100644 --- a/todo.txt +++ b/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?