comparison code/ghc.lm @ 42:f1453e8970ca

Added simulator for ghc microcontroller
author Michael Pavone <pavone@retrodev.com>
date Sat, 26 Jul 2014 19:43:27 -0700
parents
children
comparison
equal deleted inserted replaced
41:e1047192610c 42:f1453e8970ca
1 #{
2 import: [
3 length
4 reverse
5 split:at
6 map
7 fold:with
8 filter
9 flatten
10 ] from: (module: "ll.lm")
11
12 import: [
13 makeTree:size
14 makeTree
15 filledTree
16 _filledTree
17 get:fromTree:size
18 get:fromTree
19 treeMap:size
20 treeMap
21 tree:size:update:with
22 tree:update:with
23 tree:set:to
24 ] from: (module: "tree.lm")
25
26 add8 <- :a b {
27 a <- a + b
28 if: a >= 256 {
29 a <- a - 256
30 } else: {}
31 a
32 }
33
34 sub8 <- :a b {
35 a <- a - b
36 if: a < 0 {
37 a <- a + 256
38 } else: {}
39 a
40 }
41
42 mul8 <- :a b {
43 a <- a * b
44 while: { a > 256 } do: {
45 a <- a - 256
46 }
47 a
48 }
49
50 and8 <- :a b {
51 bit <- 128
52 out <- 0
53 while: { bit > 0 } do: {
54 if: a >= bit {
55 a <- a - bit
56 if: b >= bit {
57 b <- b - bit
58 out <- out + bit
59 } else: {}
60 } else: {
61 if: b >= bit {
62 b <- b - bit
63 } else: {}
64 }
65 bit <- bit / 2
66 }
67 out
68 }
69
70 or8 <- :a b {
71 bit <- 128
72 out <- 0
73 while: { bit > 0 } do: {
74 if: a >= bit {
75 a <- a - bit
76 out <- out + bit
77 if: b >= bit {
78 b <- b - bit
79 } else: {}
80 } else: {
81 if: b >= bit {
82 b <- b - bit
83 out <- out + bit
84 } else: {}
85 }
86 bit <- bit / 2
87 }
88 out
89 }
90
91 xor8 <- :a b {
92 bit <- 128
93 out <- 0
94 while: { bit > 0 } do: {
95 if: a >= bit {
96 a <- a - bit
97 if: b >= bit {
98 b <- b - bit
99 } else: {
100 out <- out + bit
101 }
102 } else: {
103 if: b >= bit {
104 b <- b - bit
105 out <- out + bit
106 } else: {}
107 }
108 bit <- bit / 2
109 }
110 out
111 }
112
113 makeCPU <- :code intHandler {
114 a <- 0
115 b <- 0
116 c <- 0
117 d <- 0
118 e <- 0
119 f <- 0
120 g <- 0
121 h <- 0
122
123 dataMem <- filledTree: 0 256
124
125 getRegVal <- :regnum pc {
126 if: regnum >= 4 {
127 if: regnum >= 6 {
128 if: regnum = 6 {
129 regnum <- g
130 } else: {
131 if: regnum = 7 {
132 regnum <- h
133 } else: {
134 regnum <- pc
135 }
136 }
137 } else: {
138 if: regnum = 4 {
139 regnum <- e
140 } else: {
141 regnum <- f
142 }
143 }
144 } else: {
145 if: regnum >= 2 {
146 if: regnum = 2 {
147 regnum <- c
148 } else: {
149 regnum <- d
150 }
151 } else: {
152 if: regnum {
153 regnum <- b
154 } else: {
155 regnum <- a
156 }
157 }
158 }
159 regnum
160 }
161
162 getArg <- :arg pc {
163 type <- arg value
164 param <- arg tail
165 if: type >= 2 {
166 if: type = 3 {
167 param <- get: param fromTree: dataMem
168 } else: {}
169 } else: {
170 param <- getRegVal: param pc
171 if: type {
172 param <- get: param fromTree: dataMem
173 } else: {}
174 }
175 param
176 }
177
178 setReg <- :regnum pc val {
179 if: regnum >= 4 {
180 if: regnum >= 6 {
181 if: regnum = 6 {
182 g <- val
183 } else: {
184 if: regnum = 7 {
185 h <- val
186 } else: {
187 pc <- val
188 }
189 }
190 } else: {
191 if: regnum = 4 {
192 e <- val
193 } else: {
194 f <- val
195 }
196 }
197 } else: {
198 if: regnum >= 2 {
199 if: regnum = 2 {
200 c <- val
201 } else: {
202 d <- val
203 }
204 } else: {
205 if: regnum {
206 b <- val
207 } else: {
208 a <- val
209 }
210 }
211 }
212 pc
213 }
214
215 saveDest <- :arg pc val {
216 type <- arg value
217 param <- arg tail
218 if: type >= 2 {
219 if: type = 3 {
220 dataMem <- tree: dataMem set: param to: val
221 } else: {}
222 } else: {
223 if: type {
224 param <- getRegVal: param pc
225 dataMem <- tree: dataMem set: param to: val
226 } else: {
227 pc <- setReg: param pc val
228 }
229 }
230 pc
231 }
232
233 mov <- :args {
234 dst <- args value
235 src <- (args tail) value
236 :pc {
237 #[1 (saveDest: dst pc (getArg: src pc))]
238 }
239 }
240
241 inc <- :args {
242 dst <- args value
243 :pc {
244 #[1 (saveDest: dst pc (add8: (getArg: dst pc) 1))]
245 }
246 }
247
248 dec <- :args {
249 dst <- args value
250 :pc {
251 #[1 (saveDest: dst pc (sub8: (getArg: dst pc) 1))]
252 }
253 }
254
255 add <- :args {
256 dst <- args value
257 src <- (args tail) value
258 :pc {
259 #[1 (saveDest: dst pc (add8: (getArg: dst pc) (getArg: src pc)))]
260 }
261 }
262
263 sub <- :args {
264 dst <- args value
265 src <- (args tail) value
266 :pc {
267 #[1 (saveDest: dst pc (sub8: (getArg: dst pc) (getArg: src pc)))]
268 }
269 }
270
271 mul <- :args {
272 dst <- args value
273 src <- (args tail) value
274 :pc {
275 #[1 (saveDest: dst pc (mul8: (getArg: dst pc) (getArg: src pc)))]
276 }
277 }
278
279 div <- :args {
280 dst <- args value
281 src <- (args tail) value
282 :pc {
283 srcv <- getArg: src pc
284 if: srcv = 0 {
285 pc <- #[0 pc]
286 } else: {
287 pc <- #[1 (saveDest: dst pc (getArg: dst pc) / srcv)]
288 }
289 pc
290 }
291 }
292
293 and <- :args {
294 dst <- args value
295 src <- (args tail) value
296 :pc {
297 #[1 (saveDest: dst pc (and8: (getArg: dst pc) (getArg: src pc)))]
298 }
299 }
300
301 or <- :args {
302 dst <- args value
303 src <- (args tail) value
304 :pc {
305 #[1 (saveDest: dst pc (or8: (getArg: dst pc) (getArg: src pc)))]
306 }
307 }
308
309 xor <- :args {
310 dst <- args value
311 src <- (args tail) value
312 :pc {
313 #[1 (saveDest: dst pc (xor8: (getArg: dst pc) (getArg: src pc)))]
314 }
315 }
316
317 jlt <- :args {
318 target <- args value
319 x <- (args tail) value
320 y <- ((args tail) tail) value
321 :pc {
322 if: x >= y {
323 } else: {
324 pc <- target
325 }
326 pc
327 }
328 }
329
330 jeq <- :args {
331 target <- args value
332 x <- (args tail) value
333 y <- ((args tail) tail) value
334 :pc {
335 if: x = y {
336 pc <- target
337 } else: {
338 }
339 pc
340 }
341 }
342
343 jgt <- :args {
344 target <- args value
345 x <- (args tail) value
346 y <- ((args tail) tail) value
347 :pc {
348 if: x > y {
349 pc <- target
350 } else: {
351 }
352 pc
353 }
354 }
355
356 int <- :args {
357 num <- args value
358 :pc {
359 iargs <- a
360 if: num = 8 {
361 iargs <- #[a b c d e f g h]
362 } else: {
363 if: num = 7 {
364 iargs <- #[a b]
365 } else: {}
366 }
367 intHandler: num iargs setReg pc
368 }
369 }
370
371
372 hlt <- :pc {
373 #[0 pc]
374 }
375
376 codeMem <- (fold: code #[(filledTree: hlt 256) 0] with: :acc inst {
377 cmem <- acc value
378 pc <- acc tail
379
380 inum <- inst value
381 args <- inst tail
382
383 if: inum >= 7 {
384 if: inum >= 11 {
385 if: inum >= 13 {
386 if: inum = 14 {
387 inst <- hlt
388 } else: {
389 inst <- int: args
390 }
391 } else: {
392 if: inum = 12 {
393 inst <- jgt: args
394 } else: {
395 inst <- jeq: args
396 }
397 }
398 } else: {
399 if: inum >= 9 {
400 if: inum = 10 {
401 inst <- jlt: args
402 } else: {
403 inst <- xor: args
404 }
405 } else: {
406 if: inum = 8 {
407 inst <- or: args
408 } else: {
409 inst <- and: args
410 }
411 }
412 }
413 } else: {
414 if: inum >= 3 {
415 if: inum >= 5 {
416 if: inum = 5 {
417 inst <- mul: args
418 } else: {
419 inst <- div: args
420 }
421 } else: {
422 if: inum = 3 {
423 inst <- add: args
424 } else: {
425 inst <- sub: args
426 }
427 }
428 } else: {
429 if: inum = 2 {
430 inst <- dec: args
431 } else: {
432 if: inum {
433 inst <- inc: args
434 } else: {
435 inst <- mov: args
436 }
437 }
438 }
439 }
440 #[(tree: cmem set: pc to: inst) pc + 1]
441 }) value
442
443 {
444 cycle <- 0
445 pc <- 0
446 ret <- 0
447 run <- 1
448
449 while: { run } do: {
450 ret <- get: pc fromTree: codeMem
451 ret <- ret: pc
452 run <- ret value
453
454 if: (ret tail) = pc {
455 pc <- pc + 1
456 } else: {
457 pc <- ret tail
458 }
459 cycle <- cycle + 1
460 if: cycle >= 1024 {
461 run <- 0
462 } else: {}
463 }
464 cycle
465 }
466 }
467
468 main <- {
469 cpu <- makeCPU: [
470 #[0 [#[0 0] #[2 31]]] //0 a <- 31
471 #[0 [#[0 1] #[2 45]]] //1 b <- 45
472 #[0 [#[0 2] #[2 57]]] //2 c <- 57
473 #[0 [#[0 3] #[2 127]]] //3 d <- 127
474 #[0 [#[0 4] #[2 128]]] //4 e <- 128
475 #[0 [#[0 5] #[2 254]]] //5 f <- 254
476 #[0 [#[0 6] #[2 255]]] //6 g <- 255
477 #[0 [#[0 7] #[2 3]]] //7 h <- 3
478 #[0 [#[3 0] #[2 45]]] //8 [0] <- 45
479 #[1 [#[0 0]]] //9 a <- a + 1 : 32
480 #[2 [#[0 1]]] //10 b <- b - 1 : 44
481 #[3 [#[0 2] #[0 3]]] //11 c <- c + d : 184
482 #[4 [#[0 4] #[0 5]]] //12 e <- e - f : 130
483 #[5 [#[0 6] #[0 7]]] //13 g <- g * h : 253
484 #[6 [#[3 0] #[0 0]]] //14 [0] <- [0] * a : 160
485 #[13 [8]] //15
486 #[14 []] //16
487 ] :num iargs setReg pc {
488 print: #[num pc iargs]
489 #[1 pc]
490 }
491 print: (add8: 2 3)
492 print: (add8: 255 1)
493 print: (add8: 129 128)
494 print: (sub8: 4 2)
495 print: (sub8: 2 4)
496 print: (sub8: 0 255)
497 print: (mul8: 255 255)
498 print: (mul8: 255 2)
499 print: (mul8: 3 5)
500 print: (and8: 127 254)
501 print: (and8: 3 5)
502 print: (or8: 127 254)
503 print: (or8: 3 5)
504 print: (xor8: 127 254)
505 print: (xor8: 3 5)
506 print: (cpu: )
507 }
508 }