Files
ansi_term
arraydeque
atty
bear_lib_terminal
bear_lib_terminal_sys
bitflags
cfg_if
clap
const_cstr
dirs
dirs_sys
dlopen
dlopen_derive
downcast_rs
lazy_static
libc
num_traits
pir_8_as
pir_8_disasm
pir_8_emu
proc_macro2
quote
serde
serde_derive
strsim
syn
textwrap
time
tinyfiledialogs
toml
unicode_width
unicode_xid
vec_map
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use self::super::super::{AluOperationShiftOrRotateDirection, AluOperationShiftOrRotateType, AluOperation};


enum RespectCarry {
    No,
    YesAdd,
    YesSub,
}


impl AluOperation {
    pub(in self::super::super) fn perform_impl(self, lhs: u8, rhs: u8, carry: &mut bool) -> u8 {
        match self {
            AluOperation::Add => add(lhs, rhs, carry, RespectCarry::No),
            // [11:38] Cat Plus Plus: Or basically: just do it as addition but two-complement negate the second operand
            // [11:38] Cat Plus Plus: So 0x02 - 0x04 is 0x02 + 0xFC
            // https://discordapp.com/channels/145079846832308224/411537636994449418/600259783072940044
            AluOperation::Sub => add(lhs, (!rhs).checked_add(1).unwrap_or(0), carry, RespectCarry::No),

            AluOperation::AddC => add(lhs, rhs, carry, RespectCarry::YesAdd),
            AluOperation::SubC => add(lhs, (!rhs).checked_add(1).unwrap_or(0), carry, RespectCarry::YesSub),

            AluOperation::Not => !lhs,
            AluOperation::Or => lhs | rhs,
            AluOperation::Xor => lhs ^ rhs,
            AluOperation::And => lhs & rhs,

            AluOperation::ShiftOrRotate { d: AluOperationShiftOrRotateDirection::Left, tt } => {
                let new_carry = (lhs & 0b1000_0000) != 0;

                let ret = match tt {
                    AluOperationShiftOrRotateType::Lsf |
                    AluOperationShiftOrRotateType::Asf => lhs << 1,
                    AluOperationShiftOrRotateType::Rtc => {
                        let carry_mask = if *carry { 0b0000_0001 } else { 0b0000_0000 };

                        (lhs << 1) | carry_mask
                    }
                    AluOperationShiftOrRotateType::Rtw => lhs.rotate_left(1),
                };

                *carry = new_carry;
                ret
            }

            AluOperation::ShiftOrRotate { d: AluOperationShiftOrRotateDirection::Right, tt } => {
                let new_carry = (lhs & 0b0000_0001) != 0;

                let ret = match tt {
                    AluOperationShiftOrRotateType::Lsf => lhs >> 1,
                    AluOperationShiftOrRotateType::Asf => {
                        let msb_mask = lhs & 0b1000_0000;

                        (lhs >> 1) | msb_mask
                    }
                    AluOperationShiftOrRotateType::Rtc => {
                        let carry_mask = if *carry { 0b1000_0000 } else { 0b0000_0000 };

                        (lhs >> 1) | carry_mask
                    }
                    AluOperationShiftOrRotateType::Rtw => lhs.rotate_right(1),
                };

                *carry = new_carry;
                ret
            }
        }
    }
}

fn add(lhs: u8, rhs: u8, carry: &mut bool, respect: RespectCarry) -> u8 {
    let mut sum = (lhs as u16) + (rhs as u16);

    match (*carry, respect) {
        (false, _) |
        (true, RespectCarry::No) => {}
        (true, RespectCarry::YesAdd) => sum += 1,
        (true, RespectCarry::YesSub) => sum -= 1,
    }

    *carry = (sum & 0b1_0000_0000) != 0;

    (sum & 0b1111_1111) as u8
}