1*ca987d46SWarner Losh\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org> 2*ca987d46SWarner Losh\ All rights reserved. 3*ca987d46SWarner Losh\ 4*ca987d46SWarner Losh\ Redistribution and use in source and binary forms, with or without 5*ca987d46SWarner Losh\ modification, are permitted provided that the following conditions 6*ca987d46SWarner Losh\ are met: 7*ca987d46SWarner Losh\ 1. Redistributions of source code must retain the above copyright 8*ca987d46SWarner Losh\ notice, this list of conditions and the following disclaimer. 9*ca987d46SWarner Losh\ 2. Redistributions in binary form must reproduce the above copyright 10*ca987d46SWarner Losh\ notice, this list of conditions and the following disclaimer in the 11*ca987d46SWarner Losh\ documentation and/or other materials provided with the distribution. 12*ca987d46SWarner Losh\ 13*ca987d46SWarner Losh\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14*ca987d46SWarner Losh\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15*ca987d46SWarner Losh\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16*ca987d46SWarner Losh\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17*ca987d46SWarner Losh\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18*ca987d46SWarner Losh\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19*ca987d46SWarner Losh\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20*ca987d46SWarner Losh\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21*ca987d46SWarner Losh\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22*ca987d46SWarner Losh\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23*ca987d46SWarner Losh\ SUCH DAMAGE. 24*ca987d46SWarner Losh\ 25*ca987d46SWarner Losh 26*ca987d46SWarner Loshmarker task-menu-commands.4th 27*ca987d46SWarner Losh 28*ca987d46SWarner Loshinclude /boot/menusets.4th 29*ca987d46SWarner Losh 30*ca987d46SWarner Loshonly forth definitions 31*ca987d46SWarner Losh 32*ca987d46SWarner Loshvariable kernel_state 33*ca987d46SWarner Loshvariable root_state 34*ca987d46SWarner Losh0 kernel_state ! 35*ca987d46SWarner Losh0 root_state ! 36*ca987d46SWarner Losh 37*ca987d46SWarner Loshalso menu-namespace also menu-command-helpers 38*ca987d46SWarner Losh 39*ca987d46SWarner Losh\ 40*ca987d46SWarner Losh\ Boot 41*ca987d46SWarner Losh\ 42*ca987d46SWarner Losh 43*ca987d46SWarner Losh: init_boot ( N -- N ) 44*ca987d46SWarner Losh dup 45*ca987d46SWarner Losh s" boot_single" getenv -1 <> if 46*ca987d46SWarner Losh drop ( n n c-addr -- n n ) \ unused 47*ca987d46SWarner Losh toggle_menuitem ( n n -- n n ) 48*ca987d46SWarner Losh s" set menu_keycode[N]=115" \ base command to execute 49*ca987d46SWarner Losh else 50*ca987d46SWarner Losh s" set menu_keycode[N]=98" \ base command to execute 51*ca987d46SWarner Losh then 52*ca987d46SWarner Losh 17 +c! \ replace 'N' with ASCII numeral 53*ca987d46SWarner Losh evaluate 54*ca987d46SWarner Losh; 55*ca987d46SWarner Losh 56*ca987d46SWarner Losh\ 57*ca987d46SWarner Losh\ Alternate Boot 58*ca987d46SWarner Losh\ 59*ca987d46SWarner Losh 60*ca987d46SWarner Losh: init_altboot ( N -- N ) 61*ca987d46SWarner Losh dup 62*ca987d46SWarner Losh s" boot_single" getenv -1 <> if 63*ca987d46SWarner Losh drop ( n c-addr -- n ) \ unused 64*ca987d46SWarner Losh toggle_menuitem ( n -- n ) 65*ca987d46SWarner Losh s" set menu_keycode[N]=109" \ base command to execute 66*ca987d46SWarner Losh else 67*ca987d46SWarner Losh s" set menu_keycode[N]=115" \ base command to execute 68*ca987d46SWarner Losh then 69*ca987d46SWarner Losh 17 +c! \ replace 'N' with ASCII numeral 70*ca987d46SWarner Losh evaluate 71*ca987d46SWarner Losh; 72*ca987d46SWarner Losh 73*ca987d46SWarner Losh: altboot ( N -- NOTREACHED ) 74*ca987d46SWarner Losh s" boot_single" 2dup getenv -1 <> if 75*ca987d46SWarner Losh drop ( c-addr/u c-addr -- c-addr/u ) \ unused 76*ca987d46SWarner Losh unsetenv ( c-addr/u -- ) 77*ca987d46SWarner Losh else 78*ca987d46SWarner Losh 2drop ( c-addr/u -- ) \ unused 79*ca987d46SWarner Losh s" set boot_single=YES" evaluate 80*ca987d46SWarner Losh then 81*ca987d46SWarner Losh 0 boot ( state -- ) 82*ca987d46SWarner Losh; 83*ca987d46SWarner Losh 84*ca987d46SWarner Losh\ 85*ca987d46SWarner Losh\ ACPI 86*ca987d46SWarner Losh\ 87*ca987d46SWarner Losh 88*ca987d46SWarner Losh: acpi_enable ( -- ) 89*ca987d46SWarner Losh s" set acpi_load=YES" evaluate \ XXX deprecated but harmless 90*ca987d46SWarner Losh s" set hint.acpi.0.disabled=0" evaluate 91*ca987d46SWarner Losh s" loader.acpi_disabled_by_user" unsetenv 92*ca987d46SWarner Losh; 93*ca987d46SWarner Losh 94*ca987d46SWarner Losh: acpi_disable ( -- ) 95*ca987d46SWarner Losh s" acpi_load" unsetenv \ XXX deprecated but harmless 96*ca987d46SWarner Losh s" set hint.acpi.0.disabled=1" evaluate 97*ca987d46SWarner Losh s" set loader.acpi_disabled_by_user=1" evaluate 98*ca987d46SWarner Losh; 99*ca987d46SWarner Losh 100*ca987d46SWarner Losh: toggle_acpi ( N -- N TRUE ) 101*ca987d46SWarner Losh 102*ca987d46SWarner Losh \ Make changes effective _before_ calling menu-redraw 103*ca987d46SWarner Losh 104*ca987d46SWarner Losh acpienabled? if 105*ca987d46SWarner Losh acpi_disable 106*ca987d46SWarner Losh else 107*ca987d46SWarner Losh acpi_enable 108*ca987d46SWarner Losh then 109*ca987d46SWarner Losh 110*ca987d46SWarner Losh menu-redraw 111*ca987d46SWarner Losh 112*ca987d46SWarner Losh TRUE \ loop menu again 113*ca987d46SWarner Losh; 114*ca987d46SWarner Losh 115*ca987d46SWarner Losh\ 116*ca987d46SWarner Losh\ Safe Mode 117*ca987d46SWarner Losh\ 118*ca987d46SWarner Losh 119*ca987d46SWarner Losh: safemode_enabled? ( -- flag ) 120*ca987d46SWarner Losh s" kern.smp.disabled" getenv -1 <> dup if 121*ca987d46SWarner Losh swap drop ( c-addr flag -- flag ) 122*ca987d46SWarner Losh then 123*ca987d46SWarner Losh; 124*ca987d46SWarner Losh 125*ca987d46SWarner Losh: safemode_enable ( -- ) 126*ca987d46SWarner Losh s" set kern.smp.disabled=1" evaluate 127*ca987d46SWarner Losh s" set hw.ata.ata_dma=0" evaluate 128*ca987d46SWarner Losh s" set hw.ata.atapi_dma=0" evaluate 129*ca987d46SWarner Losh s" set kern.eventtimer.periodic=1" evaluate 130*ca987d46SWarner Losh s" set kern.geom.part.check_integrity=0" evaluate 131*ca987d46SWarner Losh; 132*ca987d46SWarner Losh 133*ca987d46SWarner Losh: safemode_disable ( -- ) 134*ca987d46SWarner Losh s" kern.smp.disabled" unsetenv 135*ca987d46SWarner Losh s" hw.ata.ata_dma" unsetenv 136*ca987d46SWarner Losh s" hw.ata.atapi_dma" unsetenv 137*ca987d46SWarner Losh s" kern.eventtimer.periodic" unsetenv 138*ca987d46SWarner Losh s" kern.geom.part.check_integrity" unsetenv 139*ca987d46SWarner Losh; 140*ca987d46SWarner Losh 141*ca987d46SWarner Losh: init_safemode ( N -- N ) 142*ca987d46SWarner Losh safemode_enabled? if 143*ca987d46SWarner Losh toggle_menuitem ( n -- n ) 144*ca987d46SWarner Losh then 145*ca987d46SWarner Losh; 146*ca987d46SWarner Losh 147*ca987d46SWarner Losh: toggle_safemode ( N -- N TRUE ) 148*ca987d46SWarner Losh toggle_menuitem 149*ca987d46SWarner Losh 150*ca987d46SWarner Losh \ Now we're going to make the change effective 151*ca987d46SWarner Losh 152*ca987d46SWarner Losh dup toggle_stateN @ 0= if 153*ca987d46SWarner Losh safemode_disable 154*ca987d46SWarner Losh else 155*ca987d46SWarner Losh safemode_enable 156*ca987d46SWarner Losh then 157*ca987d46SWarner Losh 158*ca987d46SWarner Losh menu-redraw 159*ca987d46SWarner Losh 160*ca987d46SWarner Losh TRUE \ loop menu again 161*ca987d46SWarner Losh; 162*ca987d46SWarner Losh 163*ca987d46SWarner Losh\ 164*ca987d46SWarner Losh\ Single User Mode 165*ca987d46SWarner Losh\ 166*ca987d46SWarner Losh 167*ca987d46SWarner Losh: singleuser_enabled? ( -- flag ) 168*ca987d46SWarner Losh s" boot_single" getenv -1 <> dup if 169*ca987d46SWarner Losh swap drop ( c-addr flag -- flag ) 170*ca987d46SWarner Losh then 171*ca987d46SWarner Losh; 172*ca987d46SWarner Losh 173*ca987d46SWarner Losh: singleuser_enable ( -- ) 174*ca987d46SWarner Losh s" set boot_single=YES" evaluate 175*ca987d46SWarner Losh; 176*ca987d46SWarner Losh 177*ca987d46SWarner Losh: singleuser_disable ( -- ) 178*ca987d46SWarner Losh s" boot_single" unsetenv 179*ca987d46SWarner Losh; 180*ca987d46SWarner Losh 181*ca987d46SWarner Losh: init_singleuser ( N -- N ) 182*ca987d46SWarner Losh singleuser_enabled? if 183*ca987d46SWarner Losh toggle_menuitem ( n -- n ) 184*ca987d46SWarner Losh then 185*ca987d46SWarner Losh; 186*ca987d46SWarner Losh 187*ca987d46SWarner Losh: toggle_singleuser ( N -- N TRUE ) 188*ca987d46SWarner Losh toggle_menuitem 189*ca987d46SWarner Losh menu-redraw 190*ca987d46SWarner Losh 191*ca987d46SWarner Losh \ Now we're going to make the change effective 192*ca987d46SWarner Losh 193*ca987d46SWarner Losh dup toggle_stateN @ 0= if 194*ca987d46SWarner Losh singleuser_disable 195*ca987d46SWarner Losh else 196*ca987d46SWarner Losh singleuser_enable 197*ca987d46SWarner Losh then 198*ca987d46SWarner Losh 199*ca987d46SWarner Losh TRUE \ loop menu again 200*ca987d46SWarner Losh; 201*ca987d46SWarner Losh 202*ca987d46SWarner Losh\ 203*ca987d46SWarner Losh\ Verbose Boot 204*ca987d46SWarner Losh\ 205*ca987d46SWarner Losh 206*ca987d46SWarner Losh: verbose_enabled? ( -- flag ) 207*ca987d46SWarner Losh s" boot_verbose" getenv -1 <> dup if 208*ca987d46SWarner Losh swap drop ( c-addr flag -- flag ) 209*ca987d46SWarner Losh then 210*ca987d46SWarner Losh; 211*ca987d46SWarner Losh 212*ca987d46SWarner Losh: verbose_enable ( -- ) 213*ca987d46SWarner Losh s" set boot_verbose=YES" evaluate 214*ca987d46SWarner Losh; 215*ca987d46SWarner Losh 216*ca987d46SWarner Losh: verbose_disable ( -- ) 217*ca987d46SWarner Losh s" boot_verbose" unsetenv 218*ca987d46SWarner Losh; 219*ca987d46SWarner Losh 220*ca987d46SWarner Losh: init_verbose ( N -- N ) 221*ca987d46SWarner Losh verbose_enabled? if 222*ca987d46SWarner Losh toggle_menuitem ( n -- n ) 223*ca987d46SWarner Losh then 224*ca987d46SWarner Losh; 225*ca987d46SWarner Losh 226*ca987d46SWarner Losh: toggle_verbose ( N -- N TRUE ) 227*ca987d46SWarner Losh toggle_menuitem 228*ca987d46SWarner Losh menu-redraw 229*ca987d46SWarner Losh 230*ca987d46SWarner Losh \ Now we're going to make the change effective 231*ca987d46SWarner Losh 232*ca987d46SWarner Losh dup toggle_stateN @ 0= if 233*ca987d46SWarner Losh verbose_disable 234*ca987d46SWarner Losh else 235*ca987d46SWarner Losh verbose_enable 236*ca987d46SWarner Losh then 237*ca987d46SWarner Losh 238*ca987d46SWarner Losh TRUE \ loop menu again 239*ca987d46SWarner Losh; 240*ca987d46SWarner Losh 241*ca987d46SWarner Losh\ 242*ca987d46SWarner Losh\ Escape to Prompt 243*ca987d46SWarner Losh\ 244*ca987d46SWarner Losh 245*ca987d46SWarner Losh: goto_prompt ( N -- N FALSE ) 246*ca987d46SWarner Losh 247*ca987d46SWarner Losh s" set autoboot_delay=NO" evaluate 248*ca987d46SWarner Losh 249*ca987d46SWarner Losh cr 250*ca987d46SWarner Losh ." To get back to the menu, type `menu' and press ENTER" cr 251*ca987d46SWarner Losh ." or type `boot' and press ENTER to start FreeBSD." cr 252*ca987d46SWarner Losh cr 253*ca987d46SWarner Losh 254*ca987d46SWarner Losh FALSE \ exit the menu 255*ca987d46SWarner Losh; 256*ca987d46SWarner Losh 257*ca987d46SWarner Losh\ 258*ca987d46SWarner Losh\ Cyclestate (used by kernel/root below) 259*ca987d46SWarner Losh\ 260*ca987d46SWarner Losh 261*ca987d46SWarner Losh: init_cyclestate ( N K -- N ) 262*ca987d46SWarner Losh over cycle_stateN ( n k -- n k addr ) 263*ca987d46SWarner Losh begin 264*ca987d46SWarner Losh tuck @ ( n k addr -- n addr k c ) 265*ca987d46SWarner Losh over <> ( n addr k c -- n addr k 0|-1 ) 266*ca987d46SWarner Losh while 267*ca987d46SWarner Losh rot ( n addr k -- addr k n ) 268*ca987d46SWarner Losh cycle_menuitem 269*ca987d46SWarner Losh swap rot ( addr k n -- n k addr ) 270*ca987d46SWarner Losh repeat 271*ca987d46SWarner Losh 2drop ( n k addr -- n ) 272*ca987d46SWarner Losh; 273*ca987d46SWarner Losh 274*ca987d46SWarner Losh\ 275*ca987d46SWarner Losh\ Kernel 276*ca987d46SWarner Losh\ 277*ca987d46SWarner Losh 278*ca987d46SWarner Losh: init_kernel ( N -- N ) 279*ca987d46SWarner Losh kernel_state @ ( n -- n k ) 280*ca987d46SWarner Losh init_cyclestate ( n k -- n ) 281*ca987d46SWarner Losh; 282*ca987d46SWarner Losh 283*ca987d46SWarner Losh: activate_kernel ( N -- N ) 284*ca987d46SWarner Losh dup cycle_stateN @ ( n -- n n2 ) 285*ca987d46SWarner Losh dup kernel_state ! ( n n2 -- n n2 ) \ copy for re-initialization 286*ca987d46SWarner Losh 48 + ( n n2 -- n n2' ) \ kernel_state to ASCII num 287*ca987d46SWarner Losh 288*ca987d46SWarner Losh s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}" 289*ca987d46SWarner Losh 36 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num 290*ca987d46SWarner Losh evaluate ( n c-addr/u -- n ) \ sets $kernel to full kernel-path 291*ca987d46SWarner Losh; 292*ca987d46SWarner Losh 293*ca987d46SWarner Losh: cycle_kernel ( N -- N TRUE ) 294*ca987d46SWarner Losh cycle_menuitem \ cycle cycle_stateN to next value 295*ca987d46SWarner Losh activate_kernel \ apply current cycle_stateN 296*ca987d46SWarner Losh menu-redraw \ redraw menu 297*ca987d46SWarner Losh TRUE \ loop menu again 298*ca987d46SWarner Losh; 299*ca987d46SWarner Losh 300*ca987d46SWarner Losh\ 301*ca987d46SWarner Losh\ Root 302*ca987d46SWarner Losh\ 303*ca987d46SWarner Losh 304*ca987d46SWarner Losh: init_root ( N -- N ) 305*ca987d46SWarner Losh root_state @ ( n -- n k ) 306*ca987d46SWarner Losh init_cyclestate ( n k -- n ) 307*ca987d46SWarner Losh; 308*ca987d46SWarner Losh 309*ca987d46SWarner Losh: activate_root ( N -- N ) 310*ca987d46SWarner Losh dup cycle_stateN @ ( n -- n n2 ) 311*ca987d46SWarner Losh dup root_state ! ( n n2 -- n n2 ) \ copy for re-initialization 312*ca987d46SWarner Losh 48 + ( n n2 -- n n2' ) \ root_state to ASCII num 313*ca987d46SWarner Losh 314*ca987d46SWarner Losh s" set root=${root_prefix}${root[N]}${root_suffix}" 315*ca987d46SWarner Losh 30 +c! ( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num 316*ca987d46SWarner Losh evaluate ( n c-addr/u -- n ) \ sets $root to full kernel-path 317*ca987d46SWarner Losh; 318*ca987d46SWarner Losh 319*ca987d46SWarner Losh: cycle_root ( N -- N TRUE ) 320*ca987d46SWarner Losh cycle_menuitem \ cycle cycle_stateN to next value 321*ca987d46SWarner Losh activate_root \ apply current cycle_stateN 322*ca987d46SWarner Losh menu-redraw \ redraw menu 323*ca987d46SWarner Losh TRUE \ loop menu again 324*ca987d46SWarner Losh; 325*ca987d46SWarner Losh 326*ca987d46SWarner Losh\ 327*ca987d46SWarner Losh\ Menusets 328*ca987d46SWarner Losh\ 329*ca987d46SWarner Losh 330*ca987d46SWarner Losh: goto_menu ( N M -- N TRUE ) 331*ca987d46SWarner Losh menu-unset 332*ca987d46SWarner Losh menuset-loadsetnum ( n m -- n ) 333*ca987d46SWarner Losh menu-redraw 334*ca987d46SWarner Losh TRUE \ Loop menu again 335*ca987d46SWarner Losh; 336*ca987d46SWarner Losh 337*ca987d46SWarner Losh\ 338*ca987d46SWarner Losh\ Defaults 339*ca987d46SWarner Losh\ 340*ca987d46SWarner Losh 341*ca987d46SWarner Losh: set_default_boot_options ( N -- N TRUE ) 342*ca987d46SWarner Losh acpi_enable 343*ca987d46SWarner Losh safemode_disable 344*ca987d46SWarner Losh singleuser_disable 345*ca987d46SWarner Losh verbose_disable 346*ca987d46SWarner Losh 2 goto_menu 347*ca987d46SWarner Losh; 348*ca987d46SWarner Losh 349*ca987d46SWarner Losh\ 350*ca987d46SWarner Losh\ Set boot environment defaults 351*ca987d46SWarner Losh\ 352*ca987d46SWarner Losh 353*ca987d46SWarner Losh: init_bootenv ( -- ) 354*ca987d46SWarner Losh s" set menu_caption[1]=${bemenu_current}${vfs.root.mountfrom}" evaluate 355*ca987d46SWarner Losh s" set ansi_caption[1]=${beansi_current}${vfs.root.mountfrom}" evaluate 356*ca987d46SWarner Losh s" set menu_caption[2]=${bemenu_bootfs}${zfs_be_active}" evaluate 357*ca987d46SWarner Losh s" set ansi_caption[2]=${beansi_bootfs}${zfs_be_active}" evaluate 358*ca987d46SWarner Losh s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 359*ca987d46SWarner Losh s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate 360*ca987d46SWarner Losh; 361*ca987d46SWarner Losh 362*ca987d46SWarner Losh\ 363*ca987d46SWarner Losh\ Redraw the entire screen. A long BE name can corrupt the menu 364*ca987d46SWarner Losh\ 365*ca987d46SWarner Losh 366*ca987d46SWarner Losh: be_draw_screen 367*ca987d46SWarner Losh clear \ Clear the screen (in screen.4th) 368*ca987d46SWarner Losh print_version \ print version string (bottom-right; see version.4th) 369*ca987d46SWarner Losh draw-beastie \ Draw FreeBSD logo at right (in beastie.4th) 370*ca987d46SWarner Losh draw-brand \ Draw brand.4th logo at top (in brand.4th) 371*ca987d46SWarner Losh menu-init \ Initialize menu and draw bounding box (in menu.4th) 372*ca987d46SWarner Losh; 373*ca987d46SWarner Losh 374*ca987d46SWarner Losh\ 375*ca987d46SWarner Losh\ Select a boot environment 376*ca987d46SWarner Losh\ 377*ca987d46SWarner Losh 378*ca987d46SWarner Losh: set_bootenv ( N -- N TRUE ) 379*ca987d46SWarner Losh dup s" set vfs.root.mountfrom=${bootenv_root[E]}" 38 +c! evaluate 380*ca987d46SWarner Losh s" set currdev=${vfs.root.mountfrom}:" evaluate 381*ca987d46SWarner Losh s" unload" evaluate 382*ca987d46SWarner Losh free-module-options 383*ca987d46SWarner Losh s" /boot/defaults/loader.conf" read-conf 384*ca987d46SWarner Losh s" /boot/loader.conf" read-conf 385*ca987d46SWarner Losh s" /boot/loader.conf.local" read-conf 386*ca987d46SWarner Losh init_bootenv 387*ca987d46SWarner Losh be_draw_screen 388*ca987d46SWarner Losh menu-redraw 389*ca987d46SWarner Losh TRUE 390*ca987d46SWarner Losh; 391*ca987d46SWarner Losh 392*ca987d46SWarner Losh\ 393*ca987d46SWarner Losh\ Switch to the next page of boot environments 394*ca987d46SWarner Losh\ 395*ca987d46SWarner Losh 396*ca987d46SWarner Losh: set_be_page ( N -- N TRUE ) 397*ca987d46SWarner Losh s" zfs_be_currpage" getenv dup -1 = if 398*ca987d46SWarner Losh drop s" 1" 399*ca987d46SWarner Losh else 400*ca987d46SWarner Losh 0 s>d 2swap 401*ca987d46SWarner Losh >number ( ud caddr/u -- ud' caddr'/u' ) \ convert string to numbers 402*ca987d46SWarner Losh 2drop \ drop the string 403*ca987d46SWarner Losh 1 um/mod ( ud u1 -- u2 u3 ) \ convert double ud' to single u3' and remainder u2 404*ca987d46SWarner Losh swap drop ( ud2 u3 -- u3 ) \ drop the remainder u2 405*ca987d46SWarner Losh 1+ \ increment the page number 406*ca987d46SWarner Losh s>d <# #s #> \ convert back to a string 407*ca987d46SWarner Losh then 408*ca987d46SWarner Losh s" zfs_be_currpage" setenv 409*ca987d46SWarner Losh s" reloadbe" evaluate 410*ca987d46SWarner Losh 3 goto_menu 411*ca987d46SWarner Losh; 412*ca987d46SWarner Losh 413*ca987d46SWarner Loshonly forth definitions 414