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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
use self::super::super::super::super::isa::{GeneralPurposeRegisterBank, GeneralPurposeRegister};
use self::super::super::super::super::options::register_bank_validator;
use bear_lib_terminal::terminal::{print_xy, read_str, put_xy, clear};
use self::super::super::super::super::util::parse_with_prefix;
use bear_lib_terminal::geometry::{Point, Rect};
use num_traits::{PrimInt, Num};
use std::fmt::UpperHex;
use std::mem::size_of;
use std::str::FromStr;
const GP_REGISTER_COUNT: usize = size_of::<GeneralPurposeRegisterBank>() / size_of::<GeneralPurposeRegister>();
pub fn config_bool(x_start: usize, y_start: usize, name: &str, is_on: bool) {
line(x_start, y_start, name, if is_on { "ON" } else { "OFF" })
}
pub fn line(x_start: usize, y_start: usize, name: &str, value: &str) {
let x_start = x_start as i32;
let y_start = y_start as i32;
let name_len = name.len() as i32;
status_line_header(x_start, y_start, name);
print_xy(x_start + name_len + 1 + 1, y_start, value);
}
pub fn read_number<T: Num + PrimInt + UpperHex>(x_start: usize, y_start: usize, label: &str) -> Option<T> {
let x_start = x_start as i32;
let y_start = y_start as i32;
let label_len = label.len() as i32;
let x_past_header_start = x_start + label_len + 1 + 1;
status_line_header(x_start, y_start, label);
match read_str(Point::new(x_past_header_start, y_start), 80 - x_past_header_start) {
Some(raw_addr) => {
match parse_with_prefix(&raw_addr) {
Some(addr) => {
print_xy(x_past_header_start, y_start, &format!("{:#0w$X}", addr, w = 2 + size_of::<T>() * 2));
Some(addr)
}
None => {
print_xy(x_past_header_start, y_start, "{parse failed}");
None
}
}
}
None => {
print_xy(x_past_header_start, y_start, "{cancelled}");
None
}
}
}
pub fn read_pos_float(x_start: usize, y_start: usize, label: &str) -> Option<f64> {
let x_start = x_start as i32;
let y_start = y_start as i32;
let label_len = label.len() as i32;
let x_past_header_start = x_start + label_len + 1 + 1;
status_line_header(x_start, y_start, label);
match read_str(Point::new(x_past_header_start, y_start), 80 - x_past_header_start) {
Some(raw_flt) => {
match f64::from_str(&raw_flt) {
Ok(flt) if flt > 0f64 => {
print_xy(x_past_header_start, y_start, &flt.to_string());
Some(flt)
}
_ => {
print_xy(x_past_header_start, y_start, "{parse failed}");
None
}
}
}
None => {
print_xy(x_past_header_start, y_start, "{cancelled}");
None
}
}
}
pub fn read_gp_register_letters(x_start: usize, y_start: usize) -> Option<[char; GP_REGISTER_COUNT]> {
static LABEL: &str = "General-purpose register letters";
let x_start = x_start as i32;
let y_start = y_start as i32;
let label_len = LABEL.len() as i32;
let x_past_header_start = x_start + label_len + 1 + 1;
status_line_header(x_start, y_start, LABEL);
match read_str(Point::new(x_past_header_start, y_start), GP_REGISTER_COUNT as i32) {
Some(letters) => {
match register_bank_validator(&letters) {
Ok(()) => {
print_xy(x_past_header_start, y_start, &letters);
let mut ret = ['\0'; GP_REGISTER_COUNT];
for (i, c) in letters.chars().enumerate() {
ret[i] = c;
}
Some(ret)
}
Err(err) => {
let err_msg = &err["Register bank ".len()..];
put_xy(x_past_header_start, y_start, '{');
print_xy(x_past_header_start + 1, y_start, err_msg);
put_xy(x_past_header_start + 1 + err_msg.len() as i32, y_start, '}');
None
}
}
}
None => {
print_xy(x_past_header_start, y_start, "{cancelled}");
None
}
}
}
fn status_line_header(x_start: i32, y_start: i32, label: &str) {
let label_len = label.len() as i32;
clear(Some(Rect::from_values(x_start, y_start, 80, 1)));
print_xy(x_start, y_start, label);
put_xy(x_start + label_len, y_start, ':');
}