forked from FlatAssembler/PicoBlaze_Simulator_in_JS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdec2bin.psm
327 lines (316 loc) · 9.11 KB
/
dec2bin.psm
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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
;<b style="color: #770000">WARNING</b>: I have tried to run this on
; real PicoBlaze, but failed.
; Now, I did not have time to
; test whether a simpler
; example program using UART
; would work, to see if it
; is a problem with this
; program, or if it is maybe
; a problem with the way I
; set up PicoBlaze. I have
; opened a
; <a href="https://stackoverflow.com/q/70981222">StackOverflow question</a>
; about it, but, thus far, I
; received no response.
;This is an example program that uses
;<abbr title="Universal Asynchronous Receiver-Transmitter">UART</abbr>, the interface that PicoBlaze uses
;for connecting to terminals (a <abbr title="Disk Operating System">DOS</abbr>-like
;user interface, with a keyboard and a
;screen capable of displaying text).
;It loads base-10 integer numbers from
;the terminal, converts them into binary,
;and then prints the binary
;representations back onto the terminal.
;Example input would be: <span style="white-space: pre; display: block; font-size: 1em; background: black; color: aquamarine; margin-top: 0; margin-bottom: 0;">
<span style="color: black">;</span>1
<span style="color: black">;</span>2
<span style="color: black">;</span>4
<span style="color: black">;</span>8
<span style="color: black">;</span>15
<span style="color: black">;</span>127
<span style="color: black">;</span>255
<span style="color: black">;</span></span>
;And the expected output is: <span style="white-space:pre; display: block; font-size: 1em; background: black; color: aquamarine; margin-top: 0; margin-bottom: 0;">
<span style="color: black">;</span>1_(10)=1_(2)
<span style="color: black">;</span>2_(10)=10_(2)
<span style="color: black">;</span>4_(10)=100_(2)
<span style="color: black">;</span>8_(10)=1000_(2)
<span style="color: black">;</span>15_(10)=1111_(2)
<span style="color: black">;</span>127_(10)=1111111_(2)
<span style="color: black">;</span>255_(10)=11111111_(2)
<span style="color: black">;</span></span>
;Note that you need to click the
;"Enable UART" button in order to use it.
;Also, the trailing empty line in the
;input is necessary for the result to be
;printed.
;Now follows some boilerplate code
;we use in our Computer Architecture
;classes...
CONSTANT LED_PORT, 00
CONSTANT HEX1_PORT, 01
CONSTANT HEX2_PORT, 02
CONSTANT UART_TX_PORT, 03
CONSTANT UART_RESET_PORT, 04
CONSTANT SW_PORT, 00
CONSTANT BTN_PORT, 01
CONSTANT UART_STATUS_PORT, 02
CONSTANT UART_RX_PORT, 03
; Tx data_present
CONSTANT U_TX_D, 00000001'b
; Tx FIFO half_full
CONSTANT U_TX_H, 00000010'b
; TxFIFO full
CONSTANT U_TX_F, 00000100'b
; Rxdata_present
CONSTANT U_RX_D, 00001000'b
; RxFIFO half_full
CONSTANT U_RX_H, 00010000'b
; RxFIFO full
CONSTANT U_RX_F, 00100000'b
;The following code will not
;assemble in PicoBlaze_Simulator_in_JS
;version older than <a href="https://github.com/FlatAssembler/PicoBlaze_Simulator_in_JS/releases/tag/v2.8">v2.8</a>.
if PicoBlaze_Simulator_in_JS
display "Before starting this "
display "program, enter decimal "
display "integers separated by "
display "new-line characters in "
display "the text-area above, and "
display "also insert a new-line "
display "character after the last "
display "number."
display a ;A new-line character, see
;<a href="#newline_character">below</a> for more details.
endif
;The following code is a no-operation
;in the current version of
;<a href="https://github.com/FlatAssembler/PicoBlaze_Simulator_for_Android">PicoBlaze Simulator for Android</a>,
;but I hope it will be useful in some
;future version (when that program is
;finished by somebody who knows Java
;and Android well).
if PicoBlaze_Simulator_for_Android
display "After starting this "
display "program, type decimal "
display "integers here and "
display "press Enter after "
display "each. Right after "
display "you press Enter, "
display "this program will "
display "convert the decimal "
display "integer you just entered "
display "to binary."
display a
endif
ADDRESS 000
START:
;At the beginning, the number is 0.
load s0, 0
;And we are storing its string
;representation at the beginning
;of RAM.
namereg s3, pointer
load pointer, 0
;Now follows a loop to load
;the digits of the number.
loading_the_number:
;Load a character from the UART
;terminal.
call UART_RX
;Check whether the character is a digit.
compare s9, "0"
;If it is not a digit, jump to the
;part of the program for printing
;the number you have got.
jump c , print_the_number
compare s9, "9" + 1
;Suggestion by a <a href="https://codereview.stackexchange.com/questions/253951/converting-decimal-to-binary-in-assembly/253978#253978">StackExchange user</a>.
jump nc, print_the_number
;If it is a digit, store it into RAM.
store s9, (pointer)
add pointer, 1
;Multiply the number you have got by 10.
load sf, s0
call multiply_by_10
load s0, se
;Then, convert the digit from ASCII
;into binary.
sub s9, "0"
;And then add it to the number you
;have got.
add s0, s9
call c, abort ;In case of overflow.
jump loading_the_number ;Repeat until a
;non-digit is
;loaded.
print_the_number:
;If there are no digits to be printed,
;do not print anything.
sub pointer, 0
jump z, START
print_the_decimal:
load s4, pointer
load pointer, 0
printing_the_decimal_loop:
compare pointer, s4
jump nc, end_of_printing_the_decimal
fetch s9, (pointer)
;Do some basic sanity check: Is the
;character you are printing indeed
;a decimal digit?
compare s9, "0"
call c , abort
compare s9, "9" + 1
call nc, abort
;If it is indeed a decimal digit,
;print it.
call UART_TX
add pointer, 1
jump printing_the_decimal_loop
end_of_printing_the_decimal:
;After you have repeated the decimal
;number, print the string "_(10)=".
load s9, "_"
call UART_TX
load s9, "("
call UART_TX
load s9, "1"
call UART_TX
load s9, "0"
call UART_TX
load s9, ")"
call UART_TX
load s9, "="
call UART_TX
;If the number to be printed is
;equal to zero, print 0.
sub s0, 0
jump nz, print_the_binary
load s9, "0"
call UART_TX
jump end_of_printing_loop
print_the_binary:
;Make the pointer point to the
;beginning of RAM.
load pointer, 0
;Now goes a loop which stores the binary
;representation of the number we have
;got into RAM, but reversed.
beginning_of_converting_to_binary:
sub s0, 0
jump z , end_of_converting_to_binary
load s9, "0"
sr0 s0
jump nc, store_digit_to_memory
add s9, 1
store_digit_to_memory:
store s9, (pointer)
add pointer, 1
jump beginning_of_converting_to_binary
end_of_converting_to_binary:
;Do some basic sanity check, such as that
;the pointer does not point to zero.
compare pointer, 0
call z, abort ;Something went wrong
;so end the program.
;Check whether there are more than 8 bits.
compare pointer, 8 + 1
call nc , abort
;Now goes a loop which will print
;the binary number in RAM, with digits
;in the correct order. The pointer now
;points at a memory location right after
;the binary number (not at the last digit,
;but after it).
beginning_of_printing_loop:
sub pointer, 1
jump c , end_of_printing_loop
fetch s9 , (pointer)
;Do some basic sanity check:
;Is the character the pointer points to
;indeed a binary digit?
compare s9, "0"
jump z , memory_is_fine
compare s9, "1"
jump z , memory_is_fine
call abort ;Something went wrong,
;so end the program.
memory_is_fine:
;If everything is fine, print that
;digit.
call UART_TX
;Repeat until you have printed all
;digits of the binary number
;stored in RAM.
jump beginning_of_printing_loop
end_of_printing_loop:
;After you have printed that binary
;number, print the string "_(2)" and
;a new-line.
load s9, "_"
call UART_TX
load s9, "("
call UART_TX
load s9, "2"
call UART_TX
load s9, ")"
call UART_TX
load s9, a ;<span id="newline_character">newline character</a>, 0xa=='\n'.
;The last line is being highlighted
;incorrectly by the syntax
;highlighter, see <a href="https://github.com/FlatAssembler/PicoBlaze_Simulator_in_JS/issues/6">this GitHub issue</a> for
;more information about that.
;While I don't know how to solve that,
;there does appear to be a simple
;work-around: simply, when `<code>a</code>`
;is a hexadecimal constant, type `<code>0a</code>`
;instead, and it will be highlighted
;correctly.
call UART_TX
;The program runs in an infinite loop...
JUMP START
multiply_by_10:
load se, sf
add se, se
call c , abort
add se, se
call c , abort
add se, sf
call c , abort
add se, se
call c , abort
return
abort:
load s9, "E"
call UART_TX
load s9, "R"
call UART_TX
load s9, "R"
call UART_TX
load s9, "O"
call UART_TX
load s9, "R"
call UART_TX
load s9, "!"
call UART_TX
load s9, a ;newline
call UART_TX
infinite_loop:
jump infinite_loop
return
;Now follows some boilerplate code
;we use in our Computer Architecture
;classes...
UART_RX:
INPUT sA, UART_STATUS_PORT
TEST sA, U_RX_D
JUMP Z , UART_RX
INPUT s9, UART_RX_PORT
RETURN
UART_TX:
INPUT sA, UART_STATUS_PORT
TEST sA, U_TX_F
JUMP NZ, UART_TX
OUTPUT s9, UART_TX_PORT
RETURN