closer to being able to run a cycle?

This commit is contained in:
Trevor Merritt 2025-06-30 07:17:17 -04:00
parent 0c475127f6
commit 8ed93fc90e
11 changed files with 199 additions and 20 deletions

59
Cargo.lock generated
View File

@ -185,6 +185,7 @@ name = "core"
version = "0.1.0"
dependencies = [
"log",
"rand",
]
[[package]]
@ -474,6 +475,15 @@ dependencies = [
"miniz_oxide",
]
[[package]]
name = "ppv-lite86"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy",
]
[[package]]
name = "pretty_env_logger"
version = "0.5.0"
@ -514,6 +524,35 @@ version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "rand"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
dependencies = [
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom",
]
[[package]]
name = "regex"
version = "1.11.1"
@ -823,3 +862,23 @@ checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags 2.9.1",
]
[[package]]
name = "zerocopy"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View File

@ -24,6 +24,8 @@ impl BenEaterPC {
// tick the clock.
// tick the memory
// tick the VIA
} else {
self.cpu.tick();
}
}
}

View File

@ -1,5 +1,12 @@
pub enum Via6522Port {
A(u8),
B(u8)
}
#[derive(Default)]
pub struct Via6522 {
data_bus: u8,
address_bus: u16,
port_a_state: u8,
port_b_data: u8,
port_a_direction: u8,
@ -15,8 +22,15 @@ impl Via6522 {
}
}
pub fn set_a_direction(&mut self, new_direction: u8) {
pub fn set_port_direction(&mut self, port: Via6522Port) {
match port {
Via6522Port::A(x) => {
self.port_a_direction = x;
},
Via6522Port::B(x) => {
self.port_b_direction = x;
}
}
}
/// check for output pins and see what they say

View File

@ -3,4 +3,5 @@ name = "core"
version = "0.1.0"
edition = "2024"
[dependencies]
log = "0.4"
log = "0.4"
rand = "0.9.0"

View File

@ -1,4 +1,3 @@
use std::fmt::{Display};
#[derive(PartialEq, Debug, Copy, Clone)]
pub enum AddressMode {

View File

@ -1,5 +1,9 @@
use crate::address_mode::AddressMode;
use crate::instruction::Instruction;
use crate::mos6502flags::{Mos6502Flag, Mos6502Flags};
use crate::operand::Operand;
use crate::operation::Operation;
use crate::operation::Operation::NOP;
pub const SIZE_1KB: usize = 1024 * 1024;
pub const SIZE_32KB: usize = SIZE_1KB * 32;
@ -17,7 +21,7 @@ pub struct Mos6502Cpu {
pub microcode_step: u8,
pub address_bus: u16,
pub data_bus: u8,
ir: u8 // Instruction Register
ir: Instruction // Instruction Register
}
impl Default for Mos6502Cpu {
@ -37,7 +41,11 @@ impl Default for Mos6502Cpu {
microcode_step: 0,
address_bus: 0,
data_bus: 0,
ir: 0x00
ir: Instruction {
op: Operation::NOP,
mode: AddressMode::Implied,
operand: Operand::None,
}
}
}
}
@ -58,7 +66,11 @@ impl Mos6502Cpu {
microcode_step: 0,
address_bus: 0x0000,
data_bus: 0x00,
ir: 0x00
ir: Instruction {
op: Operation::NOP,
mode: AddressMode::Implied,
operand: Operand::None,
}
}
}
@ -105,13 +117,19 @@ impl Mos6502Cpu {
/// AddressBus, DataBus, RW flag
pub fn tick(&mut self) -> (u16, u8, bool) {
let num_microsteps_left = 0;
println!("PREPARiNG TO TICK CPU AT {:04x}", self.pc);
let mut num_microsteps_left = 0;
if num_microsteps_left == 0 {
println!("OUT OF MICROSTEPS. Time To do something that isnt microstep.");
// load the microstep buffer with what steps to run
// set the counter to the number of steps left
} else {
// run 1 microcode step
println!("Microstep {num_microsteps_left}");
num_microsteps_left -= 1;
}
// run 1 microcode step
(0,0,false)
}

View File

@ -1,4 +1,4 @@
use crate::mos6502cpu::{SIZE_32KB, SIZE_64KB};
use crate::mos6502cpu::{SIZE_32KB};
use crate::periph::rom_chip::RomChip;
/// At28C256
@ -48,20 +48,14 @@ mod test {
#[test]
fn programmed_data_reads_back_same() {
print!("Starting test...");
let mut data = At28C256::default();
for i in 0..SIZE_32KB {
data.data[i] = 0xea;
}
print!("allocated data for rom...");
println!("programmed chip...");
print!("testing");
for offset in 0..SIZE_32KB {
if offset.is_multiple_of(SIZE_1KB) {
print!(".");
};
assert_eq!(0xea, data.read(&(offset as u16)));
}
println!("passed!");
}
}

View File

@ -0,0 +1,88 @@
// HM62256 Static Ram
use log::debug;
use crate::mos6502cpu::SIZE_32KB;
use crate::periph::ram_chip::RamChip;
use crate::periph::rom_chip::RomChip;
struct Hm62256 {
base_offset: u16,
data: Box<[u8]>
}
impl Default for Hm62256 {
fn default() -> Self {
let vec = vec![0x00; SIZE_32KB];
let boxed_slice: Box<[u8]> = vec.into_boxed_slice();
let boxed_array: Box<[u8; SIZE_32KB]> = boxed_slice.try_into().expect("Unable to box the ram");
Hm62256 {
base_offset: 0x0000,
data: boxed_array
}
}
}
impl RomChip for Hm62256 {
fn read(&self, offset: &u16) -> u8 {
//println!("READING FROM RAM AT [{offset:04x}]");
self.data[*offset as usize]
}
fn program(_: Box<[u8; SIZE_32KB]>) -> Box<Self> {
debug!("Dont program ram.");
Hm62256::default().into()
}
}
impl RamChip for Hm62256 {
fn write(&mut self, offset: &u16, value: &u8) {
let effective = *offset as i32 % SIZE_32KB as i32;
println!("Writing at E[{effective:04x}] / O[{offset:04x}]");
self.data[effective as usize] = *value;
}
}
#[cfg(test)]
mod test {
use rand::random;
use super::*;
#[test]
fn smoke() { assert!(true) }
#[test]
fn written_data_comes_back() {
let mut ram = Hm62256::default();
// 100,000 random read/writes to ram that all read back right
for _ in 0..100_000 {
let mut offset: u16 = random();
println!("SIze = {SIZE_32KB}");
let value: u8 =random();
println!("Wrote [{value:02x}] to [{offset:04x}]");
ram.write(&offset, &value);
assert_eq!(ram.read(&offset), value)
}
}
#[test]
fn address_space_is_round() {
// addresses written past the last address 'loop' back to 0+(offset - MAX_SIZE)
let max_offset = SIZE_32KB;
let test_offset = max_offset;
// all zero
let mut ram = Hm62256::default();
// write FF to the addresss after the last
ram.write(&(test_offset as u16), &0xff);
// check all the ram for anything that isn't 0x00
assert_eq!(ram.read(&(0x0000)), 0xff);
for offset in 1..SIZE_32KB {
println!("Testing offset {offset:04x} for 0x00");
assert_eq!(ram.read(&(offset as u16)), 0x00);
}
}
}

View File

@ -1,3 +1,6 @@
pub mod rom_chip;
pub mod at28c256;
pub mod ram_chip;
mod hm62256;

View File

@ -0,0 +1,5 @@
use crate::periph::rom_chip::RomChip;
pub trait RamChip: RomChip {
fn write(&mut self, offset: &u16, value: &u8);
}

View File

@ -10,7 +10,3 @@ pub trait RomChip {
/// Replaces all data in the ROM chip
fn program(new_data: Box<[u8; SIZE_32KB]>) -> Box<Self>;
}
pub trait RamChip: RomChip {
fn write(&mut self, offset: &u16, value: &u8);
}