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
use super::{super::assembler::*, Program};
use super::{super::instruction_set::InstructionType::*, OutputType};
pub struct Greeter();
impl Program for Greeter {
fn clock_print_interval(&self) -> u64 {
// We don't want the clock times to interrupt our nice dialog.
std::u64::MAX
}
fn output_type(&self) -> OutputType {
OutputType::Text
}
fn ram_address_space_bits(&self) -> usize {
// I mean how long is your name really?
5
}
fn rom(&self) -> Vec<u16> {
let newline = '\n' as u8;
let hello_data = "\nWhat's your name? ".chars().map(|c| c as u8);
let nice_to_meet_data = "Nice to meet you ".chars().map(|c| c as u8);
assemble!(
// Labels
label start;
label wait_loop;
label out_loop;
label exit_out;
label out;
label process_char;
label process_to_out;
label hello;
label nice;
label out_string;
label end;
// Pointers
current_char =ram= 0;
out_start =ram= 1;
out_return =ram= 2;
line_end =ram= 3;
line_start =ram= 4;
// Program start
start: LIA.with_ptr(line_start);
STI.with_ptr(line_end);
LIA.with_label(hello);
STI.with_ptr(out_start);
LIA.with_label(wait_loop);
STI.with_ptr(out_return);
JMP.with_label(out);
wait_loop: IN.with_label(process_char);
JMP.with_label(wait_loop);
// Output
out: LDB.with_ptr(out_start);
out_loop: LDR;
JZ.with_label(exit_out);
OUT;
// We override the old data with 0s
// if it's rom it doesn't really matter
// since it is not writeable.
LIA.with_0();
STR;
LIA.with_data(1);
ADD;
SWP;
JMP.with_label(out_loop);
exit_out: LDB.with_ptr(out_return);
JMR;
// If char is newline jump to out.
process_char: STI.with_ptr(current_char);
LIB.with_data(newline);
SUB;
JZ.with_label(process_to_out);
// Otherwise store the char at *line_end
LDB.with_ptr(line_end);
LDA.with_ptr(current_char);
STR;
// And increment line_end
LIA.with_data(1);
ADD;
LIB.with_ptr(line_end);
STR;
JMP.with_label(wait_loop);
// Set arguments to out and jump to it.
process_to_out:
// First print message
LIA.with_label(out_string);
STI.with_ptr(out_return);
LIA.with_label(nice);
STI.with_ptr(out_start);
JMP.with_label(out);
// Then print stored string.
out_string: LIA.with_label(end);
STI.with_ptr(out_return);
LIA.with_ptr(line_start);
STI.with_ptr(out_start);
JMP.with_label(out);
end: JMP.with_label(start);
data#hello: hello_data;
NOP;
data#nice: nice_to_meet_data;
)
}
}