Correct internal bootconfig data
[tangerine.git] / rom / bootmenu / menu.c
blob9afb01e0162872895f4dad97ffcca9ea56c70f72
1 #define DEBUG 0
2 #include <aros/debug.h>
4 #include <proto/bootloader.h>
5 #include <proto/exec.h>
6 #include <proto/graphics.h>
7 #include <proto/intuition.h>
8 #include <devices/keyboard.h>
9 #include <devices/rawkeycodes.h>
10 #include <devices/timer.h>
11 #include <exec/memory.h>
12 #include <graphics/gfxbase.h>
13 #include <libraries/bootmenu.h>
14 #include <libraries/expansionbase.h>
15 #include <aros/bootloader.h>
16 #include <aros/symbolsets.h>
17 #include <string.h>
18 #include "devs_private.h"
20 #include "bootmenu_intern.h"
22 #include LC_LIBDEFS_FILE
24 #define BUFSIZE 100
26 #undef ExpansionBase
27 #define ExpansionBase BootMenuBase->bm_ExpansionBase
29 #if 0
30 struct GfxBase *GfxBase;
31 struct RastPort rp;
32 struct ViewPort vp;
34 static const ULONG coltab[] = {
35 (16L << 16) + 0, /* 16 colors, loaded at index 0 */
37 /* X11 color names */
38 0xB3B3B3B3, 0xB3B3B3B3, 0xB3B3B3B3, /* Grey70 */
39 0x00000000, 0x00000000, 0x00000000, /* Black */
40 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, /* White */
41 0x66666666, 0x88888888, 0xBBBBBBBB, /* AMIGA Blue */
43 0x00000000, 0x00000000, 0xFFFFFFFF, /* Blue */
44 0x00000000, 0xFFFFFFFF, 0x00000000, /* Green */
45 0xFFFFFFFF, 0x00000000, 0x00000000, /* Red */
46 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, /* Cyan */
48 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, /* Magenta */
49 0xEEEEEEEE, 0x82828282, 0xEEEEEEEE, /* Violet */
50 0xA5A5A5A5, 0x2A2A2A2A, 0x2A2A2A2A, /* Brown */
51 0xFFFFFFFF, 0xE4E4E4E4, 0xC4C4C4C4, /* Bisque */
53 0xE6E6E6E6, 0xE6E6E6E6, 0xFAFAFAFA, /* Lavender */
54 0x00000000, 0x00000000, 0x80808080, /* Navy */
55 0xF0F0F0F0, 0xE6E6E6E6, 0x8C8C8C8C, /* Khaki */
56 0xA0A0A0A0, 0x52525252, 0x2D2D2D2D, /* Sienna */
57 0L /* Termination */
60 static ULONG pointercoltab[] = {
62 0xE0E0E0E0, 0x40404040, 0x40404040,
63 0x00000000, 0x00000000, 0x00000000,
64 0xE0E0E0E0, 0xE0E0E0E0, 0xC0C0C0C0,
68 BOOL initScreen(STRPTR gfxhiddname, struct BootMenuBase *BootMenuBase)
70 struct TagItem modetags[] =
72 {BIDTAG_Depth, 2},
73 {BIDTAG_DesiredWidth, 640},
74 {BIDTAG_DesiredHeight, 200},
75 {TAG_DONE, 0UL}
77 ULONG modeid, depth;
79 D(bug("[BootMenu] initScreen(gfxhidd='%s')\n", gfxhiddname));
81 GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37);
82 if (GfxBase)
84 if (LateGfxInit(gfxhiddname))
86 modeid = BestModeIDA(modetags);
87 if (modeid != INVALID_ID)
89 InitRastPort(&rp);
90 InitVPort(&vp);
91 rp.BitMap = AllocScreenBitMap(modeid);
92 if (rp.BitMap)
94 vp.RasInfo = AllocMem(sizeof(struct RasInfo), MEMF_ANY | MEMF_CLEAR);
95 if (vp.RasInfo)
97 vp.RasInfo->BitMap = rp.BitMap;
98 vp.ColorMap = GetColorMap(4);
99 vp.ColorMap->VPModeID = modeid;
100 if (AttachPalExtra(vp.ColorMap, &vp) == 0)
102 LoadRGB32(&vp, (ULONG *)coltab);
103 depth = GetBitMapAttr(rp.BitMap, BMA_DEPTH);
104 if (depth > 4)
105 pointercoltab[0] = (3L << 16) + 17;
106 else
107 pointercoltab[0] = (3L << 16) + (1 << depth) - 3;
108 LoadRGB32(&vp, pointercoltab);
109 rp.BitMap->Flags |= BMF_AROS_HIDD;
110 SetFont(&rp, GfxBase->DefaultFont);
111 SetFrontBitMap(rp.BitMap, TRUE);
112 Forbid();
113 rp.Font->tf_Accessors++;
114 Permit();
115 SetAPen(&rp, 1);
116 Move(&rp, 100, 100);
117 Text(&rp, "Sucker", 6);
118 kprintf("done\n");
119 return TRUE;
121 FreeMem(vp.RasInfo, sizeof(struct RasInfo));
123 FreeBitMap(rp.BitMap);
127 CloseLibrary((struct Library *)GfxBase);
129 kprintf("no screen!\n");
130 return FALSE;
132 #else
134 /*****************
135 ** init_gfx() **
136 *****************/
138 static BOOL init_gfx(STRPTR gfxclassname, struct BootMenuBase *BootMenuBase)
140 BOOL success = FALSE;
141 D(bug("[BootMenu] init_gfx(hiddbase='%s')\n", gfxclassname));
143 /* Call private gfx.library call to init the HIDD.
144 Gfx library is responsable for closing the HIDD
145 library (although it will probably not be neccesary).
148 D(bug("[BootMenu] init_gfx: calling private gfx LateGfxInit() .."));
149 if (LateGfxInit(gfxclassname))
151 D(bug("Success\n"));
152 if (IntuitionBase)
154 if (LateIntuiInit(NULL))
156 success = TRUE;
160 else
162 D(bug("Failed\n"));
164 ReturnBool ("init_gfxhidd", success);
168 static BOOL init_device( STRPTR hiddclassname, STRPTR devicename, struct BootMenuBase *BootMenuBase)
170 BOOL success = FALSE;
171 struct MsgPort *mp = NULL;
173 D(bug("[BootMenu] init_device(classname='%s', devicename='%s')\n", hiddclassname, devicename));
175 if ((mp = CreateMsgPort()) != NULL)
177 struct IORequest *io = NULL;
178 if ((io = CreateIORequest(mp, sizeof ( struct IOStdReq))) != NULL)
180 if (0 == OpenDevice(devicename, 0, io, 0))
182 #define ioStd(x) ((struct IOStdReq *)x)
183 ioStd(io)->io_Command = CMD_HIDDINIT;
184 ioStd(io)->io_Data = hiddclassname;
185 ioStd(io)->io_Length = strlen(hiddclassname);
187 /* Let the device init the HIDD */
188 DoIO(io);
189 if (0 == io->io_Error)
191 success = TRUE;
193 CloseDevice(io);
195 DeleteIORequest(io);
197 DeleteMsgPort(mp);
199 ReturnBool("init_device", success);
202 static BOOL initHidds(struct BootConfig *bootcfg, struct BootMenuBase *BootMenuBase)
204 D(bug("[BootMenu] initHidds()\n"));
206 OpenLibrary(bootcfg->defaultgfx.libname, 0);
207 init_gfx(bootcfg->defaultgfx.hiddname, BootMenuBase);
209 OpenLibrary(bootcfg->defaultmouse.libname, 0);
210 init_device(bootcfg->defaultmouse.hiddname, "gameport.device", BootMenuBase);
212 return TRUE;
215 static struct Gadget *createGadgets(struct BootMenuBase_intern *BootMenuBase)
217 struct Gadget *first;
218 struct ButtonGadget *last;
220 last = BootMenuBase->bm_MainGadgets.boot = createButton(16, 190, 280, 14, (struct Gadget *)&first, "Boot", BUTTON_BOOT, BootMenuBase);
221 if (last == NULL)
222 return NULL;
223 last = BootMenuBase->bm_MainGadgets.bootnss = createButton(344, 190, 280, 14, last->gadget, "Boot With No Startup-Sequence", BUTTON_BOOT_WNSS, BootMenuBase);
224 if (last == NULL)
225 return NULL;
226 last = BootMenuBase->bm_MainGadgets.bootopt = createButton(180, 63, 280, 14, last->gadget, "Boot Options...", BUTTON_BOOT_OPTIONS, BootMenuBase);
227 if (last == NULL)
228 return NULL;
229 last = BootMenuBase->bm_MainGadgets.displayopt = createButton(180, 84, 280, 14, last->gadget, "Display Options...", BUTTON_DISPLAY_OPTIONS, BootMenuBase);
230 if (last == NULL)
231 return NULL;
232 last = BootMenuBase->bm_MainGadgets.expboarddiag = createButton(180, 105, 280, 14, last->gadget, "Expansion Board Diagnostic...", BUTTON_EXPBOARDDIAG, BootMenuBase);
233 if (last == NULL)
234 return NULL;
235 return first;
238 static void freeGadgets(struct BootMenuBase_intern *BootMenuBase)
240 if (BootMenuBase->bm_MainGadgets.boot != NULL)
241 freeButtonGadget(BootMenuBase->bm_MainGadgets.boot, BootMenuBase);
242 if (BootMenuBase->bm_MainGadgets.bootnss != NULL);
243 freeButtonGadget(BootMenuBase->bm_MainGadgets.bootnss, BootMenuBase);
244 if (BootMenuBase->bm_MainGadgets.bootopt != NULL)
245 freeButtonGadget(BootMenuBase->bm_MainGadgets.bootopt, BootMenuBase);
246 if (BootMenuBase->bm_MainGadgets.displayopt != NULL)
247 freeButtonGadget(BootMenuBase->bm_MainGadgets.displayopt, BootMenuBase);
248 if (BootMenuBase->bm_MainGadgets.expboarddiag != NULL)
249 freeButtonGadget(BootMenuBase->bm_MainGadgets.expboarddiag, BootMenuBase);
252 static void msgLoop(struct BootMenuBase *BootMenuBase, struct Window *win, struct BootConfig *bcfg)
254 BOOL in=TRUE;
255 struct IntuiMessage *msg;
256 struct Gadget *g;
260 WaitPort(win->UserPort);
261 while ((msg=(struct IntuiMessage *)GetMsg(win->UserPort)))
263 if (msg->Class == IDCMP_GADGETUP)
265 g = msg->IAddress;
266 switch (g->GadgetID)
268 case BUTTON_BOOT:
269 ExpansionBase->Flags &= ~EBF_DOSFLAG;
270 in = FALSE;
271 break;
272 case BUTTON_BOOT_WNSS:
273 ExpansionBase->Flags |= EBF_DOSFLAG;
274 in = FALSE;
275 break;
278 ReplyMsg(&msg->ExecMessage);
280 } while (in);
281 while ((msg=(struct IntuiMessage *)GetMsg(win->UserPort)))
282 ReplyMsg(&msg->ExecMessage);
285 static BOOL initScreen(struct BootMenuBase_intern *BootMenuBase, struct BootConfig *bcfg)
287 UWORD pens[] = {~0};
288 struct TagItem scrtags[] =
290 {SA_Width, 640},
291 {SA_Height, 256},
292 {SA_Depth, 4},
293 {SA_Pens, (IPTR)pens},
294 {TAG_DONE, 0UL}
296 struct TagItem wintags[] =
298 {WA_Left, 0}, /* 0 */
299 {WA_Top, 0}, /* 1 */
300 {WA_Width, 640}, /* 2 */
301 {WA_Height, 256}, /* 3 */
302 {WA_CustomScreen, 0}, /* 4 */
303 {WA_Gadgets, NULL}, /* 5 */
304 {WA_IDCMP, IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_VANILLAKEY | IDCMP_GADGETUP | IDCMP_GADGETDOWN},
305 {WA_Borderless, TRUE},
306 {WA_RMBTrap, TRUE},
307 {TAG_DONE, 0UL}
309 struct Gadget *first = NULL;
311 BootMenuBase->bm_Screen = OpenScreenTagList(NULL, scrtags);
312 if (BootMenuBase->bm_Screen != NULL)
314 first = createGadgets(BootMenuBase);
315 if (first != NULL)
317 wintags[2].ti_Data = BootMenuBase->bm_Screen->Width;
318 wintags[3].ti_Data = BootMenuBase->bm_Screen->Height;
319 wintags[4].ti_Data = (IPTR)BootMenuBase->bm_Screen;
320 wintags[5].ti_Data = (IPTR)first;
321 BootMenuBase->bm_Window = OpenWindowTagList(NULL, wintags);
322 if (BootMenuBase->bm_Window != NULL)
324 SetAPen(BootMenuBase->bm_Window->RPort, 2);
325 Move(BootMenuBase->bm_Window->RPort, 215, 20);
326 Text(BootMenuBase->bm_Window->RPort, "AROS Early Startup Control", 26);
327 SetAPen(BootMenuBase->bm_Window->RPort, 1);
328 Move(BootMenuBase->bm_Window->RPort, 225, 40);
329 Text(BootMenuBase->bm_Window->RPort, "(what is PAL and NTSC?)", 23);
330 msgLoop(BootMenuBase, BootMenuBase->bm_Window, bcfg);
331 return TRUE;
333 else
334 Alert(AT_DeadEnd | AN_OpenWindow);
335 CloseWindow(BootMenuBase->bm_Window);
336 freeGadgets(BootMenuBase);
338 else
339 Alert(AT_DeadEnd | AN_BadGadget);
340 CloseScreen(BootMenuBase->bm_Screen);
342 else
343 Alert(AT_DeadEnd | AN_OpenScreen);
344 return FALSE;
347 static BOOL buttonsPressed(struct BootMenuBase *BootMenuBase, struct DefaultHidd *kbd)
349 BOOL success = FALSE;
350 struct MsgPort *mp = NULL;
351 UBYTE matrix[16];
353 if ((mp = CreateMsgPort()) != NULL)
355 struct IORequest *io = NULL;
356 if ((io = CreateIORequest(mp, sizeof ( struct IOStdReq))) != NULL)
358 if (0 == OpenDevice("keyboard.device", 0, io, 0))
360 D(bug("[BootMenu] buttonsPressed: Checking KBD_READMATRIX\n"));
361 #define ioStd(x) ((struct IOStdReq *)x)
362 ioStd(io)->io_Command = KBD_READMATRIX;
363 ioStd(io)->io_Data = matrix;
364 ioStd(io)->io_Length = 16;
365 DoIO(io);
366 if (0 == io->io_Error)
368 #if defined(DEBUG)
369 int i;
370 D(bug("[BootMenu] buttonsPressed: Matrix : "));
371 for (i = 0; i < sizeof(matrix); i ++)
373 D(bug("%2x ", matrix[i]));
375 D(bug("\n"));
376 #endif
377 if (matrix[RAWKEY_SPACE/8] & (1<<(RAWKEY_SPACE%8)))
378 success = TRUE;
380 CloseDevice(io);
382 DeleteIORequest(io);
384 DeleteMsgPort(mp);
386 return success;
389 #endif
391 static struct BootConfig bootcfg =
393 &bootcfg,
394 NULL,
395 {"vgah.hidd", "hidd.gfx.vga"},
396 {"kbd.hidd", "hidd.kbd.hw"},
397 {"mouse.hidd", "hidd.bus.mouse"},
400 static int bootmenu_EarlyPrep(LIBBASETYPEPTR LIBBASE)
402 D(bug("[BootMenu] bootmenu_EarlyPrep()\n"));
404 struct BootLoaderBase *BootLoaderBase = NULL;
405 struct VesaInfo *vi = NULL;
407 LIBBASE->bm_BootConfig = bootcfg;
408 struct DefaultHidd *kbd = &LIBBASE->bm_BootConfig.defaultkbd;
410 if ((ExpansionBase = OpenLibrary("expansion.library",0)) != NULL)
412 if ((BootLoaderBase = OpenResource("bootloader.resource")) != NULL)
414 if ((vi = (struct VesaInfo *)GetBootInfo(BL_Video)) != NULL)
416 if (vi->ModeNumber != 3)
418 strcpy(LIBBASE->bm_BootConfig.defaultgfx.libname, "vesagfx.hidd");
419 strcpy(LIBBASE->bm_BootConfig.defaultgfx.hiddname, "hidd.gfx.vesa");
424 if (OpenLibrary(kbd->libname, 0) != NULL)
426 if (init_device(kbd->hiddname, "keyboard.device", LIBBASE))
428 return TRUE;
432 return FALSE;
435 /*****************************************************************************
437 NAME */
438 AROS_LH0(void, bootmenu_CheckAndDisplay,
440 /* SYNOPSIS */
442 /* LOCATION */
443 LIBBASETYPEPTR, LIBBASE, 1, Bootmenu)
445 /* FUNCTION
447 INPUTS
449 RESULT
451 NOTES
453 EXAMPLE
455 BUGS
457 SEE ALSO
459 INTERNALS
461 *****************************************************************************/
463 AROS_LIBFUNC_INIT
465 D(bug("[BootMenu] bootmenu_CheckAndDisplay()\n"));
467 /* check keyboard */
468 if (buttonsPressed(LIBBASE, &LIBBASE->bm_BootConfig.defaultkbd))
470 kprintf("Entering Boot Menu ...\n");
471 /* init mouse + gfx */
472 if (initHidds(&LIBBASE->bm_BootConfig, LIBBASE))
474 initScreen(LIBBASE, &LIBBASE->bm_BootConfig);
478 AROS_LIBFUNC_EXIT
479 } /* bootmenu_CheckAndDisplay */
481 ADD2INITLIB(bootmenu_EarlyPrep, 0)