Fix IO memory access .. SB128 driver makes noises in VMWare - CMI is untested (Curren...
[AROS.git] / rom / utility / unpackstructuretags.c
blob1241bd0f4630ebf4ab7b0b401fbdb385d7b05ea1
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: UnpackStructureTags - unpack structure to values in TagList.
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, UnpackStructureTags,
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, 36, Utility)
27 /* FUNCTION
28 For each table entry, if the matching tag is found in the tagList,
29 then the data in the structure will be placed in the memory pointed
30 to by the tags ti_Data.
32 Note: The value contained in ti_Data must be a *POINTER* to a
33 IPTR.
35 INPUTS
36 pack - Pointer to the memory area to be unpacked.
37 packTable - Table describing the unpacking operation.
38 See the include file <utility/pack.h> for
39 more information on this table.
40 tagList - List of TagItems to unpack into.
42 RESULT
43 The number of Tags unpacked.
45 NOTES
46 PSTF_EXISTS has no effect on this function.
48 EXAMPLE
50 BUGS
52 SEE ALSO
53 PackStructureTags(), FindTagItem()
55 INTERNALS
57 HISTORY
58 29-10-95 digulla automatically created from
59 utility_lib.fd and clib/utility_protos.h
61 *****************************************************************************/
63 AROS_LIBFUNC_INIT
65 Tag tagBase;
66 UWORD memOff;
67 UWORD tagOff;
68 UBYTE bitOff;
69 struct TagItem * ti;
70 LONG count = 0;
71 union memaccess * memptr;
73 tagBase = *packTable++;
74 for( ; *packTable != 0; packTable++)
76 /* New base tag */
77 if(*packTable == -1)
79 tagBase = *++packTable;
80 continue;
83 /* This entry is not defined for unpacking */
84 if((*packTable & PSTF_UNPACK)) continue;
86 tagOff = (*packTable >> 16) & 0x3FF;
88 /* Does the tag we are interested in exist in that list. */
89 ti = FindTagItem(tagBase + tagOff, tagList);
90 if(ti == NULL)
91 continue;
93 memOff = *packTable & 0x1FFF;
94 bitOff = (*packTable & 0xE000) >> 13;
95 memptr = (union memaccess *)((UBYTE *)pack + memOff);
98 The assigning is different for signed and unsigned since
99 ti_Data is not necessarily the same size as the structure field,
100 so we have to let the compiler do sign extension.
102 switch(*packTable & 0x98000000)
104 case PKCTRL_ULONG:
105 #if __WORDSIZE > 32
106 /* EXPERIMENTAL: use bitOff as "full IPTR flag" on 64 bits */
107 if (bitOff == 1)
108 *(IPTR *)ti->ti_Data = (IPTR)memptr->up;
109 else
110 #endif
111 *(IPTR *)ti->ti_Data = (IPTR)memptr->ul;
112 break;
114 case PKCTRL_UWORD:
115 *(IPTR *)ti->ti_Data = (IPTR)memptr->uw;
116 break;
118 case PKCTRL_UBYTE:
119 *(IPTR *)ti->ti_Data = (IPTR)memptr->ub;
120 break;
122 case PKCTRL_LONG:
123 #if __WORDSIZE > 32
124 if (bitOff == 1)
125 *(IPTR *)ti->ti_Data = (IPTR)memptr->sp;
126 else
127 #endif
128 *(IPTR *)ti->ti_Data = (IPTR)memptr->sl;
129 break;
131 case PKCTRL_WORD:
132 *(IPTR *)ti->ti_Data = (IPTR)memptr->sw;
133 break;
135 case PKCTRL_BYTE:
136 *(IPTR *)ti->ti_Data = (IPTR)memptr->sb;
137 break;
139 case PKCTRL_BIT:
140 if( memptr->ub & (1 << bitOff) )
141 *(IPTR *)ti->ti_Data = TRUE;
142 else
143 *(IPTR *)ti->ti_Data = FALSE;
144 break;
146 case PKCTRL_FLIPBIT:
147 if( memptr->ub & (1 << bitOff) )
148 *(IPTR *)ti->ti_Data = FALSE;
149 else
150 *(IPTR *)ti->ti_Data = TRUE;
151 break;
153 /* We didn't actually pack anything */
154 default:
155 count--;
157 } /* switch() */
159 count++;
161 } /* for() */
163 return count;
165 AROS_LIBFUNC_EXIT
166 } /* UnpackStructureTags */