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

Last change on this file since 624 was 602, checked in by Krister Nordvall, 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.