1 /* file: "picobit-vm.c" */
4 * Copyright 2004-2009 by Marc Feeley and Vincent St-Amour, All Rights Reserved.
8 * 15/08/2004 Release of version 1
9 * 06/07/2008 Modified for PICOBOARD2_R3
10 * 18/07/2008 Modified to use new object representation
11 * 17/12/2008 Release of version 2
14 #include "picobit-vm.h"
16 /*---------------------------------------------------------------------------*/
21 void error (char *prim
, char *msg
) {
22 printf ("ERROR: %s: %s\n", prim
, msg
);
26 void type_error (char *prim
, char *type
) {
27 printf ("ERROR: %s: An argument of type %s was expected\n", prim
, type
);
32 /*---------------------------------------------------------------------------*/
37 uint8 rom_mem
[ROM_BYTES
] =
40 #define PUTCHAR_LIGHT_not
42 0xFB, 0xD7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x32
43 , 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00
44 , 0x08, 0x50, 0x80, 0x16, 0xFE, 0xE8, 0x00, 0xFC
45 , 0x32, 0x80, 0x2D, 0xFE, 0xFC, 0x31, 0x80, 0x43
46 , 0xFE, 0xFC, 0x33, 0x80, 0x2D, 0xFE, 0xFC, 0x31
47 , 0x80, 0x43, 0xFE, 0x90, 0x16, 0x01, 0x20, 0xFC
48 , 0x32, 0xE3, 0xB0, 0x37, 0x09, 0xF3, 0xFF, 0x20
49 , 0xFC, 0x33, 0xE3, 0xB0, 0x40, 0x0A, 0xF3, 0xFF
50 , 0x08, 0xF3, 0xFF, 0x01, 0x40, 0x21, 0xD1, 0x00
51 , 0x02, 0xC0, 0x4C, 0x71, 0x01, 0x20, 0x50, 0x90
52 , 0x51, 0x00, 0xF1, 0x40, 0xD8, 0xB0, 0x59, 0x90
56 0xFB, 0xD7, 0x00, 0x00, 0x80, 0x08, 0xFE, 0xE8
57 , 0x00, 0xF6, 0xF5, 0x90, 0x08
60 uint8
rom_get (rom_addr a
) {
61 return rom_mem
[a
-CODE_START
];
65 word
ram_get_gc_tags (obj o
) { return RAM_GET_GC_TAGS_MACRO(o
); }
66 word
ram_get_gc_tag0 (obj o
) { return RAM_GET_GC_TAG0_MACRO(o
); }
67 word
ram_get_gc_tag1 (obj o
) { return RAM_GET_GC_TAG1_MACRO(o
); }
68 void ram_set_gc_tags (obj o
, word tags
) { RAM_SET_GC_TAGS_MACRO(o
, tags
); }
69 void ram_set_gc_tag0 (obj o
, word tag
) { RAM_SET_GC_TAG0_MACRO(o
,tag
); }
70 void ram_set_gc_tag1 (obj o
, word tag
) { RAM_SET_GC_TAG1_MACRO(o
,tag
); }
71 word
ram_get_field0 (obj o
) { return RAM_GET_FIELD0_MACRO(o
); }
72 word
ram_get_field1 (obj o
) { return RAM_GET_FIELD1_MACRO(o
); }
73 word
ram_get_field2 (obj o
) { return RAM_GET_FIELD2_MACRO(o
); }
74 word
ram_get_field3 (obj o
) { return RAM_GET_FIELD3_MACRO(o
); }
75 word
ram_get_fieldn (obj o
, word n
) { // TODO have as a macro ?
77 case 0: return ram_get_field0 (o
);
78 case 1: return ram_get_field1 (o
);
79 case 2: return ram_get_field2 (o
);
80 case 3: return ram_get_field3 (o
);
83 void ram_set_field0 (obj o
, word val
) { RAM_SET_FIELD0_MACRO(o
,val
); }
84 void ram_set_field1 (obj o
, word val
) { RAM_SET_FIELD1_MACRO(o
,val
); }
85 void ram_set_field2 (obj o
, word val
) { RAM_SET_FIELD2_MACRO(o
,val
); }
86 void ram_set_field3 (obj o
, word val
) { RAM_SET_FIELD3_MACRO(o
,val
); }
87 void ram_set_fieldn (obj o
, uint8 n
, word val
) { // TODO have as a macro ?
89 case 0: ram_set_field0 (o
, val
); break;
90 case 1: ram_set_field1 (o
, val
); break;
91 case 2: ram_set_field2 (o
, val
); break;
92 case 3: ram_set_field3 (o
, val
); break;
95 word
rom_get_field0 (obj o
) { return ROM_GET_FIELD0_MACRO(o
); }
96 word
rom_get_field1 (obj o
) { return ROM_GET_FIELD1_MACRO(o
); }
97 word
rom_get_field2 (obj o
) { return ROM_GET_FIELD2_MACRO(o
); }
98 word
rom_get_field3 (obj o
) { return ROM_GET_FIELD3_MACRO(o
); }
100 obj
ram_get_car (obj o
)
101 { return ((ram_get_field0 (o
) & 0x1f) << 8) | ram_get_field1 (o
); }
102 obj
rom_get_car (obj o
)
103 { return ((rom_get_field0 (o
) & 0x1f) << 8) | rom_get_field1 (o
); }
104 obj
ram_get_cdr (obj o
)
105 { return ((ram_get_field2 (o
) & 0x1f) << 8) | ram_get_field3 (o
); }
106 obj
rom_get_cdr (obj o
)
107 { return ((rom_get_field2 (o
) & 0x1f) << 8) | rom_get_field3 (o
); }
109 void ram_set_car (obj o
, obj val
) {
110 ram_set_field0 (o
, (val
>> 8) | (ram_get_field0 (o
) & 0xe0));
111 ram_set_field1 (o
, val
& 0xff);
113 void ram_set_cdr (obj o
, obj val
) {
114 ram_set_field2 (o
, (val
>> 8) | (ram_get_field2 (o
) & 0xe0));
115 ram_set_field3 (o
, val
& 0xff);
118 // function entry point
119 obj
ram_get_entry (obj o
) {
120 return (((ram_get_field0 (o
) & 0x1f) << 11)
121 | (ram_get_field1 (o
) << 3)
122 | (ram_get_field2 (o
) >> 5));
124 obj
rom_get_entry (obj o
){
125 return (((rom_get_field0 (o
) & 0x1f) << 11)
126 | (rom_get_field1 (o
) << 3)
127 | (rom_get_field2 (o
) >> 5));
130 obj
get_global (uint8 i
) {
131 // globals occupy the beginning of ram, with 2 globals per word
133 return ram_get_cdr (MIN_RAM_ENCODING
+ (i
>> 1));
135 return ram_get_car (MIN_RAM_ENCODING
+ (i
>> 1));
137 void set_global (uint8 i
, obj o
) {
139 ram_set_cdr (MIN_RAM_ENCODING
+ (i
>> 1), o
);
141 ram_set_car (MIN_RAM_ENCODING
+ (i
>> 1), o
);
144 // TODO generic functions (get_field0, get_car, etc) that work for both rom and ram were not used, are in garbage
146 /*---------------------------------------------------------------------------*/
150 int hidden_fgetc (FILE *f
)
160 #define fgetc(f) hidden_fgetc(f)
162 void write_hex_nibble (int n
)
164 putchar ("0123456789ABCDEF"[n
]);
167 void write_hex (uint8 n
)
169 write_hex_nibble (n
>> 4);
170 write_hex_nibble (n
& 0x0f);
175 if (c
>= '0' && c
<= '9')
178 if (c
>= 'A' && c
<= 'F')
179 return (c
- 'A' + 10);
181 if (c
>= 'a' && c
<= 'f')
182 return (c
- 'a' + 10);
187 int read_hex_byte (FILE *f
)
189 int h1
= hex (fgetc (f
));
190 int h2
= hex (fgetc (f
));
192 if (h1
>= 0 && h2
>= 0)
198 int read_hex_file (char *filename
)
201 FILE *f
= fopen (filename
, "r");
211 for (i
=0; i
<ROM_BYTES
; i
++)
216 while ((c
= fgetc (f
)) != EOF
)
218 if ((c
== '\r') || (c
== '\n'))
222 (len
= read_hex_byte (f
)) < 0 ||
223 (a1
= read_hex_byte (f
)) < 0 ||
224 (a2
= read_hex_byte (f
)) < 0 ||
225 (t
= read_hex_byte (f
)) < 0)
231 sum
= len
+ a1
+ a2
+ t
;
239 unsigned long adr
= ((unsigned long)hi16
<< 16) + a
- CODE_START
;
241 if ((b
= read_hex_byte (f
)) < 0)
244 if (adr
>= 0 && adr
< ROM_BYTES
)
247 a
= (a
+ 1) & 0xffff;
264 if ((a1
= read_hex_byte (f
)) < 0 ||
265 (a2
= read_hex_byte (f
)) < 0)
275 if ((b
= read_hex_byte (f
)) < 0)
282 printf ("*** HEX file checksum error (expected 0x%02x)\n", sum
);
288 if ((c
!= '\r') && (c
!= '\n'))
299 printf ("*** HEX file syntax error\n");
309 /*---------------------------------------------------------------------------*/
312 // no separate compilation
316 #include "primitives.c"
317 #include "dispatch.c"
320 /*---------------------------------------------------------------------------*/
326 printf ("usage: sim file.hex\n");
330 int main (int argc
, char *argv
[])
333 rom_addr rom_start_addr
= 0;
339 if (argc
> 1 && argv
[1][0] == '-' && argv
[1][1] == 's')
346 if ((h1
= hex (argv
[1][2])) < 0 ||
347 (h2
= hex (argv
[1][3])) < 0 ||
348 (h3
= hex (argv
[1][4])) != 0 ||
349 (h4
= hex (argv
[1][5])) != 0 ||
353 rom_start_addr
= (h1
<< 12) | (h2
<< 8) | (h3
<< 4) | h4
;
360 printf ("Start address = 0x%04x\n", rom_start_addr
+ CODE_START
);
366 if (!read_hex_file (argv
[1]))
367 printf ("*** Could not read hex file \"%s\"\n", argv
[1]);
372 if (rom_get (CODE_START
+0) != 0xfb ||
373 rom_get (CODE_START
+1) != 0xd7)
374 printf ("*** The hex file was not compiled with PICOBIT\n");
378 for (i
=0; i
<8192; i
++)
379 if (rom_get (i
) != 0xff)
380 printf ("rom_mem[0x%04x] = 0x%02x\n", i
, rom_get (i
));
386 printf ("**************** memory needed = %d\n", max_live
+1);