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

Last change on this file since 600 was 600, checked in by Tomi Tilli, 6 years ago

Hotkeybar timer tick handler now keeps interrupts disabled and updates on every fourth call.

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