lib.rsannotatedlib.rssource135 lines · 3.0 KB · raw
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}