Don't call InvertPixelArray with negative width and/or height.
[tangerine.git] / arch / .unmaintained / i386-cygwin / exec / init.c
blobf4c214b1f9260d373f1e14474b8156f5a9a2caa3
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Linux init code for emulated (Unix) systems.
6 Lang: english
7 */
9 #include <exec/types.h>
10 #include <exec/memory.h>
11 #include <exec/resident.h>
12 #include <exec/execbase.h>
14 #include <proto/exec.h>
16 #if (AROS_BIG_ENDIAN == 0)
17 #define SWAP(x) ((((ULONG)x >> 24) & 0x000000ff) |\
18 (((ULONG)x >> 8 ) & 0x0000ff00) |\
19 (((ULONG)x << 8 ) & 0x00ff0000) |\
20 (((ULONG)x << 24) & 0xff000000) )
21 #else
22 #define SWAP(x) x
23 #endif
25 #include <sys/mman.h>
26 #include <unistd.h>
28 #include <memory.h> /* From $(TOP)/rom/exec */
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <sys/termios.h>
34 extern const struct Resident
35 Expansion_resident,
36 Exec_resident,
37 Utility_resident,
38 Aros_resident,
39 /* BOOPSI_resident, */
40 OOP_resident,
41 HIDD_resident,
42 UnixIO_resident,
43 Graphics_resident,
44 Layers_resident,
45 Timer_resident,
46 Battclock_resident,
47 Keyboard_resident,
48 Gameport_resident,
49 Keymap_resident,
50 Input_resident,
51 Intuition_resident,
52 X11Hidd_resident,
53 Cybergraphics_resident,
54 Console_resident,
55 Mathffp_resident,
56 Mathieeesingbas_resident,
57 Workbench_resident,
58 Dos_resident,
59 LDDemon_resident,
60 emul_handler_resident,
61 boot_resident,
62 con_handler_resident;
66 /* This list MUST be in the correct order (priority). */
67 static const struct Resident *romtagList[] =
69 &Expansion_resident, /* SingleTask, 110 */
70 &Exec_resident, /* SingleTask, 105 */
71 &Utility_resident, /* ColdStart, 103 */
72 &Aros_resident, /* ColdStart, 102 */
73 &Mathieeesingbas_resident, /* ColdStart, 101 */
74 #if 0
75 &BOOPSI_resident, /* ColdStart, 95 */
76 #endif
77 &OOP_resident, /* ColdStart, 94 */
78 &HIDD_resident, /* ColdStart, 92 */
79 &UnixIO_resident, /* ColdStart, 91 */
80 &Graphics_resident, /* ColdStart, 65 */
81 &Layers_resident, /* ColdStart, 60 */
82 &Timer_resident, /* ColdStart, 50 */
83 &Battclock_resident, /* ColdStart, 45 */
84 &Keyboard_resident, /* ColdStart, 44 */
85 &Gameport_resident, /* ColdStart, 43 */
86 &Keymap_resident, /* ColdStart, 40 */
87 &Input_resident, /* ColdStart, 30 */
88 &Intuition_resident, /* ColdStart, 10 */
89 &X11Hidd_resident, /* ColdStart, 9 */
90 &Cybergraphics_resident, /* ColdStart, 8 */
91 &Console_resident, /* ColdStart, 5 */
92 &emul_handler_resident, /* ColdStart, 0 */
93 &Workbench_resident, /* ColdStart, -120 */
94 &Mathffp_resident, /* ColdStart, -120 */
97 NOTE: You must not put anything between these two; the code which
98 initialized boot_resident will directly call Dos_resident and
99 anything between the two will be skipped.
101 &boot_resident, /* ColdStart, -50 */
102 &Dos_resident, /* None, -120 */
103 &LDDemon_resident, /* AfterDOS, -125 */
104 &con_handler_resident, /* AfterDOS, -126 */
106 NULL
109 /* So we can examine the memory */
110 struct MemHeader *mh;
111 UBYTE *memory, *space;
112 int memSize = 8;
114 extern void InitCore(void);
115 extern struct ExecBase *PrepareExecBase(struct MemHeader *mh);
118 This is where AROS is first called by whatever system loaded it,
119 either some kind of boot loader, or a "parent" operating system.
121 For boot loaded $(ARCH), you don't need to define main() like this,
122 you can have it anyway your bootloader likes.
125 int main(int argc, char **argv)
127 /* Well, if you want you can take in command line arguments here,
128 but that is not necessary, or perhaps rather complex...
130 eg: say you wished to allow people to specify the root directory
131 arosshell --rootdir /usr/local/AROS --memsize 4
133 For an example, you could ask how much memory you want for the
134 system, chip/fast whatever...
137 struct ExecBase *SysBase;
138 struct termios t;
139 int psize = 0;
140 int i = 0, x;
141 BOOL mapSysBase = FALSE;
143 while (i < argc)
145 if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h"))
147 printf("AROS for Linux\n");
148 printf("usage: %s [options]\n",argv[0]);
149 printf(" -h show this page\n");
150 printf(" -m <size> allocate <size> Megabytes of memory for AROS\n");
151 printf(" -M allows programs to read SysBase from Address $4; SysBase is");
152 printf(" found there in big endian format\n");
153 printf(" --help same as '-h'\n");
154 printf(" --memsize <size> same as '-m <size>'\n");
155 printf(" --mapsysbase same as '-M'\n");
156 printf("\nPlease report bugs to the AROS development team. http://www.aros.org\n");
157 return 0;
159 else
160 if (!strcmp(argv[i], "--memsize") || !strcmp(argv[i], "-m"))
162 i++;
163 x = 0;
164 memSize = 0;
165 while ((argv[i])[x] >= '0' && (argv[i])[x] <= '9')
167 memSize = memSize * 10 + (argv[i])[x] - '0';
168 x++;
170 i++;
172 else
173 if (!strcmp(argv[i], "--mapsysbase") || !strcmp(argv[i], "-M"))
175 mapSysBase = TRUE;
176 i++;
178 else
179 i++;
183 First up, set up the memory.
185 If your memory starts at 0 (I think Linux does, FreeBSD doesn't),
186 then you can allocate 4K at that address, and do whatever you want
187 to make that invalid to trap NULL dereference errors.
191 if (TRUE == mapSysBase)
193 psize = getpagesize();
194 space = mmap((APTR)0, (memSize << 20), PROT_READ|PROT_WRITE,
195 MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
196 if (space != (UBYTE *)-1)
198 int size = psize/sizeof(ULONG);
199 memory = (UBYTE *)((ULONG)space + psize);
200 while(--size)
201 *((ULONG *)space)++ = 0xDEADBEEF;
203 else
205 perror("mmap");
206 exit(20);
209 else
211 /* We allocate memSize megabytes */
212 memory = malloc((memSize << 20));
213 if( !memory )
215 /*fprintf(stderr, "Cannot allocate any memory!\n");*/
216 exit(20);
220 /* Prepare the first mem header */
221 mh = (struct MemHeader *)memory;
222 mh->mh_Node.ln_Type = NT_MEMORY;
223 mh->mh_Node.ln_Name = "chip memory";
224 mh->mh_Node.ln_Pri = -5;
225 mh->mh_Attributes = MEMF_CHIP | MEMF_PUBLIC | MEMF_LOCAL |
226 MEMF_24BITDMA | MEMF_KICK;
227 mh->mh_First = (struct MemChunk *)((UBYTE *)mh+MEMHEADER_TOTAL);
228 mh->mh_First->mc_Next = NULL;
229 mh->mh_First->mc_Bytes = (memSize << 20) - MEMHEADER_TOTAL - psize;
230 mh->mh_Lower = mh->mh_First;
231 mh->mh_Upper = (APTR)(memory + (memSize << 20) - psize);
232 mh->mh_Free = mh->mh_First->mc_Bytes;
235 This will prepare enough of ExecBase to allow us to
236 call functions, it will also set up the memory list.
238 SysBase = PrepareExecBase(mh);
240 /* ROM memory header. This special memory header covers all ROM code and data sections
241 * so that TypeOfMem() will not return 0 for addresses pointing into the kernel.
243 if ((mh = (struct MemHeader *)AllocMem(sizeof(struct MemHeader), MEMF_PUBLIC)))
245 /* These symbols are provided by the linker on most platforms */
246 extern char _start, _end;
248 mh->mh_Node.ln_Type = NT_MEMORY;
249 mh->mh_Node.ln_Name = "rom memory";
250 mh->mh_Node.ln_Pri = -128;
251 mh->mh_Attributes = MEMF_KICK;
252 mh->mh_First = NULL;
253 mh->mh_Lower = (APTR)&_start;
254 mh->mh_Upper = (APTR)&_end;
255 mh->mh_Free = 0; /* Never allocate from this chunk! */
256 Forbid();
257 Enqueue(&SysBase->MemList, &mh->mh_Node);
260 /* Ok, lets start up the kernel, we are probably using the UNIX
261 kernel, or a variant of that (see config/unix).
263 InitCore();
265 /* On Linux/m68k where we can run old Amiga binaries, we should
266 put SysBase at location 4. On other systems, DON'T DO THIS.
268 if (TRUE == mapSysBase)
270 *(APTR *)4 = SWAP(SysBase);
271 if (mprotect((APTR)0, psize, PROT_READ))
273 perror("mprotect");
274 exit(10);
277 /* We might also be interested in using the BS key instead of the
278 delete key, this will do that
280 tcgetattr(0, &t);
281 t.c_cc[VERASE] = '\b';
282 #ifndef TCSASOFT
283 # define TCSASOFT 0
284 #endif
285 tcsetattr(0, TCSANOW|TCSASOFT, &t);
287 /* There is nothing more system dependant to set up,
288 so lets start that ball rolling...
290 The InitCode() call should never return in a working system.
292 SysBase->ResModules = romtagList;
293 InitCode(RTF_SINGLETASK, 0);
294 fprintf(stderr,"Returned from InitCode()\n");
295 return 1;