2023-03-08 11:01:18 +11:00
|
|
|
use crate::{
|
|
|
|
processor::{memory::mmio::gpu::Colour, Direction},
|
|
|
|
PAUSE_ENABLED, PAUSE_QUEUED, VERBOSE,
|
|
|
|
};
|
2023-03-06 19:20:47 +11:00
|
|
|
use std::{io, mem::transmute};
|
2023-02-26 09:42:15 +11:00
|
|
|
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! verbose_println {
|
|
|
|
($($tts:tt)*) => {
|
|
|
|
if $crate::util::is_verbose() {
|
|
|
|
println!($($tts)*);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! verbose_print {
|
|
|
|
($($tts:tt)*) => {
|
|
|
|
if $crate::util::is_verbose() {
|
|
|
|
print!($($tts)*);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn pause_then_step() {
|
|
|
|
unsafe {
|
|
|
|
if PAUSE_ENABLED {
|
|
|
|
let line = pause();
|
|
|
|
PAUSE_QUEUED = !line.contains("continue");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn pause() -> String {
|
|
|
|
let mut line = String::new();
|
|
|
|
match io::stdin().read_line(&mut line) {
|
|
|
|
Ok(_) => line,
|
|
|
|
Err(_) => String::from(""),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn is_verbose() -> bool {
|
|
|
|
match VERBOSE.get() {
|
|
|
|
Some(v) => *v,
|
|
|
|
None => false,
|
|
|
|
}
|
|
|
|
}
|
2023-02-12 09:27:41 +11:00
|
|
|
|
|
|
|
pub(crate) fn as_signed(unsigned: u8) -> i8 {
|
2023-02-20 10:01:53 +11:00
|
|
|
unsafe { transmute(unsigned) }
|
2023-02-12 09:27:41 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn get_bit(byte: u8, flag: u8) -> bool {
|
|
|
|
let mask = 1 << flag;
|
|
|
|
let got = byte & mask;
|
2023-02-12 09:41:34 +11:00
|
|
|
got > 0x0
|
2023-02-12 09:27:41 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn set_or_clear_bit(byte: u8, flag: u8, condition: bool) -> u8 {
|
|
|
|
if condition {
|
|
|
|
set_bit(byte, flag)
|
|
|
|
} else {
|
|
|
|
clear_bit(byte, flag)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn set_bit(byte: u8, flag: u8) -> u8 {
|
|
|
|
byte | (1 << flag)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn clear_bit(byte: u8, flag: u8) -> u8 {
|
|
|
|
byte & (!(1 << flag))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn rotate(byte: u8, direction: &Direction) -> (u8, bool) {
|
|
|
|
match direction {
|
|
|
|
Direction::Left => {
|
|
|
|
let carry = get_bit(byte, 7);
|
|
|
|
let r = byte << 1;
|
2023-02-12 09:41:34 +11:00
|
|
|
(r, carry)
|
2023-02-12 09:27:41 +11:00
|
|
|
}
|
|
|
|
Direction::Right => {
|
|
|
|
let carry = get_bit(byte, 0);
|
|
|
|
let r = byte >> 1;
|
2023-02-12 09:41:34 +11:00
|
|
|
(r, carry)
|
2023-02-12 09:27:41 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn get_rotation_carry(direction: &Direction) -> u8 {
|
|
|
|
match direction {
|
|
|
|
Direction::Left => 0b1,
|
|
|
|
Direction::Right => 0b10000000,
|
|
|
|
}
|
|
|
|
}
|
2023-02-20 10:01:53 +11:00
|
|
|
|
|
|
|
pub trait Nibbles {
|
|
|
|
fn get_low_nibble(&self) -> u8;
|
|
|
|
fn get_high_nibble(&self) -> u8;
|
|
|
|
fn set_low_nibble(&mut self, val: u8);
|
|
|
|
fn set_high_nibble(&mut self, val: u8);
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Nibbles for u8 {
|
|
|
|
fn get_low_nibble(&self) -> u8 {
|
|
|
|
*self & 0x0F
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_high_nibble(&self) -> u8 {
|
|
|
|
(*self >> 4) & 0x0F
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_low_nibble(&mut self, val: u8) {
|
|
|
|
*self = (*self & 0xF0) | (val & 0x0F);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_high_nibble(&mut self, val: u8) {
|
|
|
|
*self = (*self & 0x0F) | (val << 4);
|
|
|
|
}
|
|
|
|
}
|
2023-02-26 10:18:58 +11:00
|
|
|
|
2023-03-08 11:01:18 +11:00
|
|
|
pub fn scale_buffer<T: From<Colour> + Copy>(
|
|
|
|
buffer: &[T],
|
|
|
|
width: usize,
|
|
|
|
height: usize,
|
|
|
|
factor: usize,
|
|
|
|
) -> Vec<T> {
|
2023-02-26 10:18:58 +11:00
|
|
|
let mut v = vec![];
|
|
|
|
for y in 0..height {
|
|
|
|
for _ in 0..factor {
|
|
|
|
for x in 0..width {
|
|
|
|
for _ in 0..factor {
|
|
|
|
v.push(buffer[(y * width) + x]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
v
|
|
|
|
}
|
2023-03-09 11:52:24 +11:00
|
|
|
|
|
|
|
pub fn scale_buffer_in_place<T: From<Colour> + Copy>(
|
|
|
|
buffer: &[T],
|
|
|
|
target: &mut [T],
|
|
|
|
width: usize,
|
|
|
|
height: usize,
|
|
|
|
factor: usize,
|
|
|
|
) {
|
|
|
|
for y in 0..height {
|
|
|
|
for y_2 in 0..factor {
|
|
|
|
for x in 0..width {
|
|
|
|
for x_2 in 0..factor {
|
|
|
|
target[(((y * factor) + y_2) * (width * factor)) + (x * factor) + x_2] =
|
|
|
|
buffer[(y * width) + x];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|