New implementation with threads per component
This commit is contained in:
parent
ac8ebbafe9
commit
bfbddda58c
15 changed files with 170 additions and 265 deletions
|
|
@ -1,5 +1,6 @@
|
|||
use crate::{PinValue, Component, Pin};
|
||||
use std::sync::Arc;
|
||||
use crate::component::Component;
|
||||
use crate::pin::Pin;
|
||||
use crate::components::cpu::mos_6502::MOS6502;
|
||||
|
||||
pub struct CMOS65C02 {
|
||||
|
|
@ -76,25 +77,17 @@ impl CMOS65C02 {
|
|||
self.waiting
|
||||
}
|
||||
}
|
||||
|
||||
// Implement Component by delegating to the base 6502
|
||||
impl Component for CMOS65C02 {
|
||||
fn name(&self) -> &str {
|
||||
self.base_6502.name()
|
||||
}
|
||||
|
||||
fn pins(&self) -> &std::collections::HashMap<String, Arc<crate::Pin>> {
|
||||
fn pins(&self) -> &std::collections::HashMap<String, Arc<Pin>> {
|
||||
self.base_6502.pins()
|
||||
}
|
||||
|
||||
fn get_pin(&self, name: &str) -> Option<Arc<crate::Pin>> {
|
||||
fn get_pin(&self, name: &str) -> Option<Arc<Pin>> {
|
||||
self.base_6502.get_pin(name)
|
||||
}
|
||||
|
||||
fn connect_pin(&mut self, pin_name: &str, other_pin: Arc<crate::Pin>) -> Result<(), String> {
|
||||
self.base_6502.connect_pin(pin_name, other_pin)
|
||||
}
|
||||
|
||||
fn update(&mut self) -> Result<(), String> {
|
||||
if self.stopped {
|
||||
// Don't execute instructions if stopped
|
||||
|
|
@ -104,11 +97,9 @@ impl Component for CMOS65C02 {
|
|||
// Delegate to base implementation
|
||||
self.base_6502.update()
|
||||
}
|
||||
|
||||
fn run(&mut self) {
|
||||
self.base_6502.run()
|
||||
}
|
||||
|
||||
fn stop(&mut self) {
|
||||
self.base_6502.stop()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{PinValue, Component};
|
||||
use crate::component::Component;
|
||||
use crate::components::cpu::cmos_65c02::CMOS65C02;
|
||||
use crate::components::cpu::mos_6502::{Registers, MOS6502};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,25 +1,23 @@
|
|||
use std::collections::HashMap;
|
||||
use crate::{PinValue, BaseComponent, Component, Pin};
|
||||
use std::sync::Arc;
|
||||
use crate::component::{BaseComponent, Component};
|
||||
use crate::pin::{Pin, PinValue};
|
||||
|
||||
// Simple 4-bit and 12-bit types for the 4004
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct u4(u8);
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct u12(u16);
|
||||
|
||||
impl u4 {
|
||||
fn wrapping_add(self, other: u4) -> u4 {
|
||||
u4((self.0 + other.0) & 0xF)
|
||||
}
|
||||
}
|
||||
|
||||
impl u12 {
|
||||
fn wrapping_add(self, other: u12) -> u12 {
|
||||
u12((self.0 + other.0) & 0xFFF)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Intel4004 {
|
||||
base: BaseComponent,
|
||||
|
|
@ -27,7 +25,6 @@ pub struct Intel4004 {
|
|||
accumulator: u4,
|
||||
last_clock_state: PinValue,
|
||||
}
|
||||
|
||||
impl Intel4004 {
|
||||
pub fn new(name: String) -> Self {
|
||||
let mut base = BaseComponent::new(name);
|
||||
|
|
@ -44,15 +41,12 @@ impl Intel4004 {
|
|||
last_clock_state: PinValue::Low,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clk(&self) -> Option<Arc<Pin>> {
|
||||
self.base.get_pin("clk")
|
||||
}
|
||||
|
||||
pub fn reset(&self) -> Option<Arc<Pin>> {
|
||||
self.base.get_pin("reset")
|
||||
}
|
||||
|
||||
pub fn data(&self) -> Option<Arc<Pin>> {
|
||||
self.base.get_pin("data")
|
||||
}
|
||||
|
|
@ -62,19 +56,12 @@ impl Component for Intel4004 {
|
|||
fn name(&self) -> &str {
|
||||
self.base.name()
|
||||
}
|
||||
|
||||
fn pins(&self) -> &HashMap<String, Arc<Pin>> {
|
||||
self.base.pins()
|
||||
}
|
||||
|
||||
fn get_pin(&self, name: &str) -> Option<Arc<Pin>> {
|
||||
self.base.get_pin(name)
|
||||
}
|
||||
|
||||
fn connect_pin(&mut self, pin_name: &str, other_pin: Arc<Pin>) -> Result<(), String> {
|
||||
self.base.connect_pin(pin_name, other_pin)
|
||||
}
|
||||
|
||||
fn update(&mut self) -> Result<(), String> {
|
||||
// Read clock pin (check if any connected component is driving it low)
|
||||
let clk_pin = self.base.pins.get("clk").unwrap();
|
||||
|
|
@ -103,11 +90,9 @@ impl Component for Intel4004 {
|
|||
self.last_clock_state = clk_value;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run(&mut self) {
|
||||
self.base.run();
|
||||
}
|
||||
|
||||
fn stop(&mut self) {
|
||||
self.base.stop();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
mod cpu_traits;
|
||||
pub(crate) mod intel_4004;
|
||||
pub mod cpu_traits;
|
||||
pub mod intel_4004;
|
||||
mod mos_6502;
|
||||
mod cmos_65c02;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
use crate::{PinValue, BaseComponent, Component, Pin};
|
||||
use std::sync::Arc;
|
||||
use crate::component::{BaseComponent, Component};
|
||||
use crate::pin::{Pin, PinValue};
|
||||
|
||||
// 6502 addressing modes
|
||||
pub enum AddressingMode {
|
||||
|
|
@ -18,7 +19,6 @@ pub enum AddressingMode {
|
|||
Accumulator,
|
||||
Relative,
|
||||
}
|
||||
|
||||
// 6502 registers
|
||||
#[derive(Clone, Default)]
|
||||
pub struct Registers {
|
||||
|
|
@ -29,7 +29,6 @@ pub struct Registers {
|
|||
pub pc: u16, // Program counter
|
||||
pub sr: u8, // Status register
|
||||
}
|
||||
|
||||
// Bit positions in status register
|
||||
pub const CARRY_FLAG: u8 = 1 << 0;
|
||||
pub const ZERO_FLAG: u8 = 1 << 1;
|
||||
|
|
@ -39,7 +38,6 @@ pub const BREAK_COMMAND: u8 = 1 << 4;
|
|||
pub const UNUSED_FLAG: u8 = 1 << 5;
|
||||
pub const OVERFLOW_FLAG: u8 = 1 << 6;
|
||||
pub const NEGATIVE_FLAG: u8 = 1 << 7;
|
||||
|
||||
pub struct MOS6502 {
|
||||
base: BaseComponent,
|
||||
pub(crate) registers: Registers,
|
||||
|
|
@ -47,7 +45,6 @@ pub struct MOS6502 {
|
|||
last_clock_state: PinValue,
|
||||
// Memory interface would be added here
|
||||
}
|
||||
|
||||
impl MOS6502 {
|
||||
pub fn new(name: String) -> Self {
|
||||
let mut base = BaseComponent::new(name);
|
||||
|
|
@ -68,7 +65,6 @@ impl MOS6502 {
|
|||
last_clock_state: PinValue::Low,
|
||||
}
|
||||
}
|
||||
|
||||
// Common 6502 methods that will be inherited
|
||||
pub fn reset(&mut self) {
|
||||
self.registers.pc = 0xFFFC;
|
||||
|
|
@ -76,22 +72,18 @@ impl MOS6502 {
|
|||
self.registers.sr = 0x34; // I flag set, others cleared
|
||||
self.cycle_count = 0;
|
||||
}
|
||||
|
||||
pub fn get_register_a(&self) -> u8 {
|
||||
self.registers.a
|
||||
}
|
||||
|
||||
pub fn set_register_a(&mut self, value: u8) {
|
||||
self.registers.a = value;
|
||||
self.update_zero_negative_flags(value);
|
||||
}
|
||||
|
||||
// Common flag handling
|
||||
pub fn update_zero_negative_flags(&mut self, value: u8) {
|
||||
self.set_flag(ZERO_FLAG, value == 0);
|
||||
self.set_flag(NEGATIVE_FLAG, value & 0x80 != 0);
|
||||
}
|
||||
|
||||
pub fn set_flag(&mut self, flag: u8, condition: bool) {
|
||||
if condition {
|
||||
self.registers.sr |= flag;
|
||||
|
|
@ -113,7 +105,6 @@ impl MOS6502 {
|
|||
self.registers.x = self.registers.a;
|
||||
self.update_zero_negative_flags(self.registers.x);
|
||||
}
|
||||
|
||||
// More common instructions...
|
||||
}
|
||||
|
||||
|
|
@ -121,42 +112,30 @@ impl Component for MOS6502 {
|
|||
fn name(&self) -> &str {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn pins(&self) -> &HashMap<String, Arc<Pin>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_pin(&self, name: &str) -> Option<Arc<Pin>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn connect_pin(&mut self, pin_name: &str, other_pin: Arc<Pin>) -> Result<(), String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
// Implement Component trait methods...
|
||||
fn update(&mut self) -> Result<(), String> {
|
||||
// Clock handling and instruction execution
|
||||
let clk_pin = self.base.pins.get("clk").unwrap();
|
||||
let clk_value = clk_pin.read();
|
||||
|
||||
// Detect rising edge
|
||||
if clk_value == PinValue::High && self.last_clock_state == PinValue::Low {
|
||||
self.cycle_count += 1;
|
||||
// Instruction execution would happen here
|
||||
}
|
||||
|
||||
self.last_clock_state = clk_value;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn stop(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
// Other trait methods...
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue