source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Menus/HotkeyBar.asm@ 603

Last change on this file since 603 was 603, checked in by Krister Nordvall, 4 years ago

Changes:

  • Fixed a bug in Strings.asm from r589 where building the BIOS without MODULE_STRINGS_COMPRESSED would fail. Also removed a redundant CR to save a byte when building without MODULE_STRINGS_COMPRESSED.
  • Optimized the code in MODULE_HOTKEYS to reduce ROM space usage, stack usage and time spent in the user timer tick interrupt handler (1Ch). I hope this will fix the problem with hangs introduced in r599.
File size: 17.4 KB
Line 
1; Project name : XTIDE Universal BIOS
2; Description : Hotkey Bar related functions.
3
4;
5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2 of the License, or
11; (at your option) any later version.
12;
13; This program is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16; GNU General Public License for more details.
17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18;
19
20; Section containing code
21SECTION .text
22
23
24;--------------------------------------------------------------------
25; Handler for INT 1Ch User Timer Tick.
26; Reads key presses and draws hotkey bar.
27;
28; HotkeyBar_TimerTickHandler
29; Parameters:
30; Nothing
31; Returns:
32; Nothing
33; Corrupts registers:
34; Nothing
35;--------------------------------------------------------------------
36ALIGN JUMP_ALIGN
37HotkeyBar_TimerTickHandler:
38 push es
39%ifndef USE_186 ; LOAD_BDA_SEGMENT_TO will corrupt AX on 8088/8086
40 push ax
41%endif
42
43 ;!!! Keep interrupts disabled so there won't be another
44 ; timer tick call before we are ready
45
46 LOAD_BDA_SEGMENT_TO es, ax
47
48 ; Call previous handler
49 pushf
50 call FAR [es:BOOTVARS.hotkeyVars+HOTKEYVARS.fpPrevTimerHandler]
51
52 ; Update Hotkeybar (process key input and draw) every fourth tick
53 test BYTE [es:BDA.dwTimerTicks], 11b
54 jnz SHORT .ReturnFromHandler
55
56 push ds
57%ifdef USE_186
58 pusha
59%else
60 push di
61 push si
62 push dx
63 push cx
64%endif
65 call RamVars_GetSegmentToDS
66 call HotkeyBar_UpdateDuringDriveDetection
67%ifdef USE_186
68 popa
69%else
70 pop cx
71 pop dx
72 pop si
73 pop di
74%endif
75 pop ds
76
77.ReturnFromHandler:
78%ifndef USE_186
79 pop ax
80%endif
81 pop es
82 iret
83
84
85;--------------------------------------------------------------------
86; Scans key presses and draws any hotkey changes.
87;
88; HotkeyBar_UpdateDuringDriveDetection
89; Parameters:
90; DS: RAMVARS segment
91; ES: BDA segment (zero)
92; Returns:
93; Nothing
94; Corrupts registers:
95; AX, CX, DX, SI, DI
96;--------------------------------------------------------------------
97HotkeyBar_UpdateDuringDriveDetection:
98 call ScanHotkeysFromKeyBufferAndStoreToBootvars
99
100 ; If ESC pressed, abort detection by forcing timeout
101 cmp al, ESC_SCANCODE
102 jne SHORT .ContinueDrawing
103 mov BYTE [RAMVARS.bTimeoutTicksLeft], 0
104.ContinueDrawing:
105 ; Fall to HotkeyBar_DrawToTopOfScreen
106
107
108;--------------------------------------------------------------------
109; HotkeyBar_DrawToTopOfScreen
110; Parameters:
111; DS: RAMVARS segment
112; ES: BDA segment (zero)
113; Returns:
114; Nothing
115; Corrupts registers:
116; AX, CX, DX, SI, DI
117;--------------------------------------------------------------------
118HotkeyBar_DrawToTopOfScreen:
119 ; Store current screen coordinates to stack
120 ; (to be restored when Hotkey Bar is rendered)
121 CALL_DISPLAY_LIBRARY GetSoftwareCoordinatesToAX
122 push ax
123
124 ; Move cursor to top left corner (0, 0)
125 xor ax, ax
126 call HotkeyBar_SetCursorCoordinatesFromAX
127 ; Fall to .PrintFloppyDriveHotkeys
128
129;--------------------------------------------------------------------
130; .PrintFloppyDriveHotkeys
131; Parameters:
132; DS: RAMVARS segment
133; ES: BDA segment (zero)
134; Returns:
135; Nothing
136; Corrupts registers:
137; AX, CX, DX, SI, DI
138;--------------------------------------------------------------------
139.PrintFloppyDriveHotkeys:
140 call FloppyDrive_GetCountToAX
141 xchg cx, ax ; Any Floppy Drives?
142 jcxz .SkipFloppyDriveHotkeys
143
144 mov ax, (ANGLE_QUOTE_RIGHT << 8) | DEFAULT_FLOPPY_DRIVE_LETTER
145 mov cl, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bFddLetter]
146 mov di, g_szFDD
147
148 ; Clear CH if floppy drive is selected for boot
149%if 0 ; Not needed until more flags added
150 mov ch, FLG_HOTKEY_HD_FIRST
151 and ch, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bFlags]
152%else
153 mov ch, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bFlags]
154%endif
155 call FormatDriveHotkeyString
156
157.SkipFloppyDriveHotkeys:
158 ; Fall to .PrintHardDriveHotkeys
159
160;--------------------------------------------------------------------
161; .PrintHardDriveHotkeys
162; Parameters:
163; DS: RAMVARS segment
164; ES: BDA segment (zero)
165; Returns:
166; Nothing
167; Corrupts registers:
168; AX, CX, DX, SI, DI
169;--------------------------------------------------------------------
170 call BootVars_GetLetterForFirstHardDriveToAX
171 mov ah, ANGLE_QUOTE_RIGHT
172 mov cx, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.wHddLetterAndFlags] ; Letter to CL, flags to CH
173 ;and ch, FLG_HOTKEY_HD_FIRST ; Not needed until more flags added
174 xor ch, FLG_HOTKEY_HD_FIRST ; Clear CH if HD is selected for boot, set otherwise
175 mov di, g_szHDD
176 call FormatDriveHotkeyString
177 ; Fall to .PrintBootMenuHotkey
178
179;--------------------------------------------------------------------
180; .PrintBootMenuHotkey
181; Parameters:
182; ES: BDA segment (zero)
183; Returns:
184; Nothing
185; Corrupts registers:
186; AX, CX, DX, SI, DI
187;--------------------------------------------------------------------
188.PrintBootMenuHotkey:
189%ifdef MODULE_BOOT_MENU
190 mov ax, BOOT_MENU_HOTKEY_SCANCODE | ('2' << 8)
191 mov di, g_szBootMenu
192 call FormatFunctionHotkeyString
193%endif
194 ; Fall to .PrintComDetectHotkey
195
196;--------------------------------------------------------------------
197; .PrintComDetectHotkey
198; Parameters:
199; ES: BDA segment (zero)
200; Returns:
201; Nothing
202; Corrupts registers:
203; AX, CX, DX, SI, DI
204;--------------------------------------------------------------------
205.PrintComDetectHotkey:
206%ifdef MODULE_SERIAL
207 mov ax, COM_DETECT_HOTKEY_SCANCODE | ('6' << 8)
208 mov di, g_szHotComDetect
209 call FormatFunctionHotkeyString
210%endif
211 ; Fall to .PrintRomBootHotkey
212
213;--------------------------------------------------------------------
214; .PrintRomBootHotkey
215; Parameters:
216; ES: BDA segment (zero)
217; Returns:
218; Nothing
219; Corrupts registers:
220; AX, CX, DX, SI, DI
221;--------------------------------------------------------------------
222.PrintRomBootHotkey:
223 mov ax, ROM_BOOT_HOTKEY_SCANCODE | ('8' << 8)
224 mov di, g_szRomBoot
225 call FormatFunctionHotkeyString
226 ; Fall to .EndHotkeyBarRendering
227
228;--------------------------------------------------------------------
229; .EndHotkeyBarRendering
230; Parameters:
231; Stack: Screen coordinates before drawing Hotkey Bar
232; Returns:
233; Nothing
234; Corrupts registers:
235; AX, CX, DI
236;--------------------------------------------------------------------
237.EndHotkeyBarRendering:
238 ; Clear the rest of the top row
239 CALL_DISPLAY_LIBRARY GetColumnsToALandRowsToAH
240 eMOVZX cx, al
241 CALL_DISPLAY_LIBRARY GetSoftwareCoordinatesToAX
242 sub cl, al
243 mov al, ' '
244 CALL_DISPLAY_LIBRARY PrintRepeatedCharacterFromALwithCountInCX
245
246 ; Restore the saved coordinates from stack
247 pop ax
248 ; Fall to HotkeyBar_SetCursorCoordinatesFromAX
249
250
251;--------------------------------------------------------------------
252; HotkeyBar_SetCursorCoordinatesFromAX
253; Parameters:
254; Nothing
255; Returns:
256; Nothing
257; Corrupts registers:
258; AX, DI
259;--------------------------------------------------------------------
260HotkeyBar_SetCursorCoordinatesFromAX:
261 JMP_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
262
263
264;--------------------------------------------------------------------
265; FormatDriveHotkeyString
266; Parameters:
267; CH: Zero if letter in CL is selected for boot
268; CL: Drive letter hotkey from BOOTVARS
269; AL: First character for drive key string
270; AH: Second character for drive key string (ANGLE_QUOTE_RIGHT)
271; SI: Offset to hotkey description string
272; ES: BDA segment (zero)
273; Returns:
274; Nothing
275; Corrupts registers:
276; AX, CX, DX, SI, DI
277;--------------------------------------------------------------------
278FormatDriveHotkeyString:
279 ; Invalid scancodes are filtered on HotkeyBar_StoreHotkeyToBootvarsIfValidKeystrokeInAX
280 ; so here we have either drive letter or function key pressed. If latter, draw
281 ; drive letters as unselected
282 cmp BYTE [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode], FIRST_FUNCTION_KEY_SCANCODE
283 jae SHORT GetNonSelectedHotkeyDescriptionAttributeToDX
284
285 ; Drive selected to boot from?
286 test ch, ch
287 jnz SHORT GetNonSelectedHotkeyDescriptionAttributeToDX
288 jmp SHORT GetSelectedHotkeyDescriptionAttributeToDX
289
290
291;--------------------------------------------------------------------
292; FormatFunctionHotkeyString
293; Parameters:
294; AL: Scancode of function key, to know which if any to show as selected
295; Later replaced with an 'F' for the call to the output routine
296; AH: Second character for drive key string
297; SI: Offset to hotkey description string
298; ES: BDA segment (zero)
299; Returns:
300; Nothing
301; Corrupts registers:
302; AX, CX, DX, SI, DI
303;--------------------------------------------------------------------
304FormatFunctionHotkeyString:
305 xor cx, cx ; Null character, eaten in output routines
306
307 cmp [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode], al
308 mov al, 'F' ; Replace scancode with character for output
309
310%ifdef MODULE_BOOT_MENU
311
312GetSelectedHotkeyDescriptionAttributeToDX:
313 mov si, ATTRIBUTE_CHARS.cHighlightedItem ; Selected hotkey
314 je SHORT GetDescriptionAttributeToDX ; From compare with bScancode above and from FormatDriveHotkeyString
315
316GetNonSelectedHotkeyDescriptionAttributeToDX:
317 mov si, ATTRIBUTE_CHARS.cItem ; Unselected hotkey
318
319 ; Display Library should not be called like this
320GetDescriptionAttributeToDX:
321 xchg dx, ax
322 call MenuAttribute_GetToAXfromTypeInSI
323 xchg dx, ax ; DX = Description attribute
324 ;; fall through to PushHotkeyParamsAndFormat
325
326
327%else ; if no MODULE_BOOT_MENU - No boot menu so use simpler attributes
328
329GetSelectedHotkeyDescriptionAttributeToDX:
330 mov dx, (COLOR_ATTRIBUTE(COLOR_YELLOW, COLOR_CYAN) << 8) | MONO_REVERSE_BLINK
331 je SHORT SelectAttributeFromDHorDLbasedOnVideoMode ; From compare with bScancode above and from FormatDriveHotkeyString
332
333GetNonSelectedHotkeyDescriptionAttributeToDX:
334 mov dx, (COLOR_ATTRIBUTE(COLOR_BLACK, COLOR_CYAN) << 8) | MONO_REVERSE
335
336SelectAttributeFromDHorDLbasedOnVideoMode:
337 mov ch, [es:BDA.bVidMode] ; We only need to preserve CL
338 shr ch, 1
339 jnc SHORT .AttributeLoadedToDL ; Black & White modes
340 shr ch, 1
341 jnz SHORT .AttributeLoadedToDL ; MDA
342 mov dl, dh
343.AttributeLoadedToDL:
344 ;; fall through to PushHotkeyParamsAndFormat
345
346%endif ; MODULE_BOOT_MENU
347
348
349;--------------------------------------------------------------------
350; PushHotkeyParamsAndFormat
351; Parameters:
352; AL: First character
353; AH: Second character
354; DX: Description Attribute
355; CX: Description string parameter
356; CS:DI: Description string
357; Returns:
358; Nothing
359; Corrupts registers:
360; AX, SI, DI
361;--------------------------------------------------------------------
362PushHotkeyParamsAndFormat:
363 push bp
364 mov bp, sp
365
366 mov si, MONO_BRIGHT
367
368 push si ; Key attribute
369 push ax ; First Character
370 mov al, ah
371 push ax ; Second Character
372
373 push dx ; Description attribute
374 push di ; Description string
375 push cx ; Description string parameter
376
377 push si ; Key attribute for last space
378
379 mov si, g_szHotkey
380 jmp DetectPrint_FormatCSSIfromParamsInSSBP
381
382
383;--------------------------------------------------------------------
384; HotkeyBar_StoreDefaultDriveLettersToHotkeyVars
385; Parameters:
386; ES: BDA Segment
387; Returns:
388; Nothing
389; Corrupts registers:
390; AX
391;--------------------------------------------------------------------
392HotkeyBar_StoreDefaultDriveLettersToHotkeyVars:
393 call BootVars_GetLetterForFirstHardDriveToAX
394 mov ah, DEFAULT_FLOPPY_DRIVE_LETTER
395 xchg al, ah
396 mov [es:BOOTVARS.hotkeyVars+HOTKEYVARS.wFddAndHddLetters], ax
397 ret
398
399
400;--------------------------------------------------------------------
401; HotkeyBar_InitializeVariables
402; Parameters:
403; DS: RAMVARS Segment
404; ES: BDA Segment
405; Returns:
406; Nothing
407; Corrupts registers:
408; AX, CX, DX, DI
409;--------------------------------------------------------------------
410HotkeyBar_InitializeVariables:
411 push ds
412 push es
413 pop ds
414
415 ; Store system 1Ch Timer Tick handler and install our hotkeybar handler
416 mov ax, [BIOS_USER_TIMER_TICK_INTERRUPT_1Ch*4]
417 mov [BOOTVARS.hotkeyVars+HOTKEYVARS.fpPrevTimerHandler], ax
418 mov ax, [BIOS_USER_TIMER_TICK_INTERRUPT_1Ch*4+2]
419 mov [BOOTVARS.hotkeyVars+HOTKEYVARS.fpPrevTimerHandler+2], ax
420 mov al, BIOS_USER_TIMER_TICK_INTERRUPT_1Ch
421 mov si, HotkeyBar_TimerTickHandler
422 call Interrupts_InstallHandlerToVectorInALFromCSSI
423
424 ; Store time when hotkeybar is displayed
425 ; (it will be displayed after initialization is complete)
426 call TimerTicks_ReadFromBdaToAX
427 mov [BOOTVARS.hotkeyVars+HOTKEYVARS.wTimeWhenDisplayed], ax
428
429 pop ds
430
431 ; Initialize HOTKEYVARS by storing default drives to boot from
432 call HotkeyBar_StoreDefaultDriveLettersToHotkeyVars
433 mov dl, [cs:ROMVARS.bBootDrv]
434 ; Fall to HotkeyBar_StoreHotkeyToBootvarsForDriveNumberInDL
435
436
437;--------------------------------------------------------------------
438; HotkeyBar_StoreHotkeyToBootvarsForDriveNumberInDL
439; Parameters:
440; DS: RAMVARS segment
441; ES: BDA segment (zero)
442; DL: Drive Number
443; Returns:
444; Nothing
445; Corrupts registers:
446; AX, CX, DL, DI
447;--------------------------------------------------------------------
448HotkeyBar_StoreHotkeyToBootvarsForDriveNumberInDL:
449 call DriveXlate_ConvertDriveNumberFromDLtoDriveLetter
450 ; Fall to StoreHotkeyToBootvarsForDriveLetterInDL
451
452
453;--------------------------------------------------------------------
454; StoreHotkeyToBootvarsForDriveLetterInDL
455; Parameters:
456; DS: RAMVARS segment
457; ES: BDA segment (zero)
458; DL: Drive Letter ('A'...)
459; Returns:
460; Nothing
461; Corrupts registers:
462; AX, CX, DI
463;--------------------------------------------------------------------
464StoreHotkeyToBootvarsForDriveLetterInDL:
465 eMOVZX ax, dl
466 or al, 32 ; Upper case drive letter to lower case keystroke
467 jmp SHORT HotkeyBar_StoreHotkeyToBootvarsIfValidKeystrokeInAX
468
469
470;--------------------------------------------------------------------
471; ScanHotkeysFromKeyBufferAndStoreToBootvars
472; Parameters:
473; DS: RAMVARS segment
474; ES: BDA segment (zero)
475; Returns:
476; AL: Last scancode value
477; Corrupts registers:
478; AH, CX
479;--------------------------------------------------------------------
480ScanHotkeysFromKeyBufferAndStoreToBootvars:
481 call Keyboard_GetKeystrokeToAX
482 jz SHORT NoHotkeyToProcess
483
484 ; Prepare to read another key from buffer
485 ePUSH_T cx, ScanHotkeysFromKeyBufferAndStoreToBootvars
486 ; Fall to HotkeyBar_StoreHotkeyToBootvarsIfValidKeystrokeInAX
487
488
489;--------------------------------------------------------------------
490; HotkeyBar_StoreHotkeyToBootvarsIfValidKeystrokeInAX
491; Parameters:
492; AL: Hotkey ASCII code
493; AH: Hotkey Scancode
494; DS: RAMVARS segment
495; ES: BDA segment (zero)
496; Returns:
497; AL: Last scancode seen
498; CF: Set if valid hotkey in AL
499; Clear if scancode in AL is not for any hotkey
500; Corrupts registers:
501; AH, CX, DI
502;--------------------------------------------------------------------
503HotkeyBar_StoreHotkeyToBootvarsIfValidKeystrokeInAX:
504 mov di, BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode
505
506 ; All scancodes are saved, even if it wasn't a drive letter,
507 ; which also covers our function key case. Invalid function keys
508 ; will not do anything (won't be printed, won't be accepted as input)
509 mov [es:di], ah
510
511 ; Drive letter hotkeys remaining, allow 'a' to 'z'
512 call Char_IsLowerCaseLetterInAL
513 jnc SHORT .KeystrokeIsNotValidDriveLetter
514 and al, ~32 ; We want to print upper case letters
515
516 ; Clear HD First flag to assume Floppy Drive hotkey
517 dec di
518 and BYTE [es:di], ~FLG_HOTKEY_HD_FIRST
519
520 ; Determine if Floppy or Hard Drive hotkey
521 xchg cx, ax
522 call BootVars_GetLetterForFirstHardDriveToAX
523 cmp cl, al
524 jb SHORT .StoreDriveLetter ; Store Floppy Drive letter
525
526 ; Store Hard Drive letter
527 or BYTE [es:di], FLG_HOTKEY_HD_FIRST
528
529.StoreDriveLetter:
530 sbb di, BYTE 1 ; Sub CF if Floppy Drive
531 xchg ax, cx
532 stosb
533 stc ; Valid hotkey scancode returned in AL
534
535.KeystrokeIsNotValidDriveLetter:
536NoHotkeyToProcess:
537 mov al, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode]
538 ret
539
540
541;--------------------------------------------------------------------
542; HotkeyBar_GetBootDriveNumbersToDX
543; Parameters:
544; DS: RAMVARS segment
545; ES: BDA segment (zero)
546; Returns:
547; DX: Drives selected as boot device, DL is primary
548; Corrupts registers:
549; AX
550;--------------------------------------------------------------------
551HotkeyBar_GetBootDriveNumbersToDX:
552 mov dx, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.wFddAndHddLetters]
553
554 ; HotkeyBar_GetBootDriveNumbersToDX is called when all drives are detected and
555 ; drive letters are known.
556 ; Replace unavailable hard drive letter with first hard drive.
557 ; If we have boot menu, it will be displayed instead.
558%ifndef MODULE_BOOT_MENU
559 call BootVars_GetLetterForFirstHardDriveToAX
560 mov ah, al
561 add al, [es:BDA.bHDCount] ; AL now contains first unavailable HD letter
562 cmp dh, al ; Unavailable drive?
563 jb SHORT .ValidHardDriveLetterInDH
564 mov dh, ah ; Replace unavailable drive with first drive
565.ValidHardDriveLetterInDH:
566%endif
567
568 test BYTE [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bFlags], FLG_HOTKEY_HD_FIRST
569 jnz SHORT .noflip
570 xchg dl, dh
571.noflip:
572 call DriveXlate_ConvertDriveLetterInDLtoDriveNumber
573 xchg dl, dh
574 ; Fall to HotkeyBar_FallThroughTo_DriveXlate_ConvertDriveLetterInDLtoDriveNumber
575
576HotkeyBar_FallThroughTo_DriveXlate_ConvertDriveLetterInDLtoDriveNumber:
577
Note: See TracBrowser for help on using the repository browser.