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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use std::borrow::Cow;
use std::io::{self, Write};
use std::path::Path;
use emulator::{Flags, Instruction, IoRegisters, Ram};
use super::*;
pub fn status(computer: &mut Computer<'_>, io: &IoRegisters,
program: &Option<Program>, flags: Option<Flags>) {
let flag_register = computer.cpu.inspect_flags().clone();
let volatile_interrupt = computer.cpu.check_volatile_interrupt();
let stored_interrupt = computer.cpu.check_stored_interrupt();
let reg = computer.cpu.inspect_registers();
let input = io.inspect_input().borrow();
let output = io.inspect_output().borrow();
let (path, instruction, mnemonic) = if let &Some(ref program) = program {
let inst = program.instructions[computer.instruction_pointer];
(
ellipsize_path(&program.path, 41),
format_instruction(inst),
inst.to_mnemonic(Some(computer.instruction_pointer)),
)
} else {
("-".into(), "-".into(), "".into())
};
print!("
Register: Eingaberegister: Aktuelles Mikroprogramm:
R0: {0:08b } FC: {8:08b } {program_path}
R1: {1:08b } FD: {9:08b }
R2: {2:08b } FE: {10:08b} Nächster Befehl ({ip:05b}):
R3: {3:08b } FF: {11:08b} {instruction}
R4: {4:08b } ~ {mnemonic}
R5: {5:08b } Ausgaberegister:
R6: {6:08b } FE: {12:08b} Flag (Register) | Interrupt: A/010, B/111
R7: {7:08b } FF: {13:08b} C: {co} ({cf}), N: {no} ({nf}), Z: {zo} ({zf}) | INT: {ia}, {ib}
",
reg[0], reg[1], reg[2], reg[3],
reg[4], reg[5], reg[6], reg[7],
input[0], input[1], input[2], input[3],
output[0], output[1],
program_path = path,
instruction = instruction,
mnemonic = mnemonic,
ip = computer.instruction_pointer,
co = flags.map_or("-".into(), |f| format!("{}", f.carry() as u8)),
no = flags.map_or("-".into(), |f| format!("{}", f.negative() as u8)),
zo = flags.map_or("-".into(), |f| format!("{}", f.zero() as u8)),
ia = volatile_interrupt as u8,
ib = stored_interrupt as u8,
cf = flag_register.carry() as u8,
nf = flag_register.negative() as u8,
zf = flag_register.zero() as u8);
io::stdout().flush().unwrap();
}
fn ellipsize_path(path: &Path, max_length: usize) -> Cow<'_, str> {
assert!(max_length >= 4);
let path_string = path.to_string_lossy();
if path_string.chars().count() > max_length {
let rev_short: String = path_string.chars().rev().take(max_length - 3).collect();
"...".chars().chain(rev_short.chars().rev()).collect()
} else {
path_string
}
}
fn format_instruction(inst: Instruction) -> String {
format!("{:02b} {:05b} | {}{} | {:03b} {:04b} {}{} | {}{} {:04b} | {}",
inst.get_address_control(),
inst.get_next_instruction_address(),
inst.is_bus_writable() as u8,
inst.is_bus_enabled() as u8,
inst.get_register_address_a(),
inst.get_constant_input() & 0b1111,
inst.should_write_register_b() as u8,
inst.should_write_register() as u8,
inst.is_alu_input_a_bus() as u8,
inst.is_alu_input_b_const() as u8,
inst.get_alu_instruction(),
inst.should_store_flags() as u8)
}
pub fn display_ram(ram: &Ram<'_>) {
println!("\n _0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _A _B _C _D _E _F");
for (i, cell) in ram.inspect().borrow()[0..252].iter().enumerate() {
if i % 16 == 0 {
print!("\n{:X}_ ", i / 16);
}
print!(" {:02X}", cell);
}
println!("\n");
}
pub fn display_program(program: &Program) {
println!();
for (addr, inst) in program.instructions.iter().enumerate() {
println!("{:05b}: {:30} {}", addr, inst.to_mnemonic(Some(addr)),
format_instruction(*inst));
}
println!();
}
pub fn display_help() {
println!("\n\
FX = <value> Eingaberegister setzen (zB: FC = 11010)\n\
ENTER Nächsten Befehl ausführen\n\
load <path> Neues Mikroprogramm laden (CPU wird zurückgesetzt)\n\
trigger <int> Interrupt auslösen:\
\n INTA (MAC 010): Nur für den nächsten Befehl gültig\
\n INTB (MAC 111): Gültig bis zum nächsten Befehl mit MAC = 111\n\
ram RAM-Übersicht anzeigen\n\
program Mikroprogramm anzeigen (ohne NOPs)\n\
help Hilfe anzeigen\n\
exit/quit Emulator beenden (alternativ: STRG-D)\n")
}