Pristine Ack-5.5
[Ack-5.5.git] / util / int / do_sets.c
1 /*
2  * Sources of the "SETS" group instructions
3  */
4
5 /* $Id: do_sets.c,v 2.5 1994/06/24 10:46:53 ceriel Exp $ */
6
7 #include        <em_abs.h>
8 #include        "global.h"
9 #include        "log.h"
10 #include        "trap.h"
11 #include        "mem.h"
12 #include        "text.h"
13 #include        "fra.h"
14
15 PRIVATE bit_test(), create_set();
16
17 DoINN(l)
18         register size l;
19 {
20         /* INN w: Bit test on w byte set (bit number on top of stack) */
21
22         LOG(("@Y6 DoINN(%ld)", l));
23         spoilFRA();
24         bit_test(arg_w(l));
25 }
26
27 DoSET(l)
28         register size l;
29 {
30         /* SET w: Create singleton w byte set with bit n on (n is top of stack) */
31
32         LOG(("@Y6 DoSET(%ld)", l));
33         spoilFRA();
34         create_set(arg_w(l));
35 }
36
37 /********************************************************
38  *              bit testing                             *
39  *                                                      *
40  *      Tests whether the bit with number to be found   *
41  *      on TOS is on in 'w'-byte set.                   *
42  *      ON --> push 1 on stack.                         *
43  *      OFF -> push 0 on stack.                         *
44  ********************************************************/
45
46 PRIVATE bit_test(w)
47         size w;
48 {
49         register int bitno =
50                 (int) swpop();  /* bitno on TOS */
51         register char test_byte = (char) 0;/* default value to be tested */
52         register int wordoff = bitno / 8;
53         register int bitoff = bitno % 8; 
54
55         if (bitoff < 0) bitoff += 8;
56
57         if (must_test && !(IgnMask&BIT(ESET))) {
58                 /* Only w*8 bits CAN be tested */
59                 if (wordoff >= w) {
60                         trap(ESET);
61                 }
62         }
63         test_byte = stack_loc(SP + wordoff);
64         st_dec(w);
65         wpush((long)((test_byte & BIT(bitoff)) ? 1 : 0));
66 }
67
68 /********************************************************
69  *              set creation                            *
70  *                                                      *
71  *      Creates a singleton 'w'-byte set with as        *
72  *      singleton member, the bit with number on        *
73  *      TOS. The w bytes constituting the set are       *
74  *      pushed on the stack.                            *
75  ********************************************************/
76
77 PRIVATE create_set(w)
78         size w;
79 {
80         register int bitno = (int) swpop();
81         register size nbytes = w;
82         register int wordoff = bitno / 8;
83         register int bitoff = bitno % 8;
84
85         if (bitoff < 0) bitoff += 8;
86
87         st_inc(nbytes);
88         while (--nbytes >= 0) {
89                 st_stn(SP + nbytes, 0L, 1L);
90         }
91
92         if (must_test && !(IgnMask&BIT(ESET))) {
93                 if (wordoff >= w) {
94                         trap(ESET);
95                 }
96         }
97         st_stn(SP + wordoff, (long)BIT(bitoff), 1L);
98 }
99