Compare commits
2 Commits
f9c938757f
...
1a53f1d782
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a53f1d782 | |||
| 9b9462c98c |
@ -4,8 +4,6 @@ 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() {
|
||||
println!("Taxation is Theft");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pub const SIZE_1KB: usize = 1024 * 1024;
|
||||
pub const SIZE_1KB: usize = 1024;
|
||||
pub const SIZE_32KB: usize = SIZE_1KB * 32;
|
||||
pub const SIZE_64KB: usize = SIZE_1KB * 64;
|
||||
|
||||
|
||||
@ -42,7 +42,6 @@ impl Instruction {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::address_mode::AddressMode::*;
|
||||
|
||||
@ -102,6 +102,7 @@ impl Mos6502Cpu {
|
||||
// read the value at 0xfffe 0xffff for our int vector
|
||||
self.pc = self.read_word(&OFFSET_RESET_VECTOR);
|
||||
self.iv = self.read_word(&OFFSET_INT_VECTOR);
|
||||
println!("PC and IV are now set from ROM addresses");
|
||||
}
|
||||
|
||||
fn read_word(&self, offset: &u16) -> u16 {
|
||||
@ -137,6 +138,7 @@ impl Mos6502Cpu {
|
||||
}
|
||||
|
||||
pub fn poke_x(&mut self, new_x: u8) {
|
||||
println!("Updating register X from [{}] to [{}]", self.x, new_x);
|
||||
self.x = new_x
|
||||
}
|
||||
|
||||
@ -174,7 +176,7 @@ impl Mos6502Cpu {
|
||||
// set the counter to the number of steps left
|
||||
} else {
|
||||
// run 1 microcode step
|
||||
println!("Microstep {}", self.microcode_step);
|
||||
println!("Microstep {} for {:?}", self.microcode_step, self.ir.op);
|
||||
match self.ir.op {
|
||||
Operation::ADC => {
|
||||
}
|
||||
@ -207,19 +209,32 @@ impl Mos6502Cpu {
|
||||
Operation::CPY => {}
|
||||
Operation::DEC => {}
|
||||
Operation::DEX => {
|
||||
(self.x, _) = self.x.overflowing_sub(1) ;
|
||||
if self.microcode_step == 1 {
|
||||
let (new_x, new_carry) = self.x.overflowing_sub(1);
|
||||
self.poke_x(new_x);
|
||||
self.poke_flag(Carry, new_carry);
|
||||
}
|
||||
}
|
||||
Operation::DEY => {
|
||||
if self.microcode_step == 1 {
|
||||
(self.y, _) = self.y.overflowing_sub(1);
|
||||
}
|
||||
}
|
||||
Operation::EOR => { }
|
||||
Operation::INC => { }
|
||||
Operation::INX => {
|
||||
self.x += 1;
|
||||
if self.microcode_step == 1 {
|
||||
let (new_x, new_carry) = self.x.overflowing_add(1);
|
||||
self.poke_x(new_x);
|
||||
self.poke_flag(Carry, new_carry);
|
||||
}
|
||||
}
|
||||
Operation::INY => {
|
||||
self.y += 1;
|
||||
}
|
||||
if self.microcode_step == 1 {
|
||||
let (new_y, new_carry) = self.y.overflowing_add(1);
|
||||
self.poke_y(new_y);
|
||||
self.poke_flag(Carry, new_carry);
|
||||
} }
|
||||
Operation::JMP => {
|
||||
match self.ir.operand {
|
||||
Operand::Word(offset) => {
|
||||
@ -274,12 +289,16 @@ impl Mos6502Cpu {
|
||||
Operation::PLA => {}
|
||||
Operation::PLP => {}
|
||||
Operation::ROL => {
|
||||
if self.microcode_step == 1 {
|
||||
self.a = self.a.rotate_left(1);
|
||||
}
|
||||
}
|
||||
Operation::ROR => {
|
||||
// rotate A
|
||||
if self.microcode_step == 1 {
|
||||
self.a = self.a.rotate_right(1);
|
||||
}
|
||||
}
|
||||
Operation::RTI => {}
|
||||
Operation::RTS => {}
|
||||
Operation::SBC => {}
|
||||
@ -470,14 +489,44 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dex() {
|
||||
fn dex_inx() {
|
||||
let mut cpu = Mos6502Cpu::default();
|
||||
cpu.a = 0xab;
|
||||
cpu.x = 0xab;
|
||||
cpu.memory[0x6000] = ISA_OP_DEX;
|
||||
cpu.memory[0x6001] = ISA_OP_INX;
|
||||
cpu.pc = 0x6000;
|
||||
|
||||
for _ in 0..INSTRUCTION_TABLE[ISA_OP_DEX as usize].unwrap().cycles { cpu.tick(); }
|
||||
for _ in 0..=INSTRUCTION_TABLE[ISA_OP_DEX as usize].unwrap().cycles { cpu.tick(); }
|
||||
assert_eq!(0xaa, cpu.x);
|
||||
for _ in 0..=INSTRUCTION_TABLE[ISA_OP_INX as usize].unwrap().cycles { cpu.tick(); }
|
||||
assert_eq!(0xab, cpu.x);
|
||||
}
|
||||
|
||||
assert_eq!(0xaa, cpu.a);
|
||||
#[test]
|
||||
fn dey_iny() {
|
||||
let mut cpu = Mos6502Cpu::default();
|
||||
cpu.poke_y(0xab);
|
||||
cpu.memory[0x6000] = ISA_OP_DEY;
|
||||
cpu.memory[0x6001] = ISA_OP_INY;
|
||||
cpu.pc = 0x6000;
|
||||
|
||||
for _ in 0..=INSTRUCTION_TABLE[ISA_OP_DEY as usize].unwrap().cycles { cpu.tick(); }
|
||||
assert_eq!(0xaa, cpu.peek_y());
|
||||
for _ in 0..=INSTRUCTION_TABLE[ISA_OP_INY as usize].unwrap().cycles { cpu.tick(); }
|
||||
assert_eq!(0xab, cpu.peek_y());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rol_a_ror_a() {
|
||||
let mut cpu = Mos6502Cpu::default();
|
||||
cpu.poke_a(0b1010_1010); // 0xaa
|
||||
cpu.memory[0x6000] = ISA_OP_ROL_A;
|
||||
cpu.memory[0x6001] = ISA_OP_ROR_A;
|
||||
cpu.pc = 0x6000;
|
||||
|
||||
for _ in 0..=INSTRUCTION_TABLE[ISA_OP_ROL_A as usize].unwrap().cycles { cpu.tick(); }
|
||||
assert_eq!(cpu.peek_a(), 0b0101_0101);
|
||||
for _ in 0..=INSTRUCTION_TABLE[ISA_OP_ROR_A as usize].unwrap().cycles { cpu.tick(); }
|
||||
assert_eq!(cpu.peek_a(), 0b1010_1010);
|
||||
}
|
||||
}
|
||||
22
core/src/periph/at28c256/default.rs
Normal file
22
core/src/periph/at28c256/default.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::constants::constants_system::SIZE_32KB;
|
||||
use crate::periph::at28c256::At28C256;
|
||||
use crate::periph::hm62256::Hm62256;
|
||||
|
||||
impl Default for At28C256 {
|
||||
fn default() -> Self {
|
||||
let vec = vec![0xea; 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn smoke() { assert!(true); }
|
||||
}
|
||||
@ -1,3 +1,6 @@
|
||||
mod default;
|
||||
mod rom_chip;
|
||||
|
||||
use crate::constants::constants_system::SIZE_32KB;
|
||||
use crate::periph::rom_chip::RomChip;
|
||||
|
||||
@ -11,31 +14,6 @@ pub struct At28C256 {
|
||||
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: Box<[u8; 33554432]>) -> Box<At28C256> {
|
||||
println!("Writing new chip.");
|
||||
let mut working = At28C256::default();
|
||||
working.data = Box::new(*new_data);
|
||||
working.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::constants::constants_system::SIZE_1KB;
|
||||
27
core/src/periph/at28c256/rom_chip.rs
Normal file
27
core/src/periph/at28c256/rom_chip.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use crate::constants::constants_system::SIZE_32KB;
|
||||
use crate::periph::at28c256::At28C256;
|
||||
use crate::periph::rom_chip::RomChip;
|
||||
|
||||
impl RomChip for At28C256 {
|
||||
|
||||
fn read(&self, offset: &u16) -> u8 {
|
||||
self.data[*offset as usize]
|
||||
}
|
||||
|
||||
fn program(new_data: Box<[u8; SIZE_32KB]>) -> Box<At28C256> {
|
||||
println!("Writing new chip.");
|
||||
let mut working = At28C256::default();
|
||||
working.data = Box::new(*new_data);
|
||||
working.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn smoke() { assert!(true); }
|
||||
|
||||
|
||||
}
|
||||
@ -5,9 +5,9 @@ use crate::constants::constants_system::SIZE_32KB;
|
||||
use crate::periph::ram_chip::RamChip;
|
||||
use crate::periph::rom_chip::RomChip;
|
||||
|
||||
struct Hm62256 {
|
||||
base_offset: u16,
|
||||
data: Box<[u8]>
|
||||
pub struct Hm62256 {
|
||||
pub(crate) base_offset: u16,
|
||||
pub(crate) data: Box<[u8]>
|
||||
}
|
||||
|
||||
impl Default for Hm62256 {
|
||||
@ -24,8 +24,9 @@ impl Default for Hm62256 {
|
||||
|
||||
impl RomChip for Hm62256 {
|
||||
fn read(&self, offset: &u16) -> u8 {
|
||||
//println!("READING FROM RAM AT [{offset:04x}]");
|
||||
self.data[*offset as usize]
|
||||
// loops memory around past 32k
|
||||
let effective = *offset as i32 % SIZE_32KB as i32;
|
||||
self.data[effective as usize]
|
||||
}
|
||||
|
||||
fn program(_: Box<[u8; SIZE_32KB]>) -> Box<Self> {
|
||||
|
||||
@ -2,5 +2,5 @@ pub mod rom_chip;
|
||||
|
||||
pub mod at28c256;
|
||||
pub mod ram_chip;
|
||||
mod hm62256;
|
||||
pub mod hm62256;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user