Skip to content

Commit 590392b

Browse files
committed
other testing complete, rti not tested due to needing further implementation support; first version of cpu
1 parent c371505 commit 590392b

3 files changed

Lines changed: 45 additions & 4 deletions

File tree

src/cpu.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod branch_test;
77
mod group1_test;
88
mod group2_test;
99
mod group3_test;
10+
mod other_test;
1011
mod op;
1112
mod sb1_test;
1213
mod sb2_test;
@@ -875,7 +876,7 @@ impl CPU {
875876
fn brk(&mut self) {
876877
println!("brk: Initalized");
877878
println!("brk: pc is {}", self.pc);
878-
self.stack_push_u16(self.pc + 2 - 1);
879+
self.stack_push_u16(self.pc.wrapping_add(2));
879880
self.stack_push(self.flags.bits());
880881
self.flags.insert(CpuFlags::INTERRUPT_DISABLE);
881882
self.pc = self.mem_read_u16(0xFFFE);
@@ -884,18 +885,27 @@ impl CPU {
884885

885886
fn jsr(&mut self) {
886887
// Pushes the 16 bit value after self.pc
887-
self.stack_push_u16(self.pc + 2 - 1);
888-
self.pc = self.mem_read_u16(self.pc);
888+
// Note that self.pc is already on the memory value so we just need to push this part + 1
889+
// Eg. JSR 0xAA 0xBB, we would be pushing the memory address of 0xBB
890+
// When rts is called, pc will add 1 automatically so it returns from the next function
891+
println!("jsr: Initalized! The instruction's address is {:#x}", self.pc);
892+
self.stack_push_u16(self.pc.wrapping_add(2));
893+
// Need to subtract one at the end as run() will add one automatically
894+
self.pc = self.mem_read_u16(self.pc.wrapping_add(1)).wrapping_sub(1);
889895
}
890896

891897
fn rti(&mut self) {
898+
// Most likely coming from a BRK(software IRQ)- BRK is treated as a 2 byte instruction with an unused immediate
892899
self.flags = CpuFlags::from_bits_truncate(self.stack_pop());
893900
self.pc = self.stack_pop_u16();
901+
// Need to subtract one pc to balance out with the end of run(), which adds one to pc
902+
self.pc = self.pc.wrapping_sub(1);
894903
}
895904

896905
fn rts(&mut self) {
897906
self.pc = self.stack_pop_u16();
898-
self.pc += 1;
907+
println!("rts: Finished. The pc before finishing run is {:#x}", self.pc);
908+
// self.pc does not need to be added as at the end of run, the pc will be added by 1 automatically
899909
}
900910

901911
fn group_three(&mut self, aaa: u8, bbb: u8, _cc: u8) {

src/cpu/op.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,10 @@ pub mod branch_op {
114114
pub const BNE: u8 = 0xD0; // Branch on Not Equal (Z=0)
115115
pub const BEQ: u8 = 0xF0; // Branch on Equal (Z=1)
116116
}
117+
118+
#[cfg(test)]
119+
pub mod other_op{
120+
pub const JSR:u8 = 0x20;
121+
pub const RTI: u8 = 0x40;
122+
pub const RTS: u8 = 0x60;
123+
}

src/cpu/other_test.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
#[cfg(test)]
3+
mod branch_test {
4+
use crate::cpu::op::*;
5+
use crate::cpu::CpuFlags;
6+
use crate::cpu::CPU;
7+
8+
// BRK is not tested as every other test hinges on BRK working...
9+
10+
// JSR and RTS are tested together to see if INX is called
11+
// 0x8000 is for jsr, 8001 + 8002 is to store address
12+
// One test for jumping to a forward subroutine, another test for jumping to a previous subroutine
13+
#[test]
14+
fn test_jsr_rts(){
15+
let mut cpu = CPU::new();
16+
cpu.load_and_run(vec![other_op::JSR, 0x05, 0x80, op::INY, 0x00, op::INX, other_op::RTS]);
17+
assert!(cpu.x == 1 && cpu.y == 1, "JSR and RTS test failed! cpu.x is {}, cpu.y is {}", cpu.x, cpu.y);
18+
}
19+
20+
21+
// JSR, PHP are done for RTI testing
22+
// Check if custom flags are the same from the stack AND if INX is called
23+
// in fffe link to address, run programs in ram from 0x0000 to 0x8000,
24+
}

0 commit comments

Comments
 (0)