fix: address latching timing and cleanup debug code

This commit is contained in:
Jan-Peter von Hunnius 2026-02-25 11:55:16 +01:00
parent aae374b713
commit 1cf2cd6e2b
6 changed files with 1102 additions and 265 deletions

View file

@ -204,6 +204,10 @@ pub trait Intel400xAddressHandling {
/// Handle address nibble latching during address phase
/// Returns: (high_nibble, low_nibble, address_ready)
///
/// After the full address is latched (both nibbles received), the nibbles
/// are cleared to prepare for the next address cycle. The full address
/// should be assembled and stored before calling this function returns.
fn handle_address_latching(
&self,
nibble: u8,
@ -217,10 +221,16 @@ pub trait Intel400xAddressHandling {
// First cycle: latch high nibble (bits 7-4)
*address_high_nibble = Some(nibble);
} else if address_low_nibble.is_none() {
// Second cycle: latch low nibble (bits 3-0) and transition to latency wait
// Second cycle: latch low nibble (bits 3-0)
*address_low_nibble = Some(nibble);
// Mark address as ready and record latch time
*full_address_ready = true;
*address_latch_time = Some(Instant::now());
// Clear nibbles after full address is latched to prepare for next cycle
// The full address should be assembled from the nibbles before this returns
// (e.g., by the caller reading the nibble values before they're cleared)
*address_high_nibble = None;
*address_low_nibble = None;
}
}
@ -909,16 +919,17 @@ impl Intel400xStateMachine {
}
/// Handle address nibble latching
/// Returns true only when BOTH nibbles have been latched (address complete)
pub fn handle_address_nibble(&mut self, nibble: u8) -> bool {
if self.address_high_nibble.is_none() {
// First cycle: latch high nibble (bits 7-4)
self.address_high_nibble = Some(nibble);
true
false // Address not complete yet - still need low nibble
} else if self.address_low_nibble.is_none() {
// Second cycle: latch low nibble (bits 3-0) and transition to latency wait
self.address_low_nibble = Some(nibble);
self.address_latch_time = Some(Instant::now());
true // Address complete
true // Address complete - both nibbles latched
} else {
// Address already latched, ignore
false
@ -1381,13 +1392,15 @@ mod tests {
Duration::from_nanos(500),
);
// First nibble should latch high nibble
assert!(sm.handle_address_nibble(0xA));
// First nibble should latch high nibble but NOT complete the address
// Returns false because we still need the low nibble
assert!(!sm.handle_address_nibble(0xA));
assert_eq!(sm.get_address_high_nibble(), Some(0xA));
assert_eq!(sm.get_address_low_nibble(), None);
assert!(!sm.is_full_address_ready());
// Second nibble should latch low nibble and complete address
// Returns true because address is now complete
assert!(sm.handle_address_nibble(0x5));
assert_eq!(sm.get_address_high_nibble(), Some(0xA));
assert_eq!(sm.get_address_low_nibble(), Some(0x5));