1 /* file: "picobit-vm.h" */
4 * Copyright 2004-2009 by Marc Feeley and Vincent St-Amour, All Rights Reserved.
12 #define INFINITE_PRECISION_BIGNUMS
14 /*---------------------------------------------------------------------------*/
21 typedef unsigned char uint8
;
22 typedef unsigned short uint16
;
23 typedef unsigned long uint32
;
27 typedef uint16 ram_addr
;
28 typedef uint16 rom_addr
;
30 // pointers are 13 bits
33 /*---------------------------------------------------------------------------*/
37 #ifdef INFINITE_PRECISION_BIGNUMS
39 #define digit_width 16
42 typedef uint16 digit
; // TODO why these ? adds to the confusion
43 typedef uint32 two_digit
;
47 /*---------------------------------------------------------------------------*/
68 static volatile near uint8 FW_VALUE_UP @
0x33;
69 static volatile near uint8 FW_VALUE_HI @
0x33;
70 static volatile near uint8 FW_VALUE_LO @
0x33;
72 #define ACTIVITY_LED1_LAT LATB
73 #define ACTIVITY_LED1_BIT 5
74 #define ACTIVITY_LED2_LAT LATB
75 #define ACTIVITY_LED2_BIT 4
76 static volatile near bit ACTIVITY_LED1 @
((unsigned)&ACTIVITY_LED1_LAT
*8)+ACTIVITY_LED1_BIT
;
77 static volatile near bit ACTIVITY_LED2 @
((unsigned)&ACTIVITY_LED2_LAT
*8)+ACTIVITY_LED2_BIT
;
89 #define MAX_PACKET_SIZE BUFSIZ
92 char errbuf
[PCAP_ERRBUF_SIZE
];
94 #define INTERFACE "eth0"
95 char buf
[MAX_PACKET_SIZE
]; // buffer for writing
100 #include <sys/types.h>
101 #include <sys/timeb.h>
106 #include <sys/time.h>
112 /*---------------------------------------------------------------------------*/
114 // miscellaneous definitions
115 // TODO put at the end ?
117 // TODO these 2 are only used in negp, use them elsewhere ?
121 #define CODE_START 0x5000
123 /*---------------------------------------------------------------------------*/
128 #define IF_TRACE(x) x
129 #define IF_GC_TRACE(x) x
132 #define IF_GC_TRACE(x)
135 /*---------------------------------------------------------------------------*/
140 #define ERROR(prim, msg) halt_with_error()
141 #define TYPE_ERROR(prim, type) halt_with_error()
145 #define ERROR(prim, msg) error (prim, msg)
146 #define TYPE_ERROR(prim, type) type_error (prim, type)
147 void error (char *prim
, char *msg
);
148 void type_error (char *prim
, char *type
);
151 /*---------------------------------------------------------------------------*/
153 // address space layout
154 // TODO document each zone, also explain that since vector space is in ram, it uses the ram primitives
156 #define MAX_VEC_ENCODING 8191
157 #define MIN_VEC_ENCODING 4096
158 #define VEC_BYTES ((MAX_VEC_ENCODING - MIN_VEC_ENCODING + 1)*4)
159 // if the pic has less than 8k of memory, start vector space lower
160 // TODO the pic actually has 2k, so change these
161 // TODO we'd only actually need 1024 or so for ram and vectors, since we can't address more. this gives us a lot of rom space
163 #define MAX_RAM_ENCODING 4095
164 #define MIN_RAM_ENCODING 512
165 #define RAM_BYTES ((MAX_RAM_ENCODING - MIN_RAM_ENCODING + 1)*4)
166 // TODO watch out if we address more than what the PIC actually has
168 #define MIN_FIXNUM_ENCODING 3
169 #define MIN_FIXNUM -1
170 #define MAX_FIXNUM 255
171 #define MIN_ROM_ENCODING (MIN_FIXNUM_ENCODING+MAX_FIXNUM-MIN_FIXNUM+1)
173 #define OBJ_TO_RAM_ADDR(o,f) (((ram_addr)((uint16)(o) - MIN_RAM_ENCODING) << 2) + (f))
174 #define OBJ_TO_ROM_ADDR(o,f) (((rom_addr)((uint16)(o) - MIN_ROM_ENCODING) << 2) + (CODE_START + 4 + (f)))
178 #define ram_get(a) *(uint8*)(a+0x200)
179 #define ram_set(a,x) *(uint8*)(a+0x200) = (x)
184 uint8 ram_mem
[RAM_BYTES
+ VEC_BYTES
];
185 #define ram_get(a) ram_mem[a]
186 #define ram_set(a,x) ram_mem[a] = (x)
190 uint8
rom_get (rom_addr a
){
191 return *(rom uint8
*)a
;
197 #define ROM_BYTES 8192
198 // TODO the new pics have 32k, change this ? minus the vm size, firmware ?
199 uint8 rom_mem
[ROM_BYTES
];
200 uint8
rom_get (rom_addr a
);
203 /*---------------------------------------------------------------------------*/
207 #define RAM_GET_FIELD0_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,0))
208 #define RAM_SET_FIELD0_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,0), val)
209 #define ROM_GET_FIELD0_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,0))
211 #define RAM_GET_GC_TAGS_MACRO(o) (RAM_GET_FIELD0_MACRO(o) & 0x60)
212 #define RAM_GET_GC_TAG0_MACRO(o) (RAM_GET_FIELD0_MACRO(o) & 0x20)
213 #define RAM_GET_GC_TAG1_MACRO(o) (RAM_GET_FIELD0_MACRO(o) & 0x40)
214 #define RAM_SET_GC_TAGS_MACRO(o,tags) \
215 (RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0x9f) | (tags)))
216 #define RAM_SET_GC_TAG0_MACRO(o,tag) \
217 RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0xdf) | (tag))
218 #define RAM_SET_GC_TAG1_MACRO(o,tag) \
219 RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0xbf) | (tag))
221 #define RAM_GET_FIELD1_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,1))
222 #define RAM_GET_FIELD2_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,2))
223 #define RAM_GET_FIELD3_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,3))
224 #define RAM_SET_FIELD1_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,1), val)
225 #define RAM_SET_FIELD2_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,2), val)
226 #define RAM_SET_FIELD3_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,3), val)
227 #define ROM_GET_FIELD1_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,1))
228 #define ROM_GET_FIELD2_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,2))
229 #define ROM_GET_FIELD3_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,3))
231 word
ram_get_gc_tags (obj o
);
232 word
ram_get_gc_tag0 (obj o
);
233 word
ram_get_gc_tag1 (obj o
);
234 void ram_set_gc_tags (obj o
, word tags
);
235 void ram_set_gc_tag0 (obj o
, word tag
);
236 void ram_set_gc_tag1 (obj o
, word tag
);
237 word
ram_get_field0 (obj o
);
238 word
ram_get_field1 (obj o
);
239 word
ram_get_field2 (obj o
);
240 word
ram_get_field3 (obj o
);
241 word
ram_get_fieldn (obj o
, word n
);
242 void ram_set_field0 (obj o
, word val
);
243 void ram_set_field1 (obj o
, word val
);
244 void ram_set_field2 (obj o
, word val
);
245 void ram_set_field3 (obj o
, word val
);
246 void ram_set_fieldn (obj o
, uint8 n
, word val
);
247 word
rom_get_field0 (obj o
);
248 word
rom_get_field1 (obj o
);
249 word
rom_get_field2 (obj o
);
250 word
rom_get_field3 (obj o
);
252 obj
ram_get_car (obj o
);
253 obj
rom_get_car (obj o
);
254 obj
ram_get_cdr (obj o
);
255 obj
rom_get_cdr (obj o
);
256 void ram_set_car (obj o
, obj val
);
257 void ram_set_cdr (obj o
, obj val
);
259 obj
ram_get_entry (obj o
);
260 obj
rom_get_entry (obj o
);
262 obj
get_global (uint8 i
);
263 void set_global (uint8 i
, obj o
);
265 /*---------------------------------------------------------------------------*/
273 fixnum n MIN_FIXNUM -> 3 ... MAX_FIXNUM -> 3 + (MAX_FIXNUM-MIN_FIXNUM)
274 rom object 4 + (MAX_FIXNUM-MIN_FIXNUM) ... MIN_RAM_ENCODING-1
275 ram object MIN_RAM_ENCODING ... MAX_RAM_ENCODING
276 u8vector MIN_VEC_ENCODING ... 8191
278 layout of memory allocated objects:
280 Gs represent mark bits used by the gc
282 ifdef INFINITE_PRECISION_BIGNUMS
283 bignum n 0GG***** **next** hhhhhhhh llllllll (16 bit digit)
284 TODO what to do with the gc tags for the bignums ? will this work ?
286 ifndef INFINITE_PRECISION_BIGNUMS
287 bignum n 00000000 uuuuuuuu hhhhhhhh llllllll (24 bit signed integer)
289 pair 1GGaaaaa aaaaaaaa 000ddddd dddddddd
292 gives an address space of 2^13 * 4 = 32k divided between simple objects,
295 symbol 1GG00000 00000000 00100000 00000000
297 string 1GG***** *chars** 01000000 00000000
299 u8vector 1GGxxxxx xxxxxxxx 011yyyyy yyyyyyyy
300 x is length of the vector, in bytes (stored raw, not encoded as an object)
301 y is pointer to the elements themselves (stored in vector space)
303 closure 01Gaaaaa aaaaaaaa aaaxxxxx xxxxxxxx
304 0x5ff<a<0x4000 is entry
305 x is pointer to environment
306 the reason why the environment is on the cdr (and the entry is split on 3
307 bytes) is that, when looking for a variable, a closure is considered to be a
308 pair. The compiler adds an extra offset to any variable in the closure's
309 environment, so the car of the closure (which doesn't really exist) is never
310 checked, but the cdr is followed to find the other bindings
312 continuation 1GGxxxxx xxxxxxxx 100yyyyy yyyyyyyy
313 x is parent continuation
314 y is pointer to the second half, which is a closure (contains env and entry)
316 An environment is a list of objects built out of pairs. On entry to
317 a procedure the environment is the list of parameters to which is
318 added the environment of the closure being called.
320 The first byte at the entry point of a procedure gives the arity of
323 n = 0 to 127 -> procedure has n parameters (no rest parameter)
324 n = -128 to -1 -> procedure has -n parameters, the last is
330 #define encode_bool(x) ((obj)(x))
334 // fixnum definitions in picobit-vm.h , address space layout section
336 #define ENCODE_FIXNUM(n) ((obj)(n) + (MIN_FIXNUM_ENCODING - MIN_FIXNUM))
337 #define DECODE_FIXNUM(o) ((int32)(o) - (MIN_FIXNUM_ENCODING - MIN_FIXNUM))
339 #define IN_VEC(o) ((o) >= MIN_VEC_ENCODING)
340 #define IN_RAM(o) (!IN_VEC(o) && ((o) >= MIN_RAM_ENCODING))
341 #define IN_ROM(o) (!IN_VEC(o) && !IN_RAM(o) && ((o) >= MIN_ROM_ENCODING))
343 // bignum first byte : 00Gxxxxx
344 #define BIGNUM_FIELD0 0
345 #define RAM_BIGNUM(o) ((ram_get_field0 (o) & 0xc0) == BIGNUM_FIELD0)
346 #define ROM_BIGNUM(o) ((rom_get_field0 (o) & 0xc0) == BIGNUM_FIELD0)
348 // composite first byte : 1GGxxxxx
349 #define COMPOSITE_FIELD0 0x80
350 #define RAM_COMPOSITE(o) ((ram_get_field0 (o) & 0x80) == COMPOSITE_FIELD0)
351 #define ROM_COMPOSITE(o) ((rom_get_field0 (o) & 0x80) == COMPOSITE_FIELD0)
353 // pair third byte : 000xxxxx
354 #define PAIR_FIELD2 0
355 #define RAM_PAIR(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == PAIR_FIELD2))
356 #define ROM_PAIR(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == PAIR_FIELD2))
358 // symbol third byte : 001xxxxx
359 #define SYMBOL_FIELD2 0x20
360 #define RAM_SYMBOL(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == SYMBOL_FIELD2))
361 #define ROM_SYMBOL(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == SYMBOL_FIELD2))
363 // string third byte : 010xxxxx
364 #define STRING_FIELD2 0x40
365 #define RAM_STRING(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == STRING_FIELD2))
366 #define ROM_STRING(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == STRING_FIELD2))
368 // vector third byte : 011xxxxx
369 #define VECTOR_FIELD2 0x60
370 #define RAM_VECTOR(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == VECTOR_FIELD2))
371 #define ROM_VECTOR(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == VECTOR_FIELD2))
373 // continuation third byte : 100xxxxx
374 #define CONTINUATION_FIELD2 0x80
375 #define RAM_CONTINUATION(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2))
376 #define ROM_CONTINUATION(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2))
378 // closure first byte : 01Gxxxxx
379 #define CLOSURE_FIELD0 0x40
380 #define RAM_CLOSURE(o) ((ram_get_field0 (o) & 0xc0) == CLOSURE_FIELD0)
381 #define ROM_CLOSURE(o) ((rom_get_field0 (o) & 0xc0) == CLOSURE_FIELD0)
383 /*---------------------------------------------------------------------------*/
387 // TODO explain what each tag means, with 1-2 mark bits
388 #define GC_TAG_0_LEFT (1<<5)
389 #define GC_TAG_1_LEFT (2<<5)
390 #define GC_TAG_UNMARKED (0<<5)
392 /* Number of object fields of objects in ram */
393 #define HAS_2_OBJECT_FIELDS(visit) (RAM_PAIR(visit) || RAM_CONTINUATION(visit))
394 #ifdef INFINITE_PRECISION_BIGNUMS
395 #define HAS_1_OBJECT_FIELD(visit) (RAM_COMPOSITE(visit) \
396 || RAM_CLOSURE(visit) || RAM_BIGNUM(visit))
398 #define HAS_1_OBJECT_FIELD(visit) (RAM_COMPOSITE(visit) || RAM_CLOSURE(visit))
400 // all composites except pairs and continuations have 1 object field
402 #define NIL OBJ_FALSE
404 obj free_list
; /* list of unused cells */
405 obj free_list_vec
; /* list of unused cells in vector space */
407 obj arg1
; /* root set */
415 uint8 na
; /* interpreter variables */
426 /*---------------------------------------------------------------------------*/