use std::sync::OnceLock;
use super::{
api::{FLAG_H, FLAG_V},
util::tern_op_b,
};
pub const HALF_CARRY_ADD_TABLE: [u8; 8] = [0, FLAG_H, FLAG_H, FLAG_H, 0, 0, 0, FLAG_H];
pub const HALF_CARRY_SUB_TABLE: [u8; 8] = [0, 0, FLAG_H, 0, FLAG_H, 0, FLAG_H, FLAG_H];
pub const OVERFLOW_ADD_TABLE: [u8; 8] = [0, 0, 0, FLAG_V, FLAG_V, 0, 0, 0];
pub const OVERFLOW_SUB_TABLE: [u8; 8] = [0, FLAG_V, 0, 0, 0, 0, FLAG_V, 0];
pub struct Z80Tables {
pub sz53_table: [u8; 0x100],
pub sz53p_table: [u8; 0x100],
pub parity_table: [u8; 0x100],
}
impl Default for Z80Tables {
fn default() -> Self {
Self::new()
}
}
impl Z80Tables {
fn new() -> Self {
let mut sz53_table = [0; 0x100];
let mut sz53p_table = [0; 0x100];
let mut parity_table = [0; 0x100];
for i in 0..0x100 {
sz53_table[i] = (i as u8) & (0x08 | 0x20 | 0x80);
let mut j = i as u8;
let mut parity = 0;
for _ in 0..8 {
parity ^= j & 1;
j >>= 1;
}
parity_table[i] = tern_op_b(parity != 0, 0, 0x04);
sz53p_table[i] = sz53_table[i] | parity_table[i];
}
sz53_table[0] |= 0x40;
sz53p_table[0] |= 0x40;
Self {
sz53_table,
sz53p_table,
parity_table,
}
}
}
#[warn(clippy::redundant_closure)]
pub fn get() -> &'static Z80Tables {
static TABLES: OnceLock<Z80Tables> = OnceLock::new();
TABLES.get_or_init(Z80Tables::new)
}