Fix program counter issues
This commit is contained in:
parent
cb030b992d
commit
b320398394
|
@ -1 +1,2 @@
|
||||||
/target
|
/target
|
||||||
|
/games
|
53
src/main.rs
53
src/main.rs
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue