mirror of
https://github.com/transistorfet/moa.git
synced 2024-11-21 19:30:52 +00:00
Sega Genesis coprocessor bus is now working
I've added skeleton devices for the sound chips, and added the bank register and banked area of ram mapped to the Z80's bus. Sonic1 will now run (if the ym2612 device's size is set to 0x1000 instead of 0x04)
This commit is contained in:
parent
8743c83834
commit
9a751e5e90
@ -4,12 +4,16 @@ use std::cell::RefCell;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::system::System;
|
||||
use crate::signals::Signal;
|
||||
use crate::memory::{MemoryBlock, Bus, BusPort};
|
||||
use crate::devices::{wrap_transmutable, Address, Addressable, Debuggable};
|
||||
|
||||
use crate::cpus::m68k::{M68k, M68kType};
|
||||
use crate::cpus::z80::{Z80, Z80Type};
|
||||
use crate::peripherals::ym2612::YM2612;
|
||||
use crate::peripherals::sn76489::SN76489;
|
||||
use crate::peripherals::genesis;
|
||||
use crate::peripherals::genesis::coprocessor::{CoprocessorBankRegister, CoprocessorBankArea};
|
||||
|
||||
use crate::host::traits::{Host};
|
||||
|
||||
@ -56,14 +60,28 @@ pub fn build_genesis<H: Host>(host: &mut H, options: SegaGenesisOptions) -> Resu
|
||||
system.add_addressable_device(0x00ff0000, wrap_transmutable(ram)).unwrap();
|
||||
|
||||
|
||||
// Build the Coprocessor's Bus
|
||||
let bank_register = Signal::new(0);
|
||||
let coproc_bus = Rc::new(RefCell::new(Bus::new()));
|
||||
let coproc_mem = wrap_transmutable(MemoryBlock::new(vec![0; 0x00010000]));
|
||||
coproc_bus.borrow_mut().insert(0x0000, coproc_mem.borrow_mut().as_addressable().unwrap().len(), coproc_mem.clone());
|
||||
let coproc_ram = wrap_transmutable(MemoryBlock::new(vec![0; 0x00002000]));
|
||||
let coproc_ym_sound = wrap_transmutable(YM2612::new());
|
||||
let coproc_sn_sound = wrap_transmutable(SN76489::new());
|
||||
let coproc_register = wrap_transmutable(CoprocessorBankRegister::new(bank_register.clone()));
|
||||
let coproc_area = wrap_transmutable(CoprocessorBankArea::new(bank_register, system.bus.clone()));
|
||||
coproc_bus.borrow_mut().insert(0x0000, coproc_ram.clone());
|
||||
coproc_bus.borrow_mut().insert(0x4000, coproc_ym_sound.clone());
|
||||
coproc_bus.borrow_mut().insert(0x6000, coproc_register.clone());
|
||||
coproc_bus.borrow_mut().insert(0x7f11, coproc_sn_sound.clone());
|
||||
coproc_bus.borrow_mut().insert(0x8000, coproc_area);
|
||||
let mut coproc = Z80::new(Z80Type::Z80, 3_579_545, BusPort::new(0, 16, 8, coproc_bus.clone()));
|
||||
let reset = coproc.reset.clone();
|
||||
let bus_request = coproc.bus_request.clone();
|
||||
|
||||
system.add_addressable_device(0x00a00000, coproc_mem)?;
|
||||
// Add coprocessor devices to the system bus so the 68000 can access them too
|
||||
system.add_addressable_device(0x00a00000, coproc_ram)?;
|
||||
system.add_addressable_device(0x00a04000, coproc_ym_sound)?;
|
||||
system.add_addressable_device(0x00a06000, coproc_register)?;
|
||||
system.add_addressable_device(0x00c00010, coproc_sn_sound)?;
|
||||
system.add_device("coproc", wrap_transmutable(coproc))?;
|
||||
|
||||
|
||||
|
@ -128,7 +128,8 @@ impl Bus {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, base: Address, length: usize, dev: TransmutableBox) {
|
||||
pub fn insert(&mut self, base: Address, dev: TransmutableBox) {
|
||||
let length = dev.borrow_mut().as_addressable().unwrap().len();
|
||||
let block = Block { base, length, dev };
|
||||
let i = self.blocks.iter().position(|cur| cur.base > block.base).unwrap_or(self.blocks.len());
|
||||
self.blocks.insert(i, block);
|
||||
|
@ -1,7 +1,11 @@
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
|
||||
use crate::memory::Bus;
|
||||
use crate::error::Error;
|
||||
use crate::signals::Signal;
|
||||
use crate::devices::{Address, Addressable, Transmutable};
|
||||
use crate::devices::{Address, Addressable, Transmutable, TransmutableBox};
|
||||
|
||||
|
||||
const DEV_NAME: &'static str = "coprocessor";
|
||||
@ -68,3 +72,73 @@ impl Transmutable for CoprocessorCoordinator {
|
||||
}
|
||||
|
||||
|
||||
pub struct CoprocessorBankRegister {
|
||||
pub base: Signal<Address>,
|
||||
}
|
||||
|
||||
impl CoprocessorBankRegister {
|
||||
pub fn new(base: Signal<Address>) -> Self {
|
||||
Self {
|
||||
base,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Addressable for CoprocessorBankRegister {
|
||||
fn len(&self) -> usize {
|
||||
0x01
|
||||
}
|
||||
|
||||
fn read(&mut self, addr: Address, data: &mut [u8]) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> {
|
||||
let value = ((self.base.get() >> 1) | ((data[0] as Address) << 23)) & 0xFF8000;
|
||||
println!("New base is {:x}", value);
|
||||
self.base.set(value);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Transmutable for CoprocessorBankRegister {
|
||||
fn as_addressable(&mut self) -> Option<&mut dyn Addressable> {
|
||||
Some(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct CoprocessorBankArea {
|
||||
pub base: Signal<Address>,
|
||||
pub bus: Rc<RefCell<Bus>>,
|
||||
}
|
||||
|
||||
impl CoprocessorBankArea {
|
||||
pub fn new(base: Signal<Address>, bus: Rc<RefCell<Bus>>) -> Self {
|
||||
Self {
|
||||
base,
|
||||
bus,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Addressable for CoprocessorBankArea {
|
||||
fn len(&self) -> usize {
|
||||
0x8000
|
||||
}
|
||||
|
||||
fn read(&mut self, addr: Address, data: &mut [u8]) -> Result<(), Error> {
|
||||
self.bus.borrow_mut().read(self.base.get() + addr, data)
|
||||
}
|
||||
|
||||
fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> {
|
||||
self.bus.borrow_mut().write(self.base.get() + addr, data)
|
||||
}
|
||||
}
|
||||
|
||||
impl Transmutable for CoprocessorBankArea {
|
||||
fn as_addressable(&mut self) -> Option<&mut dyn Addressable> {
|
||||
Some(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
57
src/peripherals/sn76489.rs
Normal file
57
src/peripherals/sn76489.rs
Normal file
@ -0,0 +1,57 @@
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::system::System;
|
||||
use crate::devices::{ClockElapsed, Address, Addressable, Steppable, Transmutable};
|
||||
|
||||
const DEV_NAME: &'static str = "sn76489";
|
||||
|
||||
pub struct SN76489 {
|
||||
|
||||
}
|
||||
|
||||
impl SN76489 {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Addressable for SN76489 {
|
||||
fn len(&self) -> usize {
|
||||
0x01
|
||||
}
|
||||
|
||||
fn read(&mut self, addr: Address, data: &mut [u8]) -> Result<(), Error> {
|
||||
match addr {
|
||||
_ => {
|
||||
warning!("{}: !!! unhandled read from {:0x}", DEV_NAME, addr);
|
||||
},
|
||||
}
|
||||
debug!("{}: read from register {:x} of {:?}", DEV_NAME, addr, data);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> {
|
||||
debug!("{}: write to register {:x} with {:x}", DEV_NAME, addr, data[0]);
|
||||
match addr {
|
||||
_ => {
|
||||
warning!("{}: !!! unhandled write {:0x} to {:0x}", DEV_NAME, data[0], addr);
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Transmutable for SN76489 {
|
||||
fn as_addressable(&mut self) -> Option<&mut dyn Addressable> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
//fn as_steppable(&mut self) -> Option<&mut dyn Steppable> {
|
||||
// Some(self)
|
||||
//}
|
||||
}
|
||||
|
||||
|
57
src/peripherals/ym2612.rs
Normal file
57
src/peripherals/ym2612.rs
Normal file
@ -0,0 +1,57 @@
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::system::System;
|
||||
use crate::devices::{ClockElapsed, Address, Addressable, Steppable, Transmutable};
|
||||
|
||||
const DEV_NAME: &'static str = "ym2612";
|
||||
|
||||
pub struct YM2612 {
|
||||
|
||||
}
|
||||
|
||||
impl YM2612 {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Addressable for YM2612 {
|
||||
fn len(&self) -> usize {
|
||||
0x04
|
||||
}
|
||||
|
||||
fn read(&mut self, addr: Address, data: &mut [u8]) -> Result<(), Error> {
|
||||
match addr {
|
||||
_ => {
|
||||
warning!("{}: !!! unhandled read from {:0x}", DEV_NAME, addr);
|
||||
},
|
||||
}
|
||||
debug!("{}: read from register {:x} of {:?}", DEV_NAME, addr, data);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> {
|
||||
debug!("{}: write to register {:x} with {:x}", DEV_NAME, addr, data[0]);
|
||||
match addr {
|
||||
_ => {
|
||||
warning!("{}: !!! unhandled write {:0x} to {:0x}", DEV_NAME, data[0], addr);
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Transmutable for YM2612 {
|
||||
fn as_addressable(&mut self) -> Option<&mut dyn Addressable> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
//fn as_steppable(&mut self) -> Option<&mut dyn Steppable> {
|
||||
// Some(self)
|
||||
//}
|
||||
}
|
||||
|
||||
|
@ -56,8 +56,7 @@ impl System {
|
||||
}
|
||||
|
||||
pub fn add_peripheral(&mut self, name: &str, addr: Address, device: TransmutableBox) -> Result<(), Error> {
|
||||
let length = device.borrow_mut().as_addressable().unwrap().len();
|
||||
self.bus.borrow_mut().insert(addr, length, device.clone());
|
||||
self.bus.borrow_mut().insert(addr, device.clone());
|
||||
self.try_queue_device(device.clone());
|
||||
self.devices.insert(name.to_string(), device);
|
||||
Ok(())
|
||||
|
Loading…
Reference in New Issue
Block a user