Date: Sat, 10 Nov 2012 16:53:10 -0800 From: Devin Teske <devin.teske@fisglobal.com> To: <freebsd-current@freebsd.org> Cc: Adrian Chadd <adrian@freebsd.org>, Devin Teske <dteske@freebsd.org> Subject: HEADS UP: Forth Optimizations Message-ID: <A0A46155-0969-459E-BCD6-4AA7B8B371BE@fisglobal.com>
next in thread | raw e-mail | index | archive | help
--Apple-Mail=_A9909A1E-E6A9-43DD-8CBB-D93045B73375
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="us-ascii"
Hi Everybody,
Adrian (my co-mentor) wanted some additional eyes/names for review on a pat=
ch I'm making to sys/boot/forth (patch attached as patch.txt).
The patch makes no changes to user experience or functionality (but _does_ =
fix one incident of stack leakage -- among other things).
I wrote/tested this over a 2-day period using (as usual) VMware. I booted u=
p several times (10+) and fiddled with many things (twiddled every knob, dr=
opped to the loader prompt and went back to the menu several times, tried t=
hrowing various options like boot_single=3D"YES" and boot_verbose=3D"YES" i=
nto loader.conf(5) to make sure dynamic initialization is still working etc=
.).
The only thing I noticed after applying the patch was a drop in heap usage =
(one of the goals of the patch), showing that the optimizations did their j=
ob to make a leaner running menu. Also, the code is a lot more readable and=
got slightly reduced in size during the process.
Can someone help review this for the commit log?
--=20
Devin
=3D=3D=3D
+ This patch does not change user experience or functionality
+ Cleanup syntax, slim-down code, and make things more readable
+ Introduce new +c! operator and ilk to reduce heap usage/allocations
+ Fix a stack leak in [unused] cycle_menuitem function while we're here
(required misconfiguration and/or missing environment vars to occur)
+ Add safemode_enabled? safemode_enable and safemode_disable functions
+ Add singleuser_enabled? singleuser_enable singleuser_disable functions
+ Add verbose_enabled? verbose_enable and verbose_disable functions
+ Centralize strings (also to reduce heap usage)
PR:
Submitted by:
Reviewed by: Your_Name_Here, adrian (co-mentor) [pending his/your review]
Approved by: adrian (co-mentor) [pending his approval]
Obtained from:
MFC after:
Security:
--This line, and those below, will be ignored--
> Description of fields to fill in above: 76 columns --|
> PR: If a GNATS PR is affected by the change.
> Submitted by: If someone else sent in the change.
> Reviewed by: If someone else reviewed your modification.
> Approved by: If you needed approval for this commit.
> Obtained from: If the change is from a third party.
> MFC after: N [day[s]|week[s]|month[s]]. Request a reminder email.
> Security: Vulnerability reference (one per line) or description.
> Empty fields above will be automatically removed.
M forth/menu-commands.4th
M forth/menu.4th
_____________
The information contained in this message is proprietary and/or confidentia=
l. If you are not the intended recipient, please: (i) delete the message an=
d all copies; (ii) do not disclose, distribute or use the message in any ma=
nner; and (iii) notify the sender immediately. In addition, please be aware=
that any message addressed to our domain is subject to archiving and revie=
w by persons other than the intended recipient. Thank you.
--Apple-Mail=_A9909A1E-E6A9-43DD-8CBB-D93045B73375
Content-Disposition: attachment; filename="patch.txt"
Content-Type: text/plain; name="patch.txt"
Content-Transfer-Encoding: quoted-printable
Index: menu-commands.4th
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- menu-commands.4th (revision 242835)
+++ menu-commands.4th (working copy)
@@ -31,6 +31,10 @@ include /boot/menusets.4th
variable kernel_state
variable root_state
=20
+\=20
+\ ACPI
+\=20
+
: acpi_enable ( -- )
s" set acpi_load=3DYES" evaluate \ XXX deprecated but harmless
s" set hint.acpi.0.disabled=3D0" evaluate
@@ -58,9 +62,38 @@ variable root_state
TRUE \ loop menu again
;
=20
+\=20
+\ Safe Mode
+\=20
+
+: 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=3D1" evaluate
+ s" set hw.ata.ata_dma=3D0" evaluate
+ s" set hw.ata.atapi_dma=3D0" evaluate
+ s" set hw.ata.wc=3D0" evaluate
+ s" set hw.eisa_slots=3D0" evaluate
+ s" set kern.eventtimer.periodic=3D1" evaluate
+ s" set kern.geom.part.check_integrity=3D0" 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 )
- s" kern.smp.disabled" getenv -1 <> if
- drop ( n c-addr -- n ) \ unused
+ safemode_enabled? if
toggle_menuitem ( n -- n )
then
;
@@ -70,25 +103,10 @@ variable root_state
=20
\ Now we're going to make the change effective
=20
- s" toggle_stateN @" \ base name of toggle state var
- -rot 2dup 12 + c! rot \ replace 'N' with ASCII numeral
-
- evaluate 0=3D if
- 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
+ dup toggle_stateN @ 0=3D if
+ safemode_disable
else
- s" set kern.smp.disabled=3D1" evaluate
- s" set hw.ata.ata_dma=3D0" evaluate
- s" set hw.ata.atapi_dma=3D0" evaluate
- s" set hw.ata.wc=3D0" evaluate
- s" set hw.eisa_slots=3D0" evaluate
- s" set kern.eventtimer.periodic=3D1" evaluate
- s" set kern.geom.part.check_integrity=3D0" evaluate
+ safemode_enable
then
=20
menu-redraw
@@ -96,9 +114,26 @@ variable root_state
TRUE \ loop menu again
;
=20
+\=20
+\ Single User Mode
+\=20
+
+: singleuser_enabled? ( -- flag )
+ s" boot_single" getenv -1 <> dup if
+ swap drop ( c-addr flag -- flag )
+ then
+;
+
+: singleuser_enable ( -- )
+ s" set boot_single=3DYES" evaluate
+;
+
+: singleuser_disable ( -- )
+ s" boot_single" unsetenv
+;
+
: init_singleuser ( N -- N )
- s" boot_single" getenv -1 <> if
- drop ( n c-addr -- n ) \ unused
+ singleuser_enabled? if
toggle_menuitem ( n -- n )
then
;
@@ -109,21 +144,35 @@ variable root_state
=20
\ Now we're going to make the change effective
=20
- s" toggle_stateN @" \ base name of toggle state var
- -rot 2dup 12 + c! rot \ replace 'N' with ASCII numeral
-
- evaluate 0=3D if
- s" boot_single" unsetenv
+ dup toggle_stateN @ 0=3D if
+ singleuser_disable
else
- s" set boot_single=3DYES" evaluate
+ singleuser_enable
then
=20
TRUE \ loop menu again
;
=20
+\=20
+\ Verbose Boot
+\=20
+
+: verbose_enabled? ( -- flag )
+ s" boot_verbose" getenv -1 <> dup if
+ swap drop ( c-addr flag -- flag )
+ then
+;
+
+: verbose_enable ( -- )
+ s" set boot_verbose=3DYES" evaluate
+;
+
+: verbose_disable ( -- )
+ s" boot_verbose" unsetenv
+;
+
: init_verbose ( N -- N )
- s" boot_verbose" getenv -1 <> if
- drop ( n c-addr -- n ) \ unused
+ verbose_enabled? if
toggle_menuitem ( n -- n )
then
;
@@ -134,18 +183,19 @@ variable root_state
=20
\ Now we're going to make the change effective
=20
- s" toggle_stateN @" \ base name of toggle state var
- -rot 2dup 12 + c! rot \ replace 'N' with ASCII numeral
-
- evaluate 0=3D if
- s" boot_verbose" unsetenv
+ dup toggle_stateN @ 0=3D if
+ verbose_disable
else
- s" set boot_verbose=3DYES" evaluate
+ verbose_enable
then
=20
TRUE \ loop menu again
;
=20
+\=20
+\ Escape to Prompt
+\=20
+
: goto_prompt ( N -- N FALSE )
=20
s" set autoboot_delay=3DNO" evaluate
@@ -158,11 +208,12 @@ variable root_state
FALSE \ exit the menu
;
=20
+\=20
+\ Cyclestate (used by kernel/root below)
+\=20
+
: init_cyclestate ( N K -- N )
- over ( n k -- n k n )
- s" cycle_stateN" ( n k n -- n k n c-addr u )
- -rot tuck 11 + c! swap ( n k n c-addr u -- n k c-addr u )
- evaluate ( n k c-addr u -- n k addr )
+ 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 )
@@ -174,6 +225,10 @@ variable root_state
2drop ( n k addr -- n )
;
=20
+\
+\ Kernel
+\=20
+
: init_kernel ( N -- N )
kernel_state @ ( n -- n k )
init_cyclestate ( n k -- n )
@@ -185,21 +240,21 @@ variable root_state
=20
\ Now we're going to make the change effective
=20
- 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
=20
s" set kernel=3D${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
=20
TRUE \ loop menu again
;
=20
+\=20
+\ Root
+\=20
+
: init_root ( N -- N )
root_state @ ( n -- n k )
init_cyclestate ( n k -- n )
@@ -211,21 +266,21 @@ variable root_state
=20
\ Now we're going to make the change effective
=20
- 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
=20
s" set root=3D${root_prefix}${root[N]}${root_suffix}"
- \ command to assemble root image-path
- -rot tuck 30 + c! swap \ replace 'N' with array index value
- evaluate \ sets $kernel to full kernel-path
+ 30 +c! \ replace 'N' with ASCII numeral
+ evaluate
=20
TRUE \ loop menu again
;
=20
+\=20
+\ Menusets
+\=20
+
: goto_menu ( N M -- N TRUE )
menu-unset
menuset-loadsetnum ( n m -- n )
Index: menu.4th
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- menu.4th (revision 242835)
+++ menu.4th (working copy)
@@ -116,6 +116,48 @@ create init_text6 255 allot
create init_text7 255 allot
create init_text8 255 allot
=20
+: +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_title ( -- C-ADDR/U ) s" loader_menu_title" ;
+: 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
@@ -172,10 +214,7 @@ 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.
=20
- s" init_textN" \ base name of buffer
- -rot 2dup 9 + c! rot \ replace 'N' with ASCII num
-
- evaluate c@ 0=3D if
+ dup init_textN c@ 0=3D 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
@@ -184,18 +223,15 @@ create init_text8 255 allot
=20
\ base name of environment variable
loader_color? if
- s" ansi_caption[x]"
+ dup ansi_caption[x]
else
- s" menu_caption[x]"
+ dup menu_caption[x]
then=09
- -rot 2dup 13 + c! rot \ replace 'x' with ASCII =
numeral
=20
getenv dup -1 <> if
=20
- 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 )
=20
\ now we have the buffer c-addr on top
\ ( followed by c-addr/u of current caption )
@@ -227,36 +263,26 @@ create init_text8 255 allot
\ negate the toggled state so that we reverse the flow on =
subsequent
\ calls.
=20
- s" toggle_stateN @" \ base name of toggle state var
- -rot 2dup 12 + c! rot \ replace 'N' with ASCII numeral
-
- evaluate 0=3D if
+ dup toggle_stateN @ 0=3D if
\ state is OFF, toggle to ON
=20
- \ base name of toggled text var
+ dup
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
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
then
=20
@@ -264,30 +290,22 @@ create init_text8 255 allot
else
\ state is ON, toggle to OFF
=20
- 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 )
=20
- \ base name of caption var
+ \ Assign init_textN text to menu caption
+ 2 pick
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
=20
- 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
=20
\ 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 !
;
=20
: cycle_menuitem ( N -- N ) \ cycles through array of choices for a =
menuitem
@@ -295,13 +313,8 @@ 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.
=20
- s" cycle_stateN" \ base name of array state var
- -rot 2dup 11 + c! rot \ replace 'N' with ASCII numeral
+ dup cycle_stateN dup @ 1+ \ get value and increment
=20
- evaluate \ we now have a pointer to the proper variable
- dup @ \ resolve the pointer (but leave it on the stack)
- 1+ \ increment the value
-
\ 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.
@@ -309,14 +322,12 @@ create init_text8 255 allot
=20
dup 48 + \ duplicate Array index and convert to ASCII numeral
=20
- \ base name of array caption text
+ 3 pick swap
loader_color? if
- s" ansi_caption[x][y]" =20
+ ansi_caption[x][y]
else
- s" menu_caption[x][y]" =20
+ 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
=20
\ 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
@@ -329,19 +340,18 @@ create init_text8 255 allot
drop ( incremented array index )
0 ( new array index that will be stored later )
=20
- \ base name of caption var
+ 2 pick [char] 0
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
-
getenv dup -1 =3D if
\ This is highly unlikely to occur, but to make
\ sure that things move along smoothly, allocate
\ a temporary NULL string
=20
+ drop ( getenv cruft )
s" "
then
then
@@ -357,14 +367,14 @@ create init_text8 255 allot
\=20
\ Let's perform what we need to with the above.
=20
- \ base name of menuitem caption var
+ \ Assign array value text to menu caption
+ 4 pick
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
=20
swap ! \ update array state variable
;
@@ -400,15 +410,15 @@ create init_text8 255 allot
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
@@ -426,7 +436,7 @@ create init_text8 255 allot
: menu-create ( -- )
=20
\ Print the frame caption at (x,y)
- s" loader_menu_title" getenv dup -1 =3D if
+ str_loader_menu_title getenv dup -1 =3D if
drop s" Welcome to FreeBSD"
then
24 over 2 / - 9 at-xy type=20
@@ -435,7 +445,7 @@ create init_text8 255 allot
\ constructed dynamically -- as this function could conceivably =
set
\ the remaining environment variables to construct the menu =
entirely).
\=20
- s" menu_init" getenv dup -1 <> if
+ str_menu_init getenv dup -1 <> if
evaluate
else
drop
@@ -460,7 +470,7 @@ create init_text8 255 allot
\ Initialize the ACPI option status.
\=20
0 menuacpi !
- s" menu_acpi" getenv -1 <> if
+ str_menu_acpi getenv -1 <> if
c@ dup 48 > over 57 < and if ( '1' <=3D c1 <=3D '8' )
menuacpi !
arch-i386? if acpipresent? if
@@ -468,10 +478,7 @@ create init_text8 255 allot
\ Set menu toggle state to active state
\ (required by generic toggle_menuitem)
\=20
- menuacpi @
- s" acpienabled? toggle_stateN !"
- -rot tuck 25 + c! swap
- evaluate
+ acpienabled? menuacpi @ toggle_stateN !
then then
else
drop
@@ -482,7 +489,7 @@ create init_text8 255 allot
\ Initialize the menu_options visual separator.
\=20
0 menuoptions !
- s" menu_options" getenv -1 <> if
+ str_menu_options getenv -1 <> if
c@ dup 48 > over 57 < and if ( '1' <=3D c1 <=3D '8' )
menuoptions !
else
@@ -502,7 +509,7 @@ create init_text8 255 allot
\ If the "Options:" separator, print it.
dup menuoptions @ =3D 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 !
@@ -512,7 +519,7 @@ create init_text8 255 allot
menurow @ 2 + menurow !
menurow @ menuY @ +
at-xy
- s" menu_optionstext" getenv dup -1 <> if
+ str_menu_optionstext getenv dup -1 <> if
type
else
drop ." Options:"
@@ -521,17 +528,20 @@ create init_text8 255 allot
=20
\ If this is the ACPI menu option, act accordingly.
dup menuacpi @ =3D if
- acpimenuitem ( -- C-Addr/U | -1 )
+ dup acpimenuitem ( n -- n n c-addr/u | n n -1 )
+ dup -1 <> if
+ 13 +c! ( n n c-addr/u -- n ) \ replace =
'x'
+ else
+ swap drop ( n n -1 -- n -1 )
+ over menu_command[x] unsetenv
+ then
else
\ make sure we have not already initialized this =
item
- s" init_stateN"
- -rot 2dup 10 + c! rot \ repace 'N'
- evaluate dup @ 0=3D if
+ dup init_stateN dup @ 0=3D if
1 swap !
=20
\ If this menuitem has an initializer, =
run it
- s" menu_init[x]"
- -rot 2dup 10 + c! rot \ replace 'x'
+ dup menu_init[x]
getenv dup -1 <> if
evaluate
else
@@ -542,34 +552,22 @@ create init_text8 255 allot
then
=20
loader_color? if
- s" ansi_caption[x]"
+ dup ansi_caption[x]
else
- s" menu_caption[x]"
+ dup menu_caption[x]
then
then
=20
- ( C-Addr/U | -1 )
dup -1 <> if
- \ replace 'x' with current iteration
- -rot 2dup 13 + c! rot
- =20
\ test for environment variable
getenv dup -1 <> if
- printmenuitem ( C-Addr/U -- N )
- =20
- s" menukeyN !" \ generate cmd to store =
result
- -rot 2dup 7 + c! rot
- =20
- 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
=20
1+ dup 56 > \ add 1 to iterator, continue if less than =
57
@@ -578,7 +576,7 @@ create init_text8 255 allot
=20
\ 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)
=20
@@ -596,45 +594,22 @@ create init_text8 255 allot
\=20
: menu-timeout-update ( N -- )
=20
- dup 9 > if ( N N 9 -- N )
- drop ( N -- )
- 9 ( maximum: -- N )
- then
+ \ Enforce minimum/maximum
+ dup 9 > if drop 9 then
+ dup 0 < if drop 0 then
=20
- dup 0 < if ( N N 0 -- N )
- drop ( N -- )
- 0 ( minimum: -- N )
- then
+ s" Autoboot in N seconds. [Space] to pause" ( n -- n c-addr/u )
=20
- 48 + ( convert single-digit numeral to ASCII: N 48 -- N )
+ 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
=20
- 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 )
-
- menu_timeout_x @
- menu_timeout_y @
- at-xy ( position cursor: N Addr C N N -- N Addr C )
-
- spaces ( erase message: N Addr C -- N Addr )
- 2drop ( N Addr -- )
-
+ 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
=20
0 25 at-xy ( position cursor back at bottom-left )
@@ -682,7 +657,7 @@ create init_text8 255 allot
\ (user did not cancel by =
pressing ANY
\ key)
=20
- s" menu_timeout_command" getenv =
dup
+ str_menu_timeout_command getenv =
dup
-1 =3D if
drop \ clean-up
else
@@ -765,7 +740,7 @@ create init_text8 255 allot
0 menu_timeout_enabled ! \ start with automatic timeout disabled
=20
\ 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 -- )
=20
\ initialize state variables
@@ -801,7 +776,7 @@ create init_text8 255 allot
=20
menu_timeout_enabled @ 1 =3D if
\ read custom column position (if set)
- s" loader_menu_timeout_x" getenv dup -1 =3D if
+ str_loader_menu_timeout_x getenv dup -1 =3D if
drop \ no custom column position
menu_timeout_default_x \ use default =
setting
else
@@ -813,7 +788,7 @@ create init_text8 255 allot
menu_timeout_x ! ( store value on stack from =
above )
=20
\ read custom row position (if set)
- s" loader_menu_timeout_y" getenv dup -1 =3D if
+ str_loader_menu_timeout_y getenv dup -1 =3D if
drop \ no custom row position
menu_timeout_default_y \ use default =
setting
else
@@ -852,13 +827,9 @@ create init_text8 255 allot
=20
49 \ Iterator start (loop range 49 to 56; ASCII '1' to =
'8')
begin
- s" menukeyN @"
+ dup menukeyN @
+ rot tuck =3D if
=20
- \ replace 'N' with current iteration
- -rot 2dup 7 + c! rot
-
- evaluate rot tuck =3D if
-
\ Adjust for missing ACPI menuitem on =
non-i386
arch-i386? true <> menuacpi @ 0<> and if
menuacpi @ over 2dup < -rot =3D =
or
@@ -868,13 +839,8 @@ create init_text8 255 allot
then
then
=20
- \ 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
@@ -909,16 +875,14 @@ create init_text8 255 allot
\=20
\ Check for menu keycode shortcut(s)
\=20
- s" menu_keycode[x]"
- -rot 2dup 13 + c! rot
+ dup menu_keycode[x]
getenv dup -1 =3D if
drop
else
?number 0<> if
rot tuck =3D if
swap
- s" menu_command[x]"
- -rot 2dup 13 + c! rot
+ dup menu_command[x]
getenv dup -1 <> if
evaluate
0=3D if
@@ -950,100 +914,43 @@ create init_text8 255 allot
=20
49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8')
begin
- \ Unset variables in-order of appearance in menu.4th(8)
+ 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
=20
- 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_init[x]" \ initializer basename
- -rot 2dup 10 + 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'
- 48 -rot
+ 48 \ Iterator start (inner range 48 to 57; ASCII '0' to =
'9')
begin
- 16 2over rot + c! \ replace 'y'
- 2dup unsetenv
-
- rot 1+ dup 57 > 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
=20
- s" ansi_caption[x][y]" \ cycle_menuitem ANSI caption
- -rot 2dup 13 + c! rot \ replace 'x'
- 48 -rot
- begin
- 16 2over rot + c! \ replace 'y'
- 2dup unsetenv
+ 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
=20
- rot 1+ dup 57 > 2swap rot
- until
- 2drop drop
-
- 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
-
- s" 0 init_stateN !" \ used by menu-create
- -rot 2dup 12 + c! rot \ replace 'N'
- evaluate
-
- s" 0 toggle_stateN !" \ used by toggle_menuitem
- -rot 2dup 14 + c! rot \ replace 'N'
- evaluate
-
- s" 0 cycle_stateN !" \ used by cycle_menuitem
- -rot 2dup 13 + c! rot \ replace 'N'
- evaluate
-
- s" 0 init_textN c!" \ used by toggle_menuitem
- -rot 2dup 11 + c! rot \ replace 'N'
- evaluate
-
1+ dup 56 > \ increment, continue if less than 57
until
drop \ iterator
=20
- \ 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
=20
- \ 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
- s" menu_optionstext" unsetenv
0 menuoptions !
-
- \ clear the menu initializer
- s" menu_init" unsetenv
;
=20
\ This function both unsets menu variables and visually erases the menu =
area
--Apple-Mail=_A9909A1E-E6A9-43DD-8CBB-D93045B73375--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?A0A46155-0969-459E-BCD6-4AA7B8B371BE>
