Adds more util methods for swapping endianness and extracting data from instructions

Adds tests for new util methods
This commit is contained in:
2025-05-26 08:40:15 -04:00
parent 74bf2e71e4
commit d27d2e8e45
10 changed files with 300 additions and 33 deletions
+2 -2
View File
@@ -1,3 +1,4 @@
use std::{fs, io};
use flate2::write::{GzDecoder, GzEncoder};
use flate2::Compression;
use gemma::chip8::computer::Chip8Computer;
@@ -14,7 +15,7 @@ fn load_compressed_result(file_path: &str) -> io::Result<String> {
let compressed_data = fs::read(file_path)?;
// Create a GzDecoder to uncompress the data
let mut decoder = GzDecoder::new(&compressed_data[..]);
let mut decoder = GzDecoder::new(&mut compressed_data[..]);
let mut decompressed_data = String::new();
// Read the decompressed data directly into a String
@@ -60,4 +61,3 @@ fn computer_001_system_zero_state() {
assert_eq!(serialized, expected_string);
}
}
+1 -1
View File
@@ -304,7 +304,7 @@ fn ld_dt_vx_test() {
x.registers.poke(0x1, 0x10);
Chip8CpuInstructions::LDD(0x1).execute(&mut x);
assert_eq!(x.delay_timer.current(), 0x10);
for i in 0..0x20 {
for _ in 0..0x20 {
x.delay_timer.tick();
}
assert_eq!(x.delay_timer.current(), 0);
+219
View File
@@ -0,0 +1,219 @@
use std::collections::BTreeMap;
use gemma::chip8::util::InstructionUtil;
#[test]
fn byte_to_bools() {
let data_set: BTreeMap<u8, [bool; 8]> = BTreeMap::from(
[
(0x00, [false, false, false, false, false, false, false, false]),
(0x0f, [true, true, true, true, false, false, false, false]),
(0xaa, [false, true, false, true, false, true, false, true]),
(0xf0, [false, false, false, false, true, true, true, true]),
(0xff, [true, true, true, true, true, true, true, true]),
]
);
for (key, value) in data_set.iter() {
let result_array = InstructionUtil::byte_to_bools(*key);
for i in 0..8 {
assert_eq!(result_array[i], value[i]);
}
}
}
#[test]
fn bools_to_byte() {
let data_set: BTreeMap<u8, [bool; 8]> = BTreeMap::from(
[
(0x00, [false, false, false, false, false, false, false, false]),
(0x0f, [true, true, true, true, false, false, false, false]),
(0xaa, [false, true, false, true, false, true, false, true]),
(0xf0, [false, false, false, false, true, true, true, true]),
(0xff, [true, true, true, true, true, true, true, true]),
]
);
for (key, value) in data_set.iter() {
let result = InstructionUtil::bools_to_byte(*value);
assert_eq!(result, *key);
}
}
#[test]
fn split_bytes() {
let data_set: BTreeMap<u16, (u8, u8)> = BTreeMap::from(
[
(0xff00, (0xff, 0x00)),
(0x00ff, (0x00, 0xff)),
(0xabcd, (0xab, 0xcd)),
(0xcdab, (0xcd, 0xab))
]
);
for (key, value) in data_set.iter() {
assert_eq!(InstructionUtil::split_bytes(*key), *value);
}
}
#[test]
fn join_bytes() {
let data_set: BTreeMap<u16, (u8, u8)> = BTreeMap::from(
[
(0xff00, (0xff, 0x00)),
(0x00ff, (0x00, 0xff)),
(0xabcd, (0xab, 0xcd)),
(0xcdab, (0xcd, 0xab))
]
);
for (key, (low, high )) in data_set.iter() {
assert_eq!(InstructionUtil::join_bytes(*low, *high), *key);
}
}
#[test]
fn swap_endian() {
let data_set: BTreeMap<u16, u16> = BTreeMap::from(
[
(0xabcd, 0xcdab),
(0x00ff, 0xff00),
(0xff00, 0x00ff),
(0xffff, 0xffff),
(0x0000, 0x0000)
]
);
for (key, value) in data_set.iter() {
assert_eq!(InstructionUtil::swap_endian(*key), *value);
}
}
#[test]
fn split_bytes_swap_endian() {
let data_set: BTreeMap<u16, (u8, u8)> = BTreeMap::from([
(0x0000, (0x00, 0x00)),
(0xffff, (0xff, 0xff)),
(0xff00, (0x00, 0xff)),
(0x00ff, (0xff, 0x00)),
(0xabcd, (0xcd, 0xab))
]);
for (key, result) in data_set.iter() {
assert_eq!(InstructionUtil::split_bytes_swap_endian(*key), *result)
}
}
#[test]
fn join_bytes_swap_endian() {
let data_set: BTreeMap<u16, (u8, u8)> = BTreeMap::from([
(0xffff, (0xff, 0xff)),
(0x0000, (0x00, 0x00)),
(0xff00, (0x00, 0xff)),
(0x00ff, (0xff, 0x00)),
(0xabcd, (0xcd, 0xab))
]);
for (key, (low, high)) in data_set.iter() {
assert_eq!(InstructionUtil::join_bytes_swap_endian(*low, *high), *key);
}
}
#[test]
fn read_address_from_instruction() {
let data_set: BTreeMap<u16, u16> = BTreeMap::from([
(0xabcd, 0x0bcd),
(0xffff, 0x0fff),
(0x0000, 0x0000),
(0x8123, 0x0123)
]) ;
for (key, value) in data_set.iter() {
assert_eq!(InstructionUtil::read_addr_from_instruction(*key), *value);
}
}
#[test]
fn read_nibble_from_instruction() {
let data_set: BTreeMap<u16, u8> = BTreeMap::from([
(0xffff, 0x0f),
(0x0000, 0x00),
(0xabcd, 0x0d),
]);
for(key, value) in data_set.iter() {
assert_eq!(InstructionUtil::read_nibble_from_instruction(*key), *value);
}
}
#[test]
fn read_x_from_instruction() {
let data_set: BTreeMap<u16, u8> = BTreeMap::from([
(0xffff, 0x0f),
(0x0000, 0x00),
(0x0a00, 0x0a),
(0x0b00, 0x0b)
]);
for (key, value) in data_set.iter() {
assert_eq!(InstructionUtil::read_x_from_instruction(*key), *value);
}
}
#[test]
fn read_y_from_instruction() {
let data_set: BTreeMap<u16, u8> = BTreeMap::from([
(0xffff, 0x0f),
(0x0000, 0x00),
(0x00a0, 0x0a),
(0x00b0, 0x0b)
]);
for (key, value) in data_set.iter() {
assert_eq!(InstructionUtil::read_y_from_instruction(*key), *value);
}
}
#[test]
fn read_byte_from_instruction() {
let data_set: BTreeMap<u16, u8> = BTreeMap::from([
(0xffff, 0xff),
(0x0000, 0x00),
(0xabcd, 0xcd),
(0xcdab, 0xab)
]);
for (key, value) in data_set.iter() {
assert_eq!(InstructionUtil::read_byte_from_instruction(*key), *value);
}
}
#[test]
fn read_upper_byte_lower_nibble() {
let data_set: BTreeMap<u16, u8> = BTreeMap::from([
(0x0000, 0x00),
(0xabcd, 0x0b),
(0xffff, 0x0f),
(0xcdab, 0x0d)
]);
for (key, value) in data_set.iter() {
assert_eq!(InstructionUtil::read_upper_byte_lower_nibble(*key), *value);
}
}
#[test]
fn read_bits_from_instruction() {
let data_set: BTreeMap<u16, (u8, u8, u16)> = BTreeMap::from([
(0x0000, (0, 7, 0x00)),
(0x0000, (8, 15, 0x00)),
(0xffff, (0, 7, 0xff)),
(0xffff, (8, 15, 0xff)),
]);
for (key, (start, end, value)) in data_set.iter() {
let result = InstructionUtil::read_bits_from_instruction(*key, *start, *end);
assert_eq!(result, *value);
}
}