Skip to content

Commit fcbed3e

Browse files
committed
Add input field to mlogv32 UART0
1 parent 1782ba5 commit fcbed3e

File tree

1 file changed

+63
-25
lines changed

1 file changed

+63
-25
lines changed

src/bin/mlogv32.rs

Lines changed: 63 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![allow(dead_code)]
22

33
use std::borrow::Cow;
4+
use std::collections::VecDeque;
45
use std::io::{Cursor, Read};
56
use std::sync::mpsc::{self, Receiver, Sender};
67
use std::thread;
@@ -167,6 +168,7 @@ enum VMCommand {
167168
SetSingleStep(bool),
168169
SetBreakpoint(Option<u32>),
169170
PrintVar(U16String, Option<String>),
171+
TxUART0(String),
170172
}
171173

172174
struct VMState {
@@ -199,12 +201,47 @@ fn tui(
199201

200202
siv.add_fullscreen_layer(
201203
LinearLayout::horizontal()
204+
.child(
205+
// slider to set the size of the UART0 panel
206+
PaddedView::new(
207+
Margins::tb(1, 1),
208+
SliderView::vertical(100)
209+
.value(stdout_scroll_height)
210+
.on_change(|siv, value| {
211+
siv.call_on_name(
212+
"stdout_scroll",
213+
|v: &mut ResizedView<LinearLayout>| {
214+
v.set_height(SizeConstraint::Fixed(value));
215+
},
216+
);
217+
}),
218+
)
219+
.fixed_width(1),
220+
)
202221
.child(
203222
LinearLayout::vertical()
204223
.child(
205224
Panel::new(
206-
ScrollView::new(TextView::new_with_content(stdout))
207-
.scroll_strategy(ScrollStrategy::StickToBottom)
225+
LinearLayout::vertical()
226+
.child(
227+
ScrollView::new(TextView::new_with_content(stdout))
228+
.scroll_strategy(ScrollStrategy::StickToBottom)
229+
.full_height(),
230+
)
231+
.child(
232+
EditView::new()
233+
.on_submit({
234+
let tx = tx.clone();
235+
move |siv, cmd| {
236+
tx.send(VMCommand::TxUART0(cmd.to_string() + "\r"))
237+
.unwrap();
238+
siv.call_on_name("stdin", |view: &mut EditView| {
239+
view.set_content("");
240+
});
241+
}
242+
})
243+
.with_name("stdin"),
244+
)
208245
.fixed_height(stdout_scroll_height)
209246
.with_name("stdout_scroll"),
210247
)
@@ -288,23 +325,6 @@ fn tui(
288325
)),
289326
),
290327
)
291-
.child(
292-
// slider to set the size of the UART0 panel
293-
PaddedView::new(
294-
Margins::tb(1, 1),
295-
SliderView::vertical(100)
296-
.value(stdout_scroll_height)
297-
.on_change(|siv, value| {
298-
siv.call_on_name(
299-
"stdout_scroll",
300-
|v: &mut ResizedView<ScrollView<TextView>>| {
301-
v.set_height(SizeConstraint::Fixed(value));
302-
},
303-
);
304-
}),
305-
)
306-
.fixed_width(1),
307-
)
308328
.full_screen(),
309329
);
310330

@@ -545,7 +565,8 @@ fn main() -> Result<(), Box<dyn Error>> {
545565
let mut prev_power = true;
546566
let mut frozen = false;
547567
let mut ticks = 0;
548-
let mut uart_buf = String::new();
568+
let mut uart_rx_buf = String::new();
569+
let mut uart_tx_buf = VecDeque::<u8>::new();
549570
let state_update_interval = Duration::from_secs_f64(1. / 8.);
550571
let start = Instant::now();
551572
let mut run_start = start;
@@ -557,24 +578,38 @@ fn main() -> Result<(), Box<dyn Error>> {
557578
ticks += 1;
558579
}
559580

560-
// UART0 terminal
581+
// UART0 rx
561582
if let BuildingData::Memory(uart0) = &mut *uart0.data.borrow_mut() {
562583
let mut rx_read = (uart0[UART_RX_READ] as usize) % uart_fifo_modulo;
563584
let rx_write = (uart0[UART_RX_WRITE] as usize) % uart_fifo_modulo;
564585
if rx_read != rx_write {
565586
while rx_read != rx_write {
566587
let c = uart0[UART_RX_START + rx_read] as u8;
567-
uart_buf.push(c as char);
588+
uart_rx_buf.push(c as char);
568589
rx_read = (rx_read + 1) % uart_fifo_modulo;
569590
}
570591
uart0[UART_RX_READ] = rx_write as f64;
571592

572593
if do_tui {
573-
stdout.append(&uart_buf);
594+
stdout.append(&uart_rx_buf);
574595
} else {
575-
print!("{uart_buf}");
596+
print!("{uart_rx_buf}");
576597
}
577-
uart_buf.clear();
598+
uart_rx_buf.clear();
599+
}
600+
601+
if !uart_tx_buf.is_empty() {
602+
let tx_read = (uart0[UART_TX_READ] as usize) % uart_fifo_modulo;
603+
let mut tx_write = (uart0[UART_TX_WRITE] as usize) % uart_fifo_modulo;
604+
let mut next_tx_write = (tx_write + 1) % uart_fifo_modulo;
605+
while next_tx_write != tx_read
606+
&& let Some(c) = uart_tx_buf.pop_front()
607+
{
608+
uart0[tx_write] = c as f64;
609+
tx_write = next_tx_write;
610+
next_tx_write = (tx_write + 1) % uart_fifo_modulo;
611+
}
612+
uart0[UART_TX_WRITE] = tx_write as f64;
578613
}
579614
}
580615

@@ -673,6 +708,9 @@ fn main() -> Result<(), Box<dyn Error>> {
673708
}
674709
};
675710
}
711+
VMCommand::TxUART0(msg) => {
712+
uart_tx_buf.extend(msg.as_bytes());
713+
}
676714
}
677715
}
678716

0 commit comments

Comments
 (0)