rusty-nes/src/cpu.rs

119 lines
1.7 KiB
Rust
Raw Normal View History

2022-08-23 17:01:26 +00:00
use std::cell::RefCell;
use std::rc::{Rc, Weak};
use crate::bus::Bus;
2022-08-29 16:32:04 +00:00
use crate::instructions::INSTRUCTION_SET;
2022-08-23 20:11:25 +00:00
2022-08-25 15:01:58 +00:00
pub enum FetchType
{
Acc,
Mem
}
2022-08-23 17:01:26 +00:00
pub struct CPU
{
2022-08-23 20:11:25 +00:00
pub cycle: u8,
total_cycles: u64,
2022-08-25 15:01:58 +00:00
2022-08-23 20:11:25 +00:00
pub absolute_addr: u16,
2022-08-23 23:57:42 +00:00
pub relative_addr: i8,
2022-08-25 15:01:58 +00:00
pub fetch_type: FetchType,
2022-08-23 17:01:26 +00:00
2022-08-23 20:11:25 +00:00
pub acc: u8,
pub x: u8,
pub y: u8,
pub p: u8,
pub sp: u8,
pub pc: u16,
2022-08-23 17:01:26 +00:00
2022-08-23 20:11:25 +00:00
pub bus: Weak<RefCell<Bus>>,
2022-08-23 17:01:26 +00:00
}
impl CPU
{
pub fn new(bus: &Rc<RefCell<Bus>>) -> CPU
{
CPU {
2022-08-23 20:11:25 +00:00
cycle: 0,
total_cycles: 0,
2022-08-25 15:01:58 +00:00
2022-08-23 20:11:25 +00:00
absolute_addr: 0,
relative_addr: 0,
2022-08-25 15:01:58 +00:00
fetch_type: FetchType::Mem,
2022-08-23 20:11:25 +00:00
2022-08-23 17:01:26 +00:00
acc: 0,
x: 0,
y: 0,
p: 0,
sp: 0,
pc: 0,
bus: Rc::downgrade(bus)
2022-08-23 17:01:26 +00:00
}
}
pub fn powerup(&mut self)
{
self.p = 0x34;
self.acc = 0;
self.x = 0;
self.y = 0;
self.sp = 0xFD;
2022-08-23 17:40:48 +00:00
2022-08-23 20:11:25 +00:00
self.total_cycles = 0;
self.cycle = 6;
2022-08-23 17:40:48 +00:00
// TODO: This is just for the nestest.nes
self.pc = 0xC000;
2022-08-23 17:01:26 +00:00
}
2022-08-23 20:11:25 +00:00
pub fn cycle(&mut self)
{
self.total_cycles += 1;
if self.cycle > 0
{
self.cycle -= 1;
return;
}
self.execute();
2022-08-23 20:21:28 +00:00
self.cycle -= 1;
2022-08-23 20:11:25 +00:00
}
fn execute(&mut self)
2022-08-23 17:01:26 +00:00
{
let bus = self.bus.upgrade().unwrap();
let opcode: u8 = bus.borrow().read_cpu(self.pc);
let instr = INSTRUCTION_SET[opcode as usize].expect(&format!("Unimplemented opcode {:02X}", opcode));
2022-08-23 17:01:26 +00:00
2022-08-23 20:11:25 +00:00
print!("{:04X} ", self.pc);
for byte in 0..3
2022-08-23 17:01:26 +00:00
{
2022-08-23 20:11:25 +00:00
if byte < instr.length
{
print!("{:02X} ", bus.borrow().read_cpu(self.pc + byte as u16));
}
else
{
print!(" ");
}
2022-08-23 17:01:26 +00:00
}
2022-08-23 20:11:25 +00:00
print!(" {} ", instr.name.to_string().to_uppercase());
self.pc += 1;
(instr.addressing)(self);
(instr.action)(self);
self.cycle += instr.cycles;
println!("A:{:02X} X:{:02X} Y:{:02X} P:{:02X} SP:{:02X} CYC:{}", self.acc, self.x, self.y, self.p, self.sp, self.total_cycles);
2022-08-23 17:01:26 +00:00
}
}