1 #include <proto/bootloader.h>
2 #include <proto/exec.h>
3 #include <proto/graphics.h>
4 #include <proto/intuition.h>
5 #include <devices/keyboard.h>
6 #include <devices/rawkeycodes.h>
7 #include <devices/timer.h>
8 #include <exec/memory.h>
9 #include <graphics/gfxbase.h>
10 #include <libraries/bootmenu.h>
11 #include <aros/bootloader.h>
12 #include <aros/symbolsets.h>
14 #include "devs_private.h"
16 #include <aros/debug.h>
18 #include "bootmenu_intern.h"
20 #include LC_LIBDEFS_FILE
25 struct GfxBase
*GfxBase
;
29 static const ULONG coltab
[] = {
30 (16L << 16) + 0, /* 16 colors, loaded at index 0 */
33 0xB3B3B3B3, 0xB3B3B3B3, 0xB3B3B3B3, /* Grey70 */
34 0x00000000, 0x00000000, 0x00000000, /* Black */
35 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, /* White */
36 0x66666666, 0x88888888, 0xBBBBBBBB, /* AMIGA Blue */
38 0x00000000, 0x00000000, 0xFFFFFFFF, /* Blue */
39 0x00000000, 0xFFFFFFFF, 0x00000000, /* Green */
40 0xFFFFFFFF, 0x00000000, 0x00000000, /* Red */
41 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, /* Cyan */
43 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, /* Magenta */
44 0xEEEEEEEE, 0x82828282, 0xEEEEEEEE, /* Violet */
45 0xA5A5A5A5, 0x2A2A2A2A, 0x2A2A2A2A, /* Brown */
46 0xFFFFFFFF, 0xE4E4E4E4, 0xC4C4C4C4, /* Bisque */
48 0xE6E6E6E6, 0xE6E6E6E6, 0xFAFAFAFA, /* Lavender */
49 0x00000000, 0x00000000, 0x80808080, /* Navy */
50 0xF0F0F0F0, 0xE6E6E6E6, 0x8C8C8C8C, /* Khaki */
51 0xA0A0A0A0, 0x52525252, 0x2D2D2D2D, /* Sienna */
55 static ULONG pointercoltab
[] = {
57 0xE0E0E0E0, 0x40404040, 0x40404040,
58 0x00000000, 0x00000000, 0x00000000,
59 0xE0E0E0E0, 0xE0E0E0E0, 0xC0C0C0C0,
63 BOOL
initScreen(STRPTR gfxhiddname
, struct BootMenuBase
*bootmenubase
) {
64 struct TagItem modetags
[] =
67 {BIDTAG_DesiredWidth
, 640},
68 {BIDTAG_DesiredHeight
, 200},
73 GfxBase
= (struct GfxBase
*)OpenLibrary("graphics.library", 37);
76 if (LateGfxInit(gfxhiddname
))
78 modeid
= BestModeIDA(modetags
);
79 if (modeid
!= INVALID_ID
)
83 rp
.BitMap
= AllocScreenBitMap(modeid
);
86 vp
.RasInfo
= AllocMem(sizeof(struct RasInfo
), MEMF_ANY
| MEMF_CLEAR
);
89 vp
.RasInfo
->BitMap
= rp
.BitMap
;
90 vp
.ColorMap
= GetColorMap(4);
91 vp
.ColorMap
->VPModeID
= modeid
;
92 if (AttachPalExtra(vp
.ColorMap
, &vp
) == 0)
94 LoadRGB32(&vp
, (ULONG
*)coltab
);
95 depth
= GetBitMapAttr(rp
.BitMap
, BMA_DEPTH
);
97 pointercoltab
[0] = (3L << 16) + 17;
99 pointercoltab
[0] = (3L << 16) + (1 << depth
) - 3;
100 LoadRGB32(&vp
, pointercoltab
);
101 rp
.BitMap
->Flags
|= BMF_AROS_HIDD
;
102 SetFont(&rp
, GfxBase
->DefaultFont
);
103 SetFrontBitMap(rp
.BitMap
, TRUE
);
105 rp
.Font
->tf_Accessors
++;
109 Text(&rp
, "Sucker", 6);
113 FreeMem(vp
.RasInfo
, sizeof(struct RasInfo
));
115 FreeBitMap(rp
.BitMap
);
119 CloseLibrary((struct Library
*)GfxBase
);
121 kprintf("no screen!\n");
130 static BOOL
init_gfx(STRPTR gfxclassname
, struct BootMenuBase
*bootmenubase
)
132 BOOL success
= FALSE
;
133 EnterFunc(bug("init_gfx(hiddbase=%s)\n", gfxclassname
));
135 /* Call private gfx.library call to init the HIDD.
136 Gfx library is responsable for closing the HIDD
137 library (although it will probably not be neccesary).
140 D(bug("calling private gfx LateGfxInit()\n"));
141 if (LateGfxInit(gfxclassname
))
146 if (LateIntuiInit(NULL
))
152 ReturnBool ("init_gfxhidd", success
);
156 static BOOL
init_device( STRPTR hiddclassname
, STRPTR devicename
, struct BootMenuBase
*bootmenubase
)
158 BOOL success
= FALSE
;
161 EnterFunc(bug("init_device(classname=%s)\n", hiddclassname
));
163 mp
= CreateMsgPort();
166 struct IORequest
*io
;
167 io
= CreateIORequest(mp
, sizeof ( struct IOStdReq
));
170 if (0 == OpenDevice(devicename
, 0, io
, 0))
172 #define ioStd(x) ((struct IOStdReq *)x)
173 ioStd(io
)->io_Command
= CMD_HIDDINIT
;
174 ioStd(io
)->io_Data
= hiddclassname
;
175 ioStd(io
)->io_Length
= strlen(hiddclassname
);
177 /* Let the device init the HIDD */
179 if (0 == io
->io_Error
)
189 ReturnBool("init_device", success
);
192 BOOL
initHidds(struct BootConfig
*bootcfg
, struct BootMenuBase
*bootmenubase
) {
194 OpenLibrary(bootcfg
->defaultgfx
.libname
, 0);
195 init_gfx(bootcfg
->defaultgfx
.hiddname
, bootmenubase
);
196 OpenLibrary(bootcfg
->defaultmouse
.libname
, 0);
197 init_device(bootcfg
->defaultmouse
.hiddname
, "gameport.device", bootmenubase
);
201 struct Gadget
*createGadgets(struct BootMenuBase_intern
*bootmenubase
) {
202 struct Gadget
*first
;
203 struct ButtonGadget
*last
;
205 last
= bootmenubase
->maingadgets
.boot
= createButton(16, 190, 280, 14, (struct Gadget
*)&first
, "Boot", BUTTON_BOOT
, bootmenubase
);
208 last
= bootmenubase
->maingadgets
.bootnss
= createButton(344, 190, 280, 14, last
->gadget
, "Boot With No Startup-Sequence", BUTTON_BOOT_WNSS
, bootmenubase
);
211 last
= bootmenubase
->maingadgets
.bootopt
= createButton(180, 63, 280, 14, last
->gadget
, "Boot Options...", BUTTON_BOOT_OPTIONS
, bootmenubase
);
214 last
= bootmenubase
->maingadgets
.displayopt
= createButton(180, 84, 280, 14, last
->gadget
, "Display Options...", BUTTON_DISPLAY_OPTIONS
, bootmenubase
);
217 last
= bootmenubase
->maingadgets
.expboarddiag
= createButton(180, 105, 280, 14, last
->gadget
, "Expansion Board Diagnostic...", BUTTON_EXPBOARDDIAG
, bootmenubase
);
223 void freeGadgets(struct BootMenuBase_intern
*bootmenubase
) {
225 if (bootmenubase
->maingadgets
.boot
!= NULL
)
226 freeButtonGadget(bootmenubase
->maingadgets
.boot
, bootmenubase
);
227 if (bootmenubase
->maingadgets
.bootnss
!= NULL
);
228 freeButtonGadget(bootmenubase
->maingadgets
.bootnss
, bootmenubase
);
229 if (bootmenubase
->maingadgets
.bootopt
!= NULL
)
230 freeButtonGadget(bootmenubase
->maingadgets
.bootopt
, bootmenubase
);
231 if (bootmenubase
->maingadgets
.displayopt
!= NULL
)
232 freeButtonGadget(bootmenubase
->maingadgets
.displayopt
, bootmenubase
);
233 if (bootmenubase
->maingadgets
.expboarddiag
!= NULL
)
234 freeButtonGadget(bootmenubase
->maingadgets
.expboarddiag
, bootmenubase
);
237 void msgLoop(struct BootMenuBase
*bootmenubase
, struct Window
*win
, struct BootConfig
*bcfg
) {
239 struct IntuiMessage
*msg
;
244 WaitPort(win
->UserPort
);
245 while ((msg
=(struct IntuiMessage
*)GetMsg(win
->UserPort
)))
247 if (msg
->Class
== IDCMP_GADGETUP
)
253 bcfg
->startup_sequence
= TRUE
;
256 case BUTTON_BOOT_WNSS
:
257 bcfg
->startup_sequence
= FALSE
;
262 ReplyMsg(&msg
->ExecMessage
);
265 while ((msg
=(struct IntuiMessage
*)GetMsg(win
->UserPort
)))
266 ReplyMsg(&msg
->ExecMessage
);
269 BOOL
initScreen(struct BootMenuBase_intern
*bootmenubase
, struct BootConfig
*bcfg
) {
271 struct TagItem scrtags
[] =
276 {SA_Pens
, (IPTR
)pens
},
279 struct TagItem wintags
[] =
281 {WA_Left
, 0}, /* 0 */
283 {WA_Width
, 640}, /* 2 */
284 {WA_Height
, 256}, /* 3 */
285 {WA_CustomScreen
, 0}, /* 4 */
286 {WA_Gadgets
, NULL
}, /* 5 */
287 {WA_IDCMP
, IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE
| IDCMP_VANILLAKEY
| IDCMP_GADGETUP
| IDCMP_GADGETDOWN
},
288 {WA_Borderless
, TRUE
},
292 struct Gadget
*first
= NULL
;
294 bootmenubase
->scr
= OpenScreenTagList(NULL
, scrtags
);
295 if (bootmenubase
->scr
!= NULL
)
297 first
= createGadgets(bootmenubase
);
300 wintags
[2].ti_Data
= bootmenubase
->scr
->Width
;
301 wintags
[3].ti_Data
= bootmenubase
->scr
->Height
;
302 wintags
[4].ti_Data
= (IPTR
)bootmenubase
->scr
;
303 wintags
[5].ti_Data
= (IPTR
)first
;
304 bootmenubase
->win
= OpenWindowTagList(NULL
, wintags
);
305 if (bootmenubase
->win
!= NULL
)
307 SetAPen(bootmenubase
->win
->RPort
, 2);
308 Move(bootmenubase
->win
->RPort
, 215, 20);
309 Text(bootmenubase
->win
->RPort
, "AROS Early Startup Control", 26);
310 SetAPen(bootmenubase
->win
->RPort
, 1);
311 Move(bootmenubase
->win
->RPort
, 225, 40);
312 Text(bootmenubase
->win
->RPort
, "(what is PAL and NTSC?)", 23);
313 msgLoop(bootmenubase
, bootmenubase
->win
, bcfg
);
317 Alert(AT_DeadEnd
| AN_OpenWindow
);
318 CloseWindow(bootmenubase
->win
);
319 freeGadgets(bootmenubase
);
322 Alert(AT_DeadEnd
| AN_BadGadget
);
323 CloseScreen(bootmenubase
->scr
);
326 Alert(AT_DeadEnd
| AN_OpenScreen
);
330 void delay(struct BootMenuBase
*bootmenubase
, LONG secs
, LONG micro
) {
333 mp
= CreateMsgPort();
336 struct timerequest
*tr
;
337 tr
= (struct timerequest
*)CreateIORequest(mp
, sizeof(struct timerequest
));
340 if (OpenDevice("timer.device", UNIT_VBLANK
, (struct IORequest
*)tr
, 0) == 0)
342 #define ioStd(x) ((struct IOStdReq *)x)
343 ioStd(tr
)->io_Command
= TR_ADDREQUEST
;
344 tr
->tr_time
.tv_secs
= secs
;
345 tr
->tr_time
.tv_micro
= micro
;
346 DoIO((struct IORequest
*)tr
);
347 CloseDevice((struct IORequest
*)tr
);
349 DeleteIORequest((struct IORequest
*)tr
);
355 BOOL
buttonsPressed(struct BootMenuBase
*bootmenubase
, struct DefaultHidd
*kbd
) {
356 BOOL success
= FALSE
;
360 if (OpenLibrary(kbd
->libname
, 0) != NULL
)
362 if (init_device(kbd
->hiddname
, "keyboard.device", bootmenubase
))
364 delay(bootmenubase
, 1, 0);
365 mp
= CreateMsgPort();
368 struct IORequest
*io
;
369 io
= CreateIORequest(mp
, sizeof ( struct IOStdReq
));
372 if (0 == OpenDevice("keyboard.device", 0, io
, 0))
374 #define ioStd(x) ((struct IOStdReq *)x)
375 ioStd(io
)->io_Command
= KBD_READMATRIX
;
376 ioStd(io
)->io_Data
= matrix
;
377 ioStd(io
)->io_Length
= 16;
379 if (0 == io
->io_Error
)
381 if (matrix
[RAWKEY_SPACE
/8] & (1<<(RAWKEY_SPACE
%8)))
398 static int CheckAndDisplay(LIBBASETYPEPTR LIBBASE
)
400 struct BootLoaderBase
*BootLoaderBase
;
402 static struct BootConfig bootcfg
=
405 {"vgah.hidd", "hidd.gfx.vga"},
406 {"kbd.hidd", "hidd.kbd.hw"},
407 {"mouse.hidd", "hidd.bus.mouse"},
412 LIBBASE
->bcfg
= bootcfg
;
414 /* init keyboard + check */
415 if (buttonsPressed(LIBBASE
, &LIBBASE
->bcfg
.defaultkbd
))
417 BootLoaderBase
= OpenResource("bootloader.resource");
418 if (BootLoaderBase
) {
419 vi
= (struct VesaInfo
*)GetBootInfo(BL_Video
);
421 if (vi
->ModeNumber
!= 3) {
422 strcpy(LIBBASE
->bcfg
.defaultgfx
.libname
, "vesagfx.hidd");
423 strcpy(LIBBASE
->bcfg
.defaultgfx
.hiddname
, "hidd.gfx.vesa");
427 kprintf("Entering Boot Menu ...\n");
428 /* init mouse + gfx */
429 if (initHidds(&LIBBASE
->bcfg
, LIBBASE
))
431 initScreen(LIBBASE
, &LIBBASE
->bcfg
);
437 ADD2INITLIB(CheckAndDisplay
, 0)