2 * Copyright (C) 2011-2017, The AROS Development Team. All rights reserved.
3 * Author: Jason S. McMullan <jason.mcmullan@gmail.com>
5 * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
10 #include <proto/exec.h>
11 #include <exec/memory.h>
13 #include "amiga_hwreg.h"
18 void Early_ScreenCode(ULONG code
)
20 reg_w(BPLCON0
, 0x0200);
21 reg_w(BPL1DAT
, 0x0000);
22 reg_w(COLOR00
, code
& RGB_MASK
);
25 void Early_Alert(ULONG alert
)
27 const int bright
= ((alert
>> 4) & 1) ? 0xf : 0x7;
29 RGB(((alert
>> 2) & 1) * bright
,
30 ((alert
>> 1) & 1) * bright
,
31 ((alert
>> 0) & 1) * bright
);
33 DEBUGPUTHEX(("Early_Alert", alert
));
37 Early_ScreenCode(color
);
38 for (i
= 0; i
< 100000; i
++);
39 Early_ScreenCode(0x000);
40 for (i
= 0; i
< 100000; i
++);
42 if (!(alert
& AT_DeadEnd
))
47 /* Fatal trap for early problems */
48 extern void Exec_MagicResetCode(void);
49 void __attribute__((interrupt
)) Early_TrapHandler(void)
52 Early_ScreenCode(CODE_TRAP_FAIL
);
54 /* If we have a valid SysBase, then
55 * we can run the debugger.
60 Early_Alert(AT_DeadEnd
| 1);
62 /* Sleep for a while */
63 for (i
= 0; i
< 100000; i
++);
65 /* Reset everything but the CPU, then restart
66 * at the ROM exception vector
68 Exec_MagicResetCode();
71 APTR
Early_AllocAbs(struct MemHeader
*mh
, APTR location
, IPTR byteSize
)
74 APTR endlocation
= location
+ byteSize
;
75 struct MemChunk
*p1
, *p2
, *p3
, *p4
;
77 if (mh
->mh_Lower
> location
|| mh
->mh_Upper
< endlocation
)
80 /* Align size to the requirements */
81 byteSize
+= (IPTR
)location
&(MEMCHUNK_TOTAL
- 1);
82 byteSize
= (byteSize
+ MEMCHUNK_TOTAL
-1) & ~(MEMCHUNK_TOTAL
-1);
84 /* Align the location as well */
85 location
=(APTR
)((IPTR
)location
& ~(MEMCHUNK_TOTAL
-1));
87 /* Start and end(+1) of the block */
88 p3
=(struct MemChunk
*)location
;
89 p4
=(struct MemChunk
*)((UBYTE
*)p3
+byteSize
);
92 The free memory list is only single linked, i.e. to remove
93 elements from the list I need the node's predessor. For the
94 first element I can use freeList->mh_First instead of a real
97 p1
= (struct MemChunk
*)&mh
->mh_First
;
100 /* Follow the list to find a chunk with our memory. */
103 /* Found a chunk that fits? */
104 if((UBYTE
*)p2
+p2
->mc_Bytes
>=(UBYTE
*)p4
&&p2
<=p3
)
106 /* Check if there's memory left at the end. */
107 if((UBYTE
*)p2
+p2
->mc_Bytes
!=(UBYTE
*)p4
)
109 /* Yes. Add it to the list */
110 p4
->mc_Next
= p2
->mc_Next
;
111 p4
->mc_Bytes
= (UBYTE
*)p2
+p2
->mc_Bytes
-(UBYTE
*)p4
;
115 /* Check if there's memory left at the start. */
117 /* Yes. Adjust the size */
118 p2
->mc_Bytes
=(UBYTE
*)p3
-(UBYTE
*)p2
;
120 /* No. Skip the old chunk */
121 p1
->mc_Next
=p2
->mc_Next
;
123 /* Adjust free memory count */
124 mh
->mh_Free
-=byteSize
;
126 /* Return the memory */
130 /* goto next chunk */