Updated PCI IDs to latest snapshot.
[tangerine.git] / rom / exec / initstruct.c
blobc3aa12132e738b94e567b890fe8e153b3b148f42
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Initialize a structure.
6 Lang: english
7 */
8 #include "exec_intern.h"
9 #include <aros/libcall.h>
10 #include <proto/exec.h>
12 /*****************************************************************************
14 NAME */
16 AROS_LH3(void, InitStruct,
18 /* SYNOPSIS */
19 AROS_LHA(APTR, initTable, A1),
20 AROS_LHA(APTR, memory, A2),
21 AROS_LHA(ULONG, size, D0),
23 /* LOCATION */
24 struct ExecBase *, SysBase, 13, Exec)
26 /* FUNCTION
27 Initialize some library base or other structure depending on the
28 information in the init table. The init table consists of
29 instructions starting with an action byte followed by more
30 information. The instruction byte looks like:
32 iisscccc where ii is the instruction code:
33 0 - copy following c+1 elements
34 1 - repeat following element c+1 times
35 2 - take next byte as offset, then copy
36 3 - take the next 3 bytes (in the machine's
37 particular byte ordering) as offset, then
38 copy
39 ss is the element size
40 0 - LONGs
41 1 - WORDs
42 2 - BYTEs
43 3 - QUADs
44 cccc is the element count-1
46 Instruction bytes must follow the same alignment restrictions as LONGs;
47 the following elements are aligned to their particular restrictions.
49 A 0 instruction ends the init table.
51 INPUTS
52 initTable - Pointer to init table.
53 memory - Pointer to uninitialized structure.
54 size - Size of memory area to zero out before decoding or 0
55 for no filling.
57 RESULT
59 NOTES
61 EXAMPLE
63 BUGS
65 SEE ALSO
67 INTERNALS
69 ******************************************************************************/
71 AROS_LIBFUNC_INIT
73 LONG cnt;
74 ULONG offset=0;
75 QUAD src;
76 UBYTE *it,*dst;
77 int s,t;
79 /* Clear Memory area fast. Get number of longs and clear them. */
80 cnt=size/sizeof(LONG);
81 size&=(sizeof(LONG)-1);
82 dst=(UBYTE *)memory;
83 if(cnt)
86 *(LONG *)dst=0;
87 dst+=sizeof(LONG);
89 while(--cnt);
91 /* Clear the rest. */
92 cnt=size;
93 if(cnt)
95 *dst++=0;
96 while(--cnt);
98 it =(UBYTE *)initTable;
99 dst=(UBYTE *)memory;
101 /* As long as there's something to do */
102 while(*it!=0)
104 /* What to do. */
105 t=*it>>6&3;
107 /* Element size. */
108 s=*it>>4&3;
110 /* Number of things to do (-1). */
111 cnt=*it&15;
113 /* Depending on the action there may be more information */
114 switch(t)
116 case 0:
117 case 1:
118 /* Skip the action byte */
119 it++;
120 break;
121 case 2:
122 /* Skip the action byte, get the offset */
123 it++;
124 offset=*it++;
125 break;
126 case 3:
128 Get 24bit offset. It's the programmer's responsibility
129 to align the action byte with a LONG instruction before
130 this.
132 #if AROS_BIG_ENDIAN
133 offset=*(ULONG *)it&0xffffff;
134 #else
135 offset=it[1] | ((*(UWORD *)&it[2]) << 8);
136 #endif
137 it+=sizeof(LONG);
138 break;
141 /* Align source and destination pointers */
142 switch(s)
144 case 0:
145 /* Align pointer to LONG requirements */
146 it =(UBYTE *)(((IPTR)it +AROS_LONGALIGN-1)&~(AROS_LONGALIGN-1));
147 dst=(UBYTE *)(((IPTR)dst+AROS_LONGALIGN-1)&~(AROS_LONGALIGN-1));
148 break;
149 case 1:
150 /* Same for WORDs */
151 it =(UBYTE *)(((IPTR)it +AROS_WORDALIGN-1)&~(AROS_WORDALIGN-1));
152 dst=(UBYTE *)(((IPTR)dst+AROS_WORDALIGN-1)&~(AROS_WORDALIGN-1));
153 break;
154 case 2:
155 /* Nothing to do for bytes */
156 break;
157 case 3:
158 /* Align pointer to QUAD requirements */
159 it =(UBYTE *)(((IPTR)it +AROS_QUADALIGN-1)&~(AROS_QUADALIGN-1));
160 dst=(UBYTE *)(((IPTR)dst+AROS_QUADALIGN-1)&~(AROS_QUADALIGN-1));
161 break;
164 /* Switch over action */
165 switch(t)
167 case 2:
168 case 3:
169 /* Action is: Add offset then copy */
170 dst=(BYTE *)memory+offset;
172 /* Fall through */
173 case 0:
174 /* Action is: Copy the next <cnt> elements to the current location */
175 switch(s)
177 case 0:
178 /* Copy loop */
181 *(LONG *)dst=*(LONG *)it;
182 dst+=sizeof(LONG);
183 it +=sizeof(LONG);
184 }while(--cnt>=0);
185 break;
186 case 1:
189 *(WORD *)dst=*(WORD *)it;
190 dst+=sizeof(WORD);
191 it +=sizeof(WORD);
192 }while(--cnt>=0);
193 break;
194 case 2:
196 *dst++=*it++;
197 while(--cnt>=0);
198 break;
199 case 3:
202 *(QUAD *)dst=*(QUAD *)it;
203 dst+=sizeof(QUAD);
204 it +=sizeof(QUAD);
205 }while(--cnt>=0);
206 break;
208 break;
209 case 1:
210 /* Action is: Repeat the next element <cnt> times */
211 switch(s)
213 case 0:
214 /* Get source */
215 src=*(LONG *)it;
216 it +=sizeof(LONG);
218 /* And write it. */
221 *(LONG *)dst=src;
222 dst+=sizeof(LONG);
223 }while(--cnt>=0);
224 break;
225 case 1:
226 src=*(WORD *)it;
227 it +=sizeof(WORD);
230 *(WORD *)dst=src;
231 dst+=sizeof(WORD);
232 }while(--cnt>=0);
233 break;
234 case 2:
235 src=*it++;
237 *dst++=src;
238 while(--cnt>=0);
239 break;
240 case 3:
241 src=*(QUAD *)it;
242 it +=sizeof(QUAD);
245 *(QUAD *)dst=src;
246 dst+=sizeof(QUAD);
247 }while(--cnt>=0);
248 break;
250 break;
253 /* Align next instruction byte */
254 it=(UBYTE *)(((IPTR)it+AROS_WORDALIGN-1)&~(AROS_WORDALIGN-1));
256 AROS_LIBFUNC_EXIT