1 /*
2 * object.c
3 *
4 * Object manipulation routines.
5 *
6 */
7
8 #include "ztypes.h"
9
10 #define PARENT 0
11 #define NEXT 1
12 #define CHILD 2
13
14 #ifdef __STDC__
15 static zword_t read_object (zword_t objp, int field);
16 static void write_object (zword_t objp, int field, zword_t value);
17 #else
18 static zword_t read_object ();
19 static void write_object ();
20 #endif
21
22 /*
23 * get_object_address
24 *
25 * Calculate the address of an object in the data area.
26 *
27 */
28
29 #ifdef __STDC__
get_object_address(zword_t obj)30 zword_t get_object_address (zword_t obj)
31 #else
32 zword_t get_object_address (obj)
33 zword_t obj;
34 #endif
35 {
36 int offset;
37
38 /* Address calculation is object table base + size of default properties area +
39 object number-1 * object size */
40
41 if (h_type < V4)
42 offset = h_objects_offset + ((P3_MAX_PROPERTIES - 1) * 2) + ((obj - 1) * O3_SIZE);
43 else
44 offset = h_objects_offset + ((P4_MAX_PROPERTIES - 1) * 2) + ((obj - 1) * O4_SIZE);
45
46 return ((zword_t) offset);
47
48 }/* get_object_address */
49
50 /*
51 * insert_object
52 *
53 * Insert object 1 as the child of object 2 after first removing it from its
54 * previous parent. The object is inserted at the front of the child object
55 * chain.
56 *
57 */
58
59 #ifdef __STDC__
insert_object(zword_t obj1,zword_t obj2)60 void insert_object (zword_t obj1, zword_t obj2)
61 #else
62 void insert_object (obj1, obj2)
63 zword_t obj1;
64 zword_t obj2;
65 #endif
66 {
67 zword_t obj1p, obj2p, child2;
68
69 #ifdef STRICTZ
70 if (obj1 == 0) {
71 report_strictz_error(STRZERR_MOVE_OBJECT,
72 "@move_object called moving object 0");
73 return;
74 }
75 if (obj2 == 0) {
76 report_strictz_error(STRZERR_MOVE_OBJECT_2,
77 "@move_object called moving into object 0");
78 return;
79 }
80 #endif
81
82 /* Get addresses of both objects */
83
84 obj1p = get_object_address (obj1);
85 obj2p = get_object_address (obj2);
86
87 /* Remove object 1 from current parent */
88
89 remove_object (obj1);
90
91 /* Make object 2 object 1's parent */
92
93 write_object (obj1p, PARENT, obj2);
94
95 /* Get current first child of object 2 */
96
97 child2 = read_object (obj2p, CHILD);
98
99 /* Make object 1 first child of object 2 */
100
101 write_object (obj2p, CHILD, obj1);
102
103 /* If object 2 had children then link them into the next child field of object 1 */
104
105 if (child2)
106 write_object (obj1p, NEXT, child2);
107
108 }/* insert_object */
109
110 /*
111 * remove_object
112 *
113 * Remove an object by unlinking from the its parent object and from its
114 * siblings.
115 *
116 */
117
118 #ifdef __STDC__
remove_object(zword_t obj)119 void remove_object (zword_t obj)
120 #else
121 void remove_object (obj)
122 zword_t obj;
123 #endif
124 {
125 zword_t objp, parentp, childp, parent, child;
126
127 #ifdef STRICTZ
128 if (obj == 0) {
129 report_strictz_error(STRZERR_REMOVE_OBJECT,
130 "@remove_object called with object 0");
131 return;
132 }
133 #endif
134
135 /* Get address of object to be removed */
136
137 objp = get_object_address (obj);
138
139 /* Get parent of object, and return if no parent */
140
141 if ((parent = read_object (objp, PARENT)) == 0)
142 return;
143
144 /* Get address of parent object */
145
146 parentp = get_object_address (parent);
147
148 /* Find first child of parent */
149
150 child = read_object (parentp, CHILD);
151
152 /* If object is first child then just make the parent child pointer
153 equal to the next child */
154
155 if (child == obj)
156 write_object (parentp, CHILD, read_object (objp, NEXT));
157 else {
158
159 /* Walk down the child chain looking for this object */
160
161 do {
162 childp = get_object_address (child);
163 child = read_object (childp, NEXT);
164 } while (child != obj);
165
166 /* Set the next pointer thre previous child to the next pointer
167 of the current object child pointer */
168
169 write_object (childp, NEXT, read_object (objp, NEXT));
170 }
171
172 /* Set the parent and next child pointers to NULL */
173
174 write_object (objp, PARENT, 0);
175 write_object (objp, NEXT, 0);
176
177 }/* remove_object */
178
179 /*
180 * load_parent_object
181 *
182 * Load the parent object pointer of an object
183 *
184 */
185
186 #ifdef __STDC__
load_parent_object(zword_t obj)187 void load_parent_object (zword_t obj)
188 #else
189 void load_parent_object (obj)
190 zword_t obj;
191 #endif
192 {
193
194 #ifdef STRICTZ
195 if (obj == 0) {
196 report_strictz_error(STRZERR_GET_PARENT,
197 "@get_parent called with object 0");
198 store_operand(0);
199 return;
200 }
201 #endif
202
203 store_operand (read_object (get_object_address (obj), PARENT));
204
205 }/* load_parent_object */
206
207 /*
208 * load_child_object
209 *
210 * Load the child object pointer of an object and jump if the child pointer is
211 * not NULL.
212 *
213 */
214
215 #ifdef __STDC__
load_child_object(zword_t obj)216 void load_child_object (zword_t obj)
217 #else
218 void load_child_object (obj)
219 zword_t obj;
220 #endif
221 {
222 zword_t child;
223
224 #ifdef STRICTZ
225 if (obj == 0) {
226 report_strictz_error(STRZERR_GET_CHILD,
227 "@get_child called with object 0");
228 store_operand(0);
229 conditional_jump(FALSE);
230 return;
231 }
232 #endif
233
234 child = read_object (get_object_address (obj), CHILD);
235
236 store_operand (child);
237
238 conditional_jump (child != 0);
239
240 }/* load_child_object */
241
242 /*
243 * load_next_object
244 *
245 * Load the next child object pointer of an object and jump if the next child
246 * pointer is not NULL.
247 *
248 */
249
250 #ifdef __STDC__
load_next_object(zword_t obj)251 void load_next_object (zword_t obj)
252 #else
253 void load_next_object (obj)
254 zword_t obj;
255 #endif
256 {
257 zword_t next;
258
259 #ifdef STRICTZ
260 if (obj == 0) {
261 report_strictz_error(STRZERR_GET_SIBLING,
262 "@get_sibling called with object 0");
263 store_operand(0);
264 conditional_jump(FALSE);
265 return;
266 }
267 #endif
268
269 next = read_object (get_object_address (obj), NEXT);
270
271 store_operand (next);
272
273 conditional_jump (next != 0);
274
275 }/* load_next_object */
276
277 /*
278 * compare_parent_object
279 *
280 * Jump if object 2 is the parent of object 1
281 *
282 */
283
284 #ifdef __STDC__
compare_parent_object(zword_t obj1,zword_t obj2)285 void compare_parent_object (zword_t obj1, zword_t obj2)
286 #else
287 void compare_parent_object (obj1, obj2)
288 zword_t obj1;
289 zword_t obj2;
290 #endif
291 {
292
293 #ifdef STRICTZ
294 if (obj1 == 0) {
295 report_strictz_error(STRZERR_JIN,
296 "@jin called with object 0");
297 conditional_jump(0 == obj2);
298 return;
299 }
300 #endif
301
302 conditional_jump (read_object (get_object_address (obj1), PARENT) == obj2);
303
304 }/* compare_parent_object */
305
306 /*
307 * test_attr
308 *
309 * Test if an attribute bit is set.
310 *
311 */
312
313 #ifdef __STDC__
test_attr(zword_t obj,zword_t bit)314 void test_attr (zword_t obj, zword_t bit)
315 #else
316 void test_attr (obj, bit)
317 zword_t obj;
318 zword_t bit;
319 #endif
320 {
321 zword_t objp;
322 zbyte_t value;
323
324 assert (O3_ATTRIBUTES == O4_ATTRIBUTES);
325
326 #ifdef STRICTZ
327 if (obj == 0) {
328 report_strictz_error(STRZERR_TEST_ATTR,
329 "@test_attr called with object 0");
330 conditional_jump(FALSE);
331 return;
332 }
333 #endif
334
335 /* Get attribute address */
336
337 objp = get_object_address (obj) + (bit >> 3);
338
339 /* Load attribute byte */
340
341 value = get_byte (objp);
342
343 /* Test attribute */
344
345 conditional_jump ((value >> (7 - (bit & 7))) & 1);
346
347 }/* test_attr */
348
349 /*
350 * set_attr
351 *
352 * Set an attribute bit.
353 *
354 */
355
356 #ifdef __STDC__
set_attr(zword_t obj,zword_t bit)357 void set_attr (zword_t obj, zword_t bit)
358 #else
359 void set_attr (obj, bit)
360 zword_t obj;
361 zword_t bit;
362 #endif
363 {
364 zword_t objp;
365 zbyte_t value;
366
367 assert (O3_ATTRIBUTES == O4_ATTRIBUTES);
368
369 #ifdef STRICTZ
370 if (obj == 0) {
371 report_strictz_error(STRZERR_SET_ATTR,
372 "@set_attr called with object 0");
373 return;
374 }
375 #endif
376
377 /* Get attribute address */
378
379 objp = get_object_address (obj) + (bit >> 3);
380
381 /* Load attribute byte */
382
383 value = get_byte (objp);
384
385 /* Set attribute bit */
386
387 value |= (zbyte_t) (1 << (7 - (bit & 7)));
388
389 /* Store attribute byte */
390
391 set_byte (objp, value);
392
393 }/* set_attr */
394
395 /*
396 * clear_attr
397 *
398 * Clear an attribute bit
399 *
400 */
401
402 #ifdef __STDC__
clear_attr(zword_t obj,zword_t bit)403 void clear_attr (zword_t obj, zword_t bit)
404 #else
405 void clear_attr (obj, bit)
406 zword_t obj;
407 zword_t bit;
408 #endif
409 {
410 zword_t objp;
411 zbyte_t value;
412
413 assert (O3_ATTRIBUTES == O4_ATTRIBUTES);
414
415 #ifdef STRICTZ
416 if (obj == 0) {
417 report_strictz_error(STRZERR_CLEAR_ATTR,
418 "@clear_attr called with object 0");
419 return;
420 }
421 #endif
422
423 /* Get attribute address */
424
425 objp = get_object_address (obj) + (bit >> 3);
426
427 /* Load attribute byte */
428
429 value = get_byte (objp);
430
431 /* Clear attribute bit */
432
433 value &= (zbyte_t) ~(1 << (7 - (bit & 7)));
434
435 /* Store attribute byte */
436
437 set_byte (objp, value);
438
439 }/* clear_attr */
440
441 #ifdef __STDC__
read_object(zword_t objp,int field)442 static zword_t read_object (zword_t objp, int field)
443 #else
444 static zword_t read_object (objp, field)
445 zword_t objp;
446 int field;
447 #endif
448 {
449 zword_t value;
450
451 if (h_type < V4) {
452 if (field == PARENT)
453 value = (zword_t) get_byte (PARENT3 (objp));
454 else if (field == NEXT)
455 value = (zword_t) get_byte (NEXT3 (objp));
456 else
457 value = (zword_t) get_byte (CHILD3 (objp));
458 } else {
459 if (field == PARENT)
460 value = get_word (PARENT4 (objp));
461 else if (field == NEXT)
462 value = get_word (NEXT4 (objp));
463 else
464 value = get_word (CHILD4 (objp));
465 }
466
467 return (value);
468
469 }/* read_object */
470
471 #ifdef __STDC__
write_object(zword_t objp,int field,zword_t value)472 static void write_object (zword_t objp, int field, zword_t value)
473 #else
474 static void write_object (objp, field, value)
475 zword_t objp;
476 int field;
477 zword_t value;
478 #endif
479 {
480
481 if (h_type < V4) {
482 if (field == PARENT)
483 set_byte (PARENT3 (objp), value);
484 else if (field == NEXT)
485 set_byte (NEXT3 (objp), value);
486 else
487 set_byte (CHILD3 (objp), value);
488 } else {
489 if (field == PARENT)
490 set_word (PARENT4 (objp), value);
491 else if (field == NEXT)
492 set_word (NEXT4 (objp), value);
493 else
494 set_word (CHILD4 (objp), value);
495 }
496
497 }/* write_object */
498