122 lines
3.9 KiB
Rust
122 lines
3.9 KiB
Rust
pub struct InstructionUtil {}
|
|
|
|
impl InstructionUtil {
|
|
/// Byte To Bools
|
|
/// Convert a u8 byte to an array of bool
|
|
pub fn byte_to_bools(to_convert: u8) -> [bool; 8] {
|
|
let mut return_values = [false; 8];
|
|
for i in 0..8 {
|
|
let new_value = to_convert >> i & 0x1 == 1;
|
|
return_values[i as usize] = new_value;
|
|
}
|
|
return_values
|
|
}
|
|
|
|
/// Byte To Bools
|
|
/// Convert an array of bool to a u8
|
|
pub fn bools_to_byte(to_convert: [bool; 8]) -> u8 {
|
|
let mut return_value = 0u8;
|
|
for i in 0..to_convert.len() {
|
|
let new_bit = 0x1 << i;
|
|
if to_convert[i] {
|
|
return_value |= new_bit
|
|
}
|
|
}
|
|
return_value
|
|
}
|
|
|
|
/// Split Bytes
|
|
/// Split a u16 into a pair of u8 values for high and low byte
|
|
pub fn split_bytes(to_split: u16) -> (u8, u8) {
|
|
let high = to_split.rotate_left(8) as u8;
|
|
let low = (to_split & 0xff) as u8;
|
|
|
|
(high, low)
|
|
}
|
|
|
|
/// Join Bytes
|
|
/// Joins 2 u8 into a single u16 with high and low
|
|
/// bytes provided
|
|
pub fn join_bytes(high: u8, low: u8) -> u16 {
|
|
(high as u16) << 8 | low as u16
|
|
}
|
|
|
|
/// Swap Endian
|
|
/// Swaps the endianess of a value
|
|
/// 0xabcd -> 0xcdab
|
|
pub fn swap_endian(to_swap:u16) -> u16 {
|
|
let low = to_swap & 0xff;
|
|
let high = to_swap & 0xff00;
|
|
low << 8 | high >> 8
|
|
}
|
|
|
|
/// Split Bytes Swap Endian
|
|
/// Swaps endianness and return both bytes separately
|
|
pub fn split_bytes_swap_endian(to_split: u16) -> (u8, u8) {
|
|
InstructionUtil::split_bytes(InstructionUtil::swap_endian(to_split))
|
|
}
|
|
|
|
/// Join Bytes Swap Endian
|
|
/// Swaps endianness and returns the combined bytes
|
|
pub fn join_bytes_swap_endian(high :u8, low: u8) -> u16 {
|
|
InstructionUtil::swap_endian(InstructionUtil::join_bytes(high, low))
|
|
}
|
|
|
|
/// Read Address from Instruction
|
|
/// Reads the 'address' portion of an instruction
|
|
/// Returns the 12 LSB
|
|
/// 0xabcd -> 0x0bcd
|
|
pub fn read_addr_from_instruction(instruction_to_read_from: u16) -> u16 {
|
|
instruction_to_read_from & 0x0FFF
|
|
}
|
|
|
|
/// Read Nibble from Instruction
|
|
/// Returns the lowest 4 bits of the instruction
|
|
/// 0xabcd -> 0x0d
|
|
pub fn read_nibble_from_instruction(instruction_to_read_from: u16) -> u8 {
|
|
( instruction_to_read_from & 0x000F )as u8
|
|
}
|
|
|
|
/// Read X From Instruction
|
|
/// Returns the 4 LSB of the high byte of the instruction
|
|
/// Returns bits 9-13
|
|
/// 0xabcd -> 0x0b
|
|
pub fn read_x_from_instruction(instruction_to_read_from: u16) -> u8 {
|
|
(instruction_to_read_from & 0x0F00).rotate_right(8) as u8
|
|
}
|
|
|
|
/// Read Y from Instruction
|
|
/// Returns the 4 MSB from the low byte of the instruction
|
|
/// Returns bits 5-8
|
|
/// 0xabcd -> 0x0c
|
|
pub fn read_y_from_instruction(instruction_to_read_from: u16) -> u8 {
|
|
(instruction_to_read_from & 0x00F0).rotate_right(4) as u8
|
|
}
|
|
|
|
/// Read Byte from Instruction
|
|
/// Returns the 8 LSB from the instruction
|
|
/// Returns bits 0-7
|
|
/// 0xabcd -> 0xcd
|
|
pub fn read_byte_from_instruction(instruction_to_read_from: u16) -> u8 {
|
|
(instruction_to_read_from & 0x00FF) as u8
|
|
}
|
|
|
|
/// Alias for read_x_from_instruction
|
|
pub fn read_upper_byte_lower_nibble(to_read_from: u16) -> u8 {
|
|
InstructionUtil::read_x_from_instruction(to_read_from)
|
|
}
|
|
|
|
pub fn read_bits_from_instruction(instruction_bytes: u16, first_bit: u8, last_bit: u8) -> u16 {
|
|
// shift the value over by the 'first bit' bits
|
|
let working = instruction_bytes.rotate_right(first_bit as u32);
|
|
let mut working_mask: i32 = 0x00;
|
|
// build the mask
|
|
for _ in first_bit..=last_bit {
|
|
working_mask = working_mask.rotate_left(1) | 0x01;
|
|
}
|
|
|
|
// apply the mask to the working value
|
|
working & working_mask as u16
|
|
}
|
|
}
|