2 * Copyright 2020-2021 Niklas Ekström
5 #include <exec/types.h>
6 #include <exec/execbase.h>
7 #include <exec/memory.h>
8 #include <proto/exec.h>
9 #include <proto/graphics.h>
12 #include "fix_mem_region.h"
17 struct MemChunk *first;
18 struct MemChunk *last;
22 void add_chunk(struct MemChunkList *l, struct MemChunk *mc)
27 l->last->mc_Next = mc;
29 l->free += mc->mc_Bytes;
32 struct MemHeader *split_region(struct MemHeader *lower, ULONG split_at)
34 struct MemHeader *upper = (struct MemHeader *)AllocMem(sizeof(struct MemHeader), MEMF_PUBLIC | MEMF_CLEAR);
36 struct MemChunkList ll = {NULL, NULL, 0};
37 struct MemChunkList ul = {NULL, NULL, 0};
39 struct MemChunk *mc = lower->mh_First;
43 struct MemChunk *next_chunk = mc->mc_Next;
46 ULONG start = (ULONG)mc;
47 ULONG end = start + mc->mc_Bytes;
51 else if (split_at <= start)
55 mc->mc_Bytes = split_at - start;
58 struct MemChunk *new_chunk = (struct MemChunk *)split_at;
59 new_chunk->mc_Next = NULL;
60 new_chunk->mc_Bytes = end - split_at;
61 add_chunk(&ul, new_chunk);
66 upper->mh_Node.ln_Type = NT_MEMORY;
67 upper->mh_Node.ln_Pri = lower->mh_Node.ln_Pri;
68 upper->mh_Node.ln_Name = lower->mh_Node.ln_Name; // Use a custom name?
69 upper->mh_Attributes = lower->mh_Attributes;
71 lower->mh_First = ll.first;
72 upper->mh_First = ul.first;
74 upper->mh_Lower = (APTR)split_at;
75 upper->mh_Upper = lower->mh_Upper;
76 lower->mh_Upper = (APTR)split_at;
78 lower->mh_Free = ll.free;
79 upper->mh_Free = ul.free;
84 BOOL overlap(struct MemHeader *mh, ULONG lower, ULONG upper)
86 return lower < (ULONG)(mh->mh_Upper) && (ULONG)(mh->mh_Lower) < upper;
89 void mark_region_a314(ULONG address, ULONG size)
91 struct List *memlist = &(SysBase->MemList);
93 for (struct Node *node = memlist->lh_Head; node->ln_Succ != NULL; node = node->ln_Succ)
95 struct MemHeader *mh = (struct MemHeader *)node;
96 if (overlap(mh, address, address + size))
98 if ((ULONG)mh->mh_Lower < address)
100 mh->mh_Attributes &= ~MEMF_A314;
101 mh = split_region(mh, address);
104 Remove((struct Node *)mh);
106 if (address + size < (ULONG)mh->mh_Upper)
108 struct MemHeader *new_mh = split_region(mh, address + size);
109 new_mh->mh_Attributes &= ~MEMF_A314;
110 Enqueue(memlist, (struct Node *)new_mh);
113 mh->mh_Attributes |= MEMF_A314;
114 Enqueue(memlist, (struct Node *)mh);
123 mark_region_a314(ca->mem_base, ca->mem_size);
128 ULONG translate_address_a314(__reg("a0") void *address)
130 ULONG offset = (ULONG)address - ca->mem_base;
131 if (offset < ca->mem_size)