evolve egui interface

move more control back up to the ComputerManager
This commit is contained in:
Trevor Merritt 2024-10-22 08:25:08 -04:00
parent 665309c2e4
commit eccc3fe9e3
9 changed files with 338 additions and 202 deletions

152
.idea/workspace.xml generated
View File

@ -9,12 +9,13 @@
<component name="ChangeListManager">
<list default="true" id="9bcba7c5-ac1d-4216-959a-63faee7047bc" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gemma/src/chip8/instructions.rs" beforeDir="false" afterPath="$PROJECT_DIR$/gemma/src/chip8/instructions.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gemma/src/constants.rs" beforeDir="false" afterPath="$PROJECT_DIR$/gemma/src/constants.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gemmaegui/src/bin/gemmaegui_viewer.rs" beforeDir="false" afterPath="$PROJECT_DIR$/gemmaegui/src/bin/gemmaegui_viewer.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Cargo.lock" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gemma/src/chip8/computer_manager.rs" beforeDir="false" afterPath="$PROJECT_DIR$/gemma/src/chip8/computer_manager.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gemmaegui/src/bin/gemmaegui.rs" beforeDir="false" afterPath="$PROJECT_DIR$/gemmaegui/src/bin/gemmaegui.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gemmaimgui/src/bin/gemmaimgui.rs" beforeDir="false" afterPath="$PROJECT_DIR$/gemmaimgui/src/bin/gemmaimgui.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gemmautil/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/gemmautil/Cargo.toml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gemmautil/src/bin/ch8asm.rs" beforeDir="false" afterPath="$PROJECT_DIR$/gemmautil/src/bin/ch8asm.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gemmautil/src/bin/ch8disasm.rs" beforeDir="false" afterPath="$PROJECT_DIR$/gemmautil/src/bin/ch8disasm.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/test/gemma_disassembler_1_chip_logo_ch8_asm.asc" beforeDir="false" afterPath="$PROJECT_DIR$/resources/test/gemma_disassembler_1_chip_logo_ch8_asm.asc" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -42,87 +43,88 @@
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;Cargo.Build `Run emmagui`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Run gemmaegui_viewer`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Run gemmaegui`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Run gemmaimgui`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Run trevors_chip8_toy`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test chip8::computer::test::cls_test`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test chip8::instructions::test::LdStVx_test`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test chip8::instructions::test::random_produces_different_numbers`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test chip8::instructions::test::series8xy6_corex_tests`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test chip8::instructions::test::shl_vx_vy_test`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test chip8::util::test::byte_to_bool_changes`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test chip8::util::test::ubln`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test chip8::video::test::poke_byte_test`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test chip8::video::test::poke_byte`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test computer::test`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test instructions::test (1)`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test instructions::test`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build gemma.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Run emmagui.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Run gemmaegui.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Run gemmaegui_viewer.executor&quot;: &quot;Debug&quot;,
&quot;Cargo.Run gemmaimgui.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Run trevors_chip8_toy.executor&quot;: &quot;Debug&quot;,
&quot;Cargo.Test chip8::computer::test::cls_test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::computer::test::decoder_test_valid_instructions.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::LdStVx_test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::LdVxDt_test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::LdiAddr_test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::RndVxByte_test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::ShrVxVy_test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::SneVxVy_test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::decoder_test_invalid_instructions.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::draw_nibble_vx_vy_n_test.executor&quot;: &quot;Debug&quot;,
&quot;Cargo.Test chip8::instructions::test::encode_decode_test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::random_produces_different_numbers.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::series4000_corex_tests.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::series8xy4_corex_tests.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::series8xy6_corex_tests.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::shl_vx_vy_test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::instructions::test::subn_vx_vy_test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::util::test::bool_to_byte_changes.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::util::test::byte_to_bool_changes.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::util::test::ubln.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::video::test::poke_byte.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::video::test::poke_byte_test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::video::test::poke_sprite_test.executor&quot;: &quot;Debug&quot;,
&quot;Cargo.Test computer::test.executor&quot;: &quot;Debug&quot;,
&quot;Cargo.Test instructions::test (1).executor&quot;: &quot;Debug&quot;,
&quot;Cargo.Test instructions::test.executor&quot;: &quot;Debug&quot;,
&quot;Cargo.Test sound_timer::test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test util::test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test video::test.executor&quot;: &quot;Coverage&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.rust.reset.selective.auto.import&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;rename__instructions&quot;,
&quot;last_opened_file_path&quot;: &quot;/home/tmerritt/Projects/chip8_toy/gemmaimgui&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;org.rust.cargo.project.model.PROJECT_DISCOVERY&quot;: &quot;true&quot;,
&quot;org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon&quot;: &quot;&quot;,
&quot;org.rust.first.attach.projects&quot;: &quot;true&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;language.rust.build.tool.cargo&quot;
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"Cargo.Build `Run emmagui`.executor": "Run",
"Cargo.Build `Run gemmaegui_viewer`.executor": "Run",
"Cargo.Build `Run gemmaegui`.executor": "Run",
"Cargo.Build `Run gemmaimgui`.executor": "Run",
"Cargo.Build `Run trevors_chip8_toy`.executor": "Run",
"Cargo.Build `Test chip8::computer::test::cls_test`.executor": "Run",
"Cargo.Build `Test chip8::instructions::test::LdStVx_test`.executor": "Run",
"Cargo.Build `Test chip8::instructions::test::random_produces_different_numbers`.executor": "Run",
"Cargo.Build `Test chip8::instructions::test::series8xy6_corex_tests`.executor": "Run",
"Cargo.Build `Test chip8::instructions::test::shl_vx_vy_test`.executor": "Run",
"Cargo.Build `Test chip8::util::test::byte_to_bool_changes`.executor": "Run",
"Cargo.Build `Test chip8::util::test::ubln`.executor": "Run",
"Cargo.Build `Test chip8::video::test::poke_byte_test`.executor": "Run",
"Cargo.Build `Test chip8::video::test::poke_byte`.executor": "Run",
"Cargo.Build `Test computer::test`.executor": "Run",
"Cargo.Build `Test instructions::test (1)`.executor": "Run",
"Cargo.Build `Test instructions::test`.executor": "Run",
"Cargo.Build gemma.executor": "Run",
"Cargo.Run emmagui.executor": "Run",
"Cargo.Run gemmaegui.executor": "Debug",
"Cargo.Run gemmaegui_viewer.executor": "Debug",
"Cargo.Run gemmaimgui.executor": "Run",
"Cargo.Run trevors_chip8_toy.executor": "Debug",
"Cargo.Test chip8::computer::test::cls_test.executor": "Run",
"Cargo.Test chip8::computer::test::decoder_test_valid_instructions.executor": "Run",
"Cargo.Test chip8::instructions::test::LdStVx_test.executor": "Run",
"Cargo.Test chip8::instructions::test::LdVxDt_test.executor": "Run",
"Cargo.Test chip8::instructions::test::LdiAddr_test.executor": "Run",
"Cargo.Test chip8::instructions::test::RndVxByte_test.executor": "Run",
"Cargo.Test chip8::instructions::test::ShrVxVy_test.executor": "Run",
"Cargo.Test chip8::instructions::test::SneVxVy_test.executor": "Run",
"Cargo.Test chip8::instructions::test::decoder_test_invalid_instructions.executor": "Run",
"Cargo.Test chip8::instructions::test::draw_nibble_vx_vy_n_test.executor": "Debug",
"Cargo.Test chip8::instructions::test::encode_decode_test.executor": "Run",
"Cargo.Test chip8::instructions::test::random_produces_different_numbers.executor": "Run",
"Cargo.Test chip8::instructions::test::series4000_corex_tests.executor": "Run",
"Cargo.Test chip8::instructions::test::series8xy4_corex_tests.executor": "Run",
"Cargo.Test chip8::instructions::test::series8xy6_corex_tests.executor": "Run",
"Cargo.Test chip8::instructions::test::shl_vx_vy_test.executor": "Run",
"Cargo.Test chip8::instructions::test::subn_vx_vy_test.executor": "Run",
"Cargo.Test chip8::util::test::bool_to_byte_changes.executor": "Run",
"Cargo.Test chip8::util::test::byte_to_bool_changes.executor": "Run",
"Cargo.Test chip8::util::test::ubln.executor": "Run",
"Cargo.Test chip8::video::test::poke_byte.executor": "Run",
"Cargo.Test chip8::video::test::poke_byte_test.executor": "Run",
"Cargo.Test chip8::video::test::poke_sprite_test.executor": "Debug",
"Cargo.Test computer::test.executor": "Debug",
"Cargo.Test instructions::test (1).executor": "Debug",
"Cargo.Test instructions::test.executor": "Debug",
"Cargo.Test sound_timer::test.executor": "Run",
"Cargo.Test util::test.executor": "Run",
"Cargo.Test video::test.executor": "Coverage",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.rust.reset.selective.auto.import": "true",
"git-widget-placeholder": "master",
"last_opened_file_path": "/home/tmerritt/Projects/chip8_toy/gemmaimgui",
"node.js.detected.package.eslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
"org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "",
"org.rust.first.attach.projects": "true",
"settings.editor.selected.configurable": "language.rust.build.tool.cargo"
},
&quot;keyToStringList&quot;: {
&quot;com.intellij.ide.scratch.ScratchImplUtil$2/New Scratch File&quot;: [
&quot;TEXT&quot;
"keyToStringList": {
"com.intellij.ide.scratch.ScratchImplUtil$2/New Scratch File": [
"TEXT"
]
}
}</component>
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/gemmaimgui" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/gemmautil/src" />
<recent name="$PROJECT_DIR$/gemmaimgui/src/bin" />
</key>
</component>
<component name="RunManager" selected="Cargo.Run gemmaegui_viewer">
<component name="RunManager" selected="Cargo.Run gemmaegui">
<configuration name="Run gemmaegui" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="command" value="run --package gemmaegui --bin gemmaegui" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
@ -193,8 +195,8 @@
</configuration>
<recent_temporary>
<list>
<item itemvalue="Cargo.Run gemmaegui_viewer" />
<item itemvalue="Cargo.Run gemmaegui" />
<item itemvalue="Cargo.Run gemmaegui_viewer" />
<item itemvalue="Cargo.Run gemmaimgui" />
<item itemvalue="Cargo.Run gemmaimgui" />
<item itemvalue="Cargo.Run gemmaegui" />

64
Cargo.lock generated
View File

@ -1835,6 +1835,8 @@ version = "0.1.0"
dependencies = [
"clap",
"gemma",
"pest",
"pest_derive",
]
[[package]]
@ -3216,6 +3218,51 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pest"
version = "2.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442"
dependencies = [
"memchr",
"thiserror",
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn 2.0.79",
]
[[package]]
name = "pest_meta"
version = "2.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d"
dependencies = [
"once_cell",
"pest",
"sha2",
]
[[package]]
name = "pin-project"
version = "1.1.6"
@ -3748,6 +3795,17 @@ dependencies = [
"digest",
]
[[package]]
name = "sha2"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "shlex"
version = "1.3.0"
@ -4151,6 +4209,12 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "ucd-trie"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "uds_windows"
version = "1.1.0"

View File

@ -3,6 +3,7 @@ use std::thread;
use std::thread::{sleep, JoinHandle, Thread};
use std::time::{Duration, Instant};
use crate::chip8::computer::Chip8Computer;
use crate::chip8::cpu_states::Chip8CpuStates;
use crate::chip8::cpu_states::Chip8CpuStates::WaitingForInstruction;
pub enum ManagerDumpables {
@ -13,10 +14,10 @@ pub enum ManagerDumpables {
pub struct Chip8ComputerManager {
pub core_should_run: bool,
pub one_step: bool,
pub core_cycle_timer: bool,
pub core_last_cycle_start: Instant,
core_should_run: bool,
one_step: bool,
core_cycle_timer: bool,
core_last_cycle_start: Instant,
computer: Chip8Computer
}
@ -41,11 +42,10 @@ impl Chip8ComputerManager {
let core_handle = thread::spawn(move || {
loop {
let start_time = Instant::now();
println!("Core Thread starting at {start_time:?}");
// println!("Core Thread starting at {start_time:?}");
let sleep_time = Instant::now().duration_since(start_time).as_millis();
println!("Core Thread sleeping for {sleep_time}ms");
// println!("Core Thread sleeping for {sleep_time}ms");
sleep(Duration::from_millis((16 - sleep_time) as u64));
}
});
@ -53,16 +53,16 @@ impl Chip8ComputerManager {
Chip8ComputerManager::default()
}
pub fn start(managed: &mut Chip8ComputerManager) {
managed.core_should_run = true;
pub fn start(&mut self) {
self.core_should_run = true;
}
pub fn stop(managed: &mut Chip8ComputerManager) {
managed.core_should_run = false
pub fn stop(&mut self) {
self.core_should_run = false
}
pub fn step(managed: &mut Chip8ComputerManager) {
managed.one_step = true;
pub fn step(&mut self) {
self.one_step = true;
}
pub fn state(&mut self) -> &Chip8Computer {
@ -70,11 +70,16 @@ impl Chip8ComputerManager {
}
pub fn tick( &mut self) {
println!("STARTING TICK");
// println!("STARTING TICK");
if self.one_step | self.core_should_run {
match self.computer.state {
WaitingForInstruction => {
self.core_last_cycle_start = Instant::now();
self.computer.step_system();
println!("SYSTEM STEP");
}
_ => {}
}
};
if self.one_step {
println!("SYSTEM HALTED AFTER 1 STEP");
@ -86,6 +91,9 @@ impl Chip8ComputerManager {
pub fn press_key(&mut self, key_index: u8) {
self.computer.keypad.push_key(key_index);
if matches!(self.computer.state, Chip8CpuStates::WaitingForKey) {
self.computer.state = WaitingForInstruction
}
}
pub fn release_key(&mut self, key_index: u8) {
self.computer.keypad.release_key(key_index);

View File

@ -1,23 +1,31 @@
use std::path::PathBuf;
use std::time::Instant;
use crate::support::gemma_egui_support::{EGuiFileList, GemmaEguiSupport};
use crate::support::gemma_egui_state::GemmaEGuiState;
use eframe::egui;
use egui::Ui;
use egui::{Key, Ui};
use gemma::chip8::computer::Chip8Computer;
use gemma::chip8::computer_manager::Chip8ComputerManager;
mod support;
const LIN_KEYS: [[(Key, u8); 4]; 4] = [
[(Key::Num1, 0x01), (Key::Num2, 0x02), (Key::Num3, 0x03), (Key::Num4, 0x0c)],
[(Key::Q, 0x04), (Key::W, 0x05), (Key::E, 0x06), (Key::R, 0x0d)],
[(Key::A, 0x07), (Key::S, 0x08), (Key::D, 0x09), (Key::F, 0x0e)],
[(Key::Z, 0x0a), (Key::X, 0x00), (Key::C, 0x0b), (Key::V, 0x0F)]
];
#[derive(Default)]
struct DisplayOptions {
pub video: bool,
pub registers: bool,
pub memory: bool
pub memory: bool,
}
pub struct GemmaViewerState {
pub selected_file_index: i32,
pub selected_filename: String,
pub display_options: DisplayOptions
pub display_options: DisplayOptions,
}
impl Default for GemmaViewerState {
@ -25,7 +33,7 @@ impl Default for GemmaViewerState {
GemmaViewerState {
selected_file_index: -1,
selected_filename: String::new(),
display_options: Default::default()
display_options: Default::default(),
}
}
}
@ -68,14 +76,14 @@ fn main() -> eframe::Result {
// }
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
if ui.button("Start").clicked() {
computer.core_should_run = true;
computer.start();
}
if ui.button("Step").clicked() {
computer.one_step = true;
computer.step();
}
if ui.button("Stop").clicked() {
computer.core_should_run = false;
computer.stop();
// state.is_running = false;
}
if ui.button("Reset").clicked() {
@ -85,16 +93,30 @@ fn main() -> eframe::Result {
});
if ui.button(format!("Load {}", state.selected_filename)).clicked() {
// println!("Should load the bin now");
let read_bin = std::fs::read(PathBuf::from(format!("resources/roms/{}", state.selected_filename))).unwrap();
computer.load_bytes_to_system_memory(read_bin);
};
EGuiFileList::display_path(PathBuf::from("resources/roms"), &mut state.selected_filename, ui);
let input = ctx.input(|input| {
// loop through the keys we are checking...
for row in LIN_KEYS {
for (keyboard_key, keypad_key) in row {
if input.key_pressed(keyboard_key) {
computer.press_key(keypad_key);
// println!("KEY {keypad_key:02x} DOWN");
} else {
// release it if the user just did
if computer.is_key_pressed(keypad_key) {
computer.release_key(keypad_key);
// println!("KEY {keypad_key:02x} up");
}
// // load the bin...
// let read_bin = std::fs::read(PathBuf::from(format!("resources/roms/{}", state.selected_rom_filename))).unwrap();
// // ...then feed the system.
// system.load_bytes_to_memory(0x200, &read_bin);
// println!("Loaded {}", state.selected_rom_filename);
// }
// EGuiFileList::display_path(PathBuf::from("resources/roms"), &mut state.selected_rom_filename, ui);
}
}
}
});
ctx.request_repaint();
});
})
}

View File

@ -45,10 +45,8 @@ fn main() {
}
// END DEBUG CODE
for (key_code, key_reg) in LIN_KEYS {
if down_keys[key_code as usize] {
system.press_key(key_reg);
system.press_key(key_reg);
system.wait_for_instruction();
} else {

View File

@ -6,3 +6,5 @@ edition = "2021"
[dependencies]
gemma = { path = "../gemma" }
clap = { version = "4.5.20", features = ["derive"] }
pest = "2.7.14"
pest_derive = "2.7.14"

View File

@ -1,59 +1,87 @@
use std::fs::File;
use std::io;
use std::io::BufRead;
use std::path::Path;
use clap::Parser;
use gemma::chip8::instructions::Chip8CpuInstructions;
/// Ch8Asm
/// Converts well formed CH8ASM.
/// no variables.
/// no labels.
/// nothing fun.
pub struct Assembler {}
impl Assembler {
}
use std::fs;
// Ch8Asm
// Converts well formed CH8ASM.
// no variables.
// no labels.
// nothing fun.
use pest::Parser;
use pest_derive::Parser;
#[derive(Parser)]
#[command(version, about, long_about = None)]
struct AssemblerApp {
#[arg(short)]
input_file: Box<Path>,
}
#[grammar = "chip8_asm.pest"]
pub struct Chip8AsmParser;
fn main() {
println!("Taxation is Theft");
let result = AssemblerApp::parse();
let mut assembled_code: Vec<u8> = vec![];
// println!("Preparing to assemble {}", result.input_file.file_name());
let unparsed = fs::read_to_string("resources/test/gemma_disassembler_1_chip_logo_ch8_asm.asc").expect("Unable to read input");
let path = Path::new(result.input_file);
let file = Chip8AsmParser::parse(Rule::file, &unparsed).expect("Unable to parse. Try again.")
.next().unwrap();
// Open the file in read-only mode
let file = File::open(&path)?;
// Use a buffered reader for efficient reading
let reader = io::BufReader::new(file);
// Read the file line by line
for line in reader.lines() {
// Get the line, handling possible errors
let line = line?;
// Split the line by ';' and collect parts into a vector
let parts: Vec<&str> = line.split(';').collect();
// Print each part or process it as needed
for part in &parts {
println!("{}", part);
for record in file.into_inner() {
match record.as_rule() {
Rule::instruction => {
println!("INSTRUCTION = {:?}", record.into_inner().flatten())
}
_ => {
println!("UNHANDLED PART.");
}
}
}
// read the line split by a semicolon
}
mod test {
use super::*;
#[test]
fn bits_all_parse() {
println!("PARSED: {:?}",
Chip8AsmParser::parse(Rule::instruction, "CLS")
);
println!("PARSED: {:?}",
Chip8AsmParser::parse(Rule::parameter, "0x01")
);
let parsed = Chip8AsmParser::parse(Rule::comment, "; comment").unwrap();
for i in parsed {
println!("PARSED COMMENT -> {:?}", i);
}
let parsed =
Chip8AsmParser::parse(Rule::record, "CLS ; comment").unwrap();
for i in parsed {
println!("RULE PAIR THING: {:?}", i);
}
let parsed = Chip8AsmParser::parse(Rule::record, "ADDI 0x01 ; comment");
for i in parsed {
println!("RULE PAIR THING: {:?}", i);
}
let parsed = Chip8AsmParser::parse(Rule::record, "ADDI ; comment");
for i in parsed {
println!("RULE PAIR THING: {:?}", i);
}
println!("PARSED: {:?}",
Chip8AsmParser::parse(Rule::record, "ADD 0x01 0x02 ; Comment")
);
println!("PARSED: {:?}",
Chip8AsmParser::parse(Rule::record, "ADD ADD ADD")
);
println!("PARSED: {:?}",
Chip8AsmParser::parse(Rule::record, "ADD 0x01 0x02 ; Comment")
);
println!("PARSED: {:?}",
Chip8AsmParser::parse(Rule::record, "ADD 0x01 0x02 ; Comment")
);
}
}

View File

@ -18,23 +18,12 @@ struct DisassemblerApp {
struct Disassembler {}
impl Disassembler {
pub fn disassemble(from_data: Vec<u8>) -> String {
String::new()
}
}
fn main() {
println!("Taxation is Theft");
let result = DisassemblerApp::parse();
println!("PREPARING TO DISASSEMBLE {:?}", result.input_file.file_name());
// let target_file =
let source_file = result.input_file.to_str().unwrap();
let mut working_instruction: u16 = 0x0000;
// read the input file and loop through it byte by byte.
// read the input data and loop through it byte by byte.
let mut output_string = String::new();
for (offset, byte) in std::fs::read(source_file).unwrap().iter().enumerate() {
for (offset, byte) in from_data.iter().enumerate() {
working_instruction = (working_instruction << 8) | (*byte as u16);
if offset % 2 != 0 {
let decoded = Chip8CpuInstructions::decode(working_instruction);
@ -63,14 +52,30 @@ fn main() {
}
}
output_string
}
}
fn main() {
println!("Taxation is Theft");
let result = DisassemblerApp::parse();
println!("PREPARING TO DISASSEMBLE {:?}", result.input_file.file_name());
let source_file = result.input_file.to_str().unwrap();
let decompiled_program = Disassembler::disassemble(
std::fs::read(source_file).unwrap()
);
match result.output_file {
None => {
println!("Output to console.");
println!("OS: \n\n{}", output_string);
println!("OS: \n\n{}", decompiled_program);
}
Some(target) => {
println!("Output to {:?}", target);
std::fs::write(target, output_string).unwrap();
std::fs::write(target, decompiled_program).unwrap();
}
}
}

View File

@ -0,0 +1,7 @@
WHITESPACE = _{ " " }
instruction = { ASCII_ALPHA+ }
parameter = { "0X" ~ ASCII_HEX_DIGIT+ }
comment = { ";" ~ WHITESPACE* ~ ASCII* }
parameters = { parameter ~ (WHITESPACE* ~ "," ~ WHITESPACE* ~ parameter)* }
record = { instruction ~ WHITESPACE ~ parameters? ~ WHITESPACE* ~ comment? }
file = { SOI ~ (record ~ ("\r\n" | "\n"))* ~ EOI }