home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / rom / exec / initstruct.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-09  |  4.8 KB  |  248 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: initstruct.c,v 1.12 1997/01/01 03:46:11 ldp Exp $
  4.  
  5.     Desc:
  6.     Lang: english
  7. */
  8. #include "exec_intern.h"
  9. #include <aros/libcall.h>
  10. #include <exec/alerts.h>
  11. #include <aros/machine.h>
  12. #include <proto/exec.h>
  13.  
  14. /*****************************************************************************
  15.  
  16.     NAME */
  17.  
  18.     AROS_LH3(void, InitStruct,
  19.  
  20. /*  SYNOPSIS */
  21.     AROS_LHA(APTR,  initTable, A1),
  22.     AROS_LHA(APTR,  memory,    A2),
  23.     AROS_LHA(ULONG, size,      D0),
  24.  
  25. /*  LOCATION */
  26.     struct ExecBase *, SysBase, 13, Exec)
  27.  
  28. /*  FUNCTION
  29.     Initialize some library base or other structure depending on the
  30.     information in the init table. The init table consists of
  31.     instructions starting with an action byte followed by more
  32.     information. The instruction byte looks like:
  33.  
  34.     iisscccc where ii is the instruction code:
  35.               0 - copy following c+1 elements
  36.               1 - repeat following element c+1 times
  37.               2 - take next byte as offset, then copy
  38.               3 - take the next 3 bytes (in the machine's
  39.                   particular byte ordering) as offset, then
  40.                   copy
  41.                ss is the element size
  42.               0 - LONGs
  43.               1 - WORDs
  44.               2 - BYTEs
  45.                cccc is the element count-1
  46.  
  47.     Instruction bytes must follow the same alignement restrictions as LONGs,
  48.     the following elements are aligned to their particular restrictions.
  49.  
  50.     A 0 instruction ends the init table.
  51.  
  52.     INPUTS
  53.     initTable - Pointer to init table.
  54.     memory      - Pointer to uninitialized structure.
  55.     size      - Size of memory area to 0 out before decoding or 0
  56.             for no filling.
  57.  
  58.     RESULT
  59.  
  60.     NOTES
  61.  
  62.     EXAMPLE
  63.  
  64.     BUGS
  65.  
  66.     SEE ALSO
  67.  
  68.     INTERNALS
  69.  
  70.     HISTORY
  71.  
  72. ******************************************************************************/
  73. {
  74.     AROS_LIBFUNC_INIT
  75.  
  76.     LONG  cnt;
  77.     ULONG offset=0,src;
  78.     UBYTE *it,*dst;
  79.     int   s,t;
  80.  
  81.     /* Clear Memory area fast. Get number of longs and clear them. */
  82.     cnt=size/sizeof(LONG);
  83.     size&=(sizeof(LONG)-1);
  84.     dst=(UBYTE *)memory;
  85.     if(cnt)
  86.     do
  87.     {
  88.         *(LONG *)dst=0;
  89.         dst+=sizeof(LONG);
  90.     }
  91.     while(--cnt);
  92.  
  93.     /* Clear the rest. */
  94.     cnt=size;
  95.     if(cnt)
  96.     do
  97.         *dst++=0;
  98.     while(--cnt);
  99.  
  100.     it =(UBYTE *)initTable;
  101.     dst=(UBYTE *)memory;
  102.  
  103.     /* As long as there's something to do */
  104.     while(*it!=0)
  105.     {
  106.     /* What to do. */
  107.     t=*it>>6&3;
  108.  
  109.     /* Element size. */
  110.     s=*it>>4&3;
  111.  
  112.     /* Number of things to do (-1). */
  113.     cnt=*it&15;
  114.  
  115.     /* Depending on the action there may be more information */
  116.     switch(t)
  117.     {
  118.         case 0:
  119.         case 1:
  120.         /* Skip the action byte */
  121.         it++;
  122.         break;
  123.         case 2:
  124.         /* Skip the action byte, get the offset */
  125.         it++;
  126.         offset=*it++;
  127.         break;
  128.         case 3:
  129.         /*
  130.             Get 24bit offset. It's the programmer's responsibility
  131.             to align the action byte with a LONG instruction before
  132.             this.
  133.         */
  134. #if AROS_BIG_ENDIAN
  135.         offset=*(ULONG *)it&0xffffff;
  136. #else
  137.         offset=*(ULONG *)it>>8;
  138. #endif
  139.         it+=sizeof(LONG);
  140.         break;
  141.     }
  142.  
  143.     /* Align source and destination pointers */
  144.     switch(s)
  145.     {
  146.         case 0:
  147.         /* Align pointer to LONG requirements */
  148.         it =(UBYTE *)(((IPTR)it +AROS_LONGALIGN-1)&~(AROS_LONGALIGN-1));
  149.         dst=(UBYTE *)(((IPTR)dst+AROS_LONGALIGN-1)&~(AROS_LONGALIGN-1));
  150.         break;
  151.         case 1:
  152.         /* Same for WORDs */
  153.         it =(UBYTE *)(((IPTR)it +AROS_WORDALIGN-1)&~(AROS_WORDALIGN-1));
  154.         dst=(UBYTE *)(((IPTR)dst+AROS_WORDALIGN-1)&~(AROS_WORDALIGN-1));
  155.         break;
  156.         case 2:
  157.         /* Nothing to do for bytes */
  158.         break;
  159.         default:
  160.         /* And an Alert for nibbles ;-) */
  161.         Alert(ACPU_AddressErr);
  162.  
  163.         /*
  164.             Tell the compiler that he doesn't need to
  165.             care about side effects of Alert()
  166.         */
  167.         return;
  168.     }
  169.  
  170.     /* Switch over action */
  171.     switch(t)
  172.     {
  173.         case 2:
  174.         case 3:
  175.         /* Action is: Add offset then copy */
  176.         dst=(BYTE *)memory+offset;
  177.  
  178.         /* Fall through */
  179.         case 0:
  180.         /* Action is: Copy the next <cnt> elements to the current location */
  181.         switch(s)
  182.         {
  183.             case 0:
  184.             /* Copy loop */
  185.             do
  186.             {
  187.                 *(LONG *)dst=*(LONG *)it;
  188.                 dst+=sizeof(LONG);
  189.                 it +=sizeof(LONG);
  190.             }while(--cnt>=0);
  191.             break;
  192.             case 1:
  193.             do
  194.             {
  195.                 *(WORD *)dst=*(WORD *)it;
  196.                 dst+=sizeof(WORD);
  197.                 it +=sizeof(WORD);
  198.             }while(--cnt>=0);
  199.             break;
  200.             case 2:
  201.             do
  202.                 *dst++=*it++;
  203.             while(--cnt>=0);
  204.             break;
  205.         }
  206.         break;
  207.         case 1:
  208.         /* Action is: Repeat the next element <cnt> times */
  209.         switch(s)
  210.         {
  211.             case 0:
  212.             /* Get source */
  213.             src=*(LONG *)it;
  214.             it +=sizeof(LONG);
  215.  
  216.             /* And write it. */
  217.             do
  218.             {
  219.                 *(LONG *)dst=src;
  220.                 dst+=sizeof(LONG);
  221.             }while(--cnt>=0);
  222.             break;
  223.             case 1:
  224.             src=*(WORD *)it;
  225.             it +=sizeof(WORD);
  226.             do
  227.             {
  228.                 *(WORD *)dst=src;
  229.                 dst+=sizeof(WORD);
  230.             }while(--cnt>=0);
  231.             break;
  232.             case 2:
  233.             src=*it++;
  234.             do
  235.                 *dst++=src;
  236.             while(--cnt>=0);
  237.             break;
  238.         }
  239.         break;
  240.     }
  241.  
  242.     /* Align next instruction byte */
  243.     it=(UBYTE *)(((IPTR)it+AROS_LONGALIGN-1)&~(AROS_LONGALIGN-1));
  244.     }
  245.     AROS_LIBFUNC_EXIT
  246. }
  247.  
  248.