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>
18 #include "devs_private.h"
20 #include "bootmenu_intern.h"
22 #include LC_LIBDEFS_FILE
27 #define ExpansionBase BootMenuBase->bm_ExpansionBase
30 struct GfxBase
*GfxBase
;
34 static const ULONG coltab
[] = {
35 (16L << 16) + 0, /* 16 colors, loaded at index 0 */
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 */
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
[] =
73 {BIDTAG_DesiredWidth
, 640},
74 {BIDTAG_DesiredHeight
, 200},
79 D(bug("[BootMenu] initScreen(gfxhidd='%s')\n", gfxhiddname
));
81 GfxBase
= (struct GfxBase
*)OpenLibrary("graphics.library", 37);
84 if (LateGfxInit(gfxhiddname
))
86 modeid
= BestModeIDA(modetags
);
87 if (modeid
!= INVALID_ID
)
91 rp
.BitMap
= AllocScreenBitMap(modeid
);
94 vp
.RasInfo
= AllocMem(sizeof(struct RasInfo
), MEMF_ANY
| MEMF_CLEAR
);
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
);
105 pointercoltab
[0] = (3L << 16) + 17;
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
);
113 rp
.Font
->tf_Accessors
++;
117 Text(&rp
, "Sucker", 6);
121 FreeMem(vp
.RasInfo
, sizeof(struct RasInfo
));
123 FreeBitMap(rp
.BitMap
);
127 CloseLibrary((struct Library
*)GfxBase
);
129 kprintf("no screen!\n");
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
))
154 if (LateIntuiInit(NULL
))
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 */
189 if (0 == io
->io_Error
)
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
);
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
);
223 last
= BootMenuBase
->bm_MainGadgets
.bootnss
= createButton(344, 190, 280, 14, last
->gadget
, "Boot With No Startup-Sequence", BUTTON_BOOT_WNSS
, BootMenuBase
);
226 last
= BootMenuBase
->bm_MainGadgets
.bootopt
= createButton(180, 63, 280, 14, last
->gadget
, "Boot Options...", BUTTON_BOOT_OPTIONS
, BootMenuBase
);
229 last
= BootMenuBase
->bm_MainGadgets
.displayopt
= createButton(180, 84, 280, 14, last
->gadget
, "Display Options...", BUTTON_DISPLAY_OPTIONS
, BootMenuBase
);
232 last
= BootMenuBase
->bm_MainGadgets
.expboarddiag
= createButton(180, 105, 280, 14, last
->gadget
, "Expansion Board Diagnostic...", BUTTON_EXPBOARDDIAG
, BootMenuBase
);
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
)
255 struct IntuiMessage
*msg
;
260 WaitPort(win
->UserPort
);
261 while ((msg
=(struct IntuiMessage
*)GetMsg(win
->UserPort
)))
263 if (msg
->Class
== IDCMP_GADGETUP
)
269 ExpansionBase
->Flags
&= ~EBF_DOSFLAG
;
272 case BUTTON_BOOT_WNSS
:
273 ExpansionBase
->Flags
|= EBF_DOSFLAG
;
278 ReplyMsg(&msg
->ExecMessage
);
281 while ((msg
=(struct IntuiMessage
*)GetMsg(win
->UserPort
)))
282 ReplyMsg(&msg
->ExecMessage
);
285 static BOOL
initScreen(struct BootMenuBase_intern
*BootMenuBase
, struct BootConfig
*bcfg
)
288 struct TagItem scrtags
[] =
293 {SA_Pens
, (IPTR
)pens
},
296 struct TagItem wintags
[] =
298 {WA_Left
, 0}, /* 0 */
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
},
309 struct Gadget
*first
= NULL
;
311 BootMenuBase
->bm_Screen
= OpenScreenTagList(NULL
, scrtags
);
312 if (BootMenuBase
->bm_Screen
!= NULL
)
314 first
= createGadgets(BootMenuBase
);
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
);
334 Alert(AT_DeadEnd
| AN_OpenWindow
);
335 CloseWindow(BootMenuBase
->bm_Window
);
336 freeGadgets(BootMenuBase
);
339 Alert(AT_DeadEnd
| AN_BadGadget
);
340 CloseScreen(BootMenuBase
->bm_Screen
);
343 Alert(AT_DeadEnd
| AN_OpenScreen
);
347 static BOOL
buttonsPressed(struct BootMenuBase
*BootMenuBase
, struct DefaultHidd
*kbd
)
349 BOOL success
= FALSE
;
350 struct MsgPort
*mp
= NULL
;
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;
366 if (0 == io
->io_Error
)
370 D(bug("[BootMenu] buttonsPressed: Matrix : "));
371 for (i
= 0; i
< sizeof(matrix
); i
++)
373 D(bug("%2x ", matrix
[i
]));
377 if (matrix
[RAWKEY_SPACE
/8] & (1<<(RAWKEY_SPACE
%8)))
391 static struct BootConfig bootcfg
=
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
))
435 /*****************************************************************************
438 AROS_LH0(void, bootmenu_CheckAndDisplay
,
443 LIBBASETYPEPTR
, LIBBASE
, 1, Bootmenu
)
461 *****************************************************************************/
465 D(bug("[BootMenu] bootmenu_CheckAndDisplay()\n"));
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
);
479 } /* bootmenu_CheckAndDisplay */
481 ADD2INITLIB(bootmenu_EarlyPrep
, 0)