Fix Intel 4004 CPU instruction set and improve MCS-4 timing accuracy
Overhaul the Intel 4004 instruction set to match the real opcode map, adding missing instructions (NOP, FIM, FIN, JIN, ISZ, KBP, DCL, WR0-3, RD0-3) and refining two-byte instruction handling with proper M1/M2 data phases. Rewrite the CPU fetch-execute cycle to correctly process two-byte opcodes across separate clock cycles. Improve Intel 4001 ROM timing with M1/M2 nibble phase tracking and an A3 wait counter so the ROM drives data only when the CPU expects it. Fix state-machine transition helpers in Intel 4002 and 4003 to capture the old state before processing events, preventing incorrect exit/entry callbacks. Add non-propagating pin driver methods to prevent deadlocks caused by bidirectional pin connections during signal propagation. Add Fibonacci integration test and opcode fix plan document. Update all README files to reflect the new instruction set.
This commit is contained in:
parent
54144d10e9
commit
6a335a15d4
14 changed files with 4125 additions and 1062 deletions
|
|
@ -453,56 +453,48 @@ impl Intel4003 {
|
|||
|
||||
/// Helper function to process latency elapsed event
|
||||
fn process_latency_elapsed(&mut self) {
|
||||
let old_state = self.state_machine.get_state();
|
||||
let event = Intel400xEvent::LatencyElapsed;
|
||||
// Use process_event_direct method to avoid borrowing conflicts
|
||||
let new_state = process_event_direct(&mut self.state_machine, event);
|
||||
|
||||
// Handle state entry/exit manually
|
||||
if new_state != self.state_machine.get_state() {
|
||||
self.on_state_exit(self.state_machine.get_state());
|
||||
self.state_machine.current_state = new_state;
|
||||
if new_state != old_state {
|
||||
self.on_state_exit(old_state);
|
||||
self.on_state_entry(new_state);
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to process chip select event
|
||||
fn process_chip_select(&mut self) {
|
||||
let old_state = self.state_machine.get_state();
|
||||
let event = Intel400xEvent::ChipSelect;
|
||||
// Use process_event_direct method to avoid borrowing conflicts
|
||||
let new_state = process_event_direct(&mut self.state_machine, event);
|
||||
|
||||
// Handle state entry/exit manually
|
||||
if new_state != self.state_machine.get_state() {
|
||||
self.on_state_exit(self.state_machine.get_state());
|
||||
self.state_machine.current_state = new_state;
|
||||
if new_state != old_state {
|
||||
self.on_state_exit(old_state);
|
||||
self.on_state_entry(new_state);
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to process operation complete event
|
||||
fn process_operation_complete(&mut self) {
|
||||
let old_state = self.state_machine.get_state();
|
||||
let event = Intel400xEvent::OperationComplete;
|
||||
// Use process_event_direct method to avoid borrowing conflicts
|
||||
let new_state = process_event_direct(&mut self.state_machine, event);
|
||||
|
||||
// Handle state entry/exit manually
|
||||
if new_state != self.state_machine.get_state() {
|
||||
self.on_state_exit(self.state_machine.get_state());
|
||||
self.state_machine.current_state = new_state;
|
||||
if new_state != old_state {
|
||||
self.on_state_exit(old_state);
|
||||
self.on_state_entry(new_state);
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to process address complete event
|
||||
fn process_address_complete(&mut self) {
|
||||
let old_state = self.state_machine.get_state();
|
||||
let event = Intel400xEvent::AddressComplete;
|
||||
// Use process_event_direct method to avoid borrowing conflicts
|
||||
let new_state = process_event_direct(&mut self.state_machine, event);
|
||||
|
||||
// Handle state entry/exit manually
|
||||
if new_state != self.state_machine.get_state() {
|
||||
self.on_state_exit(self.state_machine.get_state());
|
||||
self.state_machine.current_state = new_state;
|
||||
if new_state != old_state {
|
||||
self.on_state_exit(old_state);
|
||||
self.on_state_entry(new_state);
|
||||
}
|
||||
}
|
||||
|
|
@ -576,13 +568,11 @@ impl Component for Intel4003 {
|
|||
|
||||
// Process all events
|
||||
for event in events {
|
||||
// Use the process_event_direct method to avoid borrowing conflicts
|
||||
let old_state = self.state_machine.get_state();
|
||||
let new_state = process_event_direct(&mut self.state_machine, event);
|
||||
|
||||
// Handle state entry/exit manually
|
||||
if new_state != self.state_machine.get_state() {
|
||||
self.on_state_exit(self.state_machine.get_state());
|
||||
self.state_machine.current_state = new_state;
|
||||
if new_state != old_state {
|
||||
self.on_state_exit(old_state);
|
||||
self.on_state_entry(new_state);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue