move delay code into separate function.
[AROS.git] / rom / exec / initstruct.c
blob1edcd9f210e07defe06c91dec98558d6cc05ff87
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Initialize a structure.
6 Lang: english
7 */
9 #include <aros/config.h>
10 #include <aros/libcall.h>
11 #include <proto/exec.h>
13 #include "exec_debug.h"
14 #include "exec_intern.h"
16 /*****************************************************************************
18 NAME */
20 AROS_LH3(void, InitStruct,
22 /* SYNOPSIS */
23 AROS_LHA(CONST_APTR, initTable, A1),
24 AROS_LHA(APTR, memory, A2),
25 AROS_LHA(ULONG, size, D0),
27 /* LOCATION */
28 struct ExecBase *, SysBase, 13, Exec)
30 /* FUNCTION
31 Initialize some library base or other structure depending on the
32 information in the init table. The init table consists of
33 instructions starting with an action byte followed by more
34 information. The instruction byte looks like:
36 iisscccc where ii is the instruction code:
37 0 - copy following c+1 elements
38 1 - repeat following element c+1 times
39 2 - take next byte as offset, then copy
40 3 - take the next 3 bytes (in the machine's
41 particular byte ordering) as offset, then
42 copy
43 ss is the element size
44 0 - LONGs
45 1 - WORDs
46 2 - BYTEs
47 3 - QUADs
48 cccc is the element count-1
50 Instruction bytes must follow the same alignment restrictions as LONGs;
51 the following elements are aligned to their particular restrictions.
53 A 0 instruction ends the init table.
55 INPUTS
56 initTable - Pointer to init table.
57 memory - Pointer to uninitialized structure.
58 size - Size of memory area to zero out before decoding or 0
59 for no filling.
61 RESULT
63 NOTES
65 EXAMPLE
67 BUGS
69 SEE ALSO
71 INTERNALS
73 ******************************************************************************/
75 AROS_LIBFUNC_INIT
77 LONG cnt;
78 ULONG offset=0;
79 QUAD src;
80 UBYTE *it,*dst;
81 int s,t;
83 DCREATELIBRARY("InitStruct(0x%p, 0x%p, %lu)", initTable, memory, size);
85 #if (AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
86 /* On 'real' Amigas, only the lower 16 bits are valid */
87 size &= 0xffff;
88 #endif
90 /* Clear Memory area. Use librom's memset() */
91 memset(memory, 0x00, size);
93 it =(UBYTE *)initTable;
94 dst=(UBYTE *)memory;
96 /* As long as there's something to do */
97 while(*it!=0)
99 /* What to do. */
100 t=*it>>6&3;
102 /* Element size. */
103 s=*it>>4&3;
105 /* Number of things to do (-1). */
106 cnt=*it&15;
108 /* Depending on the action there may be more information */
109 switch(t)
111 case 0:
112 case 1:
113 /* Skip the action byte */
114 it++;
115 break;
116 case 2:
117 /* Skip the action byte, get the offset */
118 it++;
119 offset=*it++;
120 break;
121 case 3:
123 Get 24bit offset. It's the programmer's responsibility
124 to align the action byte with a LONG instruction before
125 this.
127 #if AROS_BIG_ENDIAN
128 offset=*(ULONG *)it&0xffffff;
129 #else
130 offset=it[1] | ((*(UWORD *)&it[2]) << 8);
131 #endif
132 it+=sizeof(LONG);
133 break;
136 /* Align source and destination pointers */
137 switch(s)
139 case 0:
140 /* Align pointer to LONG requirements */
141 it =(UBYTE *)(((IPTR)it +AROS_LONGALIGN-1)&~(AROS_LONGALIGN-1));
142 dst=(UBYTE *)(((IPTR)dst+AROS_LONGALIGN-1)&~(AROS_LONGALIGN-1));
143 break;
144 case 1:
145 /* Same for WORDs */
146 it =(UBYTE *)(((IPTR)it +AROS_WORDALIGN-1)&~(AROS_WORDALIGN-1));
147 dst=(UBYTE *)(((IPTR)dst+AROS_WORDALIGN-1)&~(AROS_WORDALIGN-1));
148 break;
149 case 2:
150 /* Nothing to do for bytes */
151 break;
152 case 3:
153 /* Align pointer to QUAD requirements */
154 it =(UBYTE *)(((IPTR)it +AROS_QUADALIGN-1)&~(AROS_QUADALIGN-1));
155 dst=(UBYTE *)(((IPTR)dst+AROS_QUADALIGN-1)&~(AROS_QUADALIGN-1));
156 break;
159 /* Switch over action */
160 switch(t)
162 case 2:
163 case 3:
164 /* Action is: Add offset then copy */
165 dst=(BYTE *)memory+offset;
167 /* Fall through */
168 case 0:
169 /* Action is: Copy the next <cnt> elements to the current location */
170 switch(s)
172 case 0:
173 /* Copy loop */
176 *(LONG *)dst=*(LONG *)it;
177 dst+=sizeof(LONG);
178 it +=sizeof(LONG);
179 }while(--cnt>=0);
180 break;
181 case 1:
184 *(WORD *)dst=*(WORD *)it;
185 dst+=sizeof(WORD);
186 it +=sizeof(WORD);
187 }while(--cnt>=0);
188 break;
189 case 2:
191 *dst++=*it++;
192 while(--cnt>=0);
193 break;
194 case 3:
197 *(QUAD *)dst=*(QUAD *)it;
198 dst+=sizeof(QUAD);
199 it +=sizeof(QUAD);
200 }while(--cnt>=0);
201 break;
203 break;
204 case 1:
205 /* Action is: Repeat the next element <cnt> times */
206 switch(s)
208 case 0:
209 /* Get source */
210 src=*(LONG *)it;
211 it +=sizeof(LONG);
213 /* And write it. */
216 *(LONG *)dst=src;
217 dst+=sizeof(LONG);
218 }while(--cnt>=0);
219 break;
220 case 1:
221 src=*(WORD *)it;
222 it +=sizeof(WORD);
225 *(WORD *)dst=src;
226 dst+=sizeof(WORD);
227 }while(--cnt>=0);
228 break;
229 case 2:
230 src=*it++;
232 *dst++=src;
233 while(--cnt>=0);
234 break;
235 case 3:
236 src=*(QUAD *)it;
237 it +=sizeof(QUAD);
240 *(QUAD *)dst=src;
241 dst+=sizeof(QUAD);
242 }while(--cnt>=0);
243 break;
245 break;
248 /* Align next instruction byte */
249 it=(UBYTE *)(((IPTR)it+AROS_WORDALIGN-1)&~(AROS_WORDALIGN-1));
251 AROS_LIBFUNC_EXIT