summaryrefslogtreecommitdiff
path: root/cpu/os.asm
blob: c7abde3d65aeab24153697cfad24c8a88d2d7a2d (plain) (blame)
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# CONVENTION:
#       return value for functions : in register A
#       arguments for functions : registers A, B, C, D
#       all registers are caller-saved, except SP which is preserved by function calls

.text
    jal run_unit_tests 

    li A msghello
    jal ser_out_msg

    push Z
main_loop:
    # Process serial input
    jal check_input
    jz A end_process_input
    jal run_cmd
end_process_input:

    # Process clock ticking
    pop D
    li B _clock
    lw B 0(B)
    add D D B
    push D

    jz B main_loop
    li A msgtick
    jal ser_out_msg
    j main_loop

# PROCEDURE: run_cmd
# ROLE: execute and clear command stored in cmdline
# ARGUMENTS: none
run_cmd:
    push RA

    li A prompt
    jal ser_out_msg
    li A cmdline
    jal ser_out_msg
    li A endl
    jal ser_out_msg
    
    li A error
    jal ser_out_msg

    li A cmdline_used
    sw Z 0(A)

    pop RA
    jr RA
    

# PROCEDURE: ser_out_msg
# ROLE: write null-terminated string to serial output
# ARGUMENTS: address of string in register A
ser_out_msg:
    li C _output
ser_out_msg_loop:
    lb B 0(A)
    jz B ser_out_msg_ret
    sb B 0(C)
    incri A 1
    j ser_out_msg_loop
ser_out_msg_ret:
    jr RA

# PROCEDURE: check_input
# ROLE: check if an input byte is available. if it is, and is different from '\n' (10), add it to cmdline
# ARGUMENTS: none
# RETURN VALUE: 1 if read byte was '\n', 0 otherwise
# WARNING: no buffer overflow check.
check_input:
    li A _input
    lb A 0(A)
    jz A check_input_ret
    move B A
    sei A A '\n'
    jz A add_b_to_string
    move B Z
add_b_to_string:
    push A
    li A cmdline
    li D cmdline_used
    lw C 0(D)
    add A A C
    sb B 0(A)
    incri C 1
    sw C 0(D)
    pop A
    jz A check_input
check_input_ret:
    jr RA

# PROCEDURE: run_unit_tests
# ROLE: check that CPU features work correctly ; displays message to serial output
# ARGUMENTS: none
run_unit_tests:
  push RA
  
  li A testbegin
  jal ser_out_msg

  li A test0
  jal ser_out_msg
  jal unit_test_0
  li A testfail
  jz B t0fail
  li A testok
t0fail:
  jal ser_out_msg

  li A test1
  jal ser_out_msg
  jal unit_test_1
  li A testfail
  jz B t1fail
  li A testok
t1fail:
  jal ser_out_msg

  li A test2
  jal ser_out_msg
  jal unit_test_2
  li A testfail
  jz B t2fail
  li A testok
t2fail:
  jal ser_out_msg

  li A test3
  jal ser_out_msg
  jal unit_test_3
  li A testfail
  jz B t2fail
  li A testok
t3fail:
  jal ser_out_msg

  pop RA
  jr RA

unit_test_0:
  li B 1

  li C 12
  li D 44
  add C C D
  sei A C 56
  and B B A

  li C -7
  li D 7
  add C C D
  se A C Z
  and B B A

  jr RA
unit_test_1:
  li B 1
  jr RA
unit_test_2:
  li B 1
  jr RA
unit_test_3:
  li B 1
  jr RA

    

# READ-ONLY PROGRAM DATA
msghello:
    ascii "Hello, world!\n"
msgtick:
    ascii " ..."
prompt:
    ascii "\n$ "
endl:
    ascii "\n"
error:
    ascii "Sorry but I'm to stupid to understand that.\n"

testbegin:
  ascii "Runing CPU unit tests...\n"
testok:
  ascii "OK\n"
testfail:
  ascii "FAIL\n"
test0:
  ascii "Addition/substraction: "
test1:
  ascii "Unsigned multiplication: "
test2:
  ascii "Unsigned division: "
test3:
  ascii "Signed division/multiplication: "



.data
# Space where command-line is buffered from serial input
cmdline:
    byte 256
# Number of bytes used in the command-line buffer
cmdline_used:
    word 1