VIP inspection tooling #4
			
				
			
		
		
		
	| 
						 | 
					@ -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