Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pub enum Flag {
- Carry = 1 << 0,
- Zero = 1 << 1,
- Interrupt = 1 << 2,
- Decimal = 1 << 3,
- Overflow = 1 << 6,
- Negative = 1 << 7,
- }
- pub struct Registers {
- pub a: u8, // Accumulator
- pub x: u8, // X index
- pub y: u8, // Y index
- pub pc: u16, // Program Counter
- pub s: u8, // Stack pointer
- pub p: u8, // Status register
- }
- impl Registers {
- pub fn get_flag(&self, flag: Flag) -> bool {
- self.p & flag as u8 != 0
- }
- pub fn set_flag(&mut self, flag: Flag) {
- self.p |= flag as u8;
- }
- }
- const NMI_VECTOR: u16 = 0xFFFA;
- const RESET_VECTOR: u16 = 0xFFFC;
- const IRQ_VECTOR: u16 = 0xFFFE;
- pub struct CPU {
- regs: Registers,
- cycles: u64,
- nmi: bool,
- irq: bool,
- ram: Ram,
- }
- impl CPU {
- pub fn new() -> CPU {
- CPU {
- regs: Registers {
- a: 0,
- x: 0,
- y: 0,
- p: 0x34,
- s: 0xFD,
- pc: 0,
- },
- cycles: 0,
- nmi: false,
- irq: false,
- ram: Ram::default(),
- }
- }
- pub fn reset(&mut self) {
- unimplemented!();
- }
- pub fn step(&mut self) {
- let opcode = self.ram.read_byte(self.regs.pc);
- let instruction = INSTRUCTIONS[opcode as usize];
- instruction.exec(self);
- }
- fn read<A: AddressingMode>(&self, add_mode: A) -> u8 {
- add_mode.read(self)
- }
- fn write<A: AddressingMode>(&mut self, add_mode: A, val: u8) {
- add_mode.write(self, val);
- }
- }
- trait AddressingMode {
- fn read(&self, cpu: &CPU) -> u8;
- fn write(&self, cpu: &mut CPU, val: u8);
- }
- #[derive(Clone, Copy)]
- struct Immediate;
- impl AddressingMode for Immediate {
- fn read(&self, cpu: &CPU) -> u8 {
- cpu.ram.read_byte(cpu.regs.pc)
- }
- fn write(&self, _: &mut CPU, _: u8) {
- panic!("Cannot write to immediate!");
- }
- }
- #[derive(Clone, Copy)]
- struct ZeroPage;
- impl AddressingMode for ZeroPage {
- fn read(&self, cpu: &CPU) -> u8 {
- let address: u8 = cpu.read(Immediate);
- cpu.ram.read_byte(address as u16)
- }
- fn write(&self, cpu: &mut CPU, val: u8) {
- let address: u8 = cpu.read(Immediate);
- cpu.ram.write_byte(address as u16, val);
- }
- }
- #[derive(Clone, Copy)]
- struct Absolute;
- impl AddressingMode for Absolute {
- fn read(&self, cpu: &CPU) -> u8 {
- let address: u16 = cpu.ram.read_word(cpu.regs.pc);
- cpu.ram.read_byte(address)
- }
- fn write(&self, cpu: &mut CPU, val: u8) {
- let address: u16 = cpu.ram.read_word(cpu.regs.pc);
- cpu.ram.write_byte(address, val);
- }
- }
- #[derive(Clone, Copy)]
- enum AddMode {
- Immediate(Immediate),
- ZeroPage(ZeroPage),
- Absolute(Absolute),
- }
- impl AddressingMode for AddMode {
- fn read(&self, cpu: &CPU) -> u8 {
- match self {
- Self::Immediate(x) => x.read(cpu),
- Self::ZeroPage(x) => x.read(cpu),
- Self::Absolute(x) => x.read(cpu),
- }
- }
- fn write(&self, cpu: &mut CPU, val: u8) {
- match self {
- Self::Immediate(x) => x.write(cpu, val),
- Self::ZeroPage(x) => x.write(cpu, val),
- Self::Absolute(x) => x.write(cpu, val),
- }
- }
- }
- impl From<Immediate> for AddMode {
- fn from(x: Immediate) -> Self {
- Self::Immediate(x)
- }
- }
- impl From<ZeroPage> for AddMode {
- fn from(x: ZeroPage) -> Self {
- Self::ZeroPage(x)
- }
- }
- impl From<Absolute> for AddMode {
- fn from(x: Absolute) -> Self {
- Self::Absolute(x)
- }
- }
- #[derive(Clone, Copy)]
- struct Instruction {
- pub name: &'static str,
- pub cycles: usize,
- pub bytes: usize,
- pub add_mode: AddMode,
- pub handler: fn(&mut CPU, mode: AddMode),
- pub extra_cycle_on_page_cross: bool,
- }
- impl Instruction {
- fn exec(&self, cpu: &mut CPU) {
- (self.handler)(cpu, self.add_mode);
- cpu.regs.pc += self.bytes as u16;
- cpu.cycles += self.cycles as u64;
- }
- }
- fn lda(cpu: &mut CPU, mode: AddMode) {
- cpu.regs.a = mode.read(cpu);
- }
- fn sta(cpu: &mut CPU, mode: AddMode) {
- mode.write(cpu, cpu.regs.a);
- }
- // TODO: Add instructions
- lazy_static! {
- static ref INSTRUCTIONS: [Instruction; 2] = [
- Instruction {
- name: "LDA",
- cycles: 3,
- bytes: 2,
- add_mode: ZeroPage.into(),
- handler: lda,
- extra_cycle_on_page_cross: false,
- },
- Instruction {
- name: "STA",
- cycles: 4,
- bytes: 2,
- add_mode: ZeroPage.into(),
- handler: sta,
- extra_cycle_on_page_cross: false,
- }
- ];
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement