source: xtideuniversalbios/trunk/Assembly_Library/Src/Menu/Dialog/DialogFile.asm @ 602

Last change on this file since 602 was 602, checked in by krille_n_, 5 years ago

Changes:

  • SerDrive: Fixed a bug that prevented use of 3.5" 720 KB floppy disk images.
  • Also added support for Microsoft DMF (Distribution Media Format) floppy disk images.
  • XTIDECFG / Library: Minor size optimizations. Added a new macro (SKIP1B) as part of that.
  • BIOS: A small size optimization (2 bytes) to MODULE_8BIT_IDE_ADVANCED that is enabled only when USE_NEC_V is defined.
File size: 24.3 KB
Line 
1; Project name  :   Assembly Library
2; Description   :   Displays file dialog.
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
20CURRENTDIR_CHARACTERS   EQU     002Eh
21UPDIR_CHARACTERS        EQU     2E2Eh
22
23; Section containing code
24SECTION .text
25
26;--------------------------------------------------------------------
27; DialogFile_GetFileNameWithIoInDSSI
28;   Parameters:
29;       DS:SI:  Ptr to FILE_DIALOG_IO
30;       SS:BP:  Ptr to parent MENU
31;   Returns:
32;       Nothing
33;   Corrupts registers:
34;       AX, BX, CX, DX, DI
35;--------------------------------------------------------------------
36ALIGN JUMP_ALIGN
37DialogFile_GetFileNameWithIoInDSSI:
38    ; We need to store default drive because user might change drive but
39    ; then cancel the file selection. In that case the original default directory
40    ; must be restored.
41    call    Drive_GetDefaultToAL
42    push    ax
43
44    mov     bx, FileEventHandler
45    mov     BYTE [si+FILE_DIALOG_IO.bUserCancellation], TRUE
46    call    Dialog_DisplayWithDialogInputInDSSIandHandlerInBX
47
48    ; Now restore the default drive if user cancellation
49    pop     dx
50    cmp     BYTE [si+FILE_DIALOG_IO.bUserCancellation], TRUE
51    jne     SHORT .UserDidNotCancel
52    jmp     Drive_SetDefaultFromDL
53
54.UserDidNotCancel:
55    ret
56
57
58;--------------------------------------------------------------------
59; FileEventHandler
60;   Common parameters for all events:
61;       BX:         Menu event (anything from MENUEVENT struct)
62;       SS:BP:      Ptr to DIALOG
63;   Common return values for all events:
64;       CF:         Set if event processed
65;                   Cleared if event not processed
66;   Corrupts registers:
67;       All
68;--------------------------------------------------------------------
69ALIGN JUMP_ALIGN
70FileEventHandler:
71    jmp     [cs:bx+.rgfnEventHandlers]
72
73
74ALIGN JUMP_ALIGN
75.ItemSelectedFromCX:
76    call    LoadItemStringBufferToESDI
77    call    Registers_CopyESDItoDSSI
78    call    ItemLineSplitter_GetLineToDSSIandLengthToCXfromStringInDSSIwithIndexInCX
79    jmp     ParseSelectionFromItemLineInDSSI
80
81
82ALIGN JUMP_ALIGN
83.RefreshInformation:
84    call    GetInfoLinesToCXandDialogFlagsToAX
85    mov     si, [cs:.rgszInfoStringLookup]
86    xor     bx, bx
87    xchg    dx, ax
88ALIGN JUMP_ALIGN
89.InfoLineLoop:
90    shr     dl, 1
91    jnc     SHORT .CheckNextFlag
92    mov     si, [cs:bx+.rgszInfoStringLookup]
93    push    bx
94    CALL_DISPLAY_LIBRARY PrintNullTerminatedStringFromCSSI
95    pop     bx
96ALIGN JUMP_ALIGN
97.CheckNextFlag:
98    inc     bx
99    inc     bx
100    loop    .InfoLineLoop
101    stc                     ; Event processed
102    ret
103
104
105ALIGN JUMP_ALIGN
106.RefreshItemFromCX:
107    call    LoadItemStringBufferToESDI
108    mov     ax, FILE_STRING_LENGTH
109    xchg    ax, cx
110    mul     cx
111    add     di, ax
112    mov     si, di
113    mov     bx, es
114    dec     cx              ; Do not print LF at the end of file string
115    CALL_DISPLAY_LIBRARY PrintCharBufferFromBXSIwithLengthInCX
116    stc
117    ret
118
119
120ALIGN WORD_ALIGN
121.rgszInfoStringLookup:
122    dw      g_szChangeDrive
123    dw      g_szSelectDirectory
124    dw      g_szCreateNew
125
126.rgfnEventHandlers:
127istruc MENUEVENT
128    at  MENUEVENT.InitializeMenuinitFromDSSI,   dw  InitializeMenuinitFromSSBP
129    at  MENUEVENT.ExitMenu,                     dw  Dialog_EventExitMenu
130    at  MENUEVENT.IdleProcessing,               dw  Dialog_EventNotHandled
131    at  MENUEVENT.ItemHighlightedFromCX,        dw  Dialog_EventNotHandled
132    at  MENUEVENT.ItemSelectedFromCX,           dw  .ItemSelectedFromCX
133    at  MENUEVENT.KeyStrokeInAX,                dw  HandleFunctionKeyFromAH
134    at  MENUEVENT.RefreshTitle,                 dw  Dialog_EventRefreshTitle
135    at  MENUEVENT.RefreshInformation,           dw  .RefreshInformation
136    at  MENUEVENT.RefreshItemFromCX,            dw  .RefreshItemFromCX
137iend
138
139
140;--------------------------------------------------------------------
141; ReInitializeMenuinitFromSSBP
142; InitializeMenuinitFromSSBP
143;   Parameters:
144;       SS:BP:      Ptr to DIALOG
145;   Returns:
146;       Nothing
147;   Corrupts registers:
148;       All, except BP
149;--------------------------------------------------------------------
150ALIGN JUMP_ALIGN
151ReInitializeMenuinitFromSSBP:
152    call    DisplayLoadingMessageInInformationArea
153InitializeMenuinitFromSSBP:
154    call    LoadItemStringBufferToESDI
155    call    CreateStringFromCurrentDirectoryContentsToESDI
156    call    LoadItemStringBufferToESDI
157    call    SortDirectoryContentsStringFromESDIwithCountInCX
158    call    RemoveLastLFandTerminateESDIwithNull
159
160    call    Registers_CopySSBPtoDSSI
161    xor     ax, ax
162    call    Dialog_EventInitializeMenuinitFromDSSIwithHighlightedItemInAX
163    call    GetInfoLinesToCXandDialogFlagsToAX
164    mov     [bp+MENUINIT.bInfoLines], cl
165    CALL_DISPLAY_LIBRARY GetColumnsToALandRowsToAH
166    mov     [bp+MENUINIT.bHeight], ah               ; Always max height
167    mov     WORD [bp+MENU.wFirstVisibleItem], 0
168    ret
169
170
171;--------------------------------------------------------------------
172; LoadItemStringBufferToESDI
173;   Parameters:
174;       SS:BP:  Ptr to DIALOG
175;   Returns:
176;       ES:DI:  Ptr to item string buffer
177;   Corrupts registers:
178;       Nothing
179;--------------------------------------------------------------------
180ALIGN JUMP_ALIGN
181LoadItemStringBufferToESDI:
182    les     di, [bp+DIALOG.fpDialogIO]
183    les     di, [es:di+FILE_DIALOG_IO.fszItemBuffer]
184    ret
185
186
187;--------------------------------------------------------------------
188; CreateStringFromCurrentDirectoryContentsToESDI
189;   Parameters:
190;       ES:DI:  Buffer where to create item string
191;       SS:BP:  Ptr to DIALOG
192;   Returns:
193;       CX:     Number of files or directories found
194;   Corrupts registers:
195;       AX, BX, DX, SI, DI, DS
196;--------------------------------------------------------------------
197ALIGN JUMP_ALIGN
198CreateStringFromCurrentDirectoryContentsToESDI:
199    mov     bx, di
200    CALL_DISPLAY_LIBRARY PushDisplayContext
201    mov     cx, -1
202    CALL_DISPLAY_LIBRARY PrepareOffScreenBufferInESBXwithLengthInCX ; ES:DI now points to buffer
203
204    lds     si, [bp+DIALOG.fpDialogIO]
205    eMOVZX  cx, [si+FILE_DIALOG_IO.bFileAttributes]
206    lds     si, [si+FILE_DIALOG_IO.fpFileFilterString]
207    call    Directory_UpdateDTAForFirstMatchForDSSIwithAttributesInCX
208
209    call    .ClearDLifInRootDirectory
210    call    Directory_GetDiskTransferAreaAddressToDSSI
211    xor     cx, cx          ; Clear file/directory count
212    call    .FindMatchingFilesAndPrintThemToOffScreenBuffer
213
214    JMP_DISPLAY_LIBRARY PopDisplayContext
215
216;--------------------------------------------------------------------
217; .ClearDLifInRootDirectory
218;   Parameters:
219;       SS:BP:  Ptr to DIALOG
220;       ES:DI:  Ptr to destination string buffer
221;   Returns:
222;       DL:     Cleared if in root directory
223;               Set if in any other directory
224;   Corrupts registers:
225;       AX, SI, DS
226;--------------------------------------------------------------------
227ALIGN JUMP_ALIGN
228.ClearDLifInRootDirectory:
229    call    Registers_CopyESDItoDSSI
230    call    Directory_WriteCurrentPathToDSSI
231    mov     dl, [si]
232    ret
233
234;--------------------------------------------------------------------
235; .FindMatchingFilesAndPrintThemToOffScreenBuffer
236;   Parameters:
237;       CX:     Initial directory count
238;       DL:     Zero if root directory selected
239;       DS:SI:  Ptr to DTA with first matching file
240;   Returns:
241;       CX:     Incremented by number of files/directories found
242;   Corrupts registers:
243;       AX, BX, DX, DI, DS
244;--------------------------------------------------------------------
245ALIGN JUMP_ALIGN
246.FindMatchingFilesAndPrintThemToOffScreenBuffer:
247    call    AppendFileFromDTAinDSSItoOffScreenBuffer
248    call    Directory_UpdateDTAForNextMatchUsingPreviousParameters
249    jnc     SHORT .FindMatchingFilesAndPrintThemToOffScreenBuffer
250    ret
251
252
253;--------------------------------------------------------------------
254; AppendFileFromDTAinDSSItoOffScreenBuffer
255;   Parameters:
256;       CX:     Files/directories found
257;       DL:     Zero if root directory selected
258;       DS:SI:  Ptr to DTA containing file information
259;   Returns:
260;       CX:     Incremented by number of files/directories found
261;   Corrupts registers:
262;       AX, BX
263;--------------------------------------------------------------------
264ALIGN JUMP_ALIGN
265AppendFileFromDTAinDSSItoOffScreenBuffer:
266    cmp     WORD [si+DTA.szFile], CURRENTDIR_CHARACTERS
267    je      SHORT .Return                   ; We never want "."
268    test    dl, dl
269    jnz     SHORT .NotInRootDirectory
270    cmp     WORD [si+DTA.szFile], UPDIR_CHARACTERS
271    je      SHORT .Return                   ; No ".." when in root directory
272.NotInRootDirectory:
273    inc     cx                              ; Nothing filtered so increment files/directories
274
275    push    bp
276    push    si
277    push    dx
278    push    cx
279    call    .FormatFileOrDirectoryToBufferFromDTAinDSSI
280    pop     cx
281    pop     dx
282    pop     si
283    pop     bp
284.Return:
285    ret
286
287;--------------------------------------------------------------------
288; .FormatFileOrDirectoryToBufferFromDTAinDSSI
289;   Parameters:
290;       DS:SI:  Ptr to DTA containing file information
291;   Returns:
292;       Nothing
293;   Corrupts registers:
294;       AX, BX, CX, DX, SI, DI, BP
295;--------------------------------------------------------------------
296ALIGN JUMP_ALIGN
297.FormatFileOrDirectoryToBufferFromDTAinDSSI:
298    mov     bp, sp
299    lea     ax, [si+DTA.szFile]
300
301    test    BYTE [si+DTA.bFileAttributes], FLG_FILEATTR_DIRECTORY
302    jnz     SHORT .FormatDirectory
303    ; Fall to .FormatFile
304
305;--------------------------------------------------------------------
306; .FormatFile
307;   Parameters:
308;       BP:     SP before pushing formatting parameters
309;       DS:AX:  Far pointer to file name
310;       DS:SI:  Ptr to DTA containing file information
311;   Returns:
312;       Nothing
313;   Corrupts registers:
314;       AX, BX, CX, DX, SI, DI
315;--------------------------------------------------------------------
316.FormatFile:
317    xchg    si, ax
318    call    String_ConvertDSSItoLowerCase
319    xchg    ax, si
320
321    ; Push parameters for file name
322    push    ax              ; Push file name offset
323    push    ds              ; Push file name segment
324
325    ; Push parameters for file size
326    mov     ax, [si+DTA.dwFileSize]
327    mov     dx, [si+DTA.dwFileSize+2]
328    xor     bx, bx
329    xor     cx, cx
330    call    Size_GetSizeToAXAndCharToDLfromBXDXAXwithMagnitudeInCX
331    mov     cl, 'i'
332    cmp     dl, ' '
333    eCMOVE  cl, dl
334    push    ax
335    push    dx
336    push    cx
337
338    ; Format to buffer
339    mov     si, g_szFileFormat
340    jmp     SHORT .FormatStringInCSSIandReturn
341
342;--------------------------------------------------------------------
343; .FormatDirectory
344;   Parameters:
345;       BP:     SP before pushing formatting parameters
346;       DS:AX:  Far pointer to directory name
347;       DS:SI:  Ptr to DTA containing file information
348;   Returns:
349;       Nothing
350;   Corrupts registers:
351;       AX, SI, DI
352;--------------------------------------------------------------------
353ALIGN JUMP_ALIGN
354.FormatDirectory:
355    push    ax              ; Push directory name offset
356    push    ds              ; Push directory name segment
357    mov     ax, g_szSub
358    cmp     WORD [si+DTA.szFile], UPDIR_CHARACTERS
359    eCMOVE  ax, g_szUp
360    push    ax
361    mov     si, g_szDirectoryFormat
362ALIGN JUMP_ALIGN
363.FormatStringInCSSIandReturn:
364    JMP_DISPLAY_LIBRARY FormatNullTerminatedStringFromCSSI
365
366
367;--------------------------------------------------------------------
368; SortDirectoryContentsStringFromESDIwithCountInCX
369;   Parameters:
370;       CX:     Number of files and directories
371;       ES:DI:  Buffer containing directory contents string
372;       SS:BP:  Ptr to DIALOG
373;   Returns:
374;       ES:DI:  Ptr to end of directory contents string
375;   Corrupts registers:
376;       AX, BX, CX, DX, SI, DS
377;--------------------------------------------------------------------
378ALIGN JUMP_ALIGN
379SortDirectoryContentsStringFromESDIwithCountInCX:
380    call    Registers_CopyESDItoDSSI
381
382    ; Add directory contents string length to DI
383    mov     ax, FILE_STRING_LENGTH
384    push    ax
385    mul     cx
386    add     di, ax
387
388    mov     dx, cx
389    pop     cx
390    mov     bx, .FileStringComparator
391    jmp     Sort_ItemsFromDSSIwithCountInDXsizeInCXandComparatorInBX
392
393;--------------------------------------------------------------------
394; .FileStringComparator
395;   Parameters:
396;       CX:     Item size in bytes
397;       DS:SI:  Ptr to first item to compare
398;       ES:DI:  Ptr to second item to compare
399;   Returns:
400;       FLAGS:  Signed comparison between first and second item
401;   Corrupts registers:
402;       Nothing
403;--------------------------------------------------------------------
404ALIGN JUMP_ALIGN
405.FileStringComparator:
406    push    di
407    push    si
408    push    cx
409    push    bx
410
411    mov     bx, FILE_STRING_LENGTH-2            ; Zero BH
412    cmp     WORD [si], UPDIR_CHARACTERS
413    je      SHORT .ForceValueFromDSSItoBeLess
414    mov     bl, [si+bx]
415    cmp     bl, [es:di+FILE_STRING_LENGTH-2]    ; 'B' for files, 'R' for directories
416    jne     SHORT .ForceValueFromDSSItoBeMoreOrLess
417    repe cmpsb                                  ; Two directories or two files
418
419ALIGN JUMP_ALIGN
420.ReturnFromComparison:
421    pop     bx
422    pop     cx
423    pop     si
424    pop     di
425    ret
426ALIGN JUMP_ALIGN
427.ForceValueFromDSSItoBeMoreOrLess:
428    ja      SHORT .ForceValueFromDSSItoBeLess   ; Directory in SI, file in DI
429    xchg    bl, bh
430    ; Fall to ForceValueFromDSSItoBeLess
431ALIGN JUMP_ALIGN
432.ForceValueFromDSSItoBeLess:
433    cmp     bh, bl
434    jmp     SHORT .ReturnFromComparison
435
436
437;--------------------------------------------------------------------
438; RemoveLastLFandTerminateESDIwithNull
439;   Parameters:
440;       ES:DI:  Ptr to end of buffer to terminate
441;   Returns:
442;       Nothing
443;   Corrupts registers:
444;       AX
445;--------------------------------------------------------------------
446ALIGN JUMP_ALIGN
447RemoveLastLFandTerminateESDIwithNull:
448    dec     di
449    xor     ax, ax
450    stosb
451    ret
452
453
454;--------------------------------------------------------------------
455; GetInfoLinesToCXandDialogFlagsToAX
456;   Parameters:
457;       SS:BP:  Ptr to DIALOG
458;   Returns:
459;       AX:     Dialog flags
460;       CX:     Number of info lines to be displayed
461;   Corrupts registers:
462;       SI, DS
463;--------------------------------------------------------------------
464ALIGN JUMP_ALIGN
465GetInfoLinesToCXandDialogFlagsToAX:
466    ePUSH_T ax, Bit_GetSetCountToCXfromAX
467    xor     ah, ah
468    ; Fall to GetDialogFlagsToAL
469
470;--------------------------------------------------------------------
471; GetDialogFlagsToAL
472;   Parameters:
473;       SS:BP:  Ptr to DIALOG
474;   Returns:
475;       AL:     Dialog flags
476;   Corrupts registers:
477;       SI, DS
478;--------------------------------------------------------------------
479ALIGN JUMP_ALIGN
480GetDialogFlagsToAL:
481    lds     si, [bp+DIALOG.fpDialogIO]
482    mov     al, [si+FILE_DIALOG_IO.bDialogFlags]
483    ret
484
485
486;--------------------------------------------------------------------
487; ParseSelectionFromItemLineInDSSI
488;   Parameters:
489;       DS:SI:  Ptr to char buffer containing file or directory to be selected
490;       SS:BP:  Ptr to DIALOG
491;   Returns:
492;       Nothing
493;   Corrupts registers:
494;       All, except BP
495;--------------------------------------------------------------------
496ALIGN JUMP_ALIGN
497ParseSelectionFromItemLineInDSSI:
498    mov     ax, [si]
499    cmp     ax, UPDIR_CHARACTERS
500    je      SHORT .ChangeToUpdir
501    call    Char_IsUpperCaseLetterInAL
502    jc      SHORT .ParseAndChangeToSubdirInDSSI
503    call    Char_IsDecimalDigitInAL
504    jc      SHORT .ParseAndChangeToSubdirInDSSI ; Assume subdir and check for errors
505    ; Fall to .ParseAndSelectFileFromDSSI
506
507;--------------------------------------------------------------------
508; .ParseAndSelectFileFromDSSI
509;   Parameters:
510;       DS:SI:  NULL terminated string selected from dialog
511;       SS:BP:  Ptr to DIALOG
512;   Returns:
513;       Nothing (exits dialog)
514;   Corrupts registers:
515;       All, except BP
516;--------------------------------------------------------------------
517.ParseAndSelectFileFromDSSI:
518    les     di, [bp+DIALOG.fpDialogIO]
519    add     di, BYTE FILE_DIALOG_IO.szFile
520    mov     cx, FILENAME_BUFFER_SIZE-1
521    call    Memory_CopyCXbytesFromDSSItoESDI
522    xor     ax, ax
523    stosb                       ; Terminate with NULL
524    jmp     SHORT CloseFileDialogAfterSuccessfulSelection
525
526;--------------------------------------------------------------------
527; .ChangeToUpdir
528;   Parameters:
529;       SS:BP:  Ptr to DIALOG
530;   Returns:
531;       Nothing
532;   Corrupts registers:
533;       All, except BP
534;--------------------------------------------------------------------
535ALIGN JUMP_ALIGN
536.ChangeToUpdir:
537    push    cs
538    pop     ds
539    mov     si, g_szUpdir
540    jmp     SHORT .ChangeDirectoryToDSSI
541
542;--------------------------------------------------------------------
543; .ParseAndChangeToSubdirInDSSI
544;   Parameters:
545;       DS:SI:  NULL terminated string selected from dialog
546;       SS:BP:  Ptr to DIALOG
547;   Returns:
548;       Nothing
549;   Corrupts registers:
550;       All, except BP
551;--------------------------------------------------------------------
552ALIGN JUMP_ALIGN
553.ParseAndChangeToSubdirInDSSI:
554    mov     BYTE [si+12], NULL  ; Terminate with NULL (unnecessary spaces do not matter)
555.ChangeDirectoryToDSSI:
556    call    Directory_ChangeToPathFromDSSI
557    jc      SHORT .ParseAndSelectFileFromDSSI   ; Must have been a file starting with number
558    ; Fall to RefreshFilesToDisplay
559
560;--------------------------------------------------------------------
561; RefreshFilesToDisplay
562;   Parameters:
563;       SS:BP:  Ptr to DIALOG
564;   Returns:
565;       Nothing
566;   Corrupts registers:
567;       All, except BP
568;--------------------------------------------------------------------
569ALIGN JUMP_ALIGN
570RefreshFilesToDisplay:
571    call    ReInitializeMenuinitFromSSBP
572    jmp     MenuInit_RefreshMenuWindow
573
574
575;--------------------------------------------------------------------
576; HandleFunctionKeyFromAH
577;   Parameters:
578;       AH:     Scancode for function key
579;       SS:BP:  Ptr to DIALOG
580;   Returns:
581;       Nothing
582;   Corrupts registers:
583;       AX, SI, DI, BP
584;--------------------------------------------------------------------
585ALIGN JUMP_ALIGN
586HandleFunctionKeyFromAH:
587    call    GetDialogFlagsToAL
588    cmp     ah, KEY_FILEDIALOG_NEW_FILE_OR_DIR
589    je      SHORT HandleFunctionKeyForCreatingNewFileOrDirectory
590    cmp     ah, KEY_FILEDIALOG_SELECT_DIRECTORY
591    je      SHORT HandleFunctionKeyForSelectingDirectoryInsteadOfFile
592    cmp     ah, KEY_FILEDIALOG_CHANGE_DRIVE
593    je      SHORT HandleFunctionKeyForDriveChange
594ReturnWithoutHandlingKeystroke:
595    clc     ; Event not processed
596    ret
597
598
599;--------------------------------------------------------------------
600; HandleFunctionKeyForCreatingNewFileOrDirectory
601;   Parameters:
602;       AL:     File dialog flags
603;       SS:BP:  Ptr to DIALOG
604;   Returns:
605;       Closes file dialog
606;   Corrupts registers:
607;       All, except BP
608;--------------------------------------------------------------------
609ALIGN JUMP_ALIGN
610HandleFunctionKeyForCreatingNewFileOrDirectory:
611    test    al, FLG_FILEDIALOG_NEW
612    jz      SHORT ReturnWithoutHandlingKeystroke
613
614    mov     cl, STRING_DIALOG_IO_size
615    call    Memory_ReserveCLbytesFromStackToDSSI
616
617;;; InitializeStringDialogIoInDSSIforInputtingFileName
618    call    InitializeNullStringsToDialogInputInDSSI
619    mov     WORD [si+DIALOG_INPUT.fszTitle], g_szEnterNewFileOrDirectory
620    mov     WORD [si+STRING_DIALOG_IO.fnCharFilter], NULL
621    mov     WORD [si+STRING_DIALOG_IO.wBufferSize], FILENAME_BUFFER_SIZE
622    les     ax, [bp+DIALOG.fpDialogIO]
623    add     ax, BYTE FILE_DIALOG_IO.szFile
624    mov     [si+STRING_DIALOG_IO.fpReturnBuffer], ax
625    mov     [si+STRING_DIALOG_IO.fpReturnBuffer+2], es
626;;;
627
628    CALL_MENU_LIBRARY GetStringWithIoInDSSI
629    mov     al, [si+STRING_DIALOG_IO.bUserCancellation]
630    add     sp, BYTE STRING_DIALOG_IO_size
631    test    al, al      ; User cancellation?
632    jnz     SHORT ReturnWithoutHandlingKeystroke
633    jmp     CloseFileDialogAfterSuccessfulSelection
634
635
636;--------------------------------------------------------------------
637; HandleFunctionKeyForSelectingDirectoryInsteadOfFile
638;   Parameters:
639;       AL:     File dialog flags
640;       SS:BP:  Ptr to DIALOG
641;   Returns:
642;       Closes file dialog
643;   Corrupts registers:
644;       All, except BP
645;--------------------------------------------------------------------
646ALIGN JUMP_ALIGN
647HandleFunctionKeyForSelectingDirectoryInsteadOfFile:
648    test    al, FLG_FILEDIALOG_DIRECTORY
649    jz      SHORT ReturnWithoutHandlingKeystroke
650    ; Fall to CloseFileDialogAfterSuccessfulSelection
651
652;--------------------------------------------------------------------
653; CloseFileDialogAfterSuccessfulSelection
654;   Parameters:
655;       SS:BP:  Ptr to DIALOG
656;   Returns:
657;       Nothing (exits dialog)
658;   Corrupts registers:
659;       All, except BP
660;--------------------------------------------------------------------
661ALIGN JUMP_ALIGN
662CloseFileDialogAfterSuccessfulSelection:
663    lds     di, [bp+DIALOG.fpDialogIO]
664    mov     BYTE [di+FILE_DIALOG_IO.bUserCancellation], FALSE
665    jmp     MenuInit_CloseMenuWindow
666
667
668;--------------------------------------------------------------------
669; HandleFunctionKeyForDriveChange
670;   Parameters:
671;       AL:     File dialog flags
672;       SS:BP:  Ptr to DIALOG
673;   Returns:
674;       Nothing
675;   Corrupts registers:
676;       All, except BP
677;--------------------------------------------------------------------
678ALIGN JUMP_ALIGN
679HandleFunctionKeyForDriveChange:
680    test    al, FLG_FILEDIALOG_DRIVES
681    jz      SHORT ReturnWithoutHandlingKeystroke
682
683    call    DisplayLoadingMessageInInformationArea
684    mov     cl, DRIVE_DIALOG_IO_size
685    call    Memory_ReserveCLbytesFromStackToDSSI
686    call    .DisplayDriveSelectionDialogWithIoInDSSI
687    call    .ChangeDriveToUserSelectionFromIoInDSSI
688    add     sp, BYTE DRIVE_DIALOG_IO_size
689.UserCancelledDriveChange:
690    ret
691
692;--------------------------------------------------------------------
693; .DisplayDriveSelectionDialogWithIoInDSSI
694;   Parameters:
695;       DS:SI:  Ptr to uninitialized DRIVE_DIALOG_IO
696;       SS:BP:  Ptr to DIALOG
697;   Returns:
698;       DS:SI:  Ptr to DRIVE_DIALOG_IO
699;   Corrupts registers:
700;       AX, DI
701;--------------------------------------------------------------------
702ALIGN JUMP_ALIGN
703.DisplayDriveSelectionDialogWithIoInDSSI:
704    call    InitializeNullStringsToDialogInputInDSSI
705    mov     WORD [si+DIALOG_INPUT.fszTitle], g_szSelectNewDrive
706    JMP_MENU_LIBRARY GetDriveWithIoInDSSI
707
708;--------------------------------------------------------------------
709; .ChangeDriveToUserSelectionFromIoInDSSI
710;   Parameters:
711;       DS:SI:  Ptr to DRIVE_DIALOG_IO
712;       SS:BP:  Ptr to DIALOG
713;   Returns:
714;       Nothing
715;   Corrupts registers:
716;       All, except BP
717;--------------------------------------------------------------------
718ALIGN JUMP_ALIGN
719.ChangeDriveToUserSelectionFromIoInDSSI:
720    cmp     BYTE [si+DRIVE_DIALOG_IO.bUserCancellation], FALSE
721    jne     SHORT .UserCancelledDriveChange
722
723    ; Install our Custom Critical Error Handler to catch "Drive Not Ready" errors. This handler only works on DOS 3.0+ systems
724    ; but that should be OK because only DOS 3.1+ will trigger it. Under older DOS versions drives are enumerated using
725    ; GET_DOS_DRIVE_PARAMETER_BLOCK_FOR_SPECIFIC_DRIVE which will access the drive so we know it is available at this point.
726    mov     dx, DosCritical_CustomHandler
727    call    DosCritical_InstallNewHandlerFromCSDX
728
729    ; Save the current drive on stack in case the selected drive is not ready and the user decides to cancel the change.
730    call    Drive_GetDefaultToAL
731    xchg    dx, ax
732
733.RetryDrive:
734    push    dx                                  ; Save the previous current drive to stack
735
736    mov     dl, [si+DRIVE_DIALOG_IO.bReturnDriveNumber]
737    call    Drive_SetDefaultFromDL
738
739    ; Now we must try to force a media access to catch "Drive Not Ready".
740    push    ds
741    push    ss
742    pop     ds
743    ePUSH_T ax, CURRENTDIR_CHARACTERS           ; The high byte is zero
744    mov     cx, FLG_FILEATTR_DIRECTORY
745    mov     dx, sp
746    mov     ax, FIND_FIRST_MATCHING_FILE<<8
747    int     DOS_INTERRUPT_21h
748    ; Returns ERR_DOS_NO_MORE_FILES only when the root directory is the current directory (at least under Windows XP).
749    cmp     al, ERR_DOS_PATH_NOT_FOUND
750    pop     ax
751    pop     ds
752
753    pop     dx                                  ; Restore the previous current drive from stack
754
755    xchg    ah, [cs:bLastCriticalError]         ; Zero bLastCriticalError and fetch error code to AH
756    je      SHORT .DriveIsNotReady              ; A removable drive with no media (or possibly a drive that has not been formatted?)
757    cmp     ah, ERR_DOS_DRIVE_NOT_READY
758    jne     SHORT .DriveIsReady
759.DriveIsNotReady:
760    mov     bx, g_szDlgDriveNotReady
761    call    Dialogs_DisplayYesNoResponseDialogWithTitleStringInBX
762    jz      SHORT .RetryDrive
763    ; The user cancelled the drive change. Restore current drive to what it was previously.
764    call    Drive_SetDefaultFromDL
765    jmp     DosCritical_RestoreDosHandler
766
767.DriveIsReady:
768    call    DosCritical_RestoreDosHandler
769    jmp     RefreshFilesToDisplay
770
771
772;--------------------------------------------------------------------
773; DisplayLoadingMessageInInformationArea
774;   Parameters:
775;       SS:BP:      Ptr to DIALOG
776;   Returns:
777;       Nothing
778;   Corrupts registers:
779;       AX, BX, CX, DX, SI, DI
780;--------------------------------------------------------------------
781ALIGN JUMP_ALIGN
782DisplayLoadingMessageInInformationArea:
783    call    MenuText_ClearInformationArea
784    call    MenuText_PrepareToDrawInformationArea
785    mov     si, g_szLoadingPleaseWait
786    JMP_DISPLAY_LIBRARY PrintNullTerminatedStringFromCSSI
787
788
789;--------------------------------------------------------------------
790; InitializeNullStringsToDialogInputInDSSI
791;   Parameters:
792;       DS:SI:  Ptr to DIALOG_INPUT
793;       SS:BP:  Ptr to DIALOG
794;   Returns:
795;       Nothing
796;   Corrupts registers:
797;       AX
798;--------------------------------------------------------------------
799ALIGN JUMP_ALIGN
800InitializeNullStringsToDialogInputInDSSI:
801    mov     ax, g_szNull
802    mov     [si+DIALOG_INPUT.fszTitle], ax
803    mov     [si+DIALOG_INPUT.fszTitle+2], cs
804    mov     [si+DIALOG_INPUT.fszItems], ax
805    mov     [si+DIALOG_INPUT.fszItems+2], cs
806    mov     [si+DIALOG_INPUT.fszInfo], ax
807    mov     [si+DIALOG_INPUT.fszInfo+2], cs
808    ret
Note: See TracBrowser for help on using the repository browser.