mirror of
https://github.com/transistorfet/moa.git
synced 2025-02-27 08:29:18 +00:00
Simplified event queue
This commit is contained in:
parent
250c0e83d2
commit
c1ca666aa4
@ -67,8 +67,7 @@ impl M68kDecoder {
|
||||
|
||||
pub fn decode_at(&mut self, memory: &mut dyn Addressable, start: u32) -> Result<(), Error> {
|
||||
self.init(start);
|
||||
self.instruction = self.decode_one(memory)?;
|
||||
Ok(())
|
||||
self.instruction = self.decode_one(memory)
|
||||
}
|
||||
|
||||
pub fn decode_one(&mut self, memory: &mut dyn Addressable) -> Result<Instruction, Error> {
|
||||
|
@ -88,7 +88,7 @@ impl M68k {
|
||||
match self.cycle_one(system) {
|
||||
Ok(()) => Ok(()),
|
||||
//Err(Error { err: ErrorType::Processor, native, .. }) => {
|
||||
// TODO temporary: we are passing illegal instructions upward in order to fix them
|
||||
// TODO match arm conditional is temporary: illegal instructions generate a top level error in order to debug and fix issues with decode
|
||||
Err(Error { err: ErrorType::Processor, native, .. }) if native != Exceptions::IllegalInstruction as u32 => {
|
||||
self.exception(system, native as u8)?;
|
||||
Ok(())
|
||||
|
@ -1,8 +1,7 @@
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cmp::Ordering;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::collections::BinaryHeap;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::memory::Bus;
|
||||
@ -13,7 +12,7 @@ use crate::devices::{Clock, ClockElapsed, Address, TransmutableBox};
|
||||
pub struct System {
|
||||
pub clock: Clock,
|
||||
pub devices: Vec<TransmutableBox>,
|
||||
pub event_queue: BinaryHeap<EventDevice>,
|
||||
pub event_queue: Vec<SteppableDevice>,
|
||||
pub bus: Rc<RefCell<Bus>>,
|
||||
pub interrupt_controller: RefCell<InterruptController>,
|
||||
}
|
||||
@ -23,7 +22,7 @@ impl System {
|
||||
System {
|
||||
clock: 0,
|
||||
devices: vec![],
|
||||
event_queue: BinaryHeap::new(),
|
||||
event_queue: vec![],
|
||||
bus: Rc::new(RefCell::new(Bus::new())),
|
||||
interrupt_controller: RefCell::new(InterruptController::new()),
|
||||
}
|
||||
@ -40,31 +39,23 @@ impl System {
|
||||
pub fn add_addressable_device(&mut self, 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.insert_steppable_device(device.clone());
|
||||
self.try_queue_device(device.clone());
|
||||
self.devices.push(device);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn add_interruptable_device(&mut self, device: TransmutableBox) -> Result<(), Error> {
|
||||
self.interrupt_controller.borrow_mut().set_target(device.clone())?;
|
||||
self.insert_steppable_device(device.clone());
|
||||
self.try_queue_device(device.clone());
|
||||
self.devices.push(device);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn insert_steppable_device(&mut self, device: TransmutableBox) -> Result<(), Error> {
|
||||
if device.borrow_mut().as_steppable().is_some() {
|
||||
let event_device = EventDevice::new(device);
|
||||
self.event_queue.push(event_device);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn step(&mut self) -> Result<(), Error> {
|
||||
let mut event_device = self.event_queue.pop().unwrap();
|
||||
self.clock = event_device.next_clock;
|
||||
event_device.next_clock = self.clock + event_device.device.borrow_mut().as_steppable().unwrap().step(&self)?;
|
||||
self.event_queue.push(event_device);
|
||||
self.queue_device(event_device);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -106,15 +97,32 @@ impl System {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn try_queue_device(&mut self, device: TransmutableBox) {
|
||||
if device.borrow_mut().as_steppable().is_some() {
|
||||
self.queue_device(SteppableDevice::new(device));
|
||||
}
|
||||
}
|
||||
|
||||
fn queue_device(&mut self, event_device: SteppableDevice) {
|
||||
for i in (0..self.event_queue.len()).rev() {
|
||||
if self.event_queue[i].next_clock > event_device.next_clock {
|
||||
self.event_queue.insert(i + 1, event_device);
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.event_queue.insert(0, event_device);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct EventDevice {
|
||||
pub struct SteppableDevice {
|
||||
pub next_clock: Clock,
|
||||
pub device: TransmutableBox,
|
||||
}
|
||||
|
||||
impl EventDevice {
|
||||
impl SteppableDevice {
|
||||
pub fn new(device: TransmutableBox) -> Self {
|
||||
Self {
|
||||
next_clock: 0,
|
||||
@ -123,24 +131,3 @@ impl EventDevice {
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for EventDevice {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
// NOTE this is reversed so that an event with a lower clock will be higher
|
||||
other.next_clock.cmp(&self.next_clock)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for EventDevice {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for EventDevice {}
|
||||
|
||||
impl PartialEq for EventDevice {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.next_clock == other.next_clock
|
||||
}
|
||||
}
|
||||
|
||||
|
1
todo.txt
1
todo.txt
@ -13,6 +13,7 @@
|
||||
* modify the interrupt handling to make the interrupted device acknowledge the interrupt, probably via the interrupt controller somehow. It might need to be async
|
||||
such that the cpu tells the int_controller it's acknowledged, and then the interrupting device can check the interrupt controller if it needs to see the ack.
|
||||
The ym7101 could use the ack as the "off" signal, and perhaps use that for the vsync int bit
|
||||
* there's potentially an issue with interrupts for m68k where it might not properly mask interrupts causing overlapping interrupts that cause problems (eventually executing RAM in Sonic)
|
||||
|
||||
|
||||
* 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user