2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
5 Desc: Main bootmenu code
9 #include <aros/debug.h>
11 #include <proto/bootloader.h>
12 #include <proto/exec.h>
13 #include <proto/graphics.h>
14 #include <proto/intuition.h>
15 #include <proto/oop.h>
16 #include <devices/keyboard.h>
17 #include <devices/rawkeycodes.h>
18 #include <devices/timer.h>
19 #include <exec/memory.h>
20 #include <graphics/driver.h>
21 #include <libraries/expansionbase.h>
22 #include <aros/bootloader.h>
23 #include <aros/symbolsets.h>
25 #include LC_LIBDEFS_FILE
27 #include "dosboot_intern.h"
30 static BOOL
init_gfx(STRPTR gfxclassname
, BOOL bootmode
, LIBBASETYPEPTR DOSBootBase
)
35 D(bug("[BootMenu] init_gfx('%s')\n", gfxclassname
));
37 GfxBase
= (void *)OpenLibrary("graphics.library", 41);
41 gfxhidd
= OOP_NewObject(NULL
, gfxclassname
, NULL
);
43 if (AddDisplayDriver(gfxhidd
, DDRV_BootMode
, bootmode
, TAG_DONE
))
44 OOP_DisposeObject(gfxhidd
);
49 CloseLibrary(&GfxBase
->LibNode
);
51 ReturnBool ("init_gfxhidd", success
);
54 static BOOL
initHidds(LIBBASETYPEPTR DOSBootBase
)
56 struct BootConfig
*bootcfg
= &DOSBootBase
->bm_BootConfig
;
58 D(bug("[BootMenu] initHidds()\n"));
60 if (bootcfg
->gfxhidd
) {
61 if (!OpenLibrary(bootcfg
->gfxlib
, 0))
64 if (!init_gfx(bootcfg
->gfxhidd
, bootcfg
->bootmode
, DOSBootBase
))
68 D(bug("[BootMenu] initHidds: Hidds initialised\n"));
72 static struct Gadget
*createGadgets(LIBBASETYPEPTR DOSBootBase
)
74 /* FIXME: This is very unclean! free-up resources if we fail! */
76 /* Create Option Gadgets */
77 DOSBootBase
->bm_MainGadgets
.bootopt
= createButton(
79 NULL
, "Boot Options...",
80 BUTTON_BOOT_OPTIONS
, (struct DOSBootBase
*)DOSBootBase
);
81 if (DOSBootBase
->bm_MainGadgets
.bootopt
== NULL
)
84 DOSBootBase
->bm_MainGadgets
.displayopt
= createButton(
86 DOSBootBase
->bm_MainGadgets
.bootopt
->gadget
, "Display Options...",
87 BUTTON_DISPLAY_OPTIONS
, (struct DOSBootBase
*)DOSBootBase
);
88 if (DOSBootBase
->bm_MainGadgets
.displayopt
== NULL
)
91 DOSBootBase
->bm_MainGadgets
.expboarddiag
= createButton(
93 DOSBootBase
->bm_MainGadgets
.displayopt
->gadget
, "Expansion Board Diagnostic...",
94 BUTTON_EXPBOARDDIAG
, (struct DOSBootBase
*)DOSBootBase
);
95 if (DOSBootBase
->bm_MainGadgets
.expboarddiag
== NULL
)
98 /* Create BOOT Gadgets */
99 DOSBootBase
->bm_MainGadgets
.boot
= createButton(
101 DOSBootBase
->bm_MainGadgets
.expboarddiag
->gadget
, "Boot",
102 BUTTON_BOOT
, (struct DOSBootBase
*)DOSBootBase
);
103 if (DOSBootBase
->bm_MainGadgets
.boot
== NULL
)
106 DOSBootBase
->bm_MainGadgets
.bootnss
= createButton(
108 DOSBootBase
->bm_MainGadgets
.boot
->gadget
, "Boot With No Startup-Sequence",
109 BUTTON_BOOT_WNSS
, (struct DOSBootBase
*)DOSBootBase
);
110 if (DOSBootBase
->bm_MainGadgets
.bootnss
== NULL
)
113 return DOSBootBase
->bm_MainGadgets
.bootopt
->gadget
;
116 static void freeGadgets(LIBBASETYPEPTR DOSBootBase
)
118 if (DOSBootBase
->bm_MainGadgets
.boot
!= NULL
)
119 freeButtonGadget(DOSBootBase
->bm_MainGadgets
.boot
, (struct DOSBootBase
*)DOSBootBase
);
120 if (DOSBootBase
->bm_MainGadgets
.bootnss
!= NULL
);
121 freeButtonGadget(DOSBootBase
->bm_MainGadgets
.bootnss
, (struct DOSBootBase
*)DOSBootBase
);
122 if (DOSBootBase
->bm_MainGadgets
.bootopt
!= NULL
)
123 freeButtonGadget(DOSBootBase
->bm_MainGadgets
.bootopt
, (struct DOSBootBase
*)DOSBootBase
);
124 if (DOSBootBase
->bm_MainGadgets
.displayopt
!= NULL
)
125 freeButtonGadget(DOSBootBase
->bm_MainGadgets
.displayopt
, (struct DOSBootBase
*)DOSBootBase
);
126 if (DOSBootBase
->bm_MainGadgets
.expboarddiag
!= NULL
)
127 freeButtonGadget(DOSBootBase
->bm_MainGadgets
.expboarddiag
, (struct DOSBootBase
*)DOSBootBase
);
130 static void msgLoop(LIBBASETYPEPTR DOSBootBase
, struct Window
*win
)
133 struct IntuiMessage
*msg
;
136 D(bug("[BootMenu] msgLoop(DOSBootBase @ %p, Window @ %p)\n", DOSBootBase
, win
));
142 WaitPort(win
->UserPort
);
143 while ((msg
= (struct IntuiMessage
*)GetMsg(win
->UserPort
)))
145 if (msg
->Class
== IDCMP_GADGETUP
)
151 DOSBootBase
->BootFlags
&= ~BF_NO_STARTUP_SEQUENCE
;
154 case BUTTON_BOOT_WNSS
:
155 DOSBootBase
->BootFlags
|= BF_NO_STARTUP_SEQUENCE
;
160 ReplyMsg((struct Message
*)msg
);
165 bug("[BootMenu] msgLoop: Window lacks a userport!\n");
168 } while (exit
== FALSE
);
169 while ((msg
=(struct IntuiMessage
*)GetMsg(win
->UserPort
)))
170 ReplyMsg(&msg
->ExecMessage
);
173 static BOOL
initScreen(LIBBASETYPEPTR DOSBootBase
, struct BootConfig
*bcfg
)
175 struct Screen
*bm_Screen
;
176 struct Gadget
*first
= NULL
;
179 D(bug("[BootMenu] initScreen()\n"));
181 bm_Screen
= OpenBootScreen(DOSBootBase
);
182 D(bug("[BootMenu] initScreen: Screen opened @ %p\n", bm_Screen
));
184 if ((first
= createGadgets(DOSBootBase
)) != NULL
)
186 struct NewWindow nw
=
188 0, 0, /* Left, Top */
189 bm_Screen
->Width
, /* Width, Height */
191 0, 1, /* DetailPen, BlockPen */
192 IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE
| IDCMP_VANILLAKEY
| IDCMP_GADGETUP
| IDCMP_GADGETDOWN
, /* IDCMPFlags */
193 WFLG_SMART_REFRESH
| WFLG_BORDERLESS
| WFLG_ACTIVATE
, /* Flags */
194 first
, /* FirstGadget */
195 NULL
, /* CheckMark */
197 bm_Screen
, /* Screen */
199 0, 0, /* MinWidth, MinHeight */
200 0, 0, /* MaxWidth, MaxHeight */
201 CUSTOMSCREEN
, /* Type */
204 D(bug("[BootMenu] initScreen: Gadgets created @ %p\n", first
));
206 if ((DOSBootBase
->bm_Window
= OpenWindow(&nw
)) != NULL
)
208 D(bug("[BootMenu] initScreen: Window opened @ %p\n", DOSBootBase
->bm_Window
));
209 D(bug("[BootMenu] initScreen: Window RastPort @ %p\n", DOSBootBase
->bm_Window
->RPort
));
210 D(bug("[BootMenu] initScreen: Window UserPort @ %p\n", DOSBootBase
->bm_Window
->UserPort
));
211 SetAPen(DOSBootBase
->bm_Window
->RPort
, 2);
212 D(bug("[BootMenu] initScreen: SetAPen 2\n"));
213 Move(DOSBootBase
->bm_Window
->RPort
, 215, 20);
214 D(bug("[BootMenu] initScreen: Move(d) to 215, 20\n"));
215 Text(DOSBootBase
->bm_Window
->RPort
, "AROS Early Startup Control", 26);
216 D(bug("[BootMenu] initScreen: Early Startup text displayed\n"));
217 #if defined(USE_PALNTSC)
218 #warning "TODO: Check if we are using a PAL/NTSC display mode ..."
219 SetAPen(DOSBootBase
->bm_Window
->RPort
, 1);
220 Move(DOSBootBase
->bm_Window
->RPort
, 225, 40);
221 Text(DOSBootBase
->bm_Window
->RPort
, "(press a key to toggle the display between PAL and NTSC)", 23);
223 msgLoop(DOSBootBase
, DOSBootBase
->bm_Window
);
226 CloseWindow(DOSBootBase
->bm_Window
);
227 freeGadgets(DOSBootBase
);
230 CloseBootScreen(bm_Screen
, DOSBootBase
);
235 /* From keyboard.device/keyboard_intern.h */
236 #define KB_MAXKEYS 256
237 #define KB_MATRIXSIZE (KB_MAXKEYS/(sizeof(UBYTE)*8))
238 #define ioStd(x) ((struct IOStdReq *)x)
240 static BOOL
buttonsPressed(LIBBASETYPEPTR DOSBootBase
)
242 BOOL success
= FALSE
;
243 struct MsgPort
*mp
= NULL
;
244 UBYTE matrix
[KB_MATRIXSIZE
];
248 * On m68k we may have ciaa.resource (if running on classic Amiga HW)
249 * Let's check mouse buttons.
251 if (OpenResource("ciaa.resource"))
253 volatile UBYTE
*cia
= (UBYTE
*)0xbfe001;
254 volatile UWORD
*potinp
= (UWORD
*)0xdff016;
256 /* check left + right mouse button state */
257 if ((cia
[0] & 0x40) == 0 && (potinp
[0] & 0x0400) == 0)
262 if ((mp
= CreateMsgPort()) != NULL
)
264 struct IORequest
*io
= NULL
;
265 if ((io
= CreateIORequest(mp
, sizeof ( struct IOStdReq
))) != NULL
)
267 if (0 == OpenDevice("keyboard.device", 0, io
, 0))
269 D(bug("[BootMenu] buttonsPressed: Checking KBD_READMATRIX\n"));
270 ioStd(io
)->io_Command
= KBD_READMATRIX
;
271 ioStd(io
)->io_Data
= matrix
;
272 ioStd(io
)->io_Length
= sizeof(matrix
);
274 if (0 == io
->io_Error
)
278 bug("[BootMenu] buttonsPressed: Matrix : ");
279 for (i
= 0; i
< ioStd(io
)->io_Actual
; i
++)
281 bug("%02x ", matrix
[i
]);
285 if (matrix
[RAWKEY_SPACE
/8] & (1<<(RAWKEY_SPACE
%8)))
287 D(bug("[BootMenu] SPACEBAR pressed\n"));
300 int bootmenu_Init(LIBBASETYPEPTR LIBBASE
)
302 struct BootLoaderBase
*BootLoaderBase
= OpenResource("bootloader.resource");
303 BOOL bmi_RetVal
= FALSE
;
304 BOOL WantBootMenu
= FALSE
;
306 D(bug("[BootMenu] bootmenu_Init()\n"));
308 #if (AROS_FLAVOUR & AROS_FLAVOUR_STANDALONE)
311 * VGA and PCI hardware display drivers still need
312 * external initialization.
313 * This urgently needs to be fixed. After fixing this kludge
314 * will not be needed any more.
316 InitBootConfig(&LIBBASE
->bm_BootConfig
, BootLoaderBase
);
320 /* Check for command line argument */
323 struct List
*list
= NULL
;
324 struct Node
*node
= NULL
;
326 if ((list
= (struct List
*)GetBootInfo(BL_Args
)) != NULL
)
328 ForeachNode(list
,node
)
330 if (0 == stricmp(node
->ln_Name
, "bootmenu"))
332 D(bug("[BootMenu] bootmenu_Init: Forced with bootloader argument\n"));
335 else if (0 == stricmp(node
->ln_Name
, "nomonitors"))
337 LIBBASE
->BootFlags
|= BF_NO_DISPLAY_DRIVERS
;
339 else if (0 == strnicmp(node
->ln_Name
, "bootdevice=", 11))
341 LIBBASE
->db_BootDevice
= &node
->ln_Name
[11];
347 /* Initialize default HIDDs */
348 if (!initHidds(LIBBASE
))
351 /* check keyboard if needed */
353 WantBootMenu
= buttonsPressed(LIBBASE
);
355 /* Bring up early startup menu if requested */
360 D(kprintf("[BootMenu] bootmenu_Init: Entering Boot Menu ...\n"));
361 bmi_RetVal
= initScreen(LIBBASE
, &LIBBASE
->bm_BootConfig
);