mirror of
https://github.com/FranLMSP/snes.git
synced 2026-08-03 08:30:01 -04:00
Reset vector and rst instruction
This commit is contained in:
@@ -3,6 +3,7 @@ use super::registers::Registers;
|
||||
pub struct CPU {
|
||||
pub registers: Registers,
|
||||
pub cycles: usize,
|
||||
pub is_stopped: bool,
|
||||
}
|
||||
|
||||
impl CPU {
|
||||
@@ -10,6 +11,7 @@ impl CPU {
|
||||
Self {
|
||||
registers: Registers::new(),
|
||||
cycles: 0,
|
||||
is_stopped: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,6 +396,14 @@ impl CPU {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn increment_cycles_stp(&mut self) {
|
||||
self.registers.increment_pc(1); self.cycles += 3;
|
||||
}
|
||||
|
||||
pub fn increment_cycles_while_stopped(&mut self) {
|
||||
self.cycles += 1;
|
||||
}
|
||||
|
||||
pub fn increment_cycles_move(&mut self, count: usize) {
|
||||
self.registers.increment_pc(3); self.cycles += 7 * count;
|
||||
}
|
||||
|
||||
@@ -875,6 +875,11 @@ impl CPU {
|
||||
self.increment_cycles_st_index(addressing_mode);
|
||||
}
|
||||
|
||||
fn stp(&mut self, bus: &Bus) {
|
||||
self.reset_vector(bus);
|
||||
self.increment_cycles_stp();
|
||||
}
|
||||
|
||||
fn tax(&mut self) {
|
||||
if self.registers.is_16bit_index() {
|
||||
self.registers.x = self.registers.a;
|
||||
@@ -1104,6 +1109,10 @@ impl CPU {
|
||||
}
|
||||
|
||||
pub fn tick(&mut self, bus: &mut Bus) {
|
||||
if self.is_stopped {
|
||||
self.increment_cycles_while_stopped();
|
||||
return;
|
||||
}
|
||||
let opcode = bus.read(self.registers.get_pc_address());
|
||||
self.execute_opcode(opcode, bus);
|
||||
}
|
||||
@@ -1406,7 +1415,7 @@ impl CPU {
|
||||
0x83 => self.sta(bus, A::StackRelative),
|
||||
0x93 => self.sta(bus, A::StackRelativeIndirectIndexed(I::Y)),
|
||||
// STP
|
||||
0xDB => unimplemented!("STP instruction not implemented yet"),
|
||||
0xDB => self.stp(bus),
|
||||
// STX
|
||||
0x8E => self.stx(bus, A::Absolute),
|
||||
0x86 => self.stx(bus, A::DirectPage),
|
||||
@@ -2676,6 +2685,18 @@ mod cpu_instructions_tests {
|
||||
assert_eq!(cpu.cycles, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stp() {
|
||||
let mut cpu = CPU::new();
|
||||
let bus = Bus::new();
|
||||
cpu.is_stopped = false;
|
||||
cpu.registers.pc = 0x0000;
|
||||
cpu.stp(&bus);
|
||||
assert_eq!(cpu.registers.pc, 0x0003);
|
||||
assert_eq!(cpu.is_stopped, true);
|
||||
assert_eq!(cpu.cycles, 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stx() {
|
||||
let mut cpu = CPU::new();
|
||||
|
||||
@@ -3,5 +3,6 @@ pub use cpu::CPU;
|
||||
pub mod bus;
|
||||
pub mod registers;
|
||||
pub mod instructions;
|
||||
pub mod vectors;
|
||||
pub mod cycles;
|
||||
pub mod internal_registers;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
use super::cpu::CPU;
|
||||
use crate::cpu::bus::Bus;
|
||||
|
||||
impl CPU {
|
||||
pub fn reset_vector(&mut self, bus: &Bus) {
|
||||
let reset_vector = (bus.read(0x00FFFC) as u16) | ((bus.read(0x00FFFD) as u16) << 8);
|
||||
self.registers.pc = reset_vector;
|
||||
self.is_stopped = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod cpu_vectors_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_reset_vector() {
|
||||
let mut cpu = CPU::new();
|
||||
let bus = Bus::new();
|
||||
cpu.is_stopped = true;
|
||||
// TODO: test that the PC register got the right vector
|
||||
cpu.reset_vector(&bus);
|
||||
assert_eq!(cpu.is_stopped, false);
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,6 @@ impl Emulator {
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
let reset_vector = (self.bus.read(0x00FFFC) as u16) | ((self.bus.read(0x00FFFD) as u16) << 8);
|
||||
self.cpu.registers.pc = reset_vector;
|
||||
self.cpu.reset_vector(&self.bus);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user