New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / rom / exec / newallocentry.c
blobafa38a08f1e1acd9861f4dae4e400c11bc72bcdd
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Allocate memory.
6 Lang: english
7 */
8 #include <aros/config.h>
9 #include "exec_intern.h"
10 #include <aros/libcall.h>
11 #include <exec/memory.h>
12 #include <proto/exec.h>
14 #include "exec_debug.h"
15 #ifndef DEBUG_NewAllocEntry
16 # define DEBUG_NewAllocEntry 0
17 #endif
18 #undef DEBUG
19 #if DEBUG_NewAllocEntry
20 # define DEBUG 1
21 #endif
22 #include <aros/debug.h>
23 #undef kprintf
25 /*****************************************************************************
27 NAME */
29 AROS_LH3(BOOL, NewAllocEntry,
31 /* SYNOPSIS */
32 AROS_LHA(struct MemList *, entry, A0),
33 AROS_LHA(struct MemList **, return_entry, A1),
34 AROS_LHA(ULONG *, return_flags, D0),
36 /* LOCATION */
37 struct ExecBase *, SysBase, 151, Exec)
39 /* FUNCTION
40 Allocate a number of memory blocks through a MemList structure.
42 INPUTS
43 entry - The MemList with one MemEntry for each block you want to get
44 return_entry - Pointer to struct MemList *variable where the address
45 of the MemList allocated by this function will be stored.
46 return_flags - Pointer to ULONG variable where upon failure the type of
47 memory that could not be allocated is stored. You may pass
48 NULL here.
50 RESULT
51 TRUE if the allocation was successful. In this case *return_entry will
52 be set to the address of the allocated MemList. *return_flags will be set
53 to 0.
55 FALSE if the allocation failed. In this case *return_entry will be set
56 to NULL and *return_flags will be set to contain the type of memory that
57 couldn't be allocated.
59 NOTES
61 EXAMPLE
63 BUGS
65 SEE ALSO
66 AllocEntry(), FreeEntry()
68 INTERNALS
70 ******************************************************************************/
72 AROS_LIBFUNC_INIT
74 struct MemList *ret;
75 ULONG mlsize, i;
77 D(bug("NewAllocEntry $%lx num=%d\ttask=\"%s\"\n", entry, entry->ml_NumEntries, SysBase->ThisTask->tc_Node.ln_Name));
79 #if DEBUG > 0
80 for(i = 0; i < entry->ml_NumEntries; i++)
82 kprintf("\treq $%lx\tsize $%lx\n", entry->ml_ME[i].me_Reqs, entry->ml_ME[i].me_Length);
84 #endif
86 /* Calculate size of a MemList with ml_NumEntries MemEntries. */
87 mlsize = sizeof(struct MemList) - sizeof(struct MemEntry) +
88 sizeof(struct MemEntry) * entry->ml_NumEntries;
90 /* Get the MemList structure */
91 ret = (struct MemList *)AllocMem(mlsize, MEMF_PUBLIC);
93 /* The allocation failed? Return "no public memory" */
94 if(ret == NULL)
96 *return_entry = NULL;
97 if (return_flags) *return_flags = MEMF_PUBLIC;
98 return FALSE;
101 /* Init new struct */
102 ret->ml_NumEntries = entry->ml_NumEntries;
103 ret->ml_Node.ln_Type = 0;
104 ret->ml_Node.ln_Pri = 0;
105 ret->ml_Node.ln_Name = NULL;
107 /* Fill all entries */
108 for(i = 0; i < entry->ml_NumEntries; i++)
110 #if (AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
112 Somewhat of a compatibility kludge: some programs rely that
113 AllocEntry() doesn't fail if the length field is 0.
115 E.g. CrossDos' PCx wants to allocate 7 memory regions, but the
116 last two fields are empty.
118 Should this be turned into a feature and be noted in the autodoc?
119 The original behaves this way, but it is, AFAIK, not documented to do
120 so. Comments?
122 if(entry->ml_ME[i].me_Length)
124 #endif
125 /* Get one */
126 ret->ml_ME[i].me_Addr = AllocMem(entry->ml_ME[i].me_Length,
127 entry->ml_ME[i].me_Reqs);
128 /* Got it? */
129 if(ret->ml_ME[i].me_Addr == NULL)
131 /* No. Set return flags to "none of the 'ml_ME[i].me_Reqs' memory". */
132 if (return_flags) *return_flags = entry->ml_ME[i].me_Reqs;
134 /* Free everything allocated until now... */
135 for( ; i-->0; )
137 FreeMem(ret->ml_ME[i].me_Addr, ret->ml_ME[i].me_Length);
140 /* ...including the MemList */
141 FreeMem(ret, mlsize);
143 /* All done */
144 *return_entry = NULL;
146 return FALSE;
148 #if (AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
150 else /* if length = 0 */
152 ret->ml_ME[i].me_Addr = NULL;
154 #endif
155 /* Copy the Length field */
156 ret->ml_ME[i].me_Length = entry->ml_ME[i].me_Length;
159 /* Everything filled. Return OK. */
160 *return_entry = ret;
161 if (return_flags) *return_flags = 0;
163 return TRUE;
165 AROS_LIBFUNC_EXIT
166 } /* AllocEntry */