rmg-001/src/utils.rs

147 lines
5.5 KiB
Rust
Raw Normal View History

2021-10-18 01:42:36 +00:00
#[derive(Debug)]
pub enum BitIndex {
I0,
I1,
I2,
I3,
I4,
I5,
I6,
I7,
}
pub fn get_bit_index(index: BitIndex) -> u8 {
match index {
BitIndex::I0 => 0,
BitIndex::I1 => 1,
BitIndex::I2 => 2,
BitIndex::I3 => 3,
BitIndex::I4 => 4,
BitIndex::I5 => 5,
BitIndex::I6 => 6,
BitIndex::I7 => 7,
}
}
pub fn get_bit(byte: u8, index: BitIndex) -> bool {
((byte >> get_bit_index(index)) & 0b00000001) == 1
}
pub fn set_bit(byte: u8, value: bool, index: BitIndex) -> u8 {
match value {
true => 0b00000001 << get_bit_index(index) | byte,
false => ((0b0000001 << get_bit_index(index)) ^ 0b11111111) & byte,
}
}
2021-10-14 01:50:48 +00:00
pub fn join_bytes(byte1: u8, byte2: u8) -> u16 {
((byte1 as u16) << 8) | (byte2 as u16)
}
pub fn add_half_carry(byte1: u8, byte2: u8) -> bool {
let byte1 = byte1 & 0b00001111;
let byte2 = byte2 & 0b00001111;
get_bit(byte1 + byte2, BitIndex::I4)
}
pub fn sub_half_carry(byte1: u8, byte2: u8) -> bool {
let byte1 = byte1 & 0b00001111;
let byte2 = byte2 & 0b00001111;
byte2 > byte1
}
2021-10-18 00:14:41 +00:00
pub fn add_half_carry_16bit(byte1: u16, byte2: u16) -> bool {
let byte1 = byte1 & 0b0000111111111111;
let byte2 = byte2 & 0b0000111111111111;
let result = byte1 + byte2;
get_bit(result.to_be_bytes()[0], BitIndex::I4)
}
pub fn sub_half_carry_16bit(byte1: u16, byte2: u16) -> bool {
let byte1 = byte1 & 0b0000111111111111;
let byte2 = byte2 & 0b0000111111111111;
byte2 > byte1
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_set_bit() {
assert_eq!(set_bit(0b00000000, true, BitIndex::I0), 0b00000001);
assert_eq!(set_bit(0b00000000, true, BitIndex::I1), 0b00000010);
assert_eq!(set_bit(0b00000000, true, BitIndex::I2), 0b00000100);
assert_eq!(set_bit(0b00000000, true, BitIndex::I3), 0b00001000);
assert_eq!(set_bit(0b00000000, true, BitIndex::I4), 0b00010000);
assert_eq!(set_bit(0b00000000, true, BitIndex::I5), 0b00100000);
assert_eq!(set_bit(0b00000000, true, BitIndex::I6), 0b01000000);
assert_eq!(set_bit(0b00000000, true, BitIndex::I7), 0b10000000);
assert_eq!(set_bit(0b11111111, false, BitIndex::I0), 0b11111110);
assert_eq!(set_bit(0b11111111, false, BitIndex::I1), 0b11111101);
assert_eq!(set_bit(0b11111111, false, BitIndex::I2), 0b11111011);
assert_eq!(set_bit(0b11111111, false, BitIndex::I3), 0b11110111);
assert_eq!(set_bit(0b11111111, false, BitIndex::I4), 0b11101111);
assert_eq!(set_bit(0b11111111, false, BitIndex::I5), 0b11011111);
assert_eq!(set_bit(0b11111111, false, BitIndex::I6), 0b10111111);
assert_eq!(set_bit(0b11111111, false, BitIndex::I7), 0b01111111);
// Just a couple of random test
assert_eq!(set_bit(0b00000001, true, BitIndex::I0), 0b00000001);
assert_eq!(set_bit(0b11101111, true, BitIndex::I4), 0b11111111);
assert_eq!(set_bit(0b11111110, false, BitIndex::I0), 0b11111110);
assert_eq!(set_bit(0b00010000, false, BitIndex::I4), 0b00000000);
}
#[test]
fn test_get_bit() {
assert_eq!(get_bit(0b00000001, BitIndex::I0), true);
assert_eq!(get_bit(0b00000010, BitIndex::I1), true);
assert_eq!(get_bit(0b00000100, BitIndex::I2), true);
assert_eq!(get_bit(0b00001000, BitIndex::I3), true);
assert_eq!(get_bit(0b00010000, BitIndex::I4), true);
assert_eq!(get_bit(0b00100000, BitIndex::I5), true);
assert_eq!(get_bit(0b01000000, BitIndex::I6), true);
assert_eq!(get_bit(0b10000000, BitIndex::I7), true);
assert_eq!(get_bit(0b11111110, BitIndex::I0), false);
assert_eq!(get_bit(0b11111101, BitIndex::I1), false);
assert_eq!(get_bit(0b11111011, BitIndex::I2), false);
assert_eq!(get_bit(0b11110111, BitIndex::I3), false);
assert_eq!(get_bit(0b11101111, BitIndex::I4), false);
assert_eq!(get_bit(0b11011111, BitIndex::I5), false);
assert_eq!(get_bit(0b10111111, BitIndex::I6), false);
assert_eq!(get_bit(0b01111111, BitIndex::I7), false);
}
2021-10-14 01:50:48 +00:00
#[test]
fn test_join_two_bytes() {
assert_eq!(join_bytes(0b10101010, 0b11111111), 0b1010101011111111);
assert_eq!(join_bytes(0b11111111, 0b10101010), 0b1111111110101010);
}
#[test]
fn test_half_carry() {
assert_eq!(add_half_carry(0b10101010, 0b11111111), true);
assert_eq!(add_half_carry(0b00000100, 0b00001100), true);
assert_eq!(add_half_carry(0b00000100, 0b00000100), false);
assert_eq!(add_half_carry(0b00000100, 0b00001000), false);
2021-10-15 04:58:51 +00:00
assert_eq!(add_half_carry(0b00001111, 0b00000001), true);
2021-10-18 00:14:41 +00:00
assert_eq!(add_half_carry_16bit(0b1010101000000000, 0b1111111100000000), true);
assert_eq!(add_half_carry_16bit(0b0000010000000000, 0b0000110000000000), true);
assert_eq!(add_half_carry_16bit(0b0000010000000000, 0b0000010000000000), false);
assert_eq!(add_half_carry_16bit(0b0000010000000000, 0b0000100000000000), false);
assert_eq!(add_half_carry_16bit(0b0000111100000000, 0b0000000100000000), true);
assert_eq!(sub_half_carry(0b00010000, 0b00001000), true);
assert_eq!(sub_half_carry(0b00000000, 0b00000001), true);
assert_eq!(sub_half_carry(0b00001000, 0b00001000), false);
2021-10-18 00:14:41 +00:00
assert_eq!(sub_half_carry_16bit(0b0001000000000000, 0b0000100000000000), true);
assert_eq!(sub_half_carry_16bit(0b0000000000000000, 0b0000000100000000), true);
assert_eq!(sub_half_carry_16bit(0b0000100000000000, 0b0000100000000000), false);
}
}