Reworked the branch instructions of the VM, and changed code
[picobit.git] / picobit-vm.h
blob3bdd3ee03fdf9aae60cb4b924a95373462db9c9c
1 /* file: "picobit-vm.h" */
3 /*
4 * Copyright 2004-2009 by Marc Feeley and Vincent St-Amour, All Rights Reserved.
5 */
7 #ifndef PICOBIT_VM_H
8 #define PICOBIT_VM_H
10 #define DEBUG_not
11 #define DEBUG_GC_not
12 #define INFINITE_PRECISION_BIGNUMS
14 /*---------------------------------------------------------------------------*/
16 // types
18 #ifndef SIXPIC
19 // these types are already defined in SIXPIC
20 typedef char int8;
21 typedef short int16;
22 typedef long int32;
23 typedef unsigned char uint8;
24 typedef unsigned short uint16;
25 typedef unsigned long uint32;
26 #endif
28 typedef uint8 word;
30 typedef uint16 ram_addr;
31 typedef uint16 rom_addr;
33 // pointers are 13 bits
34 typedef uint16 obj;
36 /*---------------------------------------------------------------------------*/
38 // environment
40 #ifdef PICOBOARD2
41 #define ROBOT
42 #endif
44 #ifdef HI_TECH_C
45 #define ROBOT
46 #endif
48 #ifdef MCC18
49 #define ROBOT
50 #endif
52 #ifdef SIXPIC
53 #define ROBOT
54 #endif
56 #ifndef ROBOT
57 #define WORKSTATION
58 #endif
61 #ifdef HI_TECH_C
63 #include <pic18.h>
65 static volatile near uint8 FW_VALUE_UP @ 0x33;
66 static volatile near uint8 FW_VALUE_HI @ 0x33;
67 static volatile near uint8 FW_VALUE_LO @ 0x33;
69 #define ACTIVITY_LED1_LAT LATB
70 #define ACTIVITY_LED1_BIT 5
71 #define ACTIVITY_LED2_LAT LATB
72 #define ACTIVITY_LED2_BIT 4
73 static volatile near bit ACTIVITY_LED1 @ ((unsigned)&ACTIVITY_LED1_LAT*8)+ACTIVITY_LED1_BIT;
74 static volatile near bit ACTIVITY_LED2 @ ((unsigned)&ACTIVITY_LED2_LAT*8)+ACTIVITY_LED2_BIT;
76 #endif
79 #ifdef WORKSTATION
81 #include <stdio.h>
82 #include <stdlib.h>
84 #ifdef NETWORKING
85 #include <pcap.h>
86 #define MAX_PACKET_SIZE BUFSIZ
87 #define PROMISC 1
88 #define TO_MSEC 1
89 char errbuf[PCAP_ERRBUF_SIZE];
90 pcap_t *handle;
91 #define INTERFACE "eth0"
92 char buf [MAX_PACKET_SIZE]; // buffer for writing
93 #endif
95 #ifdef _WIN32
97 #include <sys/types.h>
98 #include <sys/timeb.h>
99 #include <conio.h>
101 #else
103 #include <sys/time.h>
105 #endif
107 #endif
109 /*---------------------------------------------------------------------------*/
111 // miscellaneous definitions
112 // TODO put at the end ?
114 // TODO these 2 are only used in negp, use them elsewhere ?
115 #define true 1
116 #define false 0
118 #define CODE_START 0x8000
120 /*---------------------------------------------------------------------------*/
122 // debugging
124 #ifdef DEBUG
125 #define IF_TRACE(x) x
126 #define IF_GC_TRACE(x) x
127 #else
128 #define IF_TRACE(x)
129 #define IF_GC_TRACE(x)
130 #endif
132 /*---------------------------------------------------------------------------*/
134 // error handling
136 #ifdef HI_TECH_C
137 void halt_with_error () {while(1);}
138 #endif
140 #ifdef WORKSTATION
141 #define ERROR(prim, msg) error (prim, msg)
142 #define TYPE_ERROR(prim, type) type_error (prim, type)
143 void error (char *prim, char *msg);
144 void type_error (char *prim, char *type);
145 #else
146 #define ERROR(prim, msg) halt_with_error()
147 #define TYPE_ERROR(prim, type) halt_with_error()
148 #endif
150 /*---------------------------------------------------------------------------*/
152 // address space layout
153 // TODO document each zone, also explain that since vector space is in ram, it uses the ram primitives
155 #define MAX_VEC_ENCODING 2047
156 #define MIN_VEC_ENCODING 1280
157 #define VEC_BYTES ((MAX_VEC_ENCODING - MIN_VEC_ENCODING + 1)*4)
158 // if the pic has less than 8k of memory, start vector space lower
160 #define MAX_RAM_ENCODING 1279
161 #define MIN_RAM_ENCODING 512
162 #define RAM_BYTES ((MAX_RAM_ENCODING - MIN_RAM_ENCODING + 1)*4)
164 #define MIN_FIXNUM_ENCODING 3
165 #define MIN_FIXNUM -1
166 #define MAX_FIXNUM 255
167 #define MIN_ROM_ENCODING (MIN_FIXNUM_ENCODING + MAX_FIXNUM - MIN_FIXNUM + 1)
169 #ifdef LESS_MACROS
170 uint16 OBJ_TO_RAM_ADDR(uint16 o, uint8 f) {return ((((o) - MIN_RAM_ENCODING) << 2) + (f));}
171 uint16 OBJ_TO_ROM_ADDR(uint16 o, uint8 f) {return ((((o) - MIN_ROM_ENCODING) << 2) + (CODE_START + 4 + (f)));}
172 #else
173 #define OBJ_TO_RAM_ADDR(o,f) ((((o) - MIN_RAM_ENCODING) << 2) + (f))
174 #define OBJ_TO_ROM_ADDR(o,f) ((((o) - MIN_ROM_ENCODING) << 2) + (CODE_START + 4 + (f)))
175 #endif
177 #ifdef SIXPIC
178 #ifdef LESS_MACROS
179 uint8 ram_get(uint16 a) { return *(a+0x200); }
180 void ram_set(uint16 a, uint8 x) { *(a+0x200) = (x); }
181 #else
182 #define ram_get(a) *(a+0x200)
183 #define ram_set(a,x) *(a+0x200) = (x)
184 #endif
185 #endif
187 #ifdef MCC18
188 #ifdef LESS_MACROS
189 uint8 ram_get(uint16 a) {return *(uint8*)(a+0x200);}
190 void ram_set(uint16 a, uint8 x) {*(uint8*)(a+0x200) = (x);}
191 #else
192 #define ram_get(a) *(uint8*)(a+0x200)
193 #define ram_set(a,x) *(uint8*)(a+0x200) = (x)
194 #endif
195 #endif
197 #ifdef HI_TECH_C
198 // cannot be a macro
199 uint8 ram_get(uint16 a) {
200 uint8 *p = a+0x200;
201 return *p;
203 void ram_set(uint16 a, uint8 x) {
204 uint8 *p = a+0x200;
205 *p = x;
207 #endif
209 #ifdef WORKSTATION
210 uint8 ram_mem[RAM_BYTES + VEC_BYTES];
211 #define ram_get(a) ram_mem[a]
212 #define ram_set(a,x) ram_mem[a] = (x)
213 #endif
215 #ifdef MCC18
216 uint8 rom_get (rom_addr a){
217 return *(rom uint8*)a;
219 #endif
220 #ifdef HI_TECH_C
221 uint8 rom_get (rom_addr a){
222 return flash_read(a);
224 #endif
226 #ifdef WORKSTATION
227 #define ROM_BYTES 8192
228 uint8 rom_mem[ROM_BYTES] =
230 #define RED_GREEN
231 #define PUTCHAR_LIGHT_not
232 #ifdef RED_GREEN
233 0xFB, 0xD7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x32
234 , 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00
235 , 0x08, 0x50, 0x80, 0x16, 0xFE, 0xE8, 0x00, 0xFC
236 , 0x32, 0x80, 0x2D, 0xFE, 0xFC, 0x31, 0x80, 0x43
237 , 0xFE, 0xFC, 0x33, 0x80, 0x2D, 0xFE, 0xFC, 0x31
238 , 0x80, 0x43, 0xFE, 0x90, 0x16, 0x01, 0x20, 0xFC
239 , 0x32, 0xE3, 0xB0, 0x37, 0x09, 0xF3, 0xFF, 0x20
240 , 0xFC, 0x33, 0xE3, 0xB0, 0x40, 0x0A, 0xF3, 0xFF
241 , 0x08, 0xF3, 0xFF, 0x01, 0x40, 0x21, 0xD1, 0x00
242 , 0x02, 0xC0, 0x4C, 0x71, 0x01, 0x20, 0x50, 0x90
243 , 0x51, 0x00, 0xF1, 0x40, 0xD8, 0xB0, 0x59, 0x90
244 , 0x51, 0x00, 0xFF
245 #endif
246 #ifdef PUTCHAR_LIGHT
247 0xFB, 0xD7, 0x00, 0x00, 0x80, 0x08, 0xFE, 0xE8
248 , 0x00, 0xF6, 0xF5, 0x90, 0x08
249 #endif
251 uint8 rom_get (rom_addr a) {
252 return rom_mem[a-CODE_START];
254 #endif
256 #ifdef LESS_MACROS
257 uint8 RAM_GET_FIELD0_MACRO(uint16 o) {return ram_get (OBJ_TO_RAM_ADDR(o,0));}
258 void RAM_SET_FIELD0_MACRO(uint16 o, uint8 val) {ram_set (OBJ_TO_RAM_ADDR(o,0), val);}
259 uint8 ROM_GET_FIELD0_MACRO(uint16 o) {return rom_get (OBJ_TO_ROM_ADDR(o,0));}
260 #else
261 #define RAM_GET_FIELD0_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,0))
262 #define RAM_SET_FIELD0_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,0), val)
263 #define ROM_GET_FIELD0_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,0))
264 #endif
266 #ifdef LESS_MACROS
267 uint8 RAM_GET_GC_TAGS_MACRO(uint16 o) {return (RAM_GET_FIELD0_MACRO(o) & 0x60);}
268 uint8 RAM_GET_GC_TAG0_MACRO(uint16 o) {return (RAM_GET_FIELD0_MACRO(o) & 0x20);}
269 uint8 RAM_GET_GC_TAG1_MACRO(uint16 o) {return (RAM_GET_FIELD0_MACRO(o) & 0x40);}
270 void RAM_SET_GC_TAGS_MACRO(uint16 o, uint8 tags) {(RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0x9f) | (tags)));}
271 void RAM_SET_GC_TAG0_MACRO(uint16 o, uint8 tag) {RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0xdf) | (tag));}
272 void RAM_SET_GC_TAG1_MACRO(uint16 o, uint8 tag) {RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0xbf) | (tag));}
273 #else
274 #define RAM_GET_GC_TAGS_MACRO(o) (RAM_GET_FIELD0_MACRO(o) & 0x60)
275 #define RAM_GET_GC_TAG0_MACRO(o) (RAM_GET_FIELD0_MACRO(o) & 0x20)
276 #define RAM_GET_GC_TAG1_MACRO(o) (RAM_GET_FIELD0_MACRO(o) & 0x40)
277 #define RAM_SET_GC_TAGS_MACRO(o,tags) \
278 (RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0x9f) | (tags)))
279 #define RAM_SET_GC_TAG0_MACRO(o,tag) \
280 RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0xdf) | (tag))
281 #define RAM_SET_GC_TAG1_MACRO(o,tag) \
282 RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0xbf) | (tag))
283 #endif
285 #ifdef LESS_MACROS
286 uint8 RAM_GET_FIELD1_MACRO(uint16 o) {return ram_get (OBJ_TO_RAM_ADDR(o,1));}
287 uint8 RAM_GET_FIELD2_MACRO(uint16 o) {return ram_get (OBJ_TO_RAM_ADDR(o,2));}
288 uint8 RAM_GET_FIELD3_MACRO(uint16 o) {return ram_get (OBJ_TO_RAM_ADDR(o,3));}
289 void RAM_SET_FIELD1_MACRO(uint16 o, uint8 val) {ram_set (OBJ_TO_RAM_ADDR(o,1), val);}
290 void RAM_SET_FIELD2_MACRO(uint16 o, uint8 val) {ram_set (OBJ_TO_RAM_ADDR(o,2), val);}
291 void RAM_SET_FIELD3_MACRO(uint16 o, uint8 val) {ram_set (OBJ_TO_RAM_ADDR(o,3), val);}
292 uint8 ROM_GET_FIELD1_MACRO(uint16 o) {return rom_get (OBJ_TO_ROM_ADDR(o,1));}
293 uint8 ROM_GET_FIELD2_MACRO(uint16 o) {return rom_get (OBJ_TO_ROM_ADDR(o,2));}
294 uint8 ROM_GET_FIELD3_MACRO(uint16 o) {return rom_get (OBJ_TO_ROM_ADDR(o,3));}
295 #else
296 #define RAM_GET_FIELD1_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,1))
297 #define RAM_GET_FIELD2_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,2))
298 #define RAM_GET_FIELD3_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,3))
299 #define RAM_SET_FIELD1_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,1), val)
300 #define RAM_SET_FIELD2_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,2), val)
301 #define RAM_SET_FIELD3_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,3), val)
302 #define ROM_GET_FIELD1_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,1))
303 #define ROM_GET_FIELD2_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,2))
304 #define ROM_GET_FIELD3_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,3))
305 #endif
307 word ram_get_gc_tags (obj o) { return RAM_GET_GC_TAGS_MACRO(o); }
308 word ram_get_gc_tag0 (obj o) { return RAM_GET_GC_TAG0_MACRO(o); }
309 word ram_get_gc_tag1 (obj o) { return RAM_GET_GC_TAG1_MACRO(o); }
310 void ram_set_gc_tags (obj o, word tags) { RAM_SET_GC_TAGS_MACRO(o, tags); }
311 void ram_set_gc_tag0 (obj o, word tag) { RAM_SET_GC_TAG0_MACRO(o,tag); }
312 void ram_set_gc_tag1 (obj o, word tag) { RAM_SET_GC_TAG1_MACRO(o,tag); }
313 word ram_get_field0 (obj o) { return RAM_GET_FIELD0_MACRO(o); }
314 word ram_get_field1 (obj o) { return RAM_GET_FIELD1_MACRO(o); }
315 word ram_get_field2 (obj o) { return RAM_GET_FIELD2_MACRO(o); }
316 word ram_get_field3 (obj o) { return RAM_GET_FIELD3_MACRO(o); }
317 void ram_set_field0 (obj o, word val) { RAM_SET_FIELD0_MACRO(o,val); }
318 void ram_set_field1 (obj o, word val) { RAM_SET_FIELD1_MACRO(o,val); }
319 void ram_set_field2 (obj o, word val) { RAM_SET_FIELD2_MACRO(o,val); }
320 void ram_set_field3 (obj o, word val) { RAM_SET_FIELD3_MACRO(o,val); }
321 word rom_get_field0 (obj o) { return ROM_GET_FIELD0_MACRO(o); }
322 word rom_get_field1 (obj o) { return ROM_GET_FIELD1_MACRO(o); }
323 word rom_get_field2 (obj o) { return ROM_GET_FIELD2_MACRO(o); }
324 word rom_get_field3 (obj o) { return ROM_GET_FIELD3_MACRO(o); }
326 obj ram_get_car (obj o);
327 obj rom_get_car (obj o);
328 obj ram_get_cdr (obj o);
329 obj rom_get_cdr (obj o);
330 void ram_set_car (obj o, obj val);
331 void ram_set_cdr (obj o, obj val);
333 obj ram_get_entry (obj o);
334 obj rom_get_entry (obj o);
336 obj get_global (uint8 i);
337 void set_global (uint8 i, obj o);
340 /*---------------------------------------------------------------------------*/
343 OBJECT ENCODING:
345 #f 0
346 #t 1
347 () 2
348 fixnum n MIN_FIXNUM -> 3 ... MAX_FIXNUM -> 3 + (MAX_FIXNUM-MIN_FIXNUM)
349 rom object 4 + (MAX_FIXNUM-MIN_FIXNUM) ... MIN_RAM_ENCODING-1
350 ram object MIN_RAM_ENCODING ... MAX_RAM_ENCODING
351 u8vector MIN_VEC_ENCODING ... 8191
353 layout of memory allocated objects:
355 Gs represent mark bits used by the gc
357 ifdef INFINITE_PRECISION_BIGNUMS
358 bignum n 00G***** **next** hhhhhhhh llllllll (16 bit digit)
359 TODO what to do with the gc tags for the bignums ? will this work ?
360 TODO since bignums have only 1 field, only one gc tag is should be enough
361 (only one is used anyway), so no conflict with closures
363 ifndef INFINITE_PRECISION_BIGNUMS
364 bignum n 00000000 uuuuuuuu hhhhhhhh llllllll (24 bit signed integer)
365 TODO doesn't work properly for the moment. only 16 bits are usable now
367 pair 1GGaaaaa aaaaaaaa 000ddddd dddddddd
368 a is car
369 d is cdr
370 gives an address space of 2^13 * 4 = 32k divided between simple objects,
371 rom, ram and vectors
373 symbol 1GG00000 00000000 00100000 00000000
375 string 1GG***** *chars** 01000000 00000000
377 u8vector 1GGxxxxx xxxxxxxx 011yyyyy yyyyyyyy
378 x is length of the vector, in bytes (stored raw, not encoded as an object)
379 y is pointer to the elements themselves (stored in vector space)
381 closure 01Gaaaaa aaaaaaaa aaaxxxxx xxxxxxxx
382 0x5ff<a<0x4000 is entry
383 x is pointer to environment
384 the reason why the environment is on the cdr (and the entry is split on 3
385 bytes) is that, when looking for a variable, a closure is considered to be a
386 pair. The compiler adds an extra offset to any variable in the closure's
387 environment, so the car of the closure (which doesn't really exist) is never
388 checked, but the cdr is followed to find the other bindings
390 continuation 1GGxxxxx xxxxxxxx 100yyyyy yyyyyyyy
391 x is parent continuation
392 y is pointer to the second half, which is a closure (contains env and entry)
394 An environment is a list of objects built out of pairs. On entry to
395 a procedure the environment is the list of parameters to which is
396 added the environment of the closure being called.
398 The first byte at the entry point of a procedure gives the arity of
399 the procedure:
401 n = 0 to 127 -> procedure has n parameters (no rest parameter)
402 n = -128 to -1 -> procedure has -n parameters, the last is
403 a rest parameter
406 #define OBJ_FALSE 0
407 #define OBJ_TRUE 1
408 #define encode_bool(x) (x)
410 #define OBJ_NULL 2
412 // fixnum definitions in picobit-vm.h , address space layout section
414 #ifdef LESS_MACROS
415 uint16 ENCODE_FIXNUM(uint8 n) {return ((n) + (MIN_FIXNUM_ENCODING - MIN_FIXNUM));}
416 uint8 DECODE_FIXNUM(uint16 o) {return ((o) - (MIN_FIXNUM_ENCODING - MIN_FIXNUM));}
417 #else
418 #define ENCODE_FIXNUM(n) ((n) + (MIN_FIXNUM_ENCODING - MIN_FIXNUM))
419 #define DECODE_FIXNUM(o) ((o) - (MIN_FIXNUM_ENCODING - MIN_FIXNUM))
420 #endif
422 #ifdef LESS_MACROS
423 uint8 IN_VEC(uint16 o) {return ((o) >= MIN_VEC_ENCODING);}
424 uint8 IN_RAM(uint16 o) {return (!IN_VEC(o) && ((o) >= MIN_RAM_ENCODING));}
425 uint8 IN_ROM(uint16 o) {return (!IN_VEC(o) && !IN_RAM(o) && ((o) >= MIN_ROM_ENCODING));}
426 #else
427 #define IN_VEC(o) ((o) >= MIN_VEC_ENCODING)
428 #define IN_RAM(o) (!IN_VEC(o) && ((o) >= MIN_RAM_ENCODING))
429 #define IN_ROM(o) (!IN_VEC(o) && !IN_RAM(o) && ((o) >= MIN_ROM_ENCODING))
430 #endif
432 // bignum first byte : 00Gxxxxx
433 #define BIGNUM_FIELD0 0
434 #ifdef LESS_MACROS
435 uint8 RAM_BIGNUM(uint16 o) {return ((ram_get_field0 (o) & 0xc0) == BIGNUM_FIELD0);}
436 uint8 ROM_BIGNUM(uint16 o) {return ((rom_get_field0 (o) & 0xc0) == BIGNUM_FIELD0);}
437 #else
438 #define RAM_BIGNUM(o) ((ram_get_field0 (o) & 0xc0) == BIGNUM_FIELD0)
439 #define ROM_BIGNUM(o) ((rom_get_field0 (o) & 0xc0) == BIGNUM_FIELD0)
440 #endif
442 // composite first byte : 1GGxxxxx
443 #define COMPOSITE_FIELD0 0x80
444 #ifdef LESS_MACROS
445 uint8 RAM_COMPOSITE(uint16 o) {return ((ram_get_field0 (o) & 0x80) == COMPOSITE_FIELD0);}
446 uint8 ROM_COMPOSITE(uint16 o) {return ((rom_get_field0 (o) & 0x80) == COMPOSITE_FIELD0);}
447 #else
448 #define RAM_COMPOSITE(o) ((ram_get_field0 (o) & 0x80) == COMPOSITE_FIELD0)
449 #define ROM_COMPOSITE(o) ((rom_get_field0 (o) & 0x80) == COMPOSITE_FIELD0)
450 #endif
452 // pair third byte : 000xxxxx
453 #define PAIR_FIELD2 0
454 #ifdef LESS_MACROS
455 uint8 RAM_PAIR(uint16 o) {return (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == PAIR_FIELD2));}
456 uint8 ROM_PAIR(uint16 o) {return (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == PAIR_FIELD2));}
457 #else
458 #define RAM_PAIR(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == PAIR_FIELD2))
459 #define ROM_PAIR(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == PAIR_FIELD2))
460 #endif
462 // symbol third byte : 001xxxxx
463 #define SYMBOL_FIELD2 0x20
464 #ifdef LESS_MACROS
465 uint8 RAM_SYMBOL(uint16 o) {return (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == SYMBOL_FIELD2));}
466 uint8 ROM_SYMBOL(uint16 o) {return (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == SYMBOL_FIELD2));}
467 #else
468 #define RAM_SYMBOL(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == SYMBOL_FIELD2))
469 #define ROM_SYMBOL(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == SYMBOL_FIELD2))
470 #endif
472 // string third byte : 010xxxxx
473 #define STRING_FIELD2 0x40
474 #ifdef LESS_MACROS
475 uint8 RAM_STRING(uint16 o) {return (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == STRING_FIELD2));}
476 uint8 ROM_STRING(uint16 o) {return (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == STRING_FIELD2));}
477 #else
478 #define RAM_STRING(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == STRING_FIELD2))
479 #define ROM_STRING(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == STRING_FIELD2))
480 #endif
482 // vector third byte : 011xxxxx
483 #define VECTOR_FIELD2 0x60
484 #ifdef LESS_MACROS
485 uint8 RAM_VECTOR(uint16 o) {return (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == VECTOR_FIELD2));}
486 uint8 ROM_VECTOR(uint16 o) {return (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == VECTOR_FIELD2));}
487 #else
488 #define RAM_VECTOR(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == VECTOR_FIELD2))
489 #define ROM_VECTOR(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == VECTOR_FIELD2))
490 #endif
492 // continuation third byte : 100xxxxx
493 #define CONTINUATION_FIELD2 0x80
494 #ifdef LESS_MACROS
495 uint8 RAM_CONTINUATION(uint16 o) {return (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2));}
496 uint8 ROM_CONTINUATION(uint16 o) {return (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2));}
497 #else
498 #define RAM_CONTINUATION(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2))
499 #define ROM_CONTINUATION(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2))
500 #endif
502 // closure first byte : 01Gxxxxx
503 #define CLOSURE_FIELD0 0x40
504 #ifdef LESS_MACROS
505 uint8 RAM_CLOSURE(uint16 o) {return ((ram_get_field0 (o) & 0xc0) == CLOSURE_FIELD0);}
506 uint8 ROM_CLOSURE(uint16 o) {return ((rom_get_field0 (o) & 0xc0) == CLOSURE_FIELD0);}
507 #else
508 #define RAM_CLOSURE(o) ((ram_get_field0 (o) & 0xc0) == CLOSURE_FIELD0)
509 #define ROM_CLOSURE(o) ((rom_get_field0 (o) & 0xc0) == CLOSURE_FIELD0)
510 #endif
512 /*---------------------------------------------------------------------------*/
514 // bignum definitions
516 #ifdef INFINITE_PRECISION_BIGNUMS
518 #define digit_width 16
520 typedef obj integer;
521 typedef uint16 digit; // TODO why these ? adds to the confusion
522 typedef uint32 two_digit;
524 #define obj_eq(x,y) ((x) == (y))
525 #define integer_hi_set(x,y) ram_set_car (x, y)
527 #define ZERO ENCODE_FIXNUM(0)
528 #define NEG1 (ZERO-1)
529 #define POS1 (ZERO+1)
531 integer make_integer (digit lo, integer hi);
532 integer integer_hi (integer x);
533 digit integer_lo (integer x);
535 integer norm (obj prefix, integer n);
536 uint8 negp (integer x);
537 uint8 cmp (integer x, integer y);
538 uint16 integer_length (integer x);
539 integer shr (integer x);
540 integer negative_carry (integer carry);
541 integer shl (integer x);
542 integer shift_left (integer x, uint16 n);
543 integer add (integer x, integer y);
544 integer invert (integer x);
545 integer sub (integer x, integer y);
546 integer neg (integer x);
547 integer scale (digit n, integer x);
548 integer mulnonneg (integer x, integer y);
549 integer divnonneg (integer x, integer y);
551 uint16 decode_int (obj o);
552 obj encode_int (uint16 n);
554 #endif
556 /*---------------------------------------------------------------------------*/
558 // garbage collector
560 // TODO explain what each tag means, with 1-2 mark bits
561 #define GC_TAG_0_LEFT (1<<5)
562 #define GC_TAG_1_LEFT (2<<5)
563 #define GC_TAG_UNMARKED (0<<5)
565 /* Number of object fields of objects in ram */
566 #ifdef LESS_MACROS
567 uint8 HAS_2_OBJECT_FIELDS(uint16 visit) {return (RAM_PAIR(visit) || RAM_CONTINUATION(visit));}
568 #ifdef INFINITE_PRECISION_BIGNUMS
569 uint8 HAS_1_OBJECT_FIELD(uint16 visit) {return (RAM_COMPOSITE(visit) || RAM_CLOSURE(visit) || RAM_BIGNUM(visit));}
570 #else
571 uint8 HAS_1_OBJECT_FIELD(uint16 visit) {return (RAM_COMPOSITE(visit) || RAM_CLOSURE(visit));}
572 #endif
574 #else
575 #define HAS_2_OBJECT_FIELDS(visit) (RAM_PAIR(visit) || RAM_CONTINUATION(visit))
576 #ifdef INFINITE_PRECISION_BIGNUMS
577 #define HAS_1_OBJECT_FIELD(visit) (RAM_COMPOSITE(visit) \
578 || RAM_CLOSURE(visit) || RAM_BIGNUM(visit))
579 #else
580 #define HAS_1_OBJECT_FIELD(visit) (RAM_COMPOSITE(visit) || RAM_CLOSURE(visit))
581 #endif
582 #endif
583 // all composites except pairs and continuations have 1 object field
585 #define NIL OBJ_FALSE
587 obj free_list; /* list of unused cells */
588 obj free_list_vec; /* list of unused cells in vector space */
590 obj arg1; /* root set */
591 obj arg2;
592 obj arg3;
593 obj arg4;
594 obj arg5;
595 obj cont;
596 obj env;
598 rom_addr pc; /* interpreter variables */
599 uint8 glovars;
600 rom_addr entry;
601 uint8 bytecode;
602 uint8 bytecode_hi4;
603 uint8 bytecode_lo4;
604 uint16 a1;
605 uint16 a2;
606 uint16 a3;
608 /*---------------------------------------------------------------------------*/
610 // primitives
612 #ifdef WORKSTATION
613 char *prim_name[64];
614 #endif
616 void prim_numberp ();
617 void prim_add ();
618 void prim_mul ();
619 void prim_div ();
620 void prim_rem ();
621 void prim_neg ();
622 void prim_eq ();
623 void prim_lt ();
624 void prim_gt ();
625 // TODO we have extra primitives, pring back geq, leq, and put them in a sensible place in the primitives
626 void prim_ior ();
627 void prim_xor ();
629 void prim_pairp ();
630 obj cons (obj car, obj cdr);
631 void prim_cons ();
632 void prim_car ();
633 void prim_cdr ();
634 void prim_set_car ();
635 void prim_set_cdr ();
636 void prim_nullp ();
638 void prim_u8vectorp ();
639 void prim_make_u8vector ();
640 void prim_u8vector_ref ();
641 void prim_u8vector_set ();
642 void prim_u8vector_length ();
643 void prim_u8vector_copy ();
645 void prim_eqp ();
646 void prim_not ();
647 void prim_symbolp ();
648 void prim_stringp ();
649 void prim_string2list ();
650 void prim_list2string ();
651 void prim_booleanp ();
653 #ifdef WORKSTATION
654 void show (obj o);
655 void print (obj o);
656 #endif
657 void prim_print ();
658 uint32 read_clock ();
659 void prim_clock ();
660 void prim_motor ();
661 void prim_led ();
662 void prim_led2_color ();
663 void prim_getchar_wait ();
664 void prim_putchar ();
665 void prim_beep ();
666 void prim_adc ();
667 void prim_sernum ();
669 void prim_network_init ();
670 void prim_network_cleanup ();
671 void prim_receive_packet_to_u8vector ();
672 void prim_send_packet_from_u8vector ();
674 /*---------------------------------------------------------------------------*/
676 // dispatch
678 #define FETCH_NEXT_BYTECODE() bytecode = rom_get (pc++)
680 #define PUSH_CONSTANT1 0x0
681 #define PUSH_CONSTANT2 0x1
682 #define PUSH_STACK1 0x2
683 #define PUSH_STACK2 0x3
684 #define PUSH_GLOBAL 0x4
685 #define SET_GLOBAL 0x5
686 #define CALL 0x6
687 #define JUMP 0x7
688 #if 1
689 #define JUMP_TOPLEVEL_REL4 0x8
690 #define GOTO_IF_FALSE_REL4 0x9
691 #define PUSH_CONSTANT_LONG 0xa
692 #define LABEL_INSTR 0xb
693 #else
694 #define JUMP_TOPLEVEL_REL4 0xa
695 #define GOTO_IF_FALSE_REL4 0xb
696 #define LABEL_INSTR 0x8
697 #define PUSH_CONSTANT_LONG 0x9
698 #endif
700 #define PRIM1 0xc
701 #define PRIM2 0xd
702 #define PRIM3 0xe
703 #define PRIM4 0xf
705 void push_arg1 ();
706 obj pop ();
707 void pop_procedure ();
708 uint8 handle_arity_and_rest_param (uint8 na);
709 uint8 build_env (uint8 na);
710 void save_cont ();
711 void interpreter ();
713 /*---------------------------------------------------------------------------*/
715 // debugging functions
717 #ifdef WORKSTATION
718 void show_type (obj o);
719 void show_state (rom_addr pc);
720 #endif
722 /*---------------------------------------------------------------------------*/
724 #endif