Fix all compilation errors
This commit is contained in:
parent
223fb6f55d
commit
dd3b198fd5
@ -2,14 +2,14 @@ use crate::cpu::op::AddressingMode::*;
|
|||||||
use crate::cpu::op::{AddressingMode, Instruction};
|
use crate::cpu::op::{AddressingMode, Instruction};
|
||||||
use crate::cpu::Cpu;
|
use crate::cpu::Cpu;
|
||||||
|
|
||||||
impl Cpu<'_> {
|
impl Cpu {
|
||||||
pub fn disassemble_next_instr(&self) {
|
pub fn disassemble_next_instr(&self) {
|
||||||
let registers = self.registers;
|
let registers = self.registers;
|
||||||
let op_code = self.memory_bus.get_byte(registers.pc);
|
let op_code = self.memory_bus.borrow().get_byte(registers.pc) as usize;
|
||||||
|
|
||||||
let instr: Instruction = Self::INSTRUCTIONS[op_code];
|
let instr: Instruction = Self::INSTRUCTIONS[op_code];
|
||||||
let operation = instr.op().to_string();
|
let operation = instr.op().to_string();
|
||||||
let addr_mode = self.disassemble_addr_mode(instr.addr_mode());
|
let addr_mode = self.disassemble_addr_mode(instr.addr_mode(), registers.pc);
|
||||||
|
|
||||||
dbg!(
|
dbg!(
|
||||||
"DIS {:#04x} - {:#02x} {:?} {:?} - A {:#02x}, X {:#02x}, Y {:#02x}, SP: {:#02x}, F: {:#02x}",
|
"DIS {:#04x} - {:#02x} {:?} {:?} - A {:#02x}, X {:#02x}, Y {:#02x}, SP: {:#02x}, F: {:#02x}",
|
||||||
@ -26,7 +26,7 @@ impl Cpu<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn disassemble_addr_mode(&self, addr_mode: AddressingMode, pc: u16) -> String {
|
fn disassemble_addr_mode(&self, addr_mode: AddressingMode, pc: u16) -> String {
|
||||||
let word_peek = self.memory_bus.get_word(pc);
|
let word_peek = self.memory_bus.borrow().get_word(pc);
|
||||||
let byte_peek = (word_peek & 0xFF) as u8;
|
let byte_peek = (word_peek & 0xFF) as u8;
|
||||||
|
|
||||||
match addr_mode {
|
match addr_mode {
|
||||||
|
@ -2,6 +2,7 @@ mod disassembler;
|
|||||||
mod op;
|
mod op;
|
||||||
mod operations;
|
mod operations;
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
use crate::memory::MemoryBus;
|
use crate::memory::MemoryBus;
|
||||||
use crate::Clock;
|
use crate::Clock;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
@ -9,18 +10,18 @@ use bitflags::bitflags;
|
|||||||
const STACK_ADDR: u16 = 0x0100;
|
const STACK_ADDR: u16 = 0x0100;
|
||||||
|
|
||||||
/// Represents a 6502 CPU
|
/// Represents a 6502 CPU
|
||||||
struct Cpu<'a> {
|
pub struct Cpu {
|
||||||
/// The registers of the CPU
|
/// The registers of the CPU
|
||||||
registers: CpuRegisters,
|
registers: CpuRegisters,
|
||||||
|
|
||||||
/// The memory bus accessible by the CPU
|
/// The memory bus accessible by the CPU
|
||||||
memory_bus: &'a MemoryBus,
|
memory_bus: RefCell<MemoryBus>,
|
||||||
|
|
||||||
/// The number of cycles ran on the CPU
|
/// The number of cycles ran on the CPU
|
||||||
cycle: u32,
|
cycle: usize,
|
||||||
|
|
||||||
/// The amount of cycles the CPU will be busy for (won't execute any instruction)
|
/// The amount of cycles the CPU will be busy for (won't execute any instruction)
|
||||||
busy_cycle_count: u16,
|
busy_cycle_count: usize,
|
||||||
|
|
||||||
/// Whether an OAM DMA was triggered (data transfer to the PPU OAM memory)
|
/// Whether an OAM DMA was triggered (data transfer to the PPU OAM memory)
|
||||||
oam_dma_triggered: bool,
|
oam_dma_triggered: bool,
|
||||||
@ -131,8 +132,8 @@ pub trait CpuInternals {
|
|||||||
fn stack_pop_context(&mut self);
|
fn stack_pop_context(&mut self);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Cpu<'a> {
|
impl Cpu {
|
||||||
pub fn new(memory_bus: &mut MemoryBus) -> Self {
|
pub fn new(memory_bus: RefCell<MemoryBus>) -> Self {
|
||||||
Cpu {
|
Cpu {
|
||||||
registers: CpuRegisters {
|
registers: CpuRegisters {
|
||||||
pc: 0x8000,
|
pc: 0x8000,
|
||||||
@ -151,9 +152,9 @@ impl<'a> Cpu<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CpuInternals for Cpu<'_> {
|
impl CpuInternals for Cpu {
|
||||||
fn get_status_flag(&self, flag: CpuStatus) -> bool {
|
fn get_status_flag(&self, flag: CpuStatus) -> bool {
|
||||||
*self.registers.status & flag
|
self.registers.status & flag.bits() > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_status_flag_u8(&self, flag: CpuStatus) -> u8 {
|
fn get_status_flag_u8(&self, flag: CpuStatus) -> u8 {
|
||||||
@ -166,14 +167,14 @@ impl CpuInternals for Cpu<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn program_get_next_byte(&mut self) -> u8 {
|
fn program_get_next_byte(&mut self) -> u8 {
|
||||||
let byte = self.memory_bus.get_byte(self.registers.pc);
|
let byte = self.memory_bus.borrow().get_byte(self.registers.pc);
|
||||||
self.registers.pc += 1;
|
self.registers.pc += 1;
|
||||||
|
|
||||||
byte
|
byte
|
||||||
}
|
}
|
||||||
|
|
||||||
fn program_get_next_word(&mut self) -> u16 {
|
fn program_get_next_word(&mut self) -> u16 {
|
||||||
let word = self.memory_bus.get_word(self.registers.pc);
|
let word = self.memory_bus.borrow().get_word(self.registers.pc);
|
||||||
self.registers.pc += 2;
|
self.registers.pc += 2;
|
||||||
|
|
||||||
word
|
word
|
||||||
@ -181,9 +182,9 @@ impl CpuInternals for Cpu<'_> {
|
|||||||
|
|
||||||
fn set_status_flag(&mut self, flag: CpuStatus, set: bool) {
|
fn set_status_flag(&mut self, flag: CpuStatus, set: bool) {
|
||||||
if set {
|
if set {
|
||||||
*self.registers.status |= flag;
|
self.registers.status |= flag.bits();
|
||||||
} else {
|
} else {
|
||||||
*self.registers.status &= !flag;
|
self.registers.status &= !flag.bits();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +197,7 @@ impl CpuInternals for Cpu<'_> {
|
|||||||
assert!(self.registers.sp > 0);
|
assert!(self.registers.sp > 0);
|
||||||
|
|
||||||
let addr = STACK_ADDR | self.registers.sp as u16;
|
let addr = STACK_ADDR | self.registers.sp as u16;
|
||||||
self.memory_bus.set_byte(addr, value);
|
self.memory_bus.borrow_mut().set_byte(addr, value);
|
||||||
self.registers.sp -= 1;
|
self.registers.sp -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +212,7 @@ impl CpuInternals for Cpu<'_> {
|
|||||||
self.registers.sp += 1;
|
self.registers.sp += 1;
|
||||||
let addr = STACK_ADDR | self.registers.sp as u16;
|
let addr = STACK_ADDR | self.registers.sp as u16;
|
||||||
|
|
||||||
self.memory_bus.get_byte(addr)
|
self.memory_bus.borrow().get_byte(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stack_pop_word(&mut self) -> u16 {
|
fn stack_pop_word(&mut self) -> u16 {
|
||||||
@ -240,7 +241,7 @@ impl CpuInternals for Cpu<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clock for Cpu<'_> {
|
impl Clock for Cpu {
|
||||||
fn cycle(&mut self) {
|
fn cycle(&mut self) {
|
||||||
self.cycle += 1;
|
self.cycle += 1;
|
||||||
|
|
||||||
@ -252,7 +253,7 @@ impl Clock for Cpu<'_> {
|
|||||||
self.disassemble_next_instr();
|
self.disassemble_next_instr();
|
||||||
|
|
||||||
let op_code = self.program_get_next_byte();
|
let op_code = self.program_get_next_byte();
|
||||||
let instr = Self::INSTRUCTIONS[op_code];
|
let instr = Self::INSTRUCTIONS[op_code as usize];
|
||||||
|
|
||||||
self.busy_cycle_count = instr.cycles();
|
self.busy_cycle_count = instr.cycles();
|
||||||
self.exec_instruction(instr);
|
self.exec_instruction(instr);
|
||||||
|
@ -31,13 +31,10 @@ use OperationType::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// CPU Instruction.
|
/// CPU Instruction.
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct Instruction(u8, AddressingMode, OperationType, usize);
|
pub struct Instruction(u8, AddressingMode, OperationType, usize);
|
||||||
|
|
||||||
impl Instruction {
|
impl Instruction {
|
||||||
pub const fn opcode(&self) -> u8 {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn addr_mode(&self) -> AddressingMode {
|
pub const fn addr_mode(&self) -> AddressingMode {
|
||||||
self.1
|
self.1
|
||||||
}
|
}
|
||||||
@ -69,7 +66,7 @@ impl Operand {
|
|||||||
self.value as u8
|
self.value as u8
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn is_address(&self) -> bool {
|
pub fn is_address(&self) -> bool {
|
||||||
self.operand_type == OperandType::Address
|
self.operand_type == OperandType::Address
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +76,7 @@ impl Operand {
|
|||||||
OperandType::Immediate => self.value_u8(),
|
OperandType::Immediate => self.value_u8(),
|
||||||
OperandType::Address => {
|
OperandType::Address => {
|
||||||
let addr = self.value;
|
let addr = self.value;
|
||||||
cpu.memory_bus.get_byte(addr)
|
cpu.memory_bus.borrow().get_byte(addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,7 +86,7 @@ impl Operand {
|
|||||||
OperandType::Accumulator => cpu.registers.a = value,
|
OperandType::Accumulator => cpu.registers.a = value,
|
||||||
OperandType::Address => {
|
OperandType::Address => {
|
||||||
let addr = self.value;
|
let addr = self.value;
|
||||||
cpu.memory_bus.set_byte(addr, value);
|
cpu.memory_bus.borrow_mut().set_byte(addr, value);
|
||||||
}
|
}
|
||||||
OperandType::Immediate => unreachable!("Cannot write to immediate operand"),
|
OperandType::Immediate => unreachable!("Cannot write to immediate operand"),
|
||||||
}
|
}
|
||||||
@ -97,7 +94,7 @@ impl Operand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Operands
|
// Operands
|
||||||
impl Cpu<'_> {
|
impl Cpu {
|
||||||
/// 16x16 grid of 6502 opcodes. Matches datasheet matrix for easy lookup
|
/// 16x16 grid of 6502 opcodes. Matches datasheet matrix for easy lookup
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub const INSTRUCTIONS: [Instruction; 256] = [
|
pub const INSTRUCTIONS: [Instruction; 256] = [
|
||||||
@ -119,13 +116,6 @@ impl Cpu<'_> {
|
|||||||
Instruction(0xF0, REL, BEQ, 2), Instruction(0xF1, IDY, SBC, 5), Instruction(0xF2, IMP, STP, 2), Instruction(0xF3, IDY, ISB, 8), Instruction(0xF4, ZPX, NOP, 4), Instruction(0xF5, ZPX, SBC, 4), Instruction(0xF6, ZPX, INC, 6), Instruction(0xF7, ZPX, ISB, 6), Instruction(0xF8, IMP, SED, 2), Instruction(0xF9, ABY, SBC, 4), Instruction(0xFA, IMP, NOP, 2), Instruction(0xFB, ABY, ISB, 7), Instruction(0xFC, ABX, NOP, 4), Instruction(0xFD, ABX, SBC, 4), Instruction(0xFE, ABX, INC, 7), Instruction(0xFF, ABX, ISB, 7),
|
Instruction(0xF0, REL, BEQ, 2), Instruction(0xF1, IDY, SBC, 5), Instruction(0xF2, IMP, STP, 2), Instruction(0xF3, IDY, ISB, 8), Instruction(0xF4, ZPX, NOP, 4), Instruction(0xF5, ZPX, SBC, 4), Instruction(0xF6, ZPX, INC, 6), Instruction(0xF7, ZPX, ISB, 6), Instruction(0xF8, IMP, SED, 2), Instruction(0xF9, ABY, SBC, 4), Instruction(0xFA, IMP, NOP, 2), Instruction(0xFB, ABY, ISB, 7), Instruction(0xFC, ABX, NOP, 4), Instruction(0xFD, ABX, SBC, 4), Instruction(0xFE, ABX, INC, 7), Instruction(0xFF, ABX, ISB, 7),
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn read_next_instruction(&mut self) -> Instruction {
|
|
||||||
let op_code = self.program_get_next_byte();
|
|
||||||
let instruction = Instruction[op_code];
|
|
||||||
|
|
||||||
instruction
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Decodes the next operand in memory
|
/// Decodes the next operand in memory
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
@ -226,11 +216,11 @@ impl Cpu<'_> {
|
|||||||
|
|
||||||
if ref_addr & 0xFF == 0xFF {
|
if ref_addr & 0xFF == 0xFF {
|
||||||
// Error in NES CPU for JMP op
|
// Error in NES CPU for JMP op
|
||||||
let low = self.memory_bus.get_byte(ref_addr) as u16;
|
let low = self.memory_bus.borrow().get_byte(ref_addr) as u16;
|
||||||
let high = self.memory_bus.get_byte(ref_addr & 0xFF00) as u16;
|
let high = self.memory_bus.borrow().get_byte(ref_addr & 0xFF00) as u16;
|
||||||
low + (high << 8)
|
low + (high << 8)
|
||||||
} else {
|
} else {
|
||||||
self.memory_bus.get_word(ref_addr)
|
self.memory_bus.borrow().get_word(ref_addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,17 +229,17 @@ impl Cpu<'_> {
|
|||||||
let mut ref_addr = self.program_get_next_byte() as u16;
|
let mut ref_addr = self.program_get_next_byte() as u16;
|
||||||
ref_addr += self.registers.x as u16;
|
ref_addr += self.registers.x as u16;
|
||||||
|
|
||||||
let low = self.memory_bus.get_byte(ref_addr & 0xFF) as u16;
|
let low = self.memory_bus.borrow().get_byte(ref_addr & 0xFF) as u16;
|
||||||
let high = self.memory_bus.get_byte((ref_addr + 1) & 0xFF) as u16;
|
let high = self.memory_bus.borrow().get_byte((ref_addr + 1) & 0xFF) as u16;
|
||||||
low + (high << 8)
|
low + (high << 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// (d),y - PEEK(byte) + Y
|
/// (d),y - PEEK(byte) + Y
|
||||||
fn operand_addr_indy(&mut self, page_crossed: &mut bool) -> u16 {
|
fn operand_addr_indy(&mut self, page_crossed: &mut bool) -> u16 {
|
||||||
let mut ref_addr = self.program_get_next_byte() as u16;
|
let ref_addr = self.program_get_next_byte() as u16;
|
||||||
|
|
||||||
let low = self.memory_bus.get_byte(ref_addr) as u16;
|
let low = self.memory_bus.borrow().get_byte(ref_addr) as u16;
|
||||||
let high = self.memory_bus.get_byte((ref_addr + 1) & 0xFF) as u16;
|
let high = self.memory_bus.borrow().get_byte((ref_addr + 1) & 0xFF) as u16;
|
||||||
let addr = low + (high << 8);
|
let addr = low + (high << 8);
|
||||||
let incr_addr = addr + self.registers.y as u16;
|
let incr_addr = addr + self.registers.y as u16;
|
||||||
|
|
||||||
@ -265,7 +255,7 @@ impl Cpu<'_> {
|
|||||||
|
|
||||||
// The offset is signed
|
// The offset is signed
|
||||||
let positive_offset = offset & 0x7F;
|
let positive_offset = offset & 0x7F;
|
||||||
if offset & 0x80 {
|
if offset & 0x80 > 0 {
|
||||||
base_addr.wrapping_sub(positive_offset)
|
base_addr.wrapping_sub(positive_offset)
|
||||||
} else {
|
} else {
|
||||||
base_addr.wrapping_add(positive_offset)
|
base_addr.wrapping_add(positive_offset)
|
||||||
|
@ -7,7 +7,7 @@ fn is_sign_overflow(val1: u8, val2: u8, result: u8) -> bool {
|
|||||||
(val1 & 0x80 == val2 & 0x80) && (val1 & 0x80 != result & 0x80)
|
(val1 & 0x80 == val2 & 0x80) && (val1 & 0x80 != result & 0x80)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cpu<'_> {
|
impl Cpu {
|
||||||
pub fn exec_instruction(&mut self, instr: Instruction) {
|
pub fn exec_instruction(&mut self, instr: Instruction) {
|
||||||
let operand = self.operand_decode(instr.addr_mode());
|
let operand = self.operand_decode(instr.addr_mode());
|
||||||
if operand.is_page_crossing {
|
if operand.is_page_crossing {
|
||||||
@ -322,6 +322,11 @@ impl Cpu<'_> {
|
|||||||
self.set_status_flag(CpuStatus::Carry, false);
|
self.set_status_flag(CpuStatus::Carry, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clear decimal flag
|
||||||
|
fn op_cld(&mut self, operand: Operand) {
|
||||||
|
self.set_status_flag(CpuStatus::Decimal, false);
|
||||||
|
}
|
||||||
|
|
||||||
/// Clear interrupt disable flag
|
/// Clear interrupt disable flag
|
||||||
fn op_cli(&mut self, operand: Operand) {
|
fn op_cli(&mut self, operand: Operand) {
|
||||||
self.set_status_flag(CpuStatus::InterruptDisable, false);
|
self.set_status_flag(CpuStatus::InterruptDisable, false);
|
||||||
@ -470,7 +475,7 @@ impl Cpu<'_> {
|
|||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
assert_eq!(addr_mode, AddressingMode::IND);
|
assert_eq!(addr_mode, AddressingMode::IND);
|
||||||
self.memory_bus.get_word(value)
|
self.memory_bus.borrow().get_word(value)
|
||||||
};
|
};
|
||||||
|
|
||||||
self.registers.pc = target_addr;
|
self.registers.pc = target_addr;
|
||||||
@ -840,6 +845,13 @@ impl Cpu<'_> {
|
|||||||
self.set_common_flags(x);
|
self.set_common_flags(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Transfer X to stack pointer
|
||||||
|
fn op_txs(&mut self, operand: Operand) {
|
||||||
|
let x = self.registers.x;
|
||||||
|
|
||||||
|
self.registers.sp = x;
|
||||||
|
}
|
||||||
|
|
||||||
/// Transfer Y to A
|
/// Transfer Y to A
|
||||||
fn op_tya(&mut self, operand: Operand) {
|
fn op_tya(&mut self, operand: Operand) {
|
||||||
let y = self.registers.y;
|
let y = self.registers.y;
|
||||||
|
@ -99,7 +99,7 @@ impl Rom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RomReadError {
|
pub enum RomReadError {
|
||||||
FormatNotSupported,
|
FormatNotSupported,
|
||||||
Io(std::io::Error),
|
Io(std::io::Error),
|
||||||
InvalidHeader(String),
|
InvalidHeader(String),
|
||||||
|
Loading…
Reference in New Issue
Block a user