feo3boy_opcodes/compiler/instr/
mod.rs

1//! Provides instructions, which are the definitions of what opcodes do.
2
3use std::fmt;
4use std::ops::Index;
5use std::slice::SliceIndex;
6
7use crate::compiler::instr::flow::Element;
8use crate::microcode::Microcode;
9use crate::opcode::{CBOpcode, InternalFetch, Opcode};
10
11pub mod builder;
12pub mod flow;
13
14/// Which opcode this instruction implements.
15#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd)]
16pub enum InstrId {
17    /// Instruction implements the CPU internal-fetch routine.
18    InternalFetch,
19    /// Instruction implements a normal opcode.
20    Opcode(Opcode),
21    /// Instruction implements the second byte of a CB opcode.
22    CBOpcode(CBOpcode),
23}
24
25impl fmt::Display for InstrId {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        match self {
28            Self::Opcode(opcode) => write!(f, "{}", opcode),
29            Self::CBOpcode(cbopcode) => write!(f, "{}", cbopcode),
30            Self::InternalFetch => write!(f, "{}", InternalFetch),
31        }
32    }
33}
34
35/// Definition of an instruction in the gbz80 CPU. Opcodes identify particular
36/// instructions.
37#[derive(Debug, Clone)]
38pub struct InstrDef {
39    /// ID of the instruction being defined.
40    id: InstrId,
41    /// Sequence of microcodes which make up this instruction definition.
42    microcode: Vec<Microcode>,
43    /// Code-flow of this InstrDef.
44    flow: Element,
45}
46
47impl InstrDef {
48    /// Get the number of microcode instructions in this Instr.
49    pub fn len(&self) -> usize {
50        self.microcode.len()
51    }
52
53    /// Get the label applied to this InstrDef.
54    pub fn id(&self) -> InstrId {
55        self.id
56    }
57
58    /// Get the code-flow of this instruction definition.
59    pub fn flow(&self) -> &Element {
60        &self.flow
61    }
62}
63
64/// Get the microcode at the given index.
65impl<T> Index<T> for InstrDef
66where
67    T: SliceIndex<[Microcode]>,
68{
69    type Output = <T as SliceIndex<[Microcode]>>::Output;
70
71    fn index(&self, index: T) -> &Self::Output {
72        &self.microcode[index]
73    }
74}