1 /*
2 Object
3 */
4
5 #include "object.h"
6
7 #include "head.h"
8 #include "jump.h"
9 #include "mem.h"
10 #include "print.h"
11 #include "var.h"
12
13 #define std_attr 0
14 #define std_locn 4
15 #define std_link 5
16 #define std_hold 6
17 #define std_prop 7
18 #define std_size 9
19
20 #define plus_attr 0
21 #define plus_locn 6
22 #define plus_link 8
23 #define plus_hold 10
24 #define plus_prop 12
25 #define plus_size 14
26
27 #define std_base 0x35
28 #define plus_base 0x70
29
30 #define FIRST_ATTR ((byte) 0x80)
31
32 #define static
33
std_addr(word obj)34 static long_word std_addr(word obj)
35 {
36 return hd_object() + (long_word) obj * std_size + std_base;
37 }
38
plus_addr(word obj)39 static long_word plus_addr(word obj)
40 {
41 return hd_object() + (long_word) obj * plus_size + plus_base;
42 }
43
44 /* Support */
45
get_locn(word obj)46 static word get_locn(word obj)
47 {
48 if(hd_plus())
49 return rd_word_addr(plus_addr(obj) + plus_locn);
50 else
51 return rd_byte_addr(std_addr(obj) + std_locn);
52 }
53
set_locn(word obj,word locn)54 static void set_locn(word obj, word locn)
55 {
56 if(hd_plus())
57 wr_word_addr(plus_addr(obj) + plus_locn, locn);
58 else
59 wr_byte_addr(std_addr(obj) + std_locn, locn);
60 }
61
get_link(word obj)62 static word get_link(word obj)
63 {
64 if(hd_plus())
65 return rd_word_addr(plus_addr(obj) + plus_link);
66 else
67 return rd_byte_addr(std_addr(obj) + std_link);
68 }
69
set_link(word obj,word link)70 static void set_link(word obj, word link)
71 {
72 if(hd_plus())
73 wr_word_addr(plus_addr(obj) + plus_link, link);
74 else
75 wr_byte_addr(std_addr(obj) + std_link, link);
76 }
77
get_hold(word obj)78 static word get_hold(word obj)
79 {
80 if(hd_plus())
81 return rd_word_addr(plus_addr(obj) + plus_hold);
82 else
83 return rd_byte_addr(std_addr(obj) + std_hold);
84 }
85
set_hold(word obj,word hold)86 static void set_hold(word obj, word hold)
87 {
88 if(hd_plus())
89 wr_word_addr(plus_addr(obj) + plus_hold, hold);
90 else
91 wr_byte_addr(std_addr(obj) + std_hold, hold);
92 }
93
94 /* Main routines */
95
obj_remove(word obj1)96 void obj_remove(word obj1)
97 {
98 word obj2 = get_locn(obj1);
99 if(obj2)
100 {
101 if(get_hold(obj2) == obj1)
102 {
103 set_hold(obj2, get_link(obj1));
104 }
105 else
106 {
107 obj2 = get_hold(obj2);
108 while(get_link(obj2) != obj1)
109 obj2 = get_link(obj2);
110 set_link(obj2, get_link(obj1));
111 }
112 set_locn(obj1, 0);
113 set_link(obj1, 0);
114 }
115 }
116
obj_transfer(word obj1,word obj2)117 void obj_transfer(word obj1, word obj2)
118 {
119 /* Move obj1 into obj2 */
120 obj_remove(obj1);
121 set_link(obj1, get_hold(obj2));
122 set_locn(obj1, obj2);
123 set_hold(obj2, obj1);
124 }
125
obj_holds(word obj)126 void obj_holds(word obj)
127 {
128 word hold = get_hold(obj);
129 store(hold);
130 ret_value(hold != 0);
131 }
132
obj_link(word obj)133 void obj_link(word obj)
134 {
135 word link = get_link(obj);
136 store(link);
137 ret_value(link != 0);
138 }
139
obj_attr(word obj,word attr)140 static long_word obj_attr(word obj, word attr)
141 {
142 word off = (word) attr >> 3;
143 return hd_plus() ? plus_addr(obj) + plus_attr + off
144 : std_addr(obj) + std_attr + off;
145 }
146
obj_test(word obj,word attr)147 void obj_test(word obj, word attr)
148 {
149 long_word a = obj_attr(obj, attr);
150 byte mask = ((byte) FIRST_ATTR) >> (attr % 8);
151 ret_value((mask & rd_byte_addr(a)) != 0);
152 }
153
obj_set(word obj,word attr)154 void obj_set(word obj, word attr)
155 {
156 long_word a = obj_attr(obj, attr);
157 byte mask = ((byte) FIRST_ATTR) >> (attr % 8);
158 wr_byte_addr(a, rd_byte_addr(a) | mask);
159 }
160
obj_clr(word obj,word attr)161 void obj_clr(word obj, word attr)
162 {
163 long_word a = obj_attr(obj, attr);
164 byte mask = ((byte) FIRST_ATTR) >> (attr % 8);
165 wr_byte_addr(a, rd_byte_addr(a) & ~mask);
166 }
167
obj_loc(word obj)168 void obj_loc(word obj)
169 {
170 store(get_locn(obj));
171 }
172
obj_check(word obj1,word obj2)173 void obj_check(word obj1, word obj2)
174 {
175 ret_value(get_locn(obj1) == obj2);
176 }
177
obj_print(word obj)178 void obj_print(word obj)
179 {
180 print1(obj_prop(obj) + 1);
181 }
182
obj_prop(word obj)183 word obj_prop(word obj)
184 {
185 return rd_word_addr(hd_plus() ? plus_addr(obj) + plus_prop
186 : std_addr(obj) + std_prop);
187 }
188