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"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
|
"rand",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -474,6 +475,15 @@ dependencies = [
|
|||||||
"miniz_oxide",
|
"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]]
|
[[package]]
|
||||||
name = "pretty_env_logger"
|
name = "pretty_env_logger"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -514,6 +524,35 @@ version = "5.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
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]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
@ -823,3 +862,23 @@ checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.1",
|
"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 clock.
|
||||||
// tick the memory
|
// tick the memory
|
||||||
// tick the VIA
|
// tick the VIA
|
||||||
|
} else {
|
||||||
|
self.cpu.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,12 @@
|
|||||||
|
pub enum Via6522Port {
|
||||||
|
A(u8),
|
||||||
|
B(u8)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Via6522 {
|
pub struct Via6522 {
|
||||||
|
data_bus: u8,
|
||||||
|
address_bus: u16,
|
||||||
port_a_state: u8,
|
port_a_state: u8,
|
||||||
port_b_data: u8,
|
port_b_data: u8,
|
||||||
port_a_direction: 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
|
/// check for output pins and see what they say
|
||||||
|
|||||||
@ -4,3 +4,4 @@ version = "0.1.0"
|
|||||||
edition = "2024"
|
edition = "2024"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
rand = "0.9.0"
|
||||||
@ -1,4 +1,3 @@
|
|||||||
use std::fmt::{Display};
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||||
pub enum AddressMode {
|
pub enum AddressMode {
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
|
use crate::address_mode::AddressMode;
|
||||||
use crate::instruction::Instruction;
|
use crate::instruction::Instruction;
|
||||||
use crate::mos6502flags::{Mos6502Flag, Mos6502Flags};
|
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_1KB: usize = 1024 * 1024;
|
||||||
pub const SIZE_32KB: usize = SIZE_1KB * 32;
|
pub const SIZE_32KB: usize = SIZE_1KB * 32;
|
||||||
@ -17,7 +21,7 @@ pub struct Mos6502Cpu {
|
|||||||
pub microcode_step: u8,
|
pub microcode_step: u8,
|
||||||
pub address_bus: u16,
|
pub address_bus: u16,
|
||||||
pub data_bus: u8,
|
pub data_bus: u8,
|
||||||
ir: u8 // Instruction Register
|
ir: Instruction // Instruction Register
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Mos6502Cpu {
|
impl Default for Mos6502Cpu {
|
||||||
@ -37,7 +41,11 @@ impl Default for Mos6502Cpu {
|
|||||||
microcode_step: 0,
|
microcode_step: 0,
|
||||||
address_bus: 0,
|
address_bus: 0,
|
||||||
data_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,
|
microcode_step: 0,
|
||||||
address_bus: 0x0000,
|
address_bus: 0x0000,
|
||||||
data_bus: 0x00,
|
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
|
/// AddressBus, DataBus, RW flag
|
||||||
pub fn tick(&mut self) -> (u16, u8, bool) {
|
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 {
|
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
|
// load the microstep buffer with what steps to run
|
||||||
// set the counter to the number of steps left
|
// set the counter to the number of steps left
|
||||||
}
|
} else {
|
||||||
// run 1 microcode step
|
// run 1 microcode step
|
||||||
|
println!("Microstep {num_microsteps_left}");
|
||||||
|
num_microsteps_left -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
(0,0,false)
|
(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;
|
use crate::periph::rom_chip::RomChip;
|
||||||
|
|
||||||
/// At28C256
|
/// At28C256
|
||||||
@ -48,20 +48,14 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn programmed_data_reads_back_same() {
|
fn programmed_data_reads_back_same() {
|
||||||
print!("Starting test...");
|
|
||||||
let mut data = At28C256::default();
|
let mut data = At28C256::default();
|
||||||
for i in 0..SIZE_32KB {
|
for i in 0..SIZE_32KB {
|
||||||
data.data[i] = 0xea;
|
data.data[i] = 0xea;
|
||||||
}
|
}
|
||||||
print!("allocated data for rom...");
|
|
||||||
println!("programmed chip...");
|
|
||||||
print!("testing");
|
|
||||||
for offset in 0..SIZE_32KB {
|
for offset in 0..SIZE_32KB {
|
||||||
if offset.is_multiple_of(SIZE_1KB) {
|
if offset.is_multiple_of(SIZE_1KB) {
|
||||||
print!(".");
|
|
||||||
};
|
};
|
||||||
assert_eq!(0xea, data.read(&(offset as u16)));
|
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 rom_chip;
|
||||||
|
|
||||||
pub mod at28c256;
|
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
|
/// Replaces all data in the ROM chip
|
||||||
fn program(new_data: Box<[u8; SIZE_32KB]>) -> Box<Self>;
|
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