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

Last change on this file since 599 was 599, checked in by aitotat, 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.