Removed the debugging output from picobit.
[sixpic.git] / tests / picobit / picobit-vm-sixpic.c
blob2f9e4c8fc25a2e8ccbec2249de99798085f86c51
1 // TODO at least, use #include and #define, but #define would require me to start all over...
2 // no typedefs
3 // no forward declarations
4 // Scheme-style hex literals
5 // no explicit casts (intermediate variables instead)
6 // removed functions that interact with the firmware, and with rom
7 // had some case labels that were not literals (but could have been constant folded) in the dispatch
9 /* typedef char int8; */
10 /* typedef short int16; */
11 /* typedef long int32; */
12 /* typedef unsigned char uint8; */
13 /* typedef unsigned short uint16; */
14 /* typedef unsigned long uint32; */
16 /* typedef uint8 word; */
18 /* typedef uint16 ram_addr; */
19 /* typedef uint16 rom_addr; */
21 int16 arg1;
22 int16 arg2;
23 int16 arg3;
24 int16 arg4;
25 int16 arg5;
26 int16 cont;
27 int16 env;
29 int8 na;
30 int16 pc;
31 int8 glovars;
32 int16 entry;
33 int8 bytecode;
34 int8 bytecode_hi4;
35 int8 bytecode_lo4;
36 int16 a1;
37 int16 a2;
38 int16 a3;
40 void halt_with_error (){
41 uart_write(101); // e
42 uart_write(114); // r
43 uart_write(114); // r
44 uart_write(13);
45 uart_write(10);
46 exit();
50 /* typedef int16 obj; */
51 /* int8 ram_get_gc_tags (int16 o); */
52 /* int8 ram_get_gc_tag0 (int16 o); */
53 /* int8 ram_get_gc_tag1 (int16 o); */
54 /* void ram_set_gc_tags (int16 o, int8 tags); */
55 /* void ram_set_gc_tag0 (int16 o, int8 tag); */
56 /* void ram_set_gc_tag1 (int16 o, int8 tag); */
57 /* int8 ram_get_field0 (int16 o); */
58 /* int8 ram_get_field1 (int16 o); */
59 /* int8 ram_get_field2 (int16 o); */
60 /* int8 ram_get_field3 (int16 o); */
61 /* int8 ram_get_fieldn (int16 o, int8 n); */
62 /* void ram_set_field0 (int16 o, int8 val); */
63 /* void ram_set_field1 (int16 o, int8 val); */
64 /* void ram_set_field2 (int16 o, int8 val); */
65 /* void ram_set_field3 (int16 o, int8 val); */
66 /* void ram_set_fieldn (int16 o, int8 n, int8 val); */
67 /* int8 rom_get_field0 (int16 o); */
68 /* int8 rom_get_field1 (int16 o); */
69 /* int8 rom_get_field2 (int16 o); */
70 /* int8 rom_get_field3 (int16 o); */
71 int8 ram_get_gc_tags (int16 o) {
72 int16 t2 = o - 512;
73 return (*(((t2 << 2))+#x200) & #x60); // TODO not sure these shifts really save on code space, maybe multiplications (which would be 2 additions) would be better
75 int8 ram_get_gc_tag0 (int16 o) {
76 int16 t2 = o - 512;
77 return (*(((t2 << 2))+#x200) & #x20);
79 int8 ram_get_gc_tag1 (int16 o) {
80 int16 t2 = o - 512;
81 return (*(((t2 << 2))+#x200) & #x40);
83 void ram_set_gc_tags (int16 o, int8 tags) {
84 int16 t2 = (o - 512) << 2; // TODO optimized a couple of things
85 (*((t2)+#x200) = ((*((t2)+#x200) & #x9f) | (tags))); // TODO if we could use bst and bcf, would be better
87 void ram_set_gc_tag0 (int16 o, int8 tag) {
88 int16 t2 = (o - 512) << 2; // TODO same here
89 *(t2+#x200) = ((*(t2+#x200) & #xdf) | (tag));
91 void ram_set_gc_tag1 (int16 o, int8 tag) {
92 int16 t2 = (o - 512) << 2; // TODO same here
93 *(t2+#x200) = ((*(t2+#x200) & #xbf) | (tag));
95 int8 ram_get_field0 (int16 o) { int16 t2 = o - 512; return *(((t2 << 2) + (0))+#x200); }
96 int8 ram_get_field1 (int16 o) { int16 t2 = o - 512; return *(((t2 << 2) + (1))+#x200); }
97 int8 ram_get_field2 (int16 o) { int16 t2 = o - 512; return *(((t2 << 2) + (2))+#x200); }
98 int8 ram_get_field3 (int16 o) { int16 t2 = o - 512; return *(((t2 << 2) + (3))+#x200); }
99 int8 ram_get_fieldn (int16 o, int8 n) {
100 switch (n) {
101 case 0: return ram_get_field0 (o);
102 case 1: return ram_get_field1 (o);
103 case 2: return ram_get_field2 (o);
104 case 3: return ram_get_field3 (o);
107 void ram_set_field0 (int16 o, int8 val) { int16 t2 = o - 512; *(((t2 << 2) + (0))+#x200) = (val); }
108 void ram_set_field1 (int16 o, int8 val) { int16 t2 = o - 512; *(((t2 << 2) + (1))+#x200) = (val); }
109 void ram_set_field2 (int16 o, int8 val) { int16 t2 = o - 512; *(((t2 << 2) + (2))+#x200) = (val); }
110 void ram_set_field3 (int16 o, int8 val) { int16 t2 = o - 512; *(((t2 << 2) + (3))+#x200) = (val); }
111 void ram_set_fieldn (int16 o, int8 n, int8 val) {
112 switch (n) {
113 case 0: ram_set_field0 (o, val); break;
114 case 1: ram_set_field1 (o, val); break;
115 case 2: ram_set_field2 (o, val); break;
116 case 3: ram_set_field3 (o, val); break;
119 int8 rom_get_field0 (int16 o) { int16 t2 = (o) - (3 +255 - -1 +1); return rom_get (((t2 << 2) + (#x8000 + 4 + (0)))); }
120 int8 rom_get_field1 (int16 o) { int16 t2 = (o) - (3 +255 - -1 +1); return rom_get (((t2 << 2) + (#x8000 + 4 + (1)))); }
121 int8 rom_get_field2 (int16 o) { int16 t2 = (o) - (3 +255 - -1 +1); return rom_get (((t2 << 2) + (#x8000 + 4 + (2)))); }
122 int8 rom_get_field3 (int16 o) { int16 t2 = (o) - (3 +255 - -1 +1); return rom_get (((t2 << 2) + (#x8000 + 4 + (3)))); }
125 /* int16 ram_get_car (int16 o); */
126 /* int16 rom_get_car (int16 o); */
127 /* int16 ram_get_cdr (int16 o); */
128 /* int16 rom_get_cdr (int16 o); */
129 /* void ram_set_car (int16 o, int16 val); */
130 /* void ram_set_cdr (int16 o, int16 val); */
132 /* int16 ram_get_entry (int16 o); */
133 /* int16 rom_get_entry (int16 o); */
135 int16 ram_get_car (int16 o)
136 { int16 tmp = (ram_get_field0 (o) & #x1f); return (tmp << 8) | ram_get_field1 (o); }
137 int16 rom_get_car (int16 o)
138 { int16 tmp = (rom_get_field0 (o) & #x1f); return (tmp << 8) | rom_get_field1 (o); }
139 int16 ram_get_cdr (int16 o)
140 { int16 tmp = (ram_get_field2 (o) & #x1f); return (tmp << 8) | ram_get_field3 (o); }
141 int16 rom_get_cdr (int16 o)
142 { int16 tmp = (rom_get_field2 (o) & #x1f); return (tmp << 8) | rom_get_field3 (o); }
144 void ram_set_car (int16 o, int16 val) {
145 ram_set_field0 (o, (val >> 8) | (ram_get_field0 (o) & #xe0));
146 ram_set_field1 (o, val & #xff);
148 void ram_set_cdr (int16 o, int16 val) {
149 ram_set_field2 (o, (val >> 8) | (ram_get_field2 (o) & #xe0));
150 ram_set_field3 (o, val & #xff);
154 int16 ram_get_entry (int16 o) {
155 int16 tmp = (ram_get_field0 (o) & #x1f);
156 int16 tmp2 = ram_get_field1 (o); // TODO this cast is necessary because literals are of the smallest type possible in SIXPIC, not always int (not standard)
157 return ((tmp << 11)
158 | (tmp2 << 3)
159 | (ram_get_field2 (o) >> 5));
161 int16 rom_get_entry (int16 o){
162 int16 tmp = (rom_get_field0 (o) & #x1f);
163 return ((tmp << 11)
164 | (rom_get_field1 (o) << 3)
165 | (rom_get_field2 (o) >> 5));
169 /* int16 get_global (int8 i); */
170 /* void set_global (int8 i, int16 o); */
172 int16 get_global (int8 i) {
174 if (i & 1)
175 return ram_get_cdr (512 + (i >> 1));
176 else
177 return ram_get_car (512 + (i >> 1));
179 void set_global (int8 i, int16 o) {
180 if (i & 1)
181 ram_set_cdr (512 + (i >> 1), o);
182 else
183 ram_set_car (512 + (i >> 1), o);
186 int16 free_list;
187 int16 free_list_vec;
189 void mark (int16 temp) {
192 int16 stack;
193 int16 visit;
195 if ((!((temp) >= 1280) && ((temp) >= 512))) {
196 visit = 0;
198 push:
200 stack = visit;
201 visit = temp;
205 if (((((ram_get_field0 (visit) & #x80) == #x80) || ((ram_get_field0 (visit) & #xc0) == #x40) || ((ram_get_field0 (visit) & #xc0) == 0)) && ram_get_gc_tag0 (visit))
206 || (((((ram_get_field0 (visit) & #x80) == #x80) && ((ram_get_field2 (visit) & #xe0) == 0)) || (((ram_get_field0 (visit) & #x80) == #x80) && ((ram_get_field2 (visit) & #xe0) == #x80)))
207 && (ram_get_gc_tags (visit) != (0<<5))))
209 else {
210 if (((((ram_get_field0 (visit) & #x80) == #x80) && ((ram_get_field2 (visit) & #xe0) == 0)) || (((ram_get_field0 (visit) & #x80) == #x80) && ((ram_get_field2 (visit) & #xe0) == #x80)))) {
213 visit_field2:
215 temp = ram_get_cdr (visit);
217 if ((!((temp) >= 1280) && ((temp) >= 512))) {
219 int16 tmp = 2;
220 ram_set_gc_tags (visit, (tmp<<5));
221 ram_set_cdr (visit, stack);
222 goto push;
227 goto visit_field1;
230 if ((((ram_get_field0 (visit) & #x80) == #x80) || ((ram_get_field0 (visit) & #xc0) == #x40) || ((ram_get_field0 (visit) & #xc0) == 0))) {
233 visit_field1:
236 if (((ram_get_field0 (visit) & #xc0) == #x40))
237 temp = ram_get_cdr (visit);
238 else
239 temp = ram_get_car (visit);
241 if ((!((temp) >= 1280) && ((temp) >= 512))) {
243 int16 tmp = 1;
244 ram_set_gc_tag0 (visit, (tmp<<5));
245 if (((ram_get_field0 (visit) & #xc0) == #x40))
246 ram_set_cdr (visit, stack);
247 else
248 ram_set_car (visit, stack);
250 goto push;
255 else
257 int16 tmp = 1;
258 ram_set_gc_tag0 (visit, (tmp<<5));
261 pop:
265 if (stack != 0) {
266 if (((((ram_get_field0 (stack) & #x80) == #x80) && ((ram_get_field2 (stack) & #xe0) == 0)) || (((ram_get_field0 (stack) & #x80) == #x80) && ((ram_get_field2 (stack) & #xe0) == #x80))) && ram_get_gc_tag1 (stack)) {
269 temp = ram_get_cdr (stack);
270 ram_set_cdr (stack, visit);
271 visit = stack;
272 stack = temp;
274 ram_set_gc_tag1(visit, (0<<5));
277 goto visit_field1;
280 if (((ram_get_field0 (stack) & #xc0) == #x40)) {
284 temp = ram_get_cdr (stack);
285 ram_set_cdr (stack, visit);
286 visit = stack;
287 stack = temp;
289 goto pop;
294 temp = ram_get_car (stack);
295 ram_set_car (stack, visit);
296 visit = stack;
297 stack = temp;
299 goto pop;
308 void sweep () {
315 int16 visit = 1279;
317 free_list = 0;
319 while (visit >= (512 + ((glovars + 1) >> 1))) {
321 int16 tmp = 1;
322 if ((((ram_get_field0 (visit) & #x80) == #x80)
323 && (ram_get_gc_tags (visit) == (0<<5)))
324 || !(ram_get_gc_tags (visit) & (tmp<<5))) {
326 if ((((ram_get_field0 (visit) & #x80) == #x80) && ((ram_get_field2 (visit) & #xe0) == #x60))) {
328 int16 o = ram_get_cdr (visit);
329 int16 i = ram_get_car (visit);
330 ram_set_car (o, free_list_vec);
331 ram_set_cdr (o, (i + 3) >> 2);
332 free_list_vec = o;
335 ram_set_car (visit, free_list);
336 free_list = visit;
338 else {
339 if (((ram_get_field0 (visit) & #x80) == #x80))
340 ram_set_gc_tags (visit, (0<<5));
341 else
342 ram_set_gc_tag0 (visit, (0<<5));
347 visit--;
351 void gc () {
353 /* uart_write(10); */ // TODO for debugging
354 /* uart_write(13); */
355 /* uart_write(103); // g */
356 /* uart_write(99); // c */
357 /* uart_write(10); */
358 /* uart_write(13); */
360 int8 i;
365 mark (arg1);
367 mark (arg2);
369 mark (arg3);
371 mark (arg4);
373 mark (arg5);
375 mark (cont);
377 mark (env);
380 for (i=0; i<glovars; i++)
381 mark (get_global (i));
383 sweep ();
387 int16 alloc_ram_cell () {
388 int16 o;
394 if (free_list == 0) {
396 gc ();
397 if (free_list == 0)
399 halt_with_error();
402 o = free_list;
404 free_list = ram_get_car (o);
405 /* uart_write(65); */ // TODO for debugging
406 /* uart_write(108); */
407 /* uart_write(108); */
408 /* uart_write((free_list>>12)+65); */
409 /* uart_write(((free_list>>8)&#xf)+65); */
410 /* uart_write(((free_list>>4)&#xf)+65); */
411 /* uart_write((free_list & #xf) + 65); */
412 /* uart_write(10); */
413 /* uart_write(13); */
416 return o;
419 int16 alloc_ram_cell_init (int8 f0, int8 f1, int8 f2, int8 f3) {
420 int16 o = alloc_ram_cell ();
422 ram_set_field0 (o, f0);
423 ram_set_field1 (o, f1);
424 ram_set_field2 (o, f2);
425 ram_set_field3 (o, f3);
427 return o;
430 int16 alloc_vec_cell (int16 n) {
431 int16 o = free_list_vec;
432 int16 prec = 0;
433 int8 gc_done = 0;
440 while ((ram_get_cdr (o) * 4) < n) {
441 if (o == 0) {
442 if (gc_done)
443 halt_with_error();
445 gc ();
446 gc_done = 1;
448 o = free_list_vec;
449 prec = 0;
450 continue;
452 prec = o;
453 o = ram_get_car (o);
458 if (((ram_get_cdr(o) * 4) - n) < 4) {
459 if (prec)
460 ram_set_car (prec, ram_get_car (o));
461 else
462 free_list_vec = ram_get_car (o);
466 else {
467 int16 new_free = o + ((n + 3) >> 2);
468 if (prec)
469 ram_set_car (prec, new_free);
470 else
471 free_list_vec = new_free;
472 ram_set_car (new_free, ram_get_car (o));
473 ram_set_cdr (new_free, ram_get_cdr (o) - ((n + 3) >> 2));
476 return o;
481 /* typedef int16 integer; */
482 /* typedef int16 digit; */
483 /* typedef int32 two_digit; */
484 /* int16 make_integer (int16 lo, int16 hi); */
485 /* int16 integer_hi (int16 x); */
486 /* int16 integer_lo (int16 x); */
487 int16 make_integer (int16 lo_make_integer, int16 hi_make_integer) { // TODO changed name
488 return alloc_ram_cell_init (0 | (hi_make_integer >> 8), hi_make_integer, lo_make_integer >> 8, lo_make_integer);
491 int16 integer_hi (int16 x) {
492 if ((!((x) >= 1280) && ((x) >= 512)))
493 return ram_get_car (x);
494 else if ((!((x) >= 1280) && !(!((x) >= 1280) && ((x) >= 512)) && ((x) >= (3 +255 - -1 +1))))
495 return rom_get_car (x);
496 else if (x < (3 - -1)){
497 return ((0 + (3 - -1))-1);
499 else{
500 return (0 + (3 - -1));
504 int16 integer_lo (int16 x) {
505 if ((!((x) >= 1280) && ((x) >= 512))) {
506 int16 t = ram_get_field2 (x);
507 return (t << 8) + ram_get_field3 (x);
509 else if ((!((x) >= 1280) && !(!((x) >= 1280) && ((x) >= 512)) && ((x) >= (3 +255 - -1 +1)))) {
510 int16 t = rom_get_field2 (x);
511 return (t << 8) + rom_get_field3 (x);
513 else
514 return x - (3 - -1);
518 /* int16 norm (int16 prefix, int16 n); */
519 /* int8 negp (int16 x); */
520 /* int8 cmp (int16 x, int16 y); */
521 /* int16 integer_length (int16 x); */
522 /* int16 shr (int16 x); */
523 /* int16 negative_carry (int16 carry); */
524 /* int16 shl (int16 x); */
525 /* int16 shift_left (int16 x, int16 n); */
526 /* int16 add (int16 x, int16 y); */
527 /* int16 invert (int16 x); */
528 /* int16 sub (int16 x, int16 y); */
529 /* int16 neg (int16 x); */
530 /* int16 scale (int16 n, int16 x); */
531 /* int16 mulnonneg (int16 x, int16 y); */
532 /* int16 divnonneg (int16 x, int16 y); */
534 int16 decode_int (int16 o) {
535 int8 result;
536 if (o < 3)
537 halt_with_error();
539 if (o <= (3 + (255 - -1)))
540 return (o - (3 - -1));
542 if ((!((o) >= 1280) && ((o) >= 512))) {
543 if (!((ram_get_field0 (o) & #xc0) == 0))
544 halt_with_error();
545 return ram_get_field3 (o);
547 else if ((!((o) >= 1280) && !(!((o) >= 1280) && ((o) >= 512)) && ((o) >= (3 +255 - -1 +1)))) {
548 if (!((rom_get_field0 (o) & #xc0) == 0))
549 halt_with_error();
550 return rom_get_field3 (o);
552 else
553 halt_with_error();
556 /* int16 decode_int (int16 o); */
557 /* int16 encode_int (int16 n); */
559 int16 norm (int16 prefix, int16 n_norm) { // TODO arg changed
563 while (prefix != 0) { // bbs 1 and 4
564 int16 d = integer_lo (prefix); // bb 3
565 int16 temp = prefix;
567 prefix = integer_hi (temp);
569 if (((n_norm) == ((0 + (3 - -1))))) { // bb 3 and 8
570 if (d <= 255) { // bb 6
571 n_norm = (d + (3 - -1)); // bb 10
572 continue;
575 else if (((n_norm) == (((0 + (3 - -1))-1)))) { // bbs 7 and 13
576 int16 tmp = 1; // bb 12 // FOO had int16, which made the shift useless (maybe would give the same result anyway, since 0-1 = -1), actually, changes nothing FOO having an int32 here causes compilation to fail
577 if (d >= (tmp<<16) - 1) { // bb 12 // TODO was + MIN_FIXNUM, but -1 is not a valid literal
578 int16 t = d - (tmp << 16); // bb 15
579 n_norm = (t + (3 - -1));
580 continue;
584 ram_set_car (temp, n_norm); // bb 5
585 n_norm = temp;
588 return n_norm; // bb 2
591 int8 negp (int16 x) {
594 do {
595 x = integer_hi (x); // bb 1
596 if (((x) == ((0 + (3 - -1))))) // bbs 1 and 6
597 return 0; // bb 5
598 } while (!((x) == (((0 + (3 - -1))-1)))); // bbs 2 and 8
600 return 1; // bb 3
603 int8 cmp (int16 x, int16 y) { // TODO changed. used to return -1, 0 and 1, now is 0, 1, 2
606 int8 result = 1;
607 int16 xlo;
608 int16 ylo;
610 for (;;) { // bb 2
611 if (((x) == ((0 + (3 - -1)))) // bbs 2 and 8
612 || ((x) == (((0 + (3 - -1))-1)))) { // bbs 7 and 9
613 if (!((x) == (y))) // bbs 6 and 12
614 { if (negp (y)) // bb 11
615 result = 2; // bb 14
616 else result = 0; } // bb 15
617 break; // bb 10
620 if (((y) == ((0 + (3 - -1)))) // bbs 5 and 19
621 || ((y) == (((0 + (3 - -1))-1)))) { // bbs 18 and 20
622 if (negp (x)) // bb 17
623 result = 0; // bb 22
624 else result = 2; // bb 23
625 break; // bb 21
628 xlo = integer_lo (x); // bb 16
629 ylo = integer_lo (y);
630 x = integer_hi (x);
631 y = integer_hi (y);
632 if (xlo != ylo) // bb 16 and 26
633 { if (xlo < ylo) // bb 25
634 result = 0; // bb 28
635 else result = 2; } // bb 29
637 return result;
640 int16 integer_length (int16 x) {
644 int16 result = 0;
645 int16 next;
646 int16 d;
648 while (!(((next = integer_hi (x))) == ((0 + (3 - -1))))) {
649 result += 16;
650 x = next;
653 d = integer_lo (x);
655 while (d > 0) {
656 result++;
657 d >>= 1;
660 return result;
663 int16 shr (int16 x) {
666 int16 result = 0;
667 int16 d;
669 for (;;) {
670 if (((x) == ((0 + (3 - -1)))) || ((x) == (((0 + (3 - -1))-1)))) {
671 result = norm (result, x);
672 break;
675 d = integer_lo (x);
676 x = integer_hi (x);
677 int16 tmp = 1;
678 result = make_integer ((d >> 1) |
679 ((integer_lo (x) & 1) ? (tmp<<(16-1)) : 0),
680 result);
683 return result;
686 int16 negative_carry (int16 carry) {
687 if (carry)
688 return ((0 + (3 - -1))-1);
689 else
690 return (0 + (3 - -1));
693 int16 shl (int16 x) {
696 int16 negc = (0 + (3 - -1));
697 int16 temp;
698 int16 result = 0;
699 int16 d;
701 for (;;) {
702 if (((x) == (negc))) {
703 result = norm (result, x);
704 break;
707 d = integer_lo (x);
708 x = integer_hi (x);
709 temp = negc;
710 int16 tmp = 1;
711 negc = negative_carry (d & (tmp<<15));
712 result = make_integer ((d << 1) | ((temp) == ((0 + (3 - -1))-1)), result);
715 return result;
718 int16 shift_left (int16 x, int16 n) {
721 if (((x) == ((0 + (3 - -1)))))
722 return x;
724 while (n & (16 -1)) {
725 x = shl (x);
726 n--;
729 while (n > 0) {
730 x = make_integer (0, x);
731 n -= 16;
734 return x;
737 int16 add (int16 x, int16 y) {
740 int16 negc = (0 + (3 - -1));
741 int16 result = 0;
742 int16 dx;
743 int16 dy;
745 for (;;) { // bb 2
746 if (((x) == (negc))) { // bbs 2 and 7
747 result = norm (result, y); // bb 6
748 break;
751 if (((y) == (negc))) { // bbs 5 and 10
752 result = norm (result, x); // bb 9
753 break;
756 dx = integer_lo (x); // bb 8
757 dy = integer_lo (y);
758 dx = dx + dy;
760 if (((negc) == ((0 + (3 - -1))))) // bbs 8 and 14
761 negc = negative_carry (dx < dy); // bbs 12, 15, 16, 17
762 else { // bb 13
763 dx++;
764 negc = negative_carry (dx <= dy); // bbs 13, 18, 19, 20
767 x = integer_hi (x); // bb 11
768 y = integer_hi (y);
770 result = make_integer (dx, result);
773 return result; // bb 4
776 int16 invert (int16 x) {
777 if (((x) == ((0 + (3 - -1)))))
778 return ((0 + (3 - -1))-1);
779 else
780 return (0 + (3 - -1));
783 int16 sub (int16 x, int16 y) {
785 int16 negc = ((0 + (3 - -1))-1);
786 int16 result_sub = 0; // TODO name changed
787 int16 dx_sub; // TODO changed
788 int16 dy_sub;
790 for (;;) { // bb 2
791 if (((x) == (negc)) // bbs 2 and 8
792 && (((y) == ((0 + (3 - -1)))) // bbs 7 and 10
793 || ((y) == (((0 + (3 - -1))-1))))) { // bbs 9 and 11
794 result_sub = norm (result_sub, invert (y)); // bb 6
795 break;
798 if (((y) == (invert (negc)))) { // bbs 5 and 14
799 result_sub = norm (result_sub, x); // bb 13
800 break;
803 dx_sub = integer_lo (x); // bb 12
804 dy_sub = ~integer_lo (y);
805 dx_sub = dx_sub + dy_sub;
807 if (((negc) == ((0 + (3 - -1))))) // bbs 12 and 18
808 negc = negative_carry (dx_sub < dy_sub); // bbs 16, 19, 20, 21
809 else { // bb 17, 22, 23, 24
810 dx_sub++;
811 negc = negative_carry (dx_sub <= dy_sub);
814 x = integer_hi (x); // bb 15
815 y = integer_hi (y);
817 result_sub = make_integer (dx_sub, result_sub);
820 return result_sub; // bb 4
823 int16 neg (int16 x) {
826 return sub ((0 + (3 - -1)), x);
829 int16 scale (int16 n, int16 x) {
832 int16 result;
833 int16 carry;
834 int32 m;
836 if ((n == 0) || ((x) == ((0 + (3 - -1)))))
837 return (0 + (3 - -1));
839 if (n == 1)
840 return x;
842 result = 0;
843 carry = 0;
845 for (;;) {
846 if (((x) == ((0 + (3 - -1))))){
847 if (carry <= 255)
848 result = norm (result, (carry + (3 - -1)));
849 else
850 result = norm (result, make_integer (carry, (0 + (3 - -1))));
851 break;
854 if (((x) == (((0 + (3 - -1))-1)))) {
855 carry = carry - n;
856 int16 tmp = 1;
857 if (carry >= ((tmp<<16) - 1)) // TODO -1 not a good literal
858 result = norm (result, ((carry & #xff) + (3 - -1)));
859 else
860 result = norm (result, make_integer (carry, ((0 + (3 - -1))-1)));
861 break;
864 int32 tmp1 = integer_lo (x);
865 m = tmp1 * n + carry;
867 x = integer_hi (x);
868 carry = m >> 16;
869 int16 tmp2 = m;
870 result = make_integer (tmp2, result);
873 return result;
876 int16 mulnonneg (int16 x, int16 y) {
880 int16 result = 0;
881 int16 s = scale (integer_lo (x), y);
883 for (;;) {
884 result = make_integer (integer_lo (s), result);
885 s = integer_hi (s);
886 x = integer_hi (x);
888 if (((x) == ((0 + (3 - -1)))))
889 break;
891 s = add (s, scale (integer_lo (x), y));
894 return norm (result, s);
898 int16 divnonneg (int16 x, int16 y) {
902 int16 result = (0 + (3 - -1)); // bb 0
903 int16 lx = integer_length (x);
904 int16 ly = integer_length (y);
906 if (lx >= ly) { // bb 0
907 lx = lx - ly; // bb 2
909 y = shift_left (y, lx);
911 do {
912 result = shl (result); // bb 3
913 if (cmp (x, y) >= 1) {
914 x = sub (x, y); // bb 7
915 result = add (((0 + (3 - -1))+1), result);
917 y = shr (y); // bb 6 ?
918 } while (lx-- != 0); // bbs 4 and 8
921 return result; // bb 1
924 int16 bitwise_ior (int16 x, int16 y) {
927 int16 result = 0;
929 for (;;){
930 if (((x) == ((0 + (3 - -1)))))
931 return norm(result, y);
932 if (((x) == (((0 + (3 - -1))-1))))
933 return norm(result, x);
934 result = make_integer(integer_lo(x) | integer_lo(y),
935 result);
936 x = integer_hi(x);
937 y = integer_hi(y);
941 int16 bitwise_xor (int16 x, int16 y) {
944 int16 result = 0;
946 for (;;){
947 if (((x) == ((0 + (3 - -1)))))
948 return norm(result, y);
949 if (((x) == (((0 + (3 - -1))-1))))
950 return norm(result, x);
951 result = make_integer(integer_lo(x) ^ integer_lo(y),
952 result);
953 x = integer_hi(x);
954 y = integer_hi(y);
960 int16 encode_int (int16 n) {
961 if (/* n >= -1 && */ n <= 255) { // TODO should be n >= -1, but -1 as a literal is not good. since only primitives (i.e. not the bignum code) uses it, shouldn't be a problem
962 return (n + (3 - -1)); // FOO if we go in this branch, instead of returning #f, returns a disgusting weird object, actually, only when comparing 2 ram vectors
965 return alloc_ram_cell_init (0, (0 + (3 - -1)), n >> 8, n);
967 void decode_2_int_args () {
968 a1 = decode_int (arg1);
969 a2 = decode_int (arg2);
976 void prim_numberp () {
977 if (arg1 >= 3
978 && arg1 <= (3 + (255 - -1)))
979 arg1 = 1;
980 else {
981 if ((!((arg1) >= 1280) && ((arg1) >= 512))){
982 arg1 = (ram_get_field0 (arg1) & #xc0) == 0;
984 else if ((!((arg1) >= 1280) && !(!((arg1) >= 1280) && ((arg1) >= 512)) && ((arg1) >= (3 +255 - -1 +1))))
985 arg1 = (rom_get_field0 (arg1) & #xc0) == 0;
986 else
987 arg1 = 0;
990 void prim_add () {
992 arg1 = add (arg1, arg2);
997 arg2 = 0;
1000 void prim_sub () {
1002 arg1 = sub (arg1, arg2);
1007 arg2 = 0;
1010 void prim_mul () {
1012 a1 = negp (arg1);
1013 a2 = negp (arg2);
1014 arg1 = mulnonneg (a1 ? neg(arg1) : arg1,
1015 a2 ? neg(arg2) : arg2);
1016 if (a1 + a2 == 1)
1017 arg1 = neg(arg1);
1022 arg2 = 0;
1025 void prim_div () {
1027 if (((arg2) == (((0) + (3 - -1)))))
1028 halt_with_error();
1029 a1 = negp (arg1);
1030 a2 = negp (arg2);
1031 arg1 = divnonneg (a1 ? neg(arg1) : arg1,
1032 a2 ? neg(arg2) : arg2);
1033 if (a1 + a2 == 1)
1034 arg1 = neg(arg1);
1041 arg2 = 0;
1044 void prim_rem () {
1046 if (((arg2) == (((0) + (3 - -1)))))
1047 halt_with_error();
1048 if (negp(arg1) || negp(arg2))
1049 halt_with_error();
1052 arg3 = divnonneg (arg1, arg2);
1053 arg4 = mulnonneg (arg2, arg3);
1054 arg1 = sub(arg1, arg4 );
1055 arg3 = 0;
1056 arg4 = 0;
1063 arg2 = 0;
1066 void prim_neg () {
1068 arg1 = neg (arg1);
1075 void prim_eq () {
1077 arg1 = ((cmp (arg1, arg2) == 1));
1082 arg2 = 0;
1085 void prim_lt () {
1087 arg1 = ((cmp (arg1, arg2) < 1));
1092 arg2 = 0;
1095 void prim_gt () {
1097 arg1 = ((cmp (arg1, arg2) > 1));
1102 arg2 = 0;
1105 void prim_leq () {
1107 arg1 = ((cmp (arg1, arg2) <= 1));
1112 arg2 = 0;
1116 void prim_geq () {
1118 arg1 = ((cmp (arg1, arg2) >= 1));
1123 arg2 = 0;
1126 void prim_ior () {
1128 arg1 = bitwise_ior(arg1, arg2);
1133 arg2 = 0;
1136 void prim_xor () {
1138 arg1 = bitwise_xor(arg1, arg2);
1143 arg2 = 0;
1152 void prim_pairp () {
1153 if ((!((arg1) >= 1280) && ((arg1) >= 512)))
1154 arg1 = (((((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == 0))));
1155 else if ((!((arg1) >= 1280) && !(!((arg1) >= 1280) && ((arg1) >= 512)) && ((arg1) >= (3 +255 - -1 +1))))
1156 arg1 = (((((rom_get_field0 (arg1) & #x80) == #x80) && ((rom_get_field2 (arg1) & #xe0) == 0))));
1157 else
1158 arg1 = 0;
1161 int16 cons (int16 car, int16 cdr) {
1162 return alloc_ram_cell_init (#x80 | (car >> 8),
1163 car & #xff,
1164 0 | (cdr >> 8),
1165 cdr & #xff);
1168 void prim_cons () {
1169 arg1 = cons (arg1, arg2);
1170 arg2 = 0;
1173 void prim_car () {
1174 if ((!((arg1) >= 1280) && ((arg1) >= 512))) {
1175 if (!(((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == 0)))
1176 halt_with_error();
1177 arg1 = ram_get_car (arg1);
1179 else if ((!((arg1) >= 1280) && !(!((arg1) >= 1280) && ((arg1) >= 512)) && ((arg1) >= (3 +255 - -1 +1)))) {
1180 if (!(((rom_get_field0 (arg1) & #x80) == #x80) && ((rom_get_field2 (arg1) & #xe0) == 0)))
1181 halt_with_error();
1182 arg1 = rom_get_car (arg1);
1184 else
1185 halt_with_error();
1188 void prim_cdr () {
1189 if ((!((arg1) >= 1280) && ((arg1) >= 512))) {
1190 if (!(((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == 0)))
1191 halt_with_error();
1192 arg1 = ram_get_cdr (arg1);
1194 else if ((!((arg1) >= 1280) && !(!((arg1) >= 1280) && ((arg1) >= 512)) && ((arg1) >= (3 +255 - -1 +1)))) {
1195 if (!(((rom_get_field0 (arg1) & #x80) == #x80) && ((rom_get_field2 (arg1) & #xe0) == 0)))
1196 halt_with_error();
1197 arg1 = rom_get_cdr (arg1);
1199 else
1200 halt_with_error();
1203 void prim_set_car () {
1204 if ((!((arg1) >= 1280) && ((arg1) >= 512))) {
1205 if (!(((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == 0)))
1206 halt_with_error();
1208 ram_set_car (arg1, arg2);
1209 arg1 = 0;
1210 arg2 = 0;
1212 else
1213 halt_with_error();
1216 void prim_set_cdr () {
1217 if ((!((arg1) >= 1280) && ((arg1) >= 512))) {
1218 if (!(((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == 0)))
1219 halt_with_error();
1221 ram_set_cdr (arg1, arg2);
1222 arg1 = 0;
1223 arg2 = 0;
1225 else
1226 halt_with_error();
1229 void prim_nullp () {
1230 arg1 = ((arg1 == 2));
1237 void prim_u8vectorp () {
1238 if ((!((arg1) >= 1280) && ((arg1) >= 512)))
1239 arg1 = (((((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == #x60))));
1240 else if ((!((arg1) >= 1280) && !(!((arg1) >= 1280) && ((arg1) >= 512)) && ((arg1) >= (3 +255 - -1 +1))))
1241 arg1 = (((((rom_get_field0 (arg1) & #x80) == #x80) && ((rom_get_field2 (arg1) & #xe0) == #x60))));
1242 else
1243 arg1 = 0;
1246 void prim_make_u8vector () {
1247 decode_2_int_args ();
1249 if (a2 > 255)
1250 halt_with_error();
1252 arg3 = alloc_vec_cell (a1);
1253 arg1 = alloc_ram_cell_init (#x80 | (a1 >> 8),
1254 a1 & #xff, #x60 | (arg3 >> 8),
1255 arg3 & #xff);
1257 a1 = (a1 + 3) >> 2;
1258 while (a1--) {
1259 ram_set_field0 (arg3, a2);
1260 ram_set_field1 (arg3, a2);
1261 ram_set_field2 (arg3, a2);
1262 ram_set_field3 (arg3, a2);
1263 arg3++;
1267 void prim_u8vector_ref () {
1268 a2 = decode_int (arg2);
1270 if ((!((arg1) >= 1280) && ((arg1) >= 512))) {
1271 if (!(((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == #x60)))
1272 halt_with_error();
1273 if ((ram_get_car (arg1) <= a2) || (a2 < 0))
1274 halt_with_error();
1275 arg1 = ram_get_cdr (arg1);
1277 else if ((!((arg1) >= 1280) && !(!((arg1) >= 1280) && ((arg1) >= 512)) && ((arg1) >= (3 +255 - -1 +1)))) {
1278 if (!(((rom_get_field0 (arg1) & #x80) == #x80) && ((rom_get_field2 (arg1) & #xe0) == #x60)))
1279 halt_with_error();
1280 if ((rom_get_car (arg1) <= a2) || (a2 < 0))
1281 halt_with_error();
1282 arg1 = rom_get_cdr (arg1);
1284 else
1285 halt_with_error();
1287 if (((arg1) >= 1280)) {
1288 arg1 += (a2 >> 2);
1289 a2 %= 4;
1291 arg1 = encode_int (ram_get_fieldn (arg1, a2));
1293 else {
1294 while (a2--)
1295 arg1 = rom_get_cdr (arg1);
1298 arg1 = rom_get_car (arg1);
1301 arg2 = 0;
1302 arg3 = 0;
1303 arg4 = 0;
1306 void prim_u8vector_set () {
1307 a2 = decode_int (arg2);
1308 a3 = decode_int (arg3);
1310 if (a3 > 255)
1311 halt_with_error();
1313 if ((!((arg1) >= 1280) && ((arg1) >= 512))) {
1314 if (!(((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == #x60)))
1315 halt_with_error();
1316 if ((ram_get_car (arg1) <= a2) || (a2 < 0))
1317 halt_with_error();
1318 arg1 = ram_get_cdr (arg1);
1320 else
1321 halt_with_error();
1323 arg1 += (a2 >> 2);
1324 a2 %= 4;
1326 ram_set_fieldn (arg1, a2, a3);
1328 arg1 = 0;
1329 arg2 = 0;
1330 arg3 = 0;
1333 void prim_u8vector_length () {
1334 if ((!((arg1) >= 1280) && ((arg1) >= 512))) {
1335 if (!(((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == #x60)))
1336 halt_with_error();
1337 arg1 = encode_int (ram_get_car (arg1));
1339 else if ((!((arg1) >= 1280) && !(!((arg1) >= 1280) && ((arg1) >= 512)) && ((arg1) >= (3 +255 - -1 +1)))) {
1340 if (!(((rom_get_field0 (arg1) & #x80) == #x80) && ((rom_get_field2 (arg1) & #xe0) == #x60)))
1341 halt_with_error();
1342 arg1 = encode_int (rom_get_car (arg1));
1344 else
1345 halt_with_error();
1348 void prim_u8vector_copy () {
1352 a1 = decode_int (arg2);
1353 a2 = decode_int (arg4);
1354 a3 = decode_int (arg5);
1357 if ((!((arg1) >= 1280) && ((arg1) >= 512)) && (!((arg3) >= 1280) && ((arg3) >= 512))) {
1358 if (!(((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == #x60)) || !(((ram_get_field0 (arg3) & #x80) == #x80) && ((ram_get_field2 (arg3) & #xe0) == #x60)))
1359 halt_with_error();
1360 if ((ram_get_car (arg1) < (a1 + a3)) || (a1 < 0) ||
1361 (ram_get_car (arg3) < (a2 + a3)) || (a2 < 0))
1362 halt_with_error();
1365 arg1 = ram_get_cdr (arg1);
1366 arg1 += (a1 >> 2);
1367 a1 %= 4;
1368 arg3 = ram_get_cdr (arg3);
1369 arg3 += (a2 >> 2);
1370 a2 %= 4;
1373 while (a3--) {
1374 ram_set_fieldn (arg3, a2, ram_get_fieldn (arg1, a1));
1376 a1++;
1377 arg1 += (a1 >> 2);
1378 a1 %= 4;
1379 a2++;
1380 arg3 += (a2 >> 2);
1381 a2 %= 4;
1385 else if ((!((arg1) >= 1280) && !(!((arg1) >= 1280) && ((arg1) >= 512)) && ((arg1) >= (3 +255 - -1 +1))) && (!((arg3) >= 1280) && ((arg3) >= 512))) {
1386 if (!(((rom_get_field0 (arg1) & #x80) == #x80) && ((rom_get_field2 (arg1) & #xe0) == #x60)) || !(((ram_get_field0 (arg3) & #x80) == #x80) && ((ram_get_field2 (arg3) & #xe0) == #x60)))
1387 halt_with_error();
1388 if ((rom_get_car (arg1) < (a1 + a3)) || (a1 < 0) ||
1389 (ram_get_car (arg3) < (a2 + a3)) || (a2 < 0))
1390 halt_with_error();
1392 arg1 = rom_get_cdr (arg1);
1393 while (a1--)
1394 arg1 = rom_get_cdr (arg1);
1396 arg3 = ram_get_cdr (arg3);
1397 arg3 += (a2 >> 2);
1398 a2 %= 4;
1400 while (a3--) {
1401 ram_set_fieldn (arg3, a2, decode_int (rom_get_car (arg1)));
1403 arg1 = rom_get_cdr (arg1);
1404 a2++;
1405 arg3 += (a2 >> 2);
1406 a2 %= 4;
1409 else
1410 halt_with_error();
1412 arg1 = 0;
1413 arg2 = 0;
1414 arg3 = 0;
1415 arg4 = 0;
1416 arg5 = 0;
1423 void prim_eqp () {
1424 arg1 = ((arg1 == arg2));
1425 arg2 = 0;
1428 void prim_not () {
1429 arg1 = ((arg1 == 0));
1432 void prim_symbolp () {
1433 if ((!((arg1) >= 1280) && ((arg1) >= 512)))
1434 arg1 = (((((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == #x20))));
1435 else if ((!((arg1) >= 1280) && !(!((arg1) >= 1280) && ((arg1) >= 512)) && ((arg1) >= (3 +255 - -1 +1))))
1436 arg1 = (((((rom_get_field0 (arg1) & #x80) == #x80) && ((rom_get_field2 (arg1) & #xe0) == #x20))));
1437 else
1438 arg1 = 0;
1441 void prim_stringp () {
1442 if ((!((arg1) >= 1280) && ((arg1) >= 512)))
1443 arg1 = (((((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == #x40))));
1444 else if ((!((arg1) >= 1280) && !(!((arg1) >= 1280) && ((arg1) >= 512)) && ((arg1) >= (3 +255 - -1 +1))))
1445 arg1 = (((((rom_get_field0 (arg1) & #x80) == #x80) && ((rom_get_field2 (arg1) & #xe0) == #x40))));
1446 else
1447 arg1 = 0;
1450 void prim_string2list () {
1451 if ((!((arg1) >= 1280) && ((arg1) >= 512))) {
1452 if (!(((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == #x40)))
1453 halt_with_error();
1455 arg1 = ram_get_car (arg1);
1457 else if ((!((arg1) >= 1280) && !(!((arg1) >= 1280) && ((arg1) >= 512)) && ((arg1) >= (3 +255 - -1 +1)))) {
1458 if (!(((rom_get_field0 (arg1) & #x80) == #x80) && ((rom_get_field2 (arg1) & #xe0) == #x40)))
1459 halt_with_error();
1461 arg1 = rom_get_car (arg1);
1463 else
1464 halt_with_error();
1467 void prim_list2string () {
1468 arg1 = alloc_ram_cell_init (#x80 | ((arg1 & #x1f00) >> 8),
1469 arg1 & #xff, #x40,
1473 void prim_booleanp () {
1474 arg1 = ((arg1 < 2));
1481 void prim_print () {
1486 arg1 = 0;
1489 int32 read_clock () {
1490 int32 now = 0;
1493 /* now = from_now( 0 ); */ // TODO
1494 return now;
1497 void prim_clock () {
1498 arg1 = encode_int (read_clock ());
1501 void prim_motor () {
1502 decode_2_int_args ();
1504 if (a1 < 1 || a1 > 2 || a2 < -100 || a2 > 100)
1505 halt_with_error();
1508 /* MOTOR_set( a1, a2 ); */ // TODO
1516 arg1 = 0;
1517 arg2 = 0;
1521 void prim_led () {
1522 decode_2_int_args ();
1523 a3 = decode_int (arg3);
1525 if (a1 < 1 || a1 > 3 || a2 < 0 || a3 < 0)
1526 halt_with_error();
1529 /* LED_set( a1, a2, a3 ); */ // TODO
1537 arg1 = 0;
1538 arg2 = 0;
1539 arg3 = 0;
1543 void prim_led2_color () {
1544 a1 = decode_int (arg1);
1546 if (a1 < 0 || a1 > 1)
1547 halt_with_error();
1550 /* LED2_color_set( a1 ); */ // TODO
1558 arg1 = 0;
1562 void prim_getchar_wait () {
1563 decode_2_int_args();
1564 a1 = read_clock () + a1;
1566 if (a1 < 0 || a2 < 1 || a2 > 3)
1567 halt_with_error();
1570 arg1 = 0;
1571 /* { */ // TODO
1572 /* serial_port_set ports; */
1573 /* ports = serial_rx_wait_with_timeout( a2, a1 ); */
1574 /* if (ports != 0) */
1575 /* arg1 = encode_int (serial_rx_read( ports )); */
1576 /* } */
1580 void prim_putchar () {
1581 decode_2_int_args ();
1583 if (a1 < 0 || a1 > 255 || a2 < 1 || a2 > 3)
1584 halt_with_error();
1587 /* serial_tx_write( a2, a1 ); */ // TODO
1588 uart_write(a1);
1595 arg1 = 0;
1596 arg2 = 0;
1600 void prim_beep () {
1601 decode_2_int_args ();
1603 if (a1 < 1 || a1 > 255 || a2 < 0)
1604 halt_with_error();
1607 /* beep( a1, from_now( a2 ) ); */
1615 arg1 = 0;
1616 arg2 = 0;
1620 void prim_adc () {
1621 int16 x;
1623 a1 = decode_int (arg1);
1625 if (a1 < 1 || a1 > 3)
1626 halt_with_error();
1629 /* x = adc( a1 ); */
1630 arg1 = encode_int (x);
1633 void prim_sernum () {
1634 int16 x;
1637 /* x = serial_num (); */
1644 arg1 = encode_int (x);
1651 void prim_network_init () {
1659 void prim_network_cleanup () {
1665 void prim_receive_packet_to_u8vector () {
1667 if (!(((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == #x60)))
1668 halt_with_error();
1671 void prim_send_packet_from_u8vector () {
1675 if (!(((ram_get_field0 (arg1) & #x80) == #x80) && ((ram_get_field2 (arg1) & #xe0) == #x60)))
1676 halt_with_error();
1678 a2 = decode_int (arg2);
1679 a1 = 0;
1682 if (ram_get_car (arg1) < a2)
1683 halt_with_error();
1685 arg1 = ram_get_cdr (arg1);
1686 arg2 = 0;
1689 /* void push_arg1 (); */
1690 /* int16 pop (); */
1691 /* void pop_procedure (); */
1692 /* void handle_arity_and_rest_param (); */
1693 /* void build_env (); */
1694 /* void save_cont (); */
1695 /* void interpreter (); */
1697 void push_arg1 () {
1698 env = cons (arg1, env);
1699 arg1 = 0;
1702 int16 pop () {
1703 int16 o = ram_get_car (env);
1704 env = ram_get_cdr (env);
1705 return o;
1708 void pop_procedure () {
1709 arg1 = pop();
1711 if ((!((arg1) >= 1280) && ((arg1) >= 512))) {
1712 if (!((ram_get_field0 (arg1) & #xc0) == #x40))
1713 halt_with_error();
1715 entry = ram_get_entry (arg1) + #x8000;
1717 else if ((!((arg1) >= 1280) && !(!((arg1) >= 1280) && ((arg1) >= 512)) && ((arg1) >= (3 +255 - -1 +1)))) {
1718 if (!((rom_get_field0 (arg1) & #xc0) == #x40))
1719 halt_with_error();
1721 entry = rom_get_entry (arg1) + #x8000;
1723 else
1724 halt_with_error();
1727 void handle_arity_and_rest_param () {
1728 int8 np;
1730 np = rom_get (entry++);
1732 if ((np & #x80) == 0) {
1733 if (na != np)
1734 halt_with_error();
1736 else {
1737 np = ~np;
1739 if (na < np)
1740 halt_with_error();
1742 arg3 = 2;
1744 while (na > np) {
1745 arg4 = pop();
1747 arg3 = cons (arg4, arg3);
1748 arg4 = 0;
1750 na--;
1753 arg1 = cons (arg3, arg1);
1754 arg3 = 0;
1758 void build_env () {
1759 while (na != 0) {
1760 arg3 = pop();
1762 arg1 = cons (arg3, arg1);
1764 na--;
1767 arg3 = 0;
1770 void save_cont () {
1772 arg3 = alloc_ram_cell_init (#x40 | (pc >> 11),
1773 (pc >> 3) & #xff,
1774 ((pc & #x0007) << 5) | (env >> 8),
1775 env & #xff);
1776 cont = alloc_ram_cell_init (#x80 | (cont >> 8),
1777 cont & #xff, #x80 | (arg3 >> 8),
1778 arg3 & #xff);
1779 arg3 = 0;
1782 void init_ram_heap () {
1783 int8 i;
1784 int16 o = 1279;
1786 free_list = 0;
1788 int16 tmp = (512 + ((glovars + 1) >> 1)); // TODO optimization
1789 while (o > tmp) {
1792 ram_set_gc_tags (o, (0<<5));
1793 ram_set_car (o, free_list);
1794 free_list = o;
1795 o--;
1798 free_list_vec = 1280;
1799 ram_set_car (free_list_vec, 0);
1803 ram_set_cdr (free_list_vec, ((2047 - 1280 + 1)*4) >> 2);
1805 for (i=0; i<glovars; i++)
1806 set_global (i, 0);
1808 arg1 = 0;
1809 arg2 = 0;
1810 arg3 = 0;
1811 arg4 = 0;
1812 cont = 0;
1813 env = 2;
1817 void interpreter () {
1818 int16 tmp = rom_get (#x8000 +2);
1819 pc = (#x8000 + 4) + (tmp << 2);
1821 glovars = rom_get (#x8000 +3);
1823 init_ram_heap ();
1825 dispatch: ;
1826 bytecode = rom_get (pc++);
1827 bytecode_hi4 = bytecode & #xf0;
1828 bytecode_lo4 = bytecode & #x0f;
1829 switch (bytecode_hi4 >> 4) {;
1832 case 0: // push-constant // TODO used to be #x00 >> 4
1836 arg1 = bytecode_lo4;
1838 push_arg1 ();
1840 ; goto dispatch;;
1843 case 1:;; // push-constant
1846 arg1 = bytecode_lo4+16;
1848 push_arg1 ();
1850 ; goto dispatch;;
1853 case 2:;; // push-stack
1857 arg1 = env;
1859 while (bytecode_lo4 != 0) {
1860 arg1 = ram_get_cdr (arg1);
1861 bytecode_lo4--;
1864 arg1 = ram_get_car (arg1);
1866 push_arg1 ();
1868 ; goto dispatch;;
1871 case 3:;; // push-stack
1875 bytecode_lo4 += 16;
1877 arg1 = env;
1879 while (bytecode_lo4 != 0) {
1880 arg1 = ram_get_cdr (arg1);
1881 bytecode_lo4--;
1884 arg1 = ram_get_car (arg1);
1886 push_arg1 ();
1888 ; goto dispatch;;
1891 case 4:;; // push-global
1895 arg1 = get_global (bytecode_lo4);
1897 push_arg1 ();
1899 ; goto dispatch;;
1902 case 5:;; // set-global
1906 set_global (bytecode_lo4, pop());
1908 ; goto dispatch;;
1911 case 6:;; // call
1915 na = bytecode_lo4;
1917 pop_procedure ();
1918 handle_arity_and_rest_param ();
1919 build_env ();
1920 save_cont ();
1922 env = arg1;
1923 pc = entry;
1925 arg1 = 0;
1927 ; goto dispatch;;
1930 case 7:;; // jump
1934 na = bytecode_lo4;
1936 pop_procedure ();
1937 handle_arity_and_rest_param ();
1938 build_env ();
1940 env = arg1;
1941 pc = entry;
1943 arg1 = 0;
1945 ; goto dispatch;;
1948 case 8:;;
1950 switch (bytecode_lo4) {
1951 case 0: // call-toplevel
1952 bytecode = rom_get (pc++);
1953 arg2 = bytecode;
1955 bytecode = rom_get (pc++);
1960 entry = (arg2 << 8) + bytecode + #x8000;
1961 arg1 = 2;
1963 na = rom_get (entry++);
1965 build_env ();
1966 save_cont ();
1968 env = arg1;
1969 pc = entry;
1971 arg1 = 0;
1972 arg2 = 0;
1974 break;
1976 case 1: // jump-toplevel
1977 bytecode = rom_get (pc++);
1978 arg2 = bytecode;
1980 bytecode = rom_get (pc++);
1985 entry = (arg2 << 8) + bytecode + #x8000;
1986 arg1 = 2;
1988 na = rom_get (entry++);
1990 build_env ();
1992 env = arg1;
1993 pc = entry;
1995 arg1 = 0;
1996 arg2 = 0;
1998 break;
2000 case 2: // goto
2001 bytecode = rom_get (pc++);
2002 arg2 = bytecode;
2004 bytecode = rom_get (pc++);
2009 pc = (arg2 << 8) + bytecode + #x8000;
2011 break;
2013 case 3: // goto-if-false
2014 bytecode = rom_get (pc++);
2015 arg2 = bytecode;
2017 bytecode = rom_get (pc++);
2022 if (pop() == 0)
2023 pc = (arg2 << 8) + bytecode + #x8000;
2025 break;
2027 case 4: // closure
2028 bytecode = rom_get (pc++);
2029 arg2 = bytecode;
2031 bytecode = rom_get (pc++);
2035 arg3 = pop();
2037 entry = (arg2 << 8) | bytecode;
2039 int16 tmp = (bytecode & #x07);
2040 arg1 = alloc_ram_cell_init (#x40 | (arg2 >> 3),
2041 ((arg2 & #x07) << 5) | (bytecode >> 3),
2042 (tmp << 5) |((arg3 &#x1f00) >>8),
2043 arg3 & #xff);
2045 push_arg1 ();
2047 arg2 = 0;
2048 arg3 = 0;
2050 break;
2052 /* case 5: */ // TODO useless, they don't work in the regular PICOBIT
2053 /* bytecode = rom_get (pc++); */
2055 /* ; */
2058 /* entry = pc + bytecode + #x8000; */
2059 /* arg1 = 2; */
2061 /* na = rom_get (entry++); */
2063 /* build_env (); */
2064 /* save_cont (); */
2066 /* env = arg1; */
2067 /* pc = entry; */
2069 /* arg1 = 0; */
2071 /* break; */
2073 /* case 6: */
2074 /* bytecode = rom_get (pc++); */
2076 /* ; */
2079 /* entry = pc + bytecode + #x8000; */
2080 /* arg1 = 2; */
2082 /* na = rom_get (entry++); */
2084 /* build_env (); */
2086 /* env = arg1; */
2087 /* pc = entry; */
2089 /* arg1 = 0; */
2091 /* break; */
2093 /* case 7: */
2094 /* bytecode = rom_get (pc++); */
2096 /* ; */
2098 /* pc = pc + bytecode + #x8000; */
2100 /* break; */
2102 /* case 8: */
2103 /* bytecode = rom_get (pc++); */
2105 /* ; */
2108 /* if (pop() == 0) */
2109 /* pc = pc + bytecode + #x8000; */
2111 /* break; */
2113 /* case 9: */
2114 /* bytecode = rom_get (pc++); */
2116 /* ; */
2118 /* arg3 = pop(); */
2120 /* entry = pc + bytecode; */
2122 /* arg1 = alloc_ram_cell_init (#x40 | (arg2 >> 3), */
2123 /* ((arg2 & #x07) << 5) | (bytecode >> 3), */
2124 /* ((bytecode &#x07) <<5) |((arg3 &#x1f00) >>8), */
2125 /* arg3 & #xff); */
2127 /* push_arg1 (); */
2129 /* arg3 = 0; */
2131 /* break; */
2132 case 14: // push-global [long]
2133 bytecode = rom_get (pc++);
2137 arg1 = get_global (bytecode);
2139 push_arg1 ();
2141 break;
2143 case 15: // set-global [long]
2144 bytecode = rom_get (pc++);
2148 set_global (bytecode, pop());
2150 break;
2153 ; goto dispatch;;
2156 case 9:;; // push-constant [long]
2160 bytecode = rom_get (pc++);
2164 int16 tmp = bytecode_lo4; // TODO ugly patch. not needed with gcc since the 8 is an int, and would make all the other operands ints, whereas we keep using int8, and truncate the value
2165 arg1 = (tmp << 8) | bytecode;
2166 push_arg1 ();
2168 ; goto dispatch;;
2171 case 10:;;
2173 ; goto dispatch;;
2176 case 11:;;
2178 ; goto dispatch;;
2181 case 12:;;
2185 switch (bytecode_lo4) {
2186 case 0:
2187 arg1 = pop(); prim_numberp (); push_arg1 (); break;
2188 case 1:
2189 arg2 = pop(); arg1 = pop(); prim_add (); push_arg1 (); break;
2190 case 2:
2191 arg2 = pop(); arg1 = pop(); prim_sub (); push_arg1 (); break;
2192 case 3:
2193 arg2 = pop(); arg1 = pop(); prim_mul (); push_arg1 (); break;
2194 case 4:
2195 arg2 = pop(); arg1 = pop(); prim_div (); push_arg1 (); break;
2196 case 5:
2197 arg2 = pop(); arg1 = pop(); prim_rem (); push_arg1 (); break;
2198 case 6:
2199 arg1 = pop(); prim_neg (); push_arg1 (); break;
2200 case 7:
2201 arg2 = pop(); arg1 = pop(); prim_eq (); push_arg1 (); break;
2202 case 8:
2203 arg2 = pop(); arg1 = pop(); prim_lt (); push_arg1 (); break;
2204 case 9:
2205 arg2 = pop(); arg1 = pop(); prim_leq (); push_arg1 (); break;
2206 case 10:
2207 arg2 = pop(); arg1 = pop(); prim_gt (); push_arg1 (); break;
2208 case 11:
2209 arg2 = pop(); arg1 = pop(); prim_geq (); push_arg1 (); break;
2210 case 12:
2211 arg1 = pop(); prim_pairp (); push_arg1 (); break;
2212 case 13:
2213 arg2 = pop(); arg1 = pop(); prim_cons (); push_arg1 (); break;
2214 case 14:
2215 arg1 = pop(); prim_car (); push_arg1 (); break;
2216 case 15:
2217 arg1 = pop(); prim_cdr (); push_arg1 (); break;
2220 ; goto dispatch;;
2223 case 13:;;
2227 switch (bytecode_lo4) {
2228 case 0:
2229 arg2 = pop(); arg1 = pop(); prim_set_car (); break;
2230 case 1:
2231 arg2 = pop(); arg1 = pop(); prim_set_cdr (); break;
2232 case 2:
2233 arg1 = pop(); prim_nullp (); push_arg1 (); break;
2234 case 3:
2235 arg2 = pop(); arg1 = pop(); prim_eqp (); push_arg1 (); break;
2236 case 4:
2237 arg1 = pop(); prim_not (); push_arg1 (); break;
2238 case 5: // get-cont
2240 arg1 = cont;
2241 push_arg1 ();
2242 break;
2243 case 6: // graft-to-cont
2246 arg1 = pop();
2247 cont = pop();
2249 push_arg1 ();
2251 na = 0;
2253 pop_procedure ();
2254 handle_arity_and_rest_param ();
2255 build_env ();
2257 env = arg1;
2258 pc = entry;
2260 arg1 = 0;
2262 break;
2263 case 7: // return-to-cont
2266 arg1 = pop();
2267 cont = pop();
2269 arg2 = ram_get_cdr (cont);
2271 pc = ram_get_entry (arg2);
2273 env = ram_get_cdr (arg2);
2274 cont = ram_get_car (cont);
2276 push_arg1 ();
2277 arg2 = 0;
2279 break;
2280 case 8: // halt
2282 return;
2283 case 9:
2285 arg1 = pop(); prim_symbolp (); push_arg1 (); break;
2286 case 10:
2288 arg1 = pop(); prim_stringp (); push_arg1 (); break;
2289 case 11:
2291 arg1 = pop(); prim_string2list (); push_arg1 (); break;
2292 case 12:
2294 arg1 = pop(); prim_list2string (); push_arg1 (); break;
2295 case 13:
2297 arg2 = pop(); arg1 = pop(); prim_make_u8vector (); push_arg1 (); break;
2298 case 14:
2300 arg2 = pop(); arg1 = pop(); prim_u8vector_ref (); push_arg1 (); break;
2301 case 15:
2303 arg3 = pop(); arg2 = pop(); arg1 = pop(); prim_u8vector_set (); break;
2306 ; goto dispatch;;
2309 case 14:;;
2313 switch (bytecode_lo4) {
2314 case 0:
2316 arg1 = pop();
2317 prim_print ();
2318 break;
2319 case 1:
2321 prim_clock (); push_arg1 (); break;
2322 case 2:
2324 arg2 = pop(); arg1 = pop(); prim_motor (); break;
2325 case 3:
2327 arg3 = pop(); arg2 = pop(); arg1 = pop(); prim_led (); ;break;
2328 case 4:
2330 arg1 = pop(); prim_led2_color (); break;
2331 case 5:
2333 arg2 = pop(); arg1 = pop(); prim_getchar_wait (); push_arg1 (); break;
2334 case 6:
2336 arg2 = pop(); arg1 = pop(); prim_putchar (); break;
2337 case 7:
2339 arg2 = pop(); arg1 = pop(); prim_beep (); break;
2340 case 8:
2342 arg1 = pop(); prim_adc (); push_arg1 (); break;
2343 case 9:
2345 arg1 = pop(); prim_u8vectorp (); push_arg1 (); break;
2346 case 10:
2348 prim_sernum (); push_arg1 (); break;
2349 case 11:
2351 arg1 = pop(); prim_u8vector_length (); push_arg1 (); break;
2352 case 12:
2354 arg5 = pop(); arg4 = pop(); arg3 = pop(); arg2 = pop(); arg1 = pop();
2355 prim_u8vector_copy (); break;
2356 break;
2357 case 13: // shift
2359 arg1 = pop();
2360 pop();
2361 push_arg1 ();
2362 break;
2363 case 14: // pop
2365 pop();
2366 break;
2367 case 15: // return
2369 arg1 = pop();
2370 arg2 = ram_get_cdr (cont);
2371 pc = ram_get_entry (arg2);
2372 env = ram_get_cdr (arg2);
2373 cont = ram_get_car (cont);
2374 push_arg1 ();
2375 arg2 = 0;
2376 break;
2379 ; goto dispatch;;
2383 case 15:;;
2387 switch (bytecode_lo4) {
2388 case 0:
2390 arg1 = pop(); prim_booleanp (); push_arg1 (); break;
2391 case 1:
2393 prim_network_init (); break;
2394 case 2:
2396 prim_network_cleanup (); break;
2397 case 3:
2399 arg1 = pop(); prim_receive_packet_to_u8vector (); push_arg1 (); break;
2400 case 4:
2402 arg2 = pop(); arg1 = pop(); prim_send_packet_from_u8vector ();
2403 push_arg1 (); break;
2404 case 5:
2405 arg2 = pop(); arg1 = pop(); prim_ior (); push_arg1 (); break;
2406 break;
2407 case 6:
2408 arg2 = pop(); arg1 = pop(); prim_xor (); push_arg1 (); break;
2409 break;
2412 ; goto dispatch;;
2419 interpreter();