2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Pack a TagList into a structure.
10 /*****************************************************************************
13 #include <utility/tagitem.h>
14 #include <utility/pack.h>
15 #include <proto/utility.h>
17 AROS_LH3(ULONG
, PackStructureTags
,
20 AROS_LHA(APTR
, pack
, A0
),
21 AROS_LHA(ULONG
*, packTable
, A1
),
22 AROS_LHA(struct TagItem
*, tagList
, A2
),
25 struct Library
*, UtilityBase
, 35, Utility
)
28 This function will scan through the packTable, and for each TagItem
29 described in a packTable entry which can be found in the tagList,
30 the data in the TagItem's ti_Data field will be packed into the
31 structure as described in the packTable.
34 pack - The structure to fill in.
35 packTable - Table describing how to pack the structure.
36 See the include file utility/pack.h for
37 information on the format of this table.
38 tagList - List of TagItems containing data.
41 The number of TagItems packed.
55 29-10-95 digulla automatically created from
56 utility_lib.fd and clib/utility_protos.h
58 *****************************************************************************/
68 union memaccess
* memptr
;
71 tagBase
= *packTable
++;
72 for( ; *packTable
!= 0; packTable
++)
77 tagBase
= *++packTable
;
81 /* This entry is not defined for packing */
82 if((*packTable
& PSTF_PACK
)) continue;
84 tagOff
= (*packTable
>> 16) & 0x3FF;
86 /* Does the tag we are interested in exist in that list. */
87 ti
= FindTagItem(tagBase
+ tagOff
, tagList
);
91 memOff
= *packTable
& 0x1FFF;
92 bitOff
= (*packTable
& 0xE000) >> 13;
94 memptr
= (union memaccess
*)((UBYTE
*)pack
+ memOff
);
97 If the PSTF_EXISTS bit is 1, then the tagexists says that we
100 XXX: Have to see what happens when the Tag doesn't exist.
102 if((*packTable
& (PKCTRL_BIT
|PSTF_EXISTS
)) == (PKCTRL_BIT
|PSTF_EXISTS
))
104 /* If the PSTF_SIGNED bit is 1, then this is actually FLIPBIT */
105 if(*packTable
& PSTF_SIGNED
)
106 memptr
->ub
&= ~(1 << bitOff
);
108 memptr
->ub
|= (1 << bitOff
);
115 The assigning is different for signed and unsigned since
116 ti_Data is not necessarily the same size as the structure field,
117 so we have to let the compiler do sign extension.
119 Bit shifting the packTable entry >> 24, we can do some more
120 instruction space efficient stuff.
122 This used to be done with horrible casting, but using a union
125 switch((*packTable
>> 24) & 0x98)
127 case (PKCTRL_ULONG
>> 24):
129 /* EXPERIMENTAL: bitOff == 1 specifies full IPTR on 64 bits */
131 memptr
->up
= ti
->ti_Data
;
134 memptr
->ul
= ti
->ti_Data
;
137 case (PKCTRL_UWORD
>> 24):
138 memptr
->uw
= ti
->ti_Data
;
141 case (PKCTRL_UBYTE
>> 24):
142 memptr
->ub
= ti
->ti_Data
;
145 case (PKCTRL_LONG
>> 24):
148 memptr
->sp
= ti
->ti_Data
;
151 memptr
->sl
= ti
->ti_Data
;
154 case (PKCTRL_WORD
>> 24):
155 memptr
->sw
= ti
->ti_Data
;
158 case (PKCTRL_BYTE
>> 24):
159 memptr
->sb
= ti
->ti_Data
;
162 case (PKCTRL_BIT
>> 24):
164 memptr
->ub
|= (1L << bitOff
);
166 memptr
->ub
&= ~(1L << bitOff
);
169 case (PKCTRL_FLIPBIT
>> 24):
171 memptr
->ub
&= ~(1L << bitOff
);
173 memptr
->ub
|= (1L << bitOff
);
176 /* We didn't actually pack anything */
186 } /* PackStructureTags */