Fixed a couple more things for Hi-Tech C.
[picobit.git] / picobit-vm.h
blob25a3b9ff0fd958a5f64d2e5cacb5a6acd8191fa2
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 #define OBJ_TO_RAM_ADDR(o,f) ((((o) - MIN_RAM_ENCODING) << 2) + (f))
170 #define OBJ_TO_ROM_ADDR(o,f) ((((o) - MIN_ROM_ENCODING) << 2) + (CODE_START + 4 + (f)))
172 #ifdef SIXPIC
173 #define ram_get(a) *(a+0x200)
174 #define ram_set(a,x) *(a+0x200) = (x)
175 #endif
177 #ifdef MCC18
178 #define ram_get(a) *(uint8*)(a+0x200)
179 #define ram_set(a,x) *(uint8*)(a+0x200) = (x)
180 #endif
182 #ifdef HI_TECH_C
183 // cannot be a macro
184 uint8 ram_get(uint16 a) {
185 uint8 *p = a+0x200;
186 return *p;
188 void ram_set(uint16 a, uint8 x) {
189 uint8 *p = a+0x200;
190 *p = x;
192 #endif
194 #ifdef WORKSTATION
195 uint8 ram_mem[RAM_BYTES + VEC_BYTES];
196 #define ram_get(a) ram_mem[a]
197 #define ram_set(a,x) ram_mem[a] = (x)
198 #endif
200 #ifdef MCC18
201 uint8 rom_get (rom_addr a){
202 return *(rom uint8*)a;
204 #endif
205 #ifdef HI_TECH_C
206 uint8 rom_get (rom_addr a){
207 return flash_read(a);
209 #endif
211 #ifdef WORKSTATION
212 #define ROM_BYTES 8192
213 uint8 rom_mem[ROM_BYTES] =
215 #define RED_GREEN
216 #define PUTCHAR_LIGHT_not
217 #ifdef RED_GREEN
218 0xFB, 0xD7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x32
219 , 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00
220 , 0x08, 0x50, 0x80, 0x16, 0xFE, 0xE8, 0x00, 0xFC
221 , 0x32, 0x80, 0x2D, 0xFE, 0xFC, 0x31, 0x80, 0x43
222 , 0xFE, 0xFC, 0x33, 0x80, 0x2D, 0xFE, 0xFC, 0x31
223 , 0x80, 0x43, 0xFE, 0x90, 0x16, 0x01, 0x20, 0xFC
224 , 0x32, 0xE3, 0xB0, 0x37, 0x09, 0xF3, 0xFF, 0x20
225 , 0xFC, 0x33, 0xE3, 0xB0, 0x40, 0x0A, 0xF3, 0xFF
226 , 0x08, 0xF3, 0xFF, 0x01, 0x40, 0x21, 0xD1, 0x00
227 , 0x02, 0xC0, 0x4C, 0x71, 0x01, 0x20, 0x50, 0x90
228 , 0x51, 0x00, 0xF1, 0x40, 0xD8, 0xB0, 0x59, 0x90
229 , 0x51, 0x00, 0xFF
230 #endif
231 #ifdef PUTCHAR_LIGHT
232 0xFB, 0xD7, 0x00, 0x00, 0x80, 0x08, 0xFE, 0xE8
233 , 0x00, 0xF6, 0xF5, 0x90, 0x08
234 #endif
236 uint8 rom_get (rom_addr a) {
237 return rom_mem[a-CODE_START];
239 #endif
241 #define RAM_GET_FIELD0_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,0))
242 #define RAM_SET_FIELD0_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,0), val)
243 #define ROM_GET_FIELD0_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,0))
245 #define RAM_GET_GC_TAGS_MACRO(o) (RAM_GET_FIELD0_MACRO(o) & 0x60)
246 #define RAM_GET_GC_TAG0_MACRO(o) (RAM_GET_FIELD0_MACRO(o) & 0x20)
247 #define RAM_GET_GC_TAG1_MACRO(o) (RAM_GET_FIELD0_MACRO(o) & 0x40)
248 #define RAM_SET_GC_TAGS_MACRO(o,tags) \
249 (RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0x9f) | (tags)))
250 #define RAM_SET_GC_TAG0_MACRO(o,tag) \
251 RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0xdf) | (tag))
252 #define RAM_SET_GC_TAG1_MACRO(o,tag) \
253 RAM_SET_FIELD0_MACRO(o,(RAM_GET_FIELD0_MACRO(o) & 0xbf) | (tag))
255 #define RAM_GET_FIELD1_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,1))
256 #define RAM_GET_FIELD2_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,2))
257 #define RAM_GET_FIELD3_MACRO(o) ram_get (OBJ_TO_RAM_ADDR(o,3))
258 #define RAM_SET_FIELD1_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,1), val)
259 #define RAM_SET_FIELD2_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,2), val)
260 #define RAM_SET_FIELD3_MACRO(o,val) ram_set (OBJ_TO_RAM_ADDR(o,3), val)
261 #define ROM_GET_FIELD1_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,1))
262 #define ROM_GET_FIELD2_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,2))
263 #define ROM_GET_FIELD3_MACRO(o) rom_get (OBJ_TO_ROM_ADDR(o,3))
265 word ram_get_gc_tags (obj o) { return RAM_GET_GC_TAGS_MACRO(o); }
266 word ram_get_gc_tag0 (obj o) { return RAM_GET_GC_TAG0_MACRO(o); }
267 word ram_get_gc_tag1 (obj o) { return RAM_GET_GC_TAG1_MACRO(o); }
268 void ram_set_gc_tags (obj o, word tags) { RAM_SET_GC_TAGS_MACRO(o, tags); }
269 void ram_set_gc_tag0 (obj o, word tag) { RAM_SET_GC_TAG0_MACRO(o,tag); }
270 void ram_set_gc_tag1 (obj o, word tag) { RAM_SET_GC_TAG1_MACRO(o,tag); }
271 word ram_get_field0 (obj o) { return RAM_GET_FIELD0_MACRO(o); }
272 word ram_get_field1 (obj o) { return RAM_GET_FIELD1_MACRO(o); }
273 word ram_get_field2 (obj o) { return RAM_GET_FIELD2_MACRO(o); }
274 word ram_get_field3 (obj o) { return RAM_GET_FIELD3_MACRO(o); }
275 void ram_set_field0 (obj o, word val) { RAM_SET_FIELD0_MACRO(o,val); }
276 void ram_set_field1 (obj o, word val) { RAM_SET_FIELD1_MACRO(o,val); }
277 void ram_set_field2 (obj o, word val) { RAM_SET_FIELD2_MACRO(o,val); }
278 void ram_set_field3 (obj o, word val) { RAM_SET_FIELD3_MACRO(o,val); }
279 word rom_get_field0 (obj o) { return ROM_GET_FIELD0_MACRO(o); }
280 word rom_get_field1 (obj o) { return ROM_GET_FIELD1_MACRO(o); }
281 word rom_get_field2 (obj o) { return ROM_GET_FIELD2_MACRO(o); }
282 word rom_get_field3 (obj o) { return ROM_GET_FIELD3_MACRO(o); }
284 obj ram_get_car (obj o);
285 obj rom_get_car (obj o);
286 obj ram_get_cdr (obj o);
287 obj rom_get_cdr (obj o);
288 void ram_set_car (obj o, obj val);
289 void ram_set_cdr (obj o, obj val);
291 obj ram_get_entry (obj o);
292 obj rom_get_entry (obj o);
294 obj get_global (uint8 i);
295 void set_global (uint8 i, obj o);
298 /*---------------------------------------------------------------------------*/
301 OBJECT ENCODING:
303 #f 0
304 #t 1
305 () 2
306 fixnum n MIN_FIXNUM -> 3 ... MAX_FIXNUM -> 3 + (MAX_FIXNUM-MIN_FIXNUM)
307 rom object 4 + (MAX_FIXNUM-MIN_FIXNUM) ... MIN_RAM_ENCODING-1
308 ram object MIN_RAM_ENCODING ... MAX_RAM_ENCODING
309 u8vector MIN_VEC_ENCODING ... 8191
311 layout of memory allocated objects:
313 Gs represent mark bits used by the gc
315 ifdef INFINITE_PRECISION_BIGNUMS
316 bignum n 0GG***** **next** hhhhhhhh llllllll (16 bit digit)
317 TODO what to do with the gc tags for the bignums ? will this work ?
319 ifndef INFINITE_PRECISION_BIGNUMS
320 bignum n 00000000 uuuuuuuu hhhhhhhh llllllll (24 bit signed integer)
321 TODO doesn't work properly for the moment. only 16 bits are usable now
323 pair 1GGaaaaa aaaaaaaa 000ddddd dddddddd
324 a is car
325 d is cdr
326 gives an address space of 2^13 * 4 = 32k divided between simple objects,
327 rom, ram and vectors
329 symbol 1GG00000 00000000 00100000 00000000
331 string 1GG***** *chars** 01000000 00000000
333 u8vector 1GGxxxxx xxxxxxxx 011yyyyy yyyyyyyy
334 x is length of the vector, in bytes (stored raw, not encoded as an object)
335 y is pointer to the elements themselves (stored in vector space)
337 closure 01Gaaaaa aaaaaaaa aaaxxxxx xxxxxxxx
338 0x5ff<a<0x4000 is entry
339 x is pointer to environment
340 the reason why the environment is on the cdr (and the entry is split on 3
341 bytes) is that, when looking for a variable, a closure is considered to be a
342 pair. The compiler adds an extra offset to any variable in the closure's
343 environment, so the car of the closure (which doesn't really exist) is never
344 checked, but the cdr is followed to find the other bindings
346 continuation 1GGxxxxx xxxxxxxx 100yyyyy yyyyyyyy
347 x is parent continuation
348 y is pointer to the second half, which is a closure (contains env and entry)
350 An environment is a list of objects built out of pairs. On entry to
351 a procedure the environment is the list of parameters to which is
352 added the environment of the closure being called.
354 The first byte at the entry point of a procedure gives the arity of
355 the procedure:
357 n = 0 to 127 -> procedure has n parameters (no rest parameter)
358 n = -128 to -1 -> procedure has -n parameters, the last is
359 a rest parameter
362 #define OBJ_FALSE 0
363 #define OBJ_TRUE 1
364 #define encode_bool(x) (x)
366 #define OBJ_NULL 2
368 // fixnum definitions in picobit-vm.h , address space layout section
370 #define ENCODE_FIXNUM(n) ((n) + (MIN_FIXNUM_ENCODING - MIN_FIXNUM))
371 #define DECODE_FIXNUM(o) ((o) - (MIN_FIXNUM_ENCODING - MIN_FIXNUM))
373 #define IN_VEC(o) ((o) >= MIN_VEC_ENCODING)
374 #define IN_RAM(o) (!IN_VEC(o) && ((o) >= MIN_RAM_ENCODING))
375 #define IN_ROM(o) (!IN_VEC(o) && !IN_RAM(o) && ((o) >= MIN_ROM_ENCODING))
377 // bignum first byte : 00Gxxxxx
378 #define BIGNUM_FIELD0 0
379 #define RAM_BIGNUM(o) ((ram_get_field0 (o) & 0xc0) == BIGNUM_FIELD0)
380 #define ROM_BIGNUM(o) ((rom_get_field0 (o) & 0xc0) == BIGNUM_FIELD0)
382 // composite first byte : 1GGxxxxx
383 #define COMPOSITE_FIELD0 0x80
384 #define RAM_COMPOSITE(o) ((ram_get_field0 (o) & 0x80) == COMPOSITE_FIELD0)
385 #define ROM_COMPOSITE(o) ((rom_get_field0 (o) & 0x80) == COMPOSITE_FIELD0)
387 // pair third byte : 000xxxxx
388 #define PAIR_FIELD2 0
389 #define RAM_PAIR(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == PAIR_FIELD2))
390 #define ROM_PAIR(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == PAIR_FIELD2))
392 // symbol third byte : 001xxxxx
393 #define SYMBOL_FIELD2 0x20
394 #define RAM_SYMBOL(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == SYMBOL_FIELD2))
395 #define ROM_SYMBOL(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == SYMBOL_FIELD2))
397 // string third byte : 010xxxxx
398 #define STRING_FIELD2 0x40
399 #define RAM_STRING(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == STRING_FIELD2))
400 #define ROM_STRING(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == STRING_FIELD2))
402 // vector third byte : 011xxxxx
403 #define VECTOR_FIELD2 0x60
404 #define RAM_VECTOR(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == VECTOR_FIELD2))
405 #define ROM_VECTOR(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == VECTOR_FIELD2))
407 // continuation third byte : 100xxxxx
408 #define CONTINUATION_FIELD2 0x80
409 #define RAM_CONTINUATION(o) (RAM_COMPOSITE (o) && ((ram_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2))
410 #define ROM_CONTINUATION(o) (ROM_COMPOSITE (o) && ((rom_get_field2 (o) & 0xe0) == CONTINUATION_FIELD2))
412 // closure first byte : 01Gxxxxx
413 #define CLOSURE_FIELD0 0x40
414 #define RAM_CLOSURE(o) ((ram_get_field0 (o) & 0xc0) == CLOSURE_FIELD0)
415 #define ROM_CLOSURE(o) ((rom_get_field0 (o) & 0xc0) == CLOSURE_FIELD0)
417 /*---------------------------------------------------------------------------*/
419 // bignum definitions
421 #ifdef INFINITE_PRECISION_BIGNUMS
423 #define digit_width 16
425 typedef obj integer;
426 typedef uint16 digit; // TODO why these ? adds to the confusion
427 typedef uint32 two_digit;
429 #define obj_eq(x,y) ((x) == (y))
430 #define integer_hi_set(x,y) ram_set_car (x, y)
432 #define ZERO ENCODE_FIXNUM(0)
433 #define NEG1 (ZERO-1)
434 #define POS1 (ZERO+1)
436 integer make_integer (digit lo, integer hi);
437 integer integer_hi (integer x);
438 digit integer_lo (integer x);
440 integer norm (obj prefix, integer n);
441 uint8 negp (integer x);
442 uint8 cmp (integer x, integer y);
443 uint16 integer_length (integer x);
444 integer shr (integer x);
445 integer negative_carry (integer carry);
446 integer shl (integer x);
447 integer shift_left (integer x, uint16 n);
448 integer add (integer x, integer y);
449 integer invert (integer x);
450 integer sub (integer x, integer y);
451 integer neg (integer x);
452 integer scale (digit n, integer x);
453 integer mulnonneg (integer x, integer y);
454 integer divnonneg (integer x, integer y);
456 uint16 decode_int (obj o);
457 obj encode_int (uint16 n);
459 #endif
461 /*---------------------------------------------------------------------------*/
463 // garbage collector
465 // TODO explain what each tag means, with 1-2 mark bits
466 #define GC_TAG_0_LEFT (1<<5)
467 #define GC_TAG_1_LEFT (2<<5)
468 #define GC_TAG_UNMARKED (0<<5)
470 /* Number of object fields of objects in ram */
471 #define HAS_2_OBJECT_FIELDS(visit) (RAM_PAIR(visit) || RAM_CONTINUATION(visit))
472 #ifdef INFINITE_PRECISION_BIGNUMS
473 #define HAS_1_OBJECT_FIELD(visit) (RAM_COMPOSITE(visit) \
474 || RAM_CLOSURE(visit) || RAM_BIGNUM(visit))
475 #else
476 #define HAS_1_OBJECT_FIELD(visit) (RAM_COMPOSITE(visit) || RAM_CLOSURE(visit))
477 #endif
478 // all composites except pairs and continuations have 1 object field
480 #define NIL OBJ_FALSE
482 obj free_list; /* list of unused cells */
483 obj free_list_vec; /* list of unused cells in vector space */
485 obj arg1; /* root set */
486 obj arg2;
487 obj arg3;
488 obj arg4;
489 obj arg5;
490 obj cont;
491 obj env;
493 uint8 na; /* interpreter variables */
494 rom_addr pc;
495 uint8 glovars;
496 rom_addr entry;
497 uint8 bytecode;
498 uint8 bytecode_hi4;
499 uint8 bytecode_lo4;
500 uint16 a1;
501 uint16 a2;
502 uint16 a3;
504 /*---------------------------------------------------------------------------*/
506 // primitives
508 #ifdef WORKSTATION
509 char *prim_name[64];
510 #endif
512 void prim_numberp ();
513 void prim_add ();
514 void prim_mul ();
515 void prim_div ();
516 void prim_rem ();
517 void prim_neg ();
518 void prim_eq ();
519 void prim_lt ();
520 void prim_gt ();
521 // TODO we have extra primitives, pring back geq, leq, and put them in a sensible place in the primitives
522 void prim_ior ();
523 void prim_xor ();
525 void prim_pairp ();
526 obj cons (obj car, obj cdr);
527 void prim_cons ();
528 void prim_car ();
529 void prim_cdr ();
530 void prim_set_car ();
531 void prim_set_cdr ();
532 void prim_nullp ();
534 void prim_u8vectorp ();
535 void prim_make_u8vector ();
536 void prim_u8vector_ref ();
537 void prim_u8vector_set ();
538 void prim_u8vector_length ();
539 void prim_u8vector_copy ();
541 void prim_eqp ();
542 void prim_not ();
543 void prim_symbolp ();
544 void prim_stringp ();
545 void prim_string2list ();
546 void prim_list2string ();
547 void prim_booleanp ();
549 #ifdef WORKSTATION
550 void show (obj o);
551 void print (obj o);
552 #endif
553 void prim_print ();
554 uint32 read_clock ();
555 void prim_clock ();
556 void prim_motor ();
557 void prim_led ();
558 void prim_led2_color ();
559 void prim_getchar_wait ();
560 void prim_putchar ();
561 void prim_beep ();
562 void prim_adc ();
563 void prim_sernum ();
565 void prim_network_init ();
566 void prim_network_cleanup ();
567 void prim_receive_packet_to_u8vector ();
568 void prim_send_packet_from_u8vector ();
570 /*---------------------------------------------------------------------------*/
572 // dispatch
574 #define FETCH_NEXT_BYTECODE() bytecode = rom_get (pc++)
576 #define BEGIN_DISPATCH() \
577 dispatch: \
578 IF_TRACE(show_state (pc)); \
579 FETCH_NEXT_BYTECODE(); \
580 bytecode_hi4 = bytecode & 0xf0; \
581 bytecode_lo4 = bytecode & 0x0f; \
582 switch (bytecode_hi4 >> 4) {
584 #define END_DISPATCH() }
586 #define CASE(opcode) case (opcode):;
588 #define DISPATCH(); goto dispatch;
590 #define PUSH_CONSTANT1 0x0
591 #define PUSH_CONSTANT2 0x1
592 #define PUSH_STACK1 0x2
593 #define PUSH_STACK2 0x3
594 #define PUSH_GLOBAL 0x4
595 #define SET_GLOBAL 0x5
596 #define CALL 0x6
597 #define JUMP 0x7
598 #define LABEL_INSTR 0x8
599 #define PUSH_CONSTANT_LONG 0x9
601 #define FREE1 0xa
602 #define FREE2 0xb
604 #define PRIM1 0xc
605 #define PRIM2 0xd
606 #define PRIM3 0xe
607 #define PRIM4 0xf
609 #define PUSH_ARG1() push_arg1 ()
610 #define POP() pop()
612 void push_arg1 ();
613 obj pop ();
614 void pop_procedure ();
615 void handle_arity_and_rest_param ();
616 void build_env ();
617 void save_cont ();
618 void interpreter ();
620 /*---------------------------------------------------------------------------*/
622 // debugging functions
624 #ifdef WORKSTATION
625 void show_type (obj o);
626 void show_state (rom_addr pc);
627 #endif
629 /*---------------------------------------------------------------------------*/
631 #endif