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