cpu/
diagnostics.rs

1//! Diagnostic information for log messages and alarms.
2//!
3//! The real TX-2 did not have any accompanying message to go along
4//! with alarms, but the emulator does.
5use std::fmt::{Display, Formatter};
6
7use base::instruction::Instruction;
8use base::prelude::{Address, SymbolicInstruction};
9
10/// `CurrentInstructionDiagnostics` is only for generating debug
11/// information.  It must not be used for control/execution
12/// purposes.
13///
14/// We sometimes clone this struct in cases where we are unlikely to
15/// use the cloned value (e.g. where an alarm is possible but
16/// unlikely) and so a clone of this struct needs to remain cheap.
17#[derive(Debug, Clone)]
18pub struct CurrentInstructionDiagnostics {
19    /// The instruction we are currently executing (which will not
20    /// always be the same as the contents of the N register).
21    pub current_instruction: Instruction,
22    /// The address from which we fetched the current instruction
23    /// (which is not the same as the current value of the P register,
24    /// since that gets incremented after an instruction is fetched).
25    pub instruction_address: Address,
26}
27
28impl Display for &CurrentInstructionDiagnostics {
29    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
30        if let Ok(symbolic) = SymbolicInstruction::try_from(&self.current_instruction) {
31            write!(f, "instruction {symbolic}")?;
32        } else {
33            write!(f, "instruction {:>012o}", self.current_instruction.bits(),)?;
34        };
35        write!(f, " at address {:>06o}", self.instruction_address)
36    }
37}
38
39/// Fetches diagnostics about the current instruction.
40pub trait DiagnosticFetcher {
41    fn diagnostics(self) -> CurrentInstructionDiagnostics;
42}
43
44impl DiagnosticFetcher for CurrentInstructionDiagnostics {
45    fn diagnostics(self) -> CurrentInstructionDiagnostics {
46        self
47    }
48}
49
50impl DiagnosticFetcher for &CurrentInstructionDiagnostics {
51    fn diagnostics(self) -> CurrentInstructionDiagnostics {
52        self.clone()
53    }
54}