Fix program counter issues

This commit is contained in:
paoda 2020-06-25 12:15:31 -05:00
parent cb030b992d
commit b320398394
2 changed files with 8 additions and 46 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/target /target
/games

View File

@ -76,6 +76,8 @@ impl Chip8 {
let nib_3 = (self.opcode & 0x00F0) >> 4; // 0xF let nib_3 = (self.opcode & 0x00F0) >> 4; // 0xF
let nib_4 = self.opcode & 0x000F; // 0x0 let nib_4 = self.opcode & 0x000F; // 0x0
self.pc += 2;
// nib_ns are u16s so we waste 4 bytes here. // nib_ns are u16s so we waste 4 bytes here.
match (nib_1, nib_2, nib_3, nib_4) { match (nib_1, nib_2, nib_3, nib_4) {
@ -155,13 +157,11 @@ impl Chip8 {
fn cls(&mut self) { fn cls(&mut self) {
// Clear the display // Clear the display
self.display.clear(); self.display.clear();
self.pc += 1;
} }
fn jmp_addr(&mut self, n_1: u16, n_2: u16, n_3: u16) { fn jmp_addr(&mut self, n_1: u16, n_2: u16, n_3: u16) {
// sets the program counter to addr (nnn) // sets the program counter to addr (nnn)
self.pc = Self::convert_to_addr(n_1, n_2, n_3); self.pc = Self::convert_to_addr(n_1, n_2, n_3);
self.pc += 1;
} }
fn ret(&mut self) { fn ret(&mut self) {
@ -169,7 +169,6 @@ impl Chip8 {
// then subtracts one (1) from the stack pointer // then subtracts one (1) from the stack pointer
self.pc = self.stack[self.sp as usize]; self.pc = self.stack[self.sp as usize];
self.sp -= 1; self.sp -= 1;
self.pc += 1;
} }
fn call_addr(&mut self, n_1: u16, n_2: u16, n_3: u16) { fn call_addr(&mut self, n_1: u16, n_2: u16, n_3: u16) {
@ -178,15 +177,12 @@ impl Chip8 {
self.sp += 1; self.sp += 1;
self.stack[self.sp as usize] = self.pc; self.stack[self.sp as usize] = self.pc;
self.pc = Self::convert_to_addr(n_1, n_2, n_3); self.pc = Self::convert_to_addr(n_1, n_2, n_3);
self.pc += 1;
} }
fn se_vx_byte(&mut self, x: u16, k_1: u16, k_2: u16) { fn se_vx_byte(&mut self, x: u16, k_1: u16, k_2: u16) {
// compares Vx to kk. If they are equal, pc is incremented by 2 // compares Vx to kk. If they are equal, pc is incremented by 2
if self.v[x as usize] == Self::convert_to_byte(k_1, k_2) { if self.v[x as usize] == Self::convert_to_byte(k_1, k_2) {
self.pc += 2; self.pc += 2;
} else {
self.pc += 1;
} }
} }
@ -194,8 +190,6 @@ impl Chip8 {
// compares Vx to kk. If they are **not** equal, pc is incremented by 2 // compares Vx to kk. If they are **not** equal, pc is incremented by 2
if self.v[x as usize] != Self::convert_to_byte(k_1, k_2) { if self.v[x as usize] != Self::convert_to_byte(k_1, k_2) {
self.pc += 2; self.pc += 2;
} else {
self.pc += 1;
} }
} }
@ -203,49 +197,41 @@ impl Chip8 {
// compares Vx to Vy. If they are equal, pc is incremented by 2 // compares Vx to Vy. If they are equal, pc is incremented by 2
if self.v[x as usize] == self.v[y as usize] { if self.v[x as usize] == self.v[y as usize] {
self.pc += 2; self.pc += 2;
} else {
self.pc += 1;
} }
} }
fn ld_vx_byte(&mut self, x: u16, k_1: u16, k_2: u16) { fn ld_vx_byte(&mut self, x: u16, k_1: u16, k_2: u16) {
// put value kk into Vx // put value kk into Vx
self.v[x as usize] = Self::convert_to_byte(k_1, k_2); self.v[x as usize] = Self::convert_to_byte(k_1, k_2);
self.pc += 1;
} }
fn add_vx_byte(&mut self, x: u16, k_1: u16, k_2: u16) { fn add_vx_byte(&mut self, x: u16, k_1: u16, k_2: u16) {
// calculate Vx + kk, then store it in Vx // calculate Vx + kk, then store it in Vx
let x = x as usize; let x = x as usize;
self.v[x] = self.v[x] + Self::convert_to_byte(k_1, k_2); self.v[x] = self.v[x] + Self::convert_to_byte(k_1, k_2);
self.pc += 1;
} }
fn ld_vx_vy(&mut self, x: u16, y: u16) { fn ld_vx_vy(&mut self, x: u16, y: u16) {
// store Vy in Vx // store Vy in Vx
self.v[x as usize] = self.v[y as usize]; self.v[x as usize] = self.v[y as usize];
self.pc += 1;
} }
fn or_vx_vy(&mut self, x: u16, y: u16) { fn or_vx_vy(&mut self, x: u16, y: u16) {
// calc bitwise OR on Vx and Vy, then store in Vx // calc bitwise OR on Vx and Vy, then store in Vx
let x = x as usize; let x = x as usize;
self.v[x] = self.v[x] | self.v[y as usize]; self.v[x] = self.v[x] | self.v[y as usize];
self.pc += 1;
} }
fn and_vx_vy(&mut self, x: u16, y: u16) { fn and_vx_vy(&mut self, x: u16, y: u16) {
// calc bitwise AND on Vx and Vy, then store in Vx // calc bitwise AND on Vx and Vy, then store in Vx
let x = x as usize; let x = x as usize;
self.v[x] = self.v[x] & self.v[y as usize]; self.v[x] = self.v[x] & self.v[y as usize];
self.pc += 1;
} }
fn xor_vx_vy(&mut self, x: u16, y: u16) { fn xor_vx_vy(&mut self, x: u16, y: u16) {
// calc bitwise XOR on Vx and Vy, then store in Vx // calc bitwise XOR on Vx and Vy, then store in Vx
let x = x as usize; let x = x as usize;
self.v[x] = self.v[x] ^ self.v[y as usize]; self.v[x] = self.v[x] ^ self.v[y as usize];
self.pc += 1;
} }
fn add_vx_vy(&mut self, x: u16, y: u16) { fn add_vx_vy(&mut self, x: u16, y: u16) {
@ -257,7 +243,6 @@ impl Chip8 {
let (res, did_overflow) = self.v[x].overflowing_add(self.v[y as usize]); let (res, did_overflow) = self.v[x].overflowing_add(self.v[y as usize]);
self.v[0xF as usize] = if did_overflow { 1 } else { 0 }; self.v[0xF as usize] = if did_overflow { 1 } else { 0 };
self.v[x] = res; self.v[x] = res;
self.pc += 1;
} }
fn sub_vx_vy(&mut self, x: u16, y: u16) { fn sub_vx_vy(&mut self, x: u16, y: u16) {
@ -268,7 +253,6 @@ impl Chip8 {
self.v[0xF as usize] = if vx > vy { 1 } else { 0 }; self.v[0xF as usize] = if vx > vy { 1 } else { 0 };
self.v[x as usize] = vx - vy; self.v[x as usize] = vx - vy;
self.pc += 1;
} }
fn shr_vx(&mut self, x: u16) { fn shr_vx(&mut self, x: u16) {
@ -278,7 +262,6 @@ impl Chip8 {
self.v[0xF as usize] = if (self.v[x] & 1) == 1 { 1 } else { 0 }; self.v[0xF as usize] = if (self.v[x] & 1) == 1 { 1 } else { 0 };
self.v[x] = self.v[x] >> 1; self.v[x] = self.v[x] >> 1;
self.pc += 1;
} }
fn subn_vx_vy(&mut self, x: u16, y: u16) { fn subn_vx_vy(&mut self, x: u16, y: u16) {
@ -289,7 +272,6 @@ impl Chip8 {
self.v[0xF as usize] = if vy > vx { 1 } else { 0 }; self.v[0xF as usize] = if vy > vx { 1 } else { 0 };
self.v[x as usize] = vy - vx; self.v[x as usize] = vy - vx;
self.pc += 1;
} }
fn shl_vx(&mut self, x: u16) { fn shl_vx(&mut self, x: u16) {
@ -299,28 +281,23 @@ impl Chip8 {
self.v[0xF as usize] = if (self.v[x] & 0x80) == 1 { 1 } else { 0 }; self.v[0xF as usize] = if (self.v[x] & 0x80) == 1 { 1 } else { 0 };
self.v[x] = self.v[x] << 1; self.v[x] = self.v[x] << 1;
self.pc += 1;
} }
fn sne_vx_vy(&mut self, x: u16, y: u16) { fn sne_vx_vy(&mut self, x: u16, y: u16) {
// if Vx != vy program counter is increased by 2 // if Vx != vy program counter is increased by 2
if self.v[x as usize] != self.v[y as usize] { if self.v[x as usize] != self.v[y as usize] {
self.pc += 2; self.pc += 2;
} else {
self.pc += 1;
} }
} }
fn ld_i_addr(&mut self, n_1: u16, n_2: u16, n_3: u16) { fn ld_i_addr(&mut self, n_1: u16, n_2: u16, n_3: u16) {
// set i to addr // set i to addr
self.i = Self::convert_to_addr(n_1, n_2, n_3); self.i = Self::convert_to_addr(n_1, n_2, n_3);
self.pc += 1;
} }
fn jmp_v0_addr(&mut self, n_1: u16, n_2: u16, n_3: u16) { fn jmp_v0_addr(&mut self, n_1: u16, n_2: u16, n_3: u16) {
// set program counter to addr + V0 // set program counter to addr + V0
self.pc = Self::convert_to_addr(n_1, n_2, n_3) + self.v[0 as usize] as u16; self.pc = Self::convert_to_addr(n_1, n_2, n_3) + self.v[0 as usize] as u16;
self.pc += 1;
} }
fn rnd_vx_byte(&mut self, x: u16, k_1: u16, k_2: u16) { fn rnd_vx_byte(&mut self, x: u16, k_1: u16, k_2: u16) {
@ -328,7 +305,6 @@ impl Chip8 {
// AND with the value of kk, then store in Vx // AND with the value of kk, then store in Vx
self.v[x as usize] = rand::random::<u8>() & Self::convert_to_byte(k_1, k_2); self.v[x as usize] = rand::random::<u8>() & Self::convert_to_byte(k_1, k_2);
self.pc += 1;
} }
fn drw_vx_vy_nib(&mut self, x: u16, y: u16, nib: u16) { fn drw_vx_vy_nib(&mut self, x: u16, y: u16, nib: u16) {
@ -351,11 +327,7 @@ impl Chip8 {
if let Some(key) = self.key { if let Some(key) = self.key {
if self.v[x as usize] == key { if self.v[x as usize] == key {
self.pc += 2; self.pc += 2;
} else {
self.pc += 1;
} }
} else {
self.pc += 1;
} }
} }
@ -366,8 +338,6 @@ impl Chip8 {
Some(key) => { Some(key) => {
if key != self.v[x as usize] { if key != self.v[x as usize] {
self.pc += 2; self.pc += 2;
} else {
self.pc += 1;
} }
} }
None => self.pc += 2, None => self.pc += 2,
@ -377,37 +347,31 @@ impl Chip8 {
fn ld_vx_dt(&mut self, x: u16) { fn ld_vx_dt(&mut self, x: u16) {
// set Vx to be the value of the delay timer // set Vx to be the value of the delay timer
self.v[x as usize] = self.delay.get(); self.v[x as usize] = self.delay.get();
self.pc += 1;
} }
fn ld_vx_k(&mut self, x: u16) { fn ld_vx_k(&mut self, x: u16) {
// wait (blocking) until a key is pressed // wait (blocking) until a key is pressed
// once pressed, store in Vx // once pressed, store in Vx
loop {
if let Some(key) = self.key { match self.key {
self.v[x as usize] = key; Some(key) => self.v[x as usize] = key,
break; None => self.pc -= 2,
} }
} }
self.pc += 1;
}
fn ld_dt_vx(&mut self, x: u16) { fn ld_dt_vx(&mut self, x: u16) {
// set delay timer to be value of Vx // set delay timer to be value of Vx
self.delay.set(self.v[x as usize]); self.delay.set(self.v[x as usize]);
self.pc += 1;
} }
fn ld_st_vx(&mut self, x: u16) { fn ld_st_vx(&mut self, x: u16) {
// set sound timer to be value of Vx // set sound timer to be value of Vx
self.delay.set(self.v[x as usize]); self.delay.set(self.v[x as usize]);
self.pc += 1;
} }
fn add_i_vx(&mut self, x: u16) { fn add_i_vx(&mut self, x: u16) {
// set I to be I + Vx // set I to be I + Vx
self.i = self.i + self.v[x as usize] as u16; self.i = self.i + self.v[x as usize] as u16;
self.pc += 1;
} }
fn ld_f_vx(&mut self, _x: u16) { fn ld_f_vx(&mut self, _x: u16) {
@ -428,7 +392,6 @@ impl Chip8 {
self.memory[i] = hundreds; self.memory[i] = hundreds;
self.memory[i + 1] = tens; self.memory[i + 1] = tens;
self.memory[i + 2] = ones; self.memory[i + 2] = ones;
self.pc += 1;
} }
fn ld_i_vx(&mut self, x: u16) { fn ld_i_vx(&mut self, x: u16) {
@ -437,7 +400,6 @@ impl Chip8 {
for n in 0..=(x as usize) { for n in 0..=(x as usize) {
self.memory[self.i as usize + n] = self.v[n]; self.memory[self.i as usize + n] = self.v[n];
} }
self.pc += 1;
} }
fn ld_vx_i(&mut self, x: u16) { fn ld_vx_i(&mut self, x: u16) {
@ -447,7 +409,6 @@ impl Chip8 {
for n in 0..=x { for n in 0..=x {
self.v[n] = self.memory[self.i as usize + n]; self.v[n] = self.memory[self.i as usize + n];
} }
self.pc += 1;
} }
fn convert_to_byte(k_1: u16, k_2: u16) -> u8 { fn convert_to_byte(k_1: u16, k_2: u16) -> u8 {
@ -572,7 +533,7 @@ fn main() {
let mut chip8: Chip8 = Default::default(); let mut chip8: Chip8 = Default::default();
chip8 chip8
.load_rom(Path::new("C:\\Users\\paoda\\Documents\\chip8_roms\\TICTAC")) .load_rom(Path::new("./games/c8games/TICTAC"))
.expect("Unable to load ROM"); .expect("Unable to load ROM");
loop { loop {