Modified the read interface yet again

This commit is contained in:
transistor 2021-10-26 17:33:23 -07:00
parent 1ad7ad1807
commit 8bbffbe34c
5 changed files with 34 additions and 27 deletions

View File

@ -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> {

View File

@ -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 {
}
}

View File

@ -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> {

View File

@ -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> {

View File

@ -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?