From 09c3bbc00a2bd9d922aa9a9cef477198f79e0af1 Mon Sep 17 00:00:00 2001 From: dteske Date: Mon, 12 Aug 2013 01:21:14 +0000 Subject: [PATCH] Synchronize releng/9.2 Forth code with stable/9 via MFS of 2 revisions: First, MFS of SVN r254109: itself an MFC of 22 revisions: 227727, 233941, 235560, 238431, 241310, 241361, 241363, 241365, 241367, 241523, 242667-242669, 242923, 243114, 243660, 244048, 244089, 244158, 253715, 254105, and 254108. This includes critical fixes that sadly should have been merged prior. Namely, SVN r244158 fixes a possible regression. Second, MFS of SVN r254146: Itself an MFC of r242688. Approved by: re (marius) git-svn-id: svn://svn.freebsd.org/base/releng/9.2@254235 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/boot/common/Makefile.inc | 1 + sys/boot/forth/beastie.4th | 7 +- sys/boot/forth/beastie.4th.8 | 9 +- sys/boot/forth/brand.4th | 2 +- sys/boot/forth/brand.4th.8 | 2 +- sys/boot/forth/check-password.4th | 42 +- sys/boot/forth/check-password.4th.8 | 54 ++- sys/boot/forth/color.4th | 17 +- sys/boot/forth/color.4th.8 | 25 +- sys/boot/forth/delay.4th | 2 +- sys/boot/forth/delay.4th.8 | 2 +- sys/boot/forth/frames.4th | 16 + sys/boot/forth/loader.4th | 13 + sys/boot/forth/loader.4th.8 | 2 +- sys/boot/forth/loader.conf | 2 +- sys/boot/forth/loader.conf.5 | 21 +- sys/boot/forth/loader.rc | 4 + sys/boot/forth/menu-commands.4th | 282 ++++++++++--- sys/boot/forth/menu.4th | 520 +++++++++++++----------- sys/boot/forth/menu.4th.8 | 59 ++- sys/boot/forth/menu.rc | 126 ++++-- sys/boot/forth/menusets.4th | 610 ++++++++++++++++++++++++++++ sys/boot/forth/menusets.4th.8 | 372 +++++++++++++++++ sys/boot/forth/shortcuts.4th | 2 +- sys/boot/forth/support.4th | 40 ++ sys/boot/forth/version.4th | 2 +- sys/boot/forth/version.4th.8 | 14 +- sys/boot/i386/loader/Makefile | 2 +- sys/boot/ia64/common/Makefile | 2 +- sys/boot/pc98/loader/Makefile | 2 +- sys/boot/powerpc/ofw/Makefile | 2 +- sys/boot/powerpc/ps3/Makefile | 2 +- sys/boot/sparc64/loader/Makefile | 2 +- 33 files changed, 1821 insertions(+), 439 deletions(-) create mode 100644 sys/boot/forth/menusets.4th create mode 100644 sys/boot/forth/menusets.4th.8 diff --git a/sys/boot/common/Makefile.inc b/sys/boot/common/Makefile.inc index 935519c9..fab16307 100644 --- a/sys/boot/common/Makefile.inc +++ b/sys/boot/common/Makefile.inc @@ -64,6 +64,7 @@ MAN+= ../forth/delay.4th.8 MAN+= ../forth/loader.conf.5 MAN+= ../forth/loader.4th.8 MAN+= ../forth/menu.4th.8 +MAN+= ../forth/menusets.4th.8 MAN+= ../forth/version.4th.8 .endif diff --git a/sys/boot/forth/beastie.4th b/sys/boot/forth/beastie.4th index 75d6e02a..458a7945 100644 --- a/sys/boot/forth/beastie.4th +++ b/sys/boot/forth/beastie.4th @@ -1,6 +1,6 @@ \ Copyright (c) 2003 Scott Long \ Copyright (c) 2003 Aleksander Fafula -\ Copyright (c) 2006-2011 Devin Teske +\ Copyright (c) 2006-2013 Devin Teske \ All rights reserved. \ \ Redistribution and use in source and binary forms, with or without @@ -28,7 +28,6 @@ marker task-beastie.4th -include /boot/color.4th include /boot/delay.4th variable logoX @@ -182,8 +181,8 @@ variable logoY \ beastie Color ``Helper Daemon'' mascot (19 rows x 34 columns) \ beastiebw B/W ``Helper Daemon'' mascot (19 rows x 34 columns) \ fbsdbw "FreeBSD" logo in B/W (13 rows x 21 columns) -\ orb Color ``Orb'' mascot (15 rows x 30 columns) -\ orbbw B/W ``Orb'' mascot (15 rows x 32 columns) (default) +\ orb Color ``Orb'' mascot (15 rows x 30 columns) (default) +\ orbbw B/W ``Orb'' mascot (15 rows x 32 columns) \ \ NOTE: Setting `loader_logo' to an undefined value (such as "none") will \ prevent beastie from being drawn. diff --git a/sys/boot/forth/beastie.4th.8 b/sys/boot/forth/beastie.4th.8 index 2da34a6f..30d29b2c 100644 --- a/sys/boot/forth/beastie.4th.8 +++ b/sys/boot/forth/beastie.4th.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2011 Devin Teske +.\" Copyright (c) 2011-2012 Devin Teske .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -94,8 +94,9 @@ The variable can be configured in .Xr loader.conf 5 to the number of seconds you would like to delay loading the boot menu. -During the delay the user can press Ctrl-C to fall back to autoboot or ENTER -to proceed. +During the delay the user can press Ctrl-C to fall back to +.Ic autoboot +or ENTER to proceed. The default behavior is to not delay. .El .Pp @@ -168,4 +169,4 @@ set of commands was written by .An Scott Long Aq scottl@FreeBSD.org , .An Aleksander Fafula Aq alex@fafula.com and -.An Devin Teske Aq devinteske@hotmail.com . +.An Devin Teske Aq dteske@FreeBSD.org . diff --git a/sys/boot/forth/brand.4th b/sys/boot/forth/brand.4th index bc641749..b6f22c8f 100644 --- a/sys/boot/forth/brand.4th +++ b/sys/boot/forth/brand.4th @@ -1,4 +1,4 @@ -\ Copyright (c) 2006-2011 Devin Teske +\ Copyright (c) 2006-2011 Devin Teske \ All rights reserved. \ \ Redistribution and use in source and binary forms, with or without diff --git a/sys/boot/forth/brand.4th.8 b/sys/boot/forth/brand.4th.8 index a9174f0e..64e68545 100644 --- a/sys/boot/forth/brand.4th.8 +++ b/sys/boot/forth/brand.4th.8 @@ -122,4 +122,4 @@ The .Nm set of commands was written by .An -nosplit -.An Devin Teske Aq devinteske@hotmail.com . +.An Devin Teske Aq dteske@FreeBSD.org . diff --git a/sys/boot/forth/check-password.4th b/sys/boot/forth/check-password.4th index 0a1fa5d7..26d6b94b 100644 --- a/sys/boot/forth/check-password.4th +++ b/sys/boot/forth/check-password.4th @@ -1,4 +1,4 @@ -\ Copyright (c) 2006-2011 Devin Teske +\ Copyright (c) 2006-2012 Devin Teske \ All rights reserved. \ \ Redistribution and use in source and binary forms, with or without @@ -74,7 +74,7 @@ variable readlen \ input length again ; -: read ( -- String prompt ) +: read ( String prompt -- ) 0 25 at-xy \ Move the cursor to the bottom-left dup 1+ read-start ! \ Store X offset after the prompt @@ -134,23 +134,37 @@ variable readlen \ input length : check-password ( -- ) - \ Exit if a password was not set - s" password" getenv dup -1 = if - drop exit + \ Do not allow the user to proceed beyond this point if a boot-lock + \ password has been set (preventing even boot from proceeding) + s" bootlock_password" getenv dup -1 <> if + begin + s" Boot Password: " read ( prompt -- ) + 2dup readval readlen @ compare 0<> + while + 3000 ms ." loader: incorrect password" 10 emit + repeat + 2drop ( c-addr/u ) + else + drop ( -1 ) \ getenv cruft then - begin \ Loop as long as it takes to get the right password + \ Exit if a password was not set + s" password" getenv -1 = if exit else drop then + + \ We should prevent the user from visiting the menu or dropping to the + \ interactive loader(8) prompt, but still allow the machine to boot... - s" Password: " \ Output a prompt for a password - read \ Read the user's input until Enter + 0 autoboot + \ Only reached if autoboot fails for any reason (including if/when + \ the user aborts/escapes the countdown sequence leading to boot). + + s" password" getenv + begin + s" Password: " read ( prompt -- ) 2dup readval readlen @ compare 0= if 2drop exit \ Correct password then - - \ Bad Password - 3000 ms - ." loader: incorrect password" 10 emit - - again \ Not the right password; repeat + 3000 ms ." loader: incorrect password" 10 emit + again ; diff --git a/sys/boot/forth/check-password.4th.8 b/sys/boot/forth/check-password.4th.8 index 926cebf1..e1f52b7d 100644 --- a/sys/boot/forth/check-password.4th.8 +++ b/sys/boot/forth/check-password.4th.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2011 Devin Teske +.\" Copyright (c) 2011-2012 Devin Teske .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 18, 2011 +.Dd December 10, 2012 .Dt CHECK-PASSWORD.4TH 8 .Os .Sh NAME @@ -33,7 +33,8 @@ .Sh DESCRIPTION The file that goes by the name of .Nm -is a set of commands designed to prevent booting without the proper password. +is a set of commands designed to either prevent booting or prevent modification +of boot options without an appropriately configured password. The commands of .Nm by themselves are not enough for most uses. @@ -57,30 +58,36 @@ The commands provided by it are: .Pp .Bl -tag -width disable-module_module -compact -offset indent .It Ic check-password -Once called, the user cannot continue until the correct password is entered. -If the user enters the correct password the function returns. +Dual-purpose function that can either protect the interactive boot menu or +prevent boot without password (separately). .Pp -The password that is required is configured by setting the -.Ic password -variable in -.Xr loader.conf 5 . +First checks +.Va bootlock_password +and if-set, the user cannot continue until the correct password is entered. .Pp -Subsequent calls after a successful password -has been entered will not cause reprompting -\(em the function will silently return. +Next checks +.Va password +and if-set, tries to +.Ic autoboot +and only prompts for password on failure or user-interrupt. +See +.Xr loader.conf 5 +for additional information. .El .Pp The environment variables that effect its behavior are: -.Bl -tag -width bootfile -offset indent +.Bl -tag -width bootlock_password -offset indent +.It Va bootlock_password +Sets the bootlock password (up to 16 characters long) that is required by +.Ic check-password +to be entered before the system is allowed to boot. .It Va password Sets the password (up to 16 characters long) that is required by .Ic check-password -to be entered before the system is allowed to boot. If unset (default) or NULL, -.Ic check-password -will silently abort. +before the user is allowed to visit the boot menu. .El .Sh FILES -.Bl -tag -width /boot/loader.4th -compact +.Bl -tag -width /boot/check-password.4th -compact .It Pa /boot/loader The .Xr loader 8 . @@ -101,11 +108,20 @@ check-password .Ed .Pp Set a password in -.Xr loader.conf 5 : +.Xr loader.conf 5 +to prevent modification of boot options: .Pp .Bd -literal -offset indent -compact password="abc123" .Ed +.Pp +Set a password in +.Xr loader.conf 5 +to prevent booting without password: +.Pp +.Bd -literal -offset indent -compact +bootlock_password="boot" +.Ed .Sh SEE ALSO .Xr loader.conf 5 , .Xr loader 8 , @@ -120,4 +136,4 @@ The .Nm set of commands was written by .An -nosplit -.An Devin Teske Aq devinteske@hotmail.com . +.An Devin Teske Aq dteske@FreeBSD.org . diff --git a/sys/boot/forth/color.4th b/sys/boot/forth/color.4th index 4d435938..65e6de90 100644 --- a/sys/boot/forth/color.4th +++ b/sys/boot/forth/color.4th @@ -1,4 +1,4 @@ -\ Copyright (c) 2011 Devin Teske +\ Copyright (c) 2011-2013 Devin Teske \ All rights reserved. \ \ Redistribution and use in source and binary forms, with or without @@ -26,23 +26,24 @@ marker task-color.4th -\ This function returns TRUE if the `loader_color' environment variable is set -\ to YES, yes, or 1. Otherwise, FALSE is returned. +\ This function returns FALSE if the `loader_color' environment variable is set +\ to NO, no, or 0. Otherwise, TRUE is returned (unless booting serial). \ : loader_color? ( -- N ) s" loader_color" getenv dup -1 <> if - 2dup s" YES" compare-insensitive 0= if + 2dup s" NO" compare-insensitive 0= if 2drop - TRUE exit + FALSE exit then - 2dup s" 1" compare 0= if + 2dup s" 0" compare 0= if 2drop - TRUE exit + FALSE exit then drop then + drop - drop FALSE exit + boot_serial? if FALSE else TRUE then ; diff --git a/sys/boot/forth/color.4th.8 b/sys/boot/forth/color.4th.8 index 2aba9b79..9191da0f 100644 --- a/sys/boot/forth/color.4th.8 +++ b/sys/boot/forth/color.4th.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2011 Devin Teske +.\" Copyright (c) 2011-2013 Devin Teske .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 18, 2011 +.Dd August 6, 2013 .Dt COLOR.4TH 8 .Os .Sh NAME @@ -50,33 +50,33 @@ through the command: .Dl include color.4th .Pp This line is present in -.Pa /boot/beastie.4th +.Pa /boot/loader.4th file, so it is not needed (and should not be re-issued) in a normal setup. .Pp The commands provided by it are: .Pp .Bl -tag -width disable-module_module -compact -offset indent .It Ic loader_color? -Returns TRUE if the +Returns FALSE if the .Ic loader_color environment variable is set to -.Dq YES +.Dq NO (case-insensitive) or -.Dq 1 . -Otherwise returns FALSE. +.Dq 0 . +Otherwise returns TRUE +.Pq unless booting serial . .El .Pp The environment variables that effect its behavior are: .Bl -tag -width bootfile -offset indent .It Va loader_color If set to -.Dq YES +.Dq NO (case-insensitive) or -.Dq 1 , +.Dq 0 , causes .Ic loader_color? -to return TRUE, indicating to many other modules that color should be used -whenever/wherever possible. +to return FALSE, indicating to many modules that color should not be used. .El .Sh FILES .Bl -tag -width /boot/loader.4th -compact @@ -102,7 +102,6 @@ loader_color="YES" .Sh SEE ALSO .Xr loader.conf 5 , .Xr loader 8 , -.Xr beastie.4th 8 , .Xr loader.4th 8 .Sh HISTORY The @@ -114,4 +113,4 @@ The .Nm set of commands was written by .An -nosplit -.An Devin Teske Aq devinteske@hotmail.com . +.An Devin Teske Aq dteske@FreeBSD.org . diff --git a/sys/boot/forth/delay.4th b/sys/boot/forth/delay.4th index 3068e653..0d5ecbce 100644 --- a/sys/boot/forth/delay.4th +++ b/sys/boot/forth/delay.4th @@ -1,4 +1,4 @@ -\ Copyright (c) 2008-2011 Devin Teske +\ Copyright (c) 2008-2011 Devin Teske \ All rights reserved. \ \ Redistribution and use in source and binary forms, with or without diff --git a/sys/boot/forth/delay.4th.8 b/sys/boot/forth/delay.4th.8 index 108b8d17..dd1680e2 100644 --- a/sys/boot/forth/delay.4th.8 +++ b/sys/boot/forth/delay.4th.8 @@ -123,4 +123,4 @@ The .Nm set of commands was written by .An -nosplit -.An Devin Teske Aq devinteske@hotmail.com . +.An Devin Teske Aq dteske@FreeBSD.org . diff --git a/sys/boot/forth/frames.4th b/sys/boot/forth/frames.4th index 3b1f4046..5d6df243 100644 --- a/sys/boot/forth/frames.4th +++ b/sys/boot/forth/frames.4th @@ -12,6 +12,11 @@ variable rt_el variable rb_el variable fill +\ ASCII frames (used when serial console is detected) + 45 constant ascii_dash +124 constant ascii_pipe + 43 constant ascii_plus + s" arch-pc98" environment? [if] \ Single frames 149 constant sh_el @@ -63,7 +68,17 @@ s" arch-pc98" environment? [if] loop ; +: f_ascii ( -- ) ( -- ) \ set frames to ascii + ascii_dash h_el ! + ascii_pipe v_el ! + ascii_plus lt_el ! + ascii_plus lb_el ! + ascii_plus rt_el ! + ascii_plus rb_el ! +; + : f_single ( -- ) \ set frames to single + boot_serial? if f_ascii exit then sh_el h_el ! sv_el v_el ! slt_el lt_el ! @@ -73,6 +88,7 @@ s" arch-pc98" environment? [if] ; : f_double ( -- ) \ set frames to double + boot_serial? if f_ascii exit then dh_el h_el ! dv_el v_el ! dlt_el lt_el ! diff --git a/sys/boot/forth/loader.4th b/sys/boot/forth/loader.4th index 437533a0..c701b3c0 100644 --- a/sys/boot/forth/loader.4th +++ b/sys/boot/forth/loader.4th @@ -40,6 +40,7 @@ s" arch-i386" environment? [if] [if] 2048 dictincrease ! \ 2048 additional cells each time include /boot/support.4th +include /boot/color.4th only forth also support-functions also builtins definitions @@ -59,11 +60,23 @@ only forth also support-functions also builtins definitions else drop then + s" menusets-unset" + sfind if + execute + else + drop + then ; : boot 0= if ( interpreted ) get_arguments then + loader_color? if + ." Booting..." cr + else + ." Booting..." cr + then + \ Unload only if a path was passed dup if >r over r> swap diff --git a/sys/boot/forth/loader.4th.8 b/sys/boot/forth/loader.4th.8 index 568aa847..61203645 100644 --- a/sys/boot/forth/loader.4th.8 +++ b/sys/boot/forth/loader.4th.8 @@ -99,7 +99,7 @@ This is the command used in the default .Pa /boot/loader.rc file, and it uses the -.Pa autoboot +.Ic autoboot command (see .Xr loader 8 ) , so it can be stopped for further interaction with diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf index 63b19ae3..777b2241 100644 --- a/sys/boot/forth/loader.conf +++ b/sys/boot/forth/loader.conf @@ -48,7 +48,7 @@ bitmap_type="splash_image_data" # and place it on the module_path # escape to the loader prompt, set to # "NO" to disable autobooting #beastie_disable="NO" # Turn the beastie boot menu on and off -#loader_logo="fbsdbw" # Desired logo: fbsdbw, beastiebw, beastie, none +#loader_logo="orbbw" # Desired logo: orbbw, orb, fbsdbw, beastiebw, beastie, none #comconsole_speed="9600" # Set the current serial console speed #console="vidconsole" # A comma separated list of console(s) #currdev="disk1s1a" # Set the current device diff --git a/sys/boot/forth/loader.conf.5 b/sys/boot/forth/loader.conf.5 index 5f7a0d70..110e0688 100644 --- a/sys/boot/forth/loader.conf.5 +++ b/sys/boot/forth/loader.conf.5 @@ -23,7 +23,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd July 20, 2011 +.Dd August 6, 2013 .Dt LOADER.CONF 5 .Os .Sh NAME @@ -113,8 +113,23 @@ that contains a kernel. .It Ar kernel_options Flags to be passed to the kernel. .It Ar password +Protect boot menu with a password without interrupting +.Ic autoboot +process. +The password should be in clear text format. +If a password is set, boot menu will not appear until any key is pressed during +countdown period specified by +.Va autoboot_delay +variable or +.Ic autoboot +process fails. +In both cases user should provide specified password to be able to access boot +menu. +.It Ar bootlock_password Provides a password to be required by check-password before execution is allowed to continue. +The password should be in clear text format. +If a password is set, the user must provide specified password to boot. .It Ar verbose_loading If set to .Dq YES , @@ -230,8 +245,8 @@ and .Dq Li none . .It Va loader_color If set to -.Dq YES , -the beastie boot menu will be displayed using ANSI coloring where possible. +.Dq NO , +the beastie boot menu will be displayed without ANSI coloring. .El .Sh FILES .Bl -tag -width /boot/defaults/loader.conf -compact diff --git a/sys/boot/forth/loader.rc b/sys/boot/forth/loader.rc index 0f9d37ef..1130cc97 100644 --- a/sys/boot/forth/loader.rc +++ b/sys/boot/forth/loader.rc @@ -10,5 +10,9 @@ start \ Tests for password -- executes autoboot first if a password was defined check-password +\ Uncomment to enable boot menu +\ include /boot/beastie.4th +\ beastie-start + \ Unless set otherwise, autoboot is automatic at this point diff --git a/sys/boot/forth/menu-commands.4th b/sys/boot/forth/menu-commands.4th index 828a148b..baee0b1b 100644 --- a/sys/boot/forth/menu-commands.4th +++ b/sys/boot/forth/menu-commands.4th @@ -1,4 +1,4 @@ -\ Copyright (c) 2006-2011 Devin Teske +\ Copyright (c) 2006-2012 Devin Teske \ All rights reserved. \ \ Redistribution and use in source and binary forms, with or without @@ -26,6 +26,60 @@ marker task-menu-commands.4th +include /boot/menusets.4th + +variable kernel_state +variable root_state + +\ +\ Boot +\ + +: init_boot ( N -- N ) + dup + s" boot_single" getenv -1 <> if + drop ( n n c-addr -- n n ) \ unused + toggle_menuitem ( n n -- n n ) + s" set menu_keycode[N]=115" \ base command to execute + else + s" set menu_keycode[N]=98" \ base command to execute + then + 17 +c! \ replace 'N' with ASCII numeral + evaluate +; + +\ +\ Alternate Boot +\ + +: init_altboot ( N -- N ) + dup + s" boot_single" getenv -1 <> if + drop ( n c-addr -- n ) \ unused + toggle_menuitem ( n -- n ) + s" set menu_keycode[N]=109" \ base command to execute + else + s" set menu_keycode[N]=115" \ base command to execute + then + 17 +c! \ replace 'N' with ASCII numeral + evaluate +; + +: altboot ( -- ) + s" boot_single" 2dup getenv -1 <> if + drop ( c-addr/u c-addr -- c-addr/u ) \ unused + unsetenv ( c-addr/u -- ) + else + 2drop ( c-addr/u -- ) \ unused + s" set boot_single=YES" evaluate + then + 0 boot ( state -- ) +; + +\ +\ ACPI +\ + : acpi_enable ( -- ) s" set acpi_load=YES" evaluate \ XXX deprecated but harmless s" set hint.acpi.0.disabled=0" evaluate @@ -53,39 +107,51 @@ marker task-menu-commands.4th TRUE \ loop menu again ; +\ +\ Safe Mode +\ + +: safemode_enabled? ( -- flag ) + s" kern.smp.disabled" getenv -1 <> dup if + swap drop ( c-addr flag -- flag ) + then +; + +: safemode_enable ( -- ) + s" set kern.smp.disabled=1" evaluate + s" set hw.ata.ata_dma=0" evaluate + s" set hw.ata.atapi_dma=0" evaluate + s" set hw.ata.wc=0" evaluate + s" set hw.eisa_slots=0" evaluate + s" set kern.eventtimer.periodic=1" evaluate + s" set kern.geom.part.check_integrity=0" evaluate +; + +: safemode_disable ( -- ) + s" kern.smp.disabled" unsetenv + s" hw.ata.ata_dma" unsetenv + s" hw.ata.atapi_dma" unsetenv + s" hw.ata.wc" unsetenv + s" hw.eisa_slots" unsetenv + s" kern.eventtimer.periodic" unsetenv + s" kern.geom.part.check_integrity" unsetenv +; + +: init_safemode ( N -- N ) + safemode_enabled? if + toggle_menuitem ( n -- n ) + then +; + : toggle_safemode ( N -- N TRUE ) toggle_menuitem \ Now we're going to make the change effective - s" toggle_stateN @" \ base name of toggle state var - -rot 2dup 12 + c! rot \ replace 'N' with ASCII numeral - - evaluate 0= if - s" hint.apic.0.disabled" unsetenv - s" hw.ata.ata_dma" unsetenv - s" hw.ata.atapi_dma" unsetenv - s" hw.ata.wc" unsetenv - s" hw.eisa_slots" unsetenv - s" hint.kbdmux.0.disabled" unsetenv + dup toggle_stateN @ 0= if + safemode_disable else - \ - \ Toggle ACPI elements if necessary - \ - acpipresent? if acpienabled? if - menuacpi @ dup 0<> if - toggle_menuitem ( N -- N ) - then - drop - acpi_disable - then then - - s" set hint.apic.0.disabled=1" evaluate - s" set hw.ata.ata_dma=0" evaluate - s" set hw.ata.atapi_dma=0" evaluate - s" set hw.ata.wc=0" evaluate - s" set hw.eisa_slots=0" evaluate - s" set hint.kbdmux.0.disabled=1" evaluate + safemode_enable then menu-redraw @@ -93,42 +159,88 @@ marker task-menu-commands.4th TRUE \ loop menu again ; +\ +\ Single User Mode +\ + +: singleuser_enabled? ( -- flag ) + s" boot_single" getenv -1 <> dup if + swap drop ( c-addr flag -- flag ) + then +; + +: singleuser_enable ( -- ) + s" set boot_single=YES" evaluate +; + +: singleuser_disable ( -- ) + s" boot_single" unsetenv +; + +: init_singleuser ( N -- N ) + singleuser_enabled? if + toggle_menuitem ( n -- n ) + then +; + : toggle_singleuser ( N -- N TRUE ) toggle_menuitem menu-redraw \ Now we're going to make the change effective - s" toggle_stateN @" \ base name of toggle state var - -rot 2dup 12 + c! rot \ replace 'N' with ASCII numeral - - evaluate 0= if - s" boot_single" unsetenv + dup toggle_stateN @ 0= if + singleuser_disable else - s" set boot_single=YES" evaluate + singleuser_enable then TRUE \ loop menu again ; +\ +\ Verbose Boot +\ + +: verbose_enabled? ( -- flag ) + s" boot_verbose" getenv -1 <> dup if + swap drop ( c-addr flag -- flag ) + then +; + +: verbose_enable ( -- ) + s" set boot_verbose=YES" evaluate +; + +: verbose_disable ( -- ) + s" boot_verbose" unsetenv +; + +: init_verbose ( N -- N ) + verbose_enabled? if + toggle_menuitem ( n -- n ) + then +; + : toggle_verbose ( N -- N TRUE ) toggle_menuitem menu-redraw \ Now we're going to make the change effective - s" toggle_stateN @" \ base name of toggle state var - -rot 2dup 12 + c! rot \ replace 'N' with ASCII numeral - - evaluate 0= if - s" boot_verbose" unsetenv + dup toggle_stateN @ 0= if + verbose_disable else - s" set boot_verbose=YES" evaluate + verbose_enable then TRUE \ loop menu again ; +\ +\ Escape to Prompt +\ + : goto_prompt ( N -- N FALSE ) s" set autoboot_delay=NO" evaluate @@ -141,50 +253,94 @@ marker task-menu-commands.4th FALSE \ exit the menu ; +\ +\ Cyclestate (used by kernel/root below) +\ + +: init_cyclestate ( N K -- N ) + over cycle_stateN ( n k -- n k addr ) + begin + tuck @ ( n k addr -- n addr k c ) + over <> ( n addr k c -- n addr k 0|-1 ) + while + rot ( n addr k -- addr k n ) + cycle_menuitem + swap rot ( addr k n -- n k addr ) + repeat + 2drop ( n k addr -- n ) +; + +\ +\ Kernel +\ + +: init_kernel ( N -- N ) + kernel_state @ ( n -- n k ) + init_cyclestate ( n k -- n ) +; + : cycle_kernel ( N -- N TRUE ) cycle_menuitem menu-redraw \ Now we're going to make the change effective - s" cycle_stateN" \ base name of array state var - -rot 2dup 11 + c! rot \ replace 'N' with ASCII numeral - evaluate \ translate name into address - @ \ dereference address into value + dup cycle_stateN @ + dup kernel_state ! \ save a copy for re-initialization 48 + \ convert to ASCII numeral - \ Since we are [in this file] going to override the standard `boot' - \ routine with a custom one, you should know that we use $kernel - \ when referencing the desired kernel. Set $kernel below. - s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}" - \ command to assemble full kernel-path - -rot tuck 36 + c! swap \ replace 'N' with array index value - evaluate \ sets $kernel to full kernel-path + 36 +c! \ replace 'N' with ASCII numeral + evaluate \ sets $kernel to full kernel-path TRUE \ loop menu again ; +\ +\ Root +\ + +: init_root ( N -- N ) + root_state @ ( n -- n k ) + init_cyclestate ( n k -- n ) +; + : cycle_root ( N -- N TRUE ) cycle_menuitem menu-redraw \ Now we're going to make the change effective - s" cycle_stateN" \ base name of array state var - -rot 2dup 11 + c! rot \ replace 'N' with ASCII numeral - evaluate \ translate name into address - @ \ dereference address into value + dup cycle_stateN @ + dup root_state ! \ save a copy for re-initialization 48 + \ convert to ASCII numeral - \ Since we are [in this file] going to override the standard `boot' - \ routine with a custom one, you should know that we use $root when - \ booting. Set $root below. - - s" set root=${root_prefix}${root[N]}${root_prefix}" - \ command to assemble full kernel-path - -rot tuck 30 + c! swap \ replace 'N' with array index value - evaluate \ sets $kernel to full kernel-path + s" set root=${root_prefix}${root[N]}${root_suffix}" + 30 +c! \ replace 'N' with ASCII numeral + evaluate \ sets $root to full root-path TRUE \ loop menu again ; + +\ +\ Menusets +\ + +: goto_menu ( N M -- N TRUE ) + menu-unset + menuset-loadsetnum ( n m -- n ) + menu-redraw + TRUE \ Loop menu again +; + +\ +\ Defaults +\ + +: set_default_boot_options ( N -- N TRUE ) + acpi_enable + safemode_disable + singleuser_disable + verbose_disable + 2 goto_menu +; diff --git a/sys/boot/forth/menu.4th b/sys/boot/forth/menu.4th index daac6c83..6614a9f7 100644 --- a/sys/boot/forth/menu.4th +++ b/sys/boot/forth/menu.4th @@ -1,6 +1,6 @@ \ Copyright (c) 2003 Scott Long \ Copyright (c) 2003 Aleksander Fafula -\ Copyright (c) 2006-2011 Devin Teske +\ Copyright (c) 2006-2013 Devin Teske \ All rights reserved. \ \ Redistribution and use in source and binary forms, with or without @@ -35,6 +35,8 @@ f_double \ Set frames to double (see frames.4th). Replace with \ f_single if you want single frames. 46 constant dot \ ASCII definition of a period (in decimal) + 5 constant menu_default_x \ default column position of timeout +10 constant menu_default_y \ default row position of timeout msg 4 constant menu_timeout_default_x \ default column position of timeout 23 constant menu_timeout_default_y \ default row position of timeout msg 10 constant menu_timeout_default \ default timeout (in seconds) @@ -76,6 +78,16 @@ variable menu_timeout \ determined configurable delay duration variable menu_timeout_x \ column position of timeout message variable menu_timeout_y \ row position of timeout message +\ Menu initialization status variables +variable init_state1 +variable init_state2 +variable init_state3 +variable init_state4 +variable init_state5 +variable init_state6 +variable init_state7 +variable init_state8 + \ Boolean option status variables variable toggle_state1 variable toggle_state2 @@ -106,6 +118,52 @@ create init_text6 255 allot create init_text7 255 allot create init_text8 255 allot +: +c! ( N C-ADDR/U K -- C-ADDR/U ) + 3 pick 3 pick ( n c-addr/u k -- n c-addr/u k n c-addr ) + rot + c! ( n c-addr/u k n c-addr -- n c-addr/u ) + rot drop ( n c-addr/u -- c-addr/u ) +; + +: menukeyN ( N -- ADDR ) s" menukeyN" 7 +c! evaluate ; +: init_stateN ( N -- ADDR ) s" init_stateN" 10 +c! evaluate ; +: toggle_stateN ( N -- ADDR ) s" toggle_stateN" 12 +c! evaluate ; +: cycle_stateN ( N -- ADDR ) s" cycle_stateN" 11 +c! evaluate ; +: init_textN ( N -- C-ADDR ) s" init_textN" 9 +c! evaluate ; + +: str_loader_menu_frame ( -- C-ADDR/U ) s" loader_menu_frame" ; +: str_loader_menu_title ( -- C-ADDR/U ) s" loader_menu_title" ; +: str_loader_menu_title_align ( -- C-ADDR/U ) s" loader_menu_title_align" ; +: str_loader_menu_x ( -- C-ADDR/U ) s" loader_menu_x" ; +: str_loader_menu_y ( -- C-ADDR/U ) s" loader_menu_y" ; +: str_loader_menu_timeout_x ( -- C-ADDR/U ) s" loader_menu_timeout_x" ; +: str_loader_menu_timeout_y ( -- C-ADDR/U ) s" loader_menu_timeout_y" ; +: str_menu_init ( -- C-ADDR/U ) s" menu_init" ; +: str_menu_timeout_command ( -- C-ADDR/U ) s" menu_timeout_command" ; +: str_menu_reboot ( -- C-ADDR/U ) s" menu_reboot" ; +: str_menu_acpi ( -- C-ADDR/U ) s" menu_acpi" ; +: str_menu_options ( -- C-ADDR/U ) s" menu_options" ; +: str_menu_optionstext ( -- C-ADDR/U ) s" menu_optionstext" ; + +: str_menu_init[x] ( -- C-ADDR/U ) s" menu_init[x]" ; +: str_menu_command[x] ( -- C-ADDR/U ) s" menu_command[x]" ; +: str_menu_caption[x] ( -- C-ADDR/U ) s" menu_caption[x]" ; +: str_ansi_caption[x] ( -- C-ADDR/U ) s" ansi_caption[x]" ; +: str_menu_keycode[x] ( -- C-ADDR/U ) s" menu_keycode[x]" ; +: str_toggled_text[x] ( -- C-ADDR/U ) s" toggled_text[x]" ; +: str_toggled_ansi[x] ( -- C-ADDR/U ) s" toggled_ansi[x]" ; +: str_menu_caption[x][y] ( -- C-ADDR/U ) s" menu_caption[x][y]" ; +: str_ansi_caption[x][y] ( -- C-ADDR/U ) s" ansi_caption[x][y]" ; + +: menu_init[x] ( N -- C-ADDR/U ) str_menu_init[x] 10 +c! ; +: menu_command[x] ( N -- C-ADDR/U ) str_menu_command[x] 13 +c! ; +: menu_caption[x] ( N -- C-ADDR/U ) str_menu_caption[x] 13 +c! ; +: ansi_caption[x] ( N -- C-ADDR/U ) str_ansi_caption[x] 13 +c! ; +: menu_keycode[x] ( N -- C-ADDR/U ) str_menu_keycode[x] 13 +c! ; +: toggled_text[x] ( N -- C-ADDR/U ) str_toggled_text[x] 13 +c! ; +: toggled_ansi[x] ( N -- C-ADDR/U ) str_toggled_ansi[x] 13 +c! ; +: menu_caption[x][y] ( N M -- C-ADDR/U ) str_menu_caption[x][y] 16 +c! 13 +c! ; +: ansi_caption[x][y] ( N M -- C-ADDR/U ) str_ansi_caption[x][y] 16 +c! 13 +c! ; + : arch-i386? ( -- BOOL ) \ Returns TRUE (-1) on i386, FALSE (0) otherwise. s" arch-i386" environment? dup if drop @@ -162,30 +220,24 @@ create init_text8 255 allot \ ASCII numeral equal to user-selected menu item must be on the stack. \ We do not modify the stack, so the ASCII numeral is left on top. - s" init_textN" \ base name of buffer - -rot 2dup 9 + c! rot \ replace 'N' with ASCII num - - evaluate c@ 0= if + dup init_textN c@ 0= if \ NOTE: no need to check toggle_stateN since the first time we \ are called, we will populate init_textN. Further, we don't \ need to test whether menu_caption[x] (ansi_caption[x] when - \ loader_color=1) is available since we would not have been + \ loader_color?=1) is available since we would not have been \ called if the caption was NULL. \ base name of environment variable + dup ( n -- n n ) \ key pressed loader_color? if - s" ansi_caption[x]" + ansi_caption[x] else - s" menu_caption[x]" + menu_caption[x] then - -rot 2dup 13 + c! rot \ replace 'x' with ASCII numeral - getenv dup -1 <> if - s" init_textN" \ base name of buffer - 4 pick \ copy ASCII num to top - rot tuck 9 + c! swap \ replace 'N' with ASCII num - evaluate + 2 pick ( n c-addr/u -- n c-addr/u n ) + init_textN ( n c-addr/u n -- n c-addr/u c-addr ) \ now we have the buffer c-addr on top \ ( followed by c-addr/u of current caption ) @@ -217,67 +269,49 @@ create init_text8 255 allot \ negate the toggled state so that we reverse the flow on subsequent \ calls. - s" toggle_stateN @" \ base name of toggle state var - -rot 2dup 12 + c! rot \ replace 'N' with ASCII numeral - - evaluate 0= if + dup toggle_stateN @ 0= if \ state is OFF, toggle to ON - \ base name of toggled text var + dup ( n -- n n ) \ key pressed loader_color? if - s" toggled_ansi[x]" + toggled_ansi[x] else - s" toggled_text[x]" + toggled_text[x] then - -rot 2dup 13 + c! rot \ replace 'x' with ASCII num - getenv dup -1 <> if \ Assign toggled text to menu caption - - \ base name of caption var + 2 pick ( n c-addr/u -- n c-addr/u n ) \ key pressed loader_color? if - s" ansi_caption[x]" + ansi_caption[x] else - s" menu_caption[x]" + menu_caption[x] then - 4 pick \ copy ASCII num to top - rot tuck 13 + c! swap \ replace 'x' with ASCII num - - setenv \ set new caption + setenv else \ No toggled text, keep the same caption - - drop + drop ( n -1 -- n ) \ getenv cruft then true \ new value of toggle state var (to be stored later) else \ state is ON, toggle to OFF - s" init_textN" \ base name of initial text buffer - -rot 2dup 9 + c! rot \ replace 'N' with ASCII numeral - evaluate \ convert string to c-addr - count \ convert c-addr to c-addr/u + dup init_textN count ( n -- n c-addr/u ) - \ base name of caption var + \ Assign init_textN text to menu caption + 2 pick ( n c-addr/u -- n c-addr/u n ) \ key pressed loader_color? if - s" ansi_caption[x]" + ansi_caption[x] else - s" menu_caption[x]" + menu_caption[x] then - 4 pick \ copy ASCII num to top - rot tuck 13 + c! swap \ replace 'x' with ASCII numeral + setenv - setenv \ set new caption - false \ new value of toggle state var (to be stored below) + false \ new value of toggle state var (to be stored below) then \ now we'll store the new toggle state (on top of stack) - s" toggle_stateN" \ base name of toggle state var - 3 pick \ copy ASCII numeral to top - rot tuck 12 + c! swap \ replace 'N' with ASCII numeral - evaluate \ convert string to addr - ! \ store new value + over toggle_stateN ! ; : cycle_menuitem ( N -- N ) \ cycles through array of choices for a menuitem @@ -285,28 +319,23 @@ create init_text8 255 allot \ ASCII numeral equal to user-selected menu item must be on the stack. \ We do not modify the stack, so the ASCII numeral is left on top. - s" cycle_stateN" \ base name of array state var - -rot 2dup 11 + c! rot \ replace 'N' with ASCII numeral - - evaluate \ we now have a pointer to the proper variable - dup @ \ resolve the pointer (but leave it on the stack) - 1+ \ increment the value + dup cycle_stateN dup @ 1+ \ get value and increment \ Before assigning the (incremented) value back to the pointer, \ let's test for the existence of this particular array element. \ If the element exists, we'll store index value and move on. \ Otherwise, we'll loop around to zero and store that. - dup 48 + \ duplicate Array index and convert to ASCII numeral + dup 48 + ( n addr k -- n addr k k' ) + \ duplicate array index and convert to ASCII numeral - \ base name of array caption text + 3 pick swap ( n addr k k' -- n addr k n k' ) \ (n,k') as (x,y) loader_color? if - s" ansi_caption[x][y]" + ansi_caption[x][y] else - s" menu_caption[x][y]" + menu_caption[x][y] then - -rot tuck 16 + c! swap \ replace 'y' with Array index - 4 pick rot tuck 13 + c! swap \ replace 'x' with menu choice + ( n addr k n k' -- n addr k c-addr/u ) \ Now test for the existence of our incremented array index in the \ form of $menu_caption[x][y] ($ansi_caption[x][y] with loader_color @@ -315,48 +344,47 @@ create init_text8 255 allot getenv dup -1 = if \ No caption set for this array index. Loop back to zero. - drop ( getenv cruft ) - drop ( incremented array index ) - 0 ( new array index that will be stored later ) + drop ( n addr k -1 -- n addr k ) \ getenv cruft + drop 0 ( n addr k -- n addr 0 ) \ new value to store later - \ base name of caption var + 2 pick [char] 0 ( n addr 0 -- n addr 0 n 48 ) \ (n,48) as (x,y) loader_color? if - s" ansi_caption[x][0]" + ansi_caption[x][y] else - s" menu_caption[x][0]" + menu_caption[x][y] then - 4 pick rot tuck 13 + c! swap \ replace 'x' with menu choice - + ( n addr 0 n 48 -- n addr 0 c-addr/u ) getenv dup -1 = if \ This is highly unlikely to occur, but to make \ sure that things move along smoothly, allocate \ a temporary NULL string - s" " + drop ( n addr 0 -1 -- n addr 0 ) \ getenv cruft + s" " ( n addr 0 -- n addr 0 c-addr/u ) then then \ At this point, we should have the following on the stack (in order, \ from bottom to top): \ - \ N - Ascii numeral representing the menu choice (inherited) - \ Addr - address of our internal cycle_stateN variable - \ N - zero-based number we intend to store to the above - \ C-Addr - string value we intend to store to menu_caption[x] - \ (or ansi_caption[x] with loader_color enabled) + \ n - Ascii numeral representing the menu choice (inherited) + \ addr - address of our internal cycle_stateN variable + \ k - zero-based number we intend to store to the above + \ c-addr/u - string value we intend to store to menu_caption[x] + \ (or ansi_caption[x] with loader_color enabled) \ \ Let's perform what we need to with the above. - \ base name of menuitem caption var + \ Assign array value text to menu caption + 4 pick ( n addr k c-addr/u -- n addr k c-addr/u n ) loader_color? if - s" ansi_caption[x]" + ansi_caption[x] else - s" menu_caption[x]" + menu_caption[x] then - 6 pick rot tuck 13 + c! swap \ replace 'x' with menu choice - setenv \ set the new caption + setenv - swap ! \ update array state variable + swap ! ( n addr k -- n ) \ update array state variable ; : acpipresent? ( -- flag ) \ Returns TRUE if ACPI is present, FALSE otherwise @@ -384,21 +412,21 @@ create init_text8 255 allot \ ACPI option is to be presented to the user, otherwise returns -1. Used \ internally by menu-create, you need not (nor should you) call this directly. \ -: acpimenuitem ( -- C-Addr | -1 ) +: acpimenuitem ( -- C-Addr/U | -1 ) arch-i386? if acpipresent? if acpienabled? if loader_color? if - s" toggled_ansi[x]" + str_toggled_ansi[x] else - s" toggled_text[x]" + str_toggled_text[x] then else loader_color? if - s" ansi_caption[x]" + str_ansi_caption[x] else - s" menu_caption[x]" + str_menu_caption[x] then then else @@ -416,10 +444,37 @@ create init_text8 255 allot : menu-create ( -- ) \ Print the frame caption at (x,y) - s" loader_menu_title" getenv dup -1 = if + str_loader_menu_title getenv dup -1 = if drop s" Welcome to FreeBSD" then - 24 over 2 / - 9 at-xy type + TRUE ( use default alignment ) + str_loader_menu_title_align getenv dup -1 <> if + 2dup s" left" compare-insensitive 0= if ( 1 ) + 2drop ( c-addr/u ) drop ( bool ) + menuX @ menuY @ 1- + FALSE ( don't use default alignment ) + else ( 1 ) 2dup s" right" compare-insensitive 0= if ( 2 ) + 2drop ( c-addr/u ) drop ( bool ) + menuX @ 42 + 4 - over - menuY @ 1- + FALSE ( don't use default alignment ) + else ( 2 ) 2drop ( c-addr/u ) then ( 1 ) then + else + drop ( getenv cruft ) + then + if ( use default center alignement? ) + menuX @ 19 + over 2 / - menuY @ 1- + then + at-xy type + + \ If $menu_init is set, evaluate it (allowing for whole menus to be + \ constructed dynamically -- as this function could conceivably set + \ the remaining environment variables to construct the menu entirely). + \ + str_menu_init getenv dup -1 <> if + evaluate + else + drop + then \ Print our menu options with respective key/variable associations. \ `printmenuitem' ends by adding the decimal ASCII value for the @@ -440,7 +495,7 @@ create init_text8 255 allot \ Initialize the ACPI option status. \ 0 menuacpi ! - s" menu_acpi" getenv -1 <> if + str_menu_acpi getenv -1 <> if c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' ) menuacpi ! arch-i386? if acpipresent? if @@ -448,10 +503,7 @@ create init_text8 255 allot \ Set menu toggle state to active state \ (required by generic toggle_menuitem) \ - menuacpi @ - s" acpienabled? toggle_stateN !" - -rot tuck 25 + c! swap - evaluate + acpienabled? menuacpi @ toggle_stateN ! then then else drop @@ -462,7 +514,7 @@ create init_text8 255 allot \ Initialize the menu_options visual separator. \ 0 menuoptions ! - s" menu_options" getenv -1 <> if + str_menu_options getenv -1 <> if c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' ) menuoptions ! else @@ -473,12 +525,16 @@ create init_text8 255 allot \ Initialize "Reboot" menu state variable (prevents double-entry) false menurebootadded ! + menu_start + 1- menuidx ! \ Initialize the starting index for the menu + 0 menurow ! \ Initialize the starting position for the menu + 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8') begin \ If the "Options:" separator, print it. dup menuoptions @ = if \ Optionally add a reboot option to the menu - s" menu_reboot" getenv -1 <> if + str_menu_reboot getenv -1 <> if drop s" Reboot" printmenuitem menureboot ! true menurebootadded ! @@ -488,42 +544,57 @@ create init_text8 255 allot menurow @ 2 + menurow ! menurow @ menuY @ + at-xy - ." Options:" + str_menu_optionstext getenv dup -1 <> if + type + else + drop ." Options:" + then then \ If this is the ACPI menu option, act accordingly. dup menuacpi @ = if - acpimenuitem ( -- C-Addr | -1 ) + dup acpimenuitem ( n -- n n c-addr/u | n n -1 ) + dup -1 <> if + 13 +c! ( n n c-addr/u -- n c-addr/u ) + \ replace 'x' with n + else + swap drop ( n n -1 -- n -1 ) + over menu_command[x] unsetenv + then else + \ make sure we have not already initialized this item + dup init_stateN dup @ 0= if + 1 swap ! + + \ If this menuitem has an initializer, run it + dup menu_init[x] + getenv dup -1 <> if + evaluate + else + drop + then + else + drop + then + + dup loader_color? if - s" ansi_caption[x]" + ansi_caption[x] else - s" menu_caption[x]" + menu_caption[x] then then - ( C-Addr | -1 ) dup -1 <> if - \ replace 'x' with current iteration - -rot 2dup 13 + c! rot - \ test for environment variable getenv dup -1 <> if - printmenuitem ( C-Addr -- N ) - - s" menukeyN !" \ generate cmd to store result - -rot 2dup 7 + c! rot - - evaluate + printmenuitem ( c-addr/u -- n ) + dup menukeyN ! else drop then else drop - - s" menu_command[x]" - -rot 2dup 13 + c! rot ( replace 'x' ) - unsetenv then 1+ dup 56 > \ add 1 to iterator, continue if less than 57 @@ -532,7 +603,7 @@ create init_text8 255 allot \ Optionally add a reboot option to the menu menurebootadded @ true <> if - s" menu_reboot" getenv -1 <> if + str_menu_reboot getenv -1 <> if drop \ no need for the value s" Reboot" \ menu caption (required by printmenuitem) @@ -550,45 +621,22 @@ create init_text8 255 allot \ : menu-timeout-update ( N -- ) - dup 9 > if ( N N 9 -- N ) - drop ( N -- ) - 9 ( maximum: -- N ) - then - - dup 0 < if ( N N 0 -- N ) - drop ( N -- ) - 0 ( minimum: -- N ) - then - - 48 + ( convert single-digit numeral to ASCII: N 48 -- N ) - - s" Autoboot in N seconds. [Space] to pause" ( N -- N Addr C ) - - 2 pick 48 - 0> if ( N Addr C N 48 -- N Addr C ) - - \ Modify 'N' (Addr+12) above to reflect time-left - - -rot ( N Addr C -- C N Addr ) - tuck ( C N Addr -- C Addr N Addr ) - 12 + ( C Addr N Addr -- C Addr N Addr2 ) - c! ( C Addr N Addr2 -- C Addr ) - swap ( C Addr -- Addr C ) - - menu_timeout_x @ - menu_timeout_y @ - at-xy ( position cursor: Addr C N N -- Addr C ) - - type ( print message: Addr C -- ) - - else ( N Addr C N -- N Addr C ) + \ Enforce minimum/maximum + dup 9 > if drop 9 then + dup 0 < if drop 0 then - menu_timeout_x @ - menu_timeout_y @ - at-xy ( position cursor: N Addr C N N -- N Addr C ) + s" Autoboot in N seconds. [Space] to pause" ( n -- n c-addr/u ) - spaces ( erase message: N Addr C -- N Addr ) - 2drop ( N Addr -- ) + 2 pick 0> if + rot 48 + -rot ( n c-addr/u -- n' c-addr/u ) \ convert to ASCII + 12 +c! ( n' c-addr/u -- c-addr/u ) \ replace 'N' above + menu_timeout_x @ menu_timeout_y @ at-xy \ position cursor + type ( c-addr/u -- ) \ print message + else + menu_timeout_x @ menu_timeout_y @ at-xy \ position cursor + spaces ( n c-addr/u -- n c-addr ) \ erase message + 2drop ( n c-addr -- ) then 0 25 at-xy ( position cursor back at bottom-left ) @@ -636,7 +684,7 @@ create init_text8 255 allot \ (user did not cancel by pressing ANY \ key) - s" menu_timeout_command" getenv dup + str_menu_timeout_command getenv dup -1 = if drop \ clean-up else @@ -708,8 +756,45 @@ create init_text8 255 allot menu_start 1- menuidx ! \ Initialize the starting index for the menu 0 menurow ! \ Initialize the starting position for the menu - 42 13 2 9 box \ Draw frame (w,h,x,y) - 0 25 at-xy \ Move cursor to the bottom for output + + \ Assign configuration values + str_loader_menu_y getenv dup -1 = if + drop \ no custom row position + menu_default_y + else + \ make sure custom position is a number + ?number 0= if + menu_default_y \ or use default + then + then + menuY ! + str_loader_menu_x getenv dup -1 = if + drop \ no custom column position + menu_default_x + else + \ make sure custom position is a number + ?number 0= if + menu_default_x \ or use default + then + then + menuX ! + + \ Interpret a custom frame type for the menu + TRUE ( draw a box? default yes, but might be altered below ) + str_loader_menu_frame getenv dup -1 = if ( 1 ) + drop \ no custom frame type + else ( 1 ) 2dup s" single" compare-insensitive 0= if ( 2 ) + f_single ( see frames.4th ) + else ( 2 ) 2dup s" double" compare-insensitive 0= if ( 3 ) + f_double ( see frames.4th ) + else ( 3 ) s" none" compare-insensitive 0= if ( 4 ) + drop FALSE \ don't draw a box + ( 4 ) then ( 3 ) then ( 2 ) then ( 1 ) then + if + 42 13 menuX @ 3 - menuY @ 1- box \ Draw frame (w,h,x,y) + then + + 0 25 at-xy \ Move cursor to the bottom for output ; \ Main function. Call this from your `loader.rc' file. @@ -719,7 +804,7 @@ create init_text8 255 allot 0 menu_timeout_enabled ! \ start with automatic timeout disabled \ check indication that automatic execution after delay is requested - s" menu_timeout_command" getenv -1 <> if ( Addr C -1 -- | Addr ) + str_menu_timeout_command getenv -1 <> if ( Addr C -1 -- | Addr ) drop ( just testing existence right now: Addr -- ) \ initialize state variables @@ -755,7 +840,7 @@ create init_text8 255 allot menu_timeout_enabled @ 1 = if \ read custom column position (if set) - s" loader_menu_timeout_x" getenv dup -1 = if + str_loader_menu_timeout_x getenv dup -1 = if drop \ no custom column position menu_timeout_default_x \ use default setting else @@ -767,7 +852,7 @@ create init_text8 255 allot menu_timeout_x ! ( store value on stack from above ) \ read custom row position (if set) - s" loader_menu_timeout_y" getenv dup -1 = if + str_loader_menu_timeout_y getenv dup -1 = if drop \ no custom row position menu_timeout_default_y \ use default setting else @@ -799,17 +884,15 @@ create init_text8 255 allot exit ( pedantic; never reached ) then + dup menureboot @ = if 0 reboot then + \ Evaluate the decimal ASCII value against known menu item \ key associations and act accordingly 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8') begin - s" menukeyN @" - - \ replace 'N' with current iteration - -rot 2dup 7 + c! rot - - evaluate rot tuck = if + dup menukeyN @ + rot tuck = if \ Adjust for missing ACPI menuitem on non-i386 arch-i386? true <> menuacpi @ 0<> and if @@ -820,13 +903,8 @@ create init_text8 255 allot then then - \ base env name for the value (x is a number) - s" menu_command[x]" - - \ Copy ASCII number to string at offset 13 - -rot 2dup 13 + c! rot - \ Test for the environment variable + dup menu_command[x] getenv dup -1 <> if \ Execute the stored procedure evaluate @@ -861,16 +939,14 @@ create init_text8 255 allot \ \ Check for menu keycode shortcut(s) \ - s" menu_keycode[x]" - -rot 2dup 13 + c! rot + dup menu_keycode[x] getenv dup -1 = if drop else ?number 0<> if rot tuck = if swap - s" menu_command[x]" - -rot 2dup 13 + c! rot + dup menu_command[x] getenv dup -1 <> if evaluate 0= if @@ -890,8 +966,7 @@ create init_text8 255 allot \ continue if less than 57 until drop \ loop iterator - - menureboot @ = if 0 reboot then + drop \ key pressed again \ Non-operational key was pressed; repeat ; @@ -903,77 +978,43 @@ create init_text8 255 allot 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8') begin - \ Unset variables in-order of appearance in menu.4th(8) - - s" menu_caption[x]" \ basename for caption variable - -rot 2dup 13 + c! rot \ replace 'x' with current iteration - unsetenv \ not erroneous to unset unknown var - - s" menu_command[x]" \ command basename - -rot 2dup 13 + c! rot \ replace 'x' - unsetenv - - s" menu_keycode[x]" \ keycode basename - -rot 2dup 13 + c! rot \ replace 'x' - unsetenv - - s" ansi_caption[x]" \ ANSI caption basename - -rot 2dup 13 + c! rot \ replace 'x' - unsetenv - - s" toggled_text[x]" \ toggle_menuitem caption basename - -rot 2dup 13 + c! rot \ replace 'x' - unsetenv - - s" toggled_ansi[x]" \ toggle_menuitem ANSI caption basename - -rot 2dup 13 + c! rot \ replace 'x' - unsetenv - - s" menu_caption[x][y]" \ cycle_menuitem caption - -rot 2dup 13 + c! rot \ replace 'x' - 49 -rot - begin - 16 2over rot + c! \ replace 'y' - 2dup unsetenv - - rot 1+ dup 56 > 2swap rot - until - 2drop drop - - s" ansi_caption[x][y]" \ cycle_menuitem ANSI caption - -rot 2dup 13 + c! rot \ replace 'x' - 49 -rot + dup menu_init[x] unsetenv \ menu initializer + dup menu_command[x] unsetenv \ menu command + dup menu_caption[x] unsetenv \ menu caption + dup ansi_caption[x] unsetenv \ ANSI caption + dup menu_keycode[x] unsetenv \ menu keycode + dup toggled_text[x] unsetenv \ toggle_menuitem caption + dup toggled_ansi[x] unsetenv \ toggle_menuitem ANSI caption + + 48 \ Iterator start (inner range 48 to 57; ASCII '0' to '9') begin - 16 2over rot + c! \ replace 'y' - 2dup unsetenv - - rot 1+ dup 56 > 2swap rot + \ cycle_menuitem caption and ANSI caption + 2dup menu_caption[x][y] unsetenv + 2dup ansi_caption[x][y] unsetenv + 1+ dup 57 > until - 2drop drop + drop \ inner iterator - s" 0 menukeyN !" \ basename for key association var - -rot 2dup 9 + c! rot \ replace 'N' with current iteration - evaluate \ assign zero (0) to key assoc. var + 0 over menukeyN ! \ used by menu-create, menu-display + 0 over init_stateN ! \ used by menu-create + 0 over toggle_stateN ! \ used by toggle_menuitem + 0 over init_textN c! \ used by toggle_menuitem + 0 over cycle_stateN ! \ used by cycle_menuitem 1+ dup 56 > \ increment, continue if less than 57 until drop \ iterator - \ unset the timeout command - s" menu_timeout_command" unsetenv + str_menu_timeout_command unsetenv \ menu timeout command + str_menu_reboot unsetenv \ Reboot menu option flag + str_menu_acpi unsetenv \ ACPI menu option flag + str_menu_options unsetenv \ Options separator flag + str_menu_optionstext unsetenv \ separator display text + str_menu_init unsetenv \ menu initializer - \ clear the "Reboot" menu option flag - s" menu_reboot" unsetenv 0 menureboot ! - - \ clear the ACPI menu option flag - s" menu_acpi" unsetenv 0 menuacpi ! - - \ clear the "Options" menu separator flag - s" menu_options" unsetenv 0 menuoptions ! - ; \ This function both unsets menu variables and visually erases the menu area @@ -984,10 +1025,17 @@ create init_text8 255 allot menu-erase ; -\ Assign configuration values bullet menubllt ! -10 menuY ! -5 menuX ! + +\ Initialize our menu initialization state variables +0 init_state1 ! +0 init_state2 ! +0 init_state3 ! +0 init_state4 ! +0 init_state5 ! +0 init_state6 ! +0 init_state7 ! +0 init_state8 ! \ Initialize our boolean state variables 0 toggle_state1 ! diff --git a/sys/boot/forth/menu.4th.8 b/sys/boot/forth/menu.4th.8 index ed71b89f..ab67d732 100644 --- a/sys/boot/forth/menu.4th.8 +++ b/sys/boot/forth/menu.4th.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2011 Devin Teske +.\" Copyright (c) 2011-2013 Devin Teske .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 25, 2012 +.Dd August 6, 2013 .Dt MENU.4TH 8 .Os .Sh NAME @@ -83,13 +83,14 @@ The environment variables that effect its behavior are: .Bl -tag -width bootfile -offset indent .It Va loader_color If set to -.Dq Li YES +.Dq Li NO (case-insensitive) or -.Dq Li 1 , -causes the menu to be displayed in color wherever possible. -This includes the -use of ANSI bold for numbers appearing to the left of menuitems and the use of -special +.Dq Li 0 , +causes the menu to be displayed without color. +The default is to use ANSI coloring whenever possible. +If serial boot is enabled, color is disabled by default. +Color features include the use of ANSI bold for numbers appearing to the left +of menuitems and the use of special .Dq Li ansi variables described below. .It Va autoboot_delay @@ -108,8 +109,9 @@ will wait for user input and never execute If set to .Dq Li -1 , .Ic menu-display -will boot immediately, preventing both interruption of the autoboot process and -escaping to the loader prompt. +will boot immediately, preventing both interruption of the +.Ic autoboot +process and escaping to the loader prompt. Default is .Dq Li 10 . See @@ -121,6 +123,14 @@ The command to be executed after seconds if a key is not pressed. The default is .Ic boot . +.It Va loader_menu_frame +Sets the desired box style to draw around the boot menu. +Possible values are: +.Dq Li single +.Pq the default , +.Dq Li double , +and +.Dq Li none . .It Va loader_menu_timeout_x Sets the desired column position of the timeout countdown text. Default is 4. @@ -128,9 +138,24 @@ Default is 4. Sets the desired row position of the timeout countdown text. Default is 23. .It Va loader_menu_title -The text to display centered above the menu. +The text to display above the menu. Default is .Dq Li "Welcome to FreeBSD" . +.It Va loader_menu_title_align +Default is to align +.Ic loader_menu_title +centered above the menu. This can be set to +.Dq Li left +or +.Dq Li right +to instead display the title left-or-right justified +.Pq respectively . +.It Va loader_menu_x +Sets the desired column position of the boot menu. +Default is 5. +.It Va loader_menu_y +Sets the desired row position of the boot menu. +Default is 10. .It Va menu_caption[x] The text to be displayed for the numbered menuitem .Dq Li x . @@ -147,7 +172,9 @@ When pressed, will cause the execution of .It Va ansi_caption[x] If .Va loader_color -is set, use this caption for menuitem +is set +.Pq enabled by default , +use this caption for menuitem .Dq Li x instead of .Va menu_caption[x] . @@ -164,7 +191,8 @@ Like .Va toggled_text[x] except used when .Va loader_color -is enabled. +is enabled +.Pq default . .It Va menu_caption[x][y] For menuitems where .Va menu_command[x] @@ -178,7 +206,8 @@ Like .Va menu_caption[x][y] except used when .Va loader_color -is enabled. +is enabled +.Pq default . .It Va menu_acpi When set to a number .Dq Li x @@ -320,4 +349,4 @@ The .Nm set of commands was written by .An -nosplit -.An Devin Teske Aq devinteske@hotmail.com . +.An Devin Teske Aq dteske@FreeBSD.org . diff --git a/sys/boot/forth/menu.rc b/sys/boot/forth/menu.rc index c2faf687..3e345f71 100644 --- a/sys/boot/forth/menu.rc +++ b/sys/boot/forth/menu.rc @@ -16,56 +16,100 @@ draw-brand \ draw the FreeBSD title (top-left; see `brand.4th') menu-init \ initialize the menu area (see `menu.4th') \ Initialize main menu constructs (see `menu.4th') -\ NOTE: To use the `ansi' variants, add `loader_color=1' to loader.conf(5) +\ NOTE: To use `non-ansi' variants, add `loader_color=0' to loader.conf(5) -set menu_caption[1]="Boot [Enter]" -set menu_command[1]="boot" -set ansi_caption[1]="Boot [Enter]" -set menu_keycode[1]="98" +\ +\ MAIN MENU +\ + +set menuset_name1="main" + +set mainmenu_init[1]="init_boot" +set mainmenu_caption[1]="Boot Multi User [Enter]" +set maintoggled_text[1]="Boot [S]ingle User [Enter]" +set mainmenu_command[1]="boot" +set mainansi_caption[1]="Boot Multi User [Enter]" +set maintoggled_ansi[1]="Boot Single User [Enter]" +\ keycode set by init_boot + +set mainmenu_init[2]="init_altboot" +set mainmenu_caption[2]="Boot [S]ingle User" +set maintoggled_text[2]="Boot [M]ulti User" +set mainmenu_command[2]="altboot" +set mainansi_caption[2]="Boot Single User" +set maintoggled_ansi[2]="Boot Multi User" +\ keycode set by init_altboot -set menu_caption[2]="[Esc]ape to loader prompt" -set menu_command[2]="goto_prompt" -set menu_keycode[2]="27" -set ansi_caption[2]="Escape to loader prompt" +set mainmenu_caption[3]="[Esc]ape to loader prompt" +set mainmenu_command[3]="goto_prompt" +set mainmenu_keycode[3]=27 +set mainansi_caption[3]="Escape to loader prompt" \ Enable built-in "Reboot" trailing menuitem \ NOTE: appears before menu_options if configured \ -set menu_reboot +set mainmenu_reboot \ Enable "Options:" separator. When set to a numerical value (1-8), a visual \ separator is inserted before that menuitem number. \ -set menu_options=4 - -set menu_caption[4]="[A]CPI Support off" -set toggled_text[4]="[A]CPI Support On" -set menu_command[4]="toggle_acpi" -set menu_keycode[4]="97" -set menu_acpi=4 -set ansi_caption[4]="ACPI Support Off" -set toggled_ansi[4]="ACPI Support On" - -set menu_caption[5]="Safe [M]ode... off" -set toggled_text[5]="Safe [M]ode... On" -set menu_command[5]="toggle_safemode" -set menu_keycode[5]="109" -set ansi_caption[5]="Safe Mode... Off" -set toggled_ansi[5]="Safe Mode... On" - -set menu_caption[6]="[S]ingle User. off" -set toggled_text[6]="[S]ingle User. On" -set menu_command[6]="toggle_singleuser" -set menu_keycode[6]="115" -set ansi_caption[6]="Single User. Off" -set toggled_ansi[6]="Single User. On" - -set menu_caption[7]="[V]erbose..... off" -set toggled_text[7]="[V]erbose..... On" -set menu_command[7]="toggle_verbose" -set menu_keycode[7]="118" -set ansi_caption[7]="Verbose..... Off" -set toggled_ansi[7]="Verbose..... On" +set mainmenu_options=5 + +set mainmenu_caption[5]="Configure Boot [O]ptions..." +set mainmenu_command[5]="2 goto_menu" +set mainmenu_keycode[5]=111 +set mainansi_caption[5]="Configure Boot Options..." + +\ +\ BOOT OPTIONS MENU +\ + +set menuset_name2="options" + +set optionsmenu_caption[1]="Back to Main Menu [Backspace]" +set optionsmenu_command[1]="1 goto_menu" +set optionsmenu_keycode[1]=8 +set optionsansi_caption[1]="Back to Main Menu [Backspace]" + +set optionsmenu_caption[2]="Load System [D]efaults" +set optionsmenu_command[2]="set_default_boot_options" +set optionsmenu_keycode[2]=100 +set optionsansi_caption[2]="Load System Defaults" + +set optionsmenu_options=3 +set optionsmenu_optionstext="Boot Options:" + +set optionsmenu_acpi=3 +set optionsmenu_caption[3]="[A]CPI Support off" +set optionstoggled_text[3]="[A]CPI Support On" +set optionsmenu_command[3]="toggle_acpi" +set optionsmenu_keycode[3]=97 +set optionsansi_caption[3]="ACPI Support Off" +set optionstoggled_ansi[3]="ACPI Support On" + +set optionsmenu_init[4]="init_safemode" +set optionsmenu_caption[4]="Safe [M]ode... off" +set optionstoggled_text[4]="Safe [M]ode... On" +set optionsmenu_command[4]="toggle_safemode" +set optionsmenu_keycode[4]=109 +set optionsansi_caption[4]="Safe Mode... Off" +set optionstoggled_ansi[4]="Safe Mode... On" + +set optionsmenu_init[5]="init_singleuser" +set optionsmenu_caption[5]="[S]ingle User. off" +set optionstoggled_text[5]="[S]ingle User. On" +set optionsmenu_command[5]="toggle_singleuser" +set optionsmenu_keycode[5]=115 +set optionsansi_caption[5]="Single User. Off" +set optionstoggled_ansi[5]="Single User. On" + +set optionsmenu_init[6]="init_verbose" +set optionsmenu_caption[6]="[V]erbose..... off" +set optionstoggled_text[6]="[V]erbose..... On" +set optionsmenu_command[6]="toggle_verbose" +set optionsmenu_keycode[6]=118 +set optionsansi_caption[6]="Verbose..... Off" +set optionstoggled_ansi[6]="Verbose..... On" \ Enable automatic booting (add ``autoboot_delay=N'' to loader.conf(5) to \ customize the timeout; default is 10-seconds) @@ -73,4 +117,6 @@ set toggled_ansi[7]="Verbose..... On" set menu_timeout_command="boot" \ Display the main menu (see `menu.4th') +set menuset_initial=1 +menuset-loadinitial menu-display diff --git a/sys/boot/forth/menusets.4th b/sys/boot/forth/menusets.4th new file mode 100644 index 00000000..630239fa --- /dev/null +++ b/sys/boot/forth/menusets.4th @@ -0,0 +1,610 @@ +\ Copyright (c) 2012 Devin Teske +\ All rights reserved. +\ +\ Redistribution and use in source and binary forms, with or without +\ modification, are permitted provided that the following conditions +\ are met: +\ 1. Redistributions of source code must retain the above copyright +\ notice, this list of conditions and the following disclaimer. +\ 2. Redistributions in binary form must reproduce the above copyright +\ notice, this list of conditions and the following disclaimer in the +\ documentation and/or other materials provided with the distribution. +\ +\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +\ SUCH DAMAGE. +\ +\ $FreeBSD$ + +marker task-menusets.4th + +variable menuset_use_name + +create menuset_affixbuf 255 allot +create menuset_x 1 allot +create menuset_y 1 allot + +: menuset-loadvar ( -- ) + + \ menuset_use_name is true or false + \ $type should be set to one of: + \ menu toggled ansi + \ $var should be set to one of: + \ caption command keycode text ... + \ $affix is either prefix (menuset_use_name is true) + \ or infix (menuset_use_name is false) + + s" set cmdbuf='set ${type}_${var}=\$'" evaluate + s" cmdbuf" getenv swap drop ( -- u1 ) \ get string length + menuset_use_name @ true = if + s" set cmdbuf=${cmdbuf}${affix}${type}_${var}" + ( u1 -- u1 c-addr2 u2 ) + else + s" set cmdbuf=${cmdbuf}${type}set${affix}_${var}" + ( u1 -- u1 c-addr2 u2 ) + then + evaluate ( u1 c-addr2 u2 -- u1 ) + s" cmdbuf" getenv ( u1 -- u1 c-addr2 u2 ) + rot 2 pick 2 pick over + -rot + tuck - + ( u1 c-addr2 u2 -- c-addr2 u2 c-addr1 u1 ) + \ Generate a string representing rvalue inheritance var + getenv dup -1 = if + ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 -1 ) + \ NOT set -- clean up the stack + drop ( c-addr2 u2 -1 -- c-addr2 u2 ) + 2drop ( c-addr2 u2 -- ) + else + ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 c-addr1 u1 ) + \ SET -- execute cmdbuf (c-addr2/u2) to inherit value + 2drop ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 ) + evaluate ( c-addr2 u2 -- ) + then + + s" cmdbuf" unsetenv +; + +: menuset-unloadvar ( -- ) + + \ menuset_use_name is true or false + \ $type should be set to one of: + \ menu toggled ansi + \ $var should be set to one of: + \ caption command keycode text ... + \ $affix is either prefix (menuset_use_name is true) + \ or infix (menuset_use_name is false) + + menuset_use_name @ true = if + s" set buf=${affix}${type}_${var}" + else + s" set buf=${type}set${affix}_${var}" + then + evaluate + s" buf" getenv unsetenv + s" buf" unsetenv +; + +: menuset-loadmenuvar ( -- ) + s" set type=menu" evaluate + menuset-loadvar +; + +: menuset-unloadmenuvar ( -- ) + s" set type=menu" evaluate + menuset-unloadvar +; + +: menuset-loadxvar ( -- ) + + \ menuset_use_name is true or false + \ $type should be set to one of: + \ menu toggled ansi + \ $var should be set to one of: + \ caption command keycode text ... + \ $x is "1" through "8" + \ $affix is either prefix (menuset_use_name is true) + \ or infix (menuset_use_name is false) + + s" set cmdbuf='set ${type}_${var}[${x}]=\$'" evaluate + s" cmdbuf" getenv swap drop ( -- u1 ) \ get string length + menuset_use_name @ true = if + s" set cmdbuf=${cmdbuf}${affix}${type}_${var}[${x}]" + ( u1 -- u1 c-addr2 u2 ) + else + s" set cmdbuf=${cmdbuf}${type}set${affix}_${var}[${x}]" + ( u1 -- u1 c-addr2 u2 ) + then + evaluate ( u1 c-addr2 u2 -- u1 ) + s" cmdbuf" getenv ( u1 -- u1 c-addr2 u2 ) + rot 2 pick 2 pick over + -rot + tuck - + ( u1 c-addr2 u2 -- c-addr2 u2 c-addr1 u1 ) + \ Generate a string representing rvalue inheritance var + getenv dup -1 = if + ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 -1 ) + \ NOT set -- clean up the stack + drop ( c-addr2 u2 -1 -- c-addr2 u2 ) + 2drop ( c-addr2 u2 -- ) + else + ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 c-addr1 u1 ) + \ SET -- execute cmdbuf (c-addr2/u2) to inherit value + 2drop ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 ) + evaluate ( c-addr2 u2 -- ) + then + + s" cmdbuf" unsetenv +; + +: menuset-unloadxvar ( -- ) + + \ menuset_use_name is true or false + \ $type should be set to one of: + \ menu toggled ansi + \ $var should be set to one of: + \ caption command keycode text ... + \ $x is "1" through "8" + \ $affix is either prefix (menuset_use_name is true) + \ or infix (menuset_use_name is false) + + menuset_use_name @ true = if + s" set buf=${affix}${type}_${var}[${x}]" + else + s" set buf=${type}set${affix}_${var}[${x}]" + then + evaluate + s" buf" getenv unsetenv + s" buf" unsetenv +; + +: menuset-loadansixvar ( -- ) + s" set type=ansi" evaluate + menuset-loadxvar +; + +: menuset-unloadansixvar ( -- ) + s" set type=ansi" evaluate + menuset-unloadxvar +; + +: menuset-loadmenuxvar ( -- ) + s" set type=menu" evaluate + menuset-loadxvar +; + +: menuset-unloadmenuxvar ( -- ) + s" set type=menu" evaluate + menuset-unloadxvar +; + +: menuset-loadtoggledxvar ( -- ) + s" set type=toggled" evaluate + menuset-loadxvar +; + +: menuset-unloadtoggledxvar ( -- ) + s" set type=toggled" evaluate + menuset-unloadxvar +; + +: menuset-loadxyvar ( -- ) + + \ menuset_use_name is true or false + \ $type should be set to one of: + \ menu toggled ansi + \ $var should be set to one of: + \ caption command keycode text ... + \ $x is "1" through "8" + \ $y is "0" through "9" + \ $affix is either prefix (menuset_use_name is true) + \ or infix (menuset_use_name is false) + + s" set cmdbuf='set ${type}_${var}[${x}][${y}]=\$'" evaluate + s" cmdbuf" getenv swap drop ( -- u1 ) \ get string length + menuset_use_name @ true = if + s" set cmdbuf=${cmdbuf}${affix}${type}_${var}[${x}][${y}]" + ( u1 -- u1 c-addr2 u2 ) + else + s" set cmdbuf=${cmdbuf}${type}set${affix}_${var}[${x}][${y}]" + ( u1 -- u1 c-addr2 u2 ) + then + evaluate ( u1 c-addr2 u2 -- u1 ) + s" cmdbuf" getenv ( u1 -- u1 c-addr2 u2 ) + rot 2 pick 2 pick over + -rot + tuck - + ( u1 c-addr2 u2 -- c-addr2 u2 c-addr1 u1 ) + \ Generate a string representing rvalue inheritance var + getenv dup -1 = if + ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 -1 ) + \ NOT set -- clean up the stack + drop ( c-addr2 u2 -1 -- c-addr2 u2 ) + 2drop ( c-addr2 u2 -- ) + else + ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 c-addr1 u1 ) + \ SET -- execute cmdbuf (c-addr2/u2) to inherit value + 2drop ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 ) + evaluate ( c-addr2 u2 -- ) + then + + s" cmdbuf" unsetenv +; + +: menuset-unloadxyvar ( -- ) + + \ menuset_use_name is true or false + \ $type should be set to one of: + \ menu toggled ansi + \ $var should be set to one of: + \ caption command keycode text ... + \ $x is "1" through "8" + \ $y is "0" through "9" + \ $affix is either prefix (menuset_use_name is true) + \ or infix (menuset_use_name is false) + + menuset_use_name @ true = if + s" set buf=${affix}${type}_${var}[${x}][${y}]" + else + s" set buf=${type}set${affix}_${var}[${x}][${y}]" + then + evaluate + s" buf" getenv unsetenv + s" buf" unsetenv +; + +: menuset-loadansixyvar ( -- ) + s" set type=ansi" evaluate + menuset-loadxyvar +; + +: menuset-unloadansixyvar ( -- ) + s" set type=ansi" evaluate + menuset-unloadxyvar +; + +: menuset-loadmenuxyvar ( -- ) + s" set type=menu" evaluate + menuset-loadxyvar +; + +: menuset-unloadmenuxyvar ( -- ) + s" set type=menu" evaluate + menuset-unloadxyvar +; + +: menuset-setnum-namevar ( N -- C-Addr/U ) + + s" menuset_nameNNNNN" ( n -- n c-addr1 u1 ) \ variable basename + drop 12 ( n c-addr1 u1 -- n c-addr1 12 ) \ remove "NNNNN" + rot ( n c-addr1 12 -- c-addr1 12 n ) \ move number on top + + \ convert to string + s>d <# #s #> ( c-addr1 12 n -- c-addr1 12 c-addr2 u2 ) + + \ Combine strings + begin ( using u2 in c-addr2/u2 pair as countdown to zero ) + over ( c-addr1 u1 c-addr2 u2 -- continued below ) + ( c-addr1 u1 c-addr2 u2 c-addr2 ) \ copy src-addr + c@ ( c-addr1 u1 c-addr2 u2 c-addr2 -- continued below ) + ( c-addr1 u1 c-addr2 u2 c ) \ get next src-addr byte + 4 pick 4 pick + ( c-addr1 u1 c-addr2 u2 c -- continued below ) + ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 ) + \ get destination c-addr1/u1 pair + + ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 -- cont. below ) + ( c-addr1 u1 c-addr2 u2 c c-addr3 ) + \ combine dest-c-addr to get dest-addr for byte + c! ( c-addr1 u1 c-addr2 u2 c c-addr3 -- continued below ) + ( c-addr1 u1 c-addr2 u2 ) + \ store the current src-addr byte into dest-addr + + 2swap 1+ 2swap \ increment u1 in destination c-addr1/u1 pair + swap 1+ swap \ increment c-addr2 in source c-addr2/u2 pair + 1- \ decrement u2 in the source c-addr2/u2 pair + + dup 0= \ time to break? + until + + 2drop ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 ) + \ drop temporary number-format conversion c-addr2/u2 +; + +: menuset-checksetnum ( N -- ) + + \ + \ adjust input to be both positive and no-higher than 65535 + \ + abs dup 65535 > if drop 65535 then ( n -- n ) + + \ + \ The next few blocks will determine if we should use the default + \ methodology (referencing the original numeric stack-input), or if- + \ instead $menuset_name{N} has been defined wherein we would then + \ use the value thereof as the prefix to every menu variable. + \ + + false menuset_use_name ! \ assume name is not set + + menuset-setnum-namevar + \ + \ We now have a string that is the assembled variable name to check + \ for... $menuset_name{N}. Let's check for it. + \ + 2dup ( c-addr1 u1 -- c-addr1 u1 c-addr1 u1 ) \ save a copy + getenv dup -1 <> if ( c-addr1 u1 c-addr1 u1 -- c-addr1 u1 c-addr2 u2 ) + \ The variable is set. Let's clean up the stack leaving only + \ its value for later use. + + true menuset_use_name ! + 2swap 2drop ( c-addr1 u1 c-addr2 u2 -- c-addr2 u2 ) + \ drop assembled variable name, leave the value + else ( c-addr1 u1 c-addr1 u1 -- c-addr1 u1 -1 ) \ no such variable + \ The variable is not set. Let's clean up the stack leaving the + \ string [portion] representing the original numeric input. + + drop ( c-addr1 u1 -1 -- c-addr1 u1 ) \ drop -1 result + 12 - swap 12 + swap ( c-addr1 u1 -- c-addr2 u2 ) + \ truncate to original numeric stack-input + then + + \ + \ Now, depending on whether $menuset_name{N} has been set, we have + \ either the value thereof to be used as a prefix to all menu_* + \ variables or we have a string representing the numeric stack-input + \ to be used as a "set{N}" infix to the same menu_* variables. + \ + \ For example, if the stack-input is 1 and menuset_name1 is NOT set + \ the following variables will be referenced: + \ ansiset1_caption[x] -> ansi_caption[x] + \ ansiset1_caption[x][y] -> ansi_caption[x][y] + \ menuset1_acpi -> menu_acpi + \ menuset1_caption[x] -> menu_caption[x] + \ menuset1_caption[x][y] -> menu_caption[x][y] + \ menuset1_command[x] -> menu_command[x] + \ menuset1_init -> ``evaluated'' + \ menuset1_init[x] -> menu_init[x] + \ menuset1_keycode[x] -> menu_keycode[x] + \ menuset1_options -> menu_options + \ menuset1_optionstext -> menu_optionstext + \ menuset1_reboot -> menu_reboot + \ toggledset1_ansi[x] -> toggled_ansi[x] + \ toggledset1_text[x] -> toggled_text[x] + \ otherwise, the following variables are referenced (where {name} + \ represents the value of $menuset_name1 (given 1 as stack-input): + \ {name}ansi_caption[x] -> ansi_caption[x] + \ {name}ansi_caption[x][y] -> ansi_caption[x][y] + \ {name}menu_acpi -> menu_acpi + \ {name}menu_caption[x] -> menu_caption[x] + \ {name}menu_caption[x][y] -> menu_caption[x][y] + \ {name}menu_command[x] -> menu_command[x] + \ {name}menu_init -> ``evaluated'' + \ {name}menu_init[x] -> menu_init[x] + \ {name}menu_keycode[x] -> menu_keycode[x] + \ {name}menu_options -> menu_options + \ {name}menu_optionstext -> menu_optionstext + \ {name}menu_reboot -> menu_reboot + \ {name}toggled_ansi[x] -> toggled_ansi[x] + \ {name}toggled_text[x] -> toggled_text[x] + \ + \ Note that menuset{N}_init and {name}menu_init are the initializers + \ for the entire menu (for wholly dynamic menus) opposed to the per- + \ menuitem initializers (with [x] afterward). The whole-menu init + \ routine is evaluated and not passed down to $menu_init (which + \ would result in double evaluation). By doing this, the initializer + \ can initialize the menuset before we transfer it to active-duty. + \ + + \ + \ Copy our affixation (prefix or infix depending on menuset_use_name) + \ to our buffer so that we can safely use the s-quote (s") buf again. + \ + menuset_affixbuf 0 2swap ( c-addr2 u2 -- c-addr1 0 c-addr2 u2 ) + begin ( using u2 in c-addr2/u2 pair as countdown to zero ) + over ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 c-addr2 u2 c-addr2 ) + c@ ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 c-addr2 u2 c ) + 4 pick 4 pick + ( c-addr1 u1 c-addr2 u2 c -- continued below ) + ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 ) + + ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 -- continued below ) + ( c-addr1 u1 c-addr2 u2 c c-addr3 ) + c! ( c-addr1 u1 c-addr2 u2 c c-addr3 -- continued below ) + ( c-addr1 u1 c-addr2 u2 ) + 2swap 1+ 2swap \ increment affixbuf byte position/count + swap 1+ swap \ increment strbuf pointer (source c-addr2) + 1- \ decrement strbuf byte count (source u2) + dup 0= \ time to break? + until + 2drop ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 ) \ drop strbuf c-addr2/u2 + + \ + \ Create a variable for referencing our affix data (prefix or infix + \ depending on menuset_use_name as described above). This variable will + \ be temporary and only used to simplify cmdbuf assembly. + \ + s" affix" setenv ( c-addr1 u1 -- ) +; + +: menuset-cleanup ( -- ) + s" type" unsetenv + s" var" unsetenv + s" x" unsetenv + s" y" unsetenv + s" affix" unsetenv +; + +: menuset-loadsetnum ( N -- ) + + menuset-checksetnum ( n -- ) + + \ + \ From here out, we use temporary environment variables to make + \ dealing with variable-length strings easier. + \ + \ menuset_use_name is true or false + \ $affix should be used appropriately w/respect to menuset_use_name + \ + + \ ... menu_init ... + s" set var=init" evaluate + menuset-loadmenuvar + + \ If menu_init was set by the above, evaluate it here-and-now + \ so that the remaining variables are influenced by its actions + s" menu_init" 2dup getenv dup -1 <> if + 2swap unsetenv \ don't want later menu-create to re-call this + evaluate + else + drop 2drop ( n c-addr u -1 -- n ) + then + + [char] 1 ( -- x ) \ Loop range ASCII '1' (49) to '8' (56) + begin + dup menuset_x tuck c! 1 s" x" setenv \ set loop iterator and $x + + s" set var=caption" evaluate + + \ ... menu_caption[x] ... + menuset-loadmenuxvar + + \ ... ansi_caption[x] ... + menuset-loadansixvar + + [char] 0 ( x -- x y ) \ Inner Loop ASCII '1' (48) to '9' (57) + begin + dup menuset_y tuck c! 1 s" y" setenv + \ set inner loop iterator and $y + + \ ... menu_caption[x][y] ... + menuset-loadmenuxyvar + + \ ... ansi_caption[x][y] ... + menuset-loadansixyvar + + 1+ dup 57 > ( x y -- y' 0|-1 ) \ increment and test + until + drop ( x y -- x ) + + \ ... menu_command[x] ... + s" set var=command" evaluate + menuset-loadmenuxvar + + \ ... menu_init[x] ... + s" set var=init" evaluate + menuset-loadmenuxvar + + \ ... menu_keycode[x] ... + s" set var=keycode" evaluate + menuset-loadmenuxvar + + \ ... toggled_text[x] ... + s" set var=text" evaluate + menuset-loadtoggledxvar + + \ ... toggled_ansi[x] ... + s" set var=ansi" evaluate + menuset-loadtoggledxvar + + 1+ dup 56 > ( x -- x' 0|-1 ) \ increment iterator + \ continue if less than 57 + until + drop ( x -- ) \ loop iterator + + \ ... menu_reboot ... + s" set var=reboot" evaluate + menuset-loadmenuvar + + \ ... menu_acpi ... + s" set var=acpi" evaluate + menuset-loadmenuvar + + \ ... menu_options ... + s" set var=options" evaluate + menuset-loadmenuvar + + \ ... menu_optionstext ... + s" set var=optionstext" evaluate + menuset-loadmenuvar + + menuset-cleanup +; + +: menuset-loadinitial ( -- ) + s" menuset_initial" getenv dup -1 <> if + ?number 0<> if + menuset-loadsetnum + then + else + drop \ cruft + then +; + +: menusets-unset ( -- ) + + s" menuset_initial" unsetenv + + 1 begin + dup menuset-checksetnum ( n n -- n ) + + dup menuset-setnum-namevar ( n n -- n ) + unsetenv + + \ If the current menuset does not populate the first menuitem, + \ we stop completely. + + menuset_use_name @ true = if + s" set buf=${affix}menu_caption[1]" + else + s" set buf=menuset${affix}_caption[1]" + then + evaluate s" buf" getenv getenv -1 = if + drop ( n -- ) + s" buf" unsetenv + menuset-cleanup + exit + else + drop ( n c-addr2 -- n ) \ unused + then + + [char] 1 ( n -- n x ) \ Loop range ASCII '1' (49) to '8' (56) + begin + dup menuset_x tuck c! 1 s" x" setenv \ set $x to x + + s" set var=caption" evaluate + menuset-unloadmenuxvar + menuset-unloadmenuxvar + menuset-unloadansixvar + [char] 0 ( n x -- n x y ) \ Inner loop '0' to '9' + begin + dup menuset_y tuck c! 1 s" y" setenv + \ sets $y to y + menuset-unloadmenuxyvar + menuset-unloadansixyvar + 1+ dup 57 > ( n x y -- n x y' 0|-1 ) + until + drop ( n x y -- n x ) + s" set var=command" evaluate menuset-unloadmenuxvar + s" set var=init" evaluate menuset-unloadmenuxvar + s" set var=keycode" evaluate menuset-unloadmenuxvar + s" set var=text" evaluate menuset-unloadtoggledxvar + s" set var=ansi" evaluate menuset-unloadtoggledxvar + + 1+ dup 56 > ( x -- x' 0|-1 ) \ increment and test + until + drop ( n x -- n ) \ loop iterator + + s" set var=acpi" evaluate menuset-unloadmenuvar + s" set var=init" evaluate menuset-unloadmenuvar + s" set var=options" evaluate menuset-unloadmenuvar + s" set var=optionstext" evaluate menuset-unloadmenuvar + s" set var=reboot" evaluate menuset-unloadmenuvar + + 1+ dup 65535 > ( n -- n' 0|-1 ) \ increment and test + until + drop ( n' -- ) \ loop iterator + + s" buf" unsetenv + menuset-cleanup +; diff --git a/sys/boot/forth/menusets.4th.8 b/sys/boot/forth/menusets.4th.8 new file mode 100644 index 00000000..e05e4a7d --- /dev/null +++ b/sys/boot/forth/menusets.4th.8 @@ -0,0 +1,372 @@ +.\" Copyright (c) 2012 Devin Teske +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd November 5, 2012 +.Dt MENUSETS.4TH 8 +.Os +.Sh NAME +.Nm menusets.4th +.Nd FreeBSD dynamic submenu boot module +.Sh DESCRIPTION +The file that goes by the name of +.Nm +is a set of commands designed to add submenu functionality to the dynamic menu +system provided by +.Xr menu.4th 8 . +Submenus are managed through a system of carefully named environment variables. +The commands of +.Nm +by themselves are not enough for most uses. +Please refer to the examples below for the most common situations, and to +.Xr menu.4th 8 +for additional commands. +.Pp +Before using any of the commands provided in +.Nm , +it must be included +through the command: +.Pp +.Dl include menusets.4th +.Pp +This line is present in the default +.Pa /boot/menu-commands.4th +file, so it is not needed (and should not be re-issued) in a normal setup. +.Pp +The commands provided by it are: +.Pp +.Bl -tag -width menuset-loadinitial -compact -offset indent +.It Ic menuset-loadsetnum +Takes a single integer on the stack to identify the menuset environment +variables to be activated (see environment variables below). +.It Ic menuset-loadinitial +If $menuset_initial is set, passes the value to menuset-loadsetnum. +The value must be a number. +.It Ic menusets-unset +Unsets the environment variables associated with all menusets. +Increments starting at 1 and stops at the first unconfigured menuset. +A menuset is considered configured if the caption for item 1 is set. +.El +.Pp +The environment variables that effect its behavior are: +.Bl -tag -width bootfile -offset indent +.It Va menuset_initial +Number to pass to menuset-loadsetnum when menuset-loadinitial is called. +.It Va menuset_nameN +Used to give a name to a menuset. +.El +.Pp +When a menuset is NOT given a name (the default), +menuset N is comprised of the following environment variables: +.Pp +.Bl -tag -width menusetN_caption[x][y] -compact -offset indent +.It Va ansisetN_caption[x] +-> ansi_caption[x] +.It Va ansisetN_caption[x][y] +-> ansi_caption[x][y] +.It Va menusetN_acpi +-> menu_acpi +.It Va menusetN_caption[x] +-> menu_caption[x] +.It Va menusetN_caption[x][y] +-> menu_caption[x][y] +.It Va menusetN_command[x] +-> menu_command[x] +.It Va menusetN_init +-> +.Dq Li evaluated +.It Va menusetN_init[x] +-> menu_init[x] +.It Va menusetN_keycode[x] +-> menu_keycode[x] +.It Va menusetN_options +-> menu_options +.It Va menusetN_optionstext +-> menu_optionstext +.It Va menusetN_reboot +-> menu_reboot +.It Va toggledsetN_ansi[x] +-> toggled_ansi[x] +.It Va toggledsetN_text[x] +-> toggled_text[x] +.El +.Pp +When you choose to give a menuset a name (by setting $menuset_nameN), +menuset N is instead comprised of the following environment variables: +.Pp +.Bl -tag -width NAMEmenu_caption[x][y] -compact -offset indent +.It Va NAMEansi_caption[x] +-> ansi_caption[x] +.It Va NAMEansi_caption[x][y] +-> ansi_caption[x][y] +.It Va NAMEmenu_acpi +-> menu_acpi +.It Va NAMEmenu_caption[x] +-> menu_caption[x] +.It Va NAMEmenu_caption[x][y] +-> menu_caption[x][y] +.It Va NAMEmenu_command[x] +-> menu_command[x] +.It Va NAMEmenu_init +-> +.Dq Li evaluated +.It Va NAMEmenu_init[x] +-> menu_init[x] +.It Va NAMEmenu_keycode[x] +-> menu_keycode[x] +.It Va NAMEmenu_options +-> menu_options +.It Va NAMEmenu_optionstext +-> menu_optionstext +.It Va NAMEmenu_reboot +-> menu_reboot +.It Va NAMEtoggled_ansi[x] +-> toggled_ansi[x] +.It Va NAMEtoggled_text[x] +-> toggled_text[x] +.El +.Pp +where +.Dq Li NAME +is the value of $menuset_nameN. +In the case of $NAMEmenu_init ($menusetN_init when $menuset_nameN is unset), +the value is evaluated as an FICL statement. +This can be used to dynamically adjust the menuset variables right before the +menu is activated. +.Pp +In addition, +.Nm +provides the following FICL words: +.Pp +.Bl -tag -width menuset -compact -offset indent +.It Ic menuset-checksetnum ( N -- ) +Given a single integer on the stack, sets a global variable +.Va menuset_use_name +to a boolean based on whether $menuset_nameN is set (true) or not (false). +Also sets $affix temporary variable (prefix or infix depending on +menuset_use_name). +Automatically called by menuset-loadsetnum and menusets-unset. +.It Ic menuset-loadvar ( -- ) +Used indirectly to shorten syntax and mitigate dictionary size. +Requires the following temporary environment variables: +.Pp +.Bl -tag -width affix -compact -offset indent +.It Va type +should be set to one of: menu toggled ansi +.It Va var +should be set to one of: caption command keycode text ... +.It Va affix +either a prefix (menuset_use_name is true) or infix (menuset_use_name is false) +.El +.Pp +If the global +.Va menuset_use_name +is true, the variable ${type}_${var} is made to +equal the value of the variable ${affix}${type}_${var} +(note: in this case menuset-checksetnum has set $affix to $menuset_nameN). +Otherwise (when +.Va menuset_use_name +is false), the variable ${type}_${var} is made to +equal the value of the variable ${type}set${affix}_${var} +(note: in this case menuset-checksetnum has set $affix to N). +.Pp +Both the global variable +.Va menuset_use_name +and the environment variable $affix are automatically handled by +menuset-checksetnum above (which is automatically called by +menuset-loadsetnum). +.It Ic menuset-unloadvar ( -- ) +Used indirectly to shorten syntax and mitigate dictionary size. +Like menuset-loadvar except it unsets the menuset variable. +If global +.Va menuset_use_name +is true ($affix is $menuset_nameN), +variable ${affix}${type}_${var} is unset. +Otherwise, $affix is N and variable ${type}set${affix}_${var} is unset. +.It Ic menuset-loadmenuvar ( -- ) +Sets $type to +.Dq menu +and calls menuset-loadvar. +.It Ic menuset-unloadmenuvar ( -- ) +Sets $type to +.Dq menu +and calls menuset-unloadvar. +.It Ic menuset-loadxvar ( -- ) +Like menuset-loadvar except it takes an additional temporary variable $x. +If the global +.Va menuset_use_name +is true (making $affix equal $menuset_nameN), +sets variable ${type}_${var}[${x}] to variable ${affix}${type}_${var}[${x}]. +Otherwise ($affix being N), sets the same variable to instead +${type}set{affix}_${var}[${x}]. +.It Ic menuset-unloadxvar ( -- ) +Like menuset-loadxvar except it unsets the menuset variable. +If global +.Va menuset_use_name +is true, unsets ${affix}${type}_${var}[${x}]. +Otherwise, unsets ${type}set${affix}_${var}[${x}]. +.It Ic menuset-loadansixvar ( -- ) +Sets $type to +.Dq ansi +and calls menuset-loadxvar +.It Ic menuset-unloadansixvar ( -- ) +Sets $type to +.Dq ansi +and calls menuset-unloadxvar +.It Ic menuset-loadmenuxvar ( -- ) +Sets $type to +.Dq ansi +and calls menuset-loadxvar +.It Ic menuset-unloadmenuxvar ( -- ) +Sets $type to +.Dq ansi +and calls menuset-unloadxvar +.It Ic menuset-loadtoggledxvar ( -- ) +Sets $type to +.Dq toggled +and calls menuset-loadxvar +.It Ic menuset-unloadtoggledxvar ( -- ) +Sets $type to +.Dq toggled +and calls menuset-unloadxvar +.It Ic menuset-loadxyvar ( -- ) +Like menuset-loadxvar except it takes an additional temporary variable $y. +If the global +.Va menuset_use_name +is true ($affix is $menuset_nameN), +sets variable ${type}_${var}[${x}][${y}] to ${affix}${type}_${var}[${x}][${y}]. +Otherwise ($affix is N) sets the same variable to instead +${type}set${affix}_${var}[${x}][${y}]. +.It Ic menuset-unloadxyvar ( -- ) +Like menuset-loadxyvar except it unsets the menuset variable. +If the global +.Va menuset_use_name +is true, unsets ${affix}${type}_${var}[${x}][${y}]. +Otherwise, unsets ${type}set${affix}_${var}[${x}][${y}]. +.It Ic menuset-loadansixyvar ( -- ) +Sets $type to +.Dq ansi +and calls menuset-loadxyvar. +.It Ic menuset-unloadansixyvar ( -- ) +Sets $type to +.Dq ansi +and calls menuset-unloadxyvar. +.It Ic menuset-loadmenuxyvar ( -- ) +Sets $type to +.Dq menu +and calls menuset-loadxyvar. +.It Ic menuset-unloadmenuxyvar ( -- ) +Sets $type to +.Dq menu +and calls menuset-unloadxyvar. +.It Ic menuset-setnum-namevar ( N -- C-Addr/U ) +Takes a single integer on the stack and replaces it with a string (in c-addr/u +format) whose value is +.Dq menuset_nameN . +For example, if given 1 returns +.Dq menuset_name1 . +.It Ic menuset-cleanup ( N -- ) +Unsets all the various temporary variables, currently +.Va type , +.Va var , +.Va x , +.Va y , +and +.Va affix . +.El +.Pp +For all values of +.Dq Li x +above, use any number between 1 through 9. Sorry, double-digits are not +currently supported. +For all values of +.Dq Li N +above, use any number between 1 and 65535. +.Sh FILES +.Bl -tag -width /boot/menu-commands.4th -compact +.It Pa /boot/loader +The +.Xr loader 8 . +.It Pa /boot/menu.4th +Dynamic menu module. +.It Pa /boot/menu-commands.4th +Contains the goto_menu command. +.It Pa /boot/menusets.4th +.Nm +itself. +.It Pa /boot/loader.rc +.Xr loader 8 +bootstrapping script. +.El +.Sh EXAMPLES +A simple boot menu with a submenu: +.Pp +.Bd -literal -offset indent -compact +include /boot/menu.4th +include /boot/menu-commands.4th +menu-init +set menuset1_caption[1]="Boot" +set menuset1_command[1]="boot" +set menuset1_caption[2]="Submenu..." +set menuset1_command[2]="2 goto_menu" +set menuset2_caption[1]="Back" +set menuset2_command[1]="1 goto_menu" +set menuset_initial=2 +menuset-loadinitial +menu-display +.Ed +.Pp +The same boot menu with named menusets: +.Pp +.Bd -literal -offset indent -compact +include /boot/menu.4th +include /boot/menu-commands.4th +menu-init +set menuset_name1=main +set mainmenu_caption[1]="Boot" +set mainmenu_command[1]="boot" +set mainmenu_caption[2]="Submenu..." +set mainmenu_command[2]="2 goto_menu" +set menuset_name2=sub +set submenu_caption[1]="Back" +set submenu_command[1]="1 goto_menu" +.Ed +.Sh SEE ALSO +.Xr loader.conf 5 , +.Xr loader 8 , +.Xr loader.4th 8 , +.Xr menu.4th 8 , +.Xr beastie.4th 8 +.Sh HISTORY +The +.Nm +set of commands first appeared in +.Fx 10.0 . +.Sh AUTHORS +The +.Nm +set of commands was written by +.An -nosplit +.An Devin Teske Aq dteske@FreeBSD.org . diff --git a/sys/boot/forth/shortcuts.4th b/sys/boot/forth/shortcuts.4th index 55a369b0..33a1cf67 100644 --- a/sys/boot/forth/shortcuts.4th +++ b/sys/boot/forth/shortcuts.4th @@ -1,4 +1,4 @@ -\ Copyright (c) 2008-2011 Devin Teske +\ Copyright (c) 2008-2011 Devin Teske \ All rights reserved. \ \ Redistribution and use in source and binary forms, with or without diff --git a/sys/boot/forth/support.4th b/sys/boot/forth/support.4th index 3dbeae8d..645e14d8 100644 --- a/sys/boot/forth/support.4th +++ b/sys/boot/forth/support.4th @@ -201,6 +201,46 @@ create last_module_option sizeof module.next allot 0 last_module_option ! : getenv? getenv -1 = if false else drop true then ; +\ determine if a word appears in a string, case-insensitive +: contains? ( addr1 len1 addr2 len2 -- 0 | -1 ) + 2 pick 0= if 2drop 2drop true exit then + dup 0= if 2drop 2drop false exit then + begin + begin + swap dup c@ dup 32 = over 9 = or over 10 = or + over 13 = or over 44 = or swap drop + while 1+ swap 1- repeat + swap 2 pick 1- over < + while + 2over 2over drop over compare-insensitive 0= if + 2 pick over = if 2drop 2drop true exit then + 2 pick tuck - -rot + swap over c@ dup 32 = + over 9 = or over 10 = or over 13 = or over 44 = or + swap drop if 2drop 2drop true exit then + then begin + swap dup c@ dup 32 = over 9 = or over 10 = or + over 13 = or over 44 = or swap drop + if false else true then 2 pick 0> and + while 1+ swap 1- repeat + swap + repeat + 2drop 2drop false +; + +: boot_serial? ( -- 0 | -1 ) + s" console" getenv dup -1 <> if + s" comconsole" 2swap contains? + else drop false then + s" boot_serial" getenv dup -1 <> if + swap drop 0> + else drop false then + or \ console contains comconsole ( or ) boot_serial + s" boot_multicons" getenv dup -1 <> if + swap drop 0> + else drop false then + or \ previous boolean ( or ) boot_multicons +; + \ Private definitions vocabulary support-functions diff --git a/sys/boot/forth/version.4th b/sys/boot/forth/version.4th index c59f825e..358b6b12 100644 --- a/sys/boot/forth/version.4th +++ b/sys/boot/forth/version.4th @@ -1,4 +1,4 @@ -\ Copyright (c) 2006-2011 Devin Teske +\ Copyright (c) 2006-2011 Devin Teske \ All rights reserved. \ \ Redistribution and use in source and binary forms, with or without diff --git a/sys/boot/forth/version.4th.8 b/sys/boot/forth/version.4th.8 index 2d2c39aa..efa6aa66 100644 --- a/sys/boot/forth/version.4th.8 +++ b/sys/boot/forth/version.4th.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2011 Devin Teske +.\" Copyright (c) 2011-2013 Devin Teske .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 19, 2011 +.Dd August 6, 2013 .Dt VERSION.4TH 8 .Os .Sh NAME @@ -84,10 +84,11 @@ Sets the desired ending row position of Default is 24. .It Va loader_color If set to -.Dq Li YES +.Dq Li NO (case-insensitive) or -.Dq Li 1 , -causes the version to be printed in ANSI Cyan. +.Dq Li 0 , +causes the version to be printed without color +.Pq default is ANSI Cyan . .El .Sh FILES .Bl -tag -width /boot/loader.4th -compact @@ -113,6 +114,7 @@ loader_version="loader 1.1" .Sh SEE ALSO .Xr loader.conf 5 , .Xr loader 8 , +.Xr color.4th 8 .Sh HISTORY The .Nm @@ -123,4 +125,4 @@ The .Nm set of commands was written by .An -nosplit -.An Devin Teske Aq devinteske@hotmail.com . +.An Devin Teske Aq dteske@FreeBSD.org . diff --git a/sys/boot/i386/loader/Makefile b/sys/boot/i386/loader/Makefile index b861e46c..826db726 100644 --- a/sys/boot/i386/loader/Makefile +++ b/sys/boot/i386/loader/Makefile @@ -100,7 +100,7 @@ FILESMODE_${LOADER}= ${BINMODE} -b FILES+= loader.help loader.4th support.4th loader.conf FILES+= screen.4th frames.4th beastie.4th FILES+= brand.4th check-password.4th color.4th delay.4th -FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th +FILES+= menu.4th menu-commands.4th menusets.4th shortcuts.4th version.4th FILESDIR_loader.conf= /boot/defaults .if !exists(${DESTDIR}/boot/loader.rc) diff --git a/sys/boot/ia64/common/Makefile b/sys/boot/ia64/common/Makefile index d90898f7..57400705 100644 --- a/sys/boot/ia64/common/Makefile +++ b/sys/boot/ia64/common/Makefile @@ -35,7 +35,7 @@ loader.help: help.common FILES+= loader.4th support.4th loader.conf FILES+= screen.4th frames.4th FILES+= beastie.4th brand.4th check-password.4th color.4th delay.4th -FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th +FILES+= menu.4th menu-commands.4th menusets.4th shortcuts.4th version.4th .if !exists(${DESTDIR}/boot/loader.rc) FILES+= loader.rc .endif diff --git a/sys/boot/pc98/loader/Makefile b/sys/boot/pc98/loader/Makefile index 48db11bd..489eeac1 100644 --- a/sys/boot/pc98/loader/Makefile +++ b/sys/boot/pc98/loader/Makefile @@ -88,7 +88,7 @@ FILESMODE_${LOADER}= ${BINMODE} -b FILES+= loader.help loader.4th support.4th loader.conf FILES+= screen.4th frames.4th beastie.4th FILES+= brand.4th check-password.4th color.4th delay.4th -FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th +FILES+= menu.4th menu-commands.4th menusets.4th shortcuts.4th version.4th FILESDIR_loader.conf= /boot/defaults .if !exists(${DESTDIR}/boot/loader.rc) diff --git a/sys/boot/powerpc/ofw/Makefile b/sys/boot/powerpc/ofw/Makefile index 079f552b..d3d35231 100644 --- a/sys/boot/powerpc/ofw/Makefile +++ b/sys/boot/powerpc/ofw/Makefile @@ -105,7 +105,7 @@ loader.help: help.common help.ofw FILES= loader.help loader.4th support.4th loader.conf FILES+= screen.4th frames.4th FILES+= beastie.4th brand.4th check-password.4th color.4th delay.4th -FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th +FILES+= menu.4th menu-commands.4th menusets.4th shortcuts.4th version.4th FILESDIR_loader.conf= /boot/defaults .if !exists(${DESTDIR}/boot/loader.rc) diff --git a/sys/boot/powerpc/ps3/Makefile b/sys/boot/powerpc/ps3/Makefile index 0dee5f4c..810e4805 100644 --- a/sys/boot/powerpc/ps3/Makefile +++ b/sys/boot/powerpc/ps3/Makefile @@ -116,7 +116,7 @@ loader.help: help.common help.ps3 FILES= loader.help loader.4th support.4th loader.conf FILES+= screen.4th frames.4th FILES+= beastie.4th brand.4th check-password.4th color.4th delay.4th -FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th +FILES+= menu.4th menu-commands.4th menusets.4th shortcuts.4th version.4th FILESDIR_loader.conf= /boot/defaults .if !exists(${DESTDIR}/boot/loader.rc) diff --git a/sys/boot/sparc64/loader/Makefile b/sys/boot/sparc64/loader/Makefile index 0a3b7530..4624b6f7 100644 --- a/sys/boot/sparc64/loader/Makefile +++ b/sys/boot/sparc64/loader/Makefile @@ -99,7 +99,7 @@ loader.help: help.common help.sparc64 FILES= loader.help loader.4th support.4th loader.conf FILES+= screen.4th frames.4th FILES+= beastie.4th brand.4th check-password.4th color.4th delay.4th -FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th +FILES+= menu.4th menu-commands.4th menusets.4th shortcuts.4th version.4th FILESDIR_loader.conf= /boot/defaults .if !exists(${DESTDIR}/boot/loader.rc) -- 2.42.0