Print this page
NEX-16881 use nexenta brand in the loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Revert "NEX-16881 use nexenta brand in the loader"
This reverts commit fb1dd3064bae9acf9a68f8ed41fd2f58d51de944.
NEX-16881 use nexenta brand in the loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/boot/sys/boot/forth/menu.4th
+++ new/usr/src/boot/sys/boot/forth/menu.4th
1 1 \ Copyright (c) 2003 Scott Long <scottl@FreeBSD.org>
2 2 \ Copyright (c) 2003 Aleksander Fafula <alex@fafula.com>
3 3 \ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
4 4 \ All rights reserved.
5 5 \
6 6 \ Redistribution and use in source and binary forms, with or without
7 7 \ modification, are permitted provided that the following conditions
8 8 \ are met:
9 9 \ 1. Redistributions of source code must retain the above copyright
10 10 \ notice, this list of conditions and the following disclaimer.
11 11 \ 2. Redistributions in binary form must reproduce the above copyright
12 12 \ notice, this list of conditions and the following disclaimer in the
13 13 \ documentation and/or other materials provided with the distribution.
14 14 \
15 15 \ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 16 \ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 17 \ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 18 \ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 19 \ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 20 \ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 21 \ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 22 \ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 23 \ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 24 \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 25 \ SUCH DAMAGE.
26 26 \
27 27 \ $FreeBSD$
28 28
29 29 marker task-menu.4th
30 30
31 31 \ Frame drawing
32 32 include /boot/forth/frames.4th
33 33
34 34 vocabulary menu-infrastructure
35 35 vocabulary menu-namespace
36 36 vocabulary menu-command-helpers
37 37
38 38 only forth also menu-infrastructure definitions
39 39
40 40 f_double \ Set frames to double (see frames.4th). Replace with
41 41 \ f_single if you want single frames.
42 42 46 constant dot \ ASCII definition of a period (in decimal)
43 43
44 44 5 constant menu_default_x \ default column position of timeout
45 45 10 constant menu_default_y \ default row position of timeout msg
46 46 4 constant menu_timeout_default_x \ default column position of timeout
47 47 23 constant menu_timeout_default_y \ default row position of timeout msg
48 48 10 constant menu_timeout_default \ default timeout (in seconds)
49 49
50 50 \ Customize the following values with care
51 51
52 52 1 constant menu_start \ Numerical prefix of first menu item
53 53 dot constant bullet \ Menu bullet (appears after numerical prefix)
54 54 5 constant menu_x \ Row position of the menu (from the top)
55 55 10 constant menu_y \ Column position of the menu (from left side)
56 56
57 57 \ Menu Appearance
58 58 variable menuidx \ Menu item stack for number prefixes
59 59 variable menurow \ Menu item stack for positioning
60 60 variable menubllt \ Menu item bullet
61 61
62 62 \ Menu Positioning
63 63 variable menuX \ Menu X offset (columns)
64 64 variable menuY \ Menu Y offset (rows)
65 65
66 66 \ Menu-item elements
67 67 variable menurebootadded
68 68
69 69 \ Parsing of kernels into menu-items
70 70 variable kernidx
71 71 variable kernlen
72 72 variable kernmenuidx
73 73
74 74 \ Menu timer [count-down] variables
75 75 variable menu_timeout_enabled \ timeout state (internal use only)
76 76 variable menu_time \ variable for tracking the passage of time
77 77 variable menu_timeout \ determined configurable delay duration
78 78 variable menu_timeout_x \ column position of timeout message
79 79 variable menu_timeout_y \ row position of timeout message
80 80
81 81 \ Containers for parsing kernels into menu-items
82 82 create kerncapbuf 64 allot
83 83 create kerndefault 64 allot
84 84 create kernelsbuf 256 allot
85 85
86 86 only forth also menu-namespace definitions
87 87
88 88 \ Menu-item key association/detection
89 89 variable menukey1
90 90 variable menukey2
91 91 variable menukey3
92 92 variable menukey4
93 93 variable menukey5
94 94 variable menukey6
95 95 variable menukey7
96 96 variable menukey8
97 97 variable menureboot
98 98 variable menuacpi
99 99 variable menuosconsole
100 100 variable menuoptions
101 101 variable menukernel
102 102
103 103 \ Menu initialization status variables
104 104 variable init_state1
105 105 variable init_state2
106 106 variable init_state3
107 107 variable init_state4
108 108 variable init_state5
109 109 variable init_state6
110 110 variable init_state7
111 111 variable init_state8
112 112
113 113 \ Boolean option status variables
114 114 variable toggle_state1
115 115 variable toggle_state2
116 116 variable toggle_state3
117 117 variable toggle_state4
118 118 variable toggle_state5
119 119 variable toggle_state6
120 120 variable toggle_state7
121 121 variable toggle_state8
122 122
123 123 \ Array option status variables
124 124 variable cycle_state1
125 125 variable cycle_state2
126 126 variable cycle_state3
127 127 variable cycle_state4
128 128 variable cycle_state5
129 129 variable cycle_state6
130 130 variable cycle_state7
131 131 variable cycle_state8
132 132
133 133 \ Containers for storing the initial caption text
134 134 create init_text1 64 allot
135 135 create init_text2 64 allot
136 136 create init_text3 64 allot
137 137 create init_text4 64 allot
138 138 create init_text5 64 allot
139 139 create init_text6 64 allot
140 140 create init_text7 64 allot
141 141 create init_text8 64 allot
142 142
143 143 only forth definitions
144 144
145 145 : arch-i386? ( -- BOOL ) \ Returns TRUE (-1) on i386, FALSE (0) otherwise.
146 146 s" arch-i386" environment? dup if
147 147 drop
148 148 then
149 149 ;
150 150
151 151 : acpipresent? ( -- flag ) \ Returns TRUE if ACPI is present, FALSE otherwise
152 152 s" hint.acpi.0.rsdp" getenv
153 153 dup -1 = if
154 154 drop false exit
155 155 then
156 156 2drop
157 157 true
158 158 ;
159 159
160 160 : acpienabled? ( -- flag ) \ Returns TRUE if ACPI is enabled, FALSE otherwise
161 161 s" hint.acpi.0.disabled" getenv
162 162 dup -1 <> if
163 163 s" 0" compare 0<> if
164 164 false exit
165 165 then
166 166 else
167 167 drop
168 168 then
169 169 true
170 170 ;
171 171
172 172 : +c! ( N C-ADDR/U K -- C-ADDR/U )
173 173 3 pick 3 pick ( n c-addr/u k -- n c-addr/u k n c-addr )
174 174 rot + c! ( n c-addr/u k n c-addr -- n c-addr/u )
175 175 rot drop ( n c-addr/u -- c-addr/u )
176 176 ;
177 177
178 178 only forth also menu-namespace definitions
179 179
180 180 \ Forth variables
181 181 : namespace ( C-ADDR/U N -- ) also menu-namespace +c! evaluate previous ;
182 182 : menukeyN ( N -- ADDR ) s" menukeyN" 7 namespace ;
183 183 : init_stateN ( N -- ADDR ) s" init_stateN" 10 namespace ;
184 184 : toggle_stateN ( N -- ADDR ) s" toggle_stateN" 12 namespace ;
185 185 : cycle_stateN ( N -- ADDR ) s" cycle_stateN" 11 namespace ;
186 186 : init_textN ( N -- C-ADDR ) s" init_textN" 9 namespace ;
187 187
188 188 \ Environment variables
189 189 : kernel[x] ( N -- C-ADDR/U ) s" kernel[x]" 7 +c! ;
190 190 : menu_init[x] ( N -- C-ADDR/U ) s" menu_init[x]" 10 +c! ;
191 191 : menu_command[x] ( N -- C-ADDR/U ) s" menu_command[x]" 13 +c! ;
192 192 : menu_caption[x] ( N -- C-ADDR/U ) s" menu_caption[x]" 13 +c! ;
193 193 : ansi_caption[x] ( N -- C-ADDR/U ) s" ansi_caption[x]" 13 +c! ;
194 194 : menu_keycode[x] ( N -- C-ADDR/U ) s" menu_keycode[x]" 13 +c! ;
195 195 : toggled_text[x] ( N -- C-ADDR/U ) s" toggled_text[x]" 13 +c! ;
196 196 : toggled_ansi[x] ( N -- C-ADDR/U ) s" toggled_ansi[x]" 13 +c! ;
197 197 : menu_caption[x][y] ( N M -- C-ADDR/U ) s" menu_caption[x][y]" 16 +c! 13 +c! ;
198 198 : ansi_caption[x][y] ( N M -- C-ADDR/U ) s" ansi_caption[x][y]" 16 +c! 13 +c! ;
199 199
200 200 also menu-infrastructure definitions
201 201
202 202 \ This function prints a menu item at menuX (row) and menuY (column), returns
203 203 \ the incremental decimal ASCII value associated with the menu item, and
204 204 \ increments the cursor position to the next row for the creation of the next
205 205 \ menu item. This function is called by the menu-create function. You need not
206 206 \ call it directly.
207 207 \
208 208 : printmenuitem ( menu_item_str -- ascii_keycode )
209 209
210 210 loader_color? if [char] ^ escc! then
211 211
212 212 menurow dup @ 1+ swap ! ( increment menurow )
213 213 menuidx dup @ 1+ swap ! ( increment menuidx )
214 214
215 215 \ Calculate the menuitem row position
216 216 menurow @ menuY @ +
217 217
218 218 \ Position the cursor at the menuitem position
219 219 dup menuX @ swap at-xy
220 220
221 221 \ Print the value of menuidx
222 222 loader_color? dup ( -- bool bool )
223 223 if b then
224 224 menuidx @ .
225 225 if me then
226 226
227 227 \ Move the cursor forward 1 column
228 228 dup menuX @ 1+ swap at-xy
229 229
230 230 menubllt @ emit \ Print the menu bullet using the emit function
231 231
232 232 \ Move the cursor to the 3rd column from the current position
233 233 \ to allow for a space between the numerical prefix and the
234 234 \ text caption
235 235 menuX @ 3 + swap at-xy
236 236
237 237 \ Print the menu caption (we expect a string to be on the stack
238 238 \ prior to invoking this function)
239 239 type
240 240
241 241 \ Here we will add the ASCII decimal of the numerical prefix
242 242 \ to the stack (decimal ASCII for `1' is 49) as a "return value"
243 243 menuidx @ 48 +
244 244 ;
245 245
246 246 : delim? ( C -- BOOL )
247 247 dup 32 = ( c -- c bool ) \ [sp] space
248 248 over 9 = or ( c bool -- c bool ) \ [ht] horizontal tab
249 249 over 10 = or ( c bool -- c bool ) \ [nl] newline
250 250 over 13 = or ( c bool -- c bool ) \ [cr] carriage return
251 251 over [char] , = or ( c bool -- c bool ) \ comma
252 252 swap drop ( c bool -- bool ) \ return boolean
253 253 ;
254 254
255 255 \ This function parses $kernels into variables that are used by the menu to
256 256 \ display which kernel to boot when the [overloaded] `boot' word is interpreted.
257 257 \ Used internally by menu-create, you need not (nor should you) call this
258 258 \ directly.
259 259 \
260 260 : parse-kernels ( N -- ) \ kernidx
261 261 kernidx ! ( n -- ) \ store provided `x' value
262 262 [char] 0 kernmenuidx ! \ initialize `y' value for menu_caption[x][y]
263 263
264 264 \ Attempt to get a list of kernels, fall back to sensible default
265 265 s" kernels" getenv dup -1 = if
266 266 drop ( cruft )
267 267 s" kernel kernel.old"
268 268 then ( -- c-addr/u )
269 269
270 270 \ Check to see if the user has altered $kernel by comparing it against
271 271 \ $kernel[N] where N is kernel_state (the actively displayed kernel).
272 272 s" kernel_state" evaluate @ 48 + s" kernel[N]" 7 +c! getenv
273 273 dup -1 <> if
274 274 s" kernel" getenv dup -1 = if
275 275 drop ( cruft ) s" "
276 276 then
277 277 2swap 2over compare 0= if
278 278 2drop FALSE ( skip below conditional )
279 279 else \ User has changed $kernel
280 280 TRUE ( slurp in new value )
281 281 then
282 282 else \ We haven't yet parsed $kernels into $kernel[N]
283 283 drop ( getenv cruft )
284 284 s" kernel" getenv dup -1 = if
285 285 drop ( cruft ) s" "
286 286 then
287 287 TRUE ( slurp in initial value )
288 288 then ( c-addr/u -- c-addr/u c-addr/u,-1 | 0 )
289 289 if \ slurp new value into kerndefault
290 290 kerndefault 1+ 0 2swap strcat swap 1- c!
291 291 then
292 292
293 293 \ Clear out existing parsed-kernels
294 294 kernidx @ [char] 0
295 295 begin
296 296 dup kernel[x] unsetenv
297 297 2dup menu_caption[x][y] unsetenv
298 298 2dup ansi_caption[x][y] unsetenv
299 299 1+ dup [char] 8 >
300 300 until
301 301 2drop
302 302
303 303 \ Step through the string until we find the end
304 304 begin
305 305 0 kernlen ! \ initialize length of value
306 306
307 307 \ Skip leading whitespace and/or comma delimiters
308 308 begin
309 309 dup 0<> if
310 310 over c@ delim? ( c-addr/u -- c-addr/u bool )
311 311 else
312 312 false ( c-addr/u -- c-addr/u bool )
313 313 then
314 314 while
315 315 1- swap 1+ swap ( c-addr/u -- c-addr'/u' )
316 316 repeat
317 317 ( c-addr/u -- c-addr'/u' )
318 318
319 319 dup 0= if \ end of string while eating whitespace
320 320 2drop ( c-addr/u -- )
321 321 kernmenuidx @ [char] 0 <> if \ found at least one
322 322 exit \ all done
323 323 then
324 324
325 325 \ No entries in $kernels; use $kernel instead
326 326 s" kernel" getenv dup -1 = if
327 327 drop ( cruft ) s" "
328 328 then ( -- c-addr/u )
329 329 dup kernlen ! \ store entire value length as kernlen
330 330 else
331 331 \ We're still within $kernels parsing toward the end;
332 332 \ find delimiter/end to determine kernlen
333 333 2dup ( c-addr/u -- c-addr/u c-addr/u )
334 334 begin dup 0<> while
335 335 over c@ delim? if
336 336 drop 0 ( break ) \ found delimiter
337 337 else
338 338 kernlen @ 1+ kernlen ! \ incrememnt
339 339 1- swap 1+ swap \ c-addr++ u--
340 340 then
341 341 repeat
342 342 2drop ( c-addr/u c-addr'/u' -- c-addr/u )
343 343
344 344 \ If this is the first entry, compare it to $kernel
345 345 \ If different, then insert $kernel beforehand
346 346 kernmenuidx @ [char] 0 = if
347 347 over kernlen @ kerndefault count compare if
348 348 kernelsbuf 0 kerndefault count strcat
349 349 s" ," strcat 2swap strcat
350 350 kerndefault count swap drop kernlen !
351 351 then
352 352 then
353 353 then
354 354 ( c-addr/u -- c-addr'/u' )
355 355
356 356 \ At this point, we should have something on the stack to store
357 357 \ as the next kernel menu option; start assembling variables
358 358
359 359 over kernlen @ ( c-addr/u -- c-addr/u c-addr/u2 )
360 360
361 361 \ Assign first to kernel[x]
362 362 2dup kernmenuidx @ kernel[x] setenv
363 363
364 364 \ Assign second to menu_caption[x][y]
365 365 kerncapbuf 0 s" [K]ernel: " strcat
366 366 2over strcat
367 367 kernidx @ kernmenuidx @ menu_caption[x][y]
368 368 setenv
369 369
370 370 \ Assign third to ansi_caption[x][y]
371 371 kerncapbuf 0 s" @[1mK@[37mernel: " [char] @ escc! strcat
372 372 kernmenuidx @ [char] 0 = if
373 373 s" default/@[32m"
374 374 else
375 375 s" @[34;1m"
376 376 then
377 377 [char] @ escc! strcat
378 378 2over strcat
379 379 s" @[37m" [char] @ escc! strcat
380 380 kernidx @ kernmenuidx @ ansi_caption[x][y]
381 381 setenv
382 382
383 383 2drop ( c-addr/u c-addr/u2 -- c-addr/u )
384 384
385 385 kernmenuidx @ 1+ dup kernmenuidx ! [char] 8 > if
386 386 2drop ( c-addr/u -- ) exit
387 387 then
388 388
389 389 kernlen @ - swap kernlen @ + swap ( c-addr/u -- c-addr'/u' )
390 390 again
391 391 ;
392 392
393 393 \ This function goes through the kernels that were discovered by the
394 394 \ parse-kernels function [above], adding " (# of #)" text to the end of each
395 395 \ caption.
396 396 \
397 397 : tag-kernels ( -- )
398 398 kernidx @ ( -- x ) dup 0= if exit then
399 399 [char] 0 s" (Y of Z)" ( x -- x y c-addr/u )
400 400 kernmenuidx @ -rot 7 +c! \ Replace 'Z' with number of kernels parsed
401 401 begin
402 402 2 pick 1+ -rot 2 +c! \ Replace 'Y' with current ASCII num
403 403
404 404 2over menu_caption[x][y] getenv dup -1 <> if
405 405 2dup + 1- c@ [char] ) = if
406 406 2drop \ Already tagged
407 407 else
408 408 kerncapbuf 0 2swap strcat
409 409 2over strcat
410 410 5 pick 5 pick menu_caption[x][y] setenv
411 411 then
412 412 else
413 413 drop ( getenv cruft )
414 414 then
415 415
416 416 2over ansi_caption[x][y] getenv dup -1 <> if
417 417 2dup + 1- c@ [char] ) = if
418 418 2drop \ Already tagged
419 419 else
420 420 kerncapbuf 0 2swap strcat
421 421 2over strcat
422 422 5 pick 5 pick ansi_caption[x][y] setenv
423 423 then
424 424 else
425 425 drop ( getenv cruft )
426 426 then
427 427
428 428 rot 1+ dup [char] 8 > if
429 429 -rot 2drop TRUE ( break )
430 430 else
431 431 -rot FALSE
432 432 then
433 433 until
434 434 2drop ( x y -- )
435 435 ;
436 436
437 437 \ Illumos kernel acpi-user-options has following values:
438 438 \ default: 0 - system will enable acpi based on bios date
439 439 \ on: 1 - acpi is set on
440 440 \ off: 2 - acpi is set off
441 441 \ madt: 4 - use only MADT
442 442 \ legacy: 8 - use legacy mode
443 443
444 444 : acpi-captions ( N -- )
445 445 \ first entry
446 446 dup s" [A]CPI.... default" rot 48 menu_caption[x][y] setenv
447 447 dup s" ^[1mA^[mCPI.... ^[32;7mdefault^[m" rot 48 ansi_caption[x][y] setenv
448 448
449 449 dup s" [A]CPI........ On" rot 49 menu_caption[x][y] setenv
450 450 dup s" ^[1mA^[mCPI........ ^[34;1mOn^[m" rot 49 ansi_caption[x][y] setenv
451 451
452 452 dup s" [A]CPI........ Off" rot 50 menu_caption[x][y] setenv
453 453 dup s" ^[1mA^[mCPI........ ^[34;1mOff^[m" rot 50 ansi_caption[x][y] setenv
454 454
455 455 dup s" [A]CPI....... MADT" rot 51 menu_caption[x][y] setenv
456 456 dup s" ^[1mA^[mCPI....... ^[34;1mMADT^[m" rot 51 ansi_caption[x][y] setenv
457 457
458 458 dup s" [A]CPI..... Legacy" rot 52 menu_caption[x][y] setenv
459 459 s" ^[1mA^[mCPI..... ^[34;1mLegacy^[m" rot 52 ansi_caption[x][y] setenv
460 460 ;
461 461
462 462 \ Illumos console has following values:
463 463 \ text, ttya, ttyb, ttyc, ttyd
464 464
465 465 : osconsole-captions ( N -- )
466 466 \ first entry
467 467 dup s" Os[C]onsole.. text" rot 48 menu_caption[x][y] setenv
468 468 dup s" Os^[1mC^[monsole.. ^[32;7mtext^[m" rot 48 ansi_caption[x][y] setenv
469 469
470 470 dup s" Os[C]onsole.. ttya" rot 49 menu_caption[x][y] setenv
471 471 dup s" Os^[1mC^[monsole.. ^[34;1mttya^[m" rot 49 ansi_caption[x][y] setenv
472 472
473 473 dup s" Os[C]onsole.. ttyb" rot 50 menu_caption[x][y] setenv
474 474 dup s" Os^[1mC^[monsole.. ^[34;1mttyb^[m" rot 50 ansi_caption[x][y] setenv
475 475
476 476 dup s" Os[C]onsole.. ttyc" rot 51 menu_caption[x][y] setenv
477 477 dup s" Os^[1mC^[monsole.. ^[34;1mttyc^[m" rot 51 ansi_caption[x][y] setenv
478 478
479 479 dup s" Os[C]onsole.. ttyd" rot 52 menu_caption[x][y] setenv
|
↓ open down ↓ |
479 lines elided |
↑ open up ↑ |
480 480 s" Os^[1mC^[monsole.. ^[34;1mttyd^[m" rot 52 ansi_caption[x][y] setenv
481 481 ;
482 482
483 483 \ This function creates the list of menu items. This function is called by the
484 484 \ menu-display function. You need not call it directly.
485 485 \
486 486 : menu-create ( -- )
487 487
488 488 \ Print the frame caption at (x,y)
489 489 s" loader_menu_title" getenv dup -1 = if
490 - drop s" Welcome to illumos"
490 + drop s" NexentaStor"
491 491 then
492 492 TRUE ( use default alignment )
493 493 s" loader_menu_title_align" getenv dup -1 <> if
494 494 2dup s" left" compare-insensitive 0= if ( 1 )
495 495 2drop ( c-addr/u ) drop ( bool )
496 496 menuX @ menuY @ 1-
497 497 FALSE ( don't use default alignment )
498 498 else ( 1 ) 2dup s" right" compare-insensitive 0= if ( 2 )
499 499 2drop ( c-addr/u ) drop ( bool )
500 500 menuX @ 42 + 4 - over - menuY @ 1-
501 501 FALSE ( don't use default alignment )
502 502 else ( 2 ) 2drop ( c-addr/u ) then ( 1 ) then
503 503 else
504 504 drop ( getenv cruft )
505 505 then
506 506 if ( use default center alignement? )
507 507 menuX @ 19 + over 2 / - menuY @ 1-
508 508 then
509 509 at-xy type
510 510
511 511 \ If $menu_init is set, evaluate it (allowing for whole menus to be
512 512 \ constructed dynamically -- as this function could conceivably set
513 513 \ the remaining environment variables to construct the menu entirely).
514 514 \
515 515 s" menu_init" getenv dup -1 <> if
516 516 evaluate
517 517 else
518 518 drop
519 519 then
520 520
521 521 \ Print our menu options with respective key/variable associations.
522 522 \ `printmenuitem' ends by adding the decimal ASCII value for the
523 523 \ numerical prefix to the stack. We store the value left on the stack
524 524 \ to the key binding variable for later testing against a character
525 525 \ captured by the `getkey' function.
526 526
527 527 \ Note that any menu item beyond 9 will have a numerical prefix on the
528 528 \ screen consisting of the first digit (ie. 1 for the tenth menu item)
529 529 \ and the key required to activate that menu item will be the decimal
530 530 \ ASCII of 48 plus the menu item (ie. 58 for the tenth item, aka. `:')
531 531 \ which is misleading and not desirable.
532 532 \
533 533 \ Thus, we do not allow more than 8 configurable items on the menu
534 534 \ (with "Reboot" as the optional ninth and highest numbered item).
535 535
536 536 \
537 537 \ Initialize the OsConsole option status.
538 538 \
539 539 0 menuosconsole !
540 540 s" menu_osconsole" getenv -1 <> if
541 541 c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' )
542 542 dup menuosconsole !
543 543 dup osconsole-captions
544 544
545 545 s" init_osconsole" evaluate
546 546
547 547 \ Get the current cycle state (entry to use)
548 548 s" osconsole_state" evaluate @ 48 + ( n -- n y )
549 549
550 550 \ Set the current non-ANSI caption
551 551 2dup swap dup ( n y -- n y y n n )
552 552 s" set menu_caption[x]=$menu_caption[x][y]"
553 553 17 +c! 34 +c! 37 +c! evaluate
554 554 ( n y y n n c-addr/u -- n y )
555 555
556 556 \ Set the current ANSI caption
557 557 2dup swap dup ( n y -- n y y n n )
558 558 s" set ansi_caption[x]=$ansi_caption[x][y]"
559 559 17 +c! 34 +c! 37 +c! evaluate
560 560 ( n y y n n c-addr/u -- n y )
561 561
562 562 \ Initialize cycle state from stored value
563 563 48 - ( n y -- n k )
564 564 s" init_cyclestate" evaluate ( n k -- n )
565 565
566 566 \ Set $os_console
567 567 s" activate_osconsole" evaluate ( n -- n )
568 568 then
569 569 drop
570 570 then
571 571
572 572 \
573 573 \ Initialize the ACPI option status.
574 574 \
575 575 0 menuacpi !
576 576 s" menu_acpi" getenv -1 <> if
577 577 c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' )
578 578 dup menuacpi !
579 579 dup acpi-captions
580 580
581 581 s" init_acpi" evaluate
582 582
583 583 \ Get the current cycle state (entry to use)
584 584 s" acpi_state" evaluate @ 48 + ( n -- n y )
585 585
586 586 \ Set the current non-ANSI caption
587 587 2dup swap dup ( n y -- n y y n n )
588 588 s" set menu_caption[x]=$menu_caption[x][y]"
589 589 17 +c! 34 +c! 37 +c! evaluate
590 590 ( n y y n n c-addr/u -- n y )
591 591
592 592 \ Set the current ANSI caption
593 593 2dup swap dup ( n y -- n y y n n )
594 594 s" set ansi_caption[x]=$ansi_caption[x][y]"
595 595 17 +c! 34 +c! 37 +c! evaluate
596 596 ( n y y n n c-addr/u -- n y )
597 597
598 598 \ Initialize cycle state from stored value
599 599 48 - ( n y -- n k )
600 600 s" init_cyclestate" evaluate ( n k -- n )
601 601
602 602 \ Set $acpi-user-options
603 603 s" activate_acpi" evaluate ( n -- n )
604 604 then
605 605 drop
606 606 then
607 607
608 608 \
609 609 \ Initialize kernel captions after parsing $kernels
610 610 \
611 611 0 menukernel !
612 612 s" menu_kernel" getenv -1 <> if
613 613 c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' )
614 614 dup menukernel !
615 615 dup parse-kernels tag-kernels
616 616
617 617 \ Get the current cycle state (entry to use)
618 618 s" kernel_state" evaluate @ 48 + ( n -- n y )
619 619
620 620 \ If state is invalid, reset
621 621 dup kernmenuidx @ 1- > if
622 622 drop [char] 0 ( n y -- n 48 )
623 623 0 s" kernel_state" evaluate !
624 624 over s" init_kernel" evaluate drop
625 625 then
626 626
627 627 \ Set the current non-ANSI caption
628 628 2dup swap dup ( n y -- n y y n n )
629 629 s" set menu_caption[x]=$menu_caption[x][y]"
630 630 17 +c! 34 +c! 37 +c! evaluate
631 631 ( n y y n n c-addr/u -- n y )
632 632
633 633 \ Set the current ANSI caption
634 634 2dup swap dup ( n y -- n y y n n )
635 635 s" set ansi_caption[x]=$ansi_caption[x][y]"
636 636 17 +c! 34 +c! 37 +c! evaluate
637 637 ( n y y n n c-addr/u -- n y )
638 638
639 639 \ Initialize cycle state from stored value
640 640 48 - ( n y -- n k )
641 641 s" init_cyclestate" evaluate ( n k -- n )
642 642
643 643 \ Set $kernel to $kernel[y]
644 644 s" activate_kernel" evaluate ( n -- n )
645 645 then
646 646 drop
647 647 then
648 648
649 649 \
650 650 \ Initialize the menu_options visual separator.
651 651 \
652 652 0 menuoptions !
653 653 s" menu_options" getenv -1 <> if
654 654 c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' )
655 655 menuoptions !
656 656 else
657 657 drop
658 658 then
659 659 then
660 660
661 661 \ Initialize "Reboot" menu state variable (prevents double-entry)
662 662 false menurebootadded !
663 663
664 664 menu_start
665 665 1- menuidx ! \ Initialize the starting index for the menu
666 666 0 menurow ! \ Initialize the starting position for the menu
667 667
668 668 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8')
669 669 begin
670 670 \ If the "Options:" separator, print it.
671 671 dup menuoptions @ = if
672 672 \ Optionally add a reboot option to the menu
673 673 s" menu_reboot" getenv -1 <> if
674 674 drop
675 675 s" Reboot" printmenuitem menureboot !
676 676 true menurebootadded !
677 677 then
678 678
679 679 menuX @
680 680 menurow @ 2 + menurow !
681 681 menurow @ menuY @ +
682 682 at-xy
683 683 s" menu_optionstext" getenv dup -1 <> if
684 684 type
685 685 else
686 686 drop ." Options:"
687 687 then
688 688 then
689 689
690 690 \ make sure we have not already initialized this item
691 691 dup init_stateN dup @ 0= if
692 692 1 swap !
693 693
694 694 \ If this menuitem has an initializer, run it
695 695 dup menu_init[x]
696 696 getenv dup -1 <> if
697 697 evaluate
698 698 else
699 699 drop
700 700 then
701 701 else
702 702 drop
703 703 then
704 704
705 705 dup
706 706 loader_color? if
707 707 ansi_caption[x]
708 708 else
709 709 menu_caption[x]
710 710 then
711 711
712 712 dup -1 <> if
713 713 \ test for environment variable
714 714 getenv dup -1 <> if
715 715 printmenuitem ( c-addr/u -- n )
716 716 dup menukeyN !
717 717 else
718 718 drop
719 719 then
720 720 else
721 721 drop
722 722 then
723 723
724 724 1+ dup 56 > \ add 1 to iterator, continue if less than 57
725 725 until
726 726 drop \ iterator
727 727
728 728 \ Optionally add a reboot option to the menu
729 729 menurebootadded @ true <> if
730 730 s" menu_reboot" getenv -1 <> if
731 731 drop \ no need for the value
732 732 s" Reboot" \ menu caption (required by printmenuitem)
733 733
734 734 printmenuitem
735 735 menureboot !
736 736 else
737 737 0 menureboot !
738 738 then
739 739 then
740 740 ;
741 741
742 742 \ Takes a single integer on the stack and updates the timeout display. The
743 743 \ integer must be between 0 and 9 (we will only update a single digit in the
744 744 \ source message).
745 745 \
746 746 : menu-timeout-update ( N -- )
747 747
748 748 \ Enforce minimum/maximum
749 749 dup 9 > if drop 9 then
750 750 dup 0 < if drop 0 then
751 751
752 752 s" Autoboot in N seconds. [Space] to pause" ( n -- n c-addr/u )
753 753
754 754 2 pick 0> if
755 755 rot 48 + -rot ( n c-addr/u -- n' c-addr/u ) \ convert to ASCII
756 756 12 +c! ( n' c-addr/u -- c-addr/u ) \ replace 'N' above
757 757
758 758 menu_timeout_x @ menu_timeout_y @ at-xy \ position cursor
759 759 type ( c-addr/u -- ) \ print message
760 760 else
761 761 menu_timeout_x @ menu_timeout_y @ at-xy \ position cursor
762 762 spaces ( n c-addr/u -- n c-addr ) \ erase message
763 763 2drop ( n c-addr -- )
764 764 then
765 765
766 766 0 25 at-xy ( position cursor back at bottom-left )
767 767 ;
768 768
769 769 \ This function blocks program flow (loops forever) until a key is pressed.
770 770 \ The key that was pressed is added to the top of the stack in the form of its
771 771 \ decimal ASCII representation. This function is called by the menu-display
772 772 \ function. You need not call it directly.
773 773 \ note, the esc sequences will be dropped, this needs to be changed if
774 774 \ menu is built based on arrow keys.
775 775 \
776 776 : getkey ( -- ascii_keycode )
777 777
778 778 begin \ loop forever
779 779
780 780 menu_timeout_enabled @ 1 = if
781 781 ( -- )
782 782 seconds ( get current time: -- N )
783 783 dup menu_time @ <> if ( has time elapsed?: N N N -- N )
784 784
785 785 \ At least 1 second has elapsed since last loop
786 786 \ so we will decrement our "timeout" (really a
787 787 \ counter, insuring that we do not proceed too
788 788 \ fast) and update our timeout display.
789 789
790 790 menu_time ! ( update time record: N -- )
791 791 menu_timeout @ ( "time" remaining: -- N )
792 792 dup 0> if ( greater than 0?: N N 0 -- N )
793 793 1- ( decrement counter: N -- N )
794 794 dup menu_timeout !
795 795 ( re-assign: N N Addr -- N )
796 796 then
797 797 ( -- N )
798 798
799 799 dup 0= swap 0< or if ( N <= 0?: N N -- )
800 800 \ halt the timer
801 801 0 menu_timeout ! ( 0 Addr -- )
802 802 0 menu_timeout_enabled ! ( 0 Addr -- )
803 803 then
804 804
805 805 \ update the timer display ( N -- )
806 806 menu_timeout @ menu-timeout-update
807 807
808 808 menu_timeout @ 0= if
809 809 \ We've reached the end of the timeout
810 810 \ (user did not cancel by pressing ANY
811 811 \ key)
812 812
813 813 s" menu_timeout_command" getenv dup
814 814 -1 = if
815 815 drop \ clean-up
816 816 else
817 817 evaluate
818 818 then
819 819 then
820 820
821 821 else ( -- N )
822 822 \ No [detectable] time has elapsed (in seconds)
823 823 drop ( N -- )
824 824 then
825 825 ( -- )
826 826 then
827 827
828 828 key? if \ Was a key pressed? (see loader(8))
829 829
830 830 \ An actual key was pressed (if the timeout is running,
831 831 \ kill it regardless of which key was pressed)
832 832 menu_timeout @ 0<> if
833 833 0 menu_timeout !
834 834 0 menu_timeout_enabled !
835 835
836 836 \ clear screen of timeout message
837 837 0 menu-timeout-update
838 838 then
839 839
840 840 \ get the key that was pressed and exit (if we
841 841 \ get a non-zero ASCII code)
842 842 key dup 0<> if
843 843 dup 0x1b = if
844 844 key? if ( is it sequence? )
845 845 drop
846 846 begin
847 847 key?
848 848 while
849 849 key drop
850 850 repeat
851 851 else
852 852 exit
853 853 then
854 854 else
855 855 exit
856 856 then
857 857 else
858 858 drop
859 859 then
860 860 then
861 861 50 ms \ sleep for 50 milliseconds (see loader(8))
862 862
863 863 again
864 864 ;
865 865
866 866 : menu-erase ( -- ) \ Erases menu and resets positioning variable to position 1.
867 867
868 868 \ Clear the screen area associated with the interactive menu
869 869 menuX @ menuY @
870 870 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
871 871 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
872 872 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
873 873 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
874 874 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+
875 875 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces
876 876 2drop
877 877
878 878 \ Reset the starting index and position for the menu
879 879 menu_start 1- menuidx !
880 880 0 menurow !
881 881 ;
882 882
883 883 only forth
884 884 also menu-infrastructure
885 885 also menu-namespace
886 886 also menu-command-helpers definitions
887 887
888 888 : toggle_menuitem ( N -- N ) \ toggles caption text and internal menuitem state
889 889
890 890 \ ASCII numeral equal to user-selected menu item must be on the stack.
891 891 \ We do not modify the stack, so the ASCII numeral is left on top.
892 892
893 893 dup init_textN c@ 0= if
894 894 \ NOTE: no need to check toggle_stateN since the first time we
895 895 \ are called, we will populate init_textN. Further, we don't
896 896 \ need to test whether menu_caption[x] (ansi_caption[x] when
897 897 \ loader_color?=1) is available since we would not have been
898 898 \ called if the caption was NULL.
899 899
900 900 \ base name of environment variable
901 901 dup ( n -- n n ) \ key pressed
902 902 loader_color? if
903 903 ansi_caption[x]
904 904 else
905 905 menu_caption[x]
906 906 then
907 907 getenv dup -1 <> if
908 908
909 909 2 pick ( n c-addr/u -- n c-addr/u n )
910 910 init_textN ( n c-addr/u n -- n c-addr/u c-addr )
911 911
912 912 \ now we have the buffer c-addr on top
913 913 \ ( followed by c-addr/u of current caption )
914 914
915 915 \ Copy the current caption into our buffer
916 916 2dup c! -rot \ store strlen at first byte
917 917 begin
918 918 rot 1+ \ bring alt addr to top and increment
919 919 -rot -rot \ bring buffer addr to top
920 920 2dup c@ swap c! \ copy current character
921 921 1+ \ increment buffer addr
922 922 rot 1- \ bring buffer len to top and decrement
923 923 dup 0= \ exit loop if buffer len is zero
924 924 until
925 925 2drop \ buffer len/addr
926 926 drop \ alt addr
927 927
928 928 else
929 929 drop
930 930 then
931 931 then
932 932
933 933 \ Now we are certain to have init_textN populated with the initial
934 934 \ value of menu_caption[x] (ansi_caption[x] with loader_color enabled).
935 935 \ We can now use init_textN as the untoggled caption and
936 936 \ toggled_text[x] (toggled_ansi[x] with loader_color enabled) as the
937 937 \ toggled caption and store the appropriate value into menu_caption[x]
938 938 \ (again, ansi_caption[x] with loader_color enabled). Last, we'll
939 939 \ negate the toggled state so that we reverse the flow on subsequent
940 940 \ calls.
941 941
942 942 dup toggle_stateN @ 0= if
943 943 \ state is OFF, toggle to ON
944 944
945 945 dup ( n -- n n ) \ key pressed
946 946 loader_color? if
947 947 toggled_ansi[x]
948 948 else
949 949 toggled_text[x]
950 950 then
951 951 getenv dup -1 <> if
952 952 \ Assign toggled text to menu caption
953 953 2 pick ( n c-addr/u -- n c-addr/u n ) \ key pressed
954 954 loader_color? if
955 955 ansi_caption[x]
956 956 else
957 957 menu_caption[x]
958 958 then
959 959 setenv
960 960 else
961 961 \ No toggled text, keep the same caption
962 962 drop ( n -1 -- n ) \ getenv cruft
963 963 then
964 964
965 965 true \ new value of toggle state var (to be stored later)
966 966 else
967 967 \ state is ON, toggle to OFF
968 968
969 969 dup init_textN count ( n -- n c-addr/u )
970 970
971 971 \ Assign init_textN text to menu caption
972 972 2 pick ( n c-addr/u -- n c-addr/u n ) \ key pressed
973 973 loader_color? if
974 974 ansi_caption[x]
975 975 else
976 976 menu_caption[x]
977 977 then
978 978 setenv
979 979
980 980 false \ new value of toggle state var (to be stored below)
981 981 then
982 982
983 983 \ now we'll store the new toggle state (on top of stack)
984 984 over toggle_stateN !
985 985 ;
986 986
987 987 : cycle_menuitem ( N -- N ) \ cycles through array of choices for a menuitem
988 988
989 989 \ ASCII numeral equal to user-selected menu item must be on the stack.
990 990 \ We do not modify the stack, so the ASCII numeral is left on top.
991 991
992 992 dup cycle_stateN dup @ 1+ \ get value and increment
993 993
994 994 \ Before assigning the (incremented) value back to the pointer,
995 995 \ let's test for the existence of this particular array element.
996 996 \ If the element exists, we'll store index value and move on.
997 997 \ Otherwise, we'll loop around to zero and store that.
998 998
999 999 dup 48 + ( n addr k -- n addr k k' )
1000 1000 \ duplicate array index and convert to ASCII numeral
1001 1001
1002 1002 3 pick swap ( n addr k k' -- n addr k n k' ) \ (n,k') as (x,y)
1003 1003 loader_color? if
1004 1004 ansi_caption[x][y]
1005 1005 else
1006 1006 menu_caption[x][y]
1007 1007 then
1008 1008 ( n addr k n k' -- n addr k c-addr/u )
1009 1009
1010 1010 \ Now test for the existence of our incremented array index in the
1011 1011 \ form of $menu_caption[x][y] ($ansi_caption[x][y] with loader_color
1012 1012 \ enabled) as set in loader.rc(5), et. al.
1013 1013
1014 1014 getenv dup -1 = if
1015 1015 \ No caption set for this array index. Loop back to zero.
1016 1016
1017 1017 drop ( n addr k -1 -- n addr k ) \ getenv cruft
1018 1018 drop 0 ( n addr k -- n addr 0 ) \ new value to store later
1019 1019
1020 1020 2 pick [char] 0 ( n addr 0 -- n addr 0 n 48 ) \ (n,48) as (x,y)
1021 1021 loader_color? if
1022 1022 ansi_caption[x][y]
1023 1023 else
1024 1024 menu_caption[x][y]
1025 1025 then
1026 1026 ( n addr 0 n 48 -- n addr 0 c-addr/u )
1027 1027 getenv dup -1 = if
1028 1028 \ Highly unlikely to occur, but to ensure things move
1029 1029 \ along smoothly, allocate a temporary NULL string
1030 1030 drop ( cruft ) s" "
1031 1031 then
1032 1032 then
1033 1033
1034 1034 \ At this point, we should have the following on the stack (in order,
1035 1035 \ from bottom to top):
1036 1036 \
1037 1037 \ n - Ascii numeral representing the menu choice (inherited)
1038 1038 \ addr - address of our internal cycle_stateN variable
1039 1039 \ k - zero-based number we intend to store to the above
1040 1040 \ c-addr/u - string value we intend to store to menu_caption[x]
1041 1041 \ (or ansi_caption[x] with loader_color enabled)
1042 1042 \
1043 1043 \ Let's perform what we need to with the above.
1044 1044
1045 1045 \ Assign array value text to menu caption
1046 1046 4 pick ( n addr k c-addr/u -- n addr k c-addr/u n )
1047 1047 loader_color? if
1048 1048 ansi_caption[x]
1049 1049 else
1050 1050 menu_caption[x]
1051 1051 then
1052 1052 setenv
1053 1053
1054 1054 swap ! ( n addr k -- n ) \ update array state variable
1055 1055 ;
1056 1056
1057 1057 only forth definitions also menu-infrastructure
1058 1058
1059 1059 \ Erase and redraw the menu. Useful if you change a caption and want to
1060 1060 \ update the menu to reflect the new value.
1061 1061 \
1062 1062 : menu-redraw ( -- )
1063 1063 menu-erase
1064 1064 menu-create
1065 1065 ;
1066 1066
1067 1067 \ This function initializes the menu. Call this from your `loader.rc' file
1068 1068 \ before calling any other menu-related functions.
1069 1069 \
1070 1070 : menu-init ( -- )
1071 1071 menu_start
1072 1072 1- menuidx ! \ Initialize the starting index for the menu
1073 1073 0 menurow ! \ Initialize the starting position for the menu
1074 1074
1075 1075 \ Assign configuration values
1076 1076 s" loader_menu_y" getenv dup -1 = if
1077 1077 drop \ no custom row position
1078 1078 menu_default_y
1079 1079 else
1080 1080 \ make sure custom position is a number
1081 1081 ?number 0= if
1082 1082 menu_default_y \ or use default
1083 1083 then
1084 1084 then
1085 1085 menuY !
1086 1086 s" loader_menu_x" getenv dup -1 = if
1087 1087 drop \ no custom column position
1088 1088 menu_default_x
1089 1089 else
1090 1090 \ make sure custom position is a number
1091 1091 ?number 0= if
1092 1092 menu_default_x \ or use default
1093 1093 then
1094 1094 then
1095 1095 menuX !
1096 1096
1097 1097 \ Interpret a custom frame type for the menu
1098 1098 TRUE ( draw a box? default yes, but might be altered below )
1099 1099 s" loader_menu_frame" getenv dup -1 = if ( 1 )
1100 1100 drop \ no custom frame type
1101 1101 else ( 1 ) 2dup s" single" compare-insensitive 0= if ( 2 )
1102 1102 f_single ( see frames.4th )
1103 1103 else ( 2 ) 2dup s" double" compare-insensitive 0= if ( 3 )
1104 1104 f_double ( see frames.4th )
1105 1105 else ( 3 ) s" none" compare-insensitive 0= if ( 4 )
1106 1106 drop FALSE \ don't draw a box
1107 1107 ( 4 ) then ( 3 ) then ( 2 ) then ( 1 ) then
1108 1108 if
1109 1109 42 13 menuX @ 3 - menuY @ 1- box \ Draw frame (w,h,x,y)
1110 1110 then
1111 1111
1112 1112 0 25 at-xy \ Move cursor to the bottom for output
1113 1113 ;
1114 1114
1115 1115 also menu-namespace
1116 1116
1117 1117 \ Main function. Call this from your `loader.rc' file.
1118 1118 \
1119 1119 : menu-display ( -- )
1120 1120
1121 1121 0 menu_timeout_enabled ! \ start with automatic timeout disabled
1122 1122
1123 1123 \ check indication that automatic execution after delay is requested
1124 1124 s" menu_timeout_command" getenv -1 <> if ( Addr C -1 -- | Addr )
1125 1125 drop ( just testing existence right now: Addr -- )
1126 1126
1127 1127 \ initialize state variables
1128 1128 seconds menu_time ! ( store the time we started )
1129 1129 1 menu_timeout_enabled ! ( enable automatic timeout )
1130 1130
1131 1131 \ read custom time-duration (if set)
1132 1132 s" autoboot_delay" getenv dup -1 = if
1133 1133 drop \ no custom duration (remove dup'd bunk -1)
1134 1134 menu_timeout_default \ use default setting
1135 1135 else
1136 1136 2dup ?number 0= if ( if not a number )
1137 1137 \ disable timeout if "NO", else use default
1138 1138 s" NO" compare-insensitive 0= if
1139 1139 0 menu_timeout_enabled !
1140 1140 0 ( assigned to menu_timeout below )
1141 1141 else
1142 1142 menu_timeout_default
1143 1143 then
1144 1144 else
1145 1145 -rot 2drop
1146 1146
1147 1147 \ boot immediately if less than zero
1148 1148 dup 0< if
1149 1149 drop
1150 1150 menu-create
1151 1151 0 25 at-xy
1152 1152 0 boot
1153 1153 then
1154 1154 then
1155 1155 then
1156 1156 menu_timeout ! ( store value on stack from above )
1157 1157
1158 1158 menu_timeout_enabled @ 1 = if
1159 1159 \ read custom column position (if set)
1160 1160 s" loader_menu_timeout_x" getenv dup -1 = if
1161 1161 drop \ no custom column position
1162 1162 menu_timeout_default_x \ use default setting
1163 1163 else
1164 1164 \ make sure custom position is a number
1165 1165 ?number 0= if
1166 1166 menu_timeout_default_x \ or use default
1167 1167 then
1168 1168 then
1169 1169 menu_timeout_x ! ( store value on stack from above )
1170 1170
1171 1171 \ read custom row position (if set)
1172 1172 s" loader_menu_timeout_y" getenv dup -1 = if
1173 1173 drop \ no custom row position
1174 1174 menu_timeout_default_y \ use default setting
1175 1175 else
1176 1176 \ make sure custom position is a number
1177 1177 ?number 0= if
1178 1178 menu_timeout_default_y \ or use default
1179 1179 then
1180 1180 then
1181 1181 menu_timeout_y ! ( store value on stack from above )
1182 1182 then
1183 1183 then
1184 1184
1185 1185 menu-create
1186 1186
1187 1187 begin \ Loop forever
1188 1188
1189 1189 0 25 at-xy \ Move cursor to the bottom for output
1190 1190 getkey \ Block here, waiting for a key to be pressed
1191 1191
1192 1192 dup -1 = if
1193 1193 drop exit \ Caught abort (abnormal return)
1194 1194 then
1195 1195
1196 1196 \ Boot if the user pressed Enter/Ctrl-M (13) or
1197 1197 \ Ctrl-Enter/Ctrl-J (10)
1198 1198 dup over 13 = swap 10 = or if
1199 1199 drop ( no longer needed )
1200 1200 s" boot" evaluate
1201 1201 exit ( pedantic; never reached )
1202 1202 then
1203 1203
1204 1204 dup menureboot @ = if 0 reboot then
1205 1205
1206 1206 \ Evaluate the decimal ASCII value against known menu item
1207 1207 \ key associations and act accordingly
1208 1208
1209 1209 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8')
1210 1210 begin
1211 1211 dup menukeyN @
1212 1212 rot tuck = if
1213 1213
1214 1214 \ Adjust for missing ACPI menuitem on non-i386
1215 1215 \ arch-i386? true <> menuacpi @ 0<> and if
1216 1216 \ menuacpi @ over 2dup < -rot = or
1217 1217 \ over 58 < and if
1218 1218 \ ( key >= menuacpi && key < 58: N -- N )
1219 1219 \ 1+
1220 1220 \ then
1221 1221 \ then
1222 1222
1223 1223 \ Test for the environment variable
1224 1224 dup menu_command[x]
1225 1225 getenv dup -1 <> if
1226 1226 \ Execute the stored procedure
1227 1227 evaluate
1228 1228
1229 1229 \ We expect there to be a non-zero
1230 1230 \ value left on the stack after
1231 1231 \ executing the stored procedure.
1232 1232 \ If so, continue to run, else exit.
1233 1233
1234 1234 0= if
1235 1235 drop \ key pressed
1236 1236 drop \ loop iterator
1237 1237 exit
1238 1238 else
1239 1239 swap \ need iterator on top
1240 1240 then
1241 1241 then
1242 1242
1243 1243 \ Re-adjust for missing ACPI menuitem
1244 1244 \ arch-i386? true <> menuacpi @ 0<> and if
1245 1245 \ swap
1246 1246 \ menuacpi @ 1+ over 2dup < -rot = or
1247 1247 \ over 59 < and if
1248 1248 \ 1-
1249 1249 \ then
1250 1250 \ swap
1251 1251 \ then
1252 1252 else
1253 1253 swap \ need iterator on top
1254 1254 then
1255 1255
1256 1256 \
1257 1257 \ Check for menu keycode shortcut(s)
1258 1258 \
1259 1259 dup menu_keycode[x]
1260 1260 getenv dup -1 = if
1261 1261 drop
1262 1262 else
1263 1263 ?number 0<> if
1264 1264 rot tuck = if
1265 1265 swap
1266 1266 dup menu_command[x]
1267 1267 getenv dup -1 <> if
1268 1268 evaluate
1269 1269 0= if
1270 1270 2drop
1271 1271 exit
1272 1272 then
1273 1273 else
1274 1274 drop
1275 1275 then
1276 1276 else
1277 1277 swap
1278 1278 then
1279 1279 then
1280 1280 then
1281 1281
1282 1282 1+ dup 56 > \ increment iterator
1283 1283 \ continue if less than 57
1284 1284 until
1285 1285 drop \ loop iterator
1286 1286 drop \ key pressed
1287 1287
1288 1288 again \ Non-operational key was pressed; repeat
1289 1289 ;
1290 1290
1291 1291 \ This function unsets all the possible environment variables associated with
1292 1292 \ creating the interactive menu.
1293 1293 \
1294 1294 : menu-unset ( -- )
1295 1295
1296 1296 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8')
1297 1297 begin
1298 1298 dup menu_init[x] unsetenv \ menu initializer
1299 1299 dup menu_command[x] unsetenv \ menu command
1300 1300 dup menu_caption[x] unsetenv \ menu caption
1301 1301 dup ansi_caption[x] unsetenv \ ANSI caption
1302 1302 dup menu_keycode[x] unsetenv \ menu keycode
1303 1303 dup toggled_text[x] unsetenv \ toggle_menuitem caption
1304 1304 dup toggled_ansi[x] unsetenv \ toggle_menuitem ANSI caption
1305 1305
1306 1306 48 \ Iterator start (inner range 48 to 57; ASCII '0' to '9')
1307 1307 begin
1308 1308 \ cycle_menuitem caption and ANSI caption
1309 1309 2dup menu_caption[x][y] unsetenv
1310 1310 2dup ansi_caption[x][y] unsetenv
1311 1311 1+ dup 57 >
1312 1312 until
1313 1313 drop \ inner iterator
1314 1314
1315 1315 0 over menukeyN ! \ used by menu-create, menu-display
1316 1316 0 over init_stateN ! \ used by menu-create
1317 1317 0 over toggle_stateN ! \ used by toggle_menuitem
1318 1318 0 over init_textN c! \ used by toggle_menuitem
1319 1319 0 over cycle_stateN ! \ used by cycle_menuitem
1320 1320
1321 1321 1+ dup 56 > \ increment, continue if less than 57
1322 1322 until
1323 1323 drop \ iterator
1324 1324
1325 1325 s" menu_timeout_command" unsetenv \ menu timeout command
1326 1326 s" menu_reboot" unsetenv \ Reboot menu option flag
1327 1327 s" menu_acpi" unsetenv \ ACPI menu option flag
1328 1328 s" menu_osconsole" unsetenv \ osconsole menu option flag
1329 1329 s" menu_kernel" unsetenv \ Kernel menu option flag
1330 1330 s" menu_options" unsetenv \ Options separator flag
1331 1331 s" menu_optionstext" unsetenv \ separator display text
1332 1332 s" menu_init" unsetenv \ menu initializer
1333 1333
1334 1334 0 menureboot !
1335 1335 0 menuacpi !
1336 1336 0 menuosconsole !
1337 1337 0 menuoptions !
1338 1338 ;
1339 1339
1340 1340 only forth definitions also menu-infrastructure
1341 1341
1342 1342 \ This function both unsets menu variables and visually erases the menu area
1343 1343 \ in-preparation for another menu.
1344 1344 \
1345 1345 : menu-clear ( -- )
1346 1346 menu-unset
1347 1347 menu-erase
1348 1348 ;
1349 1349
1350 1350 bullet menubllt !
1351 1351
1352 1352 also menu-namespace
1353 1353
1354 1354 \ Initialize our menu initialization state variables
1355 1355 0 init_state1 !
1356 1356 0 init_state2 !
1357 1357 0 init_state3 !
1358 1358 0 init_state4 !
1359 1359 0 init_state5 !
1360 1360 0 init_state6 !
1361 1361 0 init_state7 !
1362 1362 0 init_state8 !
1363 1363
1364 1364 \ Initialize our boolean state variables
1365 1365 0 toggle_state1 !
1366 1366 0 toggle_state2 !
1367 1367 0 toggle_state3 !
1368 1368 0 toggle_state4 !
1369 1369 0 toggle_state5 !
1370 1370 0 toggle_state6 !
1371 1371 0 toggle_state7 !
1372 1372 0 toggle_state8 !
1373 1373
1374 1374 \ Initialize our array state variables
1375 1375 0 cycle_state1 !
1376 1376 0 cycle_state2 !
1377 1377 0 cycle_state3 !
1378 1378 0 cycle_state4 !
1379 1379 0 cycle_state5 !
1380 1380 0 cycle_state6 !
1381 1381 0 cycle_state7 !
1382 1382 0 cycle_state8 !
1383 1383
1384 1384 \ Initialize string containers
1385 1385 0 init_text1 c!
1386 1386 0 init_text2 c!
1387 1387 0 init_text3 c!
1388 1388 0 init_text4 c!
1389 1389 0 init_text5 c!
1390 1390 0 init_text6 c!
1391 1391 0 init_text7 c!
1392 1392 0 init_text8 c!
1393 1393
1394 1394 only forth definitions
|
↓ open down ↓ |
894 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX