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

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

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

File size: 17.8 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
[600]50    ;!!! Keep interrupts disabled so there won't be another
51    ; timer tick call before we are ready
52
[599]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
[600]60    ; Update Hotkeybar (process key input and draw) every fourth tick
61    test    BYTE [es:BDA.dwTimerTicks], 11b
[599]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;--------------------------------------------------------------------
[528]81; Scans key presses and draws any hotkey changes.
82;
[392]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;--------------------------------------------------------------------
[599]92UpdateDuringDriveDetection:
[528]93    call    ScanHotkeysFromKeyBufferAndStoreToBootvars
[599]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   
[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:
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
[568]135    xchg    cx, ax      ; Any Floppy Drives?
136    jcxz    .SkipFloppyDriveHotkeys
[392]137
[492]138    mov     ax, (ANGLE_QUOTE_RIGHT << 8) | DEFAULT_FLOPPY_DRIVE_LETTER
[500]139    mov     cl, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bFddLetter]
[492]140    mov     di, g_szFDD
[593]141
142    ; Clear CH if floppy drive is selected for boot
143    mov     ch, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bFlags]
[600]144    ;and        ch, FLG_HOTKEY_HD_FIRST; Not needed until more flags added
[392]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;--------------------------------------------------------------------
[547]160    call    BootVars_GetLetterForFirstHardDriveToAX
[392]161    mov     ah, ANGLE_QUOTE_RIGHT
[596]162    mov     cx, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.wHddLetterAndFlags]  ; Letter to CL, flags to CH
[600]163    ;and        ch, FLG_HOTKEY_HD_FIRST ; Not needed until more flags added
[593]164    xor     ch, FLG_HOTKEY_HD_FIRST     ; Clear CH if HD is selected for boot, set otherwise
[492]165    mov     di, g_szHDD
[392]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
[492]180    mov     ax, BOOT_MENU_HOTKEY_SCANCODE | ('2' << 8)
181    mov     di, g_szBootMenu
[392]182    call    FormatFunctionHotkeyString
183%endif
[492]184    ; Fall to .PrintComDetectHotkey
[392]185
186;--------------------------------------------------------------------
[492]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
[505]201    ; Fall to .PrintRomBootHotkey
[492]202
203;--------------------------------------------------------------------
[392]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:
[492]213    mov     ax, ROM_BOOT_HOTKEY_SCANCODE | ('8' << 8)
214    mov     di, g_szRomBoot
[392]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:
[505]243    CALL_DISPLAY_LIBRARY GetColumnsToALandRowsToAH
[392]244    eMOVZX  cx, al
[505]245    CALL_DISPLAY_LIBRARY GetSoftwareCoordinatesToAX
[392]246    sub     cl, al
247    mov     al, ' '
[505]248    JMP_DISPLAY_LIBRARY PrintRepeatedCharacterFromALwithCountInCX
[392]249
250
251;--------------------------------------------------------------------
252; FormatDriveHotkeyString
253;   Parameters:
[593]254;       CH:         Zero if letter in CL is selected for boot
[392]255;       CL:         Drive letter hotkey from BOOTVARS
[492]256;       AL:         First character for drive key string
257;       AH:         Second character for drive key string (ANGLE_QUOTE_RIGHT)
[392]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;--------------------------------------------------------------------
[593]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
[392]271
[593]272    ; Drive selected to boot from?
273    test    ch, ch
274    jnz     SHORT GetNonSelectedHotkeyDescriptionAttributeToDX
275    jmp     SHORT GetSelectedHotkeyDescriptionAttributeToDX
276
277
[392]278;--------------------------------------------------------------------
279; FormatFunctionHotkeyString
280;   Parameters:
[492]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
[392]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:
[492]292    xor     cx, cx      ; Null character, eaten in output routines
[392]293
[492]294    cmp     [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode], al
295    mov     al, 'F'     ; Replace scancode with character for output
[392]296
297%ifdef MODULE_BOOT_MENU
[492]298
[593]299GetSelectedHotkeyDescriptionAttributeToDX:
[596]300    mov     si, ATTRIBUTE_CHARS.cHighlightedItem    ; Selected hotkey
[593]301    je      SHORT GetDescriptionAttributeToDX       ; From compare with bScancode above and from FormatDriveHotkeyString
[392]302
303GetNonSelectedHotkeyDescriptionAttributeToDX:
[596]304    mov     si, ATTRIBUTE_CHARS.cItem               ; Unselected hotkey
[392]305
306    ; Display Library should not be called like this
307GetDescriptionAttributeToDX:
[492]308    xchg    dx, ax
[392]309    call    MenuAttribute_GetToAXfromTypeInSI
310    xchg    dx, ax                  ; DX = Description attribute
[505]311    ;;  fall through to PushHotkeyParamsAndFormat
[392]312
313
[500]314%else ; if no MODULE_BOOT_MENU - No boot menu so use simpler attributes
315
[593]316GetSelectedHotkeyDescriptionAttributeToDX:
[410]317    mov     dx, (COLOR_ATTRIBUTE(COLOR_YELLOW, COLOR_CYAN) << 8) | MONO_REVERSE_BLINK
[593]318    je      SHORT SelectAttributeFromDHorDLbasedOnVideoMode     ; From compare with bScancode above and from FormatDriveHotkeyString
[392]319
320GetNonSelectedHotkeyDescriptionAttributeToDX:
[410]321    mov     dx, (COLOR_ATTRIBUTE(COLOR_BLACK, COLOR_CYAN) << 8) | MONO_REVERSE
[492]322
[410]323SelectAttributeFromDHorDLbasedOnVideoMode:
[500]324    mov     ch, [es:BDA.bVidMode]       ; We only need to preserve CL
325    shr     ch, 1
[410]326    jnc     SHORT .AttributeLoadedToDL  ; Black & White modes
[500]327    shr     ch, 1
[410]328    jnz     SHORT .AttributeLoadedToDL  ; MDA
329    mov     dl, dh
330.AttributeLoadedToDL:
[505]331    ;;  fall through to PushHotkeyParamsAndFormat
[410]332
[492]333%endif ; MODULE_BOOT_MENU
[392]334
335
336;--------------------------------------------------------------------
337; PushHotkeyParamsAndFormat
338;   Parameters:
[500]339;       AL:         First character
340;       AH:         Second character
[392]341;       DX:         Description Attribute
342;       CX:         Description string parameter
[492]343;       CS:DI:      Description string
[392]344;   Returns:
345;       Nothing
346;   Corrupts registers:
347;       AX, SI, DI
348;--------------------------------------------------------------------
349PushHotkeyParamsAndFormat:
350    push    bp
351    mov     bp, sp
352
[492]353    mov     si, MONO_BRIGHT
[392]354
[492]355    push    si              ; Key attribute
356    push    ax              ; First Character
357    mov     al, ah
358    push    ax              ; Second Character
359
[392]360    push    dx              ; Description attribute
[492]361    push    di              ; Description string
[392]362    push    cx              ; Description string parameter
[505]363
[492]364    push    si              ; Key attribute for last space
[392]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:
[505]394    JMP_DISPLAY_LIBRARY SetCursorCoordinatesFromAX
[392]395
396
397;--------------------------------------------------------------------
[599]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;--------------------------------------------------------------------
[528]452; HotkeyBar_StoreHotkeyToBootvarsForDriveNumberInDL
[395]453;   Parameters:
454;       DS:     RAMVARS segment
455;       ES:     BDA segment (zero)
[528]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)
[395]472;       DL:     Drive Letter ('A'...)
473;   Returns:
474;       Nothing
475;   Corrupts registers:
476;       AX, CX, DI
477;--------------------------------------------------------------------
[528]478StoreHotkeyToBootvarsForDriveLetterInDL:
[395]479    eMOVZX  ax, dl
[505]480    or      al, 32  ; Upper case drive letter to lower case keystroke
[395]481    jmp     SHORT HotkeyBar_StoreHotkeyToBootvarsIfValidKeystrokeInAX
482
483
484;--------------------------------------------------------------------
[528]485; ScanHotkeysFromKeyBufferAndStoreToBootvars
[392]486;   Parameters:
487;       DS:     RAMVARS segment
488;       ES:     BDA segment (zero)
489;   Returns:
[492]490;       AL:     Last scancode value
[392]491;   Corrupts registers:
[492]492;       AH, CX
[392]493;--------------------------------------------------------------------
[528]494ScanHotkeysFromKeyBufferAndStoreToBootvars:
[392]495    call    Keyboard_GetKeystrokeToAX
496    jz      SHORT NoHotkeyToProcess
497
[528]498    ; Prepare to read another key from buffer
499    ePUSH_T cx, ScanHotkeysFromKeyBufferAndStoreToBootvars
[392]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:
[567]511;       AL:     Last scancode seen
[528]512;       CF:     Set if valid hotkey in AL
513;               Clear if scancode in AL is not for any hotkey
[392]514;   Corrupts registers:
[492]515;       AH, CX, DI
[392]516;--------------------------------------------------------------------
517HotkeyBar_StoreHotkeyToBootvarsIfValidKeystrokeInAX:
[492]518    mov     di, BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode
[392]519
[492]520    ; All scancodes are saved, even if it wasn't a drive letter,
521    ; which also covers our function key case.  Invalid function keys
[505]522    ; will not do anything (won't be printed, won't be accepted as input)
[492]523    mov     [es:di], ah
[505]524
[392]525    ; Drive letter hotkeys remaining, allow 'a' to 'z'
526    call    Char_IsLowerCaseLetterInAL
[492]527    jnc     SHORT .KeystrokeIsNotValidDriveLetter
[505]528    and     al, ~32                 ; We want to print upper case letters
[392]529
530    ; Clear HD First flag to assume Floppy Drive hotkey
[492]531    dec     di
[392]532    and     BYTE [es:di], ~FLG_HOTKEY_HD_FIRST
533
534    ; Determine if Floppy or Hard Drive hotkey
[505]535    xchg    cx, ax
[547]536    call    BootVars_GetLetterForFirstHardDriveToAX
[392]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:
[505]544    sbb     di, BYTE 1              ; Sub CF if Floppy Drive
[392]545    xchg    ax, cx
[592]546    stosb
[528]547    stc                             ; Valid hotkey scancode returned in AL
[392]548
[505]549.KeystrokeIsNotValidDriveLetter:
[392]550NoHotkeyToProcess:
[492]551    mov     al, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode]
[392]552    ret
553
[528]554
[392]555;--------------------------------------------------------------------
[492]556; HotkeyBar_GetBootDriveNumbersToDX
[392]557;   Parameters:
558;       DS:     RAMVARS segment
559;       ES:     BDA segment (zero)
560;   Returns:
[492]561;       DX:     Drives selected as boot device, DL is primary
[392]562;   Corrupts registers:
[492]563;       AX
[392]564;--------------------------------------------------------------------
[492]565HotkeyBar_GetBootDriveNumbersToDX:
[500]566    mov     dx, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.wFddAndHddLetters]
[600]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
[505]582    test    BYTE [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bFlags], FLG_HOTKEY_HD_FIRST
[600]583    jnz     SHORT .noflip
[392]584    xchg    dl, dh
[505]585.noflip:
[492]586    call    DriveXlate_ConvertDriveLetterInDLtoDriveNumber
587    xchg    dl, dh
[505]588    ; Fall to HotkeyBar_FallThroughTo_DriveXlate_ConvertDriveLetterInDLtoDriveNumber
[392]589
[505]590HotkeyBar_FallThroughTo_DriveXlate_ConvertDriveLetterInDLtoDriveNumber:
591
Note: See TracBrowser for help on using the repository browser.