diff options
| author | 2024-04-25 21:24:10 +0100 | |
|---|---|---|
| committer | 2024-04-25 22:32:27 +0000 | |
| commit | 2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch) | |
| tree | 80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/SELECT/ROUTINE2.ASM | |
| parent | Merge pull request #430 from jpbaltazar/typoptbr (diff) | |
| download | ms-dos-main.tar.gz ms-dos-main.tar.xz ms-dos-main.zip | |
Diffstat (limited to 'v4.0/src/SELECT/ROUTINE2.ASM')
| -rw-r--r-- | v4.0/src/SELECT/ROUTINE2.ASM | 1369 |
1 files changed, 1369 insertions, 0 deletions
diff --git a/v4.0/src/SELECT/ROUTINE2.ASM b/v4.0/src/SELECT/ROUTINE2.ASM new file mode 100644 index 0000000..2a8b7ad --- /dev/null +++ b/v4.0/src/SELECT/ROUTINE2.ASM | |||
| @@ -0,0 +1,1369 @@ | |||
| 1 | ;*************************************************************************** | ||
| 2 | ; Subroutines which are called by the macros in MACROS.INC. | ||
| 3 | ; File: ROUTINE2.ASM | ||
| 4 | ; Latest Change Date: August 04, 1987 | ||
| 5 | ; | ||
| 6 | ; This is a stand alone module and is meant to be linked with the calling | ||
| 7 | ; program. | ||
| 8 | ; | ||
| 9 | ;*************************************************************************** | ||
| 10 | .ALPHA ;AN000; | ||
| 11 | ;********************************************************************** | ||
| 12 | DATA SEGMENT BYTE PUBLIC 'DATA' ;AN000; | ||
| 13 | |||
| 14 | PATH_STRING DW 0 ;AN000; | ||
| 15 | STRING_SIZE DW 0 ;AN000; | ||
| 16 | PATH_PTR DW 0 ;AN000; | ||
| 17 | PATH_SIZE DW 0 ;AN000; | ||
| 18 | MAX_CHAR DW 0 ;AN000; | ||
| 19 | CHAR_COUNT DW 0 ;AN000; | ||
| 20 | |||
| 21 | |||
| 22 | SEARCH_FLAG DB 0 ;AN000; | ||
| 23 | |||
| 24 | PERIOD EQU 00000001B ;AN000; | ||
| 25 | SLASH_FOUND EQU 00000010B ;AN000; | ||
| 26 | |||
| 27 | |||
| 28 | RESET_PERIOD EQU 11111110B ;AN000; | ||
| 29 | RESET_SLASH_FOUND EQU 11111101B ;AN000; | ||
| 30 | |||
| 31 | INVALID_STRING DB '"/\[]:|<>+=;, ' ;AN000; | ||
| 32 | END_INVALID_STRING EQU $ ;AN000; | ||
| 33 | SIZE_INVALID_STR EQU END_INVALID_STRING - INVALID_STRING ;AN000; | ||
| 34 | |||
| 35 | ZEROED_CHAR DB 0 ;AN000; | ||
| 36 | DB 0 ;AN000; | ||
| 37 | |||
| 38 | SEP_POSITION DW 0 ;AN000; | ||
| 39 | NUM_PATHS DW 0 ;AN000; | ||
| 40 | |||
| 41 | |||
| 42 | ERR_INVALID_DRV EQU 1 ;AN000; | ||
| 43 | ERR_NO_DRIVE EQU 2 ;AN000; | ||
| 44 | ERR_DRIVE EQU 3 ;AN000; | ||
| 45 | ERR_LEADING_SLASH EQU 4 ;AN000; | ||
| 46 | ERR_NO_SLASH EQU 5 ;AN000; | ||
| 47 | ERR_LAST_SLASH EQU 6 ;AN000; | ||
| 48 | ERR_INVALID_CHAR EQU 7 ;AN000; | ||
| 49 | |||
| 50 | OLD_ATTRIB DW 0 ;AN000; | ||
| 51 | NEW_ATTRIB DW 0 ;AN000; | ||
| 52 | WAY DW 0 ;AN000; | ||
| 53 | |||
| 54 | |||
| 55 | |||
| 56 | PUBLIC CHK_W_PROTECT_FLAG ;AN000; | ||
| 57 | PUBLIC W_PROTECT_FLAG ;AN000; | ||
| 58 | |||
| 59 | W_P_FILENAME_A DB 'A:\',12 DUP(0), 0 ;AC000;JW | ||
| 60 | W_P_FILENAME_B DB 'B:\',12 DUP(0), 0 ;AN000;JW | ||
| 61 | CHK_W_PROTECT_FLAG DB 0 ;AN000; | ||
| 62 | W_PROTECT_FLAG DB 0 ;AN000; | ||
| 63 | DRIVE_FLAG DB ? ;AN000;JW | ||
| 64 | |||
| 65 | |||
| 66 | NUM_FILES DW 0 ;AN000; | ||
| 67 | LIST_TYPE DW 0 ;AN000; | ||
| 68 | STR_PTR DW 0 ;AN000; | ||
| 69 | FILE_PTR DW 0 ;AN000; | ||
| 70 | |||
| 71 | |||
| 72 | |||
| 73 | DATA ENDS ;AN000; DATA | ||
| 74 | ;********************************************************************** | ||
| 75 | ; | ||
| 76 | .XLIST ;AN000; | ||
| 77 | INCLUDE STRUC.INC ;AN000; | ||
| 78 | INCLUDE MACROS.INC ;AN000; | ||
| 79 | INCLUDE VARSTRUC.INC ;AN000; | ||
| 80 | INCLUDE EXT.INC ;AN000; | ||
| 81 | INCLUDE MAC_EQU.INC ;AN000; | ||
| 82 | EXTRN EXIT_DOS:FAR ;AN000; | ||
| 83 | EXTRN POS_ZERO:FAR ;AN000; | ||
| 84 | EXTRN HOOK_INT_24:FAR ;AN000; | ||
| 85 | EXTRN RESTORE_INT_24:FAR ;AN000; | ||
| 86 | EXTRN GGET_STATUS:FAR ;AN000; | ||
| 87 | .LIST ;AN000; | ||
| 88 | ; | ||
| 89 | ; | ||
| 90 | ;********************************************************************** | ||
| 91 | CODE_FAR SEGMENT PARA PUBLIC 'CODE' ;AN000; Segment for far routine | ||
| 92 | ASSUME CS:CODE_FAR,DS:DATA ;AN000; | ||
| 93 | ; | ||
| 94 | ;******************************************************************************** | ||
| 95 | ; CHECK_DOS_PATH_ROUTINE: Check to see if the sepecified path for the DOS | ||
| 96 | ; SET PATH command is valid. | ||
| 97 | ; | ||
| 98 | ; INPUT: | ||
| 99 | ; SI = Points to an ASCII-N string containing the path to check. There sould | ||
| 100 | ; be an extra byte following the string to facilitate changing the string | ||
| 101 | ; into an ASCII-Z string. | ||
| 102 | ; | ||
| 103 | ; OUTPUT: | ||
| 104 | ; If CY = 0, the path is valid. | ||
| 105 | ; If CY = 1, The path is NOT valid: | ||
| 106 | ; | ||
| 107 | ;******************************************************************************** | ||
| 108 | PUBLIC CHECK_DOS_PATH_ROUTINE ;AN000; | ||
| 109 | CHECK_DOS_PATH_ROUTINE PROC FAR ;AN000; | ||
| 110 | ; | ||
| 111 | MOV PATH_PTR, SI ;AN000; Get the pointer from the path | ||
| 112 | MOV AX, [SI] ;AN000; Get the lenth of the path string | ||
| 113 | .IF < AX EQ 0 > ;AN000; If the length is zero then return that | ||
| 114 | JMP NO_ERROR_DOS_PATH ;AN000; the path is valid. | ||
| 115 | .ENDIF ;AN000; | ||
| 116 | MOV PATH_SIZE, AX ;AN000; Save the size of the string | ||
| 117 | ADD SI, 2 ;AN000; Adjust path pointer for length word | ||
| 118 | ; | ||
| 119 | .REPEAT ;AN000; Check all the path names in the string | ||
| 120 | MOV AL, ';' ;AN000; separator between filenames | ||
| 121 | MOV CX, PATH_PTR ;AN000; Get the pointer to the path | ||
| 122 | ADD CX, 2 ;AN000; Point to the start of the string | ||
| 123 | ADD CX, PATH_SIZE ;AN000; Add the size of the path | ||
| 124 | SUB CX, SI ;AN000; Subtract current pointer - Get length of string remaining | ||
| 125 | CALL ISOLATE_NEXT_PATH ;AN000; Make the next path name into an ASCII-Z string | ||
| 126 | PUSH SEP_POSITION ;AN000; Save the position of the path seperator | ||
| 127 | PUSH WORD PTR ZEROED_CHAR ;AN000; Save the character that was made into a zero | ||
| 128 | MOV CX, SEP_POSITION ;AN000; | ||
| 129 | SUB CX, SI ;AN000; Get the length of the string | ||
| 130 | MOV AX, 0101H ;AN000; | ||
| 131 | CALL FAR PTR CHECK_VALID_PATH ;AN000; Check if it is a valid filename | ||
| 132 | POP WORD PTR ZEROED_CHAR ;AN000; | ||
| 133 | POP SEP_POSITION ;AN000; | ||
| 134 | CALL RESTORE_SEPARATOR ;AN000; Restore the character between the path names | ||
| 135 | .IF < C > ;AN000; Was the file name not valid? | ||
| 136 | JMP ERROR_DOS_PATH ;AN000; Exit the subroutine | ||
| 137 | .ENDIF ;AN000; | ||
| 138 | MOV SI, DI ;AN000; Get the pointer to the next path name | ||
| 139 | .UNTIL < ZERO SI > ;AN000; If zero, all path names have been examined. | ||
| 140 | NO_ERROR_DOS_PATH: ;AN000; | ||
| 141 | CLC ;AN000; | ||
| 142 | JMP EXIT_DOS_PATH ;AN000; | ||
| 143 | ERROR_DOS_PATH: ;AN000; | ||
| 144 | STC ;AN000; | ||
| 145 | EXIT_DOS_PATH: ;AN000; | ||
| 146 | RET ;AN000; | ||
| 147 | ; | ||
| 148 | CHECK_DOS_PATH_ROUTINE ENDP ;AN000; | ||
| 149 | ; | ||
| 150 | ; | ||
| 151 | PUBLIC CHECK_VALID_PATH ;AN000; | ||
| 152 | ;******************************************************************************** | ||
| 153 | ; CHECK_VALID_PATH: Check to see if the sepecified path is valid. | ||
| 154 | ; | ||
| 155 | ; INPUT: | ||
| 156 | ; SI = Points to an ASCII-Z string containing the path to check. There sould | ||
| 157 | ; be an extra byte following the string to facilitate changing the string | ||
| 158 | ; into an ASCII-Z string. | ||
| 159 | ; | ||
| 160 | ; CX = The size of the string containing the path. The zero byte at the end | ||
| 161 | ; of the string is NOT included in the length. | ||
| 162 | ; | ||
| 163 | ; AL = 0: Drive letter cannot be specified. | ||
| 164 | ; = 1: Drive letter is optional and can be specified. | ||
| 165 | ; = 2: Drive letter must be specified. | ||
| 166 | ; | ||
| 167 | ; AH = 0: First non-drive character cannot be a backslash ('\') | ||
| 168 | ; = 1: First non-drive character may be a backslash ('\') | ||
| 169 | ; = 2: First non-drive character must be a backslash ('\') | ||
| 170 | ; | ||
| 171 | ; OUTPUT: | ||
| 172 | ; If CY = 0, the path is valid. | ||
| 173 | ; If CY = 1, The path is NOT valid: | ||
| 174 | ; AX = 1, The drive specified is invalid. | ||
| 175 | ; = 2, There was no drive specified. | ||
| 176 | ; = 3, There was a drive specified. | ||
| 177 | ; = 4, There was a leading backslash | ||
| 178 | ; = 5, The leading backslash was NOT present. | ||
| 179 | ; = 6, There was a trailing backslash. | ||
| 180 | ; | ||
| 181 | ;******************************************************************************** | ||
| 182 | CHECK_VALID_PATH PROC FAR ;AN000; | ||
| 183 | ; | ||
| 184 | PUSH DI ;AN000; | ||
| 185 | MOV STRING_SIZE, CX ;AN000; Save the size of the string | ||
| 186 | MOV PATH_STRING, SI ;AN000; Save the pointer to the string | ||
| 187 | CALL CHECK_VALID_DRIVE ;AN000; See if there is a valid drive | ||
| 188 | .IF < C > ;AN000; Is the drive specified invalid? | ||
| 189 | MOV AX, ERR_INVALID_DRV ;AN000; Return this error code | ||
| 190 | JMP EXIT_CHK_DRV ;AN000; Exit the subroutine | ||
| 191 | .ENDIF ;AN000; | ||
| 192 | .IF < BX EQ 0 > ;AN000; No drive sepecified? | ||
| 193 | .IF < AL EQ 2 > ;AN000; Must the drive be specified? | ||
| 194 | MOV AX, ERR_NO_DRIVE ;AN000; Return this error code | ||
| 195 | JMP EXIT_CHK_DRV ;AN000; Exit the subroutine | ||
| 196 | .ENDIF ;AN000; | ||
| 197 | .ELSE ;AN000; Otherwise, the drive WAS specified. | ||
| 198 | .IF < AL EQ 0 > ;AN000; The drive cannot be specified | ||
| 199 | MOV AX, ERR_DRIVE ;AN000; Return this error code | ||
| 200 | JMP EXIT_CHK_DRV ;AN000; Exit the subroutine | ||
| 201 | .ENDIF ;AN000; | ||
| 202 | ADD SI, 2 ;AN000; Push pointer past the drive | ||
| 203 | .ENDIF ;AN000; | ||
| 204 | .IF < <BYTE PTR [SI]> EQ '\' > ;AN000; Is the next byte a backslash? | ||
| 205 | .IF < AH EQ 0 > ;AN000; Is one permitted? | ||
| 206 | MOV AX, ERR_LEADING_SLASH ;AN000; No! Return this error code | ||
| 207 | JMP EXIT_CHK_DRV ;AN000; Exit the subroutine | ||
| 208 | .ELSE ;AN000; Otherwise, one allowed. | ||
| 209 | INC SI ;AN000; Push pointer past \ | ||
| 210 | .ENDIF ;AN000; | ||
| 211 | .ELSE ;AN000; Otherwise, byte not a backslash | ||
| 212 | .IF < AH EQ 2 > ;AN000; Was one required? | ||
| 213 | MOV AX, ERR_NO_SLASH ;AN000; If so, return this error code | ||
| 214 | JMP EXIT_CHK_DRV ;AN000; Exit from this subroutine | ||
| 215 | .ENDIF ;AN000; | ||
| 216 | .ENDIF ;AN000; | ||
| 217 | ; | ||
| 218 | MOV NUM_PATHS, 0 ;AN000; | ||
| 219 | .REPEAT ;AN000; Check all the path names in the string | ||
| 220 | MOV AL, '\' ;AN000; Separator between filenames | ||
| 221 | MOV CX, PATH_STRING ;AN000; | ||
| 222 | ADD CX, STRING_SIZE ;AN000; | ||
| 223 | SUB CX, SI ;AN000; | ||
| 224 | .IF < NUM_PATHS EQ 0 > AND ;AN000; If this is the first path checked...and | ||
| 225 | .IF < CX EQ 0 > ;AN000; If the length of the path is zero... | ||
| 226 | JMP EXIT_NO_ERROR ;AN000; Exit with no error | ||
| 227 | .ENDIF ;AN000; | ||
| 228 | CALL ISOLATE_NEXT_PATH ;AN000; Make the next path name into an ASCII-Z string | ||
| 229 | CALL CHECK_VALID_FILENAME ;AN000; Check if it is a valid filename | ||
| 230 | CALL RESTORE_SEPARATOR ;AN000; Restore the character between the path names | ||
| 231 | .IF < C > ;AN000; Was the file name not valid? | ||
| 232 | .IF < NUM_PATHS EQ 0 > ;AN000; | ||
| 233 | .LEAVE ;AN000; | ||
| 234 | .ELSE ;AN000; | ||
| 235 | MOV AX, ERR_INVALID_CHAR ;AN000; If not, return this error code | ||
| 236 | JMP EXIT_CHK_DRV ;AN000; Exit the subroutine | ||
| 237 | .ENDIF ;AN000; | ||
| 238 | .ENDIF ;AN000; | ||
| 239 | MOV SI, DI ;AN000; Get the pointer to the next path name | ||
| 240 | .UNTIL < ZERO SI > ;AN000; If zero, all path names have been examined. | ||
| 241 | ; | ||
| 242 | MOV SI, PATH_STRING ;AN000; Get the pointer to the whole string | ||
| 243 | ADD SI, STRING_SIZE ;AN000; Add the string length | ||
| 244 | DEC SI ;AN000; Point to the last character in the string | ||
| 245 | .IF < <BYTE PTR [SI]> EQ '\'> ;AN000; Is the last character a \ ? | ||
| 246 | MOV AX, ERR_LAST_SLASH ;AN000; If so, return this error code | ||
| 247 | JMP EXIT_CHK_DRV ;AN000; Exit from the subroutine | ||
| 248 | .ENDIF ;AN000; | ||
| 249 | EXIT_NO_ERROR: ;AN000; | ||
| 250 | CLC ;AN000; Indicate there were no errors | ||
| 251 | JMP EXIT_CHECK_PATH ;AN000; | ||
| 252 | ; | ||
| 253 | EXIT_CHK_DRV: ;AN000; | ||
| 254 | STC ;AN000; Indicate that there were errors | ||
| 255 | EXIT_CHECK_PATH: ;AN000; | ||
| 256 | POP DI ;AN000; | ||
| 257 | RET ;AN000; | ||
| 258 | ; | ||
| 259 | ; | ||
| 260 | CHECK_VALID_PATH ENDP ;AN000; | ||
| 261 | ;******************************************************************************** | ||
| 262 | ; CHECK_VALID_DRIVE: Check to see if there is a drive specified on the path and | ||
| 263 | ; if there is, is it valid. | ||
| 264 | ; | ||
| 265 | ; INPUT: | ||
| 266 | ; SI - Points to a string containing the path to search. | ||
| 267 | ; | ||
| 268 | ; OUTPUT: | ||
| 269 | ; If CY = 1, the drive is specified and is invalid | ||
| 270 | ; If CY = 0, The drive might be specified and is valid | ||
| 271 | ; BX = 0: The drive is NOT specified. | ||
| 272 | ; = 1: The drive IS specified. | ||
| 273 | ; | ||
| 274 | ; | ||
| 275 | ;******************************************************************************** | ||
| 276 | CHECK_VALID_DRIVE PROC NEAR ;AN000; | ||
| 277 | ; | ||
| 278 | PUSH AX ;AN000; Push all registers used | ||
| 279 | .IF < <BYTE PTR [SI+1]> EQ ':' > ;AN000; Is the second character in the string a ':' | ||
| 280 | MOV AL, [SI] ;AN000; If so, get the first character | ||
| 281 | .IF < AL AE 'A' > AND ;AN000; Is it a capital letter? | ||
| 282 | .IF < AL BE 'Z' > ;AN000; | ||
| 283 | CLC ;AN000; If so, drive valid. | ||
| 284 | MOV BX, 1 ;AN000; Indicate the drive exists | ||
| 285 | .ELSEIF < AL AE 'a' > AND ;AN000; Else, is the drive a lowercase letter? | ||
| 286 | .IF < AL BE 'z' > ;AN000; | ||
| 287 | CLC ;AN000; If so, the drive is valid | ||
| 288 | MOV BX, 1 ;AN000; Indicate that the drive exists | ||
| 289 | .ELSE ;AN000; Otherwise... | ||
| 290 | STC ;AN000; The drive is not valid | ||
| 291 | .ENDIF ;AN000; | ||
| 292 | .ELSE ;AN000; | ||
| 293 | CLC ;AN000; Indicate there were no errors | ||
| 294 | MOV BX, 0 ;AN000; The drive does not exist | ||
| 295 | .ENDIF ;AN000; | ||
| 296 | POP AX ;AN000; | ||
| 297 | ; | ||
| 298 | RET ;AN000; | ||
| 299 | ; | ||
| 300 | CHECK_VALID_DRIVE ENDP ;AN000; | ||
| 301 | ;******************************************************************************** | ||
| 302 | ; CHECK_VALID_FILENAME: Check to see if a filename is valid. | ||
| 303 | ; | ||
| 304 | ; INPUT: | ||
| 305 | ; SI - Points to an ASCII-Z string containing the filename to examine. | ||
| 306 | ; | ||
| 307 | ; OUTPUT: | ||
| 308 | ; If CY = 1, The filename is NOT valid. | ||
| 309 | ; If CY = 0, the filename IS valid. | ||
| 310 | ; | ||
| 311 | ; | ||
| 312 | ;******************************************************************************** | ||
| 313 | CHECK_VALID_FILENAME PROC NEAR ;AN000; | ||
| 314 | ; | ||
| 315 | INC NUM_PATHS ;AN000; | ||
| 316 | AND SEARCH_FLAG, RESET_PERIOD ;AN000; Indicate no periods have been found yet | ||
| 317 | MOV MAX_CHAR, 8 ;AN000; Up to 8 characters can be specified | ||
| 318 | MOV CHAR_COUNT, 0 ;AN000; Number of character so far | ||
| 319 | MOV AL, [SI] ;AN000; Get the first character in the string | ||
| 320 | .WHILE < AL NE 0 > ;AN000; Repeat untill we reach the string's end | ||
| 321 | INC CHAR_COUNT ;AN000; Increment number of characters in path | ||
| 322 | MOV BX, CHAR_COUNT ;AN000; | ||
| 323 | .IF < BX A MAX_CHAR > AND ;AN000; | ||
| 324 | .IF < AL NE '.' > ;AN000; | ||
| 325 | JMP INVALID_CHAR ;AN000; | ||
| 326 | .ENDIF ;AN000; | ||
| 327 | .IF < AL B 20 > ;AN000; Is the character's code less than 20? | ||
| 328 | JMP INVALID_CHAR ;AN000; If so, it's invalid | ||
| 329 | .ELSE ;AN000; Otherwise... | ||
| 330 | CALL VALID_CHAR ;AN000; See if it's invalid | ||
| 331 | .IF < C > ;AN000; If so, | ||
| 332 | JMP INVALID_CHAR ;AN000; Exit the subroutine | ||
| 333 | .ENDIF ;AN000; | ||
| 334 | .ENDIF ;AN000; | ||
| 335 | .IF < AL EQ '.' > ;AN000; Is the character a period? | ||
| 336 | .IF < BIT SEARCH_FLAG AND PERIOD > ;AN000; Is this the first one? | ||
| 337 | JMP INVALID_CHAR ;AN000; If not, filename is invalid. | ||
| 338 | .ELSE ;AN000; Otherwise... | ||
| 339 | OR SEARCH_FLAG, PERIOD ;AN000; Indicate that ONE has been found | ||
| 340 | .IF < CHAR_COUNT EQ 1 > ;AN000; Were there any characters before the period | ||
| 341 | JMP INVALID_CHAR ;AN000; If not, this is an invalid path | ||
| 342 | .ENDIF ;AN000; | ||
| 343 | MOV MAX_CHAR, 3 ;AN000; Allow three characters after the period | ||
| 344 | MOV CHAR_COUNT, 0 ;AN000; No characters yet | ||
| 345 | .ENDIF ;AN000; | ||
| 346 | .ENDIF ;AN000; | ||
| 347 | INC SI ;AN000; Point to next character | ||
| 348 | MOV AL, [SI] ;AN000; Get that character | ||
| 349 | .ENDWHILE ;AN000; | ||
| 350 | .IF < CHAR_COUNT EQ 0 > AND ;AN000; | ||
| 351 | .IF < MAX_CHAR EQ 8 > ;AN000; | ||
| 352 | DEC NUM_PATHS ;AN000; | ||
| 353 | JMP INVALID_CHAR ;AN000; | ||
| 354 | .ENDIF ;AN000; | ||
| 355 | CLC ;AN000; Indicate the name is valid | ||
| 356 | JMP CK_V_FILENAME ;AN000; Exit. | ||
| 357 | ; | ||
| 358 | INVALID_CHAR: ;AN000; Indicate that the name is not valid | ||
| 359 | STC ;AN000; | ||
| 360 | CK_V_FILENAME: ;AN000; | ||
| 361 | RET ;AN000; | ||
| 362 | ; | ||
| 363 | CHECK_VALID_FILENAME ENDP ;AN000; | ||
| 364 | ;******************************************************************************** | ||
| 365 | ; VALID_CHAR: Determine if a character is valid for a filename. | ||
| 366 | ; | ||
| 367 | ; INPUT: | ||
| 368 | ; AL = The character to check. | ||
| 369 | ; | ||
| 370 | ; OUTPUT: | ||
| 371 | ; If CY = 1, the character is not valid. | ||
| 372 | ; If CY = 0, the character IS valid. | ||
| 373 | ; | ||
| 374 | ;******************************************************************************** | ||
| 375 | VALID_CHAR PROC NEAR ;AN000; | ||
| 376 | ; | ||
| 377 | PUSH CX ;AN000; Save the registers used. | ||
| 378 | PUSH DI ;AN000; | ||
| 379 | PUSH ES ;AN000; | ||
| 380 | ; | ||
| 381 | MOV DI, OFFSET INVALID_STRING ;AN000; Get the address of string containing invalid characters | ||
| 382 | PUSH DS ;AN000; Save the data segment | ||
| 383 | POP ES ;AN000; Make ES=DS | ||
| 384 | MOV CX, SIZE_INVALID_STR ;AN000; Get the size of the string | ||
| 385 | CLD ;AN000; Scan forward | ||
| 386 | REPNZ SCASB ;AN000; See if this character is in the invalid string | ||
| 387 | .IF < Z > ;AN000; If so, | ||
| 388 | STC ;AN000; Indicate the character is invalid | ||
| 389 | .ELSE ;AN000; Otherwise... | ||
| 390 | CLC ;AN000; Indicate the character is valid | ||
| 391 | .ENDIF ;AN000; | ||
| 392 | POP CX ;AN000; Restore the registers | ||
| 393 | POP DI ;AN000; | ||
| 394 | POP ES ;AN000; | ||
| 395 | RET ;AN000; | ||
| 396 | ; | ||
| 397 | VALID_CHAR ENDP ;AN000; | ||
| 398 | ;******************************************************************************** | ||
| 399 | ; ISOLATE_NEXT_PATH: Search the filename for a '\'. If found, it is replaced | ||
| 400 | ; by a zero making the string into an ASCII-Z string. | ||
| 401 | ; | ||
| 402 | ; INPUT: | ||
| 403 | ; SI - Points to the first character in the path string | ||
| 404 | ; AL - Contains the character to search for | ||
| 405 | ; CX - Contains the length of the string | ||
| 406 | ; | ||
| 407 | ; OUTPUT: | ||
| 408 | ; DI - Points to the character following the next '\' | ||
| 409 | ; If this character is the last path element, DI = 0. | ||
| 410 | ; | ||
| 411 | ; ZEROED_CHAR is loaded with the character which is made into a zero. | ||
| 412 | ; | ||
| 413 | ;******************************************************************************** | ||
| 414 | ISOLATE_NEXT_PATH PROC NEAR ;AN000; | ||
| 415 | ; | ||
| 416 | PUSH AX ;AN000; Save registers used. | ||
| 417 | PUSH BX ;AN000; | ||
| 418 | PUSH CX ;AN000; | ||
| 419 | PUSH SI ;AN000; | ||
| 420 | ; | ||
| 421 | PUSH ES ;AN000; Make ES = DS | ||
| 422 | PUSH DS ;AN000; | ||
| 423 | POP ES ;AN000; | ||
| 424 | MOV DI, SI ;AN000; Copy the string pointer | ||
| 425 | ; CX holds the length of string after the pointer DI | ||
| 426 | ; AL holds the character to search for | ||
| 427 | CLD ;AN000; Search in the forward direction | ||
| 428 | REPNZ SCASB ;AN000; Search... | ||
| 429 | JNZ END_FOUND ;AN000; If NZ, we reached the string's end | ||
| 430 | MOV ZEROED_CHAR, AL ;AN000; Character overwritten with zero | ||
| 431 | MOV SEP_POSITION, DI ;AN000; Save the position of overwritten char | ||
| 432 | DEC SEP_POSITION ;AN000; | ||
| 433 | MOV BYTE PTR [DI-1], 0 ;AN000; Make the character a zero | ||
| 434 | CMP CX,0 ;AN031; SEH User may have entered semicolon as last char, so check | ||
| 435 | JE END_FOUND2 ;AN031; SEH if it is last char instead of just a separator | ||
| 436 | JMP EXIT_ISOLATE ;AN000; Exit the subroutine | ||
| 437 | END_FOUND: ;AN000; | ||
| 438 | MOV AL, [DI] ;AN000; Get the last character | ||
| 439 | MOV ZEROED_CHAR, AL ;AN000; Save it. | ||
| 440 | MOV SEP_POSITION, DI ;AN000; Save its position | ||
| 441 | MOV BYTE PTR [DI], 0 ;AN000; Make into a zero | ||
| 442 | END_FOUND2: ;AN031; SEH Handle case of semicolon as last character in path | ||
| 443 | MOV DI, 0 ;AN000; Indicate the string is finished | ||
| 444 | EXIT_ISOLATE: ;AN000; | ||
| 445 | POP ES ;AN000; Restore the registers. | ||
| 446 | POP SI ;AN000; | ||
| 447 | POP CX ;AN000; | ||
| 448 | POP BX ;AN000; | ||
| 449 | POP AX ;AN000; | ||
| 450 | ; | ||
| 451 | RET ;AN000; | ||
| 452 | ; | ||
| 453 | ISOLATE_NEXT_PATH ENDP ;AN000; | ||
| 454 | ;******************************************************************************** | ||
| 455 | ; RESTORE_SEPARATOR: Restore the character which separates the characters in | ||
| 456 | ; a path. | ||
| 457 | ; | ||
| 458 | ; INPUT: | ||
| 459 | ; SEP_POSITION - Contain the address of the location to restore the separator. | ||
| 460 | ; ZEROED_CHAR - Contains the character to be restored. | ||
| 461 | ; | ||
| 462 | ; OUTPUT: | ||
| 463 | ; None. | ||
| 464 | ; | ||
| 465 | ;******************************************************************************** | ||
| 466 | RESTORE_SEPARATOR PROC NEAR ;AN000; | ||
| 467 | ; | ||
| 468 | PUSH AX ;AN000; Save registers used | ||
| 469 | PUSH SI ;AN000; | ||
| 470 | MOV SI, SEP_POSITION ;AN000; Get the position of the character | ||
| 471 | MOV AL, ZEROED_CHAR ;AN000; Get the character | ||
| 472 | MOV [SI], AL ;AN000; Save character in this position | ||
| 473 | POP SI ;AN000; Restore the registers | ||
| 474 | POP AX ;AN000; | ||
| 475 | RET ;AN000; | ||
| 476 | ; | ||
| 477 | RESTORE_SEPARATOR ENDP ;AN000; | ||
| 478 | ;******************************************************************************** | ||
| 479 | ; CHANGE_ATTRIBUTE_ROUTINE: Change the attributes on a group of files. | ||
| 480 | ; | ||
| 481 | ; INPUT: | ||
| 482 | ; SI = The address of a list of files to change the attributes of. | ||
| 483 | ; AX = 0: Attach a new attribute to the file. | ||
| 484 | ; AX = 1: Restore the original attribute to the files. | ||
| 485 | ; BX = The number of files in the list. | ||
| 486 | ; | ||
| 487 | ; OUTPUT: | ||
| 488 | ; If CY = 1, there were error encountered. | ||
| 489 | ; If CY = 0, there were no errors. | ||
| 490 | ; | ||
| 491 | ;******************************************************************************** | ||
| 492 | PUBLIC CHANGE_ATTRIBUTE_ROUTINE ;AN000; | ||
| 493 | CHANGE_ATTRIBUTE_ROUTINE PROC FAR ;AN000; | ||
| 494 | ; | ||
| 495 | CALL HOOK_INT_24 ;AN000; | ||
| 496 | ; | ||
| 497 | MOV WAY, AX ;AN000; Save flag indicating whether we are setting or restoring the attrb. | ||
| 498 | MOV NEW_ATTRIB, 02h ;AN000; Set new attribute to hidden. | ||
| 499 | MOV DI, 0 ;AN000; Count of files processed | ||
| 500 | .WHILE < DI B BX > ;AN000; | ||
| 501 | .IF < WAY EQ 0 > ;AN000; Setting the attribute? | ||
| 502 | MOV WORD PTR [SI+12],0 ;AN000; Make filename into a ASCII-Z string | ||
| 503 | MOV DX, SI ;AN000; Load address of filename into DX | ||
| 504 | MOV AX, 4300H ;AN000; Get the file's current attribute | ||
| 505 | DOSCALL ;AN000; | ||
| 506 | .IF < C > ;AN000; Was there an error? | ||
| 507 | JMP CHMOD_ERROR ;AN000; If so, exit the subroutine | ||
| 508 | .ENDIF ;AN000; | ||
| 509 | MOV OLD_ATTRIB, CX ;AN000; Save the attribute | ||
| 510 | MOV CX, NEW_ATTRIB ;AN000; Get the new attribute | ||
| 511 | .ELSE ;AN000; Otherwise, we are restoring the attribute | ||
| 512 | MOV CX, [SI+12] ;AN000; Get the old attribute | ||
| 513 | MOV OLD_ATTRIB, CX ;AN000; Save. | ||
| 514 | MOV WORD PTR [SI+12], 0 ;AN000; Make filename into an ASCII-Z string | ||
| 515 | .ENDIF ;AN000; | ||
| 516 | MOV DX, SI ;AN000; Pointer to the filename | ||
| 517 | MOV AX, 4301H ;AN000; DOS function for setting the attribute | ||
| 518 | DOSCALL ;AN000; Set it. | ||
| 519 | .IF < C > ;AN000; Was there an error? | ||
| 520 | JMP CHMOD_ERROR ;AN000; If so, exit the subroutine | ||
| 521 | .ENDIF ;AN000; | ||
| 522 | MOV CX, OLD_ATTRIB ;AN000; Get the old attribute | ||
| 523 | MOV [SI+12], CX ;AN000; Save in the table | ||
| 524 | ADD SI, 14 ;AN000; Point to the next filename | ||
| 525 | INC DI ;AN000; Increment count of files processed | ||
| 526 | .ENDWHILE ;AN000; | ||
| 527 | CLC ;AN000; Indicate there were no errors | ||
| 528 | RET ;AN000; | ||
| 529 | ; | ||
| 530 | CHMOD_ERROR: ;AN000; | ||
| 531 | STC ;AN000; Indicate there were errors | ||
| 532 | ; | ||
| 533 | CALL RESTORE_INT_24 ;AN000; | ||
| 534 | ; | ||
| 535 | RET ;AN000; | ||
| 536 | ; | ||
| 537 | CHANGE_ATTRIBUTE_ROUTINE ENDP ;AN000; | ||
| 538 | ;**************************************************************************** | ||
| 539 | ; | ||
| 540 | ; COMPARE_ROUTINE: Compare two strings. | ||
| 541 | ; | ||
| 542 | ; INPUT: | ||
| 543 | ; SI = The address of the first string. (ASCII-N string) | ||
| 544 | ; DI = The address of the second string. (ASCII-N string) | ||
| 545 | ; | ||
| 546 | ; OUTPUT: | ||
| 547 | ; If CY = 1, the strings do no compare. | ||
| 548 | ; If CY = 0, the strings are the same. | ||
| 549 | ; | ||
| 550 | ; OPERATION: | ||
| 551 | ; | ||
| 552 | ;**************************************************************************** | ||
| 553 | PUBLIC COMPARE_ROUTINE ;AN000; | ||
| 554 | COMPARE_ROUTINE PROC FAR ;AN000; | ||
| 555 | ; | ||
| 556 | PUSH ES ;AN000; Make ES = DS | ||
| 557 | PUSH DS ;AN000; | ||
| 558 | POP ES ;AN000; | ||
| 559 | ; | ||
| 560 | MOV CX, [SI] ;AN000; Get the length of the first string | ||
| 561 | .IF < [DI] NE CX > ;AN000; Are the lengths of the strings the same? | ||
| 562 | JMP DO_NOT_COMPARE ;AN000; If not, the strings are not the same | ||
| 563 | .ENDIF ;AN000; | ||
| 564 | ADD SI, 2 ;AN000; Move points past the length words | ||
| 565 | ADD DI, 2 ;AN000; | ||
| 566 | CLD ;AN000; Compare in the forward direction | ||
| 567 | REPZ CMPSB ;AN000; Compare the strings | ||
| 568 | JNZ DO_NOT_COMPARE ;AN000; If the zero flag cleared, strings are not the same | ||
| 569 | CLC ;AN000; Indicate the strings do compare | ||
| 570 | JMP EXIT_COMPARE ;AN000; | ||
| 571 | DO_NOT_COMPARE: ;AN000; | ||
| 572 | STC ;AN000; Indicate the strings do no compare | ||
| 573 | EXIT_COMPARE: ;AN000; | ||
| 574 | POP ES ;AN000; | ||
| 575 | RET ;AN000; | ||
| 576 | ; | ||
| 577 | COMPARE_ROUTINE ENDP ;AN000; | ||
| 578 | ;**************************************************************************** | ||
| 579 | ; | ||
| 580 | ; REMOVE_END_BLANKS: Removes the trailing blanks from a string. | ||
| 581 | ; | ||
| 582 | ; INPUT: | ||
| 583 | ; ES:DI Points to the last character in the string. | ||
| 584 | ; | ||
| 585 | ; OUTPUT: | ||
| 586 | ; ES:DI Points to the new end of the string after the blanks have been | ||
| 587 | ; removed. | ||
| 588 | ; | ||
| 589 | ; OPERATION: | ||
| 590 | ; | ||
| 591 | ;**************************************************************************** | ||
| 592 | PUBLIC REMOVE_END_BLANKS ;AN000; | ||
| 593 | REMOVE_END_BLANKS PROC FAR ;AN000; | ||
| 594 | ; | ||
| 595 | MOV CX, 0FFFFH ;AN000; | ||
| 596 | MOV AL, ' ' ;AN000; | ||
| 597 | STD ;AN000; | ||
| 598 | REPZ SCASB ;AN000; | ||
| 599 | .IF < NZ > ;AN000; | ||
| 600 | INC DI ;AN000; | ||
| 601 | .ENDIF ;AN000; | ||
| 602 | RET ;AN000; | ||
| 603 | ; | ||
| 604 | REMOVE_END_BLANKS ENDP ;AN000; | ||
| 605 | ; | ||
| 606 | ;**************************************************************************** | ||
| 607 | ; | ||
| 608 | ; CHECK_WRITE_ROUTINE Determine if the diskette in drive A is write | ||
| 609 | ; protected. | ||
| 610 | ; | ||
| 611 | ; INPUT: | ||
| 612 | ; CX = 0 - drive A ;AN000;JW | ||
| 613 | ; = 1 - drive B ;AN000;JW | ||
| 614 | ; | ||
| 615 | ; OUTPUT: | ||
| 616 | ; If CY = 1, The disk IS write protected. | ||
| 617 | ; If CY = 0, The disk is NOT write protected. | ||
| 618 | ; | ||
| 619 | ; OPERATION: | ||
| 620 | ; | ||
| 621 | ;**************************************************************************** | ||
| 622 | PUBLIC CHECK_WRITE_ROUTINE ;AN000; | ||
| 623 | CHECK_WRITE_ROUTINE PROC FAR ;AN000; | ||
| 624 | ; | ||
| 625 | MOV DRIVE_FLAG,CL ;AN000; | ||
| 626 | ; | ||
| 627 | CALL HOOK_INT_24 ;AN000; | ||
| 628 | ; | ||
| 629 | MOV CHK_W_PROTECT_FLAG, TRUE ;AN000; Indicate to INT 24H handler we are looking for error | ||
| 630 | MOV W_PROTECT_FLAG, FALSE ;AN000; Error has not occured yet. | ||
| 631 | ; | ||
| 632 | MOV W_P_FILENAME_A+3, 0 ;AN000; Make drive string into ASCII-Z string | ||
| 633 | MOV W_P_FILENAME_B+3, 0 ;AN000; Make drive string into ASCII-Z string JW | ||
| 634 | .IF < DRIVE_FLAG eq DRIVE_A > ;AN000;JW | ||
| 635 | MOV DX, OFFSET W_P_FILENAME_A ;AN000; Get address of the string | ||
| 636 | .ELSE ;AN000;JW | ||
| 637 | MOV DX, OFFSET W_P_FILENAME_B ;AN000; Get address of the string JW | ||
| 638 | .ENDIF ;AN000;JW | ||
| 639 | MOV CX, 0 ;AN000; Attribute to give the file | ||
| 640 | MOV INT_24_ERROR, FALSE ;AN000; | ||
| 641 | MOV AH, 5AH ;AN000; DOS Fn. call to create a unique file | ||
| 642 | DOSCALL ;AN000; Create the file | ||
| 643 | .IF < C > ;AN000; Was there an error? | ||
| 644 | .IF < W_PROTECT_FLAG EQ TRUE > ;AN000; If the INT 24H handler was call... | ||
| 645 | JMP WRITE_PROTECTED ;AN000; The disk is write protected. | ||
| 646 | .ELSE ;AN000; Otherwise... | ||
| 647 | JMP CHECK_ERROR ;AN000; There was some other disk error | ||
| 648 | .ENDIF ;AN000; | ||
| 649 | .ELSE ;AN000; | ||
| 650 | .IF < W_PROTECT_FLAG EQ TRUE > ;AN000; If the INT 24H handler was call... | ||
| 651 | JMP WRITE_PROTECTED ;AN000; The disk is write protected. | ||
| 652 | .ENDIF ;AN000; | ||
| 653 | .ENDIF ;AN000; There were no errors... | ||
| 654 | CLOSE_FILE AX ;AN000; Close the created file | ||
| 655 | .IF < DRIVE_FLAG eq DRIVE_A > ;AN000;JW | ||
| 656 | MOV DX, OFFSET W_P_FILENAME_A ;AN000; Get address of the string | ||
| 657 | .ELSE ;AN000;JW | ||
| 658 | MOV DX, OFFSET W_P_FILENAME_B ;AN000; Get address of the string JW | ||
| 659 | .ENDIF ;AN000;JW | ||
| 660 | MOV AH, 41H ;AN000; DOS Fn. for erasing a file | ||
| 661 | DOSCALL ;AN000; Erase the file | ||
| 662 | MOV AX, 0 ;AN000; Indicate the file is NOT write protected | ||
| 663 | CLC ;AN000; Indicate there were no errors | ||
| 664 | JMP CHECK_EXIT ;AN000; Exit the routine | ||
| 665 | |||
| 666 | WRITE_PROTECTED: ;AN000; | ||
| 667 | MOV AX, 1 ;AN000; Indicate the file IS write protected | ||
| 668 | CLC ;AN000; Indicate there were no errors | ||
| 669 | JMP CHECK_EXIT ;AN000; | ||
| 670 | |||
| 671 | CHECK_ERROR: ;AN000; | ||
| 672 | MOV AX, 0 ;AN000; Indicate the file is NOT write protected | ||
| 673 | STC ;AN000; Indicate that there WERE errors | ||
| 674 | |||
| 675 | CHECK_EXIT: ;AN000; | ||
| 676 | CALL RESTORE_INT_24 ;AN000; Restore the original INT 24H handler | ||
| 677 | MOV CHK_W_PROTECT_FLAG, FALSE ;AN000; We are no longer expecting a write protect error | ||
| 678 | RET ;AN000; | ||
| 679 | |||
| 680 | CHECK_WRITE_ROUTINE ENDP ;AN000; | ||
| 681 | ;**************************************************************************** | ||
| 682 | ; | ||
| 683 | ; MATCH_FILES_ROUTINE Determine is a list of file exist on a drive. | ||
| 684 | ; | ||
| 685 | ; INPUT: | ||
| 686 | ; DI = Address of the ASCII-N string containing the drive and path to | ||
| 687 | ; search for the files. | ||
| 688 | ; SI = The address of the list of file. If AX = 2, the first two bytes | ||
| 689 | ; in the list are ignored. | ||
| 690 | ; AX = The type of list to use. | ||
| 691 | ; = 1: Use a list with only 12 bytes between the filenames. | ||
| 692 | ; = 2: Use a list with only 14 bytes between the filenames. | ||
| 693 | ; CX = The number of files in the list. | ||
| 694 | ; | ||
| 695 | ; OUTPUT: | ||
| 696 | ; If CY = 1, There was an error access the disk. | ||
| 697 | ; If CY = 0, There were no errors. | ||
| 698 | ; AX = 1: All the files are on the disk. | ||
| 699 | ; AX = 0: All the files are NOT on the disk. | ||
| 700 | ; | ||
| 701 | ; OPERATION: | ||
| 702 | ; | ||
| 703 | ;**************************************************************************** | ||
| 704 | PUBLIC MATCH_FILES_ROUTINE ;AN000; | ||
| 705 | MATCH_FILES_ROUTINE PROC FAR ;AN000; | ||
| 706 | ; | ||
| 707 | ; | ||
| 708 | PUSH ES ;AN000; Make ES = DS | ||
| 709 | PUSH DS ;AN000; | ||
| 710 | POP ES ;AN000; | ||
| 711 | ; | ||
| 712 | MOV NUM_FILES, CX ;AN000; Save the number of files | ||
| 713 | MOV LIST_TYPE, AX ;AN000; Save the type of the list | ||
| 714 | ; | ||
| 715 | MOV CX, [DI] ;AN000; Get the length of the string | ||
| 716 | ADD DI, 2 ;AN000; Point SI to the start of the string | ||
| 717 | MOV DX, DI ;AN000; Copy the address of the string | ||
| 718 | ADD DI, CX ;AN000; Point to the end of the string | ||
| 719 | .IF < LIST_TYPE EQ 2 > ;AN000; If this list is a 14 byte list... | ||
| 720 | ADD SI, 2 ;AN000; Bypass the first two bytes in the list | ||
| 721 | .ENDIF ;AN000; | ||
| 722 | MOV STR_PTR, DI ;AN000; Save the pointer to the path string | ||
| 723 | MOV FILE_PTR, SI ;AN000; Save the pointer to the file list | ||
| 724 | MOV BX, 0 ;AN000; Initialize the count of files checked | ||
| 725 | ; | ||
| 726 | .WHILE < BX B NUM_FILES > ;AN000; Perform NUM_FILES interations | ||
| 727 | CLD ;AN000; | ||
| 728 | MOV CX, 12 ;AN000; Move 12 bytes for the filename | ||
| 729 | REP MOVSB ;AN000; Move the filename after the path string | ||
| 730 | MOV BYTE PTR [DI], 0 ;AN000; Make string into an ASCII-Z string | ||
| 731 | MOV AH, 4EH ;AN000; DOS Fn. for find a file | ||
| 732 | MOV CX, 0 ;AN000; Attribute used for search | ||
| 733 | DOSCALL ;AN000; Get the matching filename | ||
| 734 | .IF < C > ;AN000; Was there an error? | ||
| 735 | .IF < AX EQ 18 > ;AN000; If error no = 18, then file not found | ||
| 736 | JMP FILE_NOT_FOUND ;AN000; Return to the user | ||
| 737 | .ELSE ;AN000; Otherwise | ||
| 738 | JMP MATCH_ERROR ;AN000; There was some other type of disk error | ||
| 739 | .ENDIF ;AN000; Exit the subroutine | ||
| 740 | .ENDIF ;AN000; | ||
| 741 | MOV DI, STR_PTR ;AN000; Get the pointer to the string | ||
| 742 | MOV SI, FILE_PTR ;AN000; Get the pointer to the file list | ||
| 743 | .IF < LIST_TYPE EQ 1 > ;AN000; Check list type for incrementing the file pointer | ||
| 744 | ADD SI, 12 ;AN000; 12 bytes between files for list type 1 | ||
| 745 | .ELSE ;AN000; | ||
| 746 | ADD SI, 14 ;AN000; 14 bytes between files for list type 2 | ||
| 747 | .ENDIF ;AN000; | ||
| 748 | MOV FILE_PTR, SI ;AN000; Save the new file name pointer | ||
| 749 | INC BX ;AN000; Increment the count of files searched for | ||
| 750 | .ENDWHILE ;AN000; | ||
| 751 | CLC ;AN000; Indicate there were no errors | ||
| 752 | MOV AX, 1 ;AN000; Indicate that all the files were found | ||
| 753 | JMP EXIT_MATCH ;AN000; | ||
| 754 | FILE_NOT_FOUND: ;AN000; | ||
| 755 | CLC ;AN000; Indicate that there were no errors | ||
| 756 | MOV AX, 0 ;AN000; But, all the files were not found | ||
| 757 | JMP EXIT_MATCH ;AN000; | ||
| 758 | MATCH_ERROR: ;AN000; | ||
| 759 | STC ;AN000; Indicate that there were errors | ||
| 760 | EXIT_MATCH: ;AN000; | ||
| 761 | POP ES ;AN000; | ||
| 762 | RET ;AN000; | ||
| 763 | ; | ||
| 764 | MATCH_FILES_ROUTINE ENDP ;AN000; | ||
| 765 | ;************************************************************************ | ||
| 766 | ; | ||
| 767 | ; CLOSE_FILE_ROUTINE: Close File | ||
| 768 | ; | ||
| 769 | ; INPUT: | ||
| 770 | ; BX = The file handle of the file to close. | ||
| 771 | ; | ||
| 772 | ; OUTPUT: | ||
| 773 | ; CY = 0, AX = undefined, successful | ||
| 774 | ; CY = 1, AX = error code | ||
| 775 | ; | ||
| 776 | ; OPERATION: | ||
| 777 | ; | ||
| 778 | ; THIS MACROS CLOSES THE FILE WITH THE GIVEN FILE HANDLE. | ||
| 779 | ; IT MAKES USE OF INT 21 (AH=3EH). | ||
| 780 | ; IF AN ERROR OCCURS, THE CARRY FLAG IS SET, AND THE ERROR CODE | ||
| 781 | ; IS RETURNED IN AX. | ||
| 782 | ; | ||
| 783 | ;************************************************************************** | ||
| 784 | PUBLIC CLOSE_FILE_ROUTINE ;AN000; | ||
| 785 | CLOSE_FILE_ROUTINE PROC FAR ;AN000; | ||
| 786 | ; | ||
| 787 | ; | ||
| 788 | CALL HOOK_INT_24 ;AN000; Hook in the critical error handler | ||
| 789 | MOV INT_24_ERROR, FALSE ;AN000; Indicate no critical error have occured yet | ||
| 790 | MOV AH, 3EH ;AN000; DOS Fn. for closing a file | ||
| 791 | DOSCALL ;AN000; Close the file | ||
| 792 | CALL RESTORE_INT_24 ;AN000; Restore the old critical error handler | ||
| 793 | RET ;AN000; | ||
| 794 | ; | ||
| 795 | CLOSE_FILE_ROUTINE ENDP ;AN000; | ||
| 796 | ;************************************************************** | ||
| 797 | ; | ||
| 798 | ; CREATE_FILE: Create new File | ||
| 799 | ; | ||
| 800 | ; INPUT: | ||
| 801 | ; DI = The address of the filename in ASCII-N format | ||
| 802 | ; CX = The attribute to give the file | ||
| 803 | ; | ||
| 804 | ; OUTPUT: | ||
| 805 | ; If CY = 0: There were no errors. | ||
| 806 | ; AX - The file handle of the created file. | ||
| 807 | ; If CY = 1: There were file errors. AX contains the error code. | ||
| 808 | ; | ||
| 809 | ; OPERATION: | ||
| 810 | ; | ||
| 811 | ; CREATE_FILE CREATES A FILE WITH THE GIVEN NAME USING INT 21H (AH=5BH) | ||
| 812 | ; IF AN ERROR OCCURS, THE CARRY FLAG IS SET, AND THE ERROR CODE | ||
| 813 | ; IS RETURNED IN AX. | ||
| 814 | ; | ||
| 815 | ;************************************************************************** | ||
| 816 | PUBLIC CREATE_FILE_ROUTINE ;AN000; | ||
| 817 | CREATE_FILE_ROUTINE PROC FAR ;AN000; | ||
| 818 | ; | ||
| 819 | CALL HOOK_INT_24 ;AN000; | ||
| 820 | CALL POS_ZERO ;AN000; | ||
| 821 | MOV DX, DI ;AN000; | ||
| 822 | ADD DX, 2 ;AN000; | ||
| 823 | MOV INT_24_ERROR, FALSE ;AN000; | ||
| 824 | MOV AH,5BH ;AN000; | ||
| 825 | DOSCALL ;AN000; | ||
| 826 | CALL RESTORE_INT_24 ;AN000; | ||
| 827 | RET ;AN000; | ||
| 828 | ; | ||
| 829 | CREATE_FILE_ROUTINE ENDP ;AN000; | ||
| 830 | ;**************************************************************************** | ||
| 831 | ; | ||
| 832 | ; ERASE_FILE_ROUTINE: Routine to erase a file. | ||
| 833 | ; | ||
| 834 | ; INPUT: | ||
| 835 | ; DI - The address of an ASCII-N string containing the name of the file | ||
| 836 | ; to erase. | ||
| 837 | ; | ||
| 838 | ; OUTPUT: | ||
| 839 | ; If CY = 0, there were no error encountered. | ||
| 840 | ; If CY = 1, there were errors. AX contains the DOS error code. | ||
| 841 | ; | ||
| 842 | ; OPERATION: | ||
| 843 | ; | ||
| 844 | ; ERASE_FILE ERASES THE FILE USING INT 21H (AH=41H). | ||
| 845 | ; IF AN ERROR OCCURS, THE CARRY FLAG IS SET, AND THE ERROR CODE | ||
| 846 | ; IS RETURNED IN AX. | ||
| 847 | ; | ||
| 848 | ;**************************************************************************** | ||
| 849 | PUBLIC ERASE_FILE_ROUTINE ;AN000; | ||
| 850 | ERASE_FILE_ROUTINE PROC FAR ;AN000; | ||
| 851 | |||
| 852 | CALL HOOK_INT_24 ;AN000; | ||
| 853 | CALL POS_ZERO ;AN000; | ||
| 854 | MOV INT_24_ERROR, FALSE ;AN000; | ||
| 855 | MOV DX, DI ;AN000; | ||
| 856 | ADD DX, 2 ;AN000; | ||
| 857 | MOV AH,41H ;AN000; | ||
| 858 | DOSCALL ;AN000; | ||
| 859 | CALL RESTORE_INT_24 ;AN000; | ||
| 860 | RET ;AN000; | ||
| 861 | |||
| 862 | ERASE_FILE_ROUTINE ENDP ;AN000; | ||
| 863 | ;**************************************************************************** | ||
| 864 | ; | ||
| 865 | ; CHMOD_FILE_ROUTINE: Change file attributes to read/write | ||
| 866 | ; | ||
| 867 | ; SYNTAX: CHMOD_FILE_ROUTINE | ||
| 868 | ; | ||
| 869 | ; INPUT: DI = POINTER TO ASCII-N STRING - FILE NAME | ||
| 870 | ; | ||
| 871 | ; OUTPUT: None. | ||
| 872 | ; | ||
| 873 | ; OPERATION: | ||
| 874 | ; The CHMOD dos call is executed (43H) to change the file's attributes | ||
| 875 | ; to read/write. | ||
| 876 | ; | ||
| 877 | ;**************************************************************************** | ||
| 878 | PUBLIC CHMOD_FILE_ROUTINE ;AN000; | ||
| 879 | CHMOD_FILE_ROUTINE PROC FAR ;AN000; | ||
| 880 | |||
| 881 | CALL HOOK_INT_24 ;AN000; | ||
| 882 | CALL POS_ZERO ;AN000; | ||
| 883 | MOV INT_24_ERROR, FALSE ;AN000; | ||
| 884 | MOV DX, DI ;AN000; | ||
| 885 | ADD DX, 2 ;AN000; | ||
| 886 | MOV AH,043H ;AN000; | ||
| 887 | MOV AL,01 ;AN000; | ||
| 888 | XOR CX,CX ;AN000; | ||
| 889 | DOSCALL ;AN000; | ||
| 890 | CALL RESTORE_INT_24 ;AN000; | ||
| 891 | RET ;AN000; | ||
| 892 | |||
| 893 | CHMOD_FILE_ROUTINE ENDP ;AN000; | ||
| 894 | ;************************************************************************ | ||
| 895 | ; FIND_FILE: Find File | ||
| 896 | ; | ||
| 897 | ; INPUT: | ||
| 898 | ; DI - The address of an ASCII-N string contian the name of the file | ||
| 899 | ; to find. | ||
| 900 | ; CX - The attribute to be used in the search. | ||
| 901 | ; | ||
| 902 | ; OUTPUT: | ||
| 903 | ; If CY = 1, there were errors encountered. AX contians the DOS error | ||
| 904 | ; code. | ||
| 905 | ; If CY = 0, there were no errors. | ||
| 906 | ; | ||
| 907 | ; OPERATION: | ||
| 908 | ; | ||
| 909 | ; FINDFILE FINDS THE FIRST FILENAME SPECIFIED USING INT 21 (AH=4EH). | ||
| 910 | ; AND LOADS INFORMATION INTO THE CURRENT DTA. | ||
| 911 | ; NOTE : THE DEFAULT DTA IS AT 80H IN THE PSP. | ||
| 912 | ; IF AN ERROR OCCURS, THE CARRY FLAG IS SET, AND THE ERROR CODE | ||
| 913 | ; IS RETURNED IN AX. | ||
| 914 | ; | ||
| 915 | ;************************************************************************ | ||
| 916 | PUBLIC FIND_FILE_ROUTINE ;AN000; | ||
| 917 | FIND_FILE_ROUTINE PROC FAR ;AN000; | ||
| 918 | ; | ||
| 919 | CALL HOOK_INT_24 ;AN000; | ||
| 920 | CALL POS_ZERO ;AN000; | ||
| 921 | MOV DX, DI ;AN000; | ||
| 922 | ADD DX, 2 ;AN000; | ||
| 923 | MOV INT_24_ERROR, FALSE ;AN000; | ||
| 924 | ; CX Contains the attribute to be used in the search | ||
| 925 | MOV AH,4EH ;AN000; | ||
| 926 | DOSCALL ;AN000; | ||
| 927 | CALL RESTORE_INT_24 ;AN000; | ||
| 928 | RET ;AN000; | ||
| 929 | |||
| 930 | FIND_FILE_ROUTINE ENDP ;AN000; | ||
| 931 | ;************************************************************************** | ||
| 932 | ; | ||
| 933 | ; OPEN_FILE_ROUTINE - Open File | ||
| 934 | ; | ||
| 935 | ; INPUT: | ||
| 936 | ; DI - The address of an ASCII-N string containing the name of the | ||
| 937 | ; file to open. | ||
| 938 | ; AL - The mode to open the file with ( 0 = read, 1 = write, | ||
| 939 | ; 2 = read/write) | ||
| 940 | ; | ||
| 941 | ; OUTPUT: | ||
| 942 | ; If CY = 1, there were errors encountered. AX contains the DOS error | ||
| 943 | ; code. | ||
| 944 | ; If CY = 0, there were no errors. AX contains the file handle. | ||
| 945 | ; | ||
| 946 | ; OPERATION: | ||
| 947 | ; | ||
| 948 | ; THIS MACRO OPENS A FILE FOR READ/WRITE OPERATIONS. | ||
| 949 | ; IT MAKES USE OF INT 21 (AH=3DH). | ||
| 950 | ; IF AN ERROR OCCURS, THE CARRY FLAG IS SET, AND THE ERROR CODE | ||
| 951 | ; IS RETURNED IN AX. | ||
| 952 | ; | ||
| 953 | ;************************************************************************** | ||
| 954 | PUBLIC OPEN_FILE_ROUTINE ;AN000; | ||
| 955 | OPEN_FILE_ROUTINE PROC FAR ;AN000; | ||
| 956 | ; | ||
| 957 | CALL HOOK_INT_24 ;AN000; | ||
| 958 | CALL POS_ZERO ;AN000; | ||
| 959 | MOV INT_24_ERROR, FALSE ;AN000; | ||
| 960 | MOV DX, DI ;AN000; | ||
| 961 | ADD DX, 2 ;AN000; | ||
| 962 | ; AL contains the mode for opening the file. | ||
| 963 | MOV AH,3DH ;AN000; | ||
| 964 | DOSCALL ;AN000; | ||
| 965 | CALL RESTORE_INT_24 ;AN000; | ||
| 966 | RET ;AN000; | ||
| 967 | |||
| 968 | OPEN_FILE_ROUTINE ENDP ;AN000; | ||
| 969 | ;************************************************************************** | ||
| 970 | ; | ||
| 971 | ; RENAME_FILE_ROUTINE - Rename File | ||
| 972 | ; | ||
| 973 | ; INPUT: | ||
| 974 | ; SI - The address of an ASCII-N string containing the file to rename | ||
| 975 | ; current file name. | ||
| 976 | ; DI - The address of an ASCII-N string containing the new name for the | ||
| 977 | ; file. | ||
| 978 | ; | ||
| 979 | ; OUTPUT: | ||
| 980 | ; If CY = 1, there were errors encountered. AX contains the DOS error | ||
| 981 | ; error code. | ||
| 982 | ; If CY = 0, there were no errors. | ||
| 983 | ; | ||
| 984 | ; | ||
| 985 | ; OPERATION: | ||
| 986 | ; | ||
| 987 | ; THIS MACRO RENAMES A FILE GIVEN 2 NAMES. | ||
| 988 | ; IT MAKES USE OF INT 21 (AH=56H). | ||
| 989 | ; IF AN ERROR OCCURS, THE CARRY FLAG IS SET, AND THE ERROR CODE | ||
| 990 | ; IS RETURNED IN AX. | ||
| 991 | ; | ||
| 992 | ;************************************************************************** | ||
| 993 | PUBLIC RENAME_FILE_ROUTINE ;AN000; | ||
| 994 | RENAME_FILE_ROUTINE PROC FAR ;AN000; | ||
| 995 | |||
| 996 | CALL HOOK_INT_24 ;AN000; | ||
| 997 | PUSH ES ;AN000; | ||
| 998 | PUSH DS ;AN000; | ||
| 999 | POP ES ;AN000; | ||
| 1000 | PUSH DI ;AN000; | ||
| 1001 | ; SI Contains the address of the string containing the old filename. | ||
| 1002 | MOV DI, SI ;AN000; | ||
| 1003 | CALL POS_ZERO ;AN000; | ||
| 1004 | MOV DX, DI ;AN000; | ||
| 1005 | ADD DX, 2 ;AN000; | ||
| 1006 | |||
| 1007 | POP DI ;AN000; | ||
| 1008 | ; DI contains the address of the string containing the new filename. | ||
| 1009 | CALL POS_ZERO ;AN000; | ||
| 1010 | ADD DI, 2 ;AN000; | ||
| 1011 | |||
| 1012 | MOV INT_24_ERROR, FALSE ;AN000; | ||
| 1013 | MOV AH,56H ;AN000; | ||
| 1014 | DOSCALL ;AN000; | ||
| 1015 | POP ES ;AN000; | ||
| 1016 | CALL RESTORE_INT_24 ;AN000; | ||
| 1017 | RET ;AN000; | ||
| 1018 | |||
| 1019 | RENAME_FILE_ROUTINE ENDP ;AN000; | ||
| 1020 | ;************************************************************************** | ||
| 1021 | ; | ||
| 1022 | ; READ_FILE_ROUTINE: Transfer the specified number of bytes from a file into a | ||
| 1023 | ; buffer location. | ||
| 1024 | ; | ||
| 1025 | ; INPUT: | ||
| 1026 | ; BX - The handle of the file to read. | ||
| 1027 | ; DX - The address of where to store the data | ||
| 1028 | ; CX - The number of characters to read | ||
| 1029 | ; | ||
| 1030 | ; OUTPUT: | ||
| 1031 | ; CY = 0, Read success. AX - number of bytes read | ||
| 1032 | ; CY = 1, Read error. AX contains the error code. | ||
| 1033 | ; | ||
| 1034 | ; OPERATION: | ||
| 1035 | ; | ||
| 1036 | ; THIS MACRO READS TO AN ALREADY OPENED FILE. | ||
| 1037 | ; IT MAKES USE OF INT 21 (AH=3FH). | ||
| 1038 | ; AX WILL RETURN THE NUMBER BYTES ACTUALLY WRITTEN. | ||
| 1039 | ; | ||
| 1040 | ;************************************************************************ | ||
| 1041 | PUBLIC READ_FILE_ROUTINE ;AN000; | ||
| 1042 | READ_FILE_ROUTINE PROC FAR ;AN000; | ||
| 1043 | ; | ||
| 1044 | CALL HOOK_INT_24 ;AN000; | ||
| 1045 | MOV INT_24_ERROR, FALSE ;AN000; | ||
| 1046 | ; BX - The file handle | ||
| 1047 | ; CX - The number of bytes to read | ||
| 1048 | ; DX - The address of the buffer to store the data | ||
| 1049 | MOV AH,3FH ;AN000; | ||
| 1050 | DOSCALL ;AN000; | ||
| 1051 | CALL RESTORE_INT_24 ;AN000; | ||
| 1052 | RET ;AN000; | ||
| 1053 | |||
| 1054 | READ_FILE_ROUTINE ENDP ;AN000; | ||
| 1055 | ;************************************************************************** | ||
| 1056 | ; | ||
| 1057 | ; WRITE_FILE_ROUTINE: Transfer the specified number of bytes from a buffer into a | ||
| 1058 | ; specified file. | ||
| 1059 | ; | ||
| 1060 | ; INPUT: | ||
| 1061 | ; BX - The handle of the file to write to. | ||
| 1062 | ; DX - The address of where the data is stored. | ||
| 1063 | ; CX - The number of characters to write. | ||
| 1064 | ; | ||
| 1065 | ; OUTPUT: | ||
| 1066 | ; CY = 0, Write success. AX - number of bytes written. | ||
| 1067 | ; CY = 1, Write error. AX contains the error code. | ||
| 1068 | ; | ||
| 1069 | ; OPERATION: | ||
| 1070 | ; | ||
| 1071 | ; THIS MACRO WRITES TO AN ALREADY OPENED FILE. | ||
| 1072 | ; IT MAKES USE OF INT 21 (AH=3DH). | ||
| 1073 | ; AX WILL RETURN THE NUMBER BYTES ACTUALLY WRITTEN. | ||
| 1074 | ; | ||
| 1075 | ;************************************************************************ | ||
| 1076 | PUBLIC WRITE_FILE_ROUTINE ;AN000; | ||
| 1077 | WRITE_FILE_ROUTINE PROC FAR ;AN000; | ||
| 1078 | ; | ||
| 1079 | CALL HOOK_INT_24 ;AN000; | ||
| 1080 | MOV INT_24_ERROR, FALSE ;AN000; | ||
| 1081 | ; BX - The file handle | ||
| 1082 | ; CX - The number of bytes to read | ||
| 1083 | ; DX - The address of the buffer to store the data | ||
| 1084 | MOV AH,40H ;AN000; | ||
| 1085 | DOSCALL ;AN000; | ||
| 1086 | CALL RESTORE_INT_24 ;AN000; | ||
| 1087 | RET ;AN000; | ||
| 1088 | |||
| 1089 | WRITE_FILE_ROUTINE ENDP ;AN000; | ||
| 1090 | ;*************************************************************************** | ||
| 1091 | ; | ||
| 1092 | ; CHECK_DISK: Check is the specified fixed disk is present. If disk is | ||
| 1093 | ; present, return disk partition status. | ||
| 1094 | ; | ||
| 1095 | ; INPUT: | ||
| 1096 | ; AX = 1: First fixed disk. | ||
| 1097 | ; = 2: Second fixed disk. | ||
| 1098 | ; | ||
| 1099 | ; OUTPUT: | ||
| 1100 | ; CX = 0: Disk not present. | ||
| 1101 | ; = 1: Disk present - No DOS or EDOS partitions | ||
| 1102 | ; = 2: Disk present - DOS or EDOS partitions exist | ||
| 1103 | ; BX = 01H: Primary DOS partition exists | ||
| 1104 | ; = 02H: Extended DOS partitions exists | ||
| 1105 | ; = 04H: Logical drives exist | ||
| 1106 | ; = 08H: Free space exists in EDOS partition | ||
| 1107 | ; = 10H: Free space exists on disk | ||
| 1108 | ; More than one status bit can be set | ||
| 1109 | ; DX = 0: There is no free space in EDOS partition and the | ||
| 1110 | ; disk. | ||
| 1111 | ; = 1: There is free space in the EDOS partition. | ||
| 1112 | ; = 2: There is no EDOS partition, but there is free | ||
| 1113 | ; disk space. | ||
| 1114 | ; DI = Buffer for fixed disk status information. | ||
| 1115 | ; | ||
| 1116 | ; OPERATION: A call is performed to the FDISK utility (GET_DISK_STATUS) | ||
| 1117 | ; to get the status of the specified fixed disk drive. The returned | ||
| 1118 | ; status information is checked and the memory variables are set as | ||
| 1119 | ; specified above. | ||
| 1120 | ; | ||
| 1121 | ;*************************************************************************** | ||
| 1122 | PUBLIC CHECK_DISK_ROUTINE ;AN000; | ||
| 1123 | CHECK_DISK_ROUTINE PROC FAR ;AN000; | ||
| 1124 | ; | ||
| 1125 | PUSH ES ;AN000; Make ES = DS | ||
| 1126 | PUSH DS ;AN000; | ||
| 1127 | POP ES ;AN000; | ||
| 1128 | PUSH DI ;AN000; | ||
| 1129 | ADD DI, 2 ;AN000; | ||
| 1130 | CALL GGET_STATUS ;AN000; | ||
| 1131 | POP DI ;AN000; | ||
| 1132 | MOV [DI+1], CL ;AN000; Store the number of table entries | ||
| 1133 | .IF < ZERO AX > ;AN000; | ||
| 1134 | .IF < BIT BX AND M_DOS_EDOS_PART > ;AN000; | ||
| 1135 | MOV CX, PRESENT_WITH_PART ;AN000; | ||
| 1136 | .ELSE ;AN000; | ||
| 1137 | MOV CX, PRESENT_WITHOUT_PART ;AN000; | ||
| 1138 | .ENDIF ;AN000; | ||
| 1139 | .ELSE ;AN000; | ||
| 1140 | MOV CX, NOT_PRESENT ;AN000; | ||
| 1141 | .ENDIF ;AN000; | ||
| 1142 | MOV DX, NO_EDOS_SPACE ;AN000; Initialize | ||
| 1143 | .IF < BIT BX AND M_EDOS_EXISTS > ;AN000; Does the extended DOS partition exist? | ||
| 1144 | .IF < BIT BX AND M_EDOS_SPACE > ;AN000; Yes! Is there free space in it? | ||
| 1145 | MOV DX, FREE_EDOS_SPACE ;AN000; Indicate that there is free space | ||
| 1146 | .ELSEIF < BIT BX NAND M_FREE_SPACE > ;AN000; Is there no free space on the disk? | ||
| 1147 | MOV DX, NO_EDOS_SPACE ;AN000; Indicate there is no free space in EDOS or on the disk. | ||
| 1148 | .ENDIF ;AN000; | ||
| 1149 | .ELSEIF < BIT BX AND M_FREE_SPACE > ;AN000; No! There is no EDOS partition | ||
| 1150 | MOV DX, NO_EDOS_BUT_SPACE ;AN000; But there is free space on the disk | ||
| 1151 | .ENDIF ;AN000; | ||
| 1152 | POP ES ;AN000; | ||
| 1153 | RET ;AN000; | ||
| 1154 | ; | ||
| 1155 | CHECK_DISK_ROUTINE ENDP ;AN000; | ||
| 1156 | ;************************************************************************;; | ||
| 1157 | ; | ||
| 1158 | ; CHECK_VALID_MEDIA: Check if the diskettes attached will support | ||
| 1159 | ; installation of SELECT. Also, check if install destination will | ||
| 1160 | ; be selected by user or determined by SELECT. | ||
| 1161 | ; | ||
| 1162 | ; SYNTAX: CHECK_VALID_MEDIA var_disk_a, var_disk_b, var_tot, var_disk, | ||
| 1163 | ; var_def, var_index, var_option | ||
| 1164 | ; | ||
| 1165 | ; INPUT: | ||
| 1166 | ; var_disk_a = diskette A presence and type | ||
| 1167 | ; var_disk_b = diskette B presence and type | ||
| 1168 | ; var_tot = total number of dikettes | ||
| 1169 | ; var_disk = 0: first fixed disk is not present | ||
| 1170 | ; > 0: first fixed disk is present | ||
| 1171 | ; | ||
| 1172 | ; OUTPUT: | ||
| 1173 | ; CY = 0: Success variables are returned as defined below. | ||
| 1174 | ; CY = 1: Error - invalid media | ||
| 1175 | ; var_def = 0 use default destination drive | ||
| 1176 | ; = 1 default destination drive not applicable | ||
| 1177 | ; var_index = 1 default destination is drive C | ||
| 1178 | ; = 2 default destination is drive B | ||
| 1179 | ; var_option = 1 possible drive B or C | ||
| 1180 | ; = 2 possible drive A or C | ||
| 1181 | ; = 3 possible drive A or B or C | ||
| 1182 | ; = 4 possible drive A or B | ||
| 1183 | ; | ||
| 1184 | ; OPERATION: The diskette drive types are checked for valid media type. | ||
| 1185 | ; If the diskette media types are valid, a check is made to determine if | ||
| 1186 | ; install destination will be user selected or will be determined by | ||
| 1187 | ; SELECT. The following checks are made. | ||
| 1188 | ; | ||
| 1189 | ; - if one diskette, return valid media and default destination is A | ||
| 1190 | ; | ||
| 1191 | ; - If two diskettes only, return valid and: | ||
| 1192 | ; if A = B, default = B | ||
| 1193 | ; if A <> B, default = A | ||
| 1194 | ; if A and B are mixed 720 and 1.44, destination option is A or B | ||
| 1195 | ; | ||
| 1196 | ; - If one diskette and a fixed disk only, return valid media and | ||
| 1197 | ; destination option is drive A or C. | ||
| 1198 | ; | ||
| 1199 | ; - If two diskettes and a fixed disk, return valid media and: | ||
| 1200 | ; if A = B, destination option is B or C | ||
| 1201 | ; if A <> B, destination option is A or C | ||
| 1202 | ; if A and B are mixed 720 and 1.44, destination option is | ||
| 1203 | ; A or B or C | ||
| 1204 | ; | ||
| 1205 | ;************************************************************************;; | ||
| 1206 | PUBLIC CHECK_VALID_MEDIA_ROUTINE ;AN111;JW | ||
| 1207 | CHECK_VALID_MEDIA_ROUTINE PROC FAR ;AN111;JW | ||
| 1208 | |||
| 1209 | |||
| 1210 | VAR_DISK_A EQU AL ;AN111;JW | ||
| 1211 | VAR_DISK_B EQU BL ;AN111;JW | ||
| 1212 | VAR_DEF EQU CL ;AN111;JW | ||
| 1213 | VAR_INDEX EQU DX ;AN111;JW | ||
| 1214 | VAR_DISK EQU SI ;AN111;JW | ||
| 1215 | VAR_OPTION EQU DI ;AN111;JW | ||
| 1216 | |||
| 1217 | .IF < VAR_DISK_A NE E_DISKETTE_INV > ;AN111; Is disk A present | ||
| 1218 | .IF <VAR_DISK_B NE E_DISKETTE_INV> ;AN111; Is disk B present | ||
| 1219 | .IF < VAR_DISK GT 0 > ;AN111; Hard disk is present? | ||
| 1220 | MOV VAR_DEF, DO_NOT_USE_DEFAULT ;AN111; Yes! Destination drive is undefined | ||
| 1221 | MOV VAR_OPTION,E_OPTION_B_C ;AN111; options will be B or C | ||
| 1222 | MOV VAR_INDEX,DEF_DEST_C ;AN073; SEH highlight option C | ||
| 1223 | CLC ;AN111; Indicate valid media | ||
| 1224 | .ELSE ;AN111; | ||
| 1225 | MOV VAR_DEF, USE_DEFAULT ;AN111; Yes! Use the default destination = B | ||
| 1226 | MOV VAR_INDEX, DEF_DEST_B ;AN111; Drive B is that default | ||
| 1227 | CLC ;AN111; Indicate valid media | ||
| 1228 | .ENDIF ;AN111; | ||
| 1229 | .ELSE ;AN111; | ||
| 1230 | .IF < VAR_DISK GT 0 > ;AN111; Hard disk is present? | ||
| 1231 | MOV VAR_DEF, DO_NOT_USE_DEFAULT ;AN111; Yes! Destination drive is undefined | ||
| 1232 | MOV VAR_OPTION, E_OPTION_A_C ;AN111; options are A or C | ||
| 1233 | MOV VAR_INDEX,DEF_DEST_C ;AN073; SEH highlight option C | ||
| 1234 | CLC ;AN111; Indicate valid media | ||
| 1235 | .ELSE ;AN111; | ||
| 1236 | MOV VAR_DEF, USE_DEFAULT ;AN111; no, Use the default destination | ||
| 1237 | MOV VAR_INDEX, DEF_DEST_A ;AN111; Drive A is that default | ||
| 1238 | CLC ;AN111; Indicate valid media | ||
| 1239 | .ENDIF ;AN111; | ||
| 1240 | .ENDIF ;AN111; | ||
| 1241 | .ELSE ;AN111; | ||
| 1242 | STC ;AN111; Indicate invalid media | ||
| 1243 | .ENDIF ;AN111; | ||
| 1244 | RET ;AN111; | ||
| 1245 | |||
| 1246 | CHECK_VALID_MEDIA_ROUTINE ENDP ;AN111;JW | ||
| 1247 | ;************************************************************************;; | ||
| 1248 | ; | ||
| 1249 | ; SCAN_DISK_TABLE: Scan the specified disk status table from the | ||
| 1250 | ; specified index item for specified field and return status information. | ||
| 1251 | ; | ||
| 1252 | ; INPUT: | ||
| 1253 | ; CX = 1: First fixed disk | ||
| 1254 | ; = 2: Second fixed disk | ||
| 1255 | ; AX = Index of the information to return | ||
| 1256 | ; | ||
| 1257 | ; OUTPUT: | ||
| 1258 | ; AX = 0: Success - Index into table is valid | ||
| 1259 | ; = 1: Error - Index invalid or end of table | ||
| 1260 | ; N_NAME_PART = Partition name. | ||
| 1261 | ; N_SIZE_PART = Partition size. | ||
| 1262 | ; N_STATUS_PART = Partition status | ||
| 1263 | ; P_DRIVE_PART = Drive letter assigned. | ||
| 1264 | ; P_LEVEL1_PART = Version number (1st part). For DOS 4.00 1st part = blank | ||
| 1265 | ; P_LEVEL2_PART = Version number (2nd part). For DOS 4.00 2nd part = 4 | ||
| 1266 | ; P_LEVEL3_PART = Version number (3rd part). For DOS 4.00 3rd part = . | ||
| 1267 | ; P_LEVEL4_PART = Version number (4th part). For DOS 4.00 4th part = 0 | ||
| 1268 | ; | ||
| 1269 | ; OPERATION: | ||
| 1270 | ; Starts scanning the disk table from the point indicated by var_index | ||
| 1271 | ; for either the name, status or type. The table is scanned until either | ||
| 1272 | ; the desired entry is found, or the end of the table is reached. If | ||
| 1273 | ; the end of the table is reached before a matching entry is found, then | ||
| 1274 | ; var_ret returns 1, else if an entry is found, it returns 0. | ||
| 1275 | ; If found, var_index will also return the index of the entry. | ||
| 1276 | ; | ||
| 1277 | ; Note: The index of the first entry in the table is 1. | ||
| 1278 | ; | ||
| 1279 | ;************************************************************************;; | ||
| 1280 | PUBLIC SCAN_DISK_TABLE_ROUTINE ;AN000; | ||
| 1281 | SCAN_DISK_TABLE_ROUTINE PROC FAR ;AN000; | ||
| 1282 | |||
| 1283 | MOV BX, 0 ;AN000; | ||
| 1284 | .IF < CX EQ TABLE_ONE > ;AN000; | ||
| 1285 | MOV SI, OFFSET DISK_1_START ;AN000; Get the address of the first table | ||
| 1286 | MOV BL, DISK_1_VAL_ITEM ;AN000; Number of entries in the first table | ||
| 1287 | .ELSE ;AN000; | ||
| 1288 | MOV SI, OFFSET DISK_2_START ;AN000; Get the address of the second table | ||
| 1289 | MOV BL, DISK_2_VAL_ITEM ;AN000; Number of entries in the second table | ||
| 1290 | .ENDIF ;AN000; | ||
| 1291 | .IF < AX BE BX > ;AN000; | ||
| 1292 | ; AX contains the index | ||
| 1293 | DEC AX ;AN000; Make the first index a 0 | ||
| 1294 | MOV DX, TYPE DISK_STATUS ;AN000; Number of bytes in the structure | ||
| 1295 | MUL DX ;AN000; Calculate the offset into the table | ||
| 1296 | ADD SI, AX ;AN000; Add to the address of the table | ||
| 1297 | COPY_BYTE N_NAME_PART, [SI].N_PART_NAME ;AN000; Copy the table entries | ||
| 1298 | COPY_WORD N_SIZE_PART, [SI].N_PART_SIZE ;AN000; | ||
| 1299 | COPY_BYTE N_STATUS_PART, [SI].N_PART_STATUS ;AN000; | ||
| 1300 | COPY_BYTE P_DRIVE_PART, [SI].P_PART_DRIVE ;AN000; | ||
| 1301 | COPY_BYTE N_TYPE_PART, [SI].N_PART_TYPE ;AN000; | ||
| 1302 | COPY_BYTE N_LEVEL1_PART, [SI].N_PART_LEVEL1 ;AN065;SEH 1st part of version number For DOS 4.00 1st part = blank | ||
| 1303 | COPY_BYTE N_LEVEL2_PART, [SI].N_PART_LEVEL2 ;AN065;SEH 2nd part of version number For DOS 4.00 2nd part = 4 | ||
| 1304 | COPY_BYTE N_LEVEL3_PART, [SI].N_PART_LEVEL3 ;AN065;SEH 2nd part of version number For DOS 4.00 3rd part = . | ||
| 1305 | COPY_BYTE N_LEVEL4_PART, [SI].N_PART_LEVEL4 ;AN065;SEH 2nd part of version number For DOS 4.00 4th part = 0 | ||
| 1306 | MOV AX, DATA_VALID ;AN000; | ||
| 1307 | .ELSE ;AN000; | ||
| 1308 | MOV AX, DATA_INVALID ;AN000; | ||
| 1309 | .ENDIF ;AN000; | ||
| 1310 | RET ;AN000; | ||
| 1311 | |||
| 1312 | SCAN_DISK_TABLE_ROUTINE ENDP ;AN000; | ||
| 1313 | ;************************************************************************;; | ||
| 1314 | ; | ||
| 1315 | ; UPDATE_DISK_TABLE: Update the specifed disk status table for the | ||
| 1316 | ; specified index item. | ||
| 1317 | ; | ||
| 1318 | ; INPUT: | ||
| 1319 | ; CX = 1: First fixed disk | ||
| 1320 | ; = 2: Second fixed disk | ||
| 1321 | ; AX = Index into table | ||
| 1322 | ; | ||
| 1323 | ; OUTPUT: | ||
| 1324 | ; AX = 0: Success - Index into table is valid | ||
| 1325 | ; = 1: Error - Index into table is not valid | ||
| 1326 | ; partition name = N_NAME_PART | ||
| 1327 | ; partition size = N_SIZE_PART | ||
| 1328 | ; partition status = N_STATUS_PART | ||
| 1329 | ; partition type = N_TYPE_PART | ||
| 1330 | ; drive letter = P_DRIVE_PART | ||
| 1331 | ; | ||
| 1332 | ; OPERATION: If the index into the disk table is valid, the disk table | ||
| 1333 | ; is updated for the specifed index. Disk status information is obtained | ||
| 1334 | ; from pre-defined locations as specified above. | ||
| 1335 | ; | ||
| 1336 | ;************************************************************************;; | ||
| 1337 | PUBLIC UPDATE_DISK_TABLE_ROUTINE ;AN000; | ||
| 1338 | UPDATE_DISK_TABLE_ROUTINE PROC FAR ;AN000; | ||
| 1339 | |||
| 1340 | MOV BH, 0 ;AN000; | ||
| 1341 | .IF < CX EQ TABLE_ONE > ;AN000; | ||
| 1342 | MOV SI, OFFSET DISK_1_START ;AN000; Get the address of the first table | ||
| 1343 | MOV BL, DISK_1_VAL_ITEM ;AN000; Number of entries in the first table | ||
| 1344 | .ELSE ;AN000; | ||
| 1345 | MOV SI, OFFSET DISK_2_START ;AN000; Get the address of the second table | ||
| 1346 | MOV BL, DISK_2_VAL_ITEM ;AN000; Number of entries in the second table | ||
| 1347 | .ENDIF ;AN000; | ||
| 1348 | ; AX contains the index. | ||
| 1349 | DEC AX ;AN000; Make the first index a 0 | ||
| 1350 | MOV DX, TYPE DISK_STATUS ;AN000; Number of bytes in the structure | ||
| 1351 | MUL DX ;AN000; Calculate the offset into the table | ||
| 1352 | ADD SI, AX ;AN000; Add to the address of the table | ||
| 1353 | .IF < VAR_INDEX BE BX > ;AN000; | ||
| 1354 | COPY_BYTE [SI].N_PART_NAME, N_NAME_PART ;AN000; | ||
| 1355 | COPY_WORD [SI].N_PART_SIZE, N_SIZE_PART ;AN000; | ||
| 1356 | COPY_BYTE [SI].N_PART_STATUS, N_STATUS_PART ;AN000; | ||
| 1357 | COPY_BYTE [SI].P_PART_DRIVE, P_DRIVE_PART ;AN000; | ||
| 1358 | COPY_BYTE [SI].N_PART_TYPE, N_TYPE_PART ;AN000; | ||
| 1359 | MOV AX, DATA_VALID ;AN000; No error. | ||
| 1360 | .ELSE ;AN000; | ||
| 1361 | MOV AX, DATA_INVALID ;AN000; Indicate an error | ||
| 1362 | .ENDIF ;AN000; | ||
| 1363 | RET ;AN000; | ||
| 1364 | ; | ||
| 1365 | UPDATE_DISK_TABLE_ROUTINE ENDP ;AN000; | ||
| 1366 | ; | ||
| 1367 | CODE_FAR ENDS ;AN000; | ||
| 1368 | ; | ||
| 1369 | END ;AN000; | ||