feat(cpu): add A1/A2/A3 address cycle timing and fix pin propagation
This commit is contained in:
parent
3cdf99630c
commit
20884b57c3
17 changed files with 4165 additions and 270 deletions
|
|
@ -46,19 +46,19 @@ impl TimingConstants {
|
|||
/// This is the standard access time for ROM and RAM operations
|
||||
/// based on the original Intel 4004 timing specifications.
|
||||
pub const DEFAULT_ACCESS_TIME: Duration = Duration::from_nanos(500); // 500ns default
|
||||
|
||||
|
||||
/// Fast access time for shift register operations (200ns)
|
||||
///
|
||||
/// The Intel 4003 shift register has faster access times compared to
|
||||
/// ROM and RAM components due to its simpler design.
|
||||
pub const FAST_ACCESS_TIME: Duration = Duration::from_nanos(200); // 200ns for shift registers
|
||||
|
||||
|
||||
/// Address setup time before clock edge (100ns)
|
||||
///
|
||||
/// Minimum time that address must be stable before the clock edge
|
||||
/// to ensure proper latching by the component.
|
||||
pub const ADDRESS_SETUP: Duration = Duration::from_nanos(100); // Address setup time
|
||||
|
||||
|
||||
/// Data valid delay after clock edge (200ns)
|
||||
///
|
||||
/// Time from clock edge until data is guaranteed to be valid on the bus
|
||||
|
|
@ -352,19 +352,19 @@ pub enum Intel400xComponentType {
|
|||
/// The 4001 is a 256-byte ROM chip that stores program instructions.
|
||||
/// It responds to address transmission and provides read-only data access.
|
||||
Intel4001,
|
||||
|
||||
|
||||
/// Intel 4002 RAM (Random Access Memory) chip
|
||||
///
|
||||
/// The 4002 is a 320-bit RAM chip organized as four registers of 20 bits each.
|
||||
/// It supports both read and write operations and includes I/O ports.
|
||||
Intel4002,
|
||||
|
||||
|
||||
/// Intel 4003 Shift Register chip
|
||||
///
|
||||
/// The 4003 is a 10-bit static shift register used for I/O expansion.
|
||||
/// It operates differently from memory chips and ignores address transmission.
|
||||
Intel4003,
|
||||
|
||||
|
||||
/// Intel 4004 CPU (Central Processing Unit) chip
|
||||
///
|
||||
/// The 4004 is the 4-bit microprocessor that controls the system.
|
||||
|
|
@ -383,25 +383,24 @@ pub enum Intel400xComponentType {
|
|||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Intel400xUnifiedState {
|
||||
// Common states (shared across all components)
|
||||
|
||||
/// Idle state - component is waiting for operation
|
||||
///
|
||||
/// In this state, the component is not actively processing any operation
|
||||
/// and is waiting for a chip select or other control signal.
|
||||
Idle,
|
||||
|
||||
|
||||
/// Address phase - latching address from CPU
|
||||
///
|
||||
/// The component is receiving address information in two 4-bit phases
|
||||
/// (high nibble first, then low nibble) from the CPU.
|
||||
AddressPhase,
|
||||
|
||||
|
||||
/// Wait latency - waiting for access time to elapse
|
||||
///
|
||||
/// After receiving the complete address, the component waits for the
|
||||
/// required access time before proceeding with the operation.
|
||||
WaitLatency,
|
||||
|
||||
|
||||
/// Drive data - transferring data on the bus
|
||||
///
|
||||
/// The component is actively driving data onto the bus (for read operations)
|
||||
|
|
@ -409,21 +408,20 @@ pub enum Intel400xUnifiedState {
|
|||
DriveData,
|
||||
|
||||
// Component-specific states
|
||||
|
||||
|
||||
// Intel 4002 (RAM) specific states
|
||||
|
||||
/// Read data state - RAM is reading from memory
|
||||
///
|
||||
/// The RAM component is reading data from the specified address and
|
||||
/// preparing to drive it onto the data bus.
|
||||
ReadData,
|
||||
|
||||
|
||||
/// Write data state - RAM is writing to memory
|
||||
///
|
||||
/// The RAM component is accepting data from the bus and writing it
|
||||
/// to the specified memory location.
|
||||
WriteData,
|
||||
|
||||
|
||||
/// Output port state - RAM is driving I/O ports
|
||||
///
|
||||
/// The RAM component is outputting data to its I/O ports rather than
|
||||
|
|
@ -431,13 +429,12 @@ pub enum Intel400xUnifiedState {
|
|||
OutputPort,
|
||||
|
||||
// Intel 4003 (Shift Register) specific states
|
||||
|
||||
/// Shift data state - shifting register contents
|
||||
///
|
||||
/// The 4003 shift register is shifting its contents serially,
|
||||
/// either in or out depending on the operation.
|
||||
ShiftData,
|
||||
|
||||
|
||||
/// Load data state - loading parallel data
|
||||
///
|
||||
/// The 4003 shift register is loading data in parallel format
|
||||
|
|
@ -445,13 +442,12 @@ pub enum Intel400xUnifiedState {
|
|||
LoadData,
|
||||
|
||||
// Intel 4004 (CPU) specific states
|
||||
|
||||
/// Fetch instruction state - CPU is fetching instruction
|
||||
///
|
||||
/// The CPU is fetching the next instruction from memory and
|
||||
/// preparing to decode and execute it.
|
||||
FetchInstruction,
|
||||
|
||||
|
||||
/// Execute instruction state - CPU is executing instruction
|
||||
///
|
||||
/// The CPU is executing the currently fetched instruction and
|
||||
|
|
@ -474,79 +470,79 @@ pub enum Intel400xEvent {
|
|||
/// Generated when the first phase of the two-phase clock transitions
|
||||
/// from low to high. Used for timing control in various operations.
|
||||
ClockPhi1Rising,
|
||||
|
||||
|
||||
/// Φ1 (Phase 1) clock falling edge
|
||||
///
|
||||
/// Generated when the first phase of the two-phase clock transitions
|
||||
/// from high to low. Often triggers address latching operations.
|
||||
ClockPhi1Falling,
|
||||
|
||||
|
||||
/// Φ2 (Phase 2) clock rising edge
|
||||
///
|
||||
/// Generated when the second phase of the two-phase clock transitions
|
||||
/// from low to high. Used for data transfer operations.
|
||||
ClockPhi2Rising,
|
||||
|
||||
|
||||
/// Φ2 (Phase 2) clock falling edge
|
||||
///
|
||||
/// Generated when the second phase of the two-phase clock transitions
|
||||
/// from high to low. Often triggers state transitions.
|
||||
ClockPhi2Falling,
|
||||
|
||||
|
||||
/// SYNC signal becomes active (high)
|
||||
///
|
||||
/// The SYNC signal indicates the start of a new instruction cycle.
|
||||
/// Components use this to synchronize their operations with the CPU.
|
||||
SyncActive,
|
||||
|
||||
|
||||
/// SYNC signal becomes inactive (low)
|
||||
///
|
||||
/// The SYNC signal indicates the end of an instruction cycle.
|
||||
/// Components may use this to reset their internal state.
|
||||
SyncInactive,
|
||||
|
||||
|
||||
/// Chip select becomes active
|
||||
///
|
||||
/// Generated when a component is selected for an operation.
|
||||
/// This typically initiates a transition from Idle to AddressPhase.
|
||||
ChipSelect,
|
||||
|
||||
|
||||
/// Chip select becomes inactive
|
||||
///
|
||||
/// Generated when a component is deselected.
|
||||
/// This typically forces a transition back to the Idle state.
|
||||
ChipDeselect,
|
||||
|
||||
|
||||
/// RESET signal becomes active (high)
|
||||
///
|
||||
/// Generated when the system reset signal is asserted.
|
||||
/// All components transition to their initial state.
|
||||
ResetActive,
|
||||
|
||||
|
||||
/// RESET signal becomes inactive (low)
|
||||
///
|
||||
/// Generated when the system reset signal is released.
|
||||
/// Components begin normal operation from their reset state.
|
||||
ResetInactive,
|
||||
|
||||
|
||||
/// Address latching complete
|
||||
///
|
||||
/// Generated when both high and low address nibbles have been latched.
|
||||
/// Triggers transition from AddressPhase to WaitLatency.
|
||||
AddressComplete,
|
||||
|
||||
|
||||
/// Access latency has elapsed
|
||||
///
|
||||
/// Generated when the required access time has passed after address latching.
|
||||
/// Triggers transition from WaitLatency to operation-specific states.
|
||||
LatencyElapsed,
|
||||
|
||||
|
||||
/// Data is ready for transfer
|
||||
///
|
||||
/// Generated when data is available for reading or writing.
|
||||
/// Used in component-specific data transfer operations.
|
||||
DataReady,
|
||||
|
||||
|
||||
/// Operation is complete
|
||||
///
|
||||
/// Generated when the current operation has finished successfully.
|
||||
|
|
@ -779,22 +775,22 @@ pub trait Intel400xComponentBehavior {
|
|||
pub struct Intel400xStateMachine {
|
||||
/// The type of component this state machine is managing
|
||||
component_type: Intel400xComponentType,
|
||||
|
||||
|
||||
/// The current state of the state machine
|
||||
pub(crate) current_state: Intel400xUnifiedState,
|
||||
|
||||
|
||||
/// The previous state before the last transition
|
||||
previous_state: Intel400xUnifiedState,
|
||||
|
||||
|
||||
/// The high nibble (bits 7-4) of the currently latching address
|
||||
address_high_nibble: Option<u8>,
|
||||
|
||||
|
||||
/// The low nibble (bits 3-0) of the currently latching address
|
||||
address_low_nibble: Option<u8>,
|
||||
|
||||
|
||||
/// The time when the address was completely latched
|
||||
address_latch_time: Option<Instant>,
|
||||
|
||||
|
||||
/// The access time to wait after address latching before data access
|
||||
access_time: Duration,
|
||||
}
|
||||
|
|
@ -1514,7 +1510,7 @@ mod tests {
|
|||
// First need to transition to AddressPhase state
|
||||
process_event_direct(&mut sm, Intel400xEvent::ChipSelect);
|
||||
assert_eq!(sm.get_state(), Intel400xUnifiedState::AddressPhase);
|
||||
|
||||
|
||||
// Now transition to WaitLatency state
|
||||
process_event_direct(&mut sm, Intel400xEvent::AddressComplete);
|
||||
assert_eq!(sm.get_state(), Intel400xUnifiedState::WaitLatency);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue