Add dpctrl+xpctrl to register view
This commit is contained in:
parent
a737cd39b7
commit
892d48e321
|
@ -1,15 +1,18 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use egui::{
|
use egui::{
|
||||||
Align, CentralPanel, Context, Label, Layout, ScrollArea, TextEdit, Ui, ViewportBuilder,
|
Align, Button, CentralPanel, Checkbox, Context, Label, Layout, ScrollArea, TextEdit, Ui,
|
||||||
ViewportId,
|
ViewportBuilder, ViewportId,
|
||||||
};
|
};
|
||||||
use egui_extras::{Column, Size, StripBuilder, TableBuilder};
|
use egui_extras::{Column, Size, StripBuilder, TableBuilder};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
emulator::SimId,
|
emulator::SimId,
|
||||||
memory::{MemoryClient, MemoryView},
|
memory::{MemoryClient, MemoryValue, MemoryView},
|
||||||
window::{utils::UiExt, AppWindow},
|
window::{
|
||||||
|
utils::{NumberEdit, UiExt},
|
||||||
|
AppWindow,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct RegisterWindow {
|
pub struct RegisterWindow {
|
||||||
|
@ -29,8 +32,7 @@ impl RegisterWindow {
|
||||||
|
|
||||||
fn show_interrupts(&mut self, ui: &mut Ui) {
|
fn show_interrupts(&mut self, ui: &mut Ui) {
|
||||||
let row_height = ui.spacing().interact_size.y;
|
let row_height = ui.spacing().interact_size.y;
|
||||||
let registers = self.registers.borrow();
|
let [mut raw_intpnd, mut raw_intenb] = self.read_address(0x0005f800);
|
||||||
let [mut raw_intpnd, mut raw_intenb] = registers.read::<[u16; 2]>(0);
|
|
||||||
let mut intenb = InterruptReg::parse(raw_intenb);
|
let mut intenb = InterruptReg::parse(raw_intenb);
|
||||||
let mut intpnd = InterruptReg::parse(raw_intpnd);
|
let mut intpnd = InterruptReg::parse(raw_intpnd);
|
||||||
ui.section("Interrupt", |ui| {
|
ui.section("Interrupt", |ui| {
|
||||||
|
@ -110,6 +112,7 @@ impl RegisterWindow {
|
||||||
add_row("LFBEND", &mut intenb.lfbend, &mut intpnd.lfbend);
|
add_row("LFBEND", &mut intenb.lfbend, &mut intpnd.lfbend);
|
||||||
add_row("SCANERR", &mut intenb.scanerr, &mut intpnd.scanerr);
|
add_row("SCANERR", &mut intenb.scanerr, &mut intpnd.scanerr);
|
||||||
});
|
});
|
||||||
|
ui.add_space(ui.available_height());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if intpnd.update(&mut raw_intpnd) {
|
if intpnd.update(&mut raw_intpnd) {
|
||||||
|
@ -119,6 +122,187 @@ impl RegisterWindow {
|
||||||
self.memory.write(self.sim_id, 0x0005f802, &raw_intenb);
|
self.memory.write(self.sim_id, 0x0005f802, &raw_intenb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn show_display_status(&mut self, ui: &mut Ui) {
|
||||||
|
let row_height = ui.spacing().interact_size.y;
|
||||||
|
let mut raw_dpstts = self.read_address(0x0005f820);
|
||||||
|
let mut dpstts = DisplayReg::parse(raw_dpstts);
|
||||||
|
ui.section("Display", |ui| {
|
||||||
|
TableBuilder::new(ui)
|
||||||
|
.column(Column::auto())
|
||||||
|
.column(Column::remainder())
|
||||||
|
.cell_layout(Layout::left_to_right(Align::Max))
|
||||||
|
.body(|mut body| {
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.label("DPSTTS");
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
let mut value_str = format!("{raw_dpstts:04x}");
|
||||||
|
ui.add_enabled(
|
||||||
|
false,
|
||||||
|
TextEdit::singleline(&mut value_str).horizontal_align(Align::Max),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(true, Checkbox::new(&mut dpstts.lock, "LOCK"));
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(false, Checkbox::new(&mut dpstts.r1bsy, "R1BSY"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(true, Checkbox::new(&mut dpstts.synce, "SYNCE"));
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(false, Checkbox::new(&mut dpstts.l1bsy, "L1BSY"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(true, Checkbox::new(&mut dpstts.re, "RE"));
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(false, Checkbox::new(&mut dpstts.r0bsy, "R0BSY"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(false, Checkbox::new(&mut dpstts.fclk, "FCLK"));
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(false, Checkbox::new(&mut dpstts.l0bsy, "L0BSY"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(false, Checkbox::new(&mut dpstts.scanrdy, "SCANRDY"));
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(true, Checkbox::new(&mut dpstts.disp, "DISP"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|_ui| {});
|
||||||
|
row.col(|ui| {
|
||||||
|
if ui
|
||||||
|
.add(Button::new("DPRST").min_size(ui.available_size()))
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
dpstts.dprst = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
ui.vertical(|ui| ui.add_space((ui.available_height() - row_height).max(0.0)));
|
||||||
|
});
|
||||||
|
if dpstts.update(&mut raw_dpstts) {
|
||||||
|
self.memory.write(self.sim_id, 0x0005f822, &raw_dpstts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_drawing_status(&mut self, ui: &mut Ui) {
|
||||||
|
let row_height = ui.spacing().interact_size.y;
|
||||||
|
let [mut raw_xpstts, raw_xpctrl] = self.read_address(0x0005f840);
|
||||||
|
let mut xpstts = DrawingReg::parse(raw_xpstts);
|
||||||
|
ui.section("Drawing", |ui| {
|
||||||
|
TableBuilder::new(ui)
|
||||||
|
.column(Column::auto())
|
||||||
|
.column(Column::remainder())
|
||||||
|
.cell_layout(Layout::left_to_right(Align::Max))
|
||||||
|
.body(|mut body| {
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.label("XPCTRL");
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
let mut value_str = format!("{raw_xpctrl:04x}");
|
||||||
|
ui.add_enabled(
|
||||||
|
false,
|
||||||
|
TextEdit::singleline(&mut value_str).horizontal_align(Align::Max),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.label("XPSTTS");
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
let mut value_str = format!("{raw_xpstts:04x}");
|
||||||
|
ui.add_enabled(
|
||||||
|
false,
|
||||||
|
TextEdit::singleline(&mut value_str).horizontal_align(Align::Max),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.label("SBCMP");
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
let old_value = xpctrl.sbcmp;
|
||||||
|
ui.add_enabled(true, NumberEdit::new(&mut xpctrl.sbcmp).range(0..32));
|
||||||
|
cmp_changed = xpctrl.sbcmp != old_value;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.label("SBCOUNT");
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(
|
||||||
|
false,
|
||||||
|
NumberEdit::new(&mut xpstts.sbcount).range(0..32),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(false, Checkbox::new(&mut xpstts.sbout, "SBOUT"));
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(false, Checkbox::new(&mut xpstts.f1bsy, "F1BSY"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(false, Checkbox::new(&mut xpstts.f0bsy, "F0BSY"));
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(false, Checkbox::new(&mut xpstts.overtime, "OVERTIME"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add_enabled(true, Checkbox::new(&mut xpstts.xpen, "XPEN"));
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
if ui
|
||||||
|
.add(Button::new("XPRST").min_size(ui.available_size()))
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
xpstts.xprst = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
ui.vertical(|ui| ui.add_space(ui.available_height()));
|
||||||
|
});
|
||||||
|
if xpstts.update(&mut raw_xpstts) {
|
||||||
|
xpstts.update(&mut raw_xpstts);
|
||||||
|
self.memory.write(self.sim_id, 0x0005f842, &raw_xpstts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_address<T: MemoryValue>(&self, address: usize) -> T {
|
||||||
|
let index = (address - 0x0005f800) / size_of::<T>();
|
||||||
|
self.registers.borrow().read(index)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppWindow for RegisterWindow {
|
impl AppWindow for RegisterWindow {
|
||||||
|
@ -145,7 +329,17 @@ impl AppWindow for RegisterWindow {
|
||||||
.horizontal(|mut strip| {
|
.horizontal(|mut strip| {
|
||||||
strip.cell(|ui| {
|
strip.cell(|ui| {
|
||||||
self.show_interrupts(ui);
|
self.show_interrupts(ui);
|
||||||
})
|
});
|
||||||
|
strip.strip(|nested| {
|
||||||
|
nested.sizes(Size::remainder(), 2).vertical(|mut strip| {
|
||||||
|
strip.cell(|ui| {
|
||||||
|
self.show_display_status(ui);
|
||||||
|
});
|
||||||
|
strip.cell(|ui| {
|
||||||
|
self.show_drawing_status(ui);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -193,3 +387,91 @@ impl InterruptReg {
|
||||||
changed
|
changed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DisplayReg {
|
||||||
|
lock: bool,
|
||||||
|
synce: bool,
|
||||||
|
re: bool,
|
||||||
|
fclk: bool,
|
||||||
|
scanrdy: bool,
|
||||||
|
r1bsy: bool,
|
||||||
|
l1bsy: bool,
|
||||||
|
r0bsy: bool,
|
||||||
|
l0bsy: bool,
|
||||||
|
disp: bool,
|
||||||
|
dprst: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DisplayReg {
|
||||||
|
fn parse(value: u16) -> Self {
|
||||||
|
Self {
|
||||||
|
lock: value & 0x0400 != 0,
|
||||||
|
synce: value & 0x0200 != 0,
|
||||||
|
re: value & 0x0100 != 0,
|
||||||
|
fclk: value & 0x0080 != 0,
|
||||||
|
scanrdy: value & 0x0040 != 0,
|
||||||
|
r1bsy: value & 0x0020 != 0,
|
||||||
|
l1bsy: value & 0x0010 != 0,
|
||||||
|
r0bsy: value & 0x0008 != 0,
|
||||||
|
l0bsy: value & 0x0004 != 0,
|
||||||
|
disp: value & 0x0002 != 0,
|
||||||
|
dprst: value & 0x0001 != 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&self, value: &mut u16) -> bool {
|
||||||
|
let new_value = (*value & 0xf800)
|
||||||
|
| if self.lock { 0x0400 } else { 0x0000 }
|
||||||
|
| if self.synce { 0x0200 } else { 0x0000 }
|
||||||
|
| if self.re { 0x0100 } else { 0x0000 }
|
||||||
|
| if self.fclk { 0x0080 } else { 0x0000 }
|
||||||
|
| if self.scanrdy { 0x0040 } else { 0x0000 }
|
||||||
|
| if self.r1bsy { 0x0020 } else { 0x0000 }
|
||||||
|
| if self.l1bsy { 0x0010 } else { 0x0000 }
|
||||||
|
| if self.r0bsy { 0x0008 } else { 0x0000 }
|
||||||
|
| if self.l0bsy { 0x0004 } else { 0x0000 }
|
||||||
|
| if self.disp { 0x0002 } else { 0x0000 }
|
||||||
|
| if self.dprst { 0x0001 } else { 0x0000 };
|
||||||
|
let changed = *value != new_value;
|
||||||
|
*value = new_value;
|
||||||
|
changed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DrawingReg {
|
||||||
|
sbout: bool,
|
||||||
|
sbcount: u8,
|
||||||
|
overtime: bool,
|
||||||
|
f1bsy: bool,
|
||||||
|
f0bsy: bool,
|
||||||
|
xpen: bool,
|
||||||
|
xprst: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DrawingReg {
|
||||||
|
fn parse(value: u16) -> Self {
|
||||||
|
Self {
|
||||||
|
sbout: value & 0x8000 != 0,
|
||||||
|
sbcount: (value >> 8) as u8 & 0x1f,
|
||||||
|
overtime: value & 0x0010 != 0,
|
||||||
|
f1bsy: value & 0x0008 != 0,
|
||||||
|
f0bsy: value & 0x0004 != 0,
|
||||||
|
xpen: value & 0x0002 != 0,
|
||||||
|
xprst: value & 0x0001 != 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&self, value: &mut u16) -> bool {
|
||||||
|
let new_value = (*value & 0x60e0)
|
||||||
|
| if self.sbout { 0x8000 } else { 0x0000 }
|
||||||
|
| (((self.sbcount & 0x1f) as u16) << 8)
|
||||||
|
| if self.overtime { 0x0010 } else { 0x0000 }
|
||||||
|
| if self.f1bsy { 0x0008 } else { 0x0000 }
|
||||||
|
| if self.f0bsy { 0x0004 } else { 0x0000 }
|
||||||
|
| if self.xpen { 0x0002 } else { 0x0000 }
|
||||||
|
| if self.xprst { 0x0001 } else { 0x0000 };
|
||||||
|
let changed = *value != new_value;
|
||||||
|
*value = new_value;
|
||||||
|
changed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue