-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathiset-src.html
356 lines (324 loc) · 16 KB
/
iset-src.html
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
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
<h3>Instruction set design puzzle</h3>
<p>There were a number of design choices made to maximize versatility of the
two-address instruction set while keeping the relay count as low as
possible. The starting arbitrary decision is that the B field is the one
which can be modified by self modified code. This implies:</p>
<ul>
<li>The B field needs to hold the destination address for jump
instructions, otherwise we can't implement subroutine linkage.</li>
<ul>
<li>But this means that the A field needs to be the one with the
complementer (controlled by the "com" bit), so we can test the A
argument for zero (by setting up the ALU to negate the A operand) and
conditionally jump all in one instruction.</li>
<li>This also implies that the B operand of the ALU needs the zero-MUX
(controlled by the "ben" bit), so that it can be masked off for this
comparison.</li>
</ul>
</ul>
<p>But which field is the result address? It turns out that we need
both.</p>
<ul>
<li>We need to be able to write to the B address in order to implement a
data move instruction (the "st"ore instruction), since we need to be able
to mask off the operand we are storing to (to pass the other argument
unchanged), and the B side has the zero-MUX.</li>
<li>But we need to be able to write to the A address in order to implement
the single-cycle loop instructions (since the B address has the jump
target): incjne and incjeq.</li>
<li>More subtly, in order to support indirection (for support of pointers)
with self-modified code, we need to be able to write both to the field
with the modifying address for write indirection, and to the other field
for read indirection. We can modify the B field of the store instruction
for write indirection, and ideally we should have a complementary load
instruction (which moves data from B to A) for read indirection. We don't
have it, but we can make do with an add instruction which writes to A by
requiring that the target address be pre-cleared.</li>
<ul>
<li>Note that we don't ever have to write to both the A and B fields at
the same time, so the memory system does not require multiple write
ports- just a single port fed by a MUX.</li>
<li>Four more relays and an added control bit would be needed to provide
a zero-MUX for the A operand to implement a load instruction for read
indirection.</li>
</ul>
</ul>
<p>Other concerns:</p>
<ul>
<li>Shift and rotate left can be implemented by adding an operand to
itself.</li>
<li>Shift and rotate right require another 9-bit 2:1 MUX at the expense
of 5 relays (we could have left these instructions out, but didn't).</li>
</ul>
<h3>Instruction Set</h3>
<p>Here is a printable <a href="http://sourceforge.net/projects/relaysbc/files/refcard.pdf/download">Reference card.pdf</a></p>
<p>The B field is always given on the right with these assembly mnemonics.
This is the field which is subject to change by self-modifying code and is
usually the result address.</p>
<p>If a two-operand instruction has a suffix of "to", as in "addto", it
means the result is placed in the right-side operand (in the B field). If
the "to" is missing, it means the result is stored in the left side (in the
A field). There is one exception to this rule: "st" (store) saves its result
in the right side even though it does not have the "to" suffix.</p>
<p>A hash (or pound sign) in front of the left operand signifies an
immediate value. The A field is treated as containing the data itself
instead of containing an address and the 'imm' bit of the instruction will
be set.</p>
<p>There are a few instructions which store their result on the left (which
means they have the "wra" bit set). These include add, rsb, incjne and
incjeq. Add and rsb seem redundant since the addto and rsbto instructions
exist, but they are needed to implement read indirection from pointers. A
real "ld" (load) instruction which saves on the left would be better for
this, but would require more relays and more control bits to implement.</p>
<p>Here are some of the possible instructions:</p>
<p><b>4010FF00 nop</b></p>
<p> No operation. Carry flag is preserved (ALU is set up to add 0xFF +
0x00 + carry flag: so if carry was set, it will be set again when this
instruction completes).
</p>
<p><b>C810FF00 halt</b></p>
<p> The clock is stopped until user presses step or run. Carry flag is
preserved.
</p>
<p><b>00000000 clc</b></p>
<p> Clear the carry flag.
</p>
<p><b>4020FF00 stc</b></p>
<p> Set the carry flag.
</p>
<p><b>4018FFbb jmp bb</b></p>
<p> Unconditional jump to bb. Carry flag is preserved. PC = bb.
</p>
<p><b>8408aabb jsr aa, bb</b></p>
<p> Jump to subroutine located at bb. The return address is placed in
memory location aa (which could be a jmp instruction located at the end of
the subroutine). Carry is cleared.
</p>
<p><b>0061aabb jmi aa, bb</b></p>
<p><b>0061aabb jlt aa, bb</b></p>
<p> Jump to bb if signed contents of memory location aa is negative
(minus, or less than zero). If [aa].7 == 1 then PC = bb else PC = PC + 1.
Carry flag is set if [aa] is zero.
</p>
<p><b>0069aabb jpl aa, bb</b></p>
<p><b>0069aabb jge aa, bb</b></p>
<p> Jump to bb if signed contents of memory location aa is positive or
zero (plus, or greater than or equal to zero). If [aa].7 == 0 then PC = bb
else PC = PC + 1. Carry flag is set if [aa] is zero.
</p>
<p><b>0062aabb jeq aa, bb</b></p>
<p> Jump to bb if contents of memory location aa is equal to zero. If
[aa] == 0 then PC = bb else PC = PC + 1. Carry flag is set if [aa] is zero.
</p>
<p><b>006Aaabb jne aa, bb</b></p>
<p> Jump to bb if contents of memory location aa is not equal to zero.
If [aa] != 0 then PC = bb else PC = PC + 1. Carry flag is set if [aa] is
zero.
</p>
<p><b>0063aabb jle aa, bb</b></p>
<p> Jump to bb if signed contents of memory location aa is less than or
equal to zero. If [aa] <= 0 then PC = bb else PC = PC + 1. Carry flag is
set if [aa] is zero.
</p>
<p><b>006Baabb jgt aa, bb</b></p>
<p> Jump to bb if signed contents of memory location aa is greater than
zero. If [aa] > 0 then PC = bb else PC = PC + 1. Carry flag is set if [aa]
is zero.
</p>
<p><b>006400bb jcc bb</b></p>
<p><b>006400bb jlo bb</b></p>
<p> Jump to bb if carry flag is clear (or if unsigned left argument is
lower than unsigned right argument of previous subtraction instruction). If
C == 0 then PC = bb else PC = PC + 1.
</p>
<p><b>006C00bb jcs bb</b></p>
<p><b>006C00bb jhs bb</b></p>
<p> Jump to aa if carry flag is set (or if unsigned left argument is
higher or same as unsigned right argument of previous subtraction
instruction). If C == 1 then PC = aa else PC = PC + 1.
</p>
<p><b>0066aabb jls aa, bb</b></p>
<p> Jump to bb if unsigned left argument is lower or same as unsigned
right argument of previous subtraction instruction. The result of the
subtraction instruction must be available in memory location aa. If C ==0
or [aa] == 0 then PC = bb else PC = PC + 1.
</p>
<p><b>006Eaabb jhi aa, bb</b></p>
<p> Jump to bb if unsigned left argument is higher than unsigned right
argument of previous subtraction instruction. The result of the subtraction
instruction must be available in memory location aa. If C == 1 and [aa] !=
0 then PC = bb else PC = PC + 1.
</p>
<p><b>020Aaabb je aa, bb</b></p>
<p> Jump to bb if left argument is even. If [aa].0 == 0 then PC = bb
else PC = PC + 1.
</p>
<p><b>0202aabb jo aa, bb</b></p>
<p> Jump to bb if unsigned left argument is odd. If [aa].0 == 1 then
PC = bb else PC = PC + 1.
</p>
<p><b>802Aaabb incjne aa, bb</b></p>
<p> Increment [aa] and jump if there is no carry from this. If [aa] ==
255 then PC = PC + 1 else PC = bb. [aa] = [aa] + 1.
</p>
<p><b>8022aabb incjeq aa, bb</b></p>
<p> Increment [aa] and jump if there is a carry. If [aa] == 255 then PC
= bb else PC = PC + 1. [aa] = [aa] + 1.
</p>
<p><b>0800aabb st aa, bb</b></p>
<p> Store contents of memory location aa into memory location bb. Carry
is cleared.
</p>
<p><b>4800aabb st #aa, bb</b></p>
<p> Store constant from instruction field aa into memory location bb.
Carry is cleared.
</p>
<p><b>1000aa00 out aa</b></p>
<p> Store contents of memory location into output register.
</p>
<p><b>5000aa00 out #aa</b></p>
<p> Store immediate data into output register.
</p>
<p><b>9800aa00 outc aa</b></p>
<p> Write contents of memory location aa to serial port.
</p>
<p><b>B800aa00 outc #aa</b></p>
<p> Write immediate data aa to serial port.
</p>
<p><b>680000bb in bb</b></p>
<p> Read input port and save value in memory location bb.
</p>
<p><b>E80000bb inwait bb</b></p>
<p> Pause CPU. When inputs change, resume CPU, read new input and save
value in memory location bb. If instead one of the keypad keys is pressed,
resume CPU and place the keypad hex code into bb (the hex keys give codes
0x00 - 0x0F and the others give codes in the range 0x10 - 0x17). Also, if
there is a key-press on the console-serial the CPU is resumed and the
character is placed into bb.
</p>
<p><b>480000bb clr bb</b></p>
<p> Clear memory location bb. [bb] = 0.
</p>
<p><b>8080aabb add aa, bb</b></p>
<p> Add [bb] to [aa]: [aa] = [aa] + [bb]
</p>
<p><b>0880aabb addto aa, bb</b></p>
<p> Add contents of memory location aa to memory location bb. [bb] =
[aa] + [bb]. Carry is modified.
</p>
<p><b>4880aabb addto #aa, bb</b></p>
<p> Add constant located in aa field of instruction to memory location
bb. Carry is modified. [bb] = aa + [bb].
</p>
<p><b>488001bb inc bb</b></p>
<p> Increment memory location bb. [bb] = [bb] + 1.
</p>
<p><b>48E001bb dec bb</b></p>
<p> Decrement memory location bb. [bb] = [bb] - 1.
</p>
<p><b>0890aabb adcto aa, bb</b></p>
<p> Add memory location aa and carry flag to memory location bb. Carry
is modified. [bb] = [aa] + [bb] + c.
</p>
<p><b>4890aabb adcto #aa, bb</b></p>
<p> Add constant located in aa field of instruction and carry flag to
memory location bb. Carry is modified.
</p>
<p><b>0880bbbb lsl bb</b></p>
<p> Logical shift left memory location bb. Zero is shifted into bit 0.
Bit 7 is saved in the carry flag.
</p>
<p><b>08A0bbbb lslo bb</b></p>
<p> Shift memory location bb left. One is shifted into bit 0. Bit 7 is
saved in the carry flag.
</p>
<p><b>0A00bbbb lsr bb</b></p>
<p> Logical shift rights memory location bb. Zero is shifted into bit 7.
Bit 0 is saved in the carry flag.
</p>
<p><b>0A20bbbb lsro bb</b></p>
<p> Shift memory location bb right. One is shifted into bit 7. Bit 0 is
saved in the carry flag.
</p>
<p><b>0A00bbbb lsrto bb</b></p>
<p> Logical shift rights memory location aa and save the result in
memory location bb. Zero is shifted into bit 7. Bit 0 is saved in the carry flag.
</p>
<p><b>0A20bbbb lsroto bb</b></p>
<p> Shift memory location aa right and save the result in memory
location bb. One is shifted into bit 7. Bit 0 is saved in the carry flag.
</p>
<p><b>0080bbbb ntoc bb</b></p>
<p> Move sign bit of memory location bb into carry. This is useful to
construct arithmetic (sign-preserving) shift right with this two instruction
sequence:
</p>
<p> ntoc bb</p>
<p> ror bb</p>
<p><b>0890bbbb rol bb</b></p>
<p> Rotate left memory location bb. Carry flag is shifted into bit 0.
Bit 7 is saved in the carry flag.
</p>
<p><b>0A10aabb rorto aa, bb</b></p>
<p> Rotate right memory location aa and save the result in memory
location bb.
</p>
<p><b>0A10bbbb ror bb</b></p>
<p> Rotate right memory location bb.
</p>
<p><b>80E0aabb rsb aa, bb</b></p>
<p> Reverse subtract: [aa] = [bb] - [aa].
</p>
<p><b>08E0aabb rsbto aa, bb</b></p>
<p> Subtract memory location aa from memory location bb. Carry is
modified. [bb] = [bb] - [aa].
</p>
<p><b>48E0aabb rsbto #aa, bb</b></p>
<p> Subtract constant located in aa field from memory location bb. [bb]
= [bb] - aa.
</p>
<p><b>08D0aabb rsbcto aa, bb</b></p>
<p> Subtract memory location aa and inverse of carry flag from memory location bb. Carry is
modified. [bb] = [bb] - [aa] - ~c.
</p>
<p><b>48D0aabb rsbcto #aa, bb</b></p>
<p> Subtract constant located in aa field and inverse of carry flag from memory location bb. [bb]
= [bb] - aa - ~c.
</p>
<p><b>0980aabb andto aa, bb</b></p>
<p> Bitwise AND contents of memory location aa into memory location bb.
[bb] = [bb] & [aa].
</p>
<p><b>4980aabb andto #aa, bb</b></p>
<p> Bitwise AND constant in aa field into memory location bb. [bb] =
[bb] & aa.
</p>
<p><b>09C0aabb bicto aa, bb</b></p>
<p> Clear each bit in memory location bb with a corresponding bit which
is set in memory location aa: [bb] = [bb] & ~[aa].
</p>
<p><b>49C0aabb bicto #aa, bb</b></p>
<p> [bb] = [bb] & ~aa.
</p>
<p><b>0860aabb negto aa, bb</b></p>
<p> Load 2's complement inverse of memory location aa into memory
location bb. [bb] = -[aa].
</p>
<p><b>0850aabb ngcto aa, bb</b></p>
<p> Load 1's complement of memory location aa plus carry into memory
location bb. [bb] = ~[aa] + c.
</p>
<p><b>0860bbbb neg bb</b></p>
<p> 2's complement memory location bb. [bb] = -[bb].
</p>
<p><b>0850bbbb ngc bb</b></p>
<p> Complement and then add carry to location bb. [bb] = ~[bb] + c.
Use for multi-precision negate.
</p>
<p><b>0840aabb comto aa, bb</b></p>
<p> Load 1's complement of memory location aa into memory location bb:
[bb] = ~[aa].
</p>
<p><b>0840bbbb com bb</b></p>
<p> 1's complement of memory location aa: [bb] = ~[bb].
</p>