2021-10-28 04:01:18 +00:00
|
|
|
|
2022-09-30 02:55:12 +00:00
|
|
|
use std::mem;
|
2021-11-13 19:39:20 +00:00
|
|
|
use std::rc::Rc;
|
|
|
|
use std::cell::RefCell;
|
|
|
|
|
2023-06-08 03:44:14 +00:00
|
|
|
use moa_core::{System, Error, Frequency, Signal, MemoryBlock, Bus, BusPort, Address, Addressable, Debuggable, Device};
|
2022-09-25 06:14:03 +00:00
|
|
|
use moa_core::host::Host;
|
2021-10-28 04:01:18 +00:00
|
|
|
|
2022-09-25 06:14:03 +00:00
|
|
|
use moa_m68k::{M68k, M68kType};
|
|
|
|
use moa_z80::{Z80, Z80Type};
|
|
|
|
use moa_peripherals_yamaha::Ym2612;
|
|
|
|
use moa_peripherals_yamaha::Sn76489;
|
2021-10-28 04:01:18 +00:00
|
|
|
|
2022-09-30 18:24:11 +00:00
|
|
|
use crate::utils;
|
2022-09-25 06:14:03 +00:00
|
|
|
use crate::peripherals::ym7101::Ym7101;
|
|
|
|
use crate::peripherals::controllers::GenesisControllers;
|
|
|
|
use crate::peripherals::coprocessor::{CoprocessorCoordinator, CoprocessorBankRegister, CoprocessorBankArea};
|
2021-10-28 04:01:18 +00:00
|
|
|
|
|
|
|
|
2021-12-06 03:41:23 +00:00
|
|
|
pub struct SegaGenesisOptions {
|
|
|
|
pub rom: String,
|
2022-09-30 02:55:12 +00:00
|
|
|
pub rom_data: Option<Vec<u8>>,
|
2021-12-06 03:41:23 +00:00
|
|
|
}
|
|
|
|
|
2023-03-06 04:19:49 +00:00
|
|
|
impl Default for SegaGenesisOptions {
|
|
|
|
fn default() -> Self {
|
2021-12-06 03:41:23 +00:00
|
|
|
Self {
|
|
|
|
rom: "".to_string(),
|
2022-09-30 02:55:12 +00:00
|
|
|
rom_data: None,
|
2021-12-06 03:41:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-30 02:55:12 +00:00
|
|
|
pub fn build_genesis<H: Host>(host: &mut H, mut options: SegaGenesisOptions) -> Result<System, Error> {
|
2023-03-06 04:19:49 +00:00
|
|
|
let mut system = System::default();
|
2021-10-28 04:01:18 +00:00
|
|
|
|
2022-09-30 18:24:11 +00:00
|
|
|
let rom_data = if options.rom_data.is_some() {
|
|
|
|
mem::take(&mut options.rom_data).unwrap()
|
2022-09-30 02:55:12 +00:00
|
|
|
} else {
|
2022-09-30 18:24:11 +00:00
|
|
|
utils::load_rom_file(&options.rom)?
|
2022-09-30 02:55:12 +00:00
|
|
|
};
|
2022-09-30 18:24:11 +00:00
|
|
|
|
|
|
|
let rom = MemoryBlock::new(rom_data);
|
2021-12-06 01:19:27 +00:00
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/GenTestV3.0.bin").unwrap();
|
2021-12-02 23:04:41 +00:00
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/HDRV_Genesis_Test_v1_4.bin").unwrap();
|
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/ComradeOj's tiny demo.bin").unwrap();
|
2021-12-06 03:41:23 +00:00
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/Digital Rain demo.bin").unwrap();
|
2021-11-03 22:33:22 +00:00
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic The Hedgehog (W) (REV 00) [!].bin").unwrap();
|
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic The Hedgehog (W) (REV 01) [!].bin").unwrap();
|
2021-12-06 03:41:23 +00:00
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic the Hedgehog 2 (JUE) [!].bin").unwrap();
|
2021-11-03 22:33:22 +00:00
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic the Hedgehog 3 (U) [!].bin").unwrap();
|
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/Earthworm Jim (U) [h1].bin").unwrap();
|
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/Home Alone (beta).bin").unwrap();
|
2021-11-07 04:44:25 +00:00
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/F1 World Championship (JUE) [!].bin").unwrap();
|
2021-11-03 22:33:22 +00:00
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/Ren and Stimpy's Invention (U) [!].bin").unwrap();
|
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/Out of this World (U) [!].bin").unwrap();
|
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/Ghostbusters (REV 00) (JUE).bin").unwrap();
|
|
|
|
//let mut rom = MemoryBlock::load("binaries/genesis/Teenage Mutant Ninja Turtles - The Hyperstone Heist (U) [!].bin").unwrap();
|
2021-12-04 21:55:58 +00:00
|
|
|
//rom.read_only();
|
2023-06-08 02:56:00 +00:00
|
|
|
let rom_end = rom.size();
|
2023-06-08 03:44:14 +00:00
|
|
|
system.add_addressable_device(0x00000000, Device::new(rom)).unwrap();
|
2021-10-28 04:01:18 +00:00
|
|
|
|
2022-09-30 18:24:11 +00:00
|
|
|
let cartridge_nvram = MemoryBlock::new(vec![0; 0x400000 - rom_end]);
|
2023-06-08 03:44:14 +00:00
|
|
|
system.add_addressable_device(rom_end as Address, Device::new(cartridge_nvram)).unwrap();
|
2021-11-16 04:51:33 +00:00
|
|
|
|
2021-10-28 04:01:18 +00:00
|
|
|
let ram = MemoryBlock::new(vec![0; 0x00010000]);
|
2023-06-08 03:44:14 +00:00
|
|
|
system.add_addressable_device(0x00ff0000, Device::new(ram)).unwrap();
|
2021-11-13 19:39:20 +00:00
|
|
|
|
2021-10-28 04:01:18 +00:00
|
|
|
|
2021-12-06 22:51:57 +00:00
|
|
|
// Build the Coprocessor's Bus
|
|
|
|
let bank_register = Signal::new(0);
|
2023-06-08 03:44:14 +00:00
|
|
|
let coproc_ram = Device::new(MemoryBlock::new(vec![0; 0x00002000]));
|
|
|
|
let coproc_ym_sound = Device::new(Ym2612::new(host, Frequency::from_hz(7_670_454))?);
|
|
|
|
let coproc_sn_sound = Device::new(Sn76489::new(host, Frequency::from_hz(3_579_545))?);
|
|
|
|
let coproc_register = Device::new(CoprocessorBankRegister::new(bank_register.clone()));
|
|
|
|
let coproc_area = Device::new(CoprocessorBankArea::new(bank_register, system.bus.clone()));
|
2021-12-07 04:44:44 +00:00
|
|
|
|
2023-03-06 04:19:49 +00:00
|
|
|
let coproc_bus = Rc::new(RefCell::new(Bus::default()));
|
2021-12-26 00:30:07 +00:00
|
|
|
coproc_bus.borrow_mut().set_ignore_unmapped(true);
|
2021-12-06 22:51:57 +00:00
|
|
|
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);
|
2023-05-13 21:47:27 +00:00
|
|
|
let mut coproc = Z80::new(Z80Type::Z80, Frequency::from_hz(3_579_545), BusPort::new(0, 16, 8, coproc_bus), None);
|
2021-12-26 00:30:07 +00:00
|
|
|
coproc.set_debugging(true);
|
2021-12-12 23:20:09 +00:00
|
|
|
let mut reset = coproc.reset.clone();
|
|
|
|
let mut bus_request = coproc.bus_request.clone();
|
|
|
|
reset.set(true);
|
|
|
|
bus_request.set(true);
|
2021-10-28 04:01:18 +00:00
|
|
|
|
2021-12-06 22:51:57 +00:00
|
|
|
// 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)?;
|
2022-09-09 02:51:29 +00:00
|
|
|
//system.add_addressable_device(0x00c00010, coproc_sn_sound)?;
|
|
|
|
system.add_device("sn_sound", coproc_sn_sound.clone())?;
|
2023-06-08 03:44:14 +00:00
|
|
|
system.add_device("coproc", Device::new(coproc))?;
|
2021-10-28 04:01:18 +00:00
|
|
|
|
|
|
|
|
2023-05-04 05:42:24 +00:00
|
|
|
let controllers = GenesisControllers::new(host)?;
|
2021-10-31 18:00:14 +00:00
|
|
|
let interrupt = controllers.get_interrupt_signal();
|
2023-06-08 03:44:14 +00:00
|
|
|
system.add_addressable_device(0x00a10000, Device::new(controllers)).unwrap();
|
2021-10-28 04:01:18 +00:00
|
|
|
|
2022-09-25 06:14:03 +00:00
|
|
|
let coproc = CoprocessorCoordinator::new(reset, bus_request);
|
2023-06-08 03:44:14 +00:00
|
|
|
system.add_addressable_device(0x00a11000, Device::new(coproc)).unwrap();
|
2021-10-28 04:01:18 +00:00
|
|
|
|
2022-09-25 06:14:03 +00:00
|
|
|
let vdp = Ym7101::new(host, interrupt, coproc_sn_sound);
|
2021-12-09 03:07:27 +00:00
|
|
|
system.break_signal = Some(vdp.frame_complete.clone());
|
2023-06-08 03:44:14 +00:00
|
|
|
system.add_peripheral("vdp", 0x00c00000, Device::new(vdp)).unwrap();
|
2021-10-28 04:01:18 +00:00
|
|
|
|
2023-04-23 22:46:47 +00:00
|
|
|
let cpu = M68k::new(M68kType::MC68000, Frequency::from_hz(7_670_454), BusPort::new(0, 24, 16, system.bus.clone()));
|
2023-06-08 03:44:14 +00:00
|
|
|
system.add_interruptable_device("cpu", Device::new(cpu)).unwrap();
|
2021-10-28 04:01:18 +00:00
|
|
|
|
|
|
|
Ok(system)
|
|
|
|
}
|
|
|
|
|