1 /* file: "picobit-vm.c" */
4 * Copyright 2004 by Marc Feeley, All Rights Reserved.
8 * 15/08/2004 Release of version 1
9 * 06/07/2008 Modified for PICOBOARD2_R3
15 /*---------------------------------------------------------------------------*/
20 typedef unsigned char uint8
;
21 typedef unsigned short uint16
;
22 typedef unsigned long uint32
;
24 /*---------------------------------------------------------------------------*/
44 static volatile near uint8 FW_VALUE_UP @
0x33;
45 static volatile near uint8 FW_VALUE_HI @
0x33;
46 static volatile near uint8 FW_VALUE_LO @
0x33;
48 #define ACTIVITY_LED1_LAT LATB
49 #define ACTIVITY_LED1_BIT 5
50 #define ACTIVITY_LED2_LAT LATB
51 #define ACTIVITY_LED2_BIT 4
52 static volatile near bit ACTIVITY_LED1 @
((unsigned)&ACTIVITY_LED1_LAT
*8)+ACTIVITY_LED1_BIT
;
53 static volatile near bit ACTIVITY_LED2 @
((unsigned)&ACTIVITY_LED2_LAT
*8)+ACTIVITY_LED2_BIT
;
64 #include <sys/types.h>
65 #include <sys/timeb.h>
74 /*---------------------------------------------------------------------------*/
78 #define CODE_START 0x5000
84 #define IF_GC_TRACE(x) x
87 #define IF_GC_TRACE(x)
90 /*---------------------------------------------------------------------------*/
95 #define ERROR(msg) halt_with_error()
96 #define TYPE_ERROR(type) halt_with_error()
103 #define ERROR(msg) error (msg)
104 #define TYPE_ERROR(type) type_error (type)
106 void error (char *msg
)
108 printf ("ERROR: %s\n", msg
);
112 void type_error (char *type
)
114 printf ("ERROR: An argument of type %s was expected\n", type
);
121 /*---------------------------------------------------------------------------*/
129 typedef uint16 ram_addr
;
130 typedef uint16 rom_addr
;
134 /*---------------------------------------------------------------------------*/
136 #define MAX_RAM_ENCODING 8192
137 #define MIN_RAM_ENCODING 512
138 #define RAM_BYTES ((MAX_RAM_ENCODING - MIN_RAM_ENCODING + 1)*4)
139 // TODO watch out if we address more than what the PIC actually has
141 // TODO change if we change the proportion of rom and ram addresses
143 #define OBJ_TO_RAM_ADDR(o,f) (((ram_addr)((uint16)(o) - MIN_RAM_ENCODING) << 2) + (f))
144 #define OBJ_TO_ROM_ADDR(o,f) (((rom_addr)((uint16)(o) - MIN_ROM_ENCODING) << 2) + (CODE_START + 4 + (f)))
146 // TODO ROM had uint8 cast, but seemed to cause problems
152 #pragma udata picobit_heap=0x200
153 uint8 ram_mem
[RAM_BYTES
];
157 #define ram_get(a) *(uint8*)(a+0x200)
158 #define ram_set(a,x) *(uint8*)(a+0x200) = (x)
159 // TODO change these since we change proportion of ram and rom ?
165 uint8 ram_mem
[RAM_BYTES
];
167 #define ram_get(a) ram_mem[a]
168 #define ram_set(a,x) ram_mem[a] = (x)
173 /*---------------------------------------------------------------------------*/
180 uint8
rom_get (rom_addr a
)
182 return *(rom uint8
*)a
;
190 #define ROM_BYTES 8192
192 uint8 rom_mem
[ROM_BYTES
] =
195 #define PUTCHAR_LIGHT_not
198 0xFB, 0xD7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x32
199 , 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00
200 , 0x08, 0x50, 0x80, 0x16, 0xFE, 0xE8, 0x00, 0xFC
201 , 0x32, 0x80, 0x2D, 0xFE, 0xFC, 0x31, 0x80, 0x43
202 , 0xFE, 0xFC, 0x33, 0x80, 0x2D, 0xFE, 0xFC, 0x31
203 , 0x80, 0x43, 0xFE, 0x90, 0x16, 0x01, 0x20, 0xFC
204 , 0x32, 0xE3, 0xB0, 0x37, 0x09, 0xF3, 0xFF, 0x20
205 , 0xFC, 0x33, 0xE3, 0xB0, 0x40, 0x0A, 0xF3, 0xFF
206 , 0x08, 0xF3, 0xFF, 0x01, 0x40, 0x21, 0xD1, 0x00
207 , 0x02, 0xC0, 0x4C, 0x71, 0x01, 0x20, 0x50, 0x90
208 , 0x51, 0x00, 0xF1, 0x40, 0xD8, 0xB0, 0x59, 0x90
212 0xFB, 0xD7, 0x00, 0x00, 0x80, 0x08, 0xFE, 0xE8
213 , 0x00, 0xF6, 0xF5, 0x90, 0x08
217 uint8
rom_get (rom_addr a
)
219 return rom_mem
[a
-CODE_START
];
224 obj globals
[GLOVARS
];
226 /*---------------------------------------------------------------------------*/
234 fixnum n MIN_FIXNUM -> 3 ... MAX_FIXNUM -> 3 + (MAX_FIXNUM-MIN_FIXNUM)
235 TODO do we want 0..127 as fixnums ? would reduce number of ra/om objects
236 rom object 4 + (MAX_FIXNUM-MIN_FIXNUM) ... MIN_RAM_ENCODING-1
237 ram object MIN_RAM_ENCODING ... 4095 TODO was 255, now we have 12 bits
239 layout of memory allocated objects:
241 G's represent mark bits used by the gc TODO change GC, and does not use the same bits
243 bignum n 00G00000 uuuuuuuu hhhhhhhh llllllll (24 bit signed integer)
244 TODO we could have 29-bit integers
246 pair 1GGaaaaa aaaaaaaa 000ddddd dddddddd
249 gives an address space of 2^13 * 4 = 32k (not all of it is for RAM, though)
251 symbol 1GG00000 00000000 00100000 00000000
253 string 1GG***** *chars** 01000000 00000000
255 vector 1GG***** *elems** 01100000 00000000 TODO not used yet
257 closure 01Gxxxxx xxxxxxxx aaaaaaaa aaaaaaaa TODO OLD
258 closure 01Gaaaaa aaaaaaaa aaaxxxxx xxxxxxxx
259 0x5ff<a<0x4000 is entry
260 x is pointer to environment
261 the reason why the environment is on the cdr (and the entry is split on 3
262 bytes) is that, when looking for a variable, a closure is considered to be a
263 pair. The compiler adds an extra offset to any variable in the closure's
264 environment, so the car of the closure (which doesn't really exist) is never
265 checked, but the cdr is followed to find the other bindings
267 continuation 1GGxxxxx xxxxxxxx 100yyyyy yyyyyyyy
268 x is parent continuation
269 y is pointer to the second half, which is a closure (contains env and entry)
271 An environment is a list of objects built out of pairs. On entry to
272 a procedure the environment is the list of parameters to which is
273 added the environment of the closure being called.
275 The first byte at the entry point of a procedure gives the arity of
278 n = 0 to 127 -> procedure has n parameters (no rest parameter)
279 n = -128 to -1 -> procedure has -n parameters, the last is
287 #define MIN_FIXNUM_ENCODING 3
289 #define MAX_FIXNUM 255
290 #define MIN_ROM_ENCODING (MIN_FIXNUM_ENCODING+MAX_FIXNUM-MIN_FIXNUM+1)
292 #define ENCODE_FIXNUM(n) ((obj)(n) + (MIN_FIXNUM_ENCODING - MIN_FIXNUM))
293 #define DECODE_FIXNUM(o) ((int32)(o) - (MIN_FIXNUM_ENCODING - MIN_FIXNUM))
296 #define IN_RAM(o) ((o) >= MIN_RAM_ENCODING)
297 #define IN_ROM(o) (!IN_RAM(o) && ((o) >= MIN_ROM_ENCODING))
299 // TODO rom now checks both bounds, solved 1-2 bugs, but now needs 2 checks
301 // bignum first byte : 00G00000
302 #define BIGNUM_FIELD0 0
303 #define RAM_BIGNUM(o) ((ram_get_field0 (o) & 0xc0) == BIGNUM_FIELD0)
304 #define ROM_BIGNUM(o) ((rom_get_field0 (o) & 0xc0) == BIGNUM_FIELD0)
306 // composite first byte : 1GGxxxxx
307 #define COMPOSITE_FIELD0 0x80
308 #define RAM_COMPOSITE(o) ((ram_get_field0 (o) & 0x80) == COMPOSITE_FIELD0)
309 #define ROM_COMPOSITE(o) ((rom_get_field0 (o) & 0x80) == COMPOSITE_FIELD0)
311 // pair third byte : 000xxxxx
312 #define PAIR_FIELD2 0
313 #define RAM_PAIR(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == PAIR_FIELD2))
314 #define ROM_PAIR(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == PAIR_FIELD2))
316 // symbol third byte : 001xxxxx
317 #define SYMBOL_FIELD2 0x20
318 #define RAM_SYMBOL(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == SYMBOL_FIELD2))
319 #define ROM_SYMBOL(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == SYMBOL_FIELD2))
321 // string third byte : 010xxxxx
322 #define STRING_FIELD2 0x40
323 #define RAM_STRING(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == STRING_FIELD2))
324 #define ROM_STRING(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == STRING_FIELD2))
326 // vector third byte : 011xxxxx
327 #define VECTOR_FIELD2 0x60
328 #define RAM_VECTOR(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == VECTOR_FIELD2))
329 #define ROM_VECTOR(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == VECTOR_FIELD2))
331 // continuation third byte : 100xxxxx
332 #define CONTINUATION_FIELD2 0x80
333 #define RAM_CONTINUATION(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2))
334 #define ROM_CONTINUATION(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2))
336 // closure first byte : 01Gxxxxx
337 #define CLOSURE_FIELD0 0x40
338 #define RAM_CLOSURE(o) ((ram_get_field0 (o) & 0xc0) == CLOSURE_FIELD0)
339 #define ROM_CLOSURE(o) ((rom_get_field0 (o) & 0xc0) == CLOSURE_FIELD0)
342 /*---------------------------------------------------------------------------*/
344 #define RAM_GET_FIELD0_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,0))
345 #define RAM_SET_FIELD0_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,0), val)
346 #define ROM_GET_FIELD0_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,0))
348 #define RAM_GET_GC_TAGS_MACRO(o) (RAM_GET_FIELD0_MACRO(o) & 0x60)
349 #define RAM_GET_GC_TAG0_MACRO(o) (RAM_GET_FIELD0_MACRO(o) & 0x20)
350 #define RAM_GET_GC_TAG1_MACRO(o) (RAM_GET_FIELD0_MACRO(o) & 0x40)
351 #define RAM_SET_GC_TAGS_MACRO(o,tags) \
352 (RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0x9f) | (tags)))
353 #define RAM_SET_GC_TAG0_MACRO(o,tag) \
354 RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0xdf) | (tag))
355 #define RAM_SET_GC_TAG1_MACRO(o,tag) \
356 RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0xbf) | (tag))
359 #define RAM_GET_FIELD1_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,1))
360 #define RAM_GET_FIELD2_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,2))
361 #define RAM_GET_FIELD3_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,3))
362 #define RAM_SET_FIELD1_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,1), val)
363 #define RAM_SET_FIELD2_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,2), val)
364 #define RAM_SET_FIELD3_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,3), val)
365 #define ROM_GET_FIELD1_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,1))
366 #define ROM_GET_FIELD2_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,2))
367 #define ROM_GET_FIELD3_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,3))
371 #define RAM_GET_FIELD1_MACRO(o) \
372 (ram_get (OBJ_TO_RAM_ADDR(o,1)) + ((RAM_GET_FIELD0_MACRO(o) & 0x03)<<8))
373 #define RAM_GET_FIELD2_MACRO(o) \
374 (ram_get (OBJ_TO_RAM_ADDR(o,2)) + ((RAM_GET_FIELD0_MACRO(o) & 0x0c)<<6))
375 #define RAM_GET_FIELD3_MACRO(o) \
376 (ram_get (OBJ_TO_RAM_ADDR(o,3)) + ((RAM_GET_FIELD0_MACRO(o) & 0x30)<<4))
377 #define RAM_SET_FIELD1_MACRO(o,val) \
379 ram_set (OBJ_TO_RAM_ADDR(o,1), (val) & 0xff); \
380 RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0xfc) + (((val) >> 8) & 0x03)); \
382 #define RAM_SET_FIELD2_MACRO(o,val) \
384 ram_set (OBJ_TO_RAM_ADDR(o,2), (val) & 0xff); \
385 RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0xf3) + (((val) >> 6) & 0x0c)); \
387 #define RAM_SET_FIELD3_MACRO(o,val) \
389 ram_set (OBJ_TO_RAM_ADDR(o,3), (val) & 0xff); \
390 RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0xcf) + (((val) >> 4) & 0x30)); \
392 #define ROM_GET_FIELD1_MACRO(o) \
393 (rom_get (OBJ_TO_ROM_ADDR(o,1)) + ((ROM_GET_FIELD0_MACRO(o) & 0x03)<<8))
394 #define ROM_GET_FIELD2_MACRO(o) \
395 (rom_get (OBJ_TO_ROM_ADDR(o,2)) + ((ROM_GET_FIELD0_MACRO(o) & 0x0c)<<6))
396 #define ROM_GET_FIELD3_MACRO(o) \
397 (rom_get (OBJ_TO_ROM_ADDR(o,3)) + ((ROM_GET_FIELD0_MACRO(o) & 0x30)<<4))
400 uint8
ram_get_gc_tags (obj o
) { return RAM_GET_GC_TAGS_MACRO(o
); }
401 uint8
ram_get_gc_tag0 (obj o
) { return RAM_GET_GC_TAG0_MACRO(o
); }
402 uint8
ram_get_gc_tag1 (obj o
) { return RAM_GET_GC_TAG1_MACRO(o
); }
403 void ram_set_gc_tags (obj o
, uint8 tags
) { RAM_SET_GC_TAGS_MACRO(o
, tags
); }
404 void ram_set_gc_tag0 (obj o
, uint8 tag
) { RAM_SET_GC_TAG0_MACRO(o
,tag
); }
405 void ram_set_gc_tag1 (obj o
, uint8 tag
) { RAM_SET_GC_TAG1_MACRO(o
,tag
); }
406 uint8
ram_get_field0 (obj o
) { return RAM_GET_FIELD0_MACRO(o
); }
407 word
ram_get_field1 (obj o
) { return RAM_GET_FIELD1_MACRO(o
); }
408 word
ram_get_field2 (obj o
) { return RAM_GET_FIELD2_MACRO(o
); }
409 word
ram_get_field3 (obj o
) { return RAM_GET_FIELD3_MACRO(o
); }
410 void ram_set_field0 (obj o
, uint8 val
) { RAM_SET_FIELD0_MACRO(o
,val
); }
411 void ram_set_field1 (obj o
, word val
) { RAM_SET_FIELD1_MACRO(o
,val
); }
412 void ram_set_field2 (obj o
, word val
) { RAM_SET_FIELD2_MACRO(o
,val
); }
413 void ram_set_field3 (obj o
, word val
) { RAM_SET_FIELD3_MACRO(o
,val
); }
414 uint8
rom_get_field0 (obj o
) { return ROM_GET_FIELD0_MACRO(o
); }
415 word
rom_get_field1 (obj o
) { return ROM_GET_FIELD1_MACRO(o
); }
416 word
rom_get_field2 (obj o
) { return ROM_GET_FIELD2_MACRO(o
); }
417 word
rom_get_field3 (obj o
) { return ROM_GET_FIELD3_MACRO(o
); }
419 obj
ram_get_car (obj o
)
420 { return ((ram_get_field0 (o
) & 0x1f) << 8) | ram_get_field1 (o
); }
421 obj
rom_get_car (obj o
)
422 { return ((rom_get_field0 (o
) & 0x1f) << 8) | rom_get_field1 (o
); }
423 obj
ram_get_cdr (obj o
)
424 { return ((ram_get_field2 (o
) & 0x1f) << 8) | ram_get_field3 (o
); }
425 obj
rom_get_cdr (obj o
)
426 { return ((rom_get_field2 (o
) & 0x1f) << 8) | rom_get_field3 (o
); }
427 void ram_set_car (obj o
, obj val
) // TODO WRONG !
429 ram_set_field0 (o
, (val
>> 8) | (ram_get_field0 (o
) & 0xe0));
430 ram_set_field1 (o
, val
& 0xff);
432 void ram_set_cdr (obj o
, obj val
) // TODO looks wrong too
434 ram_set_field2 (o
, (val
>> 8) | (ram_get_field2 (o
) & 0xe0));
435 ram_set_field3 (o
, val
& 0xff);
437 obj
ram_get_entry (obj o
)
439 return (((ram_get_field0 (o
) & 0x1f) << 11)
440 | (ram_get_field1 (o
) << 3)
441 | (ram_get_field2 (o
) >> 5));
443 obj
rom_get_entry (obj o
)
445 return (((rom_get_field0 (o
) & 0x1f) << 11)
446 | (rom_get_field1 (o
) << 3)
447 | (rom_get_field2 (o
) >> 5));
450 obj
get_global (uint8 i
)
455 void set_global (uint8 i
, obj o
)
461 void show_type (obj o
) // for debugging purposes
464 if (o
== OBJ_FALSE
) printf("#f");
465 else if (o
== OBJ_TRUE
) printf("#t");
466 else if (o
== OBJ_NULL
) printf("()");
467 else if (o
< MIN_ROM_ENCODING
) printf("fixnum");
470 if (RAM_BIGNUM(o
)) printf("ram bignum");
471 else if (RAM_PAIR(o
)) printf("ram pair");
472 else if (RAM_SYMBOL(o
)) printf("ram symbol");
473 else if (RAM_STRING(o
)) printf("ram string");
474 else if (RAM_VECTOR(o
)) printf("ram vector");
475 else if (RAM_CONTINUATION(o
)) printf("ram continuation");
476 else if (RAM_CLOSURE(o
)) printf("ram closure");
480 if (ROM_BIGNUM(o
)) printf("rom bignum");
481 else if (ROM_PAIR(o
)) printf("rom pair");
482 else if (ROM_SYMBOL(o
)) printf("rom symbol");
483 else if (ROM_STRING(o
)) printf("rom string");
484 else if (ROM_VECTOR(o
)) printf("rom vector");
485 else if (ROM_CONTINUATION(o
)) printf("rom continuation");
486 else if (RAM_CLOSURE(o
)) printf("rom closure");
493 /*---------------------------------------------------------------------------*/
495 /* Interface to GC */
497 /* GC tags are in the top 2 bits of field 0 */
498 #define GC_TAG_0_LEFT (1<<5)
499 // TODO was 3<<5, changed to play nice with procedures and bignums, but should actually set only this bit, not clear the other
500 #define GC_TAG_1_LEFT (2<<5)
501 #define GC_TAG_UNMARKED (0<<5)
503 /* Number of object fields of objects in ram */
504 #define HAS_2_OBJECT_FIELDS(visit) (RAM_PAIR(visit) || RAM_CONTINUATION(visit))
505 #define HAS_1_OBJECT_FIELD(visit) (RAM_COMPOSITE(visit) || RAM_CLOSURE(visit))
506 // all composites except pairs and continuations have 1 object field
507 // TODO if we ever have true bignums, bignums will have 1 object field
509 #define NIL OBJ_FALSE
511 /*---------------------------------------------------------------------------*/
513 /* Garbage collector */
515 obj free_list
; /* list of unused cells */
517 obj arg1
; /* root set */
524 uint8 na
; /* interpreter variables */
534 void init_ram_heap (void)
537 obj o
= MAX_RAM_ENCODING
;
541 while (o
>= MIN_RAM_ENCODING
)
543 ram_set_gc_tags (o
, GC_TAG_UNMARKED
);
544 ram_set_car (o
, free_list
);
549 for (i
=0; i
<GLOVARS
; i
++)
550 set_global (i
, OBJ_FALSE
);
577 // IF_GC_TRACE(printf ("push stack=%d (tag=%d) visit=%d (tag=%d)\n", stack, ram_get_gc_tags (stack)>>5, visit, ram_get_gc_tags (visit)>>5)); // TODO error here, tried to get the tag of nil
578 IF_GC_TRACE(printf ("push stack=%d visit=%d (tag=%d)\n", stack
, visit
, ram_get_gc_tags (visit
)>>5));
580 if ((HAS_1_OBJECT_FIELD (visit
) && ram_get_gc_tag0 (visit
))
581 || (HAS_2_OBJECT_FIELDS (visit
)
582 && (ram_get_gc_tags (visit
) != GC_TAG_UNMARKED
)))
583 // TODO ugly condition
584 IF_GC_TRACE(printf ("case 1\n"));
587 if (HAS_2_OBJECT_FIELDS(visit
)) // pairs and continuations
589 IF_GC_TRACE(printf ("case 5\n"));
593 temp
= ram_get_cdr (visit
);
597 IF_GC_TRACE(printf ("case 6\n"));
598 ram_set_gc_tags (visit
, GC_TAG_1_LEFT
);
599 ram_set_cdr (visit
, stack
);
603 IF_GC_TRACE(printf ("case 7\n"));
608 if (HAS_1_OBJECT_FIELD(visit
))
610 IF_GC_TRACE(printf ("case 8\n"));
614 if (RAM_CLOSURE(visit
)) // closures have the pointer in the cdr
615 temp
= ram_get_cdr (visit
);
617 temp
= ram_get_car (visit
);
621 IF_GC_TRACE(printf ("case 9\n"));
622 ram_set_gc_tag0 (visit
, GC_TAG_0_LEFT
); // TODO changed, now we only set bit 0, we don't change bit 1, since some objets have only 1 mark bit
623 if (RAM_CLOSURE(visit
)) // closures still have the pointer in the cdr TODO inverted
624 ram_set_cdr (visit
, stack
); // TODO BREGG is it ok ? closures seem to get messed up
626 ram_set_car (visit
, stack
);
628 goto push
; // TODO the loop goes through here, is the stack correctly set ?
631 IF_GC_TRACE(printf ("case 10\n"));
634 IF_GC_TRACE(printf ("case 11\n"));
636 ram_set_gc_tag0 (visit
, GC_TAG_0_LEFT
); // TODO changed, same as above
641 /* IF_GC_TRACE(printf ("pop stack=%d (tag=%d) visit=%d (tag=%d)\n", stack, ram_get_gc_tags (stack)>>6, visit, ram_get_gc_tags (visit)>>6)); */
642 // TODO, like for push, getting the gc tags of nil is not great
643 IF_GC_TRACE(printf ("pop stack=%d visit=%d (tag=%d)\n", stack
, visit
, ram_get_gc_tags (visit
)>>6));
647 /* if ((ram_get_gc_tags (stack) == GC_TAG_1_LEFT)) */
648 /* // this condition will always be true for unmarked closures, but */
649 /* // such an object will never be on the stack (procedures will */
650 /* // always be marked at this point), so no false positives */
651 if (HAS_2_OBJECT_FIELDS(stack
) && ram_get_gc_tag1 (stack
))
652 // TODO more specific, might help, but if the bit stays set we'll loop
654 IF_GC_TRACE(printf ("case 13\n"));
656 temp
= ram_get_cdr (stack
); /* pop through cdr */
657 ram_set_cdr (stack
, visit
);
661 ram_set_gc_tag1(visit
, GC_TAG_UNMARKED
);
662 // we unset the "1-left" bit
667 if (RAM_CLOSURE(stack
)) // TODO doesn't seem to solve the problem
668 // closures have one object field, but it's in the cdr
669 // TODO will the stack ever be a closure ? probably
671 IF_GC_TRACE(printf ("case 13.5\n")); // TODO renumber cases
673 temp
= ram_get_cdr (stack
); /* pop through cdr */
674 ram_set_cdr (stack
, visit
);
675 visit
= stack
; // TODO BREGG do we set it back as we should ?
681 IF_GC_TRACE(printf ("case 14\n"));
683 temp
= ram_get_car (stack
); /* pop through car */
684 ram_set_car (stack
, visit
);
705 obj visit
= MAX_RAM_ENCODING
;
709 while (visit
>= MIN_RAM_ENCODING
)
711 if ((RAM_COMPOSITE(visit
)
712 && (ram_get_gc_tags (visit
) == GC_TAG_UNMARKED
)) // 2 mark bit
713 || !(ram_get_gc_tags (visit
) & GC_TAG_0_LEFT
)) // 1 mark bit
716 ram_set_car (visit
, free_list
);
719 else // TODO do closures get swept even if they are live ?
721 if (RAM_COMPOSITE(visit
))
722 ram_set_gc_tags (visit
, GC_TAG_UNMARKED
);
723 else // only 1 mark bit to unset
724 ram_set_gc_tag0 (visit
, GC_TAG_UNMARKED
);
736 printf ("**************** memory needed = %d\n", max_live
+1);
746 IF_GC_TRACE(printf("\nGC BEGINS\n"));
748 IF_GC_TRACE(printf("arg1\n"));
750 IF_GC_TRACE(printf("arg2\n"));
752 IF_GC_TRACE(printf("arg3\n"));
754 IF_GC_TRACE(printf("arg4\n"));
756 IF_GC_TRACE(printf("cont\n"));
758 IF_GC_TRACE(printf("env\n"));
761 for (i
=0; i
<GLOVARS
; i
++)
762 mark (get_global (i
));
767 obj
alloc_ram_cell (void)
781 ERROR("memory is full");
786 free_list
= ram_get_car (o
);
791 obj
alloc_ram_cell_init (uint8 f0
, uint8 f1
, uint8 f2
, uint8 f3
)
793 obj o
= alloc_ram_cell ();
795 ram_set_field0 (o
, f0
);
796 ram_set_field1 (o
, f1
);
797 ram_set_field2 (o
, f2
);
798 ram_set_field3 (o
, f3
);
803 /*---------------------------------------------------------------------------*/
805 int32
decode_int (obj o
)
811 if (o
< MIN_FIXNUM_ENCODING
)
812 TYPE_ERROR("integer");
814 if (o
<= (MIN_FIXNUM_ENCODING
+ (MAX_FIXNUM
- MIN_FIXNUM
)))
815 return DECODE_FIXNUM(o
);
820 TYPE_ERROR("integer");
822 u
= ram_get_field1 (o
);
823 h
= ram_get_field2 (o
);
824 l
= ram_get_field3 (o
);
829 TYPE_ERROR("integer");
831 u
= rom_get_field1 (o
);
832 h
= rom_get_field2 (o
);
833 l
= rom_get_field3 (o
);
836 TYPE_ERROR("integer");
839 return ((int32
)((((int16
)u
- 256) << 8) + h
) << 8) + l
;
841 return ((int32
)(((int16
)u
<< 8) + h
) << 8) + l
;
844 obj
encode_int (int32 n
)
846 if (n
>= MIN_FIXNUM
&& n
<= MAX_FIXNUM
)
847 return ENCODE_FIXNUM(n
);
849 return alloc_ram_cell_init (BIGNUM_FIELD0
, n
>> 16, n
>> 8, n
);
852 /*---------------------------------------------------------------------------*/
864 else if (o
== OBJ_TRUE
)
866 else if (o
== OBJ_NULL
)
868 else if (o
<= (MIN_FIXNUM_ENCODING
+ (MAX_FIXNUM
- MIN_FIXNUM
)))
869 printf ("%d", DECODE_FIXNUM(o
));
870 else // TODO past here, everything is either in ram or in rom, until we add a 3rd space for vectors, that is
879 if ((in_ram
&& RAM_BIGNUM(o
)) || (!in_ram
&& ROM_BIGNUM(o
)))
880 printf ("%d", decode_int (o
));
881 else if ((in_ram
&& RAM_COMPOSITE(o
)) || (!in_ram
&& ROM_COMPOSITE(o
)))
886 if ((in_ram
&& RAM_PAIR(o
)) || (!in_ram
&& ROM_PAIR(o
))) // TODO not exactly efficient, fix it
890 car
= ram_get_car (o
);
891 cdr
= ram_get_cdr (o
);
895 car
= rom_get_car (o
);
896 cdr
= rom_get_cdr (o
);
907 else if ((IN_RAM(cdr
) && RAM_PAIR(cdr
))
908 || (IN_ROM(cdr
) && ROM_PAIR(cdr
)))
912 car
= ram_get_car (cdr
);
913 cdr
= ram_get_cdr (cdr
);
917 car
= rom_get_car (cdr
);
918 cdr
= rom_get_cdr (cdr
);
931 else if ((in_ram
&& RAM_SYMBOL(o
)) || (!in_ram
&& ROM_SYMBOL(o
)))
932 printf ("#<symbol>");
933 else if ((in_ram
&& RAM_STRING(o
)) || (!in_ram
&& ROM_STRING(o
)))
934 printf ("#<string>");
935 else if ((in_ram
&& RAM_VECTOR(o
)) || (!in_ram
&& ROM_VECTOR(o
)))
936 printf ("#<vector>");
940 car
= ram_get_car (o
);
941 cdr
= ram_get_cdr (o
);
942 goto loop
; // TODO ugly hack, takes advantage of the fact that pairs and continuations have the same layout
950 if (IN_RAM(o
)) // TODO can closures be in rom ? I don't think so
951 env
= ram_get_cdr (o
);
953 env
= rom_get_cdr (o
);
956 pc
= ram_get_entry (o
);
958 pc
= rom_get_entry (o
);
960 printf ("{0x%04x ", pc
);
969 void show_state (rom_addr pc
)
972 printf ("pc=0x%04x bytecode=0x%02x env=", pc
, rom_get (pc
));
975 /* show (cont); */ // TODO prob, it's cyclic
989 /*---------------------------------------------------------------------------*/
991 /* Integer operations */
993 #define encode_bool(x) ((obj)(x))
995 void prim_numberp (void)
997 if (arg1
>= MIN_FIXNUM_ENCODING
998 && arg1
<= (MIN_FIXNUM_ENCODING
+ (MAX_FIXNUM
- MIN_FIXNUM
)))
1003 arg1
= encode_bool (RAM_BIGNUM(arg1
));
1004 else if (IN_ROM(arg1
))
1005 arg1
= encode_bool (ROM_BIGNUM(arg1
));
1011 void decode_2_int_args (void)
1013 a1
= decode_int (arg1
);
1014 a2
= decode_int (arg2
);
1017 void prim_add (void)
1019 decode_2_int_args ();
1020 arg1
= encode_int (a1
+ a2
);
1024 void prim_sub (void)
1026 decode_2_int_args ();
1027 arg1
= encode_int (a1
- a2
);
1031 void prim_mul (void)
1033 decode_2_int_args ();
1034 arg1
= encode_int (a1
* a2
);
1038 void prim_div (void)
1040 decode_2_int_args ();
1042 ERROR("divide by 0");
1043 arg1
= encode_int (a1
/ a2
);
1047 void prim_rem (void)
1049 decode_2_int_args ();
1051 ERROR("divide by 0");
1052 arg1
= encode_int (a1
% a2
);
1056 void prim_neg (void)
1058 a1
= decode_int (arg1
);
1059 arg1
= encode_int (- a1
);
1064 decode_2_int_args ();
1065 arg1
= encode_bool (a1
== a2
);
1071 decode_2_int_args ();
1072 arg1
= encode_bool (a1
< a2
);
1078 decode_2_int_args ();
1079 arg1
= encode_bool (a1
> a2
);
1083 void prim_ior (void)
1085 a1
= decode_int (arg1
);
1086 a2
= decode_int (arg2
);
1087 arg1
= encode_int (a1
| a2
);
1091 void prim_xor (void)
1093 a1
= decode_int (arg1
);
1094 a2
= decode_int (arg2
);
1095 arg1
= encode_int (a1
^ a2
);
1100 /*---------------------------------------------------------------------------*/
1102 /* List operations */
1104 void prim_pairp (void)
1107 arg1
= encode_bool (RAM_PAIR(arg1
));
1108 else if (IN_ROM(arg1
))
1109 arg1
= encode_bool (ROM_PAIR(arg1
));
1114 obj
cons (obj car
, obj cdr
)
1116 return alloc_ram_cell_init (COMPOSITE_FIELD0
| ((car
& 0x1f00) >> 8),
1118 PAIR_FIELD2
| ((cdr
& 0x1f00) >> 8),
1122 void prim_cons (void)
1124 arg1
= cons (arg1
, arg2
);
1128 void prim_car (void)
1132 if (!RAM_PAIR(arg1
))
1134 arg1
= ram_get_car (arg1
);
1136 else if (IN_ROM(arg1
))
1138 if (!ROM_PAIR(arg1
))
1140 arg1
= rom_get_car (arg1
);
1148 void prim_cdr (void)
1152 if (!RAM_PAIR(arg1
))
1154 arg1
= ram_get_cdr (arg1
);
1156 else if (IN_ROM(arg1
))
1158 if (!ROM_PAIR(arg1
))
1160 arg1
= rom_get_cdr (arg1
);
1168 void prim_set_car (void)
1172 if (!RAM_PAIR(arg1
))
1175 ram_set_car (arg1
, arg2
);
1185 void prim_set_cdr (void)
1189 if (!RAM_PAIR(arg1
))
1192 ram_set_cdr (arg1
, arg2
);
1202 void prim_nullp (void)
1204 arg1
= encode_bool (arg1
== OBJ_NULL
);
1207 /*---------------------------------------------------------------------------*/
1209 /* Miscellaneous operations */
1211 void prim_eqp (void)
1213 arg1
= encode_bool (arg1
== arg2
);
1217 void prim_not (void)
1219 arg1
= encode_bool (arg1
== OBJ_FALSE
);
1222 void prim_symbolp (void)
1225 arg1
= encode_bool (RAM_SYMBOL(arg1
));
1226 else if (IN_ROM(arg1
))
1227 arg1
= encode_bool (ROM_SYMBOL(arg1
));
1232 void prim_stringp (void)
1235 arg1
= encode_bool (RAM_STRING(arg1
));
1236 else if (IN_ROM(arg1
))
1237 arg1
= encode_bool (ROM_STRING(arg1
));
1242 void prim_string2list (void)
1246 if (!RAM_STRING(arg1
))
1247 TYPE_ERROR("string");
1249 arg1
= ram_get_car (arg1
);
1251 else if (IN_ROM(arg1
))
1253 if (!ROM_STRING(arg1
))
1254 TYPE_ERROR("string");
1256 arg1
= rom_get_car (arg1
);
1259 TYPE_ERROR("string");
1262 void prim_list2string (void)
1264 arg1
= alloc_ram_cell_init (COMPOSITE_FIELD0
| ((arg1
& 0x1f00) >> 8),
1271 /*---------------------------------------------------------------------------*/
1273 /* Robot specific operations */
1276 void prim_print (void)
1291 int32
read_clock (void)
1297 now
= from_now( 0 );
1305 static int32 start
= 0;
1310 now
= tb
.time
* 1000 + tb
.millitm
;
1317 static int32 start
= 0;
1320 if (gettimeofday (&tv
, NULL
) == 0)
1322 now
= tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
1336 void prim_clock (void)
1338 arg1
= encode_int (read_clock ());
1342 void prim_motor (void)
1344 decode_2_int_args ();
1346 if (a1
< 1 || a1
> 2 || a2
< -100 || a2
> 100)
1347 ERROR("argument out of range to procedure \"motor\"");
1357 printf ("motor %d -> power=%d\n", a1
, a2
);
1367 void prim_led (void)
1369 decode_2_int_args ();
1370 a3
= decode_int (arg3
);
1372 if (a1
< 1 || a1
> 3 || a2
< 0 || a3
< 0)
1373 ERROR("argument out of range to procedure \"led\"");
1377 LED_set( a1
, a2
, a3
);
1383 printf ("led %d -> duty=%d period=%d\n", a1
, a2
, a3
);
1394 void prim_led2_color (void)
1396 a1
= decode_int (arg1
);
1398 if (a1
< 0 || a1
> 1)
1399 ERROR("argument out of range to procedure \"led2-color\"");
1403 LED2_color_set( a1
);
1409 printf ("led2-color -> %s\n", (a1
==0)?"green":"red");
1418 void prim_getchar_wait (void)
1420 decode_2_int_args();
1421 a1
= read_clock () + a1
;
1423 if (a1
< 0 || a2
< 1 || a2
> 3)
1424 ERROR("argument out of range to procedure \"getchar-wait\"");
1431 serial_port_set ports
;
1432 ports
= serial_rx_wait_with_timeout( a2
, a1
);
1434 arg1
= encode_int (serial_rx_read( ports
));
1449 arg1
= encode_int (_getch ());
1452 } while (read_clock () < a1
);
1457 arg1
= encode_int (getchar ());
1465 void prim_putchar (void)
1467 decode_2_int_args ();
1469 if (a1
< 0 || a1
> 255 || a2
< 1 || a2
> 3)
1470 ERROR("argument out of range to procedure \"putchar\"");
1474 serial_tx_write( a2
, a1
);
1490 void prim_beep (void)
1492 decode_2_int_args ();
1494 if (a1
< 1 || a1
> 255 || a2
< 0)
1495 ERROR("argument out of range to procedure \"beep\"");
1499 beep( a1
, from_now( a2
) );
1505 printf ("beep -> freq-div=%d duration=%d\n", a1
, a2
);
1515 void prim_adc (void)
1519 a1
= decode_int (arg1
);
1521 if (a1
< 1 || a1
> 3)
1522 ERROR("argument out of range to procedure \"adc\"");
1532 x
= read_clock () & 255;
1534 if (x
> 127) x
= 256 - x
;
1540 arg1
= encode_int (x
);
1544 void prim_dac (void)
1546 a1
= decode_int (arg1
);
1548 if (a1
< 0 || a1
> 255)
1549 ERROR("argument out of range to procedure \"dac\"");
1559 printf ("dac -> %d\n", a1
);
1568 void prim_sernum (void)
1584 arg1
= encode_int (x
);
1588 /*---------------------------------------------------------------------------*/
1592 int hidden_fgetc (FILE *f
)
1602 #define fgetc(f) hidden_fgetc(f)
1604 void write_hex_nibble (int n
)
1606 putchar ("0123456789ABCDEF"[n
]);
1609 void write_hex (uint8 n
)
1611 write_hex_nibble (n
>> 4);
1612 write_hex_nibble (n
& 0x0f);
1617 if (c
>= '0' && c
<= '9')
1620 if (c
>= 'A' && c
<= 'F')
1621 return (c
- 'A' + 10);
1623 if (c
>= 'a' && c
<= 'f')
1624 return (c
- 'a' + 10);
1629 int read_hex_byte (FILE *f
)
1631 int h1
= hex (fgetc (f
));
1632 int h2
= hex (fgetc (f
));
1634 if (h1
>= 0 && h2
>= 0)
1635 return (h1
<<4) + h2
;
1640 int read_hex_file (char *filename
)
1643 FILE *f
= fopen (filename
, "r");
1653 for (i
=0; i
<ROM_BYTES
; i
++)
1658 while ((c
= fgetc (f
)) != EOF
)
1660 if ((c
== '\r') || (c
== '\n'))
1664 (len
= read_hex_byte (f
)) < 0 ||
1665 (a1
= read_hex_byte (f
)) < 0 ||
1666 (a2
= read_hex_byte (f
)) < 0 ||
1667 (t
= read_hex_byte (f
)) < 0)
1673 sum
= len
+ a1
+ a2
+ t
;
1681 unsigned long adr
= ((unsigned long)hi16
<< 16) + a
- CODE_START
;
1683 if ((b
= read_hex_byte (f
)) < 0)
1686 if (adr
>= 0 && adr
< ROM_BYTES
)
1689 a
= (a
+ 1) & 0xffff;
1706 if ((a1
= read_hex_byte (f
)) < 0 ||
1707 (a2
= read_hex_byte (f
)) < 0)
1712 hi16
= (a1
<<8) + a2
;
1717 if ((b
= read_hex_byte (f
)) < 0)
1724 printf ("*** HEX file checksum error (expected 0x%02x)\n", sum
);
1730 if ((c
!= '\r') && (c
!= '\n'))
1741 printf ("*** HEX file syntax error\n");
1751 /*---------------------------------------------------------------------------*/
1753 #define FETCH_NEXT_BYTECODE() bytecode = rom_get (pc++)
1755 #define BEGIN_DISPATCH() \
1757 IF_TRACE(show_state (pc)); \
1758 FETCH_NEXT_BYTECODE(); \
1759 bytecode_hi4 = bytecode & 0xf0; \
1760 bytecode_lo4 = bytecode & 0x0f; \
1761 switch (bytecode_hi4 >> 4) {
1763 #define END_DISPATCH() }
1765 #define CASE(opcode) case (opcode>>4):;
1767 #define DISPATCH(); goto dispatch;
1772 #define bytecode TABLAT
1773 #define bytecode_hi4 WREG
1776 #define PUSH_CONSTANT1 0x00
1777 #define PUSH_CONSTANT2 0x10
1778 #define PUSH_STACK1 0x20
1779 #define PUSH_STACK2 0x30
1780 #define PUSH_GLOBAL 0x40
1781 #define SET_GLOBAL 0x50
1784 #define CALL_TOPLEVEL 0x80
1785 #define JUMP_TOPLEVEL 0x90
1787 #define GOTO_IF_FALSE 0xb0
1788 #define CLOSURE 0xc0
1795 char *prim_name
[48] =
1819 "prim #%graft-to-cont",
1820 "prim #%return-to-cont",
1824 "prim #%string->list",
1825 "prim #%list->string",
1833 "prim #%led2-color",
1834 "prim #%getchar-wait",
1841 "push-constant [long]",
1849 #define PUSH_ARG1() push_arg1 ()
1852 void push_arg1 (void)
1854 env
= cons (arg1
, env
);
1860 obj o
= ram_get_car (env
);
1861 env
= ram_get_cdr (env
);
1865 void pop_procedure (void)
1871 if (!RAM_CLOSURE(arg1
))
1872 TYPE_ERROR("procedure");
1874 entry
= ram_get_entry (arg1
) + CODE_START
; // FOO all addresses in the bytecode should be from 0, not from CODE_START, should be fixed everywhere, but might not be
1876 else if (IN_ROM(arg1
))
1878 if (!ROM_CLOSURE(arg1
))
1879 TYPE_ERROR("procedure");
1881 entry
= rom_get_entry (arg1
) + CODE_START
;
1884 TYPE_ERROR("procedure");
1887 void handle_arity_and_rest_param (void)
1891 np
= rom_get (entry
++);
1893 if ((np
& 0x80) == 0)
1896 ERROR("wrong number of arguments");
1903 ERROR("wrong number of arguments");
1911 arg3
= cons (arg4
, arg3
);
1917 arg1
= cons (arg3
, arg1
);
1922 void build_env (void)
1928 arg1
= cons (arg3
, arg1
);
1936 void save_cont (void)
1938 // the second half is a closure
1939 arg3
= alloc_ram_cell_init (CLOSURE_FIELD0
| (pc
>> 11),
1941 ((pc
& 0x0007) << 5) | (env
>> 8),
1943 cont
= alloc_ram_cell_init (COMPOSITE_FIELD0
| (cont
>> 8),
1945 CONTINUATION_FIELD2
| (arg3
>> 8),
1950 void interpreter (void)
1954 pc
= (CODE_START
+ 4) + ((rom_addr
)rom_get (CODE_START
+2) << 2);
1958 /***************************************************************************/
1959 CASE(PUSH_CONSTANT1
);
1961 IF_TRACE(printf(" (push-constant "); show (bytecode_lo4
); printf (")\n"));
1963 arg1
= bytecode_lo4
;
1969 /***************************************************************************/
1970 CASE(PUSH_CONSTANT2
);
1972 IF_TRACE(printf(" (push-constant "); show (bytecode_lo4
+16); printf (")\n"));
1973 arg1
= bytecode_lo4
+16;
1979 /***************************************************************************/
1982 IF_TRACE(printf(" (push-stack %d)\n", bytecode_lo4
));
1986 while (bytecode_lo4
!= 0)
1988 arg1
= ram_get_cdr (arg1
);
1992 arg1
= ram_get_car (arg1
);
1998 /***************************************************************************/
2001 IF_TRACE(printf(" (push-stack %d)\n", bytecode_lo4
+16));
2007 while (bytecode_lo4
!= 0)
2009 arg1
= ram_get_cdr (arg1
);
2013 arg1
= ram_get_car (arg1
);
2019 /***************************************************************************/
2022 IF_TRACE(printf(" (push-global %d)\n", bytecode_lo4
));
2024 arg1
= get_global (bytecode_lo4
);
2030 /***************************************************************************/
2033 IF_TRACE(printf(" (set-global %d)\n", bytecode_lo4
));
2035 set_global (bytecode_lo4
, POP());
2039 /***************************************************************************/
2042 IF_TRACE(printf(" (call %d)\n", bytecode_lo4
));
2047 handle_arity_and_rest_param ();
2058 /***************************************************************************/
2061 IF_TRACE(printf(" (jump %d)\n", bytecode_lo4
));
2066 handle_arity_and_rest_param ();
2076 /***************************************************************************/
2077 CASE(CALL_TOPLEVEL
);
2079 FETCH_NEXT_BYTECODE();
2082 FETCH_NEXT_BYTECODE();
2084 IF_TRACE(printf(" (call-toplevel 0x%04x)\n", ((arg2
<< 8) | bytecode
) + CODE_START
));
2086 entry
= (arg2
<< 8) + bytecode
+ CODE_START
; // TODO FOOBAR we have the last 4 bits of the opcode free, to do pretty much anything
2089 na
= rom_get (entry
++);
2102 /***************************************************************************/
2103 CASE(JUMP_TOPLEVEL
);
2105 FETCH_NEXT_BYTECODE();
2108 FETCH_NEXT_BYTECODE();
2110 IF_TRACE(printf(" (jump-toplevel 0x%04x)\n", ((arg2
<< 8) | bytecode
) + CODE_START
));
2112 entry
= (arg2
<< 8) + bytecode
+ CODE_START
; // TODO this is a common pattern
2115 na
= rom_get (entry
++);
2127 /***************************************************************************/
2130 FETCH_NEXT_BYTECODE();
2133 FETCH_NEXT_BYTECODE();
2135 IF_TRACE(printf(" (goto 0x%04x)\n", (rom_addr
)((arg2
<< 8) + bytecode
+ CODE_START
)));
2137 pc
= (arg2
<< 8) + bytecode
+ CODE_START
;
2141 /***************************************************************************/
2142 CASE(GOTO_IF_FALSE
);
2144 FETCH_NEXT_BYTECODE();
2147 FETCH_NEXT_BYTECODE();
2149 IF_TRACE(printf(" (goto-if-false 0x%04x)\n", (rom_addr
)((arg2
<< 8) + bytecode
+ CODE_START
)));
2151 if (POP() == OBJ_FALSE
)
2152 pc
= (arg2
<< 8) + bytecode
+ CODE_START
;
2156 /***************************************************************************/
2159 FETCH_NEXT_BYTECODE();
2162 FETCH_NEXT_BYTECODE();
2164 IF_TRACE(printf(" (closure 0x%04x)\n", (arg2
<< 8) | bytecode
));
2166 arg3
= POP(); // env
2168 entry
= (arg2
<< 8) | bytecode
; // TODO original had no CODE_START, why ?
2170 arg1
= alloc_ram_cell_init (CLOSURE_FIELD0
| (arg2
>> 3),
2171 ((arg2
& 0x07) << 5) | (bytecode
>> 3),
2172 ((bytecode
& 0x07) << 5) |((arg3
& 0x1f00) >> 8),
2182 /***************************************************************************/
2185 IF_TRACE(printf(" (%s)\n", prim_name
[bytecode_lo4
]));
2187 switch (bytecode_lo4
)
2190 arg1
= POP(); prim_numberp (); PUSH_ARG1(); break;
2192 arg2
= POP(); arg1
= POP(); prim_add (); PUSH_ARG1(); break;
2194 arg2
= POP(); arg1
= POP(); prim_sub (); PUSH_ARG1(); break;
2196 arg2
= POP(); arg1
= POP(); prim_mul (); PUSH_ARG1(); break;
2198 arg2
= POP(); arg1
= POP(); prim_div (); PUSH_ARG1(); break;
2200 arg2
= POP(); arg1
= POP(); prim_rem (); PUSH_ARG1(); break;
2202 arg1
= POP(); prim_neg (); PUSH_ARG1(); break;
2204 arg2
= POP(); arg1
= POP(); prim_eq (); PUSH_ARG1(); break;
2206 arg2
= POP(); arg1
= POP(); prim_lt (); PUSH_ARG1(); break;
2208 arg2
= POP(); arg1
= POP(); prim_ior (); PUSH_ARG1(); break;
2210 arg2
= POP(); arg1
= POP(); prim_gt (); PUSH_ARG1(); break;
2212 arg2
= POP(); arg1
= POP(); prim_xor (); PUSH_ARG1(); break;
2214 arg1
= POP(); prim_pairp (); PUSH_ARG1(); break;
2216 arg2
= POP(); arg1
= POP(); prim_cons (); PUSH_ARG1(); break;
2218 arg1
= POP(); prim_car (); PUSH_ARG1(); break;
2220 arg1
= POP(); prim_cdr (); PUSH_ARG1(); break;
2225 /***************************************************************************/
2228 IF_TRACE(printf(" (%s)\n", prim_name
[bytecode_lo4
+16]));
2230 switch (bytecode_lo4
)
2233 arg2
= POP(); arg1
= POP(); prim_set_car (); break;
2235 arg2
= POP(); arg1
= POP(); prim_set_cdr (); break;
2237 arg1
= POP(); prim_nullp (); PUSH_ARG1(); break;
2239 arg2
= POP(); arg1
= POP(); prim_eqp (); PUSH_ARG1(); break;
2241 arg1
= POP(); prim_not (); PUSH_ARG1(); break;
2243 /* prim #%get-cont */
2248 /* prim #%graft-to-cont */
2250 arg1
= POP(); /* thunk to call */
2251 cont
= POP(); /* continuation */
2258 handle_arity_and_rest_param ();
2268 /* prim #%return-to-cont */
2270 arg1
= POP(); /* value to return */
2271 cont
= POP(); /* continuation */
2273 arg2
= ram_get_cdr (cont
);
2275 pc
= ram_get_entry (arg2
);
2277 env
= ram_get_cdr (arg2
);
2278 cont
= ram_get_car (cont
);
2288 /* prim #%symbol? */
2289 arg1
= POP(); prim_symbolp (); PUSH_ARG1(); break;
2291 /* prim #%string? */
2292 arg1
= POP(); prim_stringp (); PUSH_ARG1(); break;
2294 /* prim #%string->list */
2295 arg1
= POP(); prim_string2list (); PUSH_ARG1(); break;
2297 /* prim #%list->string */
2298 arg1
= POP(); prim_list2string (); PUSH_ARG1(); break;
2311 /***************************************************************************/
2314 IF_TRACE(printf(" (%s)\n", prim_name
[bytecode_lo4
+32]));
2316 switch (bytecode_lo4
)
2325 prim_clock (); PUSH_ARG1(); break;
2328 arg2
= POP(); arg1
= POP(); prim_motor (); break;
2331 arg3
= POP(); arg2
= POP(); arg1
= POP(); prim_led (); ;break;
2333 /* prim #%led2-color */
2334 arg1
= POP(); prim_led2_color (); break;
2336 /* prim #%getchar-wait */
2337 arg2
= POP(); arg1
= POP(); prim_getchar_wait (); PUSH_ARG1(); break;
2339 /* prim #%putchar */
2340 arg2
= POP(); arg1
= POP(); prim_putchar (); break;
2343 arg2
= POP(); arg1
= POP(); prim_beep (); break;
2346 arg1
= POP(); prim_adc (); PUSH_ARG1(); break;
2349 arg1
= POP(); prim_dac (); break;
2352 prim_sernum (); PUSH_ARG1(); break;
2358 /* push-constant [long] */
2359 FETCH_NEXT_BYTECODE();
2361 FETCH_NEXT_BYTECODE();
2362 arg1
= (arg2
<< 8) | bytecode
;
2379 arg2
= ram_get_cdr (cont
);
2380 pc
= ram_get_entry (arg2
);
2381 env
= ram_get_cdr (arg2
);
2382 cont
= ram_get_car (cont
);
2390 /***************************************************************************/
2395 /*---------------------------------------------------------------------------*/
2401 printf ("usage: sim file.hex\n");
2405 int main (int argc
, char *argv
[])
2408 rom_addr rom_start_addr
= 0;
2410 if (argc
> 1 && argv
[1][0] == '-' && argv
[1][1] == 's')
2417 if ((h1
= hex (argv
[1][2])) < 0 ||
2418 (h2
= hex (argv
[1][3])) < 0 ||
2419 (h3
= hex (argv
[1][4])) != 0 ||
2420 (h4
= hex (argv
[1][5])) != 0 ||
2424 rom_start_addr
= (h1
<< 12) | (h2
<< 8) | (h3
<< 4) | h4
;
2431 printf ("Start address = 0x%04x\n", rom_start_addr
); // TODO says 0, but should be CODE_START ?
2437 if (!read_hex_file (argv
[1]))
2438 printf ("*** Could not read hex file \"%s\"\n", argv
[1]);
2443 if (rom_get (CODE_START
+0) != 0xfb ||
2444 rom_get (CODE_START
+1) != 0xd7)
2445 printf ("*** The hex file was not compiled with PICOBIT\n");
2449 for (i
=0; i
<8192; i
++)
2450 if (rom_get (i
) != 0xff)
2451 printf ("rom_mem[0x%04x] = 0x%02x\n", i
, rom_get (i
));
2457 printf ("**************** memory needed = %d\n", max_live
+1);
2467 /*---------------------------------------------------------------------------*/