marhel / r68k

A m68k emulator in rust - let r68k = musashi.clone();
MIT License
72 stars 7 forks source link

Make AddressBus possible to refer to as trait object #86

Closed pengi closed 4 years ago

pengi commented 4 years ago

I'm trying to use the r68k emulator (Great project!) to run some old mac applications from the 90's by creating an abstraction layer for the Macintosh toolbox.

One part of doing that is to map differnt parts of the address space, given prefixes, to differnt implementaitons. For example, one would be the video buffer, one would be the sound buffer, one would be regular RAM (possibly with memory allocation), one would be for emulade global variables.

Since it would be implemented in hardware with a demux on the MSB address bits connected to the chip enable/output enable of the different peripherals, and the lower bits as addresses, it makes sesse to treat the smaller address busses as AddressBus traits too, to keep it generic.

Therefore, I implement a MuxAddressBus, like:

pub struct PrefixMap<T> {
    // ...
}

impl<T> PrefixMap<T> {
    fn locate(&self, address : u32) -> Option<&T> {
        // ...
    }
    fn locate_mut(&mut self, address : u32) -> Option<&mut T> {
        // ...
    }
}

pub struct MuxAddressBus {
    children: PrefixMap<Box<dyn AddressBus>>
}

impl AddressBus for MuxAddressBus {
   // ...
}

In that way, I can split out the address space.

The problem is the copy_from() method required in the AddressBus trait, which not really corresponds to the physical interface of address lines, data lines and control lines (read/write signals). The copy_from corresponds more to a physical memory, and would be better implenented as part of that interface (LoggedMem / PagedMem).

So I suggest moving copy_from() method to the implementation of those objects, rather than the trait AddressBus

pengi commented 4 years ago

Realized that the core-trait branch was old... The PR is still relevant, but I'm going to update it to master

marhel commented 4 years ago

Thanks for the contribution! I'll take a look at it when you're done. I agree that memory mapping for these purposes is useful, and it was something I had in an older C++ implementation of a computer, where I had a MemoryMappedDevice that attached itself to the RAM bus to handle reads/writes at a certain address space. I haven't gotten this far in my Rust implementation of the same thing, but support for some such mechanism is definitely needed!

pengi commented 4 years ago

Mm. It's quite common for hardware to be memory mapped also. For example, Mac 128k and Mac 512k have some regions, address 0x00000000 and up is mapped to RAM (or ROM during startup), 0x04000000 is start address for ROM, 0x06000000 is start address for RAM during startup. Some peripherals, such as serial port, sound and VIA, is mapped to specific addresses and gated in hardware.

However, I closed this PR, since I couldn't change the target. So PR #87 is the exact same, but for the newer master branch. (I thought the issue #83 pointed out this branch core-trait was newer before looking at the log)