Cleanup. Split the code into various files.
[picobit.git] / picobit-vm.h
blobdae57afed2cdd7679edda56f358d9e2e56b5ede5
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 typedef char int8;
19 typedef short int16;
20 typedef long int32;
21 typedef unsigned char uint8;
22 typedef unsigned short uint16;
23 typedef unsigned long uint32;
25 typedef uint8 word;
27 typedef uint16 ram_addr;
28 typedef uint16 rom_addr;
30 // pointers are 13 bits
31 typedef uint16 obj;
33 /*---------------------------------------------------------------------------*/
35 // bignum definitions
37 #ifdef INFINITE_PRECISION_BIGNUMS
39 #define digit_width 16
41 typedef obj integer;
42 typedef uint16 digit; // TODO why these ? adds to the confusion
43 typedef uint32 two_digit;
45 #endif
47 /*---------------------------------------------------------------------------*/
49 // environment
51 #ifdef PICOBOARD2
52 #define ROBOT
53 #endif
55 #ifdef HI_TECH_C
56 #define ROBOT
57 #endif
59 #ifndef ROBOT
60 #define WORKSTATION
61 #endif
64 #ifdef HI_TECH_C
66 #include <pic18.h>
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;
79 #endif
82 #ifdef WORKSTATION
84 #include <stdio.h>
85 #include <stdlib.h>
86 #include <pcap.h>
88 // for libpcap
89 #define MAX_PACKET_SIZE BUFSIZ
90 #define PROMISC 1
91 #define TO_MSEC 1
92 char errbuf[PCAP_ERRBUF_SIZE];
93 pcap_t *handle;
94 #define INTERFACE "eth0"
95 char buf [MAX_PACKET_SIZE]; // buffer for writing
98 #ifdef _WIN32
100 #include <sys/types.h>
101 #include <sys/timeb.h>
102 #include <conio.h>
104 #else
106 #include <sys/time.h>
108 #endif
110 #endif
112 /*---------------------------------------------------------------------------*/
114 // miscellaneous definitions
115 // TODO put at the end ?
117 // TODO these 2 are only used in negp, use them elsewhere ?
118 #define true 1
119 #define false 0
121 #define CODE_START 0x5000
123 /*---------------------------------------------------------------------------*/
125 // debugging
127 #ifdef DEBUG
128 #define IF_TRACE(x) x
129 #define IF_GC_TRACE(x) x
130 #else
131 #define IF_TRACE(x)
132 #define IF_GC_TRACE(x)
133 #endif
135 /*---------------------------------------------------------------------------*/
137 // error handling
139 #ifdef PICOBOARD2
140 #define ERROR(prim, msg) halt_with_error()
141 #define TYPE_ERROR(prim, type) halt_with_error()
142 #endif
144 #ifdef WORKSTATION
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);
149 #endif
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)))
177 #ifdef PICOBOARD2
178 #define ram_get(a) *(uint8*)(a+0x200)
179 #define ram_set(a,x) *(uint8*)(a+0x200) = (x)
180 #endif
183 #ifdef WORKSTATION
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)
187 #endif
189 #ifdef PICOBOARD2
190 uint8 rom_get (rom_addr a){
191 return *(rom uint8*)a;
193 #endif
196 #ifdef WORKSTATION
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);
201 #endif
203 /*---------------------------------------------------------------------------*/
205 // memory access
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 /*---------------------------------------------------------------------------*/
268 OBJECT ENCODING:
270 #f 0
271 #t 1
272 () 2
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
290 a is car
291 d is cdr
292 gives an address space of 2^13 * 4 = 32k divided between simple objects,
293 rom, ram and vectors
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
321 the procedure:
323 n = 0 to 127 -> procedure has n parameters (no rest parameter)
324 n = -128 to -1 -> procedure has -n parameters, the last is
325 a rest parameter
328 #define OBJ_FALSE 0
329 #define OBJ_TRUE 1
330 #define encode_bool(x) ((obj)(x))
332 #define OBJ_NULL 2
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 /*---------------------------------------------------------------------------*/
385 // garbage collector
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))
397 #else
398 #define HAS_1_OBJECT_FIELD(visit) (RAM_COMPOSITE(visit) || RAM_CLOSURE(visit))
399 #endif
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 */
408 obj arg2;
409 obj arg3;
410 obj arg4;
411 obj arg5;
412 obj cont;
413 obj env;
415 uint8 na; /* interpreter variables */
416 rom_addr pc;
417 uint8 glovars;
418 rom_addr entry;
419 uint8 bytecode;
420 uint8 bytecode_hi4;
421 uint8 bytecode_lo4;
422 int32 a1;
423 int32 a2;
424 int32 a3;
426 /*---------------------------------------------------------------------------*/
428 #endif