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

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

Hotkey bar is now updated and drawn from system timer tick handler 1Ch. This gives much more responsive key input and makes possible to implement some simple detection animation to show that system has not frozen.

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