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
);
33 void halt_with_error () {
43 /*---------------------------------------------------------------------------*/
47 word
ram_get_fieldn (obj o
, word n
) {
49 case 0: return ram_get_field0 (o
);
50 case 1: return ram_get_field1 (o
);
51 case 2: return ram_get_field2 (o
);
52 case 3: return ram_get_field3 (o
);
55 void ram_set_fieldn (obj o
, uint8 n
, word val
) { // TODO have as a macro ?
57 case 0: ram_set_field0 (o
, val
); break;
58 case 1: ram_set_field1 (o
, val
); break;
59 case 2: ram_set_field2 (o
, val
); break;
60 case 3: ram_set_field3 (o
, val
); break;
64 // these temporary variables are necessary with SIXPIC, or else the shift
65 // results will be 8 bits values, which is wrong
66 obj
ram_get_car (obj o
) {
67 uint16 tmp
= ram_get_field0 (o
) & 0x1f;
68 return (tmp
<< 8) | ram_get_field1 (o
);
70 obj
rom_get_car (obj o
) {
71 uint16 tmp
= rom_get_field0 (o
) & 0x1f;
72 return (tmp
<< 8) | rom_get_field1 (o
);
74 obj
ram_get_cdr (obj o
) {
75 uint16 tmp
= ram_get_field2 (o
) & 0x1f;
76 return (tmp
<< 8) | ram_get_field3 (o
);
78 obj
rom_get_cdr (obj o
) {
79 uint16 tmp
= rom_get_field2 (o
) & 0x1f;
80 return (tmp
<< 8) | rom_get_field3 (o
);
83 void ram_set_car (obj o
, obj val
) {
84 ram_set_field0 (o
, (val
>> 8) | (ram_get_field0 (o
) & 0xe0));
85 ram_set_field1 (o
, val
& 0xff);
87 void ram_set_cdr (obj o
, obj val
) {
88 ram_set_field2 (o
, (val
>> 8) | (ram_get_field2 (o
) & 0xe0));
89 ram_set_field3 (o
, val
& 0xff);
92 // function entry point
93 // the temporary variables are necessary with SIXPIC, see above
94 obj
ram_get_entry (obj o
) {
95 uint16 tmp
= ram_get_field2 (o
);
96 return ((tmp
<< 8) | ram_get_field3 (o
));
98 obj
rom_get_entry (obj o
){
99 uint16 tmp
= rom_get_field2 (o
);
100 return ((tmp
<< 8) | rom_get_field3 (o
));
103 obj
get_global (uint8 i
) {
104 // globals occupy the beginning of ram, with 2 globals per word
106 return ram_get_cdr (MIN_RAM_ENCODING
+ (i
>> 1));
108 return ram_get_car (MIN_RAM_ENCODING
+ (i
>> 1));
110 void set_global (uint8 i
, obj o
) {
112 ram_set_cdr (MIN_RAM_ENCODING
+ (i
>> 1), o
);
114 ram_set_car (MIN_RAM_ENCODING
+ (i
>> 1), o
);
117 // TODO generic functions (get_field0, get_car, etc) that work for both rom and ram were not used, are in garbage
119 /*---------------------------------------------------------------------------*/
123 int hidden_fgetc (FILE *f
)
133 #define fgetc(f) hidden_fgetc(f)
135 void write_hex_nibble (int n
)
137 putchar ("0123456789ABCDEF"[n
]);
140 void write_hex (uint8 n
)
142 write_hex_nibble (n
>> 4);
143 write_hex_nibble (n
& 0x0f);
148 if (c
>= '0' && c
<= '9')
151 if (c
>= 'A' && c
<= 'F')
152 return (c
- 'A' + 10);
154 if (c
>= 'a' && c
<= 'f')
155 return (c
- 'a' + 10);
160 int read_hex_byte (FILE *f
)
162 int h1
= hex (fgetc (f
));
163 int h2
= hex (fgetc (f
));
165 if (h1
>= 0 && h2
>= 0)
171 int read_hex_file (char *filename
)
174 FILE *f
= fopen (filename
, "r");
184 for (i
=0; i
<ROM_BYTES
; i
++)
189 while ((c
= fgetc (f
)) != EOF
)
191 if ((c
== '\r') || (c
== '\n'))
195 (len
= read_hex_byte (f
)) < 0 ||
196 (a1
= read_hex_byte (f
)) < 0 ||
197 (a2
= read_hex_byte (f
)) < 0 ||
198 (t
= read_hex_byte (f
)) < 0)
204 sum
= len
+ a1
+ a2
+ t
;
212 unsigned long adr
= ((unsigned long)hi16
<< 16) + a
- CODE_START
;
214 if ((b
= read_hex_byte (f
)) < 0)
217 if (adr
>= 0 && adr
< ROM_BYTES
)
220 a
= (a
+ 1) & 0xffff;
237 if ((a1
= read_hex_byte (f
)) < 0 ||
238 (a2
= read_hex_byte (f
)) < 0)
248 if ((b
= read_hex_byte (f
)) < 0)
255 printf ("*** HEX file checksum error (expected 0x%02x)\n", sum
);
261 if ((c
!= '\r') && (c
!= '\n'))
272 printf ("*** HEX file syntax error\n");
282 /*---------------------------------------------------------------------------*/
285 // TODO since picobit-vm.h can now contain code (with LESS_MACROS), including
286 // the header in each results in multiple definitions of these functions.
287 // no separate compilation
291 #include "primitives.c"
292 #include "dispatch.c"
295 /*---------------------------------------------------------------------------*/
301 printf ("usage: sim file.hex\n");
305 int main (int argc
, char *argv
[])
308 rom_addr rom_start_addr
= 0;
314 if (argc
> 1 && argv
[1][0] == '-' && argv
[1][1] == 's')
321 if ((h1
= hex (argv
[1][2])) < 0 ||
322 (h2
= hex (argv
[1][3])) < 0 ||
323 (h3
= hex (argv
[1][4])) != 0 ||
324 (h4
= hex (argv
[1][5])) != 0 ||
328 rom_start_addr
= (h1
<< 12) | (h2
<< 8) | (h3
<< 4) | h4
;
335 printf ("Start address = 0x%04x\n", rom_start_addr
+ CODE_START
);
341 if (!read_hex_file (argv
[1]))
342 printf ("*** Could not read hex file \"%s\"\n", argv
[1]);
347 if (rom_get (CODE_START
+0) != 0xfb ||
348 rom_get (CODE_START
+1) != 0xd7)
349 printf ("*** The hex file was not compiled with PICOBIT\n");
353 for (i
=0; i
<8192; i
++)
354 if (rom_get (i
) != 0xff)
355 printf ("rom_mem[0x%04x] = 0x%02x\n", i
, rom_get (i
));
361 printf ("**************** memory needed = %d\n", max_live
+1);