Skip to content

Commit

Permalink
partial rewrite to use Option<NonZeroU8> to represent excess cycles
Browse files Browse the repository at this point in the history
  • Loading branch information
imagine-hussain committed Apr 30, 2024
1 parent be66916 commit ab2a99f
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 104 deletions.
39 changes: 23 additions & 16 deletions src/lib/cpu/addressing.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::num::NonZeroU8;

use crate::Cpu;

/// Functionality related to addressing modes.
Expand Down Expand Up @@ -59,7 +61,12 @@ pub enum AddressingMode {
}

impl AddressingMode {
pub fn fetch(&self) -> fn(&mut Cpu) -> u8 {
/// Uses the given addressing mode to fetch data from the Cpu.
/// # Returns
/// A tuple of the
/// - fetched data
/// - An option of any additional cycles incurred
pub fn fetch(&self) -> fn(&mut Cpu) -> (u8, Option<NonZeroU8>) {
match *self {
AddressingMode::IMP => fetching::fetch_imp,
AddressingMode::IMM => fetching::fetch_imm,
Expand All @@ -77,50 +84,50 @@ impl AddressingMode {
}
}

mod fetching {
mod fetching {
use crate::Cpu;
use std::num::NonZeroU8;

pub(super) fn fetch_imp(cpu: &mut Cpu) -> u8 {
cpu.fetched_data = cpu.registers.a;
0
pub(super) fn fetch_imp(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) {
(cpu.registers.a, None)
}

pub(super) fn fetch_imm(cpu: &mut Cpu) -> u8 {
pub(super) fn fetch_imm(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) {
cpu.absolute_addr += 1;
0

Check failure on line 97 in src/lib/cpu/addressing.rs

View workflow job for this annotation

GitHub Actions / clippy

mismatched types

error[E0308]: mismatched types --> src/lib/cpu/addressing.rs:97:9 | 95 | pub(super) fn fetch_imm(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) { | ----------------------- expected `(u8, std::option::Option<std::num::NonZero<u8>>)` because of return type 96 | cpu.absolute_addr += 1; 97 | 0 | ^ expected `(u8, Option<NonZero<u8>>)`, found integer | = note: expected tuple `(u8, std::option::Option<std::num::NonZero<u8>>)` found type `{integer}`
}

pub(super) fn fetch_zp0(cpu: &mut Cpu) -> u8 {
pub(super) fn fetch_zp0(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) {
let offset = cpu.read(cpu.registers.pc);

cpu.absolute_addr = offset as u16;

0

Check failure on line 105 in src/lib/cpu/addressing.rs

View workflow job for this annotation

GitHub Actions / clippy

mismatched types

error[E0308]: mismatched types --> src/lib/cpu/addressing.rs:105:9 | 100 | pub(super) fn fetch_zp0(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) { | ----------------------- expected `(u8, std::option::Option<std::num::NonZero<u8>>)` because of return type ... 105 | 0 | ^ expected `(u8, Option<NonZero<u8>>)`, found integer | = note: expected tuple `(u8, std::option::Option<std::num::NonZero<u8>>)` found type `{integer}`
}

pub(super) fn fetch_zpx(cpu: &mut Cpu) -> u8 {
pub(super) fn fetch_zpx(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) {
let offset = cpu.read(cpu.registers.pc) + cpu.registers.x;
cpu.absolute_addr = (offset as u16) & 0x00FF;
cpu.registers.pc += 1;
0

Check failure on line 112 in src/lib/cpu/addressing.rs

View workflow job for this annotation

GitHub Actions / clippy

mismatched types

error[E0308]: mismatched types --> src/lib/cpu/addressing.rs:112:9 | 108 | pub(super) fn fetch_zpx(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) { | ----------------------- expected `(u8, std::option::Option<std::num::NonZero<u8>>)` because of return type ... 112 | 0 | ^ expected `(u8, Option<NonZero<u8>>)`, found integer | = note: expected tuple `(u8, std::option::Option<std::num::NonZero<u8>>)` found type `{integer}`
}

pub(super) fn fetch_zpy(cpu: &mut Cpu) -> u8 {
pub(super) fn fetch_zpy(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) {
let offset = cpu.read(cpu.registers.pc) + cpu.registers.y;
cpu.absolute_addr = (offset as u16) & 0x00FF;
cpu.registers.pc += 1;
0

Check failure on line 119 in src/lib/cpu/addressing.rs

View workflow job for this annotation

GitHub Actions / clippy

mismatched types

error[E0308]: mismatched types --> src/lib/cpu/addressing.rs:119:9 | 115 | pub(super) fn fetch_zpy(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) { | ----------------------- expected `(u8, std::option::Option<std::num::NonZero<u8>>)` because of return type ... 119 | 0 | ^ expected `(u8, Option<NonZero<u8>>)`, found integer | = note: expected tuple `(u8, std::option::Option<std::num::NonZero<u8>>)` found type `{integer}`
}

pub(super) fn fetch_rel(cpu: &mut Cpu) -> u8 {
pub(super) fn fetch_rel(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) {
// TODO: check impl when signed
cpu.relative_addr = cpu.read(cpu.registers.pc) as i8;
cpu.registers.pc += 1;

0

Check failure on line 127 in src/lib/cpu/addressing.rs

View workflow job for this annotation

GitHub Actions / clippy

mismatched types

error[E0308]: mismatched types --> src/lib/cpu/addressing.rs:127:9 | 122 | pub(super) fn fetch_rel(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) { | ----------------------- expected `(u8, std::option::Option<std::num::NonZero<u8>>)` because of return type ... 127 | 0 | ^ expected `(u8, Option<NonZero<u8>>)`, found integer | = note: expected tuple `(u8, std::option::Option<std::num::NonZero<u8>>)` found type `{integer}`
}

pub(super) fn fetch_abs(cpu: &mut Cpu) -> u8 {
pub(super) fn fetch_abs(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) {
let lo = cpu.read(cpu.registers.pc);
cpu.registers.pc += 1;
let hi = cpu.read(cpu.registers.pc);
Expand All @@ -131,7 +138,7 @@ impl AddressingMode {
0

Check failure on line 138 in src/lib/cpu/addressing.rs

View workflow job for this annotation

GitHub Actions / clippy

mismatched types

error[E0308]: mismatched types --> src/lib/cpu/addressing.rs:138:9 | 130 | pub(super) fn fetch_abs(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) { | ----------------------- expected `(u8, std::option::Option<std::num::NonZero<u8>>)` because of return type ... 138 | 0 | ^ expected `(u8, Option<NonZero<u8>>)`, found integer | = note: expected tuple `(u8, std::option::Option<std::num::NonZero<u8>>)` found type `{integer}`
}

pub(super) fn fetch_abx(cpu: &mut Cpu) -> u8 {
pub(super) fn fetch_abx(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) {
let lo = cpu.read(cpu.registers.pc);
cpu.registers.pc += 1;
let hi = cpu.read(cpu.registers.pc);
Expand All @@ -146,7 +153,7 @@ impl AddressingMode {
}
}

pub(super) fn fetch_aby(cpu: &mut Cpu) -> u8 {
pub(super) fn fetch_aby(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) {
let lo = cpu.read(cpu.registers.pc);
cpu.registers.pc += 1;
let hi = cpu.read(cpu.registers.pc);
Expand All @@ -159,7 +166,7 @@ impl AddressingMode {
((cpu.absolute_addr & 0xFF00) != ((hi as u16) << 8)).into()

Check failure on line 166 in src/lib/cpu/addressing.rs

View workflow job for this annotation

GitHub Actions / clippy

the trait bound `(u8, std::option::Option<std::num::NonZero<u8>>): std::convert::From<bool>` is not satisfied

error[E0277]: the trait bound `(u8, std::option::Option<std::num::NonZero<u8>>): std::convert::From<bool>` is not satisfied --> src/lib/cpu/addressing.rs:166:62 | 166 | ((cpu.absolute_addr & 0xFF00) != ((hi as u16) << 8)).into() | ^^^^ the trait `std::convert::From<bool>` is not implemented for `(u8, std::option::Option<std::num::NonZero<u8>>)`, which is required by `bool: std::convert::Into<_>` | = help: the following other types implement trait `std::convert::From<T>`: <(T, T) as std::convert::From<[T; 2]>> <(T, T, T) as std::convert::From<[T; 3]>> <(T, T, T, T) as std::convert::From<[T; 4]>> <(T, T, T, T, T) as std::convert::From<[T; 5]>> <(T, T, T, T, T, T) as std::convert::From<[T; 6]>> <(T, T, T, T, T, T, T) as std::convert::From<[T; 7]>> <(T, T, T, T, T, T, T, T) as std::convert::From<[T; 8]>> <(T, T, T, T, T, T, T, T, T) as std::convert::From<[T; 9]>> and 15 others = note: required for `bool` to implement `std::convert::Into<(u8, std::option::Option<std::num::NonZero<u8>>)>`
}

pub(super) fn fetch_ind(cpu: &mut Cpu) -> u8 {
pub(super) fn fetch_ind(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) {
let lo = cpu.read(cpu.registers.pc);
cpu.registers.pc += 1;
let hi = cpu.read(cpu.registers.pc);
Expand All @@ -179,7 +186,7 @@ impl AddressingMode {
0

Check failure on line 186 in src/lib/cpu/addressing.rs

View workflow job for this annotation

GitHub Actions / clippy

mismatched types

error[E0308]: mismatched types --> src/lib/cpu/addressing.rs:186:9 | 169 | pub(super) fn fetch_ind(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) { | ----------------------- expected `(u8, std::option::Option<std::num::NonZero<u8>>)` because of return type ... 186 | 0 | ^ expected `(u8, Option<NonZero<u8>>)`, found integer | = note: expected tuple `(u8, std::option::Option<std::num::NonZero<u8>>)` found type `{integer}`
}

pub(super) fn fetch_izx(cpu: &mut Cpu) -> u8 {
pub(super) fn fetch_izx(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) {
let offset: u16 = (cpu.read(cpu.registers.pc) + cpu.registers.x) as u16;
cpu.registers.pc += 1;

Expand All @@ -192,7 +199,7 @@ impl AddressingMode {
0

Check failure on line 199 in src/lib/cpu/addressing.rs

View workflow job for this annotation

GitHub Actions / clippy

mismatched types

error[E0308]: mismatched types --> src/lib/cpu/addressing.rs:199:9 | 189 | pub(super) fn fetch_izx(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) { | ----------------------- expected `(u8, std::option::Option<std::num::NonZero<u8>>)` because of return type ... 199 | 0 | ^ expected `(u8, Option<NonZero<u8>>)`, found integer | = note: expected tuple `(u8, std::option::Option<std::num::NonZero<u8>>)` found type `{integer}`
}

pub(super) fn fetch_izy(cpu: &mut Cpu) -> u8 {
pub(super) fn fetch_izy(cpu: &mut Cpu) -> (u8, Option<NonZeroU8>) {
let offset: u16 = cpu.read(cpu.registers.pc) as u16;
cpu.registers.pc += 1;

Expand Down
24 changes: 13 additions & 11 deletions src/lib/cpu/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use crate::{
};
use std::{cell::RefCell, rc::Rc};

use super::addressing;

Check warning on line 12 in src/lib/cpu/cpu.rs

View workflow job for this annotation

GitHub Actions / clippy

unused import: `super::addressing`

warning: unused import: `super::addressing` --> src/lib/cpu/cpu.rs:12:5 | 12 | use super::addressing; | ^^^^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default

/// Emulator for the `6502` CPU.
///
/// DataSheet:
Expand Down Expand Up @@ -53,11 +55,11 @@ pub struct Cpu {
///
/// Not "real" parts of the hardware but for emulation
pub fetched_data: u8, // Fetched data - temp storage
pub absolute_addr: u16, // Absolute address being read off
pub relative_addr: i8, // Address relative to abs address
pub addressing_mode: AddressingMode, // Addressing mode
pub additional_cycle_addrmode: u8, // Additional cycles for addressing mode
pub additional_cycle_operation: u8, // Additional cycles for operation
pub absolute_addr: u16, // Absolute address being read off
pub relative_addr: i8, // Address relative to abs address
// pub addressing_mode: AddressingMode, // Addressing mode
pub additional_cycle_addrmode: u8, // Additional cycles for addressing mode
pub additional_cycle_operation: u8, // Additional cycles for operation
}

impl Cpu {
Expand All @@ -84,7 +86,7 @@ impl Cpu {
fetched_data: 0,
absolute_addr: 0,
relative_addr: 0,
addressing_mode: AddressingMode::IMP,
// addressing_mode: AddressingMode::IMP,
additional_cycle_addrmode: 0,
additional_cycle_operation: 0,
}));
Expand Down Expand Up @@ -129,12 +131,12 @@ impl Cpu {
self.clock.set_cycles(opcode.cycles as u64);

// Addressing Mode Lookup for `absolute_addr` or `relative_addr`
self.addressing_mode = opcode.addressing_mode;
// self.addressing_mode = opcode.addressing_mode;
// FIXME: Not sure if this is going to break things by doing a pre-emptive
// fetch of the data, since the operation_fn also fetches.
// PC may move out of sync.
// Might want to do this in the actual addressing mode functions.
self.additional_cycle_addrmode = self.addressing_mode.fetch()(self);
// self.additional_cycle_addrmode = self.addressing_mode.fetch()(self);

// Do the operation
self.additional_cycle_operation = opcode.code_type.executable()(self);

Check failure on line 142 in src/lib/cpu/cpu.rs

View workflow job for this annotation

GitHub Actions / clippy

this function takes 2 arguments but 1 argument was supplied

error[E0061]: this function takes 2 arguments but 1 argument was supplied --> src/lib/cpu/cpu.rs:142:43 | 142 | self.additional_cycle_operation = opcode.code_type.executable()(self); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------ an argument of type `cpu::addressing::AddressingMode` is missing | help: provide the argument | 142 | self.additional_cycle_operation = opcode.code_type.executable()(self, /* cpu::addressing::AddressingMode */); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -149,9 +151,9 @@ impl Cpu {

/// Fetch based on the current addressing mode. Stored in `self.fetched_data`
/// Also returns the fetched_data
pub fn fetch(&mut self) -> u8 {
pub fn fetch(&mut self, addressing_mode: AddressingMode) -> u8 {
// todo: special case for imp
self.addressing_mode.fetch()(self);
addressing_mode.fetch()(self);
self.fetched_data
}

Expand Down Expand Up @@ -270,7 +272,7 @@ impl Reset for Cpu {

self.additional_cycle_addrmode = 0;
self.additional_cycle_operation = 0;
self.addressing_mode = AddressingMode::IMP;
// self.addressing_mode = AddressingMode::IMP;
self.absolute_addr = 0;
self.fetched_data = 0;

Expand Down
6 changes: 4 additions & 2 deletions src/lib/opcodes/opcode_types.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::Cpu;
use std::{num::NonZeroU8, ops::Add};

Check warning on line 1 in src/lib/opcodes/opcode_types.rs

View workflow job for this annotation

GitHub Actions / clippy

unused imports: `num::NonZeroU8`, `ops::Add`

warning: unused imports: `num::NonZeroU8`, `ops::Add` --> src/lib/opcodes/opcode_types.rs:1:11 | 1 | use std::{num::NonZeroU8, ops::Add}; | ^^^^^^^^^^^^^^ ^^^^^^^^

use crate::{cpu::AddressingMode, Cpu};

#[allow(clippy::upper_case_acronyms)]
#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -64,7 +66,7 @@ pub enum OpCodeType {
}

impl OpCodeType {
pub fn executable(&self) -> fn(&mut Cpu) -> u8 {
pub fn executable(&self) -> fn(&mut Cpu, AddressingMode) -> u8 {
use self::OpCodeType::*;
use super::operations::*;

Expand Down
Loading

0 comments on commit ab2a99f

Please sign in to comment.