Removed code that dealt with ROM closure, since these don't exist.
[picobit.git] / picobit-vm.h
blob8f6e38e57a0e6a606670e531525d5d76e3f3830e
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 01Gxxxxx xxxxxxxx aaaaaaaa aaaaaaaa
382 0x5ff<a<0x4000 is entry
383 x is pointer to environment
385 continuation 1GGxxxxx xxxxxxxx 100yyyyy yyyyyyyy
386 x is parent continuation
387 y is pointer to the second half, which is a closure (contains env and entry)
389 An environment is a list of objects built out of pairs. On entry to
390 a procedure the environment is the list of parameters to which is
391 added the environment of the closure being called.
393 The first byte at the entry point of a procedure gives the arity of
394 the procedure:
396 n = 0 to 127 -> procedure has n parameters (no rest parameter)
397 n = -128 to -1 -> procedure has -n parameters, the last is
398 a rest parameter
401 #define OBJ_FALSE 0
402 #define OBJ_TRUE 1
403 #define encode_bool(x) (x)
405 #define OBJ_NULL 2
407 // fixnum definitions in picobit-vm.h , address space layout section
409 #ifdef LESS_MACROS
410 uint16 ENCODE_FIXNUM(uint8 n) {return ((n) + (MIN_FIXNUM_ENCODING - MIN_FIXNUM));}
411 uint8 DECODE_FIXNUM(uint16 o) {return ((o) - (MIN_FIXNUM_ENCODING - MIN_FIXNUM));}
412 #else
413 #define ENCODE_FIXNUM(n) ((n) + (MIN_FIXNUM_ENCODING - MIN_FIXNUM))
414 #define DECODE_FIXNUM(o) ((o) - (MIN_FIXNUM_ENCODING - MIN_FIXNUM))
415 #endif
417 #ifdef LESS_MACROS
418 uint8 IN_VEC(uint16 o) {return ((o) >= MIN_VEC_ENCODING);}
419 uint8 IN_RAM(uint16 o) {return (!IN_VEC(o) && ((o) >= MIN_RAM_ENCODING));}
420 uint8 IN_ROM(uint16 o) {return (!IN_VEC(o) && !IN_RAM(o) && ((o) >= MIN_ROM_ENCODING));}
421 #else
422 #define IN_VEC(o) ((o) >= MIN_VEC_ENCODING)
423 #define IN_RAM(o) (!IN_VEC(o) && ((o) >= MIN_RAM_ENCODING))
424 #define IN_ROM(o) (!IN_VEC(o) && !IN_RAM(o) && ((o) >= MIN_ROM_ENCODING))
425 #endif
427 // bignum first byte : 00Gxxxxx
428 #define BIGNUM_FIELD0 0
429 #ifdef LESS_MACROS
430 uint8 RAM_BIGNUM(uint16 o) {return ((ram_get_field0 (o) & 0xc0) == BIGNUM_FIELD0);}
431 uint8 ROM_BIGNUM(uint16 o) {return ((rom_get_field0 (o) & 0xc0) == BIGNUM_FIELD0);}
432 #else
433 #define RAM_BIGNUM(o) ((ram_get_field0 (o) & 0xc0) == BIGNUM_FIELD0)
434 #define ROM_BIGNUM(o) ((rom_get_field0 (o) & 0xc0) == BIGNUM_FIELD0)
435 #endif
437 // composite first byte : 1GGxxxxx
438 #define COMPOSITE_FIELD0 0x80
439 #ifdef LESS_MACROS
440 uint8 RAM_COMPOSITE(uint16 o) {return ((ram_get_field0 (o) & 0x80) == COMPOSITE_FIELD0);}
441 uint8 ROM_COMPOSITE(uint16 o) {return ((rom_get_field0 (o) & 0x80) == COMPOSITE_FIELD0);}
442 #else
443 #define RAM_COMPOSITE(o) ((ram_get_field0 (o) & 0x80) == COMPOSITE_FIELD0)
444 #define ROM_COMPOSITE(o) ((rom_get_field0 (o) & 0x80) == COMPOSITE_FIELD0)
445 #endif
447 // pair third byte : 000xxxxx
448 #define PAIR_FIELD2 0
449 #ifdef LESS_MACROS
450 uint8 RAM_PAIR(uint16 o) {return (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == PAIR_FIELD2));}
451 uint8 ROM_PAIR(uint16 o) {return (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == PAIR_FIELD2));}
452 #else
453 #define RAM_PAIR(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == PAIR_FIELD2))
454 #define ROM_PAIR(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == PAIR_FIELD2))
455 #endif
457 // symbol third byte : 001xxxxx
458 #define SYMBOL_FIELD2 0x20
459 #ifdef LESS_MACROS
460 uint8 RAM_SYMBOL(uint16 o) {return (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == SYMBOL_FIELD2));}
461 uint8 ROM_SYMBOL(uint16 o) {return (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == SYMBOL_FIELD2));}
462 #else
463 #define RAM_SYMBOL(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == SYMBOL_FIELD2))
464 #define ROM_SYMBOL(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == SYMBOL_FIELD2))
465 #endif
467 // string third byte : 010xxxxx
468 #define STRING_FIELD2 0x40
469 #ifdef LESS_MACROS
470 uint8 RAM_STRING(uint16 o) {return (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == STRING_FIELD2));}
471 uint8 ROM_STRING(uint16 o) {return (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == STRING_FIELD2));}
472 #else
473 #define RAM_STRING(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == STRING_FIELD2))
474 #define ROM_STRING(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == STRING_FIELD2))
475 #endif
477 // vector third byte : 011xxxxx
478 #define VECTOR_FIELD2 0x60
479 #ifdef LESS_MACROS
480 uint8 RAM_VECTOR(uint16 o) {return (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == VECTOR_FIELD2));}
481 uint8 ROM_VECTOR(uint16 o) {return (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == VECTOR_FIELD2));}
482 #else
483 #define RAM_VECTOR(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == VECTOR_FIELD2))
484 #define ROM_VECTOR(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == VECTOR_FIELD2))
485 #endif
487 // continuation third byte : 100xxxxx
488 #define CONTINUATION_FIELD2 0x80
489 #ifdef LESS_MACROS
490 uint8 RAM_CONTINUATION(uint16 o) {return (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2));}
491 uint8 ROM_CONTINUATION(uint16 o) {return (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2));}
492 #else
493 #define RAM_CONTINUATION(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2))
494 #define ROM_CONTINUATION(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2))
495 #endif
497 // closure first byte : 01Gxxxxx
498 // closures are only found in RAM
499 #define CLOSURE_FIELD0 0x40
500 #ifdef LESS_MACROS
501 uint8 RAM_CLOSURE(uint16 o) {return ((ram_get_field0 (o) & 0xc0) == CLOSURE_FIELD0);}
502 #else
503 #define RAM_CLOSURE(o) ((ram_get_field0 (o) & 0xc0) == CLOSURE_FIELD0)
504 #endif
506 /*---------------------------------------------------------------------------*/
508 // bignum definitions
510 #ifdef INFINITE_PRECISION_BIGNUMS
512 #define digit_width 16
514 typedef obj integer;
515 typedef uint16 digit; // TODO why these ? adds to the confusion
516 typedef uint32 two_digit;
518 #define obj_eq(x,y) ((x) == (y))
519 #define integer_hi_set(x,y) ram_set_car (x, y)
521 #define ZERO ENCODE_FIXNUM(0)
522 #define NEG1 (ZERO-1)
523 #define POS1 (ZERO+1)
525 integer make_integer (digit lo, integer hi);
526 integer integer_hi (integer x);
527 digit integer_lo (integer x);
529 integer norm (obj prefix, integer n);
530 uint8 negp (integer x);
531 uint8 cmp (integer x, integer y);
532 uint16 integer_length (integer x);
533 integer shr (integer x);
534 integer negative_carry (integer carry);
535 integer shl (integer x);
536 integer shift_left (integer x, uint16 n);
537 integer add (integer x, integer y);
538 integer invert (integer x);
539 integer sub (integer x, integer y);
540 integer neg (integer x);
541 integer scale (digit n, integer x);
542 integer mulnonneg (integer x, integer y);
543 integer divnonneg (integer x, integer y);
545 uint16 decode_int (obj o);
546 obj encode_int (uint16 n);
548 #endif
550 /*---------------------------------------------------------------------------*/
552 // garbage collector
554 // TODO explain what each tag means, with 1-2 mark bits
555 #define GC_TAG_0_LEFT (1<<5)
556 #define GC_TAG_1_LEFT (2<<5)
557 #define GC_TAG_UNMARKED (0<<5)
559 /* Number of object fields of objects in ram */
560 #ifdef LESS_MACROS
561 uint8 HAS_2_OBJECT_FIELDS(uint16 visit) {return (RAM_PAIR(visit) || RAM_CONTINUATION(visit));}
562 #ifdef INFINITE_PRECISION_BIGNUMS
563 uint8 HAS_1_OBJECT_FIELD(uint16 visit) {return (RAM_COMPOSITE(visit) || RAM_CLOSURE(visit) || RAM_BIGNUM(visit));}
564 #else
565 uint8 HAS_1_OBJECT_FIELD(uint16 visit) {return (RAM_COMPOSITE(visit) || RAM_CLOSURE(visit));}
566 #endif
568 #else
569 #define HAS_2_OBJECT_FIELDS(visit) (RAM_PAIR(visit) || RAM_CONTINUATION(visit))
570 #ifdef INFINITE_PRECISION_BIGNUMS
571 #define HAS_1_OBJECT_FIELD(visit) (RAM_COMPOSITE(visit) \
572 || RAM_CLOSURE(visit) || RAM_BIGNUM(visit))
573 #else
574 #define HAS_1_OBJECT_FIELD(visit) (RAM_COMPOSITE(visit) || RAM_CLOSURE(visit))
575 #endif
576 #endif
577 // all composites except pairs and continuations have 1 object field
579 #define NIL OBJ_FALSE
581 obj free_list; /* list of unused cells */
582 obj free_list_vec; /* list of unused cells in vector space */
584 obj arg1; /* root set */
585 obj arg2;
586 obj arg3;
587 obj arg4;
588 obj cont;
589 obj env;
591 rom_addr pc; /* interpreter variables */
592 uint8 glovars;
593 rom_addr entry;
594 uint8 bytecode;
595 uint8 bytecode_hi4;
596 uint8 bytecode_lo4;
597 uint16 a1;
598 uint16 a2;
599 uint16 a3;
601 /*---------------------------------------------------------------------------*/
603 // primitives
605 #ifdef WORKSTATION
606 char *prim_name[64];
607 #endif
609 void prim_numberp ();
610 void prim_add ();
611 void prim_mul_non_neg ();
612 void prim_div_non_neg ();
613 void prim_rem ();
614 void prim_eq ();
615 void prim_lt ();
616 void prim_gt ();
617 void prim_ior ();
618 void prim_xor ();
620 void prim_pairp ();
621 obj cons (obj car, obj cdr);
622 void prim_cons ();
623 void prim_car ();
624 void prim_cdr ();
625 void prim_set_car ();
626 void prim_set_cdr ();
627 void prim_nullp ();
629 void prim_u8vectorp ();
630 void prim_make_u8vector ();
631 void prim_u8vector_ref ();
632 void prim_u8vector_set ();
633 void prim_u8vector_length ();
635 void prim_eqp ();
636 void prim_not ();
637 void prim_symbolp ();
638 void prim_stringp ();
639 void prim_string2list ();
640 void prim_list2string ();
641 void prim_booleanp ();
643 #ifdef WORKSTATION
644 void show (obj o);
645 void print (obj o);
646 #endif
647 void prim_print ();
648 uint32 read_clock ();
649 void prim_clock ();
650 void prim_motor ();
651 void prim_led ();
652 void prim_led2_color ();
653 void prim_getchar_wait ();
654 void prim_putchar ();
655 void prim_beep ();
656 void prim_adc ();
657 void prim_sernum ();
659 void prim_network_init ();
660 void prim_network_cleanup ();
661 void prim_receive_packet_to_u8vector ();
662 void prim_send_packet_from_u8vector ();
664 /*---------------------------------------------------------------------------*/
666 // dispatch
668 #define FETCH_NEXT_BYTECODE() bytecode = rom_get (pc++)
670 #define PUSH_CONSTANT1 0x0
671 #define PUSH_CONSTANT2 0x1
672 #define PUSH_STACK1 0x2
673 #define PUSH_STACK2 0x3
674 #define PUSH_GLOBAL 0x4
675 #define SET_GLOBAL 0x5
676 #define CALL 0x6
677 #define JUMP 0x7
678 #if 1
679 #define JUMP_TOPLEVEL_REL4 0x8
680 #define GOTO_IF_FALSE_REL4 0x9
681 #define PUSH_CONSTANT_LONG 0xa
682 #define LABEL_INSTR 0xb
683 #else
684 #define JUMP_TOPLEVEL_REL4 0xa
685 #define GOTO_IF_FALSE_REL4 0xb
686 #define LABEL_INSTR 0x8
687 #define PUSH_CONSTANT_LONG 0x9
688 #endif
690 #define PRIM1 0xc
691 #define PRIM2 0xd
692 #define PRIM3 0xe
693 #define PRIM4 0xf
695 void push_arg1 ();
696 obj pop ();
697 void pop_procedure ();
698 uint8 handle_arity_and_rest_param (uint8 na);
699 uint8 build_env (uint8 na);
700 void save_cont ();
701 void interpreter ();
703 /*---------------------------------------------------------------------------*/
705 // debugging functions
707 #ifdef WORKSTATION
708 void show_type (obj o);
709 void show_state (rom_addr pc);
710 #endif
712 /*---------------------------------------------------------------------------*/
714 #endif