removes sccache
updates display of ben eater pc doesnt blow up when creating a rom chip anymore doesnt blow up when creating a pc anymore
This commit is contained in:
parent
d89fc1cd2b
commit
e5c2319803
@ -1,5 +1,2 @@
|
||||
[alias]
|
||||
coverage = "tarpaulin --out Html --skip-clean --output-dir coverage"
|
||||
|
||||
[build]
|
||||
rustc-wrapper = "sccache"
|
||||
|
||||
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -75,9 +75,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "beneater"
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
// This is the GUI for the BenEater PC
|
||||
use beneater::parts::cpu_display::CpuDisplay;
|
||||
use macroquad::prelude::*;
|
||||
use macroquad::telemetry::frame;
|
||||
use beneater::parts::ben_eater_pc::BenEaterPC;
|
||||
use beneater::parts::display_matrix::DisplayMatrix;
|
||||
|
||||
|
||||
#[macroquad::main("Ben Eaters PC")]
|
||||
async fn main() {
|
||||
@ -7,10 +12,32 @@ async fn main() {
|
||||
|
||||
let computer = BenEaterPC::new();
|
||||
|
||||
|
||||
let mut dm = DisplayMatrix::new(200.0, 50.0);
|
||||
let message_to_show = "Taxation is theft";
|
||||
let mut message_index = 0;
|
||||
|
||||
dm.push_letter('T');
|
||||
let mut frame_number: u32 = 0x00;
|
||||
|
||||
loop {
|
||||
clear_background(BLUE);
|
||||
|
||||
draw_text("Ben Eater", 20.0, 20.0, 30.0, BLACK);
|
||||
dm.render(20.0, 40.0);
|
||||
CpuDisplay::render(&computer.cpu, 20.0, 120.0);
|
||||
|
||||
frame_number += 1;
|
||||
|
||||
if frame_number.is_multiple_of(60) {
|
||||
dm.push_letter('X');
|
||||
}
|
||||
|
||||
if frame_number.is_multiple_of(60 * 6) {
|
||||
dm.clear_display()
|
||||
}
|
||||
|
||||
next_frame().await
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
9
beneater/src/parts/address_bus.rs
Normal file
9
beneater/src/parts/address_bus.rs
Normal file
@ -0,0 +1,9 @@
|
||||
pub struct AddressBus {
|
||||
pub address: u16
|
||||
}
|
||||
|
||||
impl AddressBus {
|
||||
pub fn new() -> Self {
|
||||
AddressBus { address: 0x0000 }
|
||||
}
|
||||
}
|
||||
@ -1,13 +1,17 @@
|
||||
use crate::parts::clock::Clock;
|
||||
use core::mos6502cpu::Mos6502Cpu;
|
||||
|
||||
struct BenEaterPC {
|
||||
pub struct BenEaterPC {
|
||||
clock: Clock,
|
||||
cpu: Mos6502Cpu,
|
||||
// pub because i am rendering it.
|
||||
// there should be a proper interface to get the data
|
||||
// for ui out of this.
|
||||
pub cpu: Mos6502Cpu,
|
||||
}
|
||||
|
||||
impl BenEaterPC {
|
||||
pub fn new() -> Self {
|
||||
println!("New BENEATERPC");
|
||||
BenEaterPC {
|
||||
clock: Clock::new(),
|
||||
cpu: Mos6502Cpu::default()
|
||||
|
||||
28
beneater/src/parts/cpu_display.rs
Normal file
28
beneater/src/parts/cpu_display.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use macroquad::color::{BLACK, Color};
|
||||
use macroquad::prelude::*;
|
||||
use macroquad::text::draw_text;
|
||||
use core::mos6502cpu::Mos6502Cpu;
|
||||
|
||||
pub struct CpuDisplay {}
|
||||
impl CpuDisplay {
|
||||
pub fn render(cpu: &Mos6502Cpu, x_offset: f32, y_offset: f32) {
|
||||
// get the data to display...
|
||||
let (pc, a, x, y, address_bus, data_bus) = cpu.dump_data();
|
||||
|
||||
// ...build the interface
|
||||
Self::draw_square(x_offset, y_offset, x_offset + 300.0, y_offset + 85.0, BLACK);
|
||||
|
||||
draw_text(format!("PC: 0x{:04x} / {}", pc, pc).as_str(), x_offset + 5.0, y_offset + 18.0, 15.0, BLACK);
|
||||
draw_text(format!("A: 0x{:02x} X: 0x{:02x} Y: 0x{:02x}", a, x, y).as_str(), x_offset + 5.0, y_offset + 35.0, 15.0, BLACK);
|
||||
draw_text(format!("Address: {:016b} | {:04x}", address_bus, address_bus).as_str(), x_offset + 5.0, y_offset + 55.0, 15.0, BLACK);
|
||||
draw_text(format!("Data: {:08b} | {:02x}", data_bus, data_bus).as_str(), x_offset + 5.0, y_offset + 75.0, 15.0, BLACK);
|
||||
}
|
||||
|
||||
fn draw_square(x1: f32, y1: f32, x2: f32, y2: f32, color: Color) {
|
||||
// println!("Square from {x1:2.0}x{y1:2.0} to {x2:2.0}x{y2:2.0} with {:?}", color);
|
||||
draw_line(x1, y1, x2, y1, 1.0, color);
|
||||
draw_line(x1, y1, x1, y2, 1.0, color);
|
||||
draw_line(x1, y2, x2, y2, 1.0, color);
|
||||
draw_line(x2, y1, x2, y2, 1.0, color);
|
||||
}
|
||||
}
|
||||
9
beneater/src/parts/data_bus.rs
Normal file
9
beneater/src/parts/data_bus.rs
Normal file
@ -0,0 +1,9 @@
|
||||
pub struct DataBus {
|
||||
pub data: u8
|
||||
}
|
||||
|
||||
impl DataBus {
|
||||
pub fn new() -> Self {
|
||||
DataBus { data: 0x00 }
|
||||
}
|
||||
}
|
||||
79
beneater/src/parts/display_matrix.rs
Normal file
79
beneater/src/parts/display_matrix.rs
Normal file
@ -0,0 +1,79 @@
|
||||
use macroquad::prelude::*;
|
||||
use crate::parts::address_bus::AddressBus;
|
||||
use crate::parts::data_bus::DataBus;
|
||||
|
||||
pub struct DisplayMatrix {
|
||||
width: f32,
|
||||
height: f32,
|
||||
text_buffer: String,
|
||||
data_bus: DataBus,
|
||||
rs: bool,
|
||||
rw: bool,
|
||||
cursor_position: u8
|
||||
}
|
||||
|
||||
impl DisplayMatrix {
|
||||
pub fn new(width: f32, height: f32) -> DisplayMatrix {
|
||||
DisplayMatrix {
|
||||
width,
|
||||
height,
|
||||
text_buffer: String::from(""),
|
||||
data_bus: DataBus::new(),
|
||||
rs: false,
|
||||
rw: false,
|
||||
cursor_position: 0x00
|
||||
}
|
||||
}
|
||||
|
||||
/// Tick
|
||||
///
|
||||
/// Checks the data bus and sees what the setup is.
|
||||
///
|
||||
/// 0 0 0 0 0 0 0 1 -> Clear Display
|
||||
/// 0 0 0 0 0 0 1 - -> Return Home
|
||||
/// 0 0 0 0 0 0 A B -> Sets cursor move direction and shift
|
||||
/// A -> 0 = Insert, 1 = Delete
|
||||
/// B -> Scroll bool
|
||||
/// 0 0 0 0 1 D C B -> Sets display mode
|
||||
/// D -> Display On/Off
|
||||
/// C -> Cursor On/Off
|
||||
/// B -> Blink
|
||||
pub fn tick(&mut self) {
|
||||
// parse whats on the data bus.
|
||||
|
||||
}
|
||||
|
||||
pub fn set_busses(&mut self, address_bus: &mut AddressBus, data_bus: &mut DataBus) {
|
||||
|
||||
}
|
||||
|
||||
pub fn push_letter(&mut self, letter_to_push: char) {
|
||||
self.cursor_position += 1;
|
||||
self.text_buffer.push(letter_to_push)
|
||||
}
|
||||
|
||||
pub fn clear_display(&mut self) {
|
||||
self.cursor_position = 0;
|
||||
self.text_buffer.clear()
|
||||
}
|
||||
|
||||
pub fn render(&self, x_offset: f32, y_offset: f32) {
|
||||
DisplayMatrix::draw_square(x_offset,
|
||||
y_offset,
|
||||
x_offset + self.width ,
|
||||
y_offset + self.height,
|
||||
BLACK);
|
||||
|
||||
let mut tmp = self.text_buffer.clone();
|
||||
tmp.push('#');
|
||||
draw_text(&*tmp, x_offset + 5.0, y_offset + 20.0, 20.0, BLACK);
|
||||
}
|
||||
|
||||
fn draw_square(x1: f32, y1: f32, x2: f32, y2: f32, color: Color) {
|
||||
// println!("Square from {x1:2.0}x{y1:2.0} to {x2:2.0}x{y2:2.0} with {:?}", color);
|
||||
draw_line(x1, y1, x2, y1, 1.0, color);
|
||||
draw_line(x1, y1, x1, y2, 1.0, color);
|
||||
draw_line(x1, y2, x2, y2, 1.0, color);
|
||||
draw_line(x2, y1, x2, y2, 1.0, color);
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,8 @@
|
||||
pub mod clock;
|
||||
mod ben_eater_pc;
|
||||
mod via6522;
|
||||
pub mod ben_eater_pc;
|
||||
pub mod via6522;
|
||||
pub mod display_matrix;
|
||||
pub mod address_bus;
|
||||
pub mod data_bus;
|
||||
pub mod cpu_display;
|
||||
mod ram_display;
|
||||
|
||||
20
beneater/src/parts/ram_display.rs
Normal file
20
beneater/src/parts/ram_display.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use macroquad::prelude::*;
|
||||
|
||||
pub struct RamDisplay {}
|
||||
|
||||
impl RamDisplay {
|
||||
pub fn render(ram: &Box<[u8]>, x_offset: f32, y_offset: f32) {
|
||||
Self::draw_square(x_offset, y_offset, x_offset + 200.0, y_offset + 300.0, BLACK);
|
||||
|
||||
draw_text("RAM", x_offset + 5.0, y_offset + 5.0, 15.0, BLACK);
|
||||
|
||||
}
|
||||
|
||||
fn draw_square(x1: f32, y1: f32, x2: f32, y2: f32, color: Color) {
|
||||
// println!("Square from {x1:2.0}x{y1:2.0} to {x2:2.0}x{y2:2.0} with {:?}", color);
|
||||
draw_line(x1, y1, x2, y1, 1.0, color);
|
||||
draw_line(x1, y1, x1, y2, 1.0, color);
|
||||
draw_line(x1, y2, x2, y2, 1.0, color);
|
||||
draw_line(x2, y1, x2, y2, 1.0, color);
|
||||
}
|
||||
}
|
||||
@ -19,12 +19,12 @@ impl Via6522 {
|
||||
|
||||
}
|
||||
|
||||
// check for output pins and see what they say
|
||||
/// check for output pins and see what they say
|
||||
pub fn update_pins(&mut self) {
|
||||
|
||||
}
|
||||
|
||||
// check for input mode pins and see what they say
|
||||
/// check for input mode pins and see what they say
|
||||
pub fn read_pins(&self) {
|
||||
|
||||
}
|
||||
|
||||
@ -5,7 +5,8 @@ pub const SIZE_32KB: usize = SIZE_1KB * 32;
|
||||
pub const SIZE_64KB: usize = SIZE_1KB * 64;
|
||||
|
||||
pub struct Mos6502Cpu {
|
||||
memory: [u8; SIZE_64KB],
|
||||
// this is public for rendering quickly.
|
||||
pub memory: Box<[u8]>,
|
||||
a: u8,
|
||||
x: u8,
|
||||
y: u8,
|
||||
@ -13,20 +14,24 @@ pub struct Mos6502Cpu {
|
||||
pc: u16,
|
||||
s: u8,
|
||||
pub microcode_step: u8,
|
||||
address_bus: u16,
|
||||
data_bus: u8,
|
||||
pub address_bus: u16,
|
||||
pub data_bus: u8,
|
||||
ir: u8 // Instruction Register
|
||||
}
|
||||
|
||||
impl Default for Mos6502Cpu {
|
||||
fn default() -> Self {
|
||||
let vec = vec![0x00; SIZE_64KB];
|
||||
let boxed_slize: Box<[u8]> = vec.into_boxed_slice();
|
||||
let boxed_array: Box<[u8; SIZE_64KB]> = boxed_slize.try_into().expect("Failed to allocate system memory");
|
||||
|
||||
Mos6502Cpu {
|
||||
memory: [0x00; SIZE_64KB],
|
||||
memory: boxed_array,
|
||||
a: 0,
|
||||
x: 0,
|
||||
y: 0,
|
||||
flags: Default::default(),
|
||||
pc: 0,
|
||||
pc: 0xfffd,
|
||||
s: 0,
|
||||
microcode_step: 0,
|
||||
address_bus: 0,
|
||||
@ -38,8 +43,11 @@ impl Default for Mos6502Cpu {
|
||||
|
||||
impl Mos6502Cpu {
|
||||
pub fn new() -> Mos6502Cpu {
|
||||
let vec = vec![0x00; SIZE_64KB];
|
||||
let boxed_slize: Box<[u8]> = vec.into_boxed_slice();
|
||||
let boxed_array: Box<[u8; SIZE_64KB]> = boxed_slize.try_into().expect("Failed to allocate system memory");
|
||||
Mos6502Cpu {
|
||||
memory: [0; SIZE_64KB],
|
||||
memory: boxed_array,
|
||||
a: 0,
|
||||
x: 0,
|
||||
y: 0,
|
||||
@ -103,5 +111,7 @@ impl Mos6502Cpu {
|
||||
self.pc, self.a, self.x, self.y, self.address_bus, self.data_bus);
|
||||
}
|
||||
|
||||
|
||||
pub fn dump_data(&self) -> ( u16, u8, u8, u8, u16, u8) {
|
||||
(self.pc, self.a, self.x, self.y, self.address_bus, self.data_bus)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::mos6502cpu::SIZE_32KB;
|
||||
use crate::mos6502cpu::{SIZE_32KB, SIZE_64KB};
|
||||
use crate::periph::rom_chip::RomChip;
|
||||
|
||||
/// At28C256
|
||||
@ -8,24 +8,37 @@ use crate::periph::rom_chip::RomChip;
|
||||
/// 256kbit storage
|
||||
/// 32kbyte storage
|
||||
pub struct At28C256 {
|
||||
data: [u8; SIZE_32KB]
|
||||
data: Box<[u8; SIZE_32KB]>,
|
||||
}
|
||||
|
||||
impl Default for At28C256 {
|
||||
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("Failed to convert Vec to boxed array");
|
||||
At28C256 {
|
||||
data: boxed_array,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RomChip for At28C256 {
|
||||
|
||||
fn read(&self, offset: &u16) -> u8 {
|
||||
self.data[*offset as usize]
|
||||
}
|
||||
|
||||
fn program(new_data: &[u8; SIZE_32KB]) -> Self {
|
||||
fn program(new_data: Box<[u8; 33554432]>) -> Box<At28C256> {
|
||||
println!("Writing new chip.");
|
||||
At28C256 {
|
||||
data: *new_data
|
||||
}
|
||||
let mut working = At28C256::default();
|
||||
working.data = Box::new(*new_data);
|
||||
working.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::mos6502cpu::SIZE_1KB;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
@ -36,16 +49,18 @@ mod test {
|
||||
#[test]
|
||||
fn programmed_data_reads_back_same() {
|
||||
print!("Starting test...");
|
||||
let data_to_write = [0xea; SIZE_32KB];
|
||||
let mut data = At28C256::default();
|
||||
for i in 0..SIZE_32KB {
|
||||
data.data[i] = 0xea;
|
||||
}
|
||||
print!("allocated data for rom...");
|
||||
let chip: At28C256 = At28C256::program(&data_to_write);
|
||||
println!("programmed chip...");
|
||||
print!("testing");
|
||||
for offset in 0..SIZE_32KB {
|
||||
if offset.is_multiple_of(1000) {
|
||||
if offset.is_multiple_of(SIZE_1KB) {
|
||||
print!(".");
|
||||
};
|
||||
assert_eq!(0xea, chip.read(&(offset as u16)));
|
||||
assert_eq!(0xea, data.read(&(offset as u16)));
|
||||
}
|
||||
println!("passed!");
|
||||
}
|
||||
|
||||
@ -8,10 +8,9 @@ pub trait RomChip {
|
||||
/// Program
|
||||
///
|
||||
/// Replaces all data in the ROM chip
|
||||
fn program(new_data: &[u8; SIZE_32KB]) -> 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