lets try clippy

This commit is contained in:
Trevor Merritt 2024-10-30 09:45:18 -04:00
parent dfce9bf9fe
commit 4fb2d6af29
10 changed files with 491 additions and 362 deletions

29
.idea/workspace.xml generated
View File

@ -7,9 +7,13 @@
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml" />
</component>
<component name="ChangeListManager">
<<<<<<< Updated upstream
<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" />
</list>
=======
<list default="true" id="9bcba7c5-ac1d-4216-959a-63faee7047bc" name="Changes" comment="" />
>>>>>>> Stashed changes
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
@ -54,17 +58,29 @@
&quot;Cargo.Build `Test chip8::video::test::poke_byte`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test chip8::video::test::scroll_down_1_row_test`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test computer::test`.executor&quot;: &quot;Run&quot;,
<<<<<<< Updated upstream
&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 `Test video::test`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build gemma.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Run ch8asm.executor&quot;: &quot;Run&quot;,
=======
&quot;Cargo.Build `Test computer_dump_registers_to_string`.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 `Test instructions_name_tests`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build `Test video::test`.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Build gemma.executor&quot;: &quot;Run&quot;,
>>>>>>> Stashed changes
&quot;Cargo.Run emmagui.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Run gemmaegui.executor&quot;: &quot;Debug&quot;,
&quot;Cargo.Run gemmaegui_viewer.executor&quot;: &quot;Debug&quot;,
&quot;Cargo.Run gemmaimgui.executor&quot;: &quot;Debug&quot;,
&quot;Cargo.Run trevors_chip8_toy.executor&quot;: &quot;Debug&quot;,
<<<<<<< Updated upstream
&quot;Cargo.Test ch8asm::test.executor&quot;: &quot;Debug&quot;,
=======
>>>>>>> Stashed changes
&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;,
@ -93,9 +109,17 @@
&quot;Cargo.Test chip8::video::test::scroll_down_1_row_test.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test chip8::video::test::write_checkboard.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test computer::test.executor&quot;: &quot;Debug&quot;,
<<<<<<< Updated upstream
&quot;Cargo.Test instruction_tests.executor&quot;: &quot;Run&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 computer_dump_registers_to_string.executor&quot;: &quot;Run&quot;,
&quot;Cargo.Test encode_decode_name_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 instructions_name_tests.executor&quot;: &quot;Run&quot;,
>>>>>>> Stashed changes
&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;Debug&quot;,
@ -258,9 +282,14 @@
<workItem from="1729353568282" duration="4624000" />
<workItem from="1729375372050" duration="3579000" />
<workItem from="1729797802231" duration="9220000" />
<<<<<<< Updated upstream
<workItem from="1729992186995" duration="4475000" />
<workItem from="1730040713781" duration="2808000" />
<workItem from="1730065968935" duration="6000" />
=======
<workItem from="1729992186995" duration="4226000" />
<workItem from="1730115460078" duration="31140000" />
>>>>>>> Stashed changes
</task>
<servers />
</component>

3
TODO Normal file
View File

@ -0,0 +1,3 @@
XOChip
- 00DN
- scroll screen content up N hires pixel, in XO-CHIP only selected planes are scrolled

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,7 @@ use log::{debug};
use crate::chip8::delay_timer::DelayTimer;
use crate::chip8::keypad::Keypad;
use crate::chip8::quirk_modes::QuirkMode;
use crate::chip8::quirk_modes::QuirkMode::Chip8;
use crate::chip8::registers::Chip8Registers;
use crate::chip8::sound_timer::SoundTimer;
use crate::chip8::stack::Chip8Stack;
@ -101,7 +102,7 @@ impl Chip8Computer {
let low_byte = local_memory.peek(start_pc + 1) as u16;
let result = high_byte | low_byte;
let decoded_instruction =
Chip8CpuInstructions::decode(result);
Chip8CpuInstructions::decode(result, &self.quirk_mode);
// todo: THIS IS BAD AND IS A SIDE EFFECT
decoded_instruction.execute(self);

View File

@ -8,6 +8,7 @@ use rand::{random, Rng};
use crate::chip8::computer::{Chip8Computer};
use crate::chip8::cpu_states::Chip8CpuStates::WaitingForKey;
use crate::chip8::instructions::Chip8CpuInstructions::*;
use crate::chip8::quirk_modes::QuirkMode;
use crate::chip8::util::InstructionUtil;
use crate::constants::{*};
@ -259,6 +260,10 @@ pub enum Chip8CpuInstructions {
///
/// Load V0..VX from RPL user flags (X <= 7)
LIDR(u8),
/// 0xBxNN
///
/// Jump to Address XNN+Vx
JPX(u8, u16)
}
impl Chip8CpuInstructions {
@ -308,12 +313,16 @@ impl Chip8CpuInstructions {
Chip8CpuInstructions::DIS => INST_DIS,
Chip8CpuInstructions::ENA => INST_ENA,
Chip8CpuInstructions::ORY(_, _) => INST_ORY,
JPX(_, _) => INST_JPX,
XXXXERRORINSTRUCTION => "XX ERROR XX",
}
}
pub fn operands(&self) -> String {
match self {
JPX(x, addr) => {
format!("0x{x:02x}, 0x{addr:04x}")
}
Chip8CpuInstructions::SYS(addr) |
Chip8CpuInstructions::JPI(addr) |
Chip8CpuInstructions::JPA(addr) |
@ -528,6 +537,9 @@ impl Chip8CpuInstructions {
INST_LDD => {
LDD(param1 as u8)
}
INST_JPX => {
JPX(param1 as u8, param2)
}
_ => {
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::LDIA(addr) => 0xA000 | 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::DRW(x_register, y_register, height) => {
0xD000 | ((*x_register as u16) << 8) | ((*y_register as u16) << 4) | (*height as u16)
@ -585,7 +598,7 @@ impl Chip8CpuInstructions {
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 y_param = InstructionUtil::read_y_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;
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,
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,
0x00FD => Chip8CpuInstructions::EXIT,
0x00FE => Chip8CpuInstructions::DIS,
@ -856,6 +894,12 @@ impl Chip8CpuInstructions {
// The program counter is set to nnn plus the value of V0.
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) => {
// Cxkk - RND Vx, byte
// Set Vx = random byte AND kk.

View File

@ -2,7 +2,6 @@
pub enum QuirkMode {
#[default]
Chip8,
SChipLegacy,
XOChip,
SChipModern
}

View File

@ -29,6 +29,7 @@ pub const INST_DRW: &str = "DRW";
pub const INST_EXIT: &str = "EXIT";
pub const INST_JPA: &str = "JPA";
pub const INST_JPI: &str = "JPI";
pub const INST_JPX: &str = "JPX";
pub const INST_BCD: &str = "BCD";
pub const INST_LDD: &str = "LDD";
pub const INST_LDF: &str = "LDF";

View File

@ -6,6 +6,7 @@ use gemma::chip8::delay_timer::DelayTimer;
use gemma::chip8::instructions::Chip8CpuInstructions;
use gemma::chip8::instructions::Chip8CpuInstructions::JPA;
use gemma::chip8::keypad::Keypad;
use gemma::chip8::quirk_modes::QuirkMode::{Chip8, SChipModern, XOChip};
use gemma::chip8::registers::Chip8Registers;
use gemma::chip8::sound_timer::SoundTimer;
use gemma::chip8::stack::Chip8Stack;
@ -72,6 +73,8 @@ fn encode_decode_test() {
assert_eq!(Chip8CpuInstructions::STR(1).encode(), 0xF175);
assert_eq!(Chip8CpuInstructions::LIDR(1).encode(), 0xF185);
/*
assert!(matches!(Chip8CpuInstructions::decode(0xF175), Chip8CpuInstructions::STR(1)));
assert!(matches!(Chip8CpuInstructions::decode(0xF185), Chip8CpuInstructions::LIDR(1)));
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(0xfe55), Chip8CpuInstructions::LDIX(0xe)));
assert!(matches!(Chip8CpuInstructions::decode(0xf365), Chip8CpuInstructions::LDRI(0x3)));
*/
}
#[test]
@ -129,8 +133,8 @@ fn decoder_test_invalid_instructions() {
];
for i in invalid_to_encode {
assert_eq!(Chip8CpuInstructions::decode(i).encode(), 0xffff);
assert!(matches!(Chip8CpuInstructions::decode(i), Chip8CpuInstructions::XXXXERRORINSTRUCTION));
assert_eq!(Chip8CpuInstructions::decode(i, &Chip8).encode(), 0xffff);
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());
}
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(&current.asm);
assert_eq!(i.to_string(), asm.to_string());
assert_eq!(i.operands(), current.operands);
}
}
#[test]
fn instructions_operands_tests() {
@ -1744,11 +1404,3 @@ fn computer_dump_registers_to_string() {
// now verify.
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();
}

View File

@ -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(&current.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));
}
}

View File

@ -2,6 +2,7 @@ use std::path::Path;
use clap::{command, Parser};
use gemma::chip8::instructions::Chip8CpuInstructions;
use gemma::chip8::instructions::Chip8CpuInstructions::XXXXERRORINSTRUCTION;
use gemma::chip8::quirk_modes::QuirkMode::Chip8;
/// ch8disasm
///
@ -26,7 +27,7 @@ impl Disassembler {
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);
let decoded = Chip8CpuInstructions::decode(working_instruction, &Chip8);
let decoded_string = decoded.to_string();
let mut current_parts = String::new();