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

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

Changes:

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