lets try clippy
This commit is contained in:
1 parent
dfce9bf9fe
commit
4fb2d6af29
10 files changed
+491
-362
No files matched your search
Generated
+29
@@ -7,9 +7,13 @@
|
|||||||
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml" />
|
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
|
<<<<<<< Updated upstream
|
||||||
<list default="true" id="9bcba7c5-ac1d-4216-959a-63faee7047bc" name="Changes" comment="">
|
<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$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
|
=======
|
||||||
|
<list default="true" id="9bcba7c5-ac1d-4216-959a-63faee7047bc" name="Changes" comment="" />
|
||||||
|
>>>>>>> Stashed changes
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
@@ -54,17 +58,29 @@
|
|||||||
"Cargo.Build `Test chip8::video::test::poke_byte`.executor": "Run",
|
"Cargo.Build `Test chip8::video::test::poke_byte`.executor": "Run",
|
||||||
"Cargo.Build `Test chip8::video::test::scroll_down_1_row_test`.executor": "Run",
|
"Cargo.Build `Test chip8::video::test::scroll_down_1_row_test`.executor": "Run",
|
||||||
"Cargo.Build `Test computer::test`.executor": "Run",
|
"Cargo.Build `Test computer::test`.executor": "Run",
|
||||||
|
<<<<<<< Updated upstream
|
||||||
"Cargo.Build `Test instructions::test (1)`.executor": "Run",
|
"Cargo.Build `Test instructions::test (1)`.executor": "Run",
|
||||||
"Cargo.Build `Test instructions::test`.executor": "Run",
|
"Cargo.Build `Test instructions::test`.executor": "Run",
|
||||||
"Cargo.Build `Test video::test`.executor": "Run",
|
"Cargo.Build `Test video::test`.executor": "Run",
|
||||||
"Cargo.Build gemma.executor": "Run",
|
"Cargo.Build gemma.executor": "Run",
|
||||||
"Cargo.Run ch8asm.executor": "Run",
|
"Cargo.Run ch8asm.executor": "Run",
|
||||||
|
=======
|
||||||
|
"Cargo.Build `Test computer_dump_registers_to_string`.executor": "Run",
|
||||||
|
"Cargo.Build `Test instructions::test (1)`.executor": "Run",
|
||||||
|
"Cargo.Build `Test instructions::test`.executor": "Run",
|
||||||
|
"Cargo.Build `Test instructions_name_tests`.executor": "Run",
|
||||||
|
"Cargo.Build `Test video::test`.executor": "Run",
|
||||||
|
"Cargo.Build gemma.executor": "Run",
|
||||||
|
>>>>>>> Stashed changes
|
||||||
"Cargo.Run emmagui.executor": "Run",
|
"Cargo.Run emmagui.executor": "Run",
|
||||||
"Cargo.Run gemmaegui.executor": "Debug",
|
"Cargo.Run gemmaegui.executor": "Debug",
|
||||||
"Cargo.Run gemmaegui_viewer.executor": "Debug",
|
"Cargo.Run gemmaegui_viewer.executor": "Debug",
|
||||||
"Cargo.Run gemmaimgui.executor": "Debug",
|
"Cargo.Run gemmaimgui.executor": "Debug",
|
||||||
"Cargo.Run trevors_chip8_toy.executor": "Debug",
|
"Cargo.Run trevors_chip8_toy.executor": "Debug",
|
||||||
|
<<<<<<< Updated upstream
|
||||||
"Cargo.Test ch8asm::test.executor": "Debug",
|
"Cargo.Test ch8asm::test.executor": "Debug",
|
||||||
|
=======
|
||||||
|
>>>>>>> Stashed changes
|
||||||
"Cargo.Test chip8::computer::test::cls_test.executor": "Run",
|
"Cargo.Test chip8::computer::test::cls_test.executor": "Run",
|
||||||
"Cargo.Test chip8::computer::test::decoder_test_valid_instructions.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::LdStVx_test.executor": "Run",
|
||||||
@@ -93,9 +109,17 @@
|
|||||||
"Cargo.Test chip8::video::test::scroll_down_1_row_test.executor": "Run",
|
"Cargo.Test chip8::video::test::scroll_down_1_row_test.executor": "Run",
|
||||||
"Cargo.Test chip8::video::test::write_checkboard.executor": "Run",
|
"Cargo.Test chip8::video::test::write_checkboard.executor": "Run",
|
||||||
"Cargo.Test computer::test.executor": "Debug",
|
"Cargo.Test computer::test.executor": "Debug",
|
||||||
|
<<<<<<< Updated upstream
|
||||||
"Cargo.Test instruction_tests.executor": "Run",
|
"Cargo.Test instruction_tests.executor": "Run",
|
||||||
"Cargo.Test instructions::test (1).executor": "Debug",
|
"Cargo.Test instructions::test (1).executor": "Debug",
|
||||||
"Cargo.Test instructions::test.executor": "Debug",
|
"Cargo.Test instructions::test.executor": "Debug",
|
||||||
|
=======
|
||||||
|
"Cargo.Test computer_dump_registers_to_string.executor": "Run",
|
||||||
|
"Cargo.Test encode_decode_name_test.executor": "Debug",
|
||||||
|
"Cargo.Test instructions::test (1).executor": "Debug",
|
||||||
|
"Cargo.Test instructions::test.executor": "Debug",
|
||||||
|
"Cargo.Test instructions_name_tests.executor": "Run",
|
||||||
|
>>>>>>> Stashed changes
|
||||||
"Cargo.Test sound_timer::test.executor": "Run",
|
"Cargo.Test sound_timer::test.executor": "Run",
|
||||||
"Cargo.Test util::test.executor": "Run",
|
"Cargo.Test util::test.executor": "Run",
|
||||||
"Cargo.Test video::test.executor": "Debug",
|
"Cargo.Test video::test.executor": "Debug",
|
||||||
@@ -258,9 +282,14 @@
|
|||||||
<workItem from="1729353568282" duration="4624000" />
|
<workItem from="1729353568282" duration="4624000" />
|
||||||
<workItem from="1729375372050" duration="3579000" />
|
<workItem from="1729375372050" duration="3579000" />
|
||||||
<workItem from="1729797802231" duration="9220000" />
|
<workItem from="1729797802231" duration="9220000" />
|
||||||
|
<<<<<<< Updated upstream
|
||||||
<workItem from="1729992186995" duration="4475000" />
|
<workItem from="1729992186995" duration="4475000" />
|
||||||
<workItem from="1730040713781" duration="2808000" />
|
<workItem from="1730040713781" duration="2808000" />
|
||||||
<workItem from="1730065968935" duration="6000" />
|
<workItem from="1730065968935" duration="6000" />
|
||||||
|
=======
|
||||||
|
<workItem from="1729992186995" duration="4226000" />
|
||||||
|
<workItem from="1730115460078" duration="31140000" />
|
||||||
|
>>>>>>> Stashed changes
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
XOChip
|
||||||
|
- 00DN
|
||||||
|
- scroll screen content up N hires pixel, in XO-CHIP only selected planes are scrolled
|
||||||
@@ -118,8 +118,8 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script>
|
<script>
|
||||||
var data = {"files":[{"path":["/","home","tmerritt","Projects","trevors_chip8_toy","gemma","src","chip8","computer.rs"],"content":"use log::{debug};\nuse crate::chip8::delay_timer::DelayTimer;\nuse crate::chip8::keypad::Keypad;\nuse crate::chip8::quirk_modes::QuirkMode;\nuse crate::chip8::registers::Chip8Registers;\nuse crate::chip8::sound_timer::SoundTimer;\nuse crate::chip8::stack::Chip8Stack;\n\nuse super::{\n cpu_states::Chip8CpuStates, instructions::Chip8CpuInstructions, system_memory::Chip8SystemMemory, video::Chip8Video,\n};\n\n#[derive(Clone)]\npub struct Chip8Computer {\n pub num_cycles: i32,\n pub memory: Chip8SystemMemory,\n pub registers: Chip8Registers,\n pub sound_timer: SoundTimer,\n pub delay_timer: DelayTimer,\n pub video_memory: Chip8Video,\n pub state: Chip8CpuStates,\n pub keypad: Keypad,\n pub stack: Chip8Stack,\n pub quirk_mode: QuirkMode\n}\nimpl Default for Chip8Computer {\n fn default() -\u003e Self {\n Self {\n num_cycles: 0,\n memory: Chip8SystemMemory::default(),\n video_memory: Chip8Video::default(),\n registers: Chip8Registers::default(),\n sound_timer: SoundTimer::new(),\n delay_timer: DelayTimer::new(),\n state: Chip8CpuStates::default(),\n keypad: Keypad::default(),\n stack: Chip8Stack::default(),\n quirk_mode: QuirkMode::default()\n }\n }\n}\n\nimpl Chip8Computer {\n pub fn reset(\u0026mut self) {\n self.video_memory.reset();\n self.num_cycles = 0;\n self.registers.reset();\n self.delay_timer.reset();\n self.sound_timer.reset();\n self.stack.reset();\n self.memory.reset();\n self.quirk_mode = QuirkMode::Chip8;\n }\n\n pub fn dump_keypad_to_string(\u0026self) -\u003e String {\n self.keypad.format_as_string()\n }\n\n pub fn dump_registers_to_string(\u0026self) -\u003e String {\n self.registers.format_as_string()\n }\n\n pub fn dump_video_to_string(\u0026self) -\u003e String {\n self.clone().video_memory.format_as_string()\n }\n\n pub fn new_with_program(new_program: Vec\u003cu16\u003e) -\u003e Self {\n let mut working = Chip8Computer::new();\n\n for (i, \u0026word) in new_program.iter().enumerate() {\n let high = (word \u003e\u003e 8) as u8;\n let low = (word \u0026 0xff) as u8;\n let base_offset = (i * 2) as u16;\n working.memory.poke(base_offset, high);\n working.memory.poke(base_offset + 1, low);\n }\n working\n }\n pub fn new() -\u003e Self {\n Chip8Computer::default()\n }\n\n pub fn load_bytes_to_memory(\u0026mut self, offset: u16, to_load: \u0026Vec\u003cu8\u003e) {\n let total_len = to_load.len() as u16;\n for current_index in 0..total_len {\n let new_value = to_load[current_index as usize];\n let new_location = current_index + offset;\n self.memory.poke(new_location, new_value);\n }\n self.registers.set_pc(offset);\n }\n\n pub fn step_system(\u0026mut self) -\u003e \u0026mut Chip8Computer {\n debug!(\"Stepping System 1 Step\");\n // read the next instruction\n let local_memory = \u0026self.memory;\n\n // let mut working_instruction: u16 = 0b0000000000000000;\n let start_pc = self.registers.peek_pc();\n let high_byte = (local_memory.peek(start_pc) as u16).rotate_left(8);\n let low_byte = local_memory.peek(start_pc + 1) as u16;\n let result = high_byte | low_byte;\n let decoded_instruction =\n Chip8CpuInstructions::decode(result);\n // todo: THIS IS BAD AND IS A SIDE EFFECT\n decoded_instruction.execute(self);\n\n match self.state {\n Chip8CpuStates::WaitingForInstruction =\u003e {\n self.sound_timer.tick();\n self.delay_timer.tick();\n self.video_memory.tick();\n self.num_cycles += 1;\n }\n Chip8CpuStates::WaitingForKey =\u003e {\n debug!(\"waiting for a key press...\");\n }\n _ =\u003e {}\n }\n self\n }\n}\n","traces":[{"line":27,"address":[842574,842064],"length":1,"stats":{"Line":6}},{"line":30,"address":[1160064],"length":1,"stats":{"Line":2}},{"line":31,"address":[842110],"length":1,"stats":{"Line":4}},{"line":32,"address":[1160095],"length":1,"stats":{"Line":4}},{"line":33,"address":[377006],"length":1,"stats":{"Line":6}},{"line":34,"address":[787405],"length":1,"stats":{"Line":4}},{"line":35,"address":[1160188],"length":1,"stats":{"Line":6}},{"line":36,"address":[42137255],"length":1,"stats":{"Line":4}},{"line":37,"address":[602778],"length":1,"stats":{"Line":6}},{"line":38,"address":[3564013],"length":1,"stats":{"Line":5}},{"line":44,"address":[377392],"length":1,"stats":{"Line":1}},{"linLine truncated
|
var data = {"files":[{"path":["/","home","tmerritt","Projects","chip8_toy","gemma","src","chip8","computer.rs"],"content":"use log::{debug};\nuse crate::chip8::delay_timer::DelayTimer;\nuse crate::chip8::keypad::Keypad;\nuse crate::chip8::quirk_modes::QuirkMode;\nuse crate::chip8::quirk_modes::QuirkMode::Chip8;\nuse crate::chip8::registers::Chip8Registers;\nuse crate::chip8::sound_timer::SoundTimer;\nuse crate::chip8::stack::Chip8Stack;\n\nuse super::{\n cpu_states::Chip8CpuStates, instructions::Chip8CpuInstructions, system_memory::Chip8SystemMemory, video::Chip8Video,\n};\n\n#[derive(Clone)]\npub struct Chip8Computer {\n pub num_cycles: i32,\n pub memory: Chip8SystemMemory,\n pub registers: Chip8Registers,\n pub sound_timer: SoundTimer,\n pub delay_timer: DelayTimer,\n pub video_memory: Chip8Video,\n pub state: Chip8CpuStates,\n pub keypad: Keypad,\n pub stack: Chip8Stack,\n pub quirk_mode: QuirkMode\n}\nimpl Default for Chip8Computer {\n fn default() -\u003e Self {\n Self {\n num_cycles: 0,\n memory: Chip8SystemMemory::default(),\n video_memory: Chip8Video::default(),\n registers: Chip8Registers::default(),\n sound_timer: SoundTimer::new(),\n delay_timer: DelayTimer::new(),\n state: Chip8CpuStates::default(),\n keypad: Keypad::default(),\n stack: Chip8Stack::default(),\n quirk_mode: QuirkMode::default()\n }\n }\n}\n\nimpl Chip8Computer {\n pub fn reset(\u0026mut self) {\n self.video_memory.reset();\n self.num_cycles = 0;\n self.registers.reset();\n self.delay_timer.reset();\n self.sound_timer.reset();\n self.stack.reset();\n self.memory.reset();\n self.quirk_mode = QuirkMode::Chip8;\n }\n\n pub fn dump_keypad_to_string(\u0026self) -\u003e String {\n self.keypad.format_as_string()\n }\n\n pub fn dump_registers_to_string(\u0026self) -\u003e String {\n self.registers.format_as_string()\n }\n\n pub fn dump_video_to_string(\u0026self) -\u003e String {\n self.clone().video_memory.format_as_string()\n }\n\n pub fn new_with_program(new_program: Vec\u003cu16\u003e) -\u003e Self {\n let mut working = Chip8Computer::new();\n\n for (i, \u0026word) in new_program.iter().enumerate() {\n let high = (word \u003e\u003e 8) as u8;\n let low = (word \u0026 0xff) as u8;\n let base_offset = (i * 2) as u16;\n working.memory.poke(base_offset, high);\n working.memory.poke(base_offset + 1, low);\n }\n working\n }\n pub fn new() -\u003e Self {\n Chip8Computer::default()\n }\n\n pub fn load_bytes_to_memory(\u0026mut self, offset: u16, to_load: \u0026Vec\u003cu8\u003e) {\n let total_len = to_load.len() as u16;\n for current_index in 0..total_len {\n let new_value = to_load[current_index as usize];\n let new_location = current_index + offset;\n self.memory.poke(new_location, new_value);\n }\n self.registers.set_pc(offset);\n }\n\n pub fn step_system(\u0026mut self) -\u003e \u0026mut Chip8Computer {\n debug!(\"Stepping System 1 Step\");\n // read the next instruction\n let local_memory = \u0026self.memory;\n\n // let mut working_instruction: u16 = 0b0000000000000000;\n let start_pc = self.registers.peek_pc();\n let high_byte = (local_memory.peek(start_pc) as u16).rotate_left(8);\n let low_byte = local_memory.peek(start_pc + 1) as u16;\n let result = high_byte | low_byte;\n let decoded_instruction =\n Chip8CpuInstructions::decode(result, \u0026self.quirk_mode);\n // todo: THIS IS BAD AND IS A SIDE EFFECT\n decoded_instruction.execute(self);\n\n match self.state {\n Chip8CpuStates::WaitingForInstruction =\u003e {\n self.sound_timer.tick();\n self.delay_timer.tick();\n self.video_memory.tick();\n self.num_cycles += 1;\n }\n Chip8CpuStates::WaitingForKey =\u003e {\n debug!(\"waiting for a key press...\");\n }\n _ =\u003e {}\n }\n self\n }\n}\n","traces":[{"line":28,"address":[1160032,1160542],"length":1,"stats":{"Line":3}},{"line":31,"address":[602624],"length":1,"stats":{"Line":7}},{"line":32,"address":[377074],"length":1,"stats":{"Line":7}},{"line":33,"address":[754655],"length":1,"stats":{"Line":8}},{"line":34,"address":[842350],"length":1,"stats":{"Line":7}},{"line":35,"address":[602733],"length":1,"stats":{"Line":4}},{"line":36,"address":[842380],"length":1,"stats":{"Line":7}},{"line":37,"address":[685351],"length":1,"stats":{"Line":7}},{"line":38,"address":[685370],"length":1,"stats":{"Line":8}},{"line":39,"address":[42137293],"length":1,"stats":{"Line":3}},{"lLine truncated
|
||||||
var previousData = {"files":[{"path":["/","home","tmerritt","Projects","trevors_chip8_toy","gemma","src","chip8","computer.rs"],"content":"use log::{debug};\nuse crate::chip8::delay_timer::DelayTimer;\nuse crate::chip8::keypad::Keypad;\nuse crate::chip8::quirk_modes::QuirkMode;\nuse crate::chip8::registers::Chip8Registers;\nuse crate::chip8::sound_timer::SoundTimer;\nuse crate::chip8::stack::Chip8Stack;\n\nuse super::{\n cpu_states::Chip8CpuStates, instructions::Chip8CpuInstructions, system_memory::Chip8SystemMemory, video::Chip8Video,\n};\n\n#[derive(Clone)]\npub struct Chip8Computer {\n pub num_cycles: i32,\n pub memory: Chip8SystemMemory,\n pub registers: Chip8Registers,\n pub sound_timer: SoundTimer,\n pub delay_timer: DelayTimer,\n pub video_memory: Chip8Video,\n pub state: Chip8CpuStates,\n pub keypad: Keypad,\n pub stack: Chip8Stack,\n pub quirk_mode: QuirkMode\n}\nimpl Default for Chip8Computer {\n fn default() -\u003e Self {\n Self {\n num_cycles: 0,\n memory: Chip8SystemMemory::default(),\n video_memory: Chip8Video::default(),\n registers: Chip8Registers::default(),\n sound_timer: SoundTimer::new(),\n delay_timer: DelayTimer::new(),\n state: Chip8CpuStates::default(),\n keypad: Keypad::default(),\n stack: Chip8Stack::default(),\n quirk_mode: QuirkMode::default()\n }\n }\n}\n\nimpl Chip8Computer {\n pub fn reset(\u0026mut self) {\n self.video_memory.reset();\n self.num_cycles = 0;\n self.registers.reset();\n self.delay_timer.reset();\n self.sound_timer.reset();\n self.stack.reset();\n self.memory.reset();\n self.quirk_mode = QuirkMode::Chip8;\n }\n\n pub fn dump_keypad_to_string(\u0026self) -\u003e String {\n self.keypad.format_as_string()\n }\n\n pub fn dump_registers_to_string(\u0026self) -\u003e String {\n self.registers.format_as_string()\n }\n\n pub fn dump_video_to_string(\u0026self) -\u003e String {\n self.clone().video_memory.format_as_string()\n }\n\n pub fn new_with_program(new_program: Vec\u003cu16\u003e) -\u003e Self {\n let mut working = Chip8Computer::new();\n\n for (i, \u0026word) in new_program.iter().enumerate() {\n let high = (word \u003e\u003e 8) as u8;\n let low = (word \u0026 0xff) as u8;\n let base_offset = (i * 2) as u16;\n working.memory.poke(base_offset, high);\n working.memory.poke(base_offset + 1, low);\n }\n working\n }\n pub fn new() -\u003e Self {\n Chip8Computer::default()\n }\n\n pub fn load_bytes_to_memory(\u0026mut self, offset: u16, to_load: \u0026Vec\u003cu8\u003e) {\n let total_len = to_load.len() as u16;\n for current_index in 0..total_len {\n let new_value = to_load[current_index as usize];\n let new_location = current_index + offset;\n self.memory.poke(new_location, new_value);\n }\n self.registers.set_pc(offset);\n }\n\n pub fn step_system(\u0026mut self) -\u003e \u0026mut Chip8Computer {\n debug!(\"Stepping System 1 Step\");\n // read the next instruction\n let local_memory = \u0026self.memory;\n\n // let mut working_instruction: u16 = 0b0000000000000000;\n let start_pc = self.registers.peek_pc();\n let high_byte = (local_memory.peek(start_pc) as u16).rotate_left(8);\n let low_byte = local_memory.peek(start_pc + 1) as u16;\n let result = high_byte | low_byte;\n let decoded_instruction =\n Chip8CpuInstructions::decode(result);\n // todo: THIS IS BAD AND IS A SIDE EFFECT\n decoded_instruction.execute(self);\n\n match self.state {\n Chip8CpuStates::WaitingForInstruction =\u003e {\n self.sound_timer.tick();\n self.delay_timer.tick();\n self.video_memory.tick();\n self.num_cycles += 1;\n }\n Chip8CpuStates::WaitingForKey =\u003e {\n debug!(\"waiting for a key press...\");\n }\n _ =\u003e {}\n }\n self\n }\n}\n","traces":[{"line":27,"address":[842574,842064],"length":1,"stats":{"Line":7}},{"line":30,"address":[376933],"length":1,"stats":{"Line":7}},{"line":31,"address":[842110],"length":1,"stats":{"Line":4}},{"line":32,"address":[376959],"length":1,"stats":{"Line":4}},{"line":33,"address":[3563934],"length":1,"stats":{"Line":6}},{"line":34,"address":[42137229],"length":1,"stats":{"Line":4}},{"line":35,"address":[377028],"length":1,"stats":{"Line":6}},{"line":36,"address":[787063],"length":1,"stats":{"Line":5}},{"line":37,"address":[1160218],"length":1,"stats":{"Line":6}},{"line":38,"address":[602797],"length":1,"stats":{"Line":4}},{"line":44,"address":[3564352],"length":1,"stats":{"Line":1}Line truncated
|
var previousData = {"files":[{"path":["/","home","tmerritt","Projects","chip8_toy","gemma","src","chip8","computer.rs"],"content":"use log::{debug};\nuse crate::chip8::delay_timer::DelayTimer;\nuse crate::chip8::keypad::Keypad;\nuse crate::chip8::quirk_modes::QuirkMode;\nuse crate::chip8::quirk_modes::QuirkMode::Chip8;\nuse crate::chip8::registers::Chip8Registers;\nuse crate::chip8::sound_timer::SoundTimer;\nuse crate::chip8::stack::Chip8Stack;\n\nuse super::{\n cpu_states::Chip8CpuStates, instructions::Chip8CpuInstructions, system_memory::Chip8SystemMemory, video::Chip8Video,\n};\n\n#[derive(Clone)]\npub struct Chip8Computer {\n pub num_cycles: i32,\n pub memory: Chip8SystemMemory,\n pub registers: Chip8Registers,\n pub sound_timer: SoundTimer,\n pub delay_timer: DelayTimer,\n pub video_memory: Chip8Video,\n pub state: Chip8CpuStates,\n pub keypad: Keypad,\n pub stack: Chip8Stack,\n pub quirk_mode: QuirkMode\n}\nimpl Default for Chip8Computer {\n fn default() -\u003e Self {\n Self {\n num_cycles: 0,\n memory: Chip8SystemMemory::default(),\n video_memory: Chip8Video::default(),\n registers: Chip8Registers::default(),\n sound_timer: SoundTimer::new(),\n delay_timer: DelayTimer::new(),\n state: Chip8CpuStates::default(),\n keypad: Keypad::default(),\n stack: Chip8Stack::default(),\n quirk_mode: QuirkMode::default()\n }\n }\n}\n\nimpl Chip8Computer {\n pub fn reset(\u0026mut self) {\n self.video_memory.reset();\n self.num_cycles = 0;\n self.registers.reset();\n self.delay_timer.reset();\n self.sound_timer.reset();\n self.stack.reset();\n self.memory.reset();\n self.quirk_mode = QuirkMode::Chip8;\n }\n\n pub fn dump_keypad_to_string(\u0026self) -\u003e String {\n self.keypad.format_as_string()\n }\n\n pub fn dump_registers_to_string(\u0026self) -\u003e String {\n self.registers.format_as_string()\n }\n\n pub fn dump_video_to_string(\u0026self) -\u003e String {\n self.clone().video_memory.format_as_string()\n }\n\n pub fn new_with_program(new_program: Vec\u003cu16\u003e) -\u003e Self {\n let mut working = Chip8Computer::new();\n\n for (i, \u0026word) in new_program.iter().enumerate() {\n let high = (word \u003e\u003e 8) as u8;\n let low = (word \u0026 0xff) as u8;\n let base_offset = (i * 2) as u16;\n working.memory.poke(base_offset, high);\n working.memory.poke(base_offset + 1, low);\n }\n working\n }\n pub fn new() -\u003e Self {\n Chip8Computer::default()\n }\n\n pub fn load_bytes_to_memory(\u0026mut self, offset: u16, to_load: \u0026Vec\u003cu8\u003e) {\n let total_len = to_load.len() as u16;\n for current_index in 0..total_len {\n let new_value = to_load[current_index as usize];\n let new_location = current_index + offset;\n self.memory.poke(new_location, new_value);\n }\n self.registers.set_pc(offset);\n }\n\n pub fn step_system(\u0026mut self) -\u003e \u0026mut Chip8Computer {\n debug!(\"Stepping System 1 Step\");\n // read the next instruction\n let local_memory = \u0026self.memory;\n\n // let mut working_instruction: u16 = 0b0000000000000000;\n let start_pc = self.registers.peek_pc();\n let high_byte = (local_memory.peek(start_pc) as u16).rotate_left(8);\n let low_byte = local_memory.peek(start_pc + 1) as u16;\n let result = high_byte | low_byte;\n let decoded_instruction =\n Chip8CpuInstructions::decode(result, \u0026self.quirk_mode);\n // todo: THIS IS BAD AND IS A SIDE EFFECT\n decoded_instruction.execute(self);\n\n match self.state {\n Chip8CpuStates::WaitingForInstruction =\u003e {\n self.sound_timer.tick();\n self.delay_timer.tick();\n self.video_memory.tick();\n self.num_cycles += 1;\n }\n Chip8CpuStates::WaitingForKey =\u003e {\n debug!(\"waiting for a key press...\");\n }\n _ =\u003e {}\n }\n self\n }\n}\n","traces":[{"line":27,"address":[841408,841918],"length":1,"stats":{"Line":6}},{"line":30,"address":[3563840],"length":1,"stats":{"Line":5}},{"line":31,"address":[841454],"length":1,"stats":{"Line":4}},{"line":32,"address":[3563871],"length":1,"stats":{"Line":3}},{"line":33,"address":[376350],"length":1,"stats":{"Line":6}},{"line":34,"address":[777997],"length":1,"stats":{"Line":3}},{"line":35,"address":[3563964],"length":1,"stats":{"Line":6}},{"line":36,"address":[42137255],"length":1,"stats":{"Line":4}},{"line":37,"address":[602778],"length":1,"stats":{"Line":7}},{"line":38,"address":[1160237],"length":1,"stats":{"LinLine truncated
|
||||||
</script>
|
</script>
|
||||||
<script crossorigin>/** @license React v16.13.1
|
<script crossorigin>/** @license React v16.13.1
|
||||||
* react.production.min.js
|
* react.production.min.js
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ 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;
|
||||||
@@ -101,7 +102,7 @@ impl Chip8Computer {
|
|||||||
let low_byte = local_memory.peek(start_pc + 1) as u16;
|
let low_byte = local_memory.peek(start_pc + 1) as u16;
|
||||||
let result = high_byte | low_byte;
|
let result = high_byte | low_byte;
|
||||||
let decoded_instruction =
|
let decoded_instruction =
|
||||||
Chip8CpuInstructions::decode(result);
|
Chip8CpuInstructions::decode(result, &self.quirk_mode);
|
||||||
// todo: THIS IS BAD AND IS A SIDE EFFECT
|
// todo: THIS IS BAD AND IS A SIDE EFFECT
|
||||||
decoded_instruction.execute(self);
|
decoded_instruction.execute(self);
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use rand::{random, 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::*;
|
||||||
|
use crate::chip8::quirk_modes::QuirkMode;
|
||||||
use crate::chip8::util::InstructionUtil;
|
use crate::chip8::util::InstructionUtil;
|
||||||
use crate::constants::{*};
|
use crate::constants::{*};
|
||||||
|
|
||||||
@@ -259,6 +260,10 @@ pub enum Chip8CpuInstructions {
|
|||||||
///
|
///
|
||||||
/// Load V0..VX from RPL user flags (X <= 7)
|
/// Load V0..VX from RPL user flags (X <= 7)
|
||||||
LIDR(u8),
|
LIDR(u8),
|
||||||
|
/// 0xBxNN
|
||||||
|
///
|
||||||
|
/// Jump to Address XNN+Vx
|
||||||
|
JPX(u8, u16)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Chip8CpuInstructions {
|
impl Chip8CpuInstructions {
|
||||||
@@ -308,12 +313,16 @@ impl Chip8CpuInstructions {
|
|||||||
Chip8CpuInstructions::DIS => INST_DIS,
|
Chip8CpuInstructions::DIS => INST_DIS,
|
||||||
Chip8CpuInstructions::ENA => INST_ENA,
|
Chip8CpuInstructions::ENA => INST_ENA,
|
||||||
Chip8CpuInstructions::ORY(_, _) => INST_ORY,
|
Chip8CpuInstructions::ORY(_, _) => INST_ORY,
|
||||||
|
JPX(_, _) => INST_JPX,
|
||||||
XXXXERRORINSTRUCTION => "XX ERROR XX",
|
XXXXERRORINSTRUCTION => "XX ERROR XX",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn operands(&self) -> String {
|
pub fn operands(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
|
JPX(x, addr) => {
|
||||||
|
format!("0x{x:02x}, 0x{addr:04x}")
|
||||||
|
}
|
||||||
Chip8CpuInstructions::SYS(addr) |
|
Chip8CpuInstructions::SYS(addr) |
|
||||||
Chip8CpuInstructions::JPI(addr) |
|
Chip8CpuInstructions::JPI(addr) |
|
||||||
Chip8CpuInstructions::JPA(addr) |
|
Chip8CpuInstructions::JPA(addr) |
|
||||||
@@ -528,6 +537,9 @@ impl Chip8CpuInstructions {
|
|||||||
INST_LDD => {
|
INST_LDD => {
|
||||||
LDD(param1 as u8)
|
LDD(param1 as u8)
|
||||||
}
|
}
|
||||||
|
INST_JPX => {
|
||||||
|
JPX(param1 as u8, param2)
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
XXXXERRORINSTRUCTION
|
XXXXERRORINSTRUCTION
|
||||||
}
|
}
|
||||||
@@ -558,6 +570,7 @@ impl Chip8CpuInstructions {
|
|||||||
Chip8CpuInstructions::SNEY(x_register, y_register) => 0x9000 | ((*x_register as u16) << 8) | ((*y_register as u16) << 4),
|
Chip8CpuInstructions::SNEY(x_register, y_register) => 0x9000 | ((*x_register as u16) << 8) | ((*y_register as u16) << 4),
|
||||||
Chip8CpuInstructions::LDIA(addr) => 0xA000 | addr,
|
Chip8CpuInstructions::LDIA(addr) => 0xA000 | addr,
|
||||||
Chip8CpuInstructions::JPI(addr) => 0xB000 | addr,
|
Chip8CpuInstructions::JPI(addr) => 0xB000 | addr,
|
||||||
|
JPX(x_register, addr)=> 0xB000u16 | ((*x_register as u16) << 12) | *addr ,
|
||||||
Chip8CpuInstructions::RND(x_register, byte) => 0xC000 | ((*x_register as u16) << 8) | (*byte as u16),
|
Chip8CpuInstructions::RND(x_register, byte) => 0xC000 | ((*x_register as u16) << 8) | (*byte as u16),
|
||||||
Chip8CpuInstructions::DRW(x_register, y_register, height) => {
|
Chip8CpuInstructions::DRW(x_register, y_register, height) => {
|
||||||
0xD000 | ((*x_register as u16) << 8) | ((*y_register as u16) << 4) | (*height as u16)
|
0xD000 | ((*x_register as u16) << 8) | ((*y_register as u16) << 4) | (*height as u16)
|
||||||
@@ -585,7 +598,7 @@ impl Chip8CpuInstructions {
|
|||||||
XXXXERRORINSTRUCTION => 0xFFFF
|
XXXXERRORINSTRUCTION => 0xFFFF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn decode(input: u16) -> Chip8CpuInstructions {
|
pub fn decode(input: u16, quirk_mode: &QuirkMode) -> Chip8CpuInstructions {
|
||||||
let x_param = InstructionUtil::read_x_from_instruction(input);
|
let x_param = InstructionUtil::read_x_from_instruction(input);
|
||||||
let y_param = InstructionUtil::read_y_from_instruction(input);
|
let y_param = InstructionUtil::read_y_from_instruction(input);
|
||||||
let addr_param = InstructionUtil::read_addr_from_instruction(input);
|
let addr_param = InstructionUtil::read_addr_from_instruction(input);
|
||||||
@@ -596,10 +609,35 @@ impl Chip8CpuInstructions {
|
|||||||
let last_nibble = (input & 0xF) as u8;
|
let last_nibble = (input & 0xF) as u8;
|
||||||
|
|
||||||
match input {
|
match input {
|
||||||
0x00C0..=0x00CF => Chip8CpuInstructions::SDN(last_nibble),
|
0x00C0..=0x00CF => {
|
||||||
|
match quirk_mode {
|
||||||
|
QuirkMode::Chip8 => {
|
||||||
|
XXXXERRORINSTRUCTION
|
||||||
|
}
|
||||||
|
QuirkMode::XOChip => {
|
||||||
|
SDN(last_nibble)
|
||||||
|
}
|
||||||
|
QuirkMode::SChipModern => {
|
||||||
|
SDN(last_nibble)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
0x00E0 => Chip8CpuInstructions::CLS,
|
0x00E0 => Chip8CpuInstructions::CLS,
|
||||||
0x00EE => Chip8CpuInstructions::RET,
|
0x00EE => Chip8CpuInstructions::RET,
|
||||||
0x00FB => Chip8CpuInstructions::SRT,
|
0x00FB => {
|
||||||
|
match quirk_mode {
|
||||||
|
QuirkMode::Chip8 => {
|
||||||
|
// does not exist on Chip8
|
||||||
|
XXXXERRORINSTRUCTION
|
||||||
|
}
|
||||||
|
QuirkMode::XOChip => {
|
||||||
|
Chip8CpuInstructions::SRT
|
||||||
|
}
|
||||||
|
QuirkMode::SChipModern => {
|
||||||
|
Chip8CpuInstructions::SRT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
0x00FC => Chip8CpuInstructions::SLF,
|
0x00FC => Chip8CpuInstructions::SLF,
|
||||||
0x00FD => Chip8CpuInstructions::EXIT,
|
0x00FD => Chip8CpuInstructions::EXIT,
|
||||||
0x00FE => Chip8CpuInstructions::DIS,
|
0x00FE => Chip8CpuInstructions::DIS,
|
||||||
@@ -856,6 +894,12 @@ impl Chip8CpuInstructions {
|
|||||||
// The program counter is set to nnn plus the value of V0.
|
// The program counter is set to nnn plus the value of V0.
|
||||||
input.registers.poke_pc(input.registers.peek(0) as u16 + addr);
|
input.registers.poke_pc(input.registers.peek(0) as u16 + addr);
|
||||||
}
|
}
|
||||||
|
// 0xBxnn Jump to Xnn+Vx
|
||||||
|
JPX(vx_register, addr) => {
|
||||||
|
let x_reg_value: u16 = input.registers.peek(*vx_register) as u16;
|
||||||
|
let new_addr = *addr + x_reg_value;
|
||||||
|
input.registers.poke_i(new_addr);
|
||||||
|
}
|
||||||
Chip8CpuInstructions::RND(x, byte) => {
|
Chip8CpuInstructions::RND(x, byte) => {
|
||||||
// Cxkk - RND Vx, byte
|
// Cxkk - RND Vx, byte
|
||||||
// Set Vx = random byte AND kk.
|
// Set Vx = random byte AND kk.
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
pub enum QuirkMode {
|
pub enum QuirkMode {
|
||||||
#[default]
|
#[default]
|
||||||
Chip8,
|
Chip8,
|
||||||
SChipLegacy,
|
|
||||||
XOChip,
|
XOChip,
|
||||||
SChipModern
|
SChipModern
|
||||||
}
|
}
|
||||||
@@ -29,6 +29,7 @@ pub const INST_DRW: &str = "DRW";
|
|||||||
pub const INST_EXIT: &str = "EXIT";
|
pub const INST_EXIT: &str = "EXIT";
|
||||||
pub const INST_JPA: &str = "JPA";
|
pub const INST_JPA: &str = "JPA";
|
||||||
pub const INST_JPI: &str = "JPI";
|
pub const INST_JPI: &str = "JPI";
|
||||||
|
pub const INST_JPX: &str = "JPX";
|
||||||
pub const INST_BCD: &str = "BCD";
|
pub const INST_BCD: &str = "BCD";
|
||||||
pub const INST_LDD: &str = "LDD";
|
pub const INST_LDD: &str = "LDD";
|
||||||
pub const INST_LDF: &str = "LDF";
|
pub const INST_LDF: &str = "LDF";
|
||||||
|
|||||||
+6
-354
@@ -6,6 +6,7 @@ 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::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::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;
|
||||||
@@ -72,6 +73,8 @@ fn encode_decode_test() {
|
|||||||
assert_eq!(Chip8CpuInstructions::STR(1).encode(), 0xF175);
|
assert_eq!(Chip8CpuInstructions::STR(1).encode(), 0xF175);
|
||||||
assert_eq!(Chip8CpuInstructions::LIDR(1).encode(), 0xF185);
|
assert_eq!(Chip8CpuInstructions::LIDR(1).encode(), 0xF185);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xF175), Chip8CpuInstructions::STR(1)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xF175), Chip8CpuInstructions::STR(1)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xF185), Chip8CpuInstructions::LIDR(1)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xF185), Chip8CpuInstructions::LIDR(1)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0x00C1u16), Chip8CpuInstructions::SDN(0x01)));
|
assert!(matches!(Chip8CpuInstructions::decode(0x00C1u16), Chip8CpuInstructions::SDN(0x01)));
|
||||||
@@ -118,6 +121,7 @@ fn encode_decode_test() {
|
|||||||
assert!(matches!(Chip8CpuInstructions::decode(0xfd33), Chip8CpuInstructions::BCD(0xd)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xfd33), Chip8CpuInstructions::BCD(0xd)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xfe55), Chip8CpuInstructions::LDIX(0xe)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xfe55), Chip8CpuInstructions::LDIX(0xe)));
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(0xf365), Chip8CpuInstructions::LDRI(0x3)));
|
assert!(matches!(Chip8CpuInstructions::decode(0xf365), Chip8CpuInstructions::LDRI(0x3)));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -129,8 +133,8 @@ fn decoder_test_invalid_instructions() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
for i in invalid_to_encode {
|
for i in invalid_to_encode {
|
||||||
assert_eq!(Chip8CpuInstructions::decode(i).encode(), 0xffff);
|
assert_eq!(Chip8CpuInstructions::decode(i, &Chip8).encode(), 0xffff);
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(i), Chip8CpuInstructions::XXXXERRORINSTRUCTION));
|
assert!(matches!(Chip8CpuInstructions::decode(i, &Chip8), Chip8CpuInstructions::XXXXERRORINSTRUCTION));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1327,350 +1331,6 @@ fn video_scroll_right_4_row_test_high_def() {
|
|||||||
assert_eq!(read_test_result("test_scroll_right_4_hd.asc"), x.format_as_string());
|
assert_eq!(read_test_result("test_scroll_right_4_hd.asc"), x.format_as_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InstructionTest {
|
|
||||||
name: String,
|
|
||||||
instruction: Chip8CpuInstructions,
|
|
||||||
operands: String,
|
|
||||||
asm: String,
|
|
||||||
encoded: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn instructions_name_tests() {
|
|
||||||
assert_eq!(Chip8CpuInstructions::SYS(0x0000).name(), INST_SYS);
|
|
||||||
assert_eq!(Chip8CpuInstructions::ADD(0x0, 0x1).name(), INST_ADD);
|
|
||||||
assert_eq!(Chip8CpuInstructions::ADDI(0x0).name(), INST_ADDI);
|
|
||||||
assert_eq!(Chip8CpuInstructions::ADDR(0x01, 0x02).name(), INST_ADDR);
|
|
||||||
assert_eq!(Chip8CpuInstructions::AND(0x01, 0x02).name(), INST_AND);
|
|
||||||
|
|
||||||
let it = vec![
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SYS.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SYS(0x123),
|
|
||||||
operands: "0x0123".to_string(),
|
|
||||||
asm: "SYS 0x0123".to_string(),
|
|
||||||
encoded: 0x0123
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_CLS.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::CLS,
|
|
||||||
asm: "CLS".to_string(),
|
|
||||||
operands: "".to_string(),
|
|
||||||
encoded: 0x00E0
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_RET.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::RET,
|
|
||||||
asm: "RET".to_string(),
|
|
||||||
operands: "".to_string(),
|
|
||||||
encoded: 0x00ee
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_JPA.to_string(),
|
|
||||||
instruction: JPA(0x234),
|
|
||||||
asm: "JPA 0x0234".to_string(),
|
|
||||||
encoded: 0xb234,
|
|
||||||
operands: "0x0234".to_string(),
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_CALL.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::CALL(0x123),
|
|
||||||
asm: "CALL 0x0123".to_string(),
|
|
||||||
encoded: 0x2123,
|
|
||||||
operands: "0x0123".to_string()
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_DRW.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::DRW(0x01, 0x02, 0x03),
|
|
||||||
operands: "0x01, 0x02, 0x03".to_string(),
|
|
||||||
asm: "DRW 0x01, 0x02, 0x03".to_string(),
|
|
||||||
encoded: 0xd123
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_JPI.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::JPI(0x321),
|
|
||||||
operands: "0x0321".to_string(),
|
|
||||||
asm: "JPI 0x0321".to_string(),
|
|
||||||
encoded: 0xb321
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SDN.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SDN(0x01),
|
|
||||||
operands: "0x01".to_string(),
|
|
||||||
asm: "SDN 0x01".to_string(),
|
|
||||||
encoded: 0x00c1
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SRT.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SRT,
|
|
||||||
operands: "".to_string(),
|
|
||||||
asm: "SRT".to_string(),
|
|
||||||
encoded: 0x00FB
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SLF.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SLF,
|
|
||||||
operands: "".to_string(),
|
|
||||||
asm: "SLF".to_string(),
|
|
||||||
encoded: 0x00FC,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_EXIT.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::EXIT,
|
|
||||||
operands: "".to_string(),
|
|
||||||
asm: "EXIT".to_string(),
|
|
||||||
encoded: 0x00FD,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_DIS.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::DIS,
|
|
||||||
operands: "".to_string(),
|
|
||||||
asm: "DIS".to_string(),
|
|
||||||
encoded: 0x00FE,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_ENA.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::ENA,
|
|
||||||
operands: "".to_string(),
|
|
||||||
asm: "ENA".to_string(),
|
|
||||||
encoded: 0x00FF,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SEX.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SEX(0x01, 0xfa),
|
|
||||||
operands: "0x01, 0xfa".to_string(),
|
|
||||||
asm: "SEX 0x01, 0xfa".to_string(),
|
|
||||||
encoded: 0x32fa,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SNEB.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SNEB(0x01, 0xab),
|
|
||||||
operands: "0x01, 0xab".to_string(),
|
|
||||||
asm: "SNEB 0x01, 0xab".to_string(),
|
|
||||||
encoded: 0x41ab,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SEY.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SEY(0x1, 0x2),
|
|
||||||
operands: "0x1, 0x2".to_string(),
|
|
||||||
asm: "SEY 0x1, 0x2".to_string(),
|
|
||||||
encoded: 0x5120
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_LDR.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::LDR(0xa, 0xbe),
|
|
||||||
operands: "0x0a, 0xbe".to_string(),
|
|
||||||
asm: "LDR 0x0a, 0xbe".to_string(),
|
|
||||||
encoded: 0x6abe,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_ADD.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::ADD(0x01, 0xab),
|
|
||||||
operands: "0x01, 0xab".to_string(),
|
|
||||||
asm: "ADD 0x01, 0xab".to_string(),
|
|
||||||
encoded: 0x71ab
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_LDRY.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::LDR_Y(0x1, 0x2),
|
|
||||||
operands: "0x1, 0x2".to_string(),
|
|
||||||
asm: "LDRY 0x1, 0x2".to_string(),
|
|
||||||
encoded: 0x8120,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_OR.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::OR(0x1, 0x2),
|
|
||||||
operands: "0x1, 0x2".to_string(),
|
|
||||||
asm: "OR 0x1, 0x2".to_string(),
|
|
||||||
encoded: 0x8121
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_AND.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::AND(0xb, 0xc),
|
|
||||||
operands: "0xb, 0xc".to_string(),
|
|
||||||
asm: "AND 0xb, 0xc".to_string(),
|
|
||||||
encoded: 0x8bc2,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_ORY.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::ORY(0xa, 0x3),
|
|
||||||
operands: "0xa, 0x3".to_string(),
|
|
||||||
asm: "ORY 0xa, 0x3".to_string(),
|
|
||||||
encoded: 0x8a33
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_ADDR.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::ADDR(0x1, 0x2),
|
|
||||||
operands: "0x1, 0x2".to_string(),
|
|
||||||
asm: "ADDR 0x1, 0x2".to_string(),
|
|
||||||
encoded: 0x8124
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SUB.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SUB(0x4, 0x5),
|
|
||||||
operands: "0x4, 0x5".to_string(),
|
|
||||||
asm: "SUB 0x4, 0x5".to_string(),
|
|
||||||
encoded: 0x8455
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SHR.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SHR(0x01, 0x1),
|
|
||||||
operands: "0x1, 0x1".to_string(),
|
|
||||||
asm: "SHR 0x1, 0x1".to_string(),
|
|
||||||
encoded: 0x8116,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SUBC.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SUBC(0xf, 0xa),
|
|
||||||
operands: "0xf, 0xa".to_string(),
|
|
||||||
asm: "SUBC 0xf, 0xa".to_string(),
|
|
||||||
encoded: 0x8fa7,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SHL.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SHL(0x1, 0x4),
|
|
||||||
operands: "0x1, 0x4".to_string(),
|
|
||||||
asm: "SHL 0x1, 0x4".to_string(),
|
|
||||||
encoded: 0x814e,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SNEY.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SNEY(0x4, 0x5),
|
|
||||||
operands: "0x4, 0x5".to_string(),
|
|
||||||
asm: "SNEY 0x4, 0x5".to_string(),
|
|
||||||
encoded: 0x9450,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_LDIA.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::LDIA(0xbee),
|
|
||||||
operands: "0x0bee".to_string(),
|
|
||||||
asm: "LDIA 0x0bee".to_string(),
|
|
||||||
encoded: 0x9bee
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_JPI.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::JPI(0xfee),
|
|
||||||
operands: "0x0fee".to_string(),
|
|
||||||
asm: "JPI 0x0fee".to_string(),
|
|
||||||
encoded: 0xbfee
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_RND.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::RND(0x1, 0xae),
|
|
||||||
operands: "0x01, 0xae".to_string(),
|
|
||||||
asm: "RND 0x01, 0xae".to_string(),
|
|
||||||
encoded: 0xc1ae,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_DRW.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::DRW(0x1, 0x2, 0xf),
|
|
||||||
operands: "0x01, 0x02, 0x0f".to_string(),
|
|
||||||
asm: "DRW 0x01, 0x02, 0x0f".to_string(),
|
|
||||||
encoded: 0xd12f
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SKP.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SKP(0x4),
|
|
||||||
operands: "0x04".to_string(),
|
|
||||||
asm: "SKP 0x04".to_string(),
|
|
||||||
encoded: 0xe49e,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_SKNP.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::SKNP(0x3),
|
|
||||||
operands: "0x03".to_string(),
|
|
||||||
asm: "SKNP 0x03".to_string(),
|
|
||||||
encoded: 0x83a1
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_LDRD.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::LDRD(0x4),
|
|
||||||
operands: "0x04".to_string(),
|
|
||||||
asm: "LDRD 0x04".to_string(),
|
|
||||||
encoded: 0xF407
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_LDRK.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::LDRK(0x6),
|
|
||||||
operands: "0x06".to_string(),
|
|
||||||
asm: "LDRK 0x06".to_string(),
|
|
||||||
encoded: 0xF60A
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_LDD.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::LDD(0x02),
|
|
||||||
operands: "0x02".to_string(),
|
|
||||||
asm: "LDD 0x02".to_string(),
|
|
||||||
encoded: 0xF215,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_LDRI.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::LDRI(0x01),
|
|
||||||
operands: "0x01".to_string(),
|
|
||||||
asm: "LDRI 0x01".to_string(),
|
|
||||||
encoded: 0xF118,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_BCD.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::BCD(0x4),
|
|
||||||
operands: "0x04".to_string(),
|
|
||||||
asm: "BCD 0x04".to_string(),
|
|
||||||
encoded: 0xF433,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_LDF.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::LDFX(0x5),
|
|
||||||
operands: "0x05".to_string(),
|
|
||||||
asm: "LDF 0x05".to_string(),
|
|
||||||
encoded: 0xF529
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_LDF2.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::LDF2(0x6),
|
|
||||||
operands: "0x06".to_string(),
|
|
||||||
asm: "LDF2 0x06".to_string(),
|
|
||||||
encoded: 0xF630
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_LDIX.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::LDIX(0x5),
|
|
||||||
operands: "0x05".to_string(),
|
|
||||||
asm: "LDIX 0x05".to_string(),
|
|
||||||
encoded: 0xF555
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_LDIS.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::LDIS(0xf),
|
|
||||||
operands: "0x0f".to_string(),
|
|
||||||
asm: "LDIS 0x0f".to_string(),
|
|
||||||
encoded: 0xFF18
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_LIDR.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::LIDR(0x4),
|
|
||||||
operands: "0x04".to_string(),
|
|
||||||
asm: "LIDR 0x04".to_string(),
|
|
||||||
encoded: 0xF485,
|
|
||||||
},
|
|
||||||
InstructionTest {
|
|
||||||
name: INST_STR.to_string(),
|
|
||||||
instruction: Chip8CpuInstructions::STR(0xa),
|
|
||||||
operands: "0x0a".to_string(),
|
|
||||||
asm: "STR 0x0a".to_string(),
|
|
||||||
encoded: 0xF000
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
for current in it {
|
|
||||||
assert_eq!(current.instruction.name(), current.name);
|
|
||||||
let i = current.instruction;
|
|
||||||
assert!(matches!(Chip8CpuInstructions::decode(current.encoded), i));
|
|
||||||
assert_eq!(i.to_string(), current.asm);
|
|
||||||
let asm = Chip8CpuInstructions::from_str(¤t.asm);
|
|
||||||
assert_eq!(i.to_string(), asm.to_string());
|
|
||||||
assert_eq!(i.operands(), current.operands);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn instructions_operands_tests() {
|
fn instructions_operands_tests() {
|
||||||
@@ -1744,11 +1404,3 @@ fn computer_dump_registers_to_string() {
|
|||||||
// now verify.
|
// now verify.
|
||||||
assert_eq!(expected_value, x.dump_registers_to_string());
|
assert_eq!(expected_value, x.dump_registers_to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
//#[test]
|
|
||||||
fn quirks_chip8_vf_reset_tests() {
|
|
||||||
// vF reset - The AND, OR and XOR opcodes (8xy1, 8xy2 and 8xy3) reset the flags
|
|
||||||
// register to zero. Test will show ERR1 if the AND and OR tests don't behave
|
|
||||||
// the same and ERR2 if the AND and XOR tests don't behave the same.
|
|
||||||
let mut x = Chip8Computer::new();
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,399 @@
|
|||||||
|
use gemma::chip8::instructions::Chip8CpuInstructions;
|
||||||
|
use gemma::chip8::instructions::Chip8CpuInstructions::*;
|
||||||
|
use gemma::chip8::quirk_modes::QuirkMode::{Chip8, SChipModern, XOChip};
|
||||||
|
use gemma::constants::*;
|
||||||
|
|
||||||
|
struct InstructionTestQuirks {
|
||||||
|
chip8: Chip8CpuInstructions,
|
||||||
|
schip: Chip8CpuInstructions,
|
||||||
|
xochip: Chip8CpuInstructions
|
||||||
|
}
|
||||||
|
|
||||||
|
struct InstructionTest {
|
||||||
|
name: String,
|
||||||
|
instruction: Chip8CpuInstructions,
|
||||||
|
operands: String,
|
||||||
|
asm: String,
|
||||||
|
encoded: u16,
|
||||||
|
quirks: InstructionTestQuirks
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn instructions_encode_decode_tests_with_quirks() {
|
||||||
|
let it = vec![
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SYS.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SYS(0x123),
|
||||||
|
operands: "0x0123".to_string(),
|
||||||
|
asm: "SYS 0x0123".to_string(),
|
||||||
|
encoded: 0x0123,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: SYS(0x123),
|
||||||
|
schip: XXXXERRORINSTRUCTION,
|
||||||
|
xochip: XXXXERRORINSTRUCTION,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_CLS.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::CLS,
|
||||||
|
asm: "CLS".to_string(),
|
||||||
|
operands: "".to_string(),
|
||||||
|
encoded: 0x00E0,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: CLS,
|
||||||
|
schip: CLS,
|
||||||
|
xochip: CLS
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_RET.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::RET,
|
||||||
|
asm: "RET".to_string(),
|
||||||
|
operands: "".to_string(),
|
||||||
|
encoded: 0x00ee,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: RET,
|
||||||
|
schip: RET,
|
||||||
|
xochip: RET
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_JPA.to_string(),
|
||||||
|
instruction: JPA(0x234),
|
||||||
|
asm: "JPA 0x0234".to_string(),
|
||||||
|
encoded: 0xb234,
|
||||||
|
operands: "0x0234".to_string(),
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: JPA(0x0234),
|
||||||
|
schip: JPA(0x0234),
|
||||||
|
xochip: JPA(0x0234)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_JPX.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::JPX(0x1, 0xab),
|
||||||
|
operands: "0x01, 0x01ab".to_string(),
|
||||||
|
asm: "JPX 0x01, 0x01ab".to_string(),
|
||||||
|
encoded: 0,
|
||||||
|
quirks: InstructionTestQuirks {
|
||||||
|
chip8: XXXXERRORINSTRUCTION,
|
||||||
|
schip: JPX(0x1, 0xab),
|
||||||
|
xochip: XXXXERRORINSTRUCTION,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
,
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_CALL.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::CALL(0x123),
|
||||||
|
asm: "CALL 0x0123".to_string(),
|
||||||
|
encoded: 0x2123,
|
||||||
|
operands: "0x0123".to_string()
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_DRW.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::DRW(0x01, 0x02, 0x03),
|
||||||
|
operands: "0x01, 0x02, 0x03".to_string(),
|
||||||
|
asm: "DRW 0x01, 0x02, 0x03".to_string(),
|
||||||
|
encoded: 0xd123
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_JPI.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::JPI(0x321),
|
||||||
|
operands: "0x0321".to_string(),
|
||||||
|
asm: "JPI 0x0321".to_string(),
|
||||||
|
encoded: 0xb321
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SDN.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SDN(0x01),
|
||||||
|
operands: "0x01".to_string(),
|
||||||
|
asm: "SDN 0x01".to_string(),
|
||||||
|
encoded: 0x00c1
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SRT.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SRT,
|
||||||
|
operands: "".to_string(),
|
||||||
|
asm: "SRT".to_string(),
|
||||||
|
encoded: 0x00FB
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SLF.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SLF,
|
||||||
|
operands: "".to_string(),
|
||||||
|
asm: "SLF".to_string(),
|
||||||
|
encoded: 0x00FC,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_EXIT.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::EXIT,
|
||||||
|
operands: "".to_string(),
|
||||||
|
asm: "EXIT".to_string(),
|
||||||
|
encoded: 0x00FD,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_DIS.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::DIS,
|
||||||
|
operands: "".to_string(),
|
||||||
|
asm: "DIS".to_string(),
|
||||||
|
encoded: 0x00FE,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_ENA.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::ENA,
|
||||||
|
operands: "".to_string(),
|
||||||
|
asm: "ENA".to_string(),
|
||||||
|
encoded: 0x00FF,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SEX.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SEX(0x01, 0xfa),
|
||||||
|
operands: "0x01, 0xfa".to_string(),
|
||||||
|
asm: "SEX 0x01, 0xfa".to_string(),
|
||||||
|
encoded: 0x32fa,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SNEB.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SNEB(0x01, 0xab),
|
||||||
|
operands: "0x01, 0xab".to_string(),
|
||||||
|
asm: "SNEB 0x01, 0xab".to_string(),
|
||||||
|
encoded: 0x41ab,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SEY.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SEY(0x1, 0x2),
|
||||||
|
operands: "0x1, 0x2".to_string(),
|
||||||
|
asm: "SEY 0x1, 0x2".to_string(),
|
||||||
|
encoded: 0x5120
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDR.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LDR(0xa, 0xbe),
|
||||||
|
operands: "0x0a, 0xbe".to_string(),
|
||||||
|
asm: "LDR 0x0a, 0xbe".to_string(),
|
||||||
|
encoded: 0x6abe,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_ADD.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::ADD(0x01, 0xab),
|
||||||
|
operands: "0x01, 0xab".to_string(),
|
||||||
|
asm: "ADD 0x01, 0xab".to_string(),
|
||||||
|
encoded: 0x71ab
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDRY.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LDR_Y(0x1, 0x2),
|
||||||
|
operands: "0x1, 0x2".to_string(),
|
||||||
|
asm: "LDRY 0x1, 0x2".to_string(),
|
||||||
|
encoded: 0x8120,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_OR.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::OR(0x1, 0x2),
|
||||||
|
operands: "0x1, 0x2".to_string(),
|
||||||
|
asm: "OR 0x1, 0x2".to_string(),
|
||||||
|
encoded: 0x8121
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_AND.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::AND(0xb, 0xc),
|
||||||
|
operands: "0xb, 0xc".to_string(),
|
||||||
|
asm: "AND 0xb, 0xc".to_string(),
|
||||||
|
encoded: 0x8bc2,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_ORY.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::ORY(0xa, 0x3),
|
||||||
|
operands: "0xa, 0x3".to_string(),
|
||||||
|
asm: "ORY 0xa, 0x3".to_string(),
|
||||||
|
encoded: 0x8a33
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_ADDR.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::ADDR(0x1, 0x2),
|
||||||
|
operands: "0x1, 0x2".to_string(),
|
||||||
|
asm: "ADDR 0x1, 0x2".to_string(),
|
||||||
|
encoded: 0x8124
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SUB.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SUB(0x4, 0x5),
|
||||||
|
operands: "0x4, 0x5".to_string(),
|
||||||
|
asm: "SUB 0x4, 0x5".to_string(),
|
||||||
|
encoded: 0x8455
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SHR.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SHR(0x01, 0x1),
|
||||||
|
operands: "0x1, 0x1".to_string(),
|
||||||
|
asm: "SHR 0x1, 0x1".to_string(),
|
||||||
|
encoded: 0x8116,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SUBC.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SUBC(0xf, 0xa),
|
||||||
|
operands: "0xf, 0xa".to_string(),
|
||||||
|
asm: "SUBC 0xf, 0xa".to_string(),
|
||||||
|
encoded: 0x8fa7,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SHL.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SHL(0x1, 0x4),
|
||||||
|
operands: "0x1, 0x4".to_string(),
|
||||||
|
asm: "SHL 0x1, 0x4".to_string(),
|
||||||
|
encoded: 0x814e,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SNEY.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SNEY(0x4, 0x5),
|
||||||
|
operands: "0x4, 0x5".to_string(),
|
||||||
|
asm: "SNEY 0x4, 0x5".to_string(),
|
||||||
|
encoded: 0x9450,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDIA.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LDIA(0xbee),
|
||||||
|
operands: "0x0bee".to_string(),
|
||||||
|
asm: "LDIA 0x0bee".to_string(),
|
||||||
|
encoded: 0x9bee
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_JPI.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::JPI(0xfee),
|
||||||
|
operands: "0x0fee".to_string(),
|
||||||
|
asm: "JPI 0x0fee".to_string(),
|
||||||
|
encoded: 0xbfee
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_RND.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::RND(0x1, 0xae),
|
||||||
|
operands: "0x01, 0xae".to_string(),
|
||||||
|
asm: "RND 0x01, 0xae".to_string(),
|
||||||
|
encoded: 0xc1ae,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_DRW.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::DRW(0x1, 0x2, 0xf),
|
||||||
|
operands: "0x01, 0x02, 0x0f".to_string(),
|
||||||
|
asm: "DRW 0x01, 0x02, 0x0f".to_string(),
|
||||||
|
encoded: 0xd12f
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SKP.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SKP(0x4),
|
||||||
|
operands: "0x04".to_string(),
|
||||||
|
asm: "SKP 0x04".to_string(),
|
||||||
|
encoded: 0xe49e,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_SKNP.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::SKNP(0x3),
|
||||||
|
operands: "0x03".to_string(),
|
||||||
|
asm: "SKNP 0x03".to_string(),
|
||||||
|
encoded: 0x83a1
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDRD.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LDRD(0x4),
|
||||||
|
operands: "0x04".to_string(),
|
||||||
|
asm: "LDRD 0x04".to_string(),
|
||||||
|
encoded: 0xF407
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDRK.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LDRK(0x6),
|
||||||
|
operands: "0x06".to_string(),
|
||||||
|
asm: "LDRK 0x06".to_string(),
|
||||||
|
encoded: 0xF60A
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDD.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LDD(0x02),
|
||||||
|
operands: "0x02".to_string(),
|
||||||
|
asm: "LDD 0x02".to_string(),
|
||||||
|
encoded: 0xF215,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDRI.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LDRI(0x01),
|
||||||
|
operands: "0x01".to_string(),
|
||||||
|
asm: "LDRI 0x01".to_string(),
|
||||||
|
encoded: 0xF118,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_BCD.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::BCD(0x4),
|
||||||
|
operands: "0x04".to_string(),
|
||||||
|
asm: "BCD 0x04".to_string(),
|
||||||
|
encoded: 0xF433,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDF.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LDFX(0x5),
|
||||||
|
operands: "0x05".to_string(),
|
||||||
|
asm: "LDF 0x05".to_string(),
|
||||||
|
encoded: 0xF529
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDF2.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LDF2(0x6),
|
||||||
|
operands: "0x06".to_string(),
|
||||||
|
asm: "LDF2 0x06".to_string(),
|
||||||
|
encoded: 0xF630
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDIX.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LDIX(0x5),
|
||||||
|
operands: "0x05".to_string(),
|
||||||
|
asm: "LDIX 0x05".to_string(),
|
||||||
|
encoded: 0xF555
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LDIS.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LDIS(0xf),
|
||||||
|
operands: "0x0f".to_string(),
|
||||||
|
asm: "LDIS 0x0f".to_string(),
|
||||||
|
encoded: 0xFF18
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_LIDR.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::LIDR(0x4),
|
||||||
|
operands: "0x04".to_string(),
|
||||||
|
asm: "LIDR 0x04".to_string(),
|
||||||
|
encoded: 0xF485,
|
||||||
|
},
|
||||||
|
InstructionTest {
|
||||||
|
name: INST_STR.to_string(),
|
||||||
|
instruction: Chip8CpuInstructions::STR(0xa),
|
||||||
|
operands: "0x0a".to_string(),
|
||||||
|
asm: "STR 0x0a".to_string(),
|
||||||
|
encoded: 0xF000
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
];
|
||||||
|
|
||||||
|
for current in it {
|
||||||
|
assert_eq!(current.instruction.name(), current.name);
|
||||||
|
let i = current.instruction;
|
||||||
|
assert!(matches!(Chip8CpuInstructions::decode(current.encoded, &Chip8), i));
|
||||||
|
assert_eq!(i.to_string(), current.asm);
|
||||||
|
let asm = Chip8CpuInstructions::from_str(¤t.asm);
|
||||||
|
assert_eq!(i.to_string(), asm.to_string());
|
||||||
|
assert_eq!(i.operands(), current.operands);
|
||||||
|
// test quirks
|
||||||
|
let as_chip8 = Chip8CpuInstructions::decode(current.encoded, &Chip8);
|
||||||
|
let quirks_chip8 = current.quirks.chip8;
|
||||||
|
let as_schip = Chip8CpuInstructions::decode(current.encoded, &SChipModern);
|
||||||
|
let quirks_schip = current.quirks.schip;
|
||||||
|
let as_xochip = Chip8CpuInstructions::decode(current.encoded, &XOChip);
|
||||||
|
let quirks_xochip = current.quirks.xochip;
|
||||||
|
|
||||||
|
assert!(matches!(as_chip8, quirks_chip8));
|
||||||
|
assert!(matches!(as_schip, quirks_schip));
|
||||||
|
assert!(matches!(as_xochip, quirks_xochip));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ use std::path::Path;
|
|||||||
use clap::{command, Parser};
|
use clap::{command, Parser};
|
||||||
use gemma::chip8::instructions::Chip8CpuInstructions;
|
use gemma::chip8::instructions::Chip8CpuInstructions;
|
||||||
use gemma::chip8::instructions::Chip8CpuInstructions::XXXXERRORINSTRUCTION;
|
use gemma::chip8::instructions::Chip8CpuInstructions::XXXXERRORINSTRUCTION;
|
||||||
|
use gemma::chip8::quirk_modes::QuirkMode::Chip8;
|
||||||
|
|
||||||
/// ch8disasm
|
/// ch8disasm
|
||||||
///
|
///
|
||||||
@@ -26,7 +27,7 @@ impl Disassembler {
|
|||||||
for (offset, byte) in from_data.iter().enumerate() {
|
for (offset, byte) in from_data.iter().enumerate() {
|
||||||
working_instruction = (working_instruction << 8) | (*byte as u16);
|
working_instruction = (working_instruction << 8) | (*byte as u16);
|
||||||
if offset % 2 != 0 {
|
if offset % 2 != 0 {
|
||||||
let decoded = Chip8CpuInstructions::decode(working_instruction);
|
let decoded = Chip8CpuInstructions::decode(working_instruction, &Chip8);
|
||||||
let decoded_string = decoded.to_string();
|
let decoded_string = decoded.to_string();
|
||||||
let mut current_parts = String::new();
|
let mut current_parts = String::new();
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user