closer to being able to run a cycle?
This commit is contained in:
parent
0c475127f6
commit
8ed93fc90e
59
Cargo.lock
generated
59
Cargo.lock
generated
@ -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",
|
||||
]
|
||||
|
||||
@ -24,6 +24,8 @@ impl BenEaterPC {
|
||||
// tick the clock.
|
||||
// tick the memory
|
||||
// tick the VIA
|
||||
} else {
|
||||
self.cpu.tick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -3,4 +3,5 @@ name = "core"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
log = "0.4"
|
||||
rand = "0.9.0"
|
||||
@ -1,4 +1,3 @@
|
||||
use std::fmt::{Display};
|
||||
|
||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||
pub enum AddressMode {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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!");
|
||||
}
|
||||
}
|
||||
|
||||
88
core/src/periph/hm62256.rs
Normal file
88
core/src/periph/hm62256.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,6 @@
|
||||
pub mod rom_chip;
|
||||
|
||||
pub mod at28c256;
|
||||
pub mod ram_chip;
|
||||
mod hm62256;
|
||||
|
||||
|
||||
5
core/src/periph/ram_chip.rs
Normal file
5
core/src/periph/ram_chip.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use crate::periph::rom_chip::RomChip;
|
||||
|
||||
pub trait RamChip: RomChip {
|
||||
fn write(&mut self, offset: &u16, value: &u8);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user