mirror of
https://github.com/arnaucube/chip8-rs.git
synced 2026-02-06 18:56:47 +01:00
u8 operations with wrapping to avoid overflow
This commit is contained in:
13
README.md
13
README.md
@@ -1,6 +1,17 @@
|
|||||||
# chip8-rs
|
# chip8-rs
|
||||||
|
|
||||||
CHIP-8 emulator written in Rust.
|
CHIP-8 emulator written in Rust.
|
||||||
(Done with the Go implementation: https://github.com/arnaucube/go-chip8)
|
|
||||||
|
*(Done with the Go implementation: https://github.com/arnaucube/go-chip8)*
|
||||||
|
|
||||||
https://en.wikipedia.org/wiki/CHIP-8
|
https://en.wikipedia.org/wiki/CHIP-8
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
```
|
||||||
|
./chip8-rs --file roms/invaders.c8
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub struct Chip8 {
|
|||||||
delay_timer: u8,
|
delay_timer: u8,
|
||||||
sound_timer: u8,
|
sound_timer: u8,
|
||||||
stack: [u16; 16],
|
stack: [u16; 16],
|
||||||
sp: isize,
|
sp: usize,
|
||||||
pub key: [u8; 16],
|
pub key: [u8; 16],
|
||||||
pub draw_flag: bool,
|
pub draw_flag: bool,
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ impl Chip8 {
|
|||||||
let y: usize = ((self.opcode & 0x00F0) >> 4) as usize;
|
let y: usize = ((self.opcode & 0x00F0) >> 4) as usize;
|
||||||
let nn: u8 = (self.opcode & 0x00FF) as u8;
|
let nn: u8 = (self.opcode & 0x00FF) as u8;
|
||||||
let nnn: u16 = (self.opcode & 0x0FFF) as u16;
|
let nnn: u16 = (self.opcode & 0x0FFF) as u16;
|
||||||
// println!("{:?} {:?}", self.opcode, self.pc);
|
// println!("{:x} {:?}", self.opcode, self.pc);
|
||||||
|
|
||||||
// Decode Opcode
|
// Decode Opcode
|
||||||
// https://en.wikipedia.org/wiki/CHIP-8#Opcode_table
|
// https://en.wikipedia.org/wiki/CHIP-8#Opcode_table
|
||||||
@@ -95,10 +95,10 @@ impl Chip8 {
|
|||||||
0x000E => {
|
0x000E => {
|
||||||
// 00EE Returns from a subroutine
|
// 00EE Returns from a subroutine
|
||||||
self.sp -= 1;
|
self.sp -= 1;
|
||||||
self.pc = self.stack[self.sp as usize];
|
self.pc = self.stack[self.sp];
|
||||||
self.pc += 2;
|
self.pc += 2;
|
||||||
}
|
}
|
||||||
_ => println!("unk {:x}", self.opcode),
|
_ => println!("Unknown opcode: {:x}", self.opcode),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x1000 => {
|
0x1000 => {
|
||||||
@@ -107,7 +107,7 @@ impl Chip8 {
|
|||||||
}
|
}
|
||||||
0x2000 => {
|
0x2000 => {
|
||||||
// 2NNN Calls subroutine at NNN
|
// 2NNN Calls subroutine at NNN
|
||||||
self.stack[self.sp as usize] = self.pc;
|
self.stack[self.sp] = self.pc;
|
||||||
self.sp += 1;
|
self.sp += 1;
|
||||||
self.pc = nnn;
|
self.pc = nnn;
|
||||||
}
|
}
|
||||||
@@ -143,7 +143,7 @@ impl Chip8 {
|
|||||||
}
|
}
|
||||||
0x7000 => {
|
0x7000 => {
|
||||||
// 7XNN Adds NN to VX. (Carry flag is not changed)
|
// 7XNN Adds NN to VX. (Carry flag is not changed)
|
||||||
self.v[x] += nn;
|
self.v[x] = self.v[x].wrapping_add(nn);
|
||||||
self.pc += 2;
|
self.pc += 2;
|
||||||
}
|
}
|
||||||
0x8000 => {
|
0x8000 => {
|
||||||
@@ -176,7 +176,7 @@ impl Chip8 {
|
|||||||
} else {
|
} else {
|
||||||
self.v[0xF] = 0;
|
self.v[0xF] = 0;
|
||||||
}
|
}
|
||||||
self.v[x] += self.v[y];
|
self.v[x] = self.v[x].wrapping_add(self.v[y]);
|
||||||
self.pc += 2;
|
self.pc += 2;
|
||||||
}
|
}
|
||||||
0x0005 => {
|
0x0005 => {
|
||||||
@@ -187,7 +187,7 @@ impl Chip8 {
|
|||||||
} else {
|
} else {
|
||||||
self.v[0xF] = 0;
|
self.v[0xF] = 0;
|
||||||
}
|
}
|
||||||
self.v[x] -= self.v[y];
|
self.v[x] = self.v[x].wrapping_sub(self.v[y]);
|
||||||
self.pc += 2;
|
self.pc += 2;
|
||||||
}
|
}
|
||||||
0x0006 => {
|
0x0006 => {
|
||||||
@@ -198,7 +198,7 @@ impl Chip8 {
|
|||||||
} else {
|
} else {
|
||||||
self.v[0xF] = 0;
|
self.v[0xF] = 0;
|
||||||
}
|
}
|
||||||
self.v[x] = self.v[x] >> 1;
|
self.v[x] = self.v[x].wrapping_shr(1);
|
||||||
self.pc += 2;
|
self.pc += 2;
|
||||||
}
|
}
|
||||||
0x0007 => {
|
0x0007 => {
|
||||||
@@ -209,7 +209,7 @@ impl Chip8 {
|
|||||||
} else {
|
} else {
|
||||||
self.v[0xF] = 0;
|
self.v[0xF] = 0;
|
||||||
}
|
}
|
||||||
self.v[x] = self.v[y] - self.v[x];
|
self.v[x] = self.v[y].wrapping_sub(self.v[x]);
|
||||||
self.pc += 2;
|
self.pc += 2;
|
||||||
}
|
}
|
||||||
0x000E => {
|
0x000E => {
|
||||||
@@ -220,10 +220,10 @@ impl Chip8 {
|
|||||||
} else {
|
} else {
|
||||||
self.v[0xF] = 0;
|
self.v[0xF] = 0;
|
||||||
}
|
}
|
||||||
self.v[x] = self.v[x] << 1;
|
self.v[x] = self.v[x].wrapping_shl(1);
|
||||||
self.pc += 2;
|
self.pc += 2;
|
||||||
}
|
}
|
||||||
_ => println!("unk {:x}", self.opcode),
|
_ => println!("Unknown opcode: {:x}", self.opcode),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x9000 => {
|
0x9000 => {
|
||||||
@@ -243,7 +243,7 @@ impl Chip8 {
|
|||||||
0xB000 => {
|
0xB000 => {
|
||||||
// BNNN Jumps to the address NNN plus V0
|
// BNNN Jumps to the address NNN plus V0
|
||||||
self.pc = nnn + self.v[0] as u16;
|
self.pc = nnn + self.v[0] as u16;
|
||||||
self.pc += 2;
|
// self.pc += 2;
|
||||||
}
|
}
|
||||||
0xC000 => {
|
0xC000 => {
|
||||||
// CXNN Sets VX to the result of a bitwise and operation on a
|
// CXNN Sets VX to the result of a bitwise and operation on a
|
||||||
@@ -275,9 +275,8 @@ impl Chip8 {
|
|||||||
}
|
}
|
||||||
if self.gfx[pos] == 1 {
|
if self.gfx[pos] == 1 {
|
||||||
self.v[0xF] = 1;
|
self.v[0xF] = 1;
|
||||||
} else {
|
|
||||||
self.gfx[pos] ^= 1;
|
|
||||||
}
|
}
|
||||||
|
self.gfx[pos] ^= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -305,7 +304,7 @@ impl Chip8 {
|
|||||||
}
|
}
|
||||||
self.pc += 2;
|
self.pc += 2;
|
||||||
}
|
}
|
||||||
_ => println!("unk {:x}", self.opcode),
|
_ => println!("Unknown opcode: {:x}", self.opcode),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0xF000 => {
|
0xF000 => {
|
||||||
@@ -378,10 +377,10 @@ impl Chip8 {
|
|||||||
}
|
}
|
||||||
self.pc += 2;
|
self.pc += 2;
|
||||||
}
|
}
|
||||||
_ => println!("unk {:x}", self.opcode),
|
_ => println!("Unknown opcode: {:x}", self.opcode),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => println!("opc {:x}", self.opcode),
|
_ => println!("Unknown opcode: {:x}", self.opcode),
|
||||||
}
|
}
|
||||||
if self.delay_timer > 0 {
|
if self.delay_timer > 0 {
|
||||||
self.delay_timer -= 1;
|
self.delay_timer -= 1;
|
||||||
|
|||||||
BIN
screenshots/s0.png
Normal file
BIN
screenshots/s0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
BIN
screenshots/s1.png
Normal file
BIN
screenshots/s1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
BIN
screenshots/s2.png
Normal file
BIN
screenshots/s2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
BIN
screenshots/s3.png
Normal file
BIN
screenshots/s3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
21
src/main.rs
21
src/main.rs
@@ -30,7 +30,7 @@ impl SdlEmulator {
|
|||||||
let video_subsystem = sdl_context.video().unwrap();
|
let video_subsystem = sdl_context.video().unwrap();
|
||||||
|
|
||||||
let window = video_subsystem
|
let window = video_subsystem
|
||||||
.window("rust-sdl2 demo", (w * zoom) as u32, (h * zoom) as u32)
|
.window("chip8-rs", (w * zoom) as u32, (h * zoom) as u32)
|
||||||
.position_centered()
|
.position_centered()
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -45,14 +45,15 @@ impl SdlEmulator {
|
|||||||
vkeys.insert(Keycode::Q, 0x04);
|
vkeys.insert(Keycode::Q, 0x04);
|
||||||
vkeys.insert(Keycode::W, 0x05);
|
vkeys.insert(Keycode::W, 0x05);
|
||||||
vkeys.insert(Keycode::E, 0x06);
|
vkeys.insert(Keycode::E, 0x06);
|
||||||
vkeys.insert(Keycode::R, 0x07);
|
vkeys.insert(Keycode::R, 0x0d);
|
||||||
vkeys.insert(Keycode::A, 0x08);
|
vkeys.insert(Keycode::A, 0x07);
|
||||||
vkeys.insert(Keycode::S, 0x09);
|
vkeys.insert(Keycode::S, 0x08);
|
||||||
vkeys.insert(Keycode::D, 0x0E);
|
vkeys.insert(Keycode::D, 0x09);
|
||||||
vkeys.insert(Keycode::F, 0x0A);
|
vkeys.insert(Keycode::F, 0x0e);
|
||||||
vkeys.insert(Keycode::Z, 0x00);
|
vkeys.insert(Keycode::Z, 0x0a);
|
||||||
vkeys.insert(Keycode::X, 0x0B);
|
vkeys.insert(Keycode::X, 0x00);
|
||||||
vkeys.insert(Keycode::V, 0x0F);
|
vkeys.insert(Keycode::C, 0x0b);
|
||||||
|
vkeys.insert(Keycode::V, 0x0f);
|
||||||
|
|
||||||
SdlEmulator {
|
SdlEmulator {
|
||||||
w,
|
w,
|
||||||
@@ -152,6 +153,6 @@ fn main() {
|
|||||||
e.draw_graphics();
|
e.draw_graphics();
|
||||||
}
|
}
|
||||||
e.set_keys();
|
e.set_keys();
|
||||||
std::thread::sleep(time::Duration::from_millis(1000 / 60));
|
std::thread::sleep(time::Duration::from_millis(200 / 60));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user