apply of clippy.
fixed missing imports and builds and tests as expected again
This commit is contained in:
parent
4fb2d6af29
commit
011874bca6
@ -2,7 +2,6 @@ use log::{debug};
|
|||||||
use crate::chip8::delay_timer::DelayTimer;
|
use crate::chip8::delay_timer::DelayTimer;
|
||||||
use crate::chip8::keypad::Keypad;
|
use crate::chip8::keypad::Keypad;
|
||||||
use crate::chip8::quirk_modes::QuirkMode;
|
use crate::chip8::quirk_modes::QuirkMode;
|
||||||
use crate::chip8::quirk_modes::QuirkMode::Chip8;
|
|
||||||
use crate::chip8::registers::Chip8Registers;
|
use crate::chip8::registers::Chip8Registers;
|
||||||
use crate::chip8::sound_timer::SoundTimer;
|
use crate::chip8::sound_timer::SoundTimer;
|
||||||
use crate::chip8::stack::Chip8Stack;
|
use crate::chip8::stack::Chip8Stack;
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
use std::sync::mpsc::{channel, Sender};
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::thread::{sleep, JoinHandle, Thread};
|
use std::thread::sleep;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use crate::chip8::computer::Chip8Computer;
|
use crate::chip8::computer::Chip8Computer;
|
||||||
use crate::chip8::cpu_states::Chip8CpuStates;
|
use crate::chip8::cpu_states::Chip8CpuStates;
|
||||||
@ -69,14 +68,11 @@ impl Chip8ComputerManager {
|
|||||||
// println!("STARTING TICK");
|
// println!("STARTING TICK");
|
||||||
let mut did_tick: bool = false;
|
let mut did_tick: bool = false;
|
||||||
if self.one_step | self.core_should_run {
|
if self.one_step | self.core_should_run {
|
||||||
match self.computer.state {
|
if let WaitingForInstruction = self.computer.state {
|
||||||
WaitingForInstruction => {
|
self.core_last_cycle_start = Instant::now();
|
||||||
self.core_last_cycle_start = Instant::now();
|
self.computer.step_system();
|
||||||
self.computer.step_system();
|
did_tick = true
|
||||||
did_tick = true
|
// println!("SYSTEM STEP");
|
||||||
// println!("SYSTEM STEP");
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if self.one_step {
|
if self.one_step {
|
||||||
|
|||||||
@ -3,6 +3,12 @@ pub struct DelayTimer {
|
|||||||
counter: u8
|
counter: u8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for DelayTimer {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl DelayTimer {
|
impl DelayTimer {
|
||||||
pub fn current(&self) -> u8 {
|
pub fn current(&self) -> u8 {
|
||||||
self.counter
|
self.counter
|
||||||
@ -19,7 +25,7 @@ impl DelayTimer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_timer(&mut self, new_value: u8) {
|
pub fn set_timer(&mut self, new_value: u8) {
|
||||||
self.counter = new_value as u8
|
self.counter = new_value
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(&mut self) {
|
pub fn tick(&mut self) {
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
use std::arch::x86_64::_mm_xor_pd;
|
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
use std::ops::{BitAnd, Deref, Shr};
|
use std::ops::BitAnd;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use chrono::ParseMonthError;
|
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use rand::{random, Rng};
|
use rand::Rng;
|
||||||
use crate::chip8::computer::{Chip8Computer};
|
use crate::chip8::computer::{Chip8Computer};
|
||||||
use crate::chip8::cpu_states::Chip8CpuStates::WaitingForKey;
|
use crate::chip8::cpu_states::Chip8CpuStates::WaitingForKey;
|
||||||
use crate::chip8::instructions::Chip8CpuInstructions::*;
|
use crate::chip8::instructions::Chip8CpuInstructions::*;
|
||||||
@ -548,11 +546,11 @@ impl Chip8CpuInstructions {
|
|||||||
|
|
||||||
pub fn encode(&self) -> u16 {
|
pub fn encode(&self) -> u16 {
|
||||||
match self {
|
match self {
|
||||||
Chip8CpuInstructions::SYS(target) => 0x0000 | (target & 0x0FFF) as u16,
|
Chip8CpuInstructions::SYS(target) => target & 0x0FFF,
|
||||||
Chip8CpuInstructions::CLS => 0x00E0,
|
Chip8CpuInstructions::CLS => 0x00E0,
|
||||||
Chip8CpuInstructions::RET => 0x00EE,
|
Chip8CpuInstructions::RET => 0x00EE,
|
||||||
Chip8CpuInstructions::JPA(new_addr) => 0x1000 | (new_addr & 0x0FFF) as u16,
|
Chip8CpuInstructions::JPA(new_addr) => 0x1000 | (new_addr & 0x0FFF),
|
||||||
Chip8CpuInstructions::CALL(address) => 0x2000 | (address & 0x0FFF) as u16,
|
Chip8CpuInstructions::CALL(address) => 0x2000 | (address & 0x0FFF),
|
||||||
Chip8CpuInstructions::SEX(vx_register, byte) => 0x3000 | ((*vx_register as u16) << 8) | (*byte as u16),
|
Chip8CpuInstructions::SEX(vx_register, byte) => 0x3000 | ((*vx_register as u16) << 8) | (*byte as u16),
|
||||||
Chip8CpuInstructions::SNEB(vx_register, byte) => 0x4000 | ((*vx_register as u16) << 8) | (*byte as u16),
|
Chip8CpuInstructions::SNEB(vx_register, byte) => 0x4000 | ((*vx_register as u16) << 8) | (*byte as u16),
|
||||||
Chip8CpuInstructions::SEY(x_register, y_register) => 0x5000 | ((*x_register as u16) << 8) | ((*y_register as u16) << 4),
|
Chip8CpuInstructions::SEY(x_register, y_register) => 0x5000 | ((*x_register as u16) << 8) | ((*y_register as u16) << 4),
|
||||||
@ -695,10 +693,10 @@ impl Chip8CpuInstructions {
|
|||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
let start_pc = input.registers.peek_pc();
|
let start_pc = input.registers.peek_pc();
|
||||||
input.registers.poke_pc(start_pc + 2);
|
input.registers.poke_pc(start_pc + 2);
|
||||||
let _ = match self {
|
match self {
|
||||||
// 0x0nnn Exit to System Call
|
// 0x0nnn Exit to System Call
|
||||||
Chip8CpuInstructions::SYS(new_address) => {
|
Chip8CpuInstructions::SYS(new_address) => {
|
||||||
input.registers.poke_pc(*new_address as u16);
|
input.registers.poke_pc(*new_address);
|
||||||
}
|
}
|
||||||
// * 0x00E0 Clear Screen
|
// * 0x00E0 Clear Screen
|
||||||
Chip8CpuInstructions::CLS => {
|
Chip8CpuInstructions::CLS => {
|
||||||
@ -710,17 +708,17 @@ impl Chip8CpuInstructions {
|
|||||||
}
|
}
|
||||||
// 0x1nnn Jump to Address
|
// 0x1nnn Jump to Address
|
||||||
Chip8CpuInstructions::JPA(new_address) => {
|
Chip8CpuInstructions::JPA(new_address) => {
|
||||||
input.registers.poke_pc(*new_address as u16);
|
input.registers.poke_pc(*new_address);
|
||||||
}
|
}
|
||||||
// 0x2nnn Call Subroutine
|
// 0x2nnn Call Subroutine
|
||||||
Chip8CpuInstructions::CALL(new_address) => {
|
Chip8CpuInstructions::CALL(new_address) => {
|
||||||
let return_address = input.registers.peek_pc();
|
let return_address = input.registers.peek_pc();
|
||||||
input.registers.poke_pc(*new_address as u16);
|
input.registers.poke_pc(*new_address);
|
||||||
input.stack.push(&return_address);
|
input.stack.push(&return_address);
|
||||||
}
|
}
|
||||||
// 0x3xkk Skip next instruction if Vx = kk.
|
// 0x3xkk Skip next instruction if Vx = kk.
|
||||||
Chip8CpuInstructions::SEX(vx_register, byte) => {
|
Chip8CpuInstructions::SEX(vx_register, byte) => {
|
||||||
if input.registers.peek(*vx_register as u8) == *byte as u8 {
|
if input.registers.peek(*vx_register) == { *byte } {
|
||||||
input.registers.advance_pc();
|
input.registers.advance_pc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -737,7 +735,7 @@ impl Chip8CpuInstructions {
|
|||||||
}
|
}
|
||||||
// 0x5xy0 Skip next instruction if Vx == Vy
|
// 0x5xy0 Skip next instruction if Vx == Vy
|
||||||
Chip8CpuInstructions::SEY(x, y) => {
|
Chip8CpuInstructions::SEY(x, y) => {
|
||||||
if input.registers.peek(*x as u8) == input.registers.peek(*y as u8) {
|
if input.registers.peek(*x) == input.registers.peek(*y) {
|
||||||
input.registers.advance_pc();
|
input.registers.advance_pc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -751,37 +749,37 @@ impl Chip8CpuInstructions {
|
|||||||
}
|
}
|
||||||
// 0x8xy0 Set value of Vy in Vx
|
// 0x8xy0 Set value of Vy in Vx
|
||||||
Chip8CpuInstructions::LDR_Y(x, y) => {
|
Chip8CpuInstructions::LDR_Y(x, y) => {
|
||||||
input.registers.poke(*x as u8, input.registers.peek(*y as u8));
|
input.registers.poke(*x, input.registers.peek(*y));
|
||||||
}
|
}
|
||||||
// 0x8xy1 Set Vx = Vx OR Vy
|
// 0x8xy1 Set Vx = Vx OR Vy
|
||||||
Chip8CpuInstructions::OR(x, y) => {
|
Chip8CpuInstructions::OR(x, y) => {
|
||||||
// shift them to 16 bit
|
// shift them to 16 bit
|
||||||
let working_16_x = input.registers.peek(*x as u8) as u16;
|
let working_16_x = input.registers.peek(*x) as u16;
|
||||||
let working_16_y = input.registers.peek(*y as u8) as u16;
|
let working_16_y = input.registers.peek(*y) as u16;
|
||||||
// OR them
|
// OR them
|
||||||
let working_16_or = working_16_x | working_16_y;
|
let working_16_or = working_16_x | working_16_y;
|
||||||
// shift them back to 8 bit.
|
// shift them back to 8 bit.
|
||||||
input.registers.poke(*x as u8, working_16_or as u8);
|
input.registers.poke(*x, working_16_or as u8);
|
||||||
debug!("OrVxVy [0x{x:1x}] [0x{y:1x}]")
|
debug!("OrVxVy [0x{x:1x}] [0x{y:1x}]")
|
||||||
}
|
}
|
||||||
// 0x8xy2 Set Vx = Vx AND Vy
|
// 0x8xy2 Set Vx = Vx AND Vy
|
||||||
Chip8CpuInstructions::AND(x, y) => {
|
Chip8CpuInstructions::AND(x, y) => {
|
||||||
let lhs_16 = input.registers.peek(*x as u8) as u16;
|
let lhs_16 = input.registers.peek(*x) as u16;
|
||||||
let rhs_16 = input.registers.peek(*y as u8) as u16;
|
let rhs_16 = input.registers.peek(*y) as u16;
|
||||||
input.registers.poke(*x as u8, (lhs_16 & rhs_16) as u8);
|
input.registers.poke(*x, (lhs_16 & rhs_16) as u8);
|
||||||
}
|
}
|
||||||
// 0x8xy3 Set Vx = Vx XOR Vy
|
// 0x8xy3 Set Vx = Vx XOR Vy
|
||||||
Chip8CpuInstructions::ORY(x, y) => {
|
Chip8CpuInstructions::ORY(x, y) => {
|
||||||
let lhs_16 = input.registers.peek(*x as u8) as u16;
|
let lhs_16 = input.registers.peek(*x) as u16;
|
||||||
let rhs_16 = input.registers.peek(*y as u8) as u16;
|
let rhs_16 = input.registers.peek(*y) as u16;
|
||||||
input.registers.poke(*x as u8, (lhs_16 ^ rhs_16) as u8);
|
input.registers.poke(*x, (lhs_16 ^ rhs_16) as u8);
|
||||||
}
|
}
|
||||||
// 0x8xy4 Set Vx = Vx + Vy (SET VF on Carry)
|
// 0x8xy4 Set Vx = Vx + Vy (SET VF on Carry)
|
||||||
Chip8CpuInstructions::ADDR(x, y) => {
|
Chip8CpuInstructions::ADDR(x, y) => {
|
||||||
let lhs = input.registers.peek(*x as u8) as i16;
|
let lhs = input.registers.peek(*x) as i16;
|
||||||
let rhs = input.registers.peek(*y as u8) as i16;
|
let rhs = input.registers.peek(*y) as i16;
|
||||||
let working = lhs + rhs;
|
let working = lhs + rhs;
|
||||||
input.registers.poke(*x as u8, working as u8);
|
input.registers.poke(*x, working as u8);
|
||||||
|
|
||||||
if working >= 0x100 {
|
if working >= 0x100 {
|
||||||
input.registers.poke(0xf, 0x01);
|
input.registers.poke(0xf, 0x01);
|
||||||
@ -808,7 +806,7 @@ impl Chip8CpuInstructions {
|
|||||||
1
|
1
|
||||||
};
|
};
|
||||||
|
|
||||||
input.registers.poke(*x as u8, result as u8);
|
input.registers.poke(*x, result as u8);
|
||||||
input.registers.poke(0x0f, borrow_flag);
|
input.registers.poke(0x0f, borrow_flag);
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::SHR(x, _) => {
|
Chip8CpuInstructions::SHR(x, _) => {
|
||||||
@ -820,7 +818,7 @@ impl Chip8CpuInstructions {
|
|||||||
|
|
||||||
// overflow check
|
// overflow check
|
||||||
let rotated = initial_value >> 1;
|
let rotated = initial_value >> 1;
|
||||||
input.registers.poke(*x as u8, rotated);
|
input.registers.poke(*x, rotated);
|
||||||
if initial_value.bitand(0b1) == 1 {
|
if initial_value.bitand(0b1) == 1 {
|
||||||
input.registers.poke(0x0f, 0x01);
|
input.registers.poke(0x0f, 0x01);
|
||||||
} else {
|
} else {
|
||||||
@ -832,8 +830,8 @@ impl Chip8CpuInstructions {
|
|||||||
// Set Vx = Vy - Vx, set VF = NOT borrow.
|
// Set Vx = Vy - Vx, set VF = NOT borrow.
|
||||||
//
|
//
|
||||||
// If Vy > Vx, then VF is set to 1, otherwise 0. Then Vx is subtracted from Vy, and the results stored in Vx.
|
// If Vy > Vx, then VF is set to 1, otherwise 0. Then Vx is subtracted from Vy, and the results stored in Vx.
|
||||||
let y_register = input.registers.peek(*y as u8);
|
let y_register = input.registers.peek(*y);
|
||||||
let x_register = input.registers.peek(*x as u8);
|
let x_register = input.registers.peek(*x);
|
||||||
let mut value_to_poke = 0;
|
let mut value_to_poke = 0;
|
||||||
|
|
||||||
let new_value = if y_register < x_register {
|
let new_value = if y_register < x_register {
|
||||||
@ -859,7 +857,7 @@ impl Chip8CpuInstructions {
|
|||||||
|
|
||||||
// overflow check
|
// overflow check
|
||||||
let rotated = initial_value << 1;
|
let rotated = initial_value << 1;
|
||||||
input.registers.poke(*x as u8, rotated);
|
input.registers.poke(*x, rotated);
|
||||||
if initial_value.bitand(0b10000000) == 0b10000000 {
|
if initial_value.bitand(0b10000000) == 0b10000000 {
|
||||||
input.registers.poke(0x0f, 0x01);
|
input.registers.poke(0x0f, 0x01);
|
||||||
} else {
|
} else {
|
||||||
@ -872,8 +870,8 @@ impl Chip8CpuInstructions {
|
|||||||
//
|
//
|
||||||
// The values of Vx and Vy are compared, and if they are not equal, the program counter is increased by 2.
|
// The values of Vx and Vy are compared, and if they are not equal, the program counter is increased by 2.
|
||||||
|
|
||||||
let x_reg_value = input.registers.peek(*vx_register as u8);
|
let x_reg_value = input.registers.peek(*vx_register);
|
||||||
let y_reg_value = input.registers.peek(*vy_register as u8);
|
let y_reg_value = input.registers.peek(*vy_register);
|
||||||
if x_reg_value != y_reg_value {
|
if x_reg_value != y_reg_value {
|
||||||
input.registers.advance_pc();
|
input.registers.advance_pc();
|
||||||
}
|
}
|
||||||
@ -912,7 +910,7 @@ impl Chip8CpuInstructions {
|
|||||||
let and_value: u8 = *byte;
|
let and_value: u8 = *byte;
|
||||||
let result = new_value & and_value;
|
let result = new_value & and_value;
|
||||||
debug!("RANDOM: [{new_value:02x}] AND: [{and_value:02x} Result: [{result:02x}]");
|
debug!("RANDOM: [{new_value:02x}] AND: [{and_value:02x} Result: [{result:02x}]");
|
||||||
input.registers.poke(*x as u8, new_value & *byte as u8)
|
input.registers.poke(*x, new_value & { *byte })
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::DRW(y, x, n) => {
|
Chip8CpuInstructions::DRW(y, x, n) => {
|
||||||
// Display n-byte sprite starting at memory location I at (Vx, Vy), set VF = collision.
|
// Display n-byte sprite starting at memory location I at (Vx, Vy), set VF = collision.
|
||||||
@ -968,7 +966,7 @@ impl Chip8CpuInstructions {
|
|||||||
// Skip next instruction if key with the value of Vx is pressed.
|
// Skip next instruction if key with the value of Vx is pressed.
|
||||||
//
|
//
|
||||||
// Checks the keyboard, and if the key corresponding to the value of Vx is currently in the down position, PC is increased by 2.
|
// Checks the keyboard, and if the key corresponding to the value of Vx is currently in the down position, PC is increased by 2.
|
||||||
let key_to_check = input.registers.peek(*x as u8);
|
let key_to_check = input.registers.peek(*x);
|
||||||
let is_pressed = input.keypad.pressed(key_to_check);
|
let is_pressed = input.keypad.pressed(key_to_check);
|
||||||
if is_pressed {
|
if is_pressed {
|
||||||
input.registers.advance_pc();
|
input.registers.advance_pc();
|
||||||
@ -982,7 +980,7 @@ impl Chip8CpuInstructions {
|
|||||||
// Checks the keyboard,
|
// Checks the keyboard,
|
||||||
// and if the key corresponding to the value of Vx is currently in the up position,
|
// and if the key corresponding to the value of Vx is currently in the up position,
|
||||||
// PC is increased by 2.
|
// PC is increased by 2.
|
||||||
let target_key = input.registers.peek(*x as u8);
|
let target_key = input.registers.peek(*x);
|
||||||
let is_pressed = input.keypad.pressed(target_key);
|
let is_pressed = input.keypad.pressed(target_key);
|
||||||
debug!("SnKpVx [{x:1x}]");
|
debug!("SnKpVx [{x:1x}]");
|
||||||
if !is_pressed {
|
if !is_pressed {
|
||||||
@ -995,7 +993,7 @@ impl Chip8CpuInstructions {
|
|||||||
//
|
//
|
||||||
// The value of DT is placed into Vx.
|
// The value of DT is placed into Vx.
|
||||||
let value_to_set = input.delay_timer.current();
|
let value_to_set = input.delay_timer.current();
|
||||||
input.registers.poke(*x as u8, value_to_set as u8);
|
input.registers.poke(*x, value_to_set);
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::LDRK(x) => {
|
Chip8CpuInstructions::LDRK(x) => {
|
||||||
// Fx0A - LD Vx, K
|
// Fx0A - LD Vx, K
|
||||||
@ -1009,11 +1007,11 @@ impl Chip8CpuInstructions {
|
|||||||
// Set delay timer = Vx.
|
// Set delay timer = Vx.
|
||||||
//
|
//
|
||||||
// DT is set equal to the value of Vx.
|
// DT is set equal to the value of Vx.
|
||||||
let new_time = input.registers.peek(*source_register as u8);
|
let new_time = input.registers.peek(*source_register);
|
||||||
input.delay_timer.set_timer(new_time);
|
input.delay_timer.set_timer(new_time);
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::LDIS(new_time) => {
|
Chip8CpuInstructions::LDIS(new_time) => {
|
||||||
let new_value = input.registers.peek(*new_time as u8);
|
let new_value = input.registers.peek(*new_time);
|
||||||
input.sound_timer.set_timer(new_value as i32);
|
input.sound_timer.set_timer(new_value as i32);
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::ADDI(x) => {
|
Chip8CpuInstructions::ADDI(x) => {
|
||||||
@ -1022,7 +1020,7 @@ impl Chip8CpuInstructions {
|
|||||||
//
|
//
|
||||||
// The values of I and Vx are added, and the results are stored in I.
|
// The values of I and Vx are added, and the results are stored in I.
|
||||||
let base = input.registers.peek_i();
|
let base = input.registers.peek_i();
|
||||||
let x_value = input.registers.peek(*x as u8);
|
let x_value = input.registers.peek(*x);
|
||||||
input.registers.poke_i(base + x_value as u16);
|
input.registers.poke_i(base + x_value as u16);
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::LDFX(x) => {
|
Chip8CpuInstructions::LDFX(x) => {
|
||||||
@ -1036,7 +1034,7 @@ impl Chip8CpuInstructions {
|
|||||||
let x_value: u8 = input.registers.peek(*x);
|
let x_value: u8 = input.registers.peek(*x);
|
||||||
|
|
||||||
let real_offset = x_value as u16 * 5;
|
let real_offset = x_value as u16 * 5;
|
||||||
input.registers.poke_i(real_offset as u16);
|
input.registers.poke_i(real_offset);
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::BCD(x) => {
|
Chip8CpuInstructions::BCD(x) => {
|
||||||
// Fx33 - LD B, Vx
|
// Fx33 - LD B, Vx
|
||||||
@ -1046,7 +1044,7 @@ impl Chip8CpuInstructions {
|
|||||||
// digit in memory at location in I, the tens digit at location I+1,
|
// digit in memory at location in I, the tens digit at location I+1,
|
||||||
// and the ones digit at location I+2.
|
// and the ones digit at location I+2.
|
||||||
|
|
||||||
let to_convert = input.registers.peek(*x as u8);
|
let to_convert = input.registers.peek(*x);
|
||||||
|
|
||||||
// how many hundreds
|
// how many hundreds
|
||||||
let hundreds = to_convert / 100;
|
let hundreds = to_convert / 100;
|
||||||
@ -1070,7 +1068,7 @@ impl Chip8CpuInstructions {
|
|||||||
// starting at the address in I.
|
// starting at the address in I.
|
||||||
let offset = input.registers.peek_i();
|
let offset = input.registers.peek_i();
|
||||||
for i in 0..=*x {
|
for i in 0..=*x {
|
||||||
input.memory.poke(offset + i as u16, input.registers.peek(i as u8));
|
input.memory.poke(offset + i as u16, input.registers.peek(i));
|
||||||
}
|
}
|
||||||
input.registers.poke_i(offset + 1);
|
input.registers.poke_i(offset + 1);
|
||||||
}
|
}
|
||||||
@ -1084,7 +1082,7 @@ impl Chip8CpuInstructions {
|
|||||||
debug!("WILL READ {num_loops:x} BYTES");
|
debug!("WILL READ {num_loops:x} BYTES");
|
||||||
for index in 0..num_loops {
|
for index in 0..num_loops {
|
||||||
let src_value = input.memory.peek(index as u16 + offset);
|
let src_value = input.memory.peek(index as u16 + offset);
|
||||||
input.registers.poke(index as u8, src_value);
|
input.registers.poke(index, src_value);
|
||||||
debug!("POKING Register 0x{index:02x} with 0x{src_value:04x} using offset 0x{offset:04x}");
|
debug!("POKING Register 0x{index:02x} with 0x{src_value:04x} using offset 0x{offset:04x}");
|
||||||
}
|
}
|
||||||
input.registers.poke_i(offset + 1);
|
input.registers.poke_i(offset + 1);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use crate::constants::CHIP8_KEYBOARD;
|
use crate::constants::CHIP8_KEYBOARD;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Keypad {
|
pub struct Keypad {
|
||||||
keys: [bool; 0x10],
|
keys: [bool; 0x10],
|
||||||
}
|
}
|
||||||
@ -30,13 +31,6 @@ impl Keypad {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Keypad {
|
|
||||||
fn default() -> Self {
|
|
||||||
Keypad {
|
|
||||||
keys: [ false; 16]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Keypad {
|
impl Keypad {
|
||||||
pub fn push_key(&mut self, key_index: u8) {
|
pub fn push_key(&mut self, key_index: u8) {
|
||||||
|
|||||||
@ -5,6 +5,12 @@ pub struct SoundTimer {
|
|||||||
counter: i32
|
counter: i32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for SoundTimer {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SoundTimer {
|
impl SoundTimer {
|
||||||
pub fn current(&self) -> i32 {
|
pub fn current(&self) -> i32 {
|
||||||
self.counter
|
self.counter
|
||||||
|
|||||||
@ -1,15 +1,9 @@
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Chip8Stack {
|
pub struct Chip8Stack {
|
||||||
items: Vec<u16>
|
items: Vec<u16>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Chip8Stack {
|
|
||||||
fn default() -> Self {
|
|
||||||
Chip8Stack {
|
|
||||||
items: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Chip8Stack {
|
impl Chip8Stack {
|
||||||
pub fn push(&mut self, new_value: &u16) {
|
pub fn push(&mut self, new_value: &u16) {
|
||||||
|
|||||||
@ -15,7 +15,7 @@ impl InstructionUtil {
|
|||||||
for i in 0..to_convert.len() {
|
for i in 0..to_convert.len() {
|
||||||
let new_bit = 0x1 << i;
|
let new_bit = 0x1 << i;
|
||||||
if to_convert[i] {
|
if to_convert[i] {
|
||||||
return_value = return_value | new_bit
|
return_value |= new_bit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return_value
|
return_value
|
||||||
@ -29,8 +29,8 @@ impl InstructionUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn join_bytes(high: u8, low: u8) -> u16 {
|
pub fn join_bytes(high: u8, low: u8) -> u16 {
|
||||||
let result = (high as u16) << 8 | low as u16;
|
|
||||||
result
|
(high as u16) << 8 | low as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
// nnn or addr - A 12-bit value, the lowest 12 bits of the instruction
|
// nnn or addr - A 12-bit value, the lowest 12 bits of the instruction
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
use log::{debug};
|
use log::{debug};
|
||||||
use crate::chip8::util::InstructionUtil;
|
|
||||||
use crate::chip8::video::Chip8VideoModes::{HighRes, LowRes};
|
use crate::chip8::video::Chip8VideoModes::{HighRes, LowRes};
|
||||||
use crate::constants::{CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_MEMORY, CHIP8_VIDEO_WIDTH, SCHIP_VIDE_MEMORY, SCHIP_VIDEO_HEIGHT, SCHIP_VIDEO_WIDTH};
|
use crate::constants::{CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_MEMORY, CHIP8_VIDEO_WIDTH, SCHIP_VIDE_MEMORY, SCHIP_VIDEO_HEIGHT, SCHIP_VIDEO_WIDTH};
|
||||||
|
|
||||||
@ -86,10 +85,8 @@ impl Chip8Video {
|
|||||||
let old_value = self.memory[effective_address as usize];
|
let old_value = self.memory[effective_address as usize];
|
||||||
let xored_value = new_value ^ old_value; // XOR of the video
|
let xored_value = new_value ^ old_value; // XOR of the video
|
||||||
// if the frame has already changed we dont care if it changed again.
|
// if the frame has already changed we dont care if it changed again.
|
||||||
if !self.has_frame_changed {
|
if !self.has_frame_changed && old_value != xored_value {
|
||||||
if old_value != xored_value {
|
self.has_frame_changed = true
|
||||||
self.has_frame_changed = true
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// println!("VIDEO POKE COMPLETE WITH {effective_address} SET TO {xored_value}");
|
// println!("VIDEO POKE COMPLETE WITH {effective_address} SET TO {xored_value}");
|
||||||
@ -164,7 +161,7 @@ impl Chip8Video {
|
|||||||
|
|
||||||
for current_row in 0..height {
|
for current_row in 0..height {
|
||||||
let row_offset = current_row * width;
|
let row_offset = current_row * width;
|
||||||
for current_column in (0..width - 4) {
|
for current_column in 0..width - 4 {
|
||||||
let source: usize = (row_offset + current_column) as usize;
|
let source: usize = (row_offset + current_column) as usize;
|
||||||
let target: usize = source + 4;
|
let target: usize = source + 4;
|
||||||
self.memory[target] = self.memory[source];
|
self.memory[target] = self.memory[source];
|
||||||
@ -184,7 +181,7 @@ impl Chip8Video {
|
|||||||
let max_source_row = height - how_far;
|
let max_source_row = height - how_far;
|
||||||
for current_source_row in (0..max_source_row).rev() {
|
for current_source_row in (0..max_source_row).rev() {
|
||||||
let current_source_offset = current_source_row * width;
|
let current_source_offset = current_source_row * width;
|
||||||
for current_source_column in (0..width) {
|
for current_source_column in 0..width {
|
||||||
let base_offset: usize = (current_source_offset + current_source_column) as usize;
|
let base_offset: usize = (current_source_offset + current_source_column) as usize;
|
||||||
let extended_offset: usize = base_offset + row_shift as usize;
|
let extended_offset: usize = base_offset + row_shift as usize;
|
||||||
self.memory[extended_offset] = self.memory[base_offset];
|
self.memory[extended_offset] = self.memory[base_offset];
|
||||||
|
|||||||
@ -34,7 +34,7 @@ fn reset_clears_video() {
|
|||||||
fn level1_test() {
|
fn level1_test() {
|
||||||
let mut x = Chip8Computer::new();
|
let mut x = Chip8Computer::new();
|
||||||
let level_1_rom = load_rom("1-chip8-logo.ch8");
|
let level_1_rom = load_rom("1-chip8-logo.ch8");
|
||||||
x.load_bytes_to_memory(0x200, (&level_1_rom).into());
|
x.load_bytes_to_memory(0x200, (&level_1_rom));
|
||||||
|
|
||||||
// run for 0x40 cycles
|
// run for 0x40 cycles
|
||||||
while x.num_cycles < 0x40 {
|
while x.num_cycles < 0x40 {
|
||||||
@ -49,7 +49,7 @@ fn level2_test() {
|
|||||||
// Load the IBM rom and run it.
|
// Load the IBM rom and run it.
|
||||||
// it takes 39 cycles to get to the end so lets run it 40.
|
// it takes 39 cycles to get to the end so lets run it 40.
|
||||||
let test_rom_to_run = load_rom("2-ibm-logo.ch8");
|
let test_rom_to_run = load_rom("2-ibm-logo.ch8");
|
||||||
x.load_bytes_to_memory(0x200, (&test_rom_to_run).into());
|
x.load_bytes_to_memory(0x200, (&test_rom_to_run));
|
||||||
for _ in 0..40 {
|
for _ in 0..40 {
|
||||||
x.step_system();
|
x.step_system();
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ fn level3_test() {
|
|||||||
let mut x = Chip8Computer::new();
|
let mut x = Chip8Computer::new();
|
||||||
|
|
||||||
x.load_bytes_to_memory(
|
x.load_bytes_to_memory(
|
||||||
0x200, (&load_rom("3-corax+.ch8")).into()
|
0x200, (&load_rom("3-corax+.ch8"))
|
||||||
);
|
);
|
||||||
for i in 0..0x180 {
|
for i in 0..0x180 {
|
||||||
x.step_system();
|
x.step_system();
|
||||||
@ -76,7 +76,7 @@ fn level3_test() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn rps_test() {
|
fn rps_test() {
|
||||||
let mut x = Chip8Computer::new();
|
let mut x = Chip8Computer::new();
|
||||||
x.load_bytes_to_memory(0x200, &load_rom("RPS.ch8").into());
|
x.load_bytes_to_memory(0x200, &load_rom("RPS.ch8"));
|
||||||
for _ in 0..0xF0 {
|
for _ in 0..0xF0 {
|
||||||
x.step_system();
|
x.step_system();
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ fn rps_test() {
|
|||||||
fn level4_test() {
|
fn level4_test() {
|
||||||
// flags
|
// flags
|
||||||
let mut x = Chip8Computer::new();
|
let mut x = Chip8Computer::new();
|
||||||
x.load_bytes_to_memory(0x200, &load_rom("4-flags.ch8").into());
|
x.load_bytes_to_memory(0x200, &load_rom("4-flags.ch8"));
|
||||||
for _ in 0..0x400 {
|
for _ in 0..0x400 {
|
||||||
x.step_system();
|
x.step_system();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
use std::collections::{BTreeMap, BTreeSet};
|
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use rand::random;
|
use rand::random;
|
||||||
use gemma::chip8::computer::Chip8Computer;
|
use gemma::chip8::computer::Chip8Computer;
|
||||||
use gemma::chip8::delay_timer::DelayTimer;
|
use gemma::chip8::delay_timer::DelayTimer;
|
||||||
use gemma::chip8::instructions::Chip8CpuInstructions;
|
use gemma::chip8::instructions::Chip8CpuInstructions;
|
||||||
use gemma::chip8::instructions::Chip8CpuInstructions::JPA;
|
|
||||||
use gemma::chip8::keypad::Keypad;
|
use gemma::chip8::keypad::Keypad;
|
||||||
use gemma::chip8::quirk_modes::QuirkMode::{Chip8, SChipModern, XOChip};
|
use gemma::chip8::quirk_modes::QuirkMode::Chip8;
|
||||||
use gemma::chip8::registers::Chip8Registers;
|
use gemma::chip8::registers::Chip8Registers;
|
||||||
use gemma::chip8::sound_timer::SoundTimer;
|
use gemma::chip8::sound_timer::SoundTimer;
|
||||||
use gemma::chip8::stack::Chip8Stack;
|
use gemma::chip8::stack::Chip8Stack;
|
||||||
@ -300,7 +298,7 @@ fn cls_test() {
|
|||||||
Chip8CpuInstructions::CLS.execute(&mut x);
|
Chip8CpuInstructions::CLS.execute(&mut x);
|
||||||
assert_eq!(x.registers.peek_pc(), 0x202);
|
assert_eq!(x.registers.peek_pc(), 0x202);
|
||||||
for i in 0..CHIP8_VIDEO_MEMORY {
|
for i in 0..CHIP8_VIDEO_MEMORY {
|
||||||
assert_eq!(x.video_memory.peek(i as u16), false);
|
assert!(!x.video_memory.peek(i as u16));
|
||||||
}
|
}
|
||||||
// draw some thing to the video memory
|
// draw some thing to the video memory
|
||||||
x.video_memory.poke(0x01, true);
|
x.video_memory.poke(0x01, true);
|
||||||
@ -310,7 +308,7 @@ fn cls_test() {
|
|||||||
Chip8CpuInstructions::CLS.execute(&mut x);
|
Chip8CpuInstructions::CLS.execute(&mut x);
|
||||||
|
|
||||||
for i in 0..CHIP8_VIDEO_MEMORY {
|
for i in 0..CHIP8_VIDEO_MEMORY {
|
||||||
assert_eq!(x.video_memory.peek(i as u16), false);
|
assert!(!x.video_memory.peek(i as u16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -778,7 +776,7 @@ fn keypad_keys_check() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn keypad_string_format_test() {
|
fn keypad_string_format_test() {
|
||||||
let mut k = Keypad::new();
|
let k = Keypad::new();
|
||||||
|
|
||||||
|
|
||||||
assert_eq!(k.format_as_string(), read_test_result("gemma_keypad_string_result.asc"));
|
assert_eq!(k.format_as_string(), read_test_result("gemma_keypad_string_result.asc"));
|
||||||
@ -998,7 +996,7 @@ fn video_default_test() {
|
|||||||
for i in 0..CHIP8_VIDEO_MEMORY {
|
for i in 0..CHIP8_VIDEO_MEMORY {
|
||||||
assert!(!x.clone().peek(i as u16));
|
assert!(!x.clone().peek(i as u16));
|
||||||
// then flip the value and test again.
|
// then flip the value and test again.
|
||||||
&x.poke(i as u16, true);
|
x.poke(i as u16, true);
|
||||||
assert!(x.clone().peek(i as u16));
|
assert!(x.clone().peek(i as u16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1050,7 +1048,7 @@ fn video_poke_2byte_test() {
|
|||||||
let mut expected = String::new();
|
let mut expected = String::new();
|
||||||
expected = "** **** **** ".to_string() + &*" ".repeat(64 - 16).to_string() + "\n";
|
expected = "** **** **** ".to_string() + &*" ".repeat(64 - 16).to_string() + "\n";
|
||||||
for i in 0..31 {
|
for i in 0..31 {
|
||||||
expected += &*((&*" ".repeat(64)).to_string() + "\n");
|
expected += &*((*" ".repeat(64)).to_string() + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(expected, x.format_as_string());
|
assert_eq!(expected, x.format_as_string());
|
||||||
@ -1065,7 +1063,7 @@ fn video_poke_multirow_2_byte_sprite() {
|
|||||||
fn video_cls_stddef() {
|
fn video_cls_stddef() {
|
||||||
let width = 64;
|
let width = 64;
|
||||||
let height = 32;
|
let height = 32;
|
||||||
let mut initial_memory = vec![];
|
let initial_memory = vec![];
|
||||||
let mut ws = String::new();
|
let mut ws = String::new();
|
||||||
let mut set_x = Chip8Video::new(initial_memory.into());
|
let mut set_x = Chip8Video::new(initial_memory.into());
|
||||||
for cbr in 0..32 {
|
for cbr in 0..32 {
|
||||||
@ -1186,7 +1184,7 @@ fn video_verify_change_registered() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn video_write_checkboard() {
|
fn video_write_checkboard() {
|
||||||
let mut v = build_checkerboard();
|
let v = build_checkerboard();
|
||||||
assert_eq!(v.clone().format_as_string(), read_test_result("test_video_write_checkerboard.asc"));
|
assert_eq!(v.clone().format_as_string(), read_test_result("test_video_write_checkerboard.asc"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1234,23 +1232,23 @@ fn video_collision_test() {
|
|||||||
// set the cell thats already set...
|
// set the cell thats already set...
|
||||||
x.poke(0x00, true);
|
x.poke(0x00, true);
|
||||||
// it becomes unset and theres a frame changed
|
// it becomes unset and theres a frame changed
|
||||||
assert_eq!(false, x.peek(0x00));
|
assert!(!x.peek(0x00));
|
||||||
|
|
||||||
assert_eq!(true, x.clone().has_frame_changed);
|
assert!(x.clone().has_frame_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn video_collision_test2() {
|
fn video_collision_test2() {
|
||||||
let mut x = Chip8Video::default();
|
let mut x = Chip8Video::default();
|
||||||
x.poke_byte(0x00, 0b11110000);
|
x.poke_byte(0x00, 0b11110000);
|
||||||
assert_eq!(true, x.has_frame_changed);
|
assert!(x.has_frame_changed);
|
||||||
x.tick();
|
x.tick();
|
||||||
assert_eq!(false, x.has_frame_changed);
|
assert!(!x.has_frame_changed);
|
||||||
// clear the 'has changed' flag
|
// clear the 'has changed' flag
|
||||||
|
|
||||||
// now set a no-collision value
|
// now set a no-collision value
|
||||||
x.poke_byte(0x00, 0b00001111);
|
x.poke_byte(0x00, 0b00001111);
|
||||||
assert_eq!(true, x.has_frame_changed);
|
assert!(x.has_frame_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1280,7 +1278,7 @@ fn video_scroll_down_10_row_test() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn video_high_res_has_right_resolution() {
|
fn video_high_res_has_right_resolution() {
|
||||||
let mut x = build_checkboard_hd();
|
let x = build_checkboard_hd();
|
||||||
println!("[{}]", x.format_as_string());
|
println!("[{}]", x.format_as_string());
|
||||||
assert_eq!(read_test_result("test_video_highdef.asc"), x.format_as_string());
|
assert_eq!(read_test_result("test_video_highdef.asc"), x.format_as_string());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use crate::support::gemma_egui_support::{EGuiFileList, GemmaEguiSupport};
|
use crate::support::gemma_egui_support::{EGuiFileList, GemmaEguiSupport};
|
||||||
use crate::support::gemma_egui_state::GemmaEGuiState;
|
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
use egui::{Key, Ui};
|
use egui::Key;
|
||||||
use gemma::chip8::computer::Chip8Computer;
|
use gemma::chip8::computer::Chip8Computer;
|
||||||
use gemma::chip8::computer_manager::Chip8ComputerManager;
|
use gemma::chip8::computer_manager::Chip8ComputerManager;
|
||||||
|
|
||||||
@ -58,7 +57,7 @@ fn main() -> eframe::Result {
|
|||||||
};
|
};
|
||||||
|
|
||||||
eframe::run_simple_native("EGUI Gemma", options, move |ctx, _frame| {
|
eframe::run_simple_native("EGUI Gemma", options, move |ctx, _frame| {
|
||||||
catppuccin_egui::set_theme(&ctx, catppuccin_egui::MOCHA);
|
catppuccin_egui::set_theme(ctx, catppuccin_egui::MOCHA);
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
let frame_start_time = Instant::now();
|
let frame_start_time = Instant::now();
|
||||||
|
|
||||||
@ -70,11 +69,11 @@ fn main() -> eframe::Result {
|
|||||||
ui.heading("EGUI Gemma");
|
ui.heading("EGUI Gemma");
|
||||||
|
|
||||||
// if state.display_memory {
|
// if state.display_memory {
|
||||||
GemmaEguiSupport::memory_view(&local_computer, ui);
|
GemmaEguiSupport::memory_view(local_computer, ui);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if state.display_registers {
|
// if state.display_registers {
|
||||||
GemmaEguiSupport::registers_view(&local_computer, ui);
|
GemmaEguiSupport::registers_view(local_computer, ui);
|
||||||
// }
|
// }
|
||||||
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
||||||
if ui.button("Start").clicked() {
|
if ui.button("Start").clicked() {
|
||||||
@ -100,7 +99,7 @@ fn main() -> eframe::Result {
|
|||||||
computer.load_bytes_to_system_memory(read_bin);
|
computer.load_bytes_to_system_memory(read_bin);
|
||||||
};
|
};
|
||||||
EGuiFileList::display_path(PathBuf::from("resources/roms"), &mut state.selected_filename, ui);
|
EGuiFileList::display_path(PathBuf::from("resources/roms"), &mut state.selected_filename, ui);
|
||||||
let input = ctx.input(|input| {
|
ctx.input(|input| {
|
||||||
// loop through the keys we are checking...
|
// loop through the keys we are checking...
|
||||||
for row in LIN_KEYS {
|
for row in LIN_KEYS {
|
||||||
for (keyboard_key, keypad_key) in row {
|
for (keyboard_key, keypad_key) in row {
|
||||||
|
|||||||
@ -1,13 +1,9 @@
|
|||||||
use std::fs::read_dir;
|
use std::fs::read_dir;
|
||||||
use std::ops::Index;
|
use std::path::PathBuf;
|
||||||
use std::path::{Display, PathBuf};
|
use egui::{Align, Color32, ComboBox, Pos2, TextBuffer};
|
||||||
use std::thread;
|
|
||||||
use std::time::Duration;
|
|
||||||
use egui::{Align, Color32, ComboBox, Direction, Pos2, Response, TextBuffer};
|
|
||||||
use egui::Rect;
|
use egui::Rect;
|
||||||
use egui::Vec2;
|
use egui::Vec2;
|
||||||
use egui::Ui;
|
use egui::Ui;
|
||||||
use egui::WidgetType::SelectableLabel;
|
|
||||||
use crate::Chip8Computer;
|
use crate::Chip8Computer;
|
||||||
|
|
||||||
const CELL_WIDTH: f32 = 5.0;
|
const CELL_WIDTH: f32 = 5.0;
|
||||||
@ -16,7 +12,7 @@ const CELL_HEIGHT: f32 = 5.0;
|
|||||||
pub struct EGuiFileList {}
|
pub struct EGuiFileList {}
|
||||||
impl EGuiFileList {
|
impl EGuiFileList {
|
||||||
pub fn display_path(root: PathBuf, selected_filename: &mut String, ui: &mut Ui) {
|
pub fn display_path(root: PathBuf, selected_filename: &mut String, ui: &mut Ui) {
|
||||||
let mut working_filename = selected_filename.clone();
|
let working_filename = selected_filename.clone();
|
||||||
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
||||||
// ui.label(format!("Displaying {}", root.to_str().unwrap_or("Unable to Load Path")));
|
// ui.label(format!("Displaying {}", root.to_str().unwrap_or("Unable to Load Path")));
|
||||||
ComboBox::from_label("Select ROM")
|
ComboBox::from_label("Select ROM")
|
||||||
|
|||||||
@ -1,20 +1,7 @@
|
|||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::fs::DirEntry;
|
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use gemma::{
|
|
||||||
chip8::computer::Chip8Computer,
|
|
||||||
constants::{CHIP8_MEMORY_SIZE, CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_WIDTH},
|
|
||||||
};
|
|
||||||
use imgui::*;
|
|
||||||
use sys::{ImColor, ImVec2, ImVector_ImU32};
|
|
||||||
use rand::random;
|
|
||||||
use gemma::chip8::computer_manager::Chip8ComputerManager;
|
use gemma::chip8::computer_manager::Chip8ComputerManager;
|
||||||
use gemma::chip8::cpu_states::Chip8CpuStates::WaitingForInstruction;
|
|
||||||
use gemma::chip8::system_memory::Chip8SystemMemory;
|
|
||||||
use support::{emmagui_support::GemmaImguiSupport, ui_state::ImGuiUiState};
|
use support::{emmagui_support::GemmaImguiSupport, ui_state::ImGuiUiState};
|
||||||
use clap::{Parser, Subcommand};
|
|
||||||
use gemma::chip8::quirk_modes::QuirkMode;
|
|
||||||
use gemma::chip8::quirk_modes::QuirkMode::Chip8;
|
|
||||||
|
|
||||||
|
|
||||||
mod support;
|
mod support;
|
||||||
@ -78,22 +65,22 @@ fn main() {
|
|||||||
}
|
}
|
||||||
// GUI Parts
|
// GUI Parts
|
||||||
if ui_state.show_video {
|
if ui_state.show_video {
|
||||||
GemmaImguiSupport::video_display(&system.state(), &ui_state, ui);
|
GemmaImguiSupport::video_display(system.state(), &ui_state, ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
GemmaImguiSupport::system_controls(&mut system, &mut ui_state, ui);
|
GemmaImguiSupport::system_controls(&mut system, &mut ui_state, ui);
|
||||||
|
|
||||||
if ui_state.show_registers {
|
if ui_state.show_registers {
|
||||||
GemmaImguiSupport::registers_view(&system.state(), ui);
|
GemmaImguiSupport::registers_view(system.state(), ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ui_state.show_memory {
|
if ui_state.show_memory {
|
||||||
let active_instruction = system.state().registers.peek_pc();
|
let active_instruction = system.state().registers.peek_pc();
|
||||||
GemmaImguiSupport::hex_memory_display(system.state().memory.clone(), (0x100, 0x10), active_instruction as i16, ui);
|
GemmaImguiSupport::hex_memory_display(system.state().memory, (0x100, 0x10), active_instruction as i16, ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ui_state.show_keypad {
|
if ui_state.show_keypad {
|
||||||
GemmaImguiSupport::keypad_display(&system.state(), ui);
|
GemmaImguiSupport::keypad_display(system.state(), ui);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,15 @@
|
|||||||
use std::ffi::OsString;
|
|
||||||
use gemma::constants::CHIP8_KEYBOARD;
|
use gemma::constants::CHIP8_KEYBOARD;
|
||||||
use std::fs::{File, read_dir};
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::time::Duration;
|
|
||||||
use imgui::{Condition, ImColor32, Ui};
|
use imgui::{Condition, ImColor32, Ui};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use gemma::chip8::computer::Chip8Computer;
|
use gemma::chip8::computer::Chip8Computer;
|
||||||
use gemma::chip8::computer_manager::Chip8ComputerManager;
|
use gemma::chip8::computer_manager::Chip8ComputerManager;
|
||||||
use gemma::chip8::computer_manager::ManagerDumpables::{Keyboard, Registers, Video};
|
use gemma::chip8::computer_manager::ManagerDumpables::{Keyboard, Registers, Video};
|
||||||
use gemma::chip8::keypad::Keypad;
|
|
||||||
use gemma::chip8::system_memory::Chip8SystemMemory;
|
use gemma::chip8::system_memory::Chip8SystemMemory;
|
||||||
use gemma::constants::{CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_WIDTH};
|
|
||||||
use crate::ImGuiUiState;
|
use crate::ImGuiUiState;
|
||||||
use crate::support::gui_file_list::GuiFileList;
|
use crate::support::gui_file_list::GuiFileList;
|
||||||
use super::ui_state;
|
|
||||||
|
|
||||||
const ROM_ROOT: &str = "/home/tmerritt/Projects/chip8_toy/resources/roms";
|
const ROM_ROOT: &str = "/home/tmerritt/Projects/chip8_toy/resources/roms";
|
||||||
|
|
||||||
@ -25,7 +20,7 @@ const CELL_HEIGHT: i32 = 5i32;
|
|||||||
|
|
||||||
impl GemmaImguiSupport {
|
impl GemmaImguiSupport {
|
||||||
pub fn keypad_display(system_to_display: &Chip8Computer, ui: &Ui) {
|
pub fn keypad_display(system_to_display: &Chip8Computer, ui: &Ui) {
|
||||||
ui.window(format!("Keypad"))
|
ui.window("Keypad".to_string())
|
||||||
.size([100.0, 100.0], Condition::FirstUseEver)
|
.size([100.0, 100.0], Condition::FirstUseEver)
|
||||||
.build(|| {
|
.build(|| {
|
||||||
for row in CHIP8_KEYBOARD {
|
for row in CHIP8_KEYBOARD {
|
||||||
@ -35,7 +30,7 @@ impl GemmaImguiSupport {
|
|||||||
} else {
|
} else {
|
||||||
format!("{:1x}", key)
|
format!("{:1x}", key)
|
||||||
};
|
};
|
||||||
ui.text(format!("{}", label));
|
ui.text(&label);
|
||||||
ui.same_line();
|
ui.same_line();
|
||||||
}
|
}
|
||||||
ui.text("");
|
ui.text("");
|
||||||
|
|||||||
@ -20,8 +20,8 @@ impl GuiFileList {
|
|||||||
known_files.sort();
|
known_files.sort();
|
||||||
|
|
||||||
for (index, entry) in known_files.iter().enumerate() {
|
for (index, entry) in known_files.iter().enumerate() {
|
||||||
let mut working_select = ui.selectable_config(format!("{}", entry.clone().into_string().unwrap()));
|
let mut working_select = ui.selectable_config(entry.clone().into_string().unwrap().to_string());
|
||||||
if entry.to_str().unwrap().to_string() == selected_filename.as_str().to_string() {
|
if *entry.to_str().unwrap() == *selected_filename.as_str() {
|
||||||
working_select = working_select.selected(true);
|
working_select = working_select.selected(true);
|
||||||
}
|
}
|
||||||
if working_select.build() {
|
if working_select.build() {
|
||||||
|
|||||||
@ -37,7 +37,7 @@ async fn run() -> anyhow::Result<String> {
|
|||||||
let mut event_pump = sdl.event_pump().map_err(|e| anyhow::anyhow!("Failed to get SDL event pump: {}", e))?;
|
let mut event_pump = sdl.event_pump().map_err(|e| anyhow::anyhow!("Failed to get SDL event pump: {}", e))?;
|
||||||
|
|
||||||
// Initial settings
|
// Initial settings
|
||||||
let mut color = [0.0, 0.0, 0.0, 1.0]; // Background color
|
let color = [0.0, 0.0, 0.0, 1.0]; // Background color
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
let mut timestep = TimeStep::new();
|
let mut timestep = TimeStep::new();
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,9 @@
|
|||||||
use std::fs::read_dir;
|
use std::fs::read_dir;
|
||||||
use std::ops::Index;
|
use std::path::PathBuf;
|
||||||
use std::path::{Display, PathBuf};
|
use egui::{Align, Color32, ComboBox, Pos2, TextBuffer};
|
||||||
use std::thread;
|
|
||||||
use std::time::Duration;
|
|
||||||
use egui::{Align, Color32, ComboBox, Direction, Pos2, Response, TextBuffer};
|
|
||||||
use egui::Rect;
|
use egui::Rect;
|
||||||
use egui::Vec2;
|
use egui::Vec2;
|
||||||
use egui::Ui;
|
use egui::Ui;
|
||||||
use egui::WidgetType::SelectableLabel;
|
|
||||||
use crate::Chip8Computer;
|
use crate::Chip8Computer;
|
||||||
|
|
||||||
const CELL_WIDTH: f32 = 5.0;
|
const CELL_WIDTH: f32 = 5.0;
|
||||||
@ -16,7 +12,7 @@ const CELL_HEIGHT: f32 = 5.0;
|
|||||||
pub struct EGuiFileList {}
|
pub struct EGuiFileList {}
|
||||||
impl EGuiFileList {
|
impl EGuiFileList {
|
||||||
pub fn display_path(root: PathBuf, selected_filename: &mut String, ui: &mut Ui) {
|
pub fn display_path(root: PathBuf, selected_filename: &mut String, ui: &mut Ui) {
|
||||||
let mut working_filename = selected_filename.clone();
|
let working_filename = selected_filename.clone();
|
||||||
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
||||||
// ui.label(format!("Displaying {}", root.to_str().unwrap_or("Unable to Load Path")));
|
// ui.label(format!("Displaying {}", root.to_str().unwrap_or("Unable to Load Path")));
|
||||||
ComboBox::from_label("Select ROM")
|
ComboBox::from_label("Select ROM")
|
||||||
@ -46,7 +42,7 @@ impl EGuiFileList {
|
|||||||
pub struct GemmaEguiSupport {}
|
pub struct GemmaEguiSupport {}
|
||||||
|
|
||||||
impl GemmaEguiSupport {
|
impl GemmaEguiSupport {
|
||||||
pub fn controls_view(mut system: &mut Chip8Computer, ui: &mut Ui) {
|
pub fn controls_view(system: &mut Chip8Computer, ui: &mut Ui) {
|
||||||
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
||||||
if ui.button("Start").clicked() {
|
if ui.button("Start").clicked() {
|
||||||
println!("Start");
|
println!("Start");
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{BufReader, Read};
|
use std::io::{BufReader, Read};
|
||||||
use clap::{Arg, Command, ArgAction, ValueEnum};
|
use clap::{Arg, Command};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct CliArgs {
|
struct CliArgs {
|
||||||
|
|||||||
@ -14,8 +14,6 @@ pub struct Chip8AsmParser;
|
|||||||
fn main() {
|
fn main() {
|
||||||
println!("Taxation is Theft");
|
println!("Taxation is Theft");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let unparsed = fs::read_to_string("resources/test/gemma_disassembler_1_chip_logo_ch8_asm.asc").expect("Unable to read input");
|
let unparsed = fs::read_to_string("resources/test/gemma_disassembler_1_chip_logo_ch8_asm.asc").expect("Unable to read input");
|
||||||
|
|
||||||
let file = Chip8AsmParser::parse(Rule::file, &unparsed).expect("Unable to parse. Try again.")
|
let file = Chip8AsmParser::parse(Rule::file, &unparsed).expect("Unable to parse. Try again.")
|
||||||
@ -34,7 +32,8 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use pest::Parser;
|
||||||
|
use crate::{Chip8AsmParser, Rule};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bits_all_parse() {
|
fn bits_all_parse() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user