-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprogram.mem
350 lines (349 loc) · 5.65 KB
/
program.mem
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
// Hand assembled
// Format is Instr_code[15:12],Dest[11],Literal[10:0]
// STACKPTR equ 0x1FF
//
// WREG equ 0x200 // W Register
// CARRY equ 0x201 // Carry Register
// ZERO equ 0x202 // Zero Register
// INDV equ 0x203 // Indirect Value Register
// INDA equ 0x204 // Indirect Pointer Register
//
// W equ 0
// w equ 0
// M equ 1
// m equ 1
//
// ORG 0x0000
//0000 RESET: gol STARTUP
C005 // gol STARTUP => gol 0x005 => C,0,0x005
xxxx
xxxx
xxxx
//
//0004 ORG 0x0004
//0004 INTERRUPT_VECTOR: rfi // Interrupts not used
F000
//
//0005 ORG 0x0005
//0005 STARTUP:
// // initialize stack
//0005 mlw (STACKPTR - 1) // 0x1FE is top of stack
21FE
//0006 mwm STACKPTR
11FF
// //int i = 0;
// i equ 0x0000
//0007 mlw .0
2000
//0008 mwm i
1000
//
// //int j = 20;
// j equ 0x0001
//0009 mlw .20
2014
//000A mwm j
1001
//
// //int k = 0;
// k equ 0x0002
//000B mlw .0
2000
//000C mwm k
1002
//
// //int l[10];
// l equ 0x0003
// l_end equ (l + 10 - 1) // l_end = 0x000C
//
// //void main(void) {
//000D gol MAIN
C010
//
xxxx //000F
xxxx //000F
//0010 ORG 0x0010
//0010 MAIN:
// // for (i = 0; i < 10; i++) {
// // l[i] = add(&j, i);
// // }
// MAIN_TEMP_0 equ 0x000D
// MAIN_TEMP_1 equ 0x000E
//0010 mm STACKPTR,w // get top of stack
01FF
//0011 mwm MAIN_TEMP_0 // save original stack position
100D
//0012 mwm INDA // point the Indirect access at the stack
1204
//0013 mlw MAIN_ADD_RETURN // return address
2020
//0014 mwm INDV
1203
//0015 mlw .1
2001
//0016 sub INDA,M // next stack address
9A04
// // load args right to left
//0017 mm i,w
0000
//0018 mwm INDV
1203
//0019 mlw .1
2001
//001A sub INDA,M // next stack address
9A04
//001B mlw j // &j
2001
//001C mwm INDV
1203
//001D mm INDA,w
0204
//001E mwm STACKPTR
11FF
//001F gol ADD
C068
//
//0020 MAIN_ADD_RETURN:
//0020 mm STACKPTR,w
01FF
//0021 mwm INDA
1204
//0022 mm INDV,w // load return value
0203
//0023 mwm MAIN_TEMP_1 // save return value
100E
//0024 mm MAIN_TEMP_0,w // load previous STACKPTR value
000D
//0025 mwm STACKPTR // "pop" function args off stack
11FF
//0026 mlw l
2003
//0027 mwm INDA
1204
//0028 mm i,w
0000
//0029 add INDA,m
8A04
//002A mm MAIN_TEMP_1,w
000D
//002B mwm INDV
1203
//
// // i < 10 ?
//002C mlw .1
2001
//002D add i,m
8800
//002E mlw .10
200A
//002F sub i,w
9000
//0030 sms CARRY // skip if carry set
A201
//0031 gol MAIN // i < 10
C010
//
// // out of for loop
// // i = i - j;
//0032 mm j,w
0001
//0033 sub i,m
9800
//
// // if (i >= 10) {
// // j = 0xaa;
// // } else {
// // j = 0x55;
// // }
//0034 mlw .10
200A
//0035 mwm MAIN_TEMP_1 // safe to reuse
100E
//0036 rlm i,w
3000
//0037 smc CARRY // If carry set, number is negative
B201
// // borrow check doesn't work with mixed signs. Since
// // 10 is a positive literal the "compiler" knows that if i is negative,
// // i < 10
//0038 gol MAIN_I_SIGN_NEG
C041
//
//0039 mm i,w
0000
//003A sub MAIN_TEMP_1,w
900E
//003B mlw 0x55 // assume not
2055
//003C sms CARRY
A201
//003D mlw 0xaa // i > 10
20AA
//003E smc ZERO
B202
//003F mlw 0xaa // i == 10
20AA
//0040 gol MAIN_I_SIGN_END
C042
//
// // If i is negative, it's obviously less than 10
//0041 MAIN_I_SIGN_NEG:
//0041 mlw 0x55
2055
//
//0042 MAIN_I_SIGN_END:
//0042 mwm j
1001
//
// // k = 0x55a9;
//0043 mlw (0x55a9 >> 5) // staying under sign ext.
22AD // 0x55AA >> 5 = 0x2AD
//0044 add k,m // could use mwm, but we know the memory is zeroed, and this assures that carry is cleared in one op
8802
//0045 rlm k,m // 1
3802
//0046 rlm k,m // 2
3802
//0047 rlm k,m // 3
3802
//0048 rlm k,m // 4
3802
//0049 rlm k,m // 5
3802
//004A mlw 0x9
2009
//004B add k,m
8802
//
// // while ((j & k) != 0) {
// // k++;
// // }
//004C mm k,w
0002
//004D awm j,w
5001
//004E smc ZERO
B202
//004F gol MAIN_WHILE_LOOP_END // (j & k) == 0
C056
//0050 MAIN_WHILE_LOOP:
//0050 mlw .1
2001
//0051 add k,m
8802
//0052 mm k,w
0002
//0053 awm j,w
5001
//0054 sms ZERO
A202
//0055 gol MAIN_WHILE_LOOP
C050
//
//0056 MAIN_WHILE_LOOP_END:
// // i = (j | k) == -1;
//0056 mm k,w
0002
//0057 owm j,w
6001
//0058 mwm MAIN_TEMP_1
100E
//0059 mlw .-1
27FF
//005A sub MAIN_TEMP_1,w
900E
//005B mm ZERO,w // if temp == -1, zero = 1, else 0
0202
//005C mwm i;
1000
//
// // i = j > k;
//005D mm j,w
0001
//005E sub k,w // CARRY clear if Wreg > Mem
9002
//005F mlw 1 // assume true
2001
//0060 smc CARRY
B201
//0061 mlw 0
2000
//0062 mwm i
1000
//
// // i = j <= k;
//0063 mm j,w
0001
//0064 sub k,w // CARRY set if Wreg <= Mem
9002
//0065 mm CARRY,w
0201
//0066 mwm i
1000
//
//0067 END_OF_PROGRAM:
//0067 wfi // effectively a halt if there's no interrupt
E000
// // and/or the interrupt handler just does rfi
//
//0068 ADD:
// // return addr = *(STACKPTR + 2)
// // by_ref = *(STACKPTR)
// // by_val = *(STACKPTR + 1)
// // return value = *(STACKPTR - 1)
//
// // int add(int *by_ref, int by_val) {
// ADD_TEMP_0 equ 0x000F
//
//0068 mm STACKPTR,w
01FF
//0069 mwm INDA
1204
//006A mlw .1
2001
//006B add INDA,m // by_val
8A04
//006C mm INDV,w
0203
//006D mwm ADD_TEMP_0 // by_val
100F
//006E mm STACKPTR, w
01FF
//006F mwm INDA,m // by_ref
1204
//0070 mm INDV,w // by_ref pointer value loaded in W
0203
//0071 mwm INDA // by_ref pointer value loaded into indirect
1204
//0072 mm ADD_TEMP_0,w // by_val
000F
// // *by_ref = *by_ref + by_val;
//0073 add INDV,m
8A03
//
// // return by_val;
// // }
//0074 mm STACKPTR,w
01FF
//0075 mwm INDA,m
1204
//0076 mlw .1
2001
//0077 sub INDA,m // return value
9A04
//0078 mm ADD_TEMP_0,w
000F
//0079 mwm INDV
1203
//007A mm INDA,w
0204
//007B mwm STACKPTR // update STACKPTR
11FF
//007C mlw .3
2003
//007D add INDA,m // return adress
8A04
//007E mm INDV,w
0203
//007F gow // return
D000