Skip to main content

c6000_disassembler/instruction/
register.rs

1use std::{
2    fmt::Display,
3    ops::{AddAssign, Not},
4};
5
6#[derive(PartialEq, Eq, Clone, Copy, Debug)]
7pub enum Register {
8    A(u8),
9    APair(u8, u8),
10    B(u8),
11    BPair(u8, u8),
12}
13
14impl Register {
15    pub fn from(value: u8, side: bool) -> Self {
16        if side == false {
17            Self::A(value)
18        } else {
19            Self::B(value)
20        }
21    }
22
23    pub fn from_pair(value: u8, side: bool) -> Self {
24        let value2 = value - value % 2;
25        let value1 = value2 + 1;
26        if side == false {
27            Self::APair(value1, value2)
28        } else {
29            Self::BPair(value1, value2)
30        }
31    }
32
33    pub fn side(&self) -> bool {
34        match self {
35            Self::A(_) => false,
36            Self::APair(_, _) => false,
37            Self::B(_) => true,
38            Self::BPair(_, _) => true,
39        }
40    }
41}
42
43impl Display for Register {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        match self {
46            Self::A(num) => write!(f, "A{num}"),
47            Self::APair(num1, num2) => write!(f, "A{num1}:A{num2}"),
48            Self::B(num) => write!(f, "B{num}"),
49            Self::BPair(num1, num2) => write!(f, "B{num1}:B{num2}"),
50        }
51    }
52}
53
54impl AddAssign<u8> for Register {
55    fn add_assign(&mut self, rhs: u8) {
56        match self {
57            Self::A(num) | Self::B(num) => *num += rhs,
58            Self::APair(num1, num2) | Self::BPair(num1, num2) => {
59                *num1 += rhs - rhs % 2;
60                *num2 = *num1 - 1;
61            }
62        }
63    }
64}
65
66impl Not for Register {
67    type Output = Self;
68
69    fn not(self) -> Self::Output {
70        match self {
71            Self::A(num) => Self::B(num),
72            Self::APair(num1, num2) => Self::BPair(num1, num2),
73            Self::B(num) => Self::A(num),
74            Self::BPair(num1, num2) => Self::APair(num1, num2),
75        }
76    }
77}
78
79#[derive(PartialEq, Eq, Clone, Copy, Debug)]
80pub enum ControlRegister {
81    /// Addressing mode register.
82    AMR,
83    /// Control status register.
84    CSR,
85    /// Galois field multiply control register.
86    GFPGFR,
87    /// Interrupt clear register.
88    ICR,
89    /// Interrupt enable register.
90    IER,
91    /// Interrupt flag register.
92    IFR,
93    /// Interrupt return pointer register.
94    IRP,
95    /// Interrupt set register.
96    ISR,
97    /// Interrupt service table pointer register.
98    ISTP,
99    /// Nonmaskable interrupt return pointer register.
100    NRP,
101    /// Program counter, E1 phase.
102    PCE1,
103
104    // Control Register File Extensions (C64x+ DSP)
105    /// Debug interrupt enable register.
106    DIER,
107    /// DSP core number register.
108    DNUM,
109    /// Exception clear register.
110    ECR,
111    /// Exception flag register.
112    EFR,
113    /// GMPY A-side polynomial register.
114    GPLYA,
115    /// GMPY B-side polynomial register.
116    GPLYB,
117    /// Internal exception report register.
118    IERR,
119    /// Inner loop count register.
120    ILC,
121    /// Interrupt task state register.
122    ITSR,
123    /// NMI/Exception task state register.
124    NTSR,
125    /// Restricted entry point address register.
126    REP,
127    /// Reload inner loop count register.
128    RILC,
129    /// Saturation status register.
130    SSR,
131    /// Time-stamp counter (high 32) register.
132    TSCH,
133    /// Time-stamp counter (low 32) register.
134    TSCL,
135    /// Task state register.
136    TSR,
137}
138
139impl ControlRegister {
140    pub fn from(low: u8, high: u8) -> Option<Self> {
141        match low {
142            0b00000 => Some(Self::AMR),
143            0b00001 => Some(Self::CSR),
144            0b11001 => Some(Self::DIER),
145            0b10001 => Some(Self::DNUM),
146            0b11101 => Some(Self::ECR),
147            0b11000 => Some(Self::GFPGFR),
148            0b10110 => Some(Self::GPLYA),
149            0b10111 => Some(Self::GPLYB),
150            0b00011 => Some(Self::ICR),
151            0b00100 => Some(Self::IER),
152            0b11111 => Some(Self::IERR),
153            0b00010 if high == 0b00000 || high == 0b00010 => Some(Self::IFR),
154            0b00010 => Some(Self::ISR),
155            0b01101 => Some(Self::ILC),
156            0b00110 => Some(Self::IRP),
157            0b00101 => Some(Self::ISTP),
158            0b11011 => Some(Self::ITSR),
159            0b00111 => Some(Self::NRP),
160            0b11100 => Some(Self::NTSR),
161            0b10000 => Some(Self::PCE1),
162            0b01111 => Some(Self::REP),
163            0b01110 => Some(Self::RILC),
164            0b10101 => Some(Self::SSR),
165            0b01011 => Some(Self::TSCH),
166            0b01010 => Some(Self::TSCL),
167            0b11010 => Some(Self::TSR),
168            _ => None,
169        }
170    }
171}
172
173impl Display for ControlRegister {
174    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
175        match self {
176            Self::AMR => write!(f, "AMR"),
177            Self::CSR => write!(f, "CSR"),
178            Self::GFPGFR => write!(f, "GFPGFR"),
179            Self::ICR => write!(f, "ICR"),
180            Self::IER => write!(f, "IER"),
181            Self::IFR => write!(f, "IFR"),
182            Self::IRP => write!(f, "IRP"),
183            Self::ISR => write!(f, "ISR"),
184            Self::ISTP => write!(f, "ISTP"),
185            Self::NRP => write!(f, "NRP"),
186            Self::PCE1 => write!(f, "PCE1"),
187            Self::DIER => write!(f, "DIER"),
188            Self::DNUM => write!(f, "DNUM"),
189            Self::ECR => write!(f, "ECR"),
190            Self::EFR => write!(f, "EFR"),
191            Self::GPLYA => write!(f, "GPLYA"),
192            Self::GPLYB => write!(f, "GPLYB"),
193            Self::IERR => write!(f, "IERR"),
194            Self::ILC => write!(f, "ILC"),
195            Self::ITSR => write!(f, "ITSR"),
196            Self::NTSR => write!(f, "NTSR"),
197            Self::REP => write!(f, "REP"),
198            Self::RILC => write!(f, "RILC"),
199            Self::SSR => write!(f, "SSR"),
200            Self::TSCH => write!(f, "TSCH"),
201            Self::TSCL => write!(f, "TSCL"),
202            Self::TSR => write!(f, "TSR"),
203        }
204    }
205}
206
207pub enum RegisterFile {
208    GeneralPurpose(Register),
209    Control(ControlRegister),
210}
211
212impl RegisterFile {
213    pub fn side(&self) -> Option<bool> {
214        if let Self::GeneralPurpose(register) = self {
215            Some(register.side())
216        } else {
217            None
218        }
219    }
220}
221
222impl Display for RegisterFile {
223    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
224        match self {
225            Self::GeneralPurpose(register) => write!(f, "{register}"),
226            Self::Control(register) => write!(f, "{register}"),
227        }
228    }
229}