Skip to content

Commit

Permalink
Split bus and dma wait state counters
Browse files Browse the repository at this point in the history
  • Loading branch information
dbalsom committed Aug 15, 2023
1 parent 6e8607c commit 2b5d14b
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 55 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
@@ -1,6 +1,9 @@

## [0.1.4](https://github.com/dbalsom/martypc/releases/tag/0.1.4) (2023-07-XX)
## [0.1.4](https://github.com/dbalsom/martypc/releases/tag/0.1.4) (2023-08-XX)

* Added MMIO peek functions. Allows Memory debug viewer to peek into MMIO regions, if device supports.
* Brand new, simplified BIU state logic
* Fixed & Improved DMA refresh scheduling. (Fixes 8088MPH CPU test)
* Fixed issue where Call Stack could grow uncontrollably with recursive code or interrupts
* Fixed CS:IP reporting in Instruction trace mode logs
* Fixed memory leak in Instruction trace mode (thanks Folkert)
Expand Down
40 changes: 29 additions & 11 deletions core/src/cpu_808x/biu.rs
Expand Up @@ -338,6 +338,7 @@ impl Cpu {
// - We are scheduling a prefetch during a CODE fetch
// - The queue length was 3 at the beginning of T3

/*
// If we are in some kind of bus transfer (not passive) then add any wait states that
// might apply.
let schedule_adjust = if self.bus_status != BusStatus::Passive {
Expand All @@ -346,17 +347,34 @@ impl Cpu {
else {
0
};
*/

if self.bus_status == BusStatus::CodeFetch
&& (self.queue.len() == 3 || (self.queue.len() == 2 && self.queue_op != QueueOp::Idle))
{
self.fetch_state = FetchState::Scheduled(ct + schedule_adjust);
self.next_fetch_state = FetchState::Delayed(3);
if ct == 0 {
// Schedule count of 0 indicates fetch after bus transfer is complete, ie, ScheduleNext
if self.bus_status == BusStatus::CodeFetch
&& (self.queue.len() == 3 || (self.queue.len() == 2 && self.queue_op != QueueOp::Idle))
{
self.fetch_state = FetchState::ScheduleNext;
self.next_fetch_state = FetchState::Delayed(3);
}
else {
self.fetch_state = FetchState::ScheduleNext;
self.next_fetch_state = FetchState::InProgress;
};
}
else {
self.fetch_state = FetchState::Scheduled(ct + schedule_adjust);
self.next_fetch_state = FetchState::InProgress;
};

if self.bus_status == BusStatus::CodeFetch
&& (self.queue.len() == 3 || (self.queue.len() == 2 && self.queue_op != QueueOp::Idle))
{
self.fetch_state = FetchState::Scheduled(ct);
self.next_fetch_state = FetchState::Delayed(3);
}
else {
self.fetch_state = FetchState::Scheduled(ct);
self.next_fetch_state = FetchState::InProgress;
};
}

// new bus logic: transition to PF state
self.biu_change_state(BiuStateNew::Prefetch);
Expand All @@ -366,7 +384,7 @@ impl Cpu {
/// T3 or later. This incurs two penalty cycles.
pub fn biu_abort_fetch(&mut self) {

self.fetch_state = FetchState::Aborted(2);
self.fetch_state = FetchState::Aborting(2);
self.t_cycle = TCycle::T1;
self.bus_status = BusStatus::Passive;
self.i8288.ale = false;
Expand Down Expand Up @@ -463,7 +481,7 @@ impl Cpu {
// EU has not claimed the bus, attempt to prefetch...
if self.biu_queue_has_room() {
if !self.fetch_suspended {
self.biu_schedule_fetch(2);
self.biu_schedule_fetch(0);
}
}
else {
Expand Down Expand Up @@ -533,7 +551,7 @@ impl Cpu {
FetchState::Scheduled(c) => {
*c = c.saturating_sub(1);
}
FetchState::Aborted(c) => {
FetchState::Aborting(c) => {
*c = c.saturating_sub(1);

if *c == 0 {
Expand Down
54 changes: 14 additions & 40 deletions core/src/cpu_808x/cycle.rs
Expand Up @@ -228,11 +228,11 @@ impl Cpu {
// Do DRAM refresh (DMA channel 0) simulation
if self.enable_wait_states && self.dram_refresh_simulation {

self.dram_refresh_cycle_num -= 1;
self.dram_refresh_cycle_num = self.dram_refresh_cycle_num.saturating_sub(1);

match &mut self.dma_state {
DmaState::Idle => {
if self.dram_refresh_cycle_num == 0 {
if self.dram_refresh_cycle_num == 0 && self.dram_refresh_cycle_period > 0 {
// DRAM refresh cycle counter has hit terminal count.
// Begin DMA transfer simulation by issuing a DREQ.
self.dma_state = DmaState::Dreq;
Expand Down Expand Up @@ -282,8 +282,7 @@ impl Cpu {
*cycles = cycles.saturating_sub(1);
if *cycles == 3 {
// DMAWAIT asserted on S2
self.wait_states += 7; // Effectively 6 as this is decremented this cycle
//self.wait_states += 6_u32.saturating_sub(self.wait_states);
self.dma_wait_states = 7; // Effectively 6 as this is decremented this cycle
self.ready = false;
}
if *cycles == 0 {
Expand Down Expand Up @@ -338,7 +337,7 @@ impl Cpu {
TCycle::T2 => TCycle::T3,
TCycle::T3 => {
// If no wait states have been reported, advance to T3, otherwise go to Tw
if self.wait_states == 0 {
if self.wait_states == 0 && self.dma_wait_states == 0 {
self.biu_bus_end();
TCycle::T4
}
Expand All @@ -349,7 +348,7 @@ impl Cpu {
TCycle::Tw => {
// If we are handling wait states, continue in Tw (decrement at end of cycle)
// If we have handled all wait states, transition to T4
if self.wait_states > 0 {
if self.wait_states > 0 || self.dma_wait_states > 0 {
//log::debug!("wait states: {}", self.wait_states);
TCycle::Tw
}
Expand All @@ -369,51 +368,25 @@ impl Cpu {
self.biu_tick_prefetcher();

match self.fetch_state {
FetchState::Scheduled(1) => {
//trace_print!(self, "fetch decision: {}", self.queue.len());
if (self.queue.len() == 3 && self.queue_op == QueueOp::Idle)
|| (self.queue.len() == 2 && self.queue_op != QueueOp::Idle)
{
if self.bus_status == BusStatus::CodeFetch {
//trace_print!(self, "fetch delay here?");
}
}
}
FetchState::Scheduled(0) => {
FetchState::ScheduleNext | FetchState::Scheduled(0) => {
// A fetch is scheduled for this cycle; however we may have additional delays to process.

// If bus_pending_eu is true, then we arrived here during biu_bus_begin.
// That means that we biu_bus_begin will process a fetch abort.
// In that case, we should do nothing instead of transitioning to a new fetch state.
if !self.bus_pending_eu {

// Check if we are entering Delayed fetch states, but the queue is full.
if !self.biu_queue_has_room() && matches!(self.next_fetch_state, FetchState::Delayed(_)) {

if self.bus_pending_eu {
// Don't stall the BIU if there is pending bus request from the EU - we are likely
// in bus_begin() and will process an abort instead.
self.trace_comment("SHOULD ABORT!");
if let BusStatus::Passive = self.bus_status {

// Begin a fetch if we are not transitioning into any delay state, otherwise transition
// into said state.
if self.next_fetch_state == FetchState::InProgress {
self.begin_fetch();
}
else {
//self.biu_abort_fetch_full();
self.fetch_state = self.next_fetch_state;
}
}
else if self.last_queue_delay == QueueDelay::Read && !self.fetch_suspended {
// Sc2 delay

//self.next_fetch_state = FetchState::Delayed(2);
//self.trace_comment("DELAY2");
}

// Begin a fetch if we are not transitioning into any delay state, otherwise transition
// into said state.
if self.next_fetch_state == FetchState::InProgress {
self.begin_fetch();
}
else {
self.fetch_state = self.next_fetch_state;
}
}
}
FetchState::DelayDone => {
Expand Down Expand Up @@ -451,6 +424,7 @@ impl Cpu {

self.cycle_num += 1;
self.wait_states = self.wait_states.saturating_sub(1);
self.dma_wait_states = self.dma_wait_states.saturating_sub(1);

/*
// Try to catch a runaway instruction?
Expand Down
8 changes: 5 additions & 3 deletions core/src/cpu_808x/mod.rs
Expand Up @@ -758,6 +758,7 @@ pub struct Cpu
dram_refresh_cycle_num: u32,
dram_refresh_adjust: u32,
dma_aen: bool,
dma_wait_states: u32,

// Trap stuff
trap_enable_delay: u32, // Number of cycles to delay trap flag enablement.
Expand Down Expand Up @@ -964,9 +965,10 @@ pub enum FetchState {
Suspended,
InProgress,
Scheduled(u8),
ScheduleNext,
Delayed(u8),
DelayDone,
Aborted(u8),
Aborting(u8),
BlockedByEU
}

Expand Down Expand Up @@ -1168,7 +1170,7 @@ impl Cpu {
pub fn is_last_wait(&self) -> bool {
match self.t_cycle {
TCycle::T3 | TCycle::Tw => {
if self.wait_states == 0 {
if self.wait_states == 0 && self.dma_wait_states == 0 {
true
}
else {
Expand All @@ -1184,7 +1186,7 @@ impl Cpu {
match self.t_cycle {
TCycle::T1 | TCycle::T2 => true,
TCycle::T3 | TCycle::Tw => {
if self.wait_states != 0 {
if self.wait_states > 0 || self.dma_wait_states > 0 {
true
}
else {
Expand Down

0 comments on commit 2b5d14b

Please sign in to comment.