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
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;--------------------------------------------------------------------
[599]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;--------------------------------------------------------------------
[528]89; Scans key presses and draws any hotkey changes.
90;
[392]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;--------------------------------------------------------------------
[599]100UpdateDuringDriveDetection:
[528]101    call    ScanHotkeysFromKeyBufferAndStoreToBootvars
[599]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   
[392]109    ; Fall to HotkeyBar_DrawToTopOfScreen
[505]110
111
[392]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
[568]143    xchg    cx, ax      ; Any Floppy Drives?
144    jcxz    .SkipFloppyDriveHotkeys
[392]145
[492]146    mov     ax, (ANGLE_QUOTE_RIGHT << 8) | DEFAULT_FLOPPY_DRIVE_LETTER
[500]147    mov     cl, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bFddLetter]
[492]148    mov     di, g_szFDD
[593]149
150    ; Clear CH if floppy drive is selected for boot
151    mov     ch, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bFlags]
[599]152    and     ch, FLG_HOTKEY_HD_FIRST
[392]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;--------------------------------------------------------------------
[547]168    call    BootVars_GetLetterForFirstHardDriveToAX
[392]169    mov     ah, ANGLE_QUOTE_RIGHT
[596]170    mov     cx, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.wHddLetterAndFlags]  ; Letter to CL, flags to CH
[599]171    and     ch, FLG_HOTKEY_HD_FIRST
[593]172    xor     ch, FLG_HOTKEY_HD_FIRST     ; Clear CH if HD is selected for boot, set otherwise
[492]173    mov     di, g_szHDD
[392]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
[492]188    mov     ax, BOOT_MENU_HOTKEY_SCANCODE | ('2' << 8)
189    mov     di, g_szBootMenu
[392]190    call    FormatFunctionHotkeyString
191%endif
[492]192    ; Fall to .PrintComDetectHotkey
[392]193
194;--------------------------------------------------------------------
[492]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
[505]209    ; Fall to .PrintRomBootHotkey
[492]210
211;--------------------------------------------------------------------
[392]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:
[492]221    mov     ax, ROM_BOOT_HOTKEY_SCANCODE | ('8' << 8)
222    mov     di, g_szRomBoot
[392]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:
[505]251    CALL_DISPLAY_LIBRARY GetColumnsToALandRowsToAH
[392]252    eMOVZX  cx, al
[505]253    CALL_DISPLAY_LIBRARY GetSoftwareCoordinatesToAX
[392]254    sub     cl, al
255    mov     al, ' '
[505]256    JMP_DISPLAY_LIBRARY PrintRepeatedCharacterFromALwithCountInCX
[392]257
258
259;--------------------------------------------------------------------
260; FormatDriveHotkeyString
261;   Parameters:
[593]262;       CH:         Zero if letter in CL is selected for boot
[392]263;       CL:         Drive letter hotkey from BOOTVARS
[492]264;       AL:         First character for drive key string
265;       AH:         Second character for drive key string (ANGLE_QUOTE_RIGHT)
[392]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;--------------------------------------------------------------------
[593]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
[392]279
[593]280    ; Drive selected to boot from?
281    test    ch, ch
282    jnz     SHORT GetNonSelectedHotkeyDescriptionAttributeToDX
283    jmp     SHORT GetSelectedHotkeyDescriptionAttributeToDX
284
285
[392]286;--------------------------------------------------------------------
287; FormatFunctionHotkeyString
288;   Parameters:
[492]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
[392]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:
[492]300    xor     cx, cx      ; Null character, eaten in output routines
[392]301
[492]302    cmp     [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode], al
303    mov     al, 'F'     ; Replace scancode with character for output
[392]304
305%ifdef MODULE_BOOT_MENU
[492]306
[593]307GetSelectedHotkeyDescriptionAttributeToDX:
[596]308    mov     si, ATTRIBUTE_CHARS.cHighlightedItem    ; Selected hotkey
[593]309    je      SHORT GetDescriptionAttributeToDX       ; From compare with bScancode above and from FormatDriveHotkeyString
[392]310
311GetNonSelectedHotkeyDescriptionAttributeToDX:
[596]312    mov     si, ATTRIBUTE_CHARS.cItem               ; Unselected hotkey
[392]313
314    ; Display Library should not be called like this
315GetDescriptionAttributeToDX:
[492]316    xchg    dx, ax
[392]317    call    MenuAttribute_GetToAXfromTypeInSI
318    xchg    dx, ax                  ; DX = Description attribute
[505]319    ;;  fall through to PushHotkeyParamsAndFormat
[392]320
321
[500]322%else ; if no MODULE_BOOT_MENU - No boot menu so use simpler attributes
323
[593]324GetSelectedHotkeyDescriptionAttributeToDX:
[410]325    mov     dx, (COLOR_ATTRIBUTE(COLOR_YELLOW, COLOR_CYAN) << 8) | MONO_REVERSE_BLINK
[593]326    je      SHORT SelectAttributeFromDHorDLbasedOnVideoMode     ; From compare with bScancode above and from FormatDriveHotkeyString
[392]327
328GetNonSelectedHotkeyDescriptionAttributeToDX:
[410]329    mov     dx, (COLOR_ATTRIBUTE(COLOR_BLACK, COLOR_CYAN) << 8) | MONO_REVERSE
[492]330
[410]331SelectAttributeFromDHorDLbasedOnVideoMode:
[500]332    mov     ch, [es:BDA.bVidMode]       ; We only need to preserve CL
333    shr     ch, 1
[410]334    jnc     SHORT .AttributeLoadedToDL  ; Black & White modes
[500]335    shr     ch, 1
[410]336    jnz     SHORT .AttributeLoadedToDL  ; MDA
337    mov     dl, dh
338.AttributeLoadedToDL:
[505]339    ;;  fall through to PushHotkeyParamsAndFormat
[410]340
[492]341%endif ; MODULE_BOOT_MENU
[392]342
343
344;--------------------------------------------------------------------
345; PushHotkeyParamsAndFormat
346;   Parameters:
[500]347;       AL:         First character
348;       AH:         Second character
[392]349;       DX:         Description Attribute
350;       CX:         Description string parameter
[492]351;       CS:DI:      Description string
[392]352;   Returns:
353;       Nothing
354;   Corrupts registers:
355;       AX, SI, DI
356;--------------------------------------------------------------------
357PushHotkeyParamsAndFormat:
358    push    bp
359    mov     bp, sp
360
[492]361    mov     si, MONO_BRIGHT
[392]362
[492]363    push    si              ; Key attribute
364    push    ax              ; First Character
365    mov     al, ah
366    push    ax              ; Second Character
367
[392]368    push    dx              ; Description attribute
[492]369    push    di              ; Description string
[392]370    push    cx              ; Description string parameter
[505]371
[492]372    push    si              ; Key attribute for last space
[392]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:
[505]402    JMP_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
[392]403
404
405;--------------------------------------------------------------------
[599]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;--------------------------------------------------------------------
[528]460; HotkeyBar_StoreHotkeyToBootvarsForDriveNumberInDL
[395]461;   Parameters:
462;       DS:     RAMVARS segment
463;       ES:     BDA segment (zero)
[528]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)
[395]480;       DL:     Drive Letter ('A'...)
481;   Returns:
482;       Nothing
483;   Corrupts registers:
484;       AX, CX, DI
485;--------------------------------------------------------------------
[528]486StoreHotkeyToBootvarsForDriveLetterInDL:
[395]487    eMOVZX  ax, dl
[505]488    or      al, 32  ; Upper case drive letter to lower case keystroke
[395]489    jmp     SHORT HotkeyBar_StoreHotkeyToBootvarsIfValidKeystrokeInAX
490
491
492;--------------------------------------------------------------------
[528]493; ScanHotkeysFromKeyBufferAndStoreToBootvars
[392]494;   Parameters:
495;       DS:     RAMVARS segment
496;       ES:     BDA segment (zero)
497;   Returns:
[492]498;       AL:     Last scancode value
[392]499;   Corrupts registers:
[492]500;       AH, CX
[392]501;--------------------------------------------------------------------
[528]502ScanHotkeysFromKeyBufferAndStoreToBootvars:
[392]503    call    Keyboard_GetKeystrokeToAX
504    jz      SHORT NoHotkeyToProcess
505
[528]506    ; Prepare to read another key from buffer
507    ePUSH_T cx, ScanHotkeysFromKeyBufferAndStoreToBootvars
[392]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:
[567]519;       AL:     Last scancode seen
[528]520;       CF:     Set if valid hotkey in AL
521;               Clear if scancode in AL is not for any hotkey
[392]522;   Corrupts registers:
[492]523;       AH, CX, DI
[392]524;--------------------------------------------------------------------
525HotkeyBar_StoreHotkeyToBootvarsIfValidKeystrokeInAX:
[492]526    mov     di, BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode
[392]527
[492]528    ; All scancodes are saved, even if it wasn't a drive letter,
529    ; which also covers our function key case.  Invalid function keys
[505]530    ; will not do anything (won't be printed, won't be accepted as input)
[492]531    mov     [es:di], ah
[505]532
[392]533    ; Drive letter hotkeys remaining, allow 'a' to 'z'
534    call    Char_IsLowerCaseLetterInAL
[492]535    jnc     SHORT .KeystrokeIsNotValidDriveLetter
[505]536    and     al, ~32                 ; We want to print upper case letters
[392]537
538    ; Clear HD First flag to assume Floppy Drive hotkey
[492]539    dec     di
[392]540    and     BYTE [es:di], ~FLG_HOTKEY_HD_FIRST
541
542    ; Determine if Floppy or Hard Drive hotkey
[505]543    xchg    cx, ax
[547]544    call    BootVars_GetLetterForFirstHardDriveToAX
[392]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:
[505]552    sbb     di, BYTE 1              ; Sub CF if Floppy Drive
[392]553    xchg    ax, cx
[592]554    stosb
[528]555    stc                             ; Valid hotkey scancode returned in AL
[392]556
[505]557.KeystrokeIsNotValidDriveLetter:
[392]558NoHotkeyToProcess:
[492]559    mov     al, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode]
[392]560    ret
561
[528]562
[392]563;--------------------------------------------------------------------
[492]564; HotkeyBar_GetBootDriveNumbersToDX
[392]565;   Parameters:
566;       DS:     RAMVARS segment
567;       ES:     BDA segment (zero)
568;   Returns:
[492]569;       DX:     Drives selected as boot device, DL is primary
[392]570;   Corrupts registers:
[492]571;       AX
[392]572;--------------------------------------------------------------------
[492]573HotkeyBar_GetBootDriveNumbersToDX:
[500]574    mov     dx, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.wFddAndHddLetters]
[505]575    test    BYTE [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bFlags], FLG_HOTKEY_HD_FIRST
[492]576    jnz     .noflip
[392]577    xchg    dl, dh
[505]578.noflip:
[492]579    call    DriveXlate_ConvertDriveLetterInDLtoDriveNumber
580    xchg    dl, dh
[505]581    ; Fall to HotkeyBar_FallThroughTo_DriveXlate_ConvertDriveLetterInDLtoDriveNumber
[392]582
[505]583HotkeyBar_FallThroughTo_DriveXlate_ConvertDriveLetterInDLtoDriveNumber:
584
Note: See TracBrowser for help on using the repository browser.