Implement working Dxyn Opcode
This commit is contained in:
parent
2e2497206f
commit
05f52dd397
10
src/emu.rs
10
src/emu.rs
|
@ -62,7 +62,7 @@ impl Chip8 {
|
|||
pub fn execute_cycle(&mut self) {
|
||||
self.opcode = self.get_opcode();
|
||||
println!("{:#x}", self.opcode);
|
||||
self.handle_opcode();
|
||||
self.execute_opcode();
|
||||
|
||||
self.delay.tick();
|
||||
self.sound.tick();
|
||||
|
@ -98,7 +98,7 @@ impl Chip8 {
|
|||
)
|
||||
}
|
||||
|
||||
fn handle_opcode(&mut self) {
|
||||
fn execute_opcode(&mut self) {
|
||||
let (nib_1, nib_2, nib_3, nib_4) = Self::get_nibs(self.opcode);
|
||||
|
||||
let nnn: u16 = self.opcode & 0x0FFF;
|
||||
|
@ -236,7 +236,7 @@ impl Chip8 {
|
|||
|
||||
fn add_vx_byte(&mut self, x: u8, kk: u8) {
|
||||
// calculate Vx + kk, then store it in Vx
|
||||
self.v[x as usize] += kk;
|
||||
self.v[x as usize] = self.v[x as usize].wrapping_add(kk);
|
||||
}
|
||||
|
||||
fn ld_vx_vy(&mut self, x: u8, y: u8) {
|
||||
|
@ -337,7 +337,7 @@ impl Chip8 {
|
|||
fn draw(&mut self, x: u8, y: u8, n: u8) {
|
||||
let i = self.i as usize;
|
||||
let draw_pos = (self.v[x as usize], self.v[y as usize]);
|
||||
let sprite_data = &self.v[i..(i + n as usize)];
|
||||
let sprite_data = &self.memory[i..(i + n as usize)];
|
||||
|
||||
let collision = self.display.draw_sprite(draw_pos, sprite_data);
|
||||
|
||||
|
@ -971,6 +971,6 @@ mod test {
|
|||
#[test]
|
||||
#[ignore]
|
||||
fn opcode_set_i_to_hex_sprite_loc_works() {
|
||||
todo!("Figure out how this instructin works")
|
||||
todo!("Figure out how this instruction works")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ fn main() {
|
|||
|
||||
let mut chip8: Chip8 = Default::default();
|
||||
chip8
|
||||
.load_rom(Path::new("./games/test_opcode.ch8"))
|
||||
.load_rom(Path::new("./games/ibm_logo.ch8"))
|
||||
.expect("Unable to load ROM");
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
|
|
|
@ -1,34 +1,45 @@
|
|||
#[derive(Copy, Clone)]
|
||||
pub struct Display {
|
||||
pub buf: [u8; Self::SCREEN_SIZE],
|
||||
pub buf: [u8; Self::WIDTH as usize * Self::HEIGHT as usize],
|
||||
}
|
||||
|
||||
impl Display {
|
||||
const SCREEN_SIZE: usize = 64 * 32;
|
||||
const WIDTH: u8 = 64;
|
||||
const HEIGHT: u8 = 32;
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.buf = [0x0; Self::SCREEN_SIZE]
|
||||
self.buf = [0x0; Self::WIDTH as usize * Self::HEIGHT as usize]
|
||||
}
|
||||
|
||||
pub fn draw_sprite(&mut self, coords: (u8, u8), data: &[u8]) -> bool {
|
||||
let x = coords.0;
|
||||
let y = coords.1;
|
||||
let x = coords.0 % Self::WIDTH;
|
||||
let y = coords.1 % Self::HEIGHT;
|
||||
let mut set_vf = false;
|
||||
// Each Byte is a row, and there are n bytes in data
|
||||
// When writing, x should not change but y should be incremented
|
||||
// after each iteration in the loop.
|
||||
for (i, byte) in data.iter().enumerate() {
|
||||
|
||||
// Each byte in data is a row, with the column being data.len() tall
|
||||
// This means when writing this sprite, x should not change, but y
|
||||
// should be incremented by 1 for every new byte we draw to the graphics buffer
|
||||
for (y_offset, byte) in data.iter().enumerate() {
|
||||
// Access every bit of the byte
|
||||
for j in 0..8 {
|
||||
let bit = (byte >> j) & 0x01;
|
||||
let display_index = j as usize + 8 * i as usize;
|
||||
for x_bit_offset in 0..8 {
|
||||
// The Coordinates of this bit in the gfx buffer
|
||||
let gfx_x = x + x_bit_offset;
|
||||
let gfx_y = y + y_offset as u8;
|
||||
|
||||
let old_value = self.buf[display_index];
|
||||
self.buf[display_index] ^= bit;
|
||||
let bit = (byte >> x_bit_offset) & 0x01;
|
||||
|
||||
if old_value == 0x01 && self.buf[display_index] == 0x00 {
|
||||
// Translate the gfx_x and gfx_y to an index in the 1D buffer
|
||||
let gfx_i = (Self::WIDTH as usize * gfx_y as usize) + gfx_x as usize;
|
||||
|
||||
if gfx_i >= self.buf.len() {
|
||||
break; // Stop Drawing this spite and move on to the next
|
||||
}
|
||||
|
||||
if bit == 0x1 && self.buf[gfx_i] == 0x1 {
|
||||
set_vf = true;
|
||||
}
|
||||
|
||||
self.buf[gfx_i] ^= bit;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,7 +50,7 @@ impl Display {
|
|||
impl Default for Display {
|
||||
fn default() -> Self {
|
||||
Display {
|
||||
buf: [0x0; Self::SCREEN_SIZE],
|
||||
buf: [0x0; Self::WIDTH as usize * Self::HEIGHT as usize],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue