5 /* $Id: init.c,v 2.4 1994/06/24 10:47:31 ceriel Exp $ */
21 /****************************************************************
22 * The EM-machine is not implemented as a contiguous *
23 * piece of memory. Instead there are a number of *
24 * "floating" pieces of memory, each representing a *
25 * specific part of the machine. There are separate *
27 * - stack and local area (stack), *
28 * - heap area & global data area (data), *
29 * - program text & procedure descriptors (text). *
30 * The names in parenthesis are the names of the global *
31 * variables used within our program, pointing to *
32 * the beginning of such an area. The sizes of the global *
33 * data area and the program text can be determined *
34 * once and for all in the "rd_header" routine. *
35 ****************************************************************/
37 extern char **environ;
39 PRIVATE ptr storestring();
40 PRIVATE size alignedstrlen();
49 register size env_vec_size; /* size of environ vector */
50 register size arg_vec_size; /* size of argument vector */
51 register size string_size = 0; /* total size arg, env, strings */
52 register ptr ARGB, vecp, strp;
54 init_ofiles(1); /* Initialize all output files */
57 /* Read the load file header, to obtain wsize and psize */
59 rd_open(load_name); /* Open object file */
61 rd_header(); /* Read in load file header */
63 /* Initialize wsize- and psize-dependent variables */
66 i_minsw = (wsize == 2) ? I_MINS2 : I_MINS4;
67 i_maxsw = (wsize == 2) ? I_MAXS2 : I_MAXS4;
68 i_maxuw = (wsize == 2) ? I_MAXU2 : I_MAXU4;
69 max_addr = i2p(((psize == 2) ? I_MAXU2 : I_MAXS4) / wsize * wsize) - 1;
70 min_off = (psize == 2) ? (-MAX_OFF2-1) : (-MAX_OFF4-1);
71 max_off = (psize == 2) ? MAX_OFF2 : MAX_OFF4;
73 /* Determine nr of bytes, needed to store arguments/environment */
75 env_vec_size = 0; /* length of environ vector copy */
76 for (p = environ; *p != (char *) 0; p++) {
77 string_size += alignedstrlen(*p);
78 env_vec_size += psize;
80 env_vec_size += psize; /* terminating zero */
82 arg_vec_size = 0; /* length of argument vector copy */
83 for (p = av; *p != (char *) 0; p++) {
84 string_size += alignedstrlen(*p);
85 arg_vec_size += psize;
87 arg_vec_size += psize; /* terminating zero */
89 /* One pseudo-register */
90 ARGB = i2p(SZDATA); /* command arguments base */
92 /* Initialize segments */
94 init_data(ARGB + arg_vec_size + env_vec_size + string_size);
99 /* Initialize trap registers */
100 TrapPI = 0; /* set Trap Procedure Identifier */
101 OnTrap = TR_ABORT; /* there cannot be a trap handler yet*/
102 IgnMask = PreIgnMask; /* copy Ignore Mask from preset */
104 /* Initialize Exit Status */
105 ES_def = UNDEFINED; /* set Exit Status illegal */
107 /* Read partitions */
115 /* Set up the arguments and environment */
117 vecp = ARGB; /* start of environ vector copy */
118 dppush(vecp); /* push address of env pointer */
119 strp = vecp + env_vec_size; /* start of environ strings */
120 for (p = environ; *p != (char *) 0; p++) {
122 strp = storestring(strp, *p);
125 dt_stdp(vecp, i2p(0)); /* terminating zero */
127 vecp = strp; /* start of argument vector copy */
128 dppush(vecp); /* push address of argv pointer */
129 strp = vecp + arg_vec_size; /* start of argument strings */
130 for (p = av; *p != (char *) 0; p++) {
132 strp = storestring(strp, *p);
135 dt_stdp(vecp, i2p(0)); /* terminating zero */
137 wpush((long) ac); /* push argc */
140 PRIVATE size alignedstrlen(s)
143 register size len = strlen(s) + 1;
145 return (len + wsize - 1) / wsize * wsize;
148 PRIVATE ptr storestring(addr, s)
152 /* Store string, aligned to a fit multiple of wsize bytes.
153 Return first address on a wordsize boundary after string.
155 register size oldlen = strlen(s) + 1;
156 register size newlen = ((oldlen + wsize - 1) / wsize) * wsize;
159 LOG(("@g6 storestring(%lu, %s), oldlen = %ld, newlen = %ld",
160 addr, s, oldlen, newlen));
161 ch_in_data(addr, newlen);
162 ch_aligned(addr, newlen);
164 /* copy data of source string */
165 for (i = 0; i < oldlen; i++) {
166 data_loc(addr + i) = *s++;
169 /* pad until newlen */
170 for (; i < newlen; i++) {
171 data_loc(addr + i) = (char) 0;
178 dt_clear_area(from, to)
182 /* includes *from but excludes *to */
185 for (a = from; a < to; a++) {
190 st_clear_area(from, to)
194 /* includes both *from and *to (since ML+1 is unexpressible) */
197 for (a = from; a >= to; a--) {