Krolyxon
Tag v0.3.0

Branches

Tags

Refs →

bench51cratesbench51-guisrcpanesinterrupts.rs

83 lines · 3.2 KB · Rust

1//! Interrupt system: enable, priority and request flag of each source.
2
3use bench51_core::session::{Session, vector_name};
4use bench51_core::sfr::{IE, IP, SCON, TCON};
5use eframe::egui::{self, Ui};
6
7use super::sfr_chip;
8use crate::theme::{WARNING, palette};
9use crate::widgets;
10
11/// (name, vector, IE/IP mask, request flag as (SFR, mask)).
12const SOURCES: [(&str, u16, u8, (u8, u8)); 5] = [
13 ("INT0", 0x03, 0x01, (TCON, 0x02)),
14 ("T0", 0x0B, 0x02, (TCON, 0x20)),
15 ("INT1", 0x13, 0x04, (TCON, 0x08)),
16 ("T1", 0x1B, 0x08, (TCON, 0x80)),
17 ("UART", 0x23, 0x10, (SCON, 0x03)),
18];
19
20pub fn show(ui: &mut Ui, s: &mut Session) {
21 let p = palette(ui.ctx());
22 egui::ScrollArea::vertical()
23 .auto_shrink([false; 2])
24 .show(ui, |ui| {
25 ui.horizontal(|ui| {
26 sfr_chip(ui, s, "EA", IE, 0x80);
27 ui.add_space(12.0);
28 let state = if s.sim.power_down {
29 ("power-down", WARNING)
30 } else if s.sim.idle {
31 ("idle", WARNING)
32 } else {
33 ("running", p.text_secondary)
34 };
35 ui.label(p.label("CPU"));
36 ui.label(p.label(state.0).color(state.1));
37 });
38 ui.add_space(10.0);
39 egui::Grid::new("irqs")
40 .num_columns(5)
41 .spacing([14.0, 6.0])
42 .show(ui, |ui| {
43 for h in ["Source", "Vector", "Enable", "Priority", "Request"] {
44 ui.label(p.label(h).color(p.text_disabled));
45 }
46 ui.end_row();
47 for (name, vector, mask, (flag_sfr, flag_mask)) in SOURCES {
48 let active = s.sim.last_irq == Some(vector) && !s.sim.in_service.is_empty();
49 ui.label(p.label(name).color(if active {
50 p.text_display
51 } else {
52 p.text_primary
53 }));
54 ui.label(p.data(format!("{vector:04X}")).color(p.text_secondary));
55 sfr_chip(ui, s, "EN", IE, mask);
56 sfr_chip(ui, s, "HI", IP, mask);
57 let req = s.sim.sfr(flag_sfr) & flag_mask != 0;
58 if flag_sfr == SCON {
59 widgets::bit_chip(ui, "RI|TI", req);
60 } else {
61 sfr_chip(ui, s, "REQ", flag_sfr, flag_mask);
62 }
63 ui.end_row();
64 }
65 });
66 widgets::section(ui, "In service");
67 let levels = if s.sim.in_service.is_empty() {
68 "none".to_string()
69 } else {
70 s.sim
71 .in_service
72 .iter()
73 .map(|l| format!("L{l}"))
74 .collect::<Vec<_>>()
75 .join(" > ")
76 };
77 widgets::stat_row(ui, "Levels", p.data(levels));
78 let last = s.sim.last_irq.map_or("—".to_string(), |v| {
79 format!("{v:04X}h {}", vector_name(v))
80 });
81 widgets::stat_row(ui, "Last taken", p.data(last));
82 });
83}