diff options
| author | 1983-08-12 17:53:34 -0700 | |
|---|---|---|
| committer | 2018-09-21 17:53:34 -0700 | |
| commit | 80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 (patch) | |
| tree | ee4357f7f3dd0f2ded59b9c6e7384432d85e7ec9 /v2.0/source/FAT.ASM | |
| parent | MS-DOS v1.25 Release (diff) | |
| download | ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.tar.gz ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.tar.xz ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.zip | |
MS-DOS v2.0 Release
Diffstat (limited to 'v2.0/source/FAT.ASM')
| -rw-r--r-- | v2.0/source/FAT.ASM | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/v2.0/source/FAT.ASM b/v2.0/source/FAT.ASM new file mode 100644 index 0000000..b1a4863 --- /dev/null +++ b/v2.0/source/FAT.ASM | |||
| @@ -0,0 +1,362 @@ | |||
| 1 | ; | ||
| 2 | ; FAT operations for MSDOS | ||
| 3 | ; | ||
| 4 | |||
| 5 | INCLUDE DOSSEG.ASM | ||
| 6 | |||
| 7 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 8 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 9 | |||
| 10 | .xlist | ||
| 11 | .xcref | ||
| 12 | INCLUDE DOSSYM.ASM | ||
| 13 | INCLUDE DEVSYM.ASM | ||
| 14 | .cref | ||
| 15 | .list | ||
| 16 | |||
| 17 | TITLE FAT - FAT maintenance routines | ||
| 18 | NAME FAT | ||
| 19 | |||
| 20 | i_need CURBUF,DWORD | ||
| 21 | i_need CLUSSPLIT,BYTE | ||
| 22 | i_need CLUSSAVE,WORD | ||
| 23 | i_need CLUSSEC,WORD | ||
| 24 | i_need THISDRV,BYTE | ||
| 25 | i_need DEVCALL,BYTE | ||
| 26 | i_need CALLMED,BYTE | ||
| 27 | i_need CALLRBYT,BYTE | ||
| 28 | i_need BUFFHEAD,DWORD | ||
| 29 | i_need CALLXAD,DWORD | ||
| 30 | i_need CALLBPB,DWORD | ||
| 31 | |||
| 32 | SUBTTL UNPACK -- UNPACK FAT ENTRIES | ||
| 33 | PAGE | ||
| 34 | |||
| 35 | ASSUME SS:DOSGROUP | ||
| 36 | procedure UNPACK,NEAR | ||
| 37 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 38 | |||
| 39 | ; Inputs: | ||
| 40 | ; BX = Cluster number | ||
| 41 | ; ES:BP = Base of drive parameters | ||
| 42 | ; Outputs: | ||
| 43 | ; DI = Contents of FAT for given cluster | ||
| 44 | ; Zero set means DI=0 (free cluster) | ||
| 45 | ; SI Destroyed, No other registers affected. Fatal error if cluster too big. | ||
| 46 | |||
| 47 | CMP BX,ES:[BP.dpb_max_cluster] | ||
| 48 | JA HURTFAT | ||
| 49 | CALL MAPCLUSTER | ||
| 50 | ASSUME DS:NOTHING | ||
| 51 | MOV DI,[DI] | ||
| 52 | JNC HAVCLUS | ||
| 53 | PUSH CX | ||
| 54 | MOV CL,4 | ||
| 55 | SHR DI,CL | ||
| 56 | POP CX | ||
| 57 | STC | ||
| 58 | HAVCLUS: | ||
| 59 | AND DI,0FFFH | ||
| 60 | PUSH SS | ||
| 61 | POP DS | ||
| 62 | return | ||
| 63 | |||
| 64 | HURTFAT: | ||
| 65 | PUSH AX | ||
| 66 | MOV AH,80H ; Signal Bad FAT to INT int_fatal_abort handler | ||
| 67 | MOV DI,0FFFH ; In case INT int_fatal_abort returns (it shouldn't) | ||
| 68 | invoke FATAL | ||
| 69 | POP AX ; Try to ignore bad FAT | ||
| 70 | return | ||
| 71 | UNPACK ENDP | ||
| 72 | |||
| 73 | SUBTTL PACK -- PACK FAT ENTRIES | ||
| 74 | PAGE | ||
| 75 | procedure PACK,NEAR | ||
| 76 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 77 | |||
| 78 | ; Inputs: | ||
| 79 | ; BX = Cluster number | ||
| 80 | ; DX = Data | ||
| 81 | ; ES:BP = Pointer to drive DPB | ||
| 82 | ; Outputs: | ||
| 83 | ; The data is stored in the FAT at the given cluster. | ||
| 84 | ; SI,DX,DI all destroyed | ||
| 85 | ; No other registers affected | ||
| 86 | |||
| 87 | CALL MAPCLUSTER | ||
| 88 | ASSUME DS:NOTHING | ||
| 89 | MOV SI,[DI] | ||
| 90 | JNC ALIGNED | ||
| 91 | PUSH CX | ||
| 92 | MOV CL,4 | ||
| 93 | SHL DX,CL | ||
| 94 | POP CX | ||
| 95 | AND SI,0FH | ||
| 96 | JMP SHORT PACKIN | ||
| 97 | ALIGNED: | ||
| 98 | AND SI,0F000H | ||
| 99 | PACKIN: | ||
| 100 | OR SI,DX | ||
| 101 | MOV [DI],SI | ||
| 102 | LDS SI,[CURBUF] | ||
| 103 | MOV [SI.BUFDIRTY],1 | ||
| 104 | CMP BYTE PTR [CLUSSPLIT],0 | ||
| 105 | PUSH SS | ||
| 106 | POP DS | ||
| 107 | ASSUME DS:DOSGROUP | ||
| 108 | retz | ||
| 109 | PUSH AX | ||
| 110 | PUSH BX | ||
| 111 | PUSH CX | ||
| 112 | MOV AX,[CLUSSAVE] | ||
| 113 | MOV DS,WORD PTR [CURBUF+2] | ||
| 114 | ASSUME DS:NOTHING | ||
| 115 | ADD SI,BUFINSIZ | ||
| 116 | MOV [SI],AH | ||
| 117 | PUSH SS | ||
| 118 | POP DS | ||
| 119 | ASSUME DS:DOSGROUP | ||
| 120 | PUSH AX | ||
| 121 | MOV DX,[CLUSSEC] | ||
| 122 | MOV SI,1 | ||
| 123 | XOR AL,AL | ||
| 124 | invoke GETBUFFRB | ||
| 125 | LDS DI,[CURBUF] | ||
| 126 | ASSUME DS:NOTHING | ||
| 127 | MOV [DI.BUFDIRTY],1 | ||
| 128 | ADD DI,BUFINSIZ | ||
| 129 | DEC DI | ||
| 130 | ADD DI,ES:[BP.dpb_sector_size] | ||
| 131 | POP AX | ||
| 132 | MOV [DI],AL | ||
| 133 | PUSH SS | ||
| 134 | POP DS | ||
| 135 | POP CX | ||
| 136 | POP BX | ||
| 137 | POP AX | ||
| 138 | return | ||
| 139 | PACK ENDP | ||
| 140 | |||
| 141 | SUBTTL MAPCLUSTER - BUFFER A FAT SECTOR | ||
| 142 | PAGE | ||
| 143 | procedure MAPCLUSTER,NEAR | ||
| 144 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 145 | |||
| 146 | ; Inputs: | ||
| 147 | ; ES:BP Points to DPB | ||
| 148 | ; BX Is cluster number | ||
| 149 | ; Function: | ||
| 150 | ; Get a pointer to the cluster | ||
| 151 | ; Outputs: | ||
| 152 | ; DS:DI Points to contents of FAT for given cluster | ||
| 153 | ; DS:SI Points to start of buffer | ||
| 154 | ; Carry set if cluster data is in high 12 bits of word | ||
| 155 | ; No other registers effected | ||
| 156 | |||
| 157 | MOV BYTE PTR [CLUSSPLIT],0 | ||
| 158 | PUSH AX | ||
| 159 | PUSH BX | ||
| 160 | PUSH CX | ||
| 161 | PUSH DX | ||
| 162 | MOV AX,BX | ||
| 163 | SHR AX,1 | ||
| 164 | ADD AX,BX | ||
| 165 | XOR DX,DX | ||
| 166 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 167 | DIV CX ; AX is FAT sector # DX is sector index | ||
| 168 | ADD AX,ES:[BP.dpb_first_FAT] | ||
| 169 | DEC CX | ||
| 170 | PUSH AX | ||
| 171 | PUSH DX | ||
| 172 | PUSH CX | ||
| 173 | MOV DX,AX | ||
| 174 | XOR AL,AL | ||
| 175 | MOV SI,1 | ||
| 176 | invoke GETBUFFRB | ||
| 177 | LDS SI,[CURBUF] | ||
| 178 | ASSUME DS:NOTHING | ||
| 179 | LEA DI,[SI.BufInSiz] | ||
| 180 | POP CX | ||
| 181 | POP AX | ||
| 182 | POP DX | ||
| 183 | ADD DI,AX | ||
| 184 | CMP AX,CX | ||
| 185 | JNZ MAPRET | ||
| 186 | MOV AL,[DI] | ||
| 187 | PUSH SS | ||
| 188 | POP DS | ||
| 189 | ASSUME DS:DOSGROUP | ||
| 190 | INC BYTE PTR [CLUSSPLIT] | ||
| 191 | MOV BYTE PTR [CLUSSAVE],AL | ||
| 192 | MOV [CLUSSEC],DX | ||
| 193 | INC DX | ||
| 194 | XOR AL,AL | ||
| 195 | MOV SI,1 | ||
| 196 | invoke GETBUFFRB | ||
| 197 | LDS SI,[CURBUF] | ||
| 198 | ASSUME DS:NOTHING | ||
| 199 | LEA DI,[SI.BufInSiz] | ||
| 200 | MOV AL,[DI] | ||
| 201 | PUSH SS | ||
| 202 | POP DS | ||
| 203 | ASSUME DS:DOSGROUP | ||
| 204 | MOV BYTE PTR [CLUSSAVE+1],AL | ||
| 205 | MOV DI,OFFSET DOSGROUP:CLUSSAVE | ||
| 206 | MAPRET: | ||
| 207 | POP DX | ||
| 208 | POP CX | ||
| 209 | POP BX | ||
| 210 | MOV AX,BX | ||
| 211 | SHR AX,1 | ||
| 212 | POP AX | ||
| 213 | return | ||
| 214 | MAPCLUSTER ENDP | ||
| 215 | |||
| 216 | SUBTTL FATREAD -- CHECK DRIVE GET FAT | ||
| 217 | PAGE | ||
| 218 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 219 | |||
| 220 | procedure FAT_operation,NEAR | ||
| 221 | FATERR: | ||
| 222 | AND DI,STECODE ; Put error code in DI | ||
| 223 | MOV AH,2 ; While trying to read FAT | ||
| 224 | MOV AL,BYTE PTR [THISDRV] ; Tell which drive | ||
| 225 | invoke FATAL1 | ||
| 226 | |||
| 227 | entry FATREAD | ||
| 228 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 229 | |||
| 230 | ; Function: | ||
| 231 | ; If disk may have been changed, FAT is read in and buffers are | ||
| 232 | ; flagged invalid. If not, no action is taken. | ||
| 233 | ; Outputs: | ||
| 234 | ; ES:BP = Base of drive parameters | ||
| 235 | ; All other registers destroyed | ||
| 236 | |||
| 237 | MOV AL,BYTE PTR [THISDRV] | ||
| 238 | invoke GETBP | ||
| 239 | MOV AL,DMEDHL | ||
| 240 | MOV AH,ES:[BP.dpb_UNIT] | ||
| 241 | MOV WORD PTR [DEVCALL],AX | ||
| 242 | MOV BYTE PTR [DEVCALL.REQFUNC],DEVMDCH | ||
| 243 | MOV [DEVCALL.REQSTAT],0 | ||
| 244 | MOV AL,ES:[BP.dpb_media] | ||
| 245 | MOV BYTE PTR [CALLMED],AL | ||
| 246 | PUSH ES | ||
| 247 | PUSH DS | ||
| 248 | MOV BX,OFFSET DOSGROUP:DEVCALL | ||
| 249 | LDS SI,ES:[BP.dpb_driver_addr] ; DS:SI Points to device header | ||
| 250 | ASSUME DS:NOTHING | ||
| 251 | POP ES ; ES:BX Points to call header | ||
| 252 | invoke DEVIOCALL2 | ||
| 253 | PUSH SS | ||
| 254 | POP DS | ||
| 255 | ASSUME DS:DOSGROUP | ||
| 256 | POP ES ; Restore ES:BP | ||
| 257 | MOV DI,[DEVCALL.REQSTAT] | ||
| 258 | TEST DI,STERR | ||
| 259 | JNZ FATERR | ||
| 260 | XOR AH,AH | ||
| 261 | XCHG AH,ES:[BP.dpb_first_access] ; Reset dpb_first_access | ||
| 262 | MOV AL,BYTE PTR [THISDRV] ; Use physical unit number | ||
| 263 | OR AH,BYTE PTR [CALLRBYT] | ||
| 264 | JS NEWDSK ; new disk or first access? | ||
| 265 | JZ CHKBUFFDIRT | ||
| 266 | return ; If Media not changed | ||
| 267 | CHKBUFFDIRT: | ||
| 268 | INC AH ; Here if ?Media..Check buffers | ||
| 269 | LDS DI,[BUFFHEAD] | ||
| 270 | ASSUME DS:NOTHING | ||
| 271 | NBUFFER: ; Look for dirty buffers | ||
| 272 | CMP AX,WORD PTR [DI.BUFDRV] | ||
| 273 | retz ; There is a dirty buffer, assume Media OK | ||
| 274 | LDS DI,[DI.NEXTBUF] | ||
| 275 | CMP DI,-1 | ||
| 276 | JNZ NBUFFER | ||
| 277 | ; If no dirty buffers, assume Media changed | ||
| 278 | NEWDSK: | ||
| 279 | invoke SETVISIT | ||
| 280 | NXBUFFER: | ||
| 281 | MOV [DI.VISIT],1 | ||
| 282 | CMP AL,[DI.BUFDRV] ; For this drive? | ||
| 283 | JNZ SKPBUFF | ||
| 284 | MOV WORD PTR [DI.BUFDRV],00FFH ; Free up buffer | ||
| 285 | invoke SCANPLACE | ||
| 286 | SKPBUFF: | ||
| 287 | invoke SKIPVISIT | ||
| 288 | JNZ NXBUFFER | ||
| 289 | LDS DI,ES:[BP.dpb_driver_addr] | ||
| 290 | TEST [DI.SDEVATT],ISFATBYDEV | ||
| 291 | JNZ GETFREEBUF | ||
| 292 | context DS | ||
| 293 | MOV BX,2 | ||
| 294 | CALL UNPACK ; Read the first FAT sector into CURBUF | ||
| 295 | LDS DI,[CURBUF] | ||
| 296 | JMP SHORT GOTGETBUF | ||
| 297 | GETFREEBUF: | ||
| 298 | ASSUME DS:NOTHING | ||
| 299 | PUSH ES ; Get a free buffer for BIOS to use | ||
| 300 | PUSH BP | ||
| 301 | LDS DI,[BUFFHEAD] | ||
| 302 | invoke BUFWRITE | ||
| 303 | POP BP | ||
| 304 | POP ES | ||
| 305 | GOTGETBUF: | ||
| 306 | ADD DI,BUFINSIZ | ||
| 307 | MOV WORD PTR [CALLXAD+2],DS | ||
| 308 | PUSH SS | ||
| 309 | POP DS | ||
| 310 | ASSUME DS:DOSGROUP | ||
| 311 | MOV WORD PTR [CALLXAD],DI | ||
| 312 | MOV AL,DBPBHL | ||
| 313 | MOV AH,BYTE PTR ES:[BP.dpb_UNIT] | ||
| 314 | MOV WORD PTR [DEVCALL],AX | ||
| 315 | MOV BYTE PTR [DEVCALL.REQFUNC],DEVBPB | ||
| 316 | MOV [DEVCALL.REQSTAT],0 | ||
| 317 | MOV AL,BYTE PTR ES:[BP.dpb_media] | ||
| 318 | MOV [CALLMED],AL | ||
| 319 | PUSH ES | ||
| 320 | PUSH DS | ||
| 321 | PUSH WORD PTR ES:[BP.dpb_driver_addr+2] | ||
| 322 | PUSH WORD PTR ES:[BP.dpb_driver_addr] | ||
| 323 | MOV BX,OFFSET DOSGROUP:DEVCALL | ||
| 324 | POP SI | ||
| 325 | POP DS ; DS:SI Points to device header | ||
| 326 | ASSUME DS:NOTHING | ||
| 327 | POP ES ; ES:BX Points to call header | ||
| 328 | invoke DEVIOCALL2 | ||
| 329 | POP ES ; Restore ES:BP | ||
| 330 | PUSH SS | ||
| 331 | POP DS | ||
| 332 | ASSUME DS:DOSGROUP | ||
| 333 | MOV DI,[DEVCALL.REQSTAT] | ||
| 334 | TEST DI,STERR | ||
| 335 | JNZ FATERRJ | ||
| 336 | MOV AL,BYTE PTR ES:[BP.dpb_media] | ||
| 337 | LDS SI,[CALLBPB] | ||
| 338 | ASSUME DS:NOTHING | ||
| 339 | CMP AL,BYTE PTR [SI.BPMEDIA] | ||
| 340 | JZ DPBOK | ||
| 341 | invoke $SETDPB | ||
| 342 | LDS DI,[CALLXAD] ; Get back buffer pointer | ||
| 343 | MOV AL,BYTE PTR ES:[BP.dpb_FAT_count] | ||
| 344 | MOV AH,BYTE PTR ES:[BP.dpb_FAT_size] | ||
| 345 | MOV WORD PTR [DI.BUFWRTCNT-BUFINSIZ],AX ;Correct buffer info | ||
| 346 | DPBOK: | ||
| 347 | context ds | ||
| 348 | MOV AX,-1 | ||
| 349 | TEST ES:[BP.dpb_current_dir],AX | ||
| 350 | retz ; If root, leave as root | ||
| 351 | MOV ES:[BP.dpb_current_dir],AX ; Path may be bad, mark invalid | ||
| 352 | return | ||
| 353 | |||
| 354 | FATERRJ: JMP FATERR | ||
| 355 | |||
| 356 | FAT_operation ENDP | ||
| 357 | |||
| 358 | do_ext | ||
| 359 | |||
| 360 | CODE ENDS | ||
| 361 | END | ||
| 362 | |||