1mod instructions; 2pub mod traits; 3 4use crate::traits::BusInterface; 5use bincode::{Decode, Encode}; 6use jgenesis_common::num::GetBit; 7 8#[derive(Debug, Clone, Copy, Default, Encode, Decode)] 9pub struct StatusRegister { 10 negative: bool, 11 overflow: bool, 12 direct_page: bool, 13 break_flag: bool, 14 half_carry: bool, 15 interrupt_enabled: bool, 16 zero: bool, 17 carry: bool, 18} 19 20impl From<StatusRegister> for u8 { 21 fn from(value: StatusRegister) -> Self { 22 (u8::from(value.negative) << 7) 23 | (u8::from(value.overflow) << 6) 24 | (u8::from(value.direct_page) << 5) 25 | (u8::from(value.break_flag) << 4) 26 | (u8::from(value.half_carry) << 3) 27 | (u8::from(value.interrupt_enabled) << 2) 28 | (u8::from(value.zero) << 1) 29 | u8::from(value.carry) 30 } 31} 32 33impl From<u8> for StatusRegister { 34 fn from(value: u8) -> Self { 35 Self { 36 negative: value.bit(7), 37 overflow: value.bit(6), 38 direct_page: value.bit(5), 39 break_flag: value.bit(4), 40 half_carry: value.bit(3), 41 interrupt_enabled: value.bit(2), 42 zero: value.bit(1), 43 carry: value.bit(0), 44 } 45 } 46} 47 48#[derive(Debug, Clone, Default, Encode, Decode)] 49pub struct Registers { 50 pub a: u8, 51 pub x: u8, 52 pub y: u8, 53 pub sp: u8, 54 pub pc: u16, 55 pub psw: StatusRegister, 56} 57 58impl Registers { 59 fn ya(&self) -> u16 { 60 u16::from_le_bytes([self.a, self.y]) 61 } 62 63 fn set_ya(&mut self, ya: u16) { 64 let [a, y] = ya.to_le_bytes(); 65 self.a = a; 66 self.y = y; 67 } 68} 69 70#[derive(Debug, Clone, Default, Encode, Decode)] 71struct State { 72 opcode: u8, 73 cycle: u8, 74 stopped: bool, 75 // Variables to store data between cycles 76 t0: u8, 77 t1: u8, 78 t2: u8, 79 t3: u8, 80} 81 82#[derive(Debug, Clone, Default, Encode, Decode)] 83pub struct Spc700 { 84 registers: Registers, 85 state: State, 86} 87 88const RESET_VECTOR: u16 = 0xFFFE; 89 90impl Spc700 { 91 #[must_use] 92 pub fn new() -> Self { 93 Self::default() 94 } 95 96 pub fn tick<B: BusInterface>(&mut self, bus: &mut B) { 97 instructions::execute(self, bus); 98 } 99 100 pub fn reset<B: BusInterface>(&mut self, bus: &mut B) { 101 let pc_lsb = bus.read(RESET_VECTOR); 102 let pc_msb = bus.read(RESET_VECTOR + 1); 103 self.registers.pc = u16::from_le_bytes([pc_lsb, pc_msb]); 104 105 self.state.cycle = 0; 106 self.state.stopped = false; 107 } 108 109 fn final_cycle(&mut self) { 110 self.state.cycle = 0; 111 } 112 113 fn direct_page_msb(&self) -> u8 { 114 // 1 -> 0x01, 0 -> 0x00 115 self.registers.psw.direct_page.into() 116 } 117 118 fn stack_pointer(&self) -> u16 { 119 u16::from_le_bytes([self.registers.sp, 0x01]) 120 } 121 122 #[must_use] 123 pub fn is_mid_instruction(&self) -> bool { 124 self.state.cycle != 0 125 } 126 127 #[must_use] 128 pub fn registers(&self) -> &Registers { 129 &self.registers 130 } 131 132 pub fn set_registers(&mut self, registers: Registers) { 133 self.registers = registers; 134 } 135}