revert between 56095 -> 55830 in arch
[AROS.git] / rom / utility / packstructuretags.c
blob1da7d055b0767ebaa1b14268eb8dbd57e7858340
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Pack a TagList into a structure.
6 Lang: english
7 */
8 #include "intern.h"
10 /*****************************************************************************
12 NAME */
13 #include <utility/tagitem.h>
14 #include <utility/pack.h>
15 #include <proto/utility.h>
17 AROS_LH3(ULONG, PackStructureTags,
19 /* SYNOPSIS */
20 AROS_LHA(APTR , pack, A0),
21 AROS_LHA(ULONG *, packTable, A1),
22 AROS_LHA(struct TagItem *, tagList, A2),
24 /* LOCATION */
25 struct Library *, UtilityBase, 35, Utility)
27 /* FUNCTION
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.
33 INPUTS
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.
40 RESULT
41 The number of TagItems packed.
43 NOTES
45 EXAMPLE
47 BUGS
49 SEE ALSO
50 UnpackStructureTags()
52 INTERNALS
54 HISTORY
55 29-10-95 digulla automatically created from
56 utility_lib.fd and clib/utility_protos.h
58 *****************************************************************************/
60 AROS_LIBFUNC_INIT
62 Tag tagBase;
63 UWORD memOff;
64 UWORD tagOff;
65 UBYTE bitOff;
66 struct TagItem * ti;
67 LONG count = 0;
68 union memaccess * memptr;
71 tagBase = *packTable++;
72 for( ; *packTable != 0; packTable++)
74 /* New base tag */
75 if(*packTable == -1)
77 tagBase = *++packTable;
78 continue;
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);
88 if(ti == NULL)
89 continue;
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
98 set the bit to 1.
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);
107 else
108 memptr->ub |= (1 << bitOff);
110 count++;
111 continue;
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
123 is much neater.
125 switch((*packTable >> 24) & 0x98)
127 case (PKCTRL_ULONG >> 24):
128 #if __WORDSIZE > 32
129 /* EXPERIMENTAL: bitOff == 1 specifies full IPTR on 64 bits */
130 if (bitOff == 1)
131 memptr->up = ti->ti_Data;
132 else
133 #endif
134 memptr->ul = ti->ti_Data;
135 break;
137 case (PKCTRL_UWORD >> 24):
138 memptr->uw = ti->ti_Data;
139 break;
141 case (PKCTRL_UBYTE >> 24):
142 memptr->ub = ti->ti_Data;
143 break;
145 case (PKCTRL_LONG >> 24):
146 #if __WORDSIZE > 32
147 if (bitOff == 1)
148 memptr->sp = ti->ti_Data;
149 else
150 #endif
151 memptr->sl = ti->ti_Data;
152 break;
154 case (PKCTRL_WORD >> 24):
155 memptr->sw = ti->ti_Data;
156 break;
158 case (PKCTRL_BYTE >> 24):
159 memptr->sb = ti->ti_Data;
160 break;
162 case (PKCTRL_BIT >> 24):
163 if(ti->ti_Data)
164 memptr->ub |= (1L << bitOff);
165 else
166 memptr->ub &= ~(1L << bitOff);
167 break;
169 case (PKCTRL_FLIPBIT >> 24):
170 if(ti->ti_Data)
171 memptr->ub &= ~(1L << bitOff);
172 else
173 memptr->ub |= (1L << bitOff);
174 break;
176 /* We didn't actually pack anything */
177 default:
178 count--;
179 } /* switch() */
180 count++;
181 } /* for() */
183 return count;
185 AROS_LIBFUNC_EXIT
186 } /* PackStructureTags */