1 /* yForth? - Written by Luca Padovani (C) 1996/97
2 * ------------------------------------------------------------------------
3 * This software is FreeWare as long as it comes with this header in each
4 * source file, anyway you can use it or any part of it whatever
5 * you want. It comes without any warranty, so use it at your own risk.
6 * ------------------------------------------------------------------------
7 * Module name: yforth.c
8 * Abstract: Main program
22 jmp_buf warm_start_jump, cold_start_jump;
24 Char *dp0; /* Data-Space base pointer */
25 Cell dspace_size = DEF_DSPACE_SIZE; /* Data-Space size */
26 Cell dstack_size = DEF_DSTACK_SIZE, /* Data-Stack size */
27 rstack_size = DEF_RSTACK_SIZE, /* Return-stack size */
28 fstack_size = DEF_FSTACK_SIZE; /* Floating-stack size */
29 Cell tib_size = DEF_TIB_SIZE; /* TIB size */
30 Cell in_pnos, pnos_size; /* Pictured Numeric Output String */
31 Char *pnos, *p_pnos; /* Ptrs inside PNOS */
32 Cell pad_size = DEF_PAD_SIZE; /* PAD size */
34 static char *file_name, /* Ptr to file name on command line, if present */
35 *image_file; /* Ptr to image file name on cmd line, if present */
40 static struct image_header hd;
42 void print_version() {
43 printf("yForth? v%d.%d%s - Written by Luca Padovani (C) 1996.\n\
44 This software is Freeware, use it at your own risk.\n",
45 VER_HI, VER_LO, VER_TEST);
48 void print_help(void) {
50 printf("Usage: yForth [options] [file name]\n\
51 -d<n> Data-Space size -s<n> Data-Stack size\n\
52 -r<n> Return-Stack size -f<n> Floating-Stack size\n\
53 -t<n> TIB size -p<n> PAD size\n\
54 -h,-H This help -q Quiet\n\
55 -i<file> Image file\n\
56 All sizes are expressed in cells.\n");
59 /* do_parameters: processes parameters passed on command line */
60 void do_parameters(int argc, char *argv[]) {
63 if (argv[i][0] == '-')
65 case 'd': dspace_size = atoi(argv[i] + 2); break;
66 case 's': dstack_size = atoi(argv[i] + 2); break;
67 case 'r': rstack_size = atoi(argv[i] + 2); break;
68 case 'f': fstack_size = atoi(argv[i] + 2); break;
69 case 't': tib_size = atoi(argv[i] + 2); break;
70 case 'p': pad_size = atoi(argv[i] + 2); break;
71 case 'q': silent = 1; break;
72 case 'i': image_file = argv[i] + 2; break;
79 fprintf(stderr, "%c unknown option, use -h for help.\n");
90 /* default_parameters: adjust environment parameters in case they do not
91 * fall into required range
93 void default_parameters(void) {
94 dspace_size = max(MIN_DSPACE_SIZE, dspace_size);
95 dstack_size = max(MIN_DSTACK_SIZE, dstack_size);
96 rstack_size = max(MIN_RSTACK_SIZE, rstack_size);
97 fstack_size = max(MIN_FSTACK_SIZE, fstack_size);
98 tib_size = max(MIN_TIB_SIZE, tib_size);
99 pad_size = max(MIN_PAD_SIZE, pad_size);
102 /* load_image_file: loads image file named "name" into the dictionary. Loading
103 * is divided in two parts: when "header" is set to 1 the file is opened and
104 * the header is loaded into the structure "hd". Then some checks are made
105 * to adjust parameters in case of a corrupted image.
106 * Finally, when "load_image_file" is called with "header" set to 0, the
107 * actual loading is performed. Note that pointers inside the dictionary
108 * are absolute, so an image file can be loaded only if the allocated
109 * memory is placed at the same address when it's been saved. Furthermore,
110 * the same image file cannot be loaded thru different version of the
111 * executable file "yForth".
113 int load_image_file(char *name, int header) {
114 FILE *f = fopen(name, "rb");
118 if (fread(&hd, sizeof(struct image_header), 1, f)) {
119 if (hd.ver_hi != VER_HI || hd.ver_lo != VER_LO)
121 fprintf(stderr, "Warning: different image file version (%d.%d).\n",
122 hd.ver_hi, hd.ver_lo);
123 if (hd.pattern != VERSION_PATTERN)
125 fprintf(stderr, "Warning: different version pattern (Image: %x).\n",
128 } else fprintf(stderr, "Error: can't read image file header.\n");
130 fseek(f, sizeof(struct image_header), SEEK_SET);
131 if (hd.base == dp0) {
132 struct voc_marker vm;
133 if (fread(&vm, sizeof(struct voc_marker), 1, f) < 1 ||
134 fread(dp0, sizeof(Cell), hd.dspace_size, f) != hd.dspace_size)
135 fprintf(stderr, "Error: can't read image file.\n");
137 load_vocabulary(&vm);
140 } else fprintf(stderr, "Error: can't load image file with base %u at %u.\n",
144 } else fprintf(stderr, "Can't open image file (%s).\n", name);
148 main(int argc, char *argv[]) {
149 do_parameters(argc, argv);
151 if (load_image_file(image_file, 1)) exit(-1);
152 } else fopen(argv[0], "rb");
153 /* !!! WARNING !!! Previous line opens a file even if no image-file
154 * is specified. This is because in some system data space would
155 * result unaligned in subsequent loadings. I have to find a more
156 * smart trick here...
159 default_parameters();
161 open_block_file("YFORTH.BLK");
163 init_stacks(dstack_size, rstack_size, fstack_size);
164 if (image_file && dspace_size < hd.dspace_size) {
166 fprintf(stderr, "Warning: can't restrict dictionary to %u cells, now is %u cells.\n",
167 dspace_size, hd.dspace_size);
168 dspace_size = max(dspace_size, hd.dspace_size);
170 init_data_space(dspace_size);
176 silent |= setjmp(cold_start_jump);
178 if (load_image_file(image_file, 0)) exit(-1);
180 /* Note that after a cold start the vocabulary is reloaded */
185 printf("Cell: %d Double-Cell: %d Char: %d Real: %d\n",
186 sizeof(Cell), sizeof(DCell), sizeof(Char), sizeof(Real));
189 init_forth_environment(!image_file);
190 if (!setjmp(warm_start_jump) && file_name) load_file(file_name);