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/DOS/DIR.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/DOS/DIR.ASM')
| -rw-r--r-- | v4.0/src/DOS/DIR.ASM | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/v4.0/src/DOS/DIR.ASM b/v4.0/src/DOS/DIR.ASM new file mode 100644 index 0000000..2a86997 --- /dev/null +++ b/v4.0/src/DOS/DIR.ASM | |||
| @@ -0,0 +1,445 @@ | |||
| 1 | ; SCCSID = @(#)dir.asm 1.1 85/04/10 | ||
| 2 | ; SCCSID = @(#)dir.asm 1.1 85/04/10 | ||
| 3 | TITLE DIR - Directory and path cracking | ||
| 4 | NAME Dir | ||
| 5 | ; Main Path cracking routines, low level search routines | ||
| 6 | ; | ||
| 7 | ; FindEntry | ||
| 8 | ; SEARCH | ||
| 9 | ; Srch | ||
| 10 | ; NEXTENT | ||
| 11 | ; MetaCompare | ||
| 12 | ; NEXTENTRY | ||
| 13 | ; GETENTRY | ||
| 14 | ; GETENT | ||
| 15 | ; SETDIRSRCH | ||
| 16 | ; SETROOTSRCH | ||
| 17 | ; | ||
| 18 | ; Revision history: | ||
| 19 | ; | ||
| 20 | ; A000 version 4.00 Jan. 1988 | ||
| 21 | ; | ||
| 22 | |||
| 23 | ; | ||
| 24 | ; get the appropriate segment definitions | ||
| 25 | ; | ||
| 26 | .xlist | ||
| 27 | include dosseg.asm | ||
| 28 | include fastopen.inc | ||
| 29 | |||
| 30 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 31 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 32 | |||
| 33 | .xcref | ||
| 34 | include dossym.inc | ||
| 35 | .cref | ||
| 36 | .list | ||
| 37 | |||
| 38 | asmvar Kanji | ||
| 39 | |||
| 40 | i_need EntFree,WORD | ||
| 41 | i_need DirStart,WORD | ||
| 42 | i_need LastEnt,WORD | ||
| 43 | i_need ClusNum,WORD | ||
| 44 | i_need CurBuf,DWORD | ||
| 45 | i_need Attrib,BYTE | ||
| 46 | i_need DelAll,BYTE | ||
| 47 | i_need VolID,BYTE | ||
| 48 | i_need Name1,BYTE | ||
| 49 | i_need ThisDPB,DWORD | ||
| 50 | i_need EntLast,WORD | ||
| 51 | i_need Creating,BYTE | ||
| 52 | i_need SecClusPos,BYTE | ||
| 53 | i_need ClusFac,BYTE | ||
| 54 | i_need NxtClusNum,WORD | ||
| 55 | i_need DirSec,DWORD ;AN000; | ||
| 56 | I_need FastOpenFlg,BYTE ;AN000; | ||
| 57 | I_need HIGH_SECTOR,WORD ;AN000; | ||
| 58 | |||
| 59 | Break <FINDENTRY -- LOOK FOR AN ENTRY> | ||
| 60 | |||
| 61 | ; Inputs: | ||
| 62 | ; [THISDPB] set | ||
| 63 | ; [SECCLUSPOS] = 0 | ||
| 64 | ; [DIRSEC] = Starting directory sector number | ||
| 65 | ; [CLUSNUM] = Next cluster of directory | ||
| 66 | ; [CLUSFAC] = Sectors/Cluster | ||
| 67 | ; [NAME1] = Name to look for | ||
| 68 | ; Function: | ||
| 69 | ; Find file name in disk directory. | ||
| 70 | ; "?" matches any character. | ||
| 71 | ; Outputs: | ||
| 72 | ; Carry set if name not found | ||
| 73 | ; ELSE | ||
| 74 | ; Zero set if attributes match (always except when creating) | ||
| 75 | ; AH = Device ID (bit 7 set if not disk) | ||
| 76 | ; [THISDPB] = Base of drive parameters | ||
| 77 | ; DS = DOSGROUP | ||
| 78 | ; ES = DOSGROUP | ||
| 79 | ; [CURBUF+2]:BX = Pointer into directory buffer | ||
| 80 | ; [CURBUF+2]:SI = Pointer to First Cluster field in directory entry | ||
| 81 | ; [CURBUF] has directory record with match | ||
| 82 | ; [NAME1] has file name | ||
| 83 | ; [LASTENT] is entry number of the entry | ||
| 84 | ; All other registers destroyed. | ||
| 85 | |||
| 86 | procedure SEARCH,near | ||
| 87 | |||
| 88 | entry FindEntry | ||
| 89 | DOSAssume CS,<DS>,"FindEntry" | ||
| 90 | ASSUME ES:NOTHING | ||
| 91 | |||
| 92 | invoke STARTSRCH | ||
| 93 | MOV AL,Attrib | ||
| 94 | AND AL,NOT attr_ignore ; Ignore useless bits | ||
| 95 | CMP AL,attr_volume_id ; Looking for vol ID only ? | ||
| 96 | JNZ NOTVOLSRCH ; No | ||
| 97 | CALL SETROOTSRCH ; Yes force search of root | ||
| 98 | NOTVOLSRCH: | ||
| 99 | CALL GETENTRY | ||
| 100 | JNC Srch | ||
| 101 | JMP SETESRET | ||
| 102 | |||
| 103 | entry Srch | ||
| 104 | |||
| 105 | PUSH DS | ||
| 106 | MOV DS,WORD PTR [CURBUF+2] | ||
| 107 | ASSUME DS:NOTHING | ||
| 108 | MOV AH,BYTE PTR [BX] | ||
| 109 | OR AH,AH ; End of directory? | ||
| 110 | JZ FREE | ||
| 111 | CMP AH,BYTE PTR [DELALL] ; Free entry? | ||
| 112 | JZ FREE | ||
| 113 | TEST BYTE PTR [BX+11],attr_volume_id | ||
| 114 | ; Volume ID file? | ||
| 115 | JZ CHKFNAM ; NO | ||
| 116 | INC BYTE PTR [VOLID] | ||
| 117 | CHKFNAM: | ||
| 118 | ; Context ES | ||
| 119 | ASSUME ES:DOSGroup | ||
| 120 | MOV SI,SS | ||
| 121 | MOV ES,SI | ||
| 122 | MOV SI,BX | ||
| 123 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 124 | ;;;;; 7/29/86 | ||
| 125 | CMP BYTE PTR [NAME1],0E5H ; special char check | ||
| 126 | JNZ NO_E5 | ||
| 127 | MOV BYTE PTR [NAME1],05H | ||
| 128 | NO_E5: | ||
| 129 | ;;;;; 7/29/86 | ||
| 130 | CALL MetaCompare | ||
| 131 | JZ FOUND | ||
| 132 | POP DS | ||
| 133 | |||
| 134 | entry NEXTENT | ||
| 135 | DOSAssume CS,<DS>,"NextEnt" | ||
| 136 | |||
| 137 | Assert ISDPB,<<WORD PTR THISDPB+2>,<WORD PTR THISDPB>>,"NextEnt" | ||
| 138 | LES BP,[THISDPB] | ||
| 139 | ASSUME ES:NOTHING | ||
| 140 | CALL NEXTENTRY | ||
| 141 | JNC SRCH | ||
| 142 | JMP SHORT SETESRET | ||
| 143 | |||
| 144 | FREE: | ||
| 145 | POP DS | ||
| 146 | DOSAssume CS,<DS>,"DIR/Free" | ||
| 147 | MOV CX,[LASTENT] | ||
| 148 | CMP CX,[ENTFREE] | ||
| 149 | JAE TSTALL | ||
| 150 | MOV [ENTFREE],CX | ||
| 151 | TSTALL: | ||
| 152 | CMP AH,BYTE PTR [DELALL] ; At end of directory? | ||
| 153 | NextEntJ: | ||
| 154 | JZ NEXTENT ; No - continue search | ||
| 155 | MOV [ENTLAST],CX | ||
| 156 | STC | ||
| 157 | JMP SHORT SETESRET | ||
| 158 | |||
| 159 | FOUND: | ||
| 160 | ; | ||
| 161 | ; We have a file with a matching name. We must now consider the attributes: | ||
| 162 | ; ATTRIB Action | ||
| 163 | ; ------ ------ | ||
| 164 | ; Volume_ID Is Volume_ID in test? | ||
| 165 | ; Otherwise If no create then Is ATTRIB+extra superset of test? | ||
| 166 | ; If create then Is ATTRIB equal to test? | ||
| 167 | ; | ||
| 168 | MOV CH,[SI] ; Attributes of file | ||
| 169 | POP DS | ||
| 170 | DOSAssume CS,<DS>,"DIR/found" | ||
| 171 | MOV AH,Attrib ; Attributes of search | ||
| 172 | AND AH,NOT attr_ignore | ||
| 173 | LEA SI,[SI+Dir_First-Dir_Attr] ; point to firclus field | ||
| 174 | TEST CH,attr_volume_id ; Volume ID file? | ||
| 175 | JZ check_one_volume_id ; Nope check other attributes | ||
| 176 | TEST AH,attr_volume_id ; Can we find Volume ID? | ||
| 177 | JZ NEXTENTJ ; Nope, (not even $FCB_CREATE) | ||
| 178 | XOR AH,AH ; Set zero flag for $FCB_CREATE | ||
| 179 | JMP SHORT RETFF ; Found Volume ID | ||
| 180 | check_one_volume_id: | ||
| 181 | CMP AH,attr_volume_id ; Looking only for Volume ID? | ||
| 182 | JZ NEXTENTJ ; Yes, continue search | ||
| 183 | invoke MatchAttributes | ||
| 184 | JZ RETFF | ||
| 185 | TEST BYTE PTR [CREATING],-1 ; Pass back mismatch if creating | ||
| 186 | JZ NEXTENTJ ; Otherwise continue searching | ||
| 187 | RETFF: | ||
| 188 | LES BP,[THISDPB] | ||
| 189 | MOV AH,ES:[BP.dpb_drive] | ||
| 190 | SETESRET: | ||
| 191 | PUSH SS | ||
| 192 | POP ES | ||
| 193 | return | ||
| 194 | EndProc Search | ||
| 195 | |||
| 196 | ; Inputs: | ||
| 197 | ; DS:SI -> 11 character FCB style name NO '?' | ||
| 198 | ; Typically this is a directory entry. It MUST be in upper case | ||
| 199 | ; ES:DI -> 11 character FCB style name with possible '?' | ||
| 200 | ; Typically this is a FCB or SFT. It MUST be in upper case | ||
| 201 | ; Function: | ||
| 202 | ; Compare FCB style names allowing for ? match to any char | ||
| 203 | ; Outputs: | ||
| 204 | ; Zero if match else NZ | ||
| 205 | ; Destroys CX,SI,DI all others preserved | ||
| 206 | |||
| 207 | procedure MetaCompare,near | ||
| 208 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 209 | MOV CX,11 | ||
| 210 | IF DBCS ;AN000; | ||
| 211 | ;-------------------- Start of DBCS ;AN000; | ||
| 212 | CMP BYTE PTR DS:[SI],05H ;AN000;; Special case for lead byte of 05h | ||
| 213 | JNE WILDCRD2 ;AN000;; Compare as normal if not an 05h | ||
| 214 | CMP BYTE PTR ES:[DI],0E5H ;AN000;; 05h and 0E5h equivalent for lead byte | ||
| 215 | JNE WILDCRD2 ;AN000;; Compare as normal if not an 05h | ||
| 216 | DEC CX ;AN000;; One less byte to compare | ||
| 217 | INC SI ;AN000;; Bypass lead byte in source and | ||
| 218 | INC DI ;AN000;; destination when 05h and 0E5h found. | ||
| 219 | WILDCRD2: ;AN000; | ||
| 220 | PUSH AX ;AN000;;KK. save ax | ||
| 221 | cagain: ;AN000;;KK. | ||
| 222 | CMP CX,0 ;AN000;;KK. end of compare ? | ||
| 223 | JLE metaend2 ;AN000;;KK. yes | ||
| 224 | MOV AL,[SI] ;AN000;;KK. is it a Kanji | ||
| 225 | invoke testkanj ;AN000;;KK. | ||
| 226 | JZ notdb ;AN000;;KK. no | ||
| 227 | MOV AX,'??' ;AN000;;KK. | ||
| 228 | CMP ES:[DI],AX ;AN000;;KK. is es:di pointing to '??' | ||
| 229 | JNZ metaend3 ;AN000;;KK. no | ||
| 230 | ADD SI,2 ;AN000;;KK. | ||
| 231 | ADD DI,2 ;AN000;;KK. update pointers and count | ||
| 232 | subcx: ;AN000; | ||
| 233 | SUB CX,2 ;AN000;;KK. | ||
| 234 | JMP cagain ;AN000;;KK. | ||
| 235 | metaend3: ;AN000;;KK. | ||
| 236 | CMPSW ;AN000;;KK. | ||
| 237 | JNZ metaend2 ;AN000;;KK. | ||
| 238 | JMP subcx ;AN000;;KK. | ||
| 239 | notdb: ;AN000; | ||
| 240 | CMPSB ;AN000;;KK. same code ? | ||
| 241 | JZ sameco ;AN000;;KK. yes | ||
| 242 | CMP BYTE PTR ES:[DI-1],"?" ;AN000;;KK. ? | ||
| 243 | JNZ metaend2 ;AN000;;KK. no | ||
| 244 | sameco: ;AN000; | ||
| 245 | DEC CX ;AN000;;KK. decrement count | ||
| 246 | JMP cagain ;AN000;;KK. | ||
| 247 | |||
| 248 | metaend2: ;AN000; | ||
| 249 | POP AX ;AN000;;KK. | ||
| 250 | ;-------------------- End of DBCS ;AN000; KK. | ||
| 251 | ELSE ;AN000; | ||
| 252 | WILDCRD: | ||
| 253 | REPE CMPSB | ||
| 254 | JZ MetaRet ; most of the time we will fail. | ||
| 255 | CHECK_META: | ||
| 256 | CMP BYTE PTR ES:[DI-1],"?" | ||
| 257 | JZ WildCrd | ||
| 258 | MetaRet: | ||
| 259 | ENDIF ;AN000; | ||
| 260 | return ; Zero set, Match | ||
| 261 | EndProc MetaCompare | ||
| 262 | |||
| 263 | Break <NEXTENTRY -- STEP THROUGH DIRECTORY> | ||
| 264 | |||
| 265 | ; Inputs: | ||
| 266 | ; Same as outputs of GETENTRY, above | ||
| 267 | ; Function: | ||
| 268 | ; Update BX, and [LASTENT] for next directory entry. | ||
| 269 | ; Carry set if no more. | ||
| 270 | |||
| 271 | Procedure NextEntry | ||
| 272 | DOSAssume CS,<DS>,"NextEntry" | ||
| 273 | ASSUME ES:NOTHING | ||
| 274 | |||
| 275 | MOV AX,[LASTENT] | ||
| 276 | CMP AX,[ENTLAST] | ||
| 277 | JZ NONE | ||
| 278 | INC AX | ||
| 279 | LEA BX,[BX+32] | ||
| 280 | CMP BX,DX | ||
| 281 | JB HAVIT | ||
| 282 | MOV BL,BYTE PTR [SECCLUSPOS] | ||
| 283 | INC BL | ||
| 284 | CMP BL,BYTE PTR [CLUSFAC] | ||
| 285 | JB SAMECLUS | ||
| 286 | MOV BX,[NXTCLUSNUM] | ||
| 287 | Invoke IsEOF | ||
| 288 | JAE NONE | ||
| 289 | CMP BX,2 | ||
| 290 | JB NONE | ||
| 291 | JMP GETENT | ||
| 292 | |||
| 293 | NONE: | ||
| 294 | STC | ||
| 295 | return | ||
| 296 | |||
| 297 | HAVIT: | ||
| 298 | MOV [LASTENT],AX | ||
| 299 | CLC | ||
| 300 | return | ||
| 301 | |||
| 302 | SAMECLUS: | ||
| 303 | MOV BYTE PTR [SECCLUSPOS],BL | ||
| 304 | MOV [LASTENT],AX | ||
| 305 | PUSH DS | ||
| 306 | LDS DI,[CURBUF] | ||
| 307 | ASSUME DS:NOTHING | ||
| 308 | MOV DX,WORD PTR [DI.buf_sector+2] ;AN000; >32mb | ||
| 309 | MOV [HIGH_SECTOR],DX ;AN000; >32mb | ||
| 310 | MOV DX,WORD PTR [DI.buf_sector] ;AN000; >32mb | ||
| 311 | |||
| 312 | ADD DX,1 ;AN000; >32mb | ||
| 313 | ADC [HIGH_SECTOR],0 ;AN000; >32mb | ||
| 314 | POP DS | ||
| 315 | DOSAssume CS,<DS>,"DIR/SameClus" | ||
| 316 | invoke FIRSTCLUSTER | ||
| 317 | XOR BX,BX | ||
| 318 | JMP SETENTRY | ||
| 319 | EndProc NextEntry | ||
| 320 | |||
| 321 | ; Inputs: | ||
| 322 | ; [LASTENT] has directory entry | ||
| 323 | ; ES:BP points to drive parameters | ||
| 324 | ; [DIRSEC],[CLUSNUM],[CLUSFAC],[ENTLAST] set for DIR involved | ||
| 325 | ; Function: | ||
| 326 | ; Locates directory entry in preparation for search | ||
| 327 | ; GETENT provides entry for passing desired entry in AX | ||
| 328 | ; Outputs: | ||
| 329 | ; [CURBUF+2]:BX = Pointer to next directory entry in CURBUF | ||
| 330 | ; [CURBUF+2]:DX = Pointer to first byte after end of CURBUF | ||
| 331 | ; [LASTENT] = New directory entry number | ||
| 332 | ; [NXTCLUSNUM],[SECCLUSPOS] set via DIRREAD | ||
| 333 | ; Carry set if error (currently user FAILed to I 24) | ||
| 334 | |||
| 335 | Procedure GETENTRY,NEAR | ||
| 336 | DOSAssume CS,<DS>,"GetEntry" | ||
| 337 | ASSUME ES:NOTHING | ||
| 338 | |||
| 339 | MOV AX,[LASTENT] | ||
| 340 | |||
| 341 | entry GETENT | ||
| 342 | |||
| 343 | Assert ISDPB,<ES,BP>,"GetEntry/GetEnt" | ||
| 344 | MOV [LASTENT],AX | ||
| 345 | ; | ||
| 346 | ; Convert the entry number in AX into a byte offset from the beginning of the | ||
| 347 | ; directory. | ||
| 348 | ; | ||
| 349 | mov cl,5 ; shift left by 5 = mult by 32 | ||
| 350 | rol ax,cl ; keep hight order bits | ||
| 351 | mov dx,ax | ||
| 352 | and ax, NOT (32-1) ; mask off high order bits | ||
| 353 | and dx, 32-1 ; mask off low order bits | ||
| 354 | ; | ||
| 355 | ; DX:AX contain the byte offset of the required directory entry from the | ||
| 356 | ; beginning of the directory. Convert this to a sector number. Round the | ||
| 357 | ; sector size down to a multiple of 32. | ||
| 358 | ; | ||
| 359 | MOV BX,ES:[BP.dpb_sector_size] | ||
| 360 | AND BL,255-31 ; Must be multiple of 32 | ||
| 361 | DIV BX | ||
| 362 | MOV BX,DX ; Position within sector | ||
| 363 | PUSH BX | ||
| 364 | invoke DIRREAD | ||
| 365 | POP BX | ||
| 366 | retc | ||
| 367 | SETENTRY: | ||
| 368 | MOV DX,WORD PTR [CURBUF] | ||
| 369 | ADD DX,BUFINSIZ | ||
| 370 | ADD BX,DX | ||
| 371 | ADD DX,ES:[BP.dpb_sector_size] ; Always clears carry | ||
| 372 | return | ||
| 373 | EndProc GetEntry | ||
| 374 | |||
| 375 | Break <SETDIRSRCH SETROOTSRCH -- Set Search environments> | ||
| 376 | |||
| 377 | ; Inputs: | ||
| 378 | ; BX cluster number of start of directory | ||
| 379 | ; ES:BP Points to DPB | ||
| 380 | ; DI next cluster number from fastopen extended info. DOS 3.3 only | ||
| 381 | ; Function: | ||
| 382 | ; Set up a directory search | ||
| 383 | ; Outputs: | ||
| 384 | ; [DIRSTART] = BX | ||
| 385 | ; [CLUSFAC],[CLUSNUM],[SECCLUSPOS],[DIRSEC] set | ||
| 386 | ; Carry set if error (currently user FAILed to I 24) | ||
| 387 | ; destroys AX,DX,BX | ||
| 388 | |||
| 389 | procedure SETDIRSRCH | ||
| 390 | DOSAssume CS,<DS>,"SetDirSrch" | ||
| 391 | ASSUME ES:NOTHING | ||
| 392 | |||
| 393 | Assert ISDPB,<ES,BP>,"SetDirSrch" | ||
| 394 | OR BX,BX | ||
| 395 | JZ SETROOTSRCH | ||
| 396 | MOV [DIRSTART],BX | ||
| 397 | MOV AL,ES:[BP.dpb_cluster_mask] | ||
| 398 | INC AL | ||
| 399 | MOV BYTE PTR [CLUSFAC],AL | ||
| 400 | ; DOS 3.3 for FastOPen F.C. 6/12/86 | ||
| 401 | SaveReg <SI> | ||
| 402 | TEST [FastOpenFlg],Lookup_Success | ||
| 403 | JNZ UNP_OK | ||
| 404 | |||
| 405 | ; DOS 3.3 for FastOPen F.C. 6/12/86 | ||
| 406 | invoke UNPACK | ||
| 407 | JNC UNP_OK | ||
| 408 | RestoreReg <SI> | ||
| 409 | return | ||
| 410 | |||
| 411 | UNP_OK: | ||
| 412 | MOV [CLUSNUM],DI | ||
| 413 | MOV DX,BX | ||
| 414 | XOR BL,BL | ||
| 415 | MOV BYTE PTR [SECCLUSPOS],BL | ||
| 416 | invoke FIGREC | ||
| 417 | RestoreReg <SI> | ||
| 418 | PUSH DX ;AN000; >32mb | ||
| 419 | MOV DX,[HIGH_SECTOR] ;AN000; >32mb | ||
| 420 | MOV WORD PTR [DIRSEC+2],DX ;AN000; >32mb | ||
| 421 | POP DX ;AN000; >32mb | ||
| 422 | MOV WORD PTR [DIRSEC],DX | ||
| 423 | CLC | ||
| 424 | return | ||
| 425 | |||
| 426 | entry SETROOTSRCH | ||
| 427 | DOSAssume CS,<DS>,"SetRootSrch" | ||
| 428 | ASSUME ES:NOTHING | ||
| 429 | XOR AX,AX | ||
| 430 | MOV [DIRSTART],AX | ||
| 431 | MOV BYTE PTR [SECCLUSPOS],AL | ||
| 432 | DEC AX | ||
| 433 | MOV [CLUSNUM],AX | ||
| 434 | MOV AX,ES:[BP.dpb_first_sector] | ||
| 435 | MOV DX,ES:[BP.dpb_dir_sector] | ||
| 436 | SUB AX,DX | ||
| 437 | MOV BYTE PTR [CLUSFAC],AL | ||
| 438 | MOV WORD PTR [DIRSEC],DX ;F.C. >32mb | ||
| 439 | MOV WORD PTR [DIRSEC+2],0 ;F.C. >32mb | ||
| 440 | CLC | ||
| 441 | return | ||
| 442 | EndProc SETDIRSRCH | ||
| 443 | |||
| 444 | CODE ENDS | ||
| 445 | END | ||