From f9a81e200ccdebfc914bf441de2e841a2f450baf Mon Sep 17 00:00:00 2001 From: Denis Nutiu Date: Fri, 6 Dec 2024 23:51:05 +0200 Subject: [PATCH] implement generate random number + jump with offset --- Cargo.lock | 78 ++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/emulator.rs | 10 ++++++ src/instruction.rs | 13 ++++++++ src/main.rs | 2 +- 5 files changed, 103 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index c654a0a..f394490 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,7 @@ dependencies = [ "env_logger", "log", "pretty_assertions", + "rand", "ratatui", ] @@ -96,6 +97,12 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "cassowary" version = "0.3.0" @@ -260,6 +267,17 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "hashbrown" version = "0.15.2" @@ -414,6 +432,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + [[package]] name = "pretty_assertions" version = "1.4.1" @@ -442,6 +469,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "ratatui" version = "0.29.0" @@ -769,3 +826,24 @@ name = "yansi" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index cfd1973..aed2421 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ env_logger = "0.11.5" anyhow = "1.0.93" ratatui = "0.29.0" crossterm = "0.28.1" +rand = "0.8.5" [dev-dependencies] pretty_assertions = "1.4.1" diff --git a/src/emulator.rs b/src/emulator.rs index 53fcbe5..6d270bc 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -7,6 +7,7 @@ use std::fs::File; use std::io::Read; use std::path::Path; use std::{thread, time}; +use rand::Rng; /// Represents the display's width in pixels. const DISPLAY_WIDTH: usize = 64; @@ -269,6 +270,15 @@ where self.registers[vx as usize] = self.registers[vy as usize]; self.registers[vx as usize] >>= 1; } + ProcessorInstruction::JumpWithOffset(address) => { + let offset = self.registers[0x0]; + trace!("Jump With offset Address={address:04x} Offset={offset:04x}"); + + self.program_counter = address + offset as u16 + } + ProcessorInstruction::GenerateRandomNumber(register, data) => { + self.registers[register as usize] = rand::thread_rng().gen_range(0x00..0xFF) & data + } ProcessorInstruction::UnknownInstruction => { warn!("Unknown instruction: {:04x}, skipping.", instruction); } diff --git a/src/instruction.rs b/src/instruction.rs index 6453565..51d289c 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -50,6 +50,10 @@ pub enum ProcessorInstruction { /// Set VX = VY << 1 VF needs to be set to the bit that is shifted out. /// This instruction has different behaviour on CHIP-48 and SUPER-CHIP. ShiftLeft(u8, u8), + /// Jumps to the address and adds V0 offset. + JumpWithOffset(u16), + /// Generates a random number ANDed with the data and stores it in VX. + GenerateRandomNumber(u8, u8), /// Unknown instruction UnknownInstruction, } @@ -168,6 +172,15 @@ impl Instruction { Self::grab_first_nibble(data), Self::grab_middle_nibble(data), ), + (0xB, _, _, _) => { + ProcessorInstruction::JumpWithOffset(Self::grab_inner_data(data)) + } + (0xC, _, _, _) => { + ProcessorInstruction::GenerateRandomNumber( + Self::grab_first_nibble(data), + Self::grab_last_byte(data), + ) + } // Unknown instruction _ => ProcessorInstruction::UnknownInstruction, } diff --git a/src/main.rs b/src/main.rs index 893c006..ca02681 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ fn main() -> Result<(), anyhow::Error> { let mut emulator = Emulator::new(RatatuiDisplay::new()); - emulator.emulate(String::from("./roms/1-chip8-logo.ch8"))?; + emulator.emulate(String::from("./roms/3-corax+.ch8"))?; Ok(()) }