diff options
Diffstat (limited to 'v2.0/source/RECOVER.ASM')
| -rw-r--r-- | v2.0/source/RECOVER.ASM | 876 |
1 files changed, 876 insertions, 0 deletions
diff --git a/v2.0/source/RECOVER.ASM b/v2.0/source/RECOVER.ASM new file mode 100644 index 0000000..05d27f9 --- /dev/null +++ b/v2.0/source/RECOVER.ASM | |||
| @@ -0,0 +1,876 @@ | |||
| 1 | TITLE RECOVER MS-DOS File/Disk Recovery Utility | ||
| 2 | ;---------------------------------------------------------- | ||
| 3 | ; | ||
| 4 | ; Recover - Program to rebuild an ms.dos directory | ||
| 5 | ; | ||
| 6 | ; Copyright 1982 by Microsoft Corporation | ||
| 7 | ; Written by Chris Peters, April 1982 | ||
| 8 | ; | ||
| 9 | ;----------------------------------------------------------- | ||
| 10 | ; | ||
| 11 | ;REV 1.5 added header message ARR | ||
| 12 | ; | ||
| 13 | |||
| 14 | FALSE EQU 0 | ||
| 15 | TRUE EQU NOT FALSE | ||
| 16 | |||
| 17 | |||
| 18 | IBMVER EQU true | ||
| 19 | KANJI EQU FALSE | ||
| 20 | |||
| 21 | bdos equ 21h | ||
| 22 | boot equ 20h | ||
| 23 | aread equ 25h | ||
| 24 | awrite equ 26h | ||
| 25 | |||
| 26 | INCLUDE DOSSYM.ASM | ||
| 27 | |||
| 28 | ; | ||
| 29 | cr equ 0dh | ||
| 30 | lf equ 0ah | ||
| 31 | ; | ||
| 32 | fcb equ 5ch | ||
| 33 | |||
| 34 | code segment public | ||
| 35 | code ends | ||
| 36 | |||
| 37 | const segment public byte | ||
| 38 | const ends | ||
| 39 | |||
| 40 | data segment public byte | ||
| 41 | data ends | ||
| 42 | |||
| 43 | |||
| 44 | dg group code,const,data | ||
| 45 | |||
| 46 | code segment public | ||
| 47 | assume cs:dg,ds:dg,es:dg,ss:dg | ||
| 48 | |||
| 49 | PUBLIC PCRLF,PRINT,INT_23,convert | ||
| 50 | EXTRN dskwrt:NEAR,dskrd:NEAR,DSKERR:NEAR,report:NEAR | ||
| 51 | |||
| 52 | org 100h | ||
| 53 | |||
| 54 | recover:jmp rec_start | ||
| 55 | |||
| 56 | HEADER DB "Vers 1.50" | ||
| 57 | |||
| 58 | ;-----------------------------------------------------------------------; | ||
| 59 | hardch dd ? | ||
| 60 | |||
| 61 | the_root db 0 ;root directory flag | ||
| 62 | |||
| 63 | fudge db 0 ;directory changed flag | ||
| 64 | user_drive db 0 | ||
| 65 | drive db 0 | ||
| 66 | |||
| 67 | |||
| 68 | dirchar db "/",0 | ||
| 69 | |||
| 70 | |||
| 71 | userdir db "/",0 | ||
| 72 | db (dirstrlen) dup(0) | ||
| 73 | |||
| 74 | fname_buffer db 128 dup(0) | ||
| 75 | ;-----------------------------------------------------------------------; | ||
| 76 | |||
| 77 | pcrlf: mov dx,offset dg: crlf | ||
| 78 | print: mov ah,STD_CON_STRING_OUTPUT | ||
| 79 | int bdos | ||
| 80 | pret: ret | ||
| 81 | ; | ||
| 82 | convert:push bx | ||
| 83 | xor ax,ax | ||
| 84 | mov bx,ax | ||
| 85 | mov bp,ax | ||
| 86 | mov cx,32 | ||
| 87 | convlp: shl si,1 | ||
| 88 | rcl di,1 | ||
| 89 | xchg ax,bp | ||
| 90 | call convwrd | ||
| 91 | xchg ax,bp | ||
| 92 | xchg ax,bx | ||
| 93 | call convwrd | ||
| 94 | xchg ax,bx | ||
| 95 | adc al,0 | ||
| 96 | loop convlp | ||
| 97 | |||
| 98 | mov cx,1810h | ||
| 99 | xchg dx,ax | ||
| 100 | call digit | ||
| 101 | xchg ax,bx | ||
| 102 | call outword | ||
| 103 | mov ax,bp | ||
| 104 | call outword | ||
| 105 | pop dx | ||
| 106 | call print | ||
| 107 | ret2: ret | ||
| 108 | ; | ||
| 109 | outword:push ax | ||
| 110 | mov dl,ah | ||
| 111 | call outbyte | ||
| 112 | pop dx | ||
| 113 | outbyte:mov dh,dl | ||
| 114 | shr dl,1 | ||
| 115 | shr dl,1 | ||
| 116 | shr dl,1 | ||
| 117 | shr dl,1 | ||
| 118 | call digit | ||
| 119 | mov dl,dh | ||
| 120 | digit: and dl,0fh | ||
| 121 | jz blankzer | ||
| 122 | xor cl,cl | ||
| 123 | blankzer: | ||
| 124 | dec ch | ||
| 125 | and cl,ch | ||
| 126 | or dl,30h | ||
| 127 | sub dl,cl | ||
| 128 | cmp dl,30h | ||
| 129 | jl ret2 | ||
| 130 | mov ah,STD_CON_OUTPUT | ||
| 131 | int bdos | ||
| 132 | ret | ||
| 133 | ; | ||
| 134 | convwrd:adc al,al | ||
| 135 | daa | ||
| 136 | xchg al,ah | ||
| 137 | adc al,al | ||
| 138 | daa | ||
| 139 | xchg al,ah | ||
| 140 | ret | ||
| 141 | ; | ||
| 142 | ; bx = fat[ax] | ||
| 143 | ; | ||
| 144 | getfat: mov bx,offset dg: fattbl | ||
| 145 | push ax | ||
| 146 | mov si,ax | ||
| 147 | sar ax,1 | ||
| 148 | pushf | ||
| 149 | add si,ax | ||
| 150 | mov bx,word ptr [bx][si] | ||
| 151 | popf | ||
| 152 | jnc getfat1 | ||
| 153 | mov cl,4 | ||
| 154 | shr bx,cl | ||
| 155 | getfat1:and bh,00001111b | ||
| 156 | pop ax | ||
| 157 | mov cx,secsiz | ||
| 158 | ret | ||
| 159 | ; | ||
| 160 | ; fat[ax] = dx | ||
| 161 | ; | ||
| 162 | setfat: mov bx,offset dg: fattbl | ||
| 163 | push ax | ||
| 164 | push dx | ||
| 165 | mov si,ax | ||
| 166 | sar ax,1 | ||
| 167 | pushf | ||
| 168 | add si,ax | ||
| 169 | mov ax,word ptr [bx][si] | ||
| 170 | popf | ||
| 171 | jnc setfat2 | ||
| 172 | and ax,000fh | ||
| 173 | mov cl,4 | ||
| 174 | shl dx,cl | ||
| 175 | setfat1:or ax,dx | ||
| 176 | mov word ptr [bx][si],ax | ||
| 177 | pop dx | ||
| 178 | pop ax | ||
| 179 | ret | ||
| 180 | |||
| 181 | setfat2:and ax,0f000h | ||
| 182 | jmp setfat1 | ||
| 183 | |||
| 184 | load: mov dx,firfat | ||
| 185 | mov al,byte ptr fatnum | ||
| 186 | mov byte ptr fatcnt,al | ||
| 187 | mov al,byte ptr drive | ||
| 188 | mov cx,fatsiz | ||
| 189 | mov bx,offset dg: fattbl | ||
| 190 | ret66: ret | ||
| 191 | |||
| 192 | readft: call load | ||
| 193 | readit: call dskrd | ||
| 194 | cmp [fndfat],0 ;save location of readable fat sector | ||
| 195 | jnz fdfat | ||
| 196 | mov [fndfat],dx | ||
| 197 | fdfat: cmp word ptr [bx+1],-1 | ||
| 198 | jz ret66 | ||
| 199 | |||
| 200 | add dx,cx ;try to read the other fats | ||
| 201 | dec byte ptr fatcnt | ||
| 202 | jnz readit | ||
| 203 | |||
| 204 | mov dx,[fndfat] ;see if any readable at all | ||
| 205 | or dx,dx | ||
| 206 | jz readft ;if not disk is blown, keep trying | ||
| 207 | call dskrd | ||
| 208 | ret | ||
| 209 | |||
| 210 | wrtfat: call load | ||
| 211 | wrtit: push ax | ||
| 212 | push bx | ||
| 213 | push cx | ||
| 214 | push dx | ||
| 215 | call dskwrt | ||
| 216 | pop dx | ||
| 217 | pop cx | ||
| 218 | pop bx | ||
| 219 | pop ax | ||
| 220 | |||
| 221 | wrtok: add dx,cx | ||
| 222 | dec byte ptr fatcnt | ||
| 223 | jnz wrtit | ||
| 224 | ret | ||
| 225 | |||
| 226 | printerr: | ||
| 227 | call print | ||
| 228 | jmp rabort | ||
| 229 | |||
| 230 | |||
| 231 | rec_start: | ||
| 232 | |||
| 233 | ;Code to print header | ||
| 234 | ; PUSH AX | ||
| 235 | ; MOV DX,OFFSET DG:HEADER | ||
| 236 | ; CALL print | ||
| 237 | ; POP AX | ||
| 238 | |||
| 239 | DOSVER_HIGH EQU 0200H ;2.00 in hex | ||
| 240 | PUSH AX ;Save DRIVE validity info | ||
| 241 | MOV AH,GET_VERSION | ||
| 242 | INT 21H | ||
| 243 | XCHG AH,AL ;Turn it around to AH.AL | ||
| 244 | CMP AX,DOSVER_HIGH | ||
| 245 | JAE OKDOS | ||
| 246 | GOTBADDOS: | ||
| 247 | MOV DX,OFFSET DG:BADVER | ||
| 248 | CALL PRINT | ||
| 249 | INT 20H | ||
| 250 | |||
| 251 | OKDOS: POP AX | ||
| 252 | |||
| 253 | cmp al,0ffH | ||
| 254 | JZ BADDRVSPECJ | ||
| 255 | mov si,80h | ||
| 256 | lodsb | ||
| 257 | or al,al | ||
| 258 | jz noparm | ||
| 259 | look: lodsb | ||
| 260 | cmp al," " | ||
| 261 | jz look | ||
| 262 | cmp al,9 | ||
| 263 | jz look | ||
| 264 | cmp al,13 | ||
| 265 | jnz gotparm | ||
| 266 | noparm: | ||
| 267 | jmp noname | ||
| 268 | |||
| 269 | BADDRVSPECJ: JMP BADDRVSPEC | ||
| 270 | |||
| 271 | gotparm: | ||
| 272 | mov ah,DISK_RESET | ||
| 273 | int bdos ;empty buffer queue | ||
| 274 | |||
| 275 | mov ah,get_default_drive ;save current drive | ||
| 276 | int 21h | ||
| 277 | mov [user_drive],al | ||
| 278 | |||
| 279 | mov bx,fcb ;determine input command | ||
| 280 | mov al,[bx] | ||
| 281 | dec al | ||
| 282 | cmp al,-1 | ||
| 283 | jnz drvok1 | ||
| 284 | mov al,[user_drive] | ||
| 285 | drvok1: | ||
| 286 | mov [drive],al | ||
| 287 | add [drvlet],al | ||
| 288 | add [drvlet1],al | ||
| 289 | mov dx,offset dg: askmsg | ||
| 290 | call print | ||
| 291 | mov ah,STD_CON_INPUT_FLUSH | ||
| 292 | mov al,1 ;wait for a key | ||
| 293 | int bdos | ||
| 294 | |||
| 295 | cmp al,17h | ||
| 296 | jnz drvok2 | ||
| 297 | mov dx,offset dg: egomes | ||
| 298 | jmp printerr | ||
| 299 | egomes: db "Chris Peters helped with the new dos!",cr,lf | ||
| 300 | db "Microsoft rules ok$" | ||
| 301 | |||
| 302 | drvok2: | ||
| 303 | IF IBMVER | ||
| 304 | MOV AL,DRIVE ;This is for ibm's single drive sys | ||
| 305 | PUSH DS | ||
| 306 | MOV BX,50H | ||
| 307 | MOV DS,BX | ||
| 308 | MOV DS:(BYTE PTR 4),AL ;Indicate drive changed | ||
| 309 | POP DS | ||
| 310 | ENDIF | ||
| 311 | |||
| 312 | ;----- Process Pathnames -----------------------------------------------; | ||
| 313 | mov ax,(char_oper shl 8) ;get switch character | ||
| 314 | int 21h | ||
| 315 | cmp dl,"/" | ||
| 316 | jnz slashok ;if not / , then not PC | ||
| 317 | mov [dirchar],"\" ;in PC, dir separator = \ | ||
| 318 | mov [userdir],"\" | ||
| 319 | |||
| 320 | slashok: | ||
| 321 | mov si,81h ;point to cammand line | ||
| 322 | mov di,offset dg: fname_buffer | ||
| 323 | xor cx,cx ;zero pathname length | ||
| 324 | |||
| 325 | kill_bl: | ||
| 326 | lodsb ;get rid of blanks | ||
| 327 | cmp al,9 | ||
| 328 | je kill_bl | ||
| 329 | cmp al,' ' | ||
| 330 | je kill_bl | ||
| 331 | cmp al,13 ;A carriage return? | ||
| 332 | jne next_char | ||
| 333 | jmp noname ;yes, file name missing | ||
| 334 | |||
| 335 | next_char: | ||
| 336 | stosb ;put patname in buffer | ||
| 337 | inc cx | ||
| 338 | lodsb | ||
| 339 | cmp al,' ' | ||
| 340 | je name_copied | ||
| 341 | cmp al,9 | ||
| 342 | je name_copied | ||
| 343 | cmp al,13 ; a CR ? | ||
| 344 | jne next_char | ||
| 345 | |||
| 346 | name_copied: | ||
| 347 | mov byte ptr [di],0 ;nul terminate the pathname | ||
| 348 | dec di ;adjust to the end of the pathname | ||
| 349 | |||
| 350 | ;----- Scan for directory ----------------------------------------------; | ||
| 351 | |||
| 352 | IF KANJI | ||
| 353 | mov dx,offset dg: [fname_buffer] | ||
| 354 | PUSH DX | ||
| 355 | PUSH DI | ||
| 356 | MOV BX,DI | ||
| 357 | MOV DI,DX | ||
| 358 | DELLOOP: | ||
| 359 | CMP DI,BX | ||
| 360 | JZ GOTDELE | ||
| 361 | MOV AL,[DI] | ||
| 362 | INC DI | ||
| 363 | CALL TESTKANJ | ||
| 364 | JZ NOTKANJ11 | ||
| 365 | INC DI | ||
| 366 | JMP DELLOOP | ||
| 367 | |||
| 368 | NOTKANJ11: | ||
| 369 | cmp al,[dirchar] | ||
| 370 | JNZ DELLOOP | ||
| 371 | MOV DX,DI ;Point to char after '/' | ||
| 372 | DEC DX | ||
| 373 | DEC DX ;Point to char before '/' | ||
| 374 | JMP DELLOOP | ||
| 375 | |||
| 376 | GOTDELE: | ||
| 377 | MOV DI,DX | ||
| 378 | POP AX ;Initial DI | ||
| 379 | POP DX | ||
| 380 | SUB AX,DI ;Distance moved | ||
| 381 | SUB CX,AX ;Set correct CX | ||
| 382 | CMP DX,DI | ||
| 383 | JB sja ;Found a pathsep | ||
| 384 | JA sjb ;Started with a pathsep, root | ||
| 385 | MOV AX,[DI] | ||
| 386 | CALL TESTKANJ | ||
| 387 | JNZ same_dirj | ||
| 388 | XCHG AH,AL | ||
| 389 | cmp al,[dirchar] | ||
| 390 | jz sja ;One character directory | ||
| 391 | same_dirj: | ||
| 392 | ELSE | ||
| 393 | mov al,[dirchar] ;get directory separator character | ||
| 394 | std ;scan backwards | ||
| 395 | repnz scasb ;(cx has the pathname length) | ||
| 396 | cld ;reset direction, just in case | ||
| 397 | jz sja | ||
| 398 | ENDIF | ||
| 399 | |||
| 400 | jmp same_dir ;no dir separator char. found, the | ||
| 401 | ; file is in the current directory | ||
| 402 | ; of the corresponding drive. Ergo, | ||
| 403 | ; the FCB contains the data already. | ||
| 404 | |||
| 405 | sja: | ||
| 406 | jcxz sjb ;no more chars left, it refers to root | ||
| 407 | cmp byte ptr [di],':' ;is the prvious character a disk def? | ||
| 408 | jne not_root | ||
| 409 | sjb: | ||
| 410 | mov [the_root],01h ;file is in the root | ||
| 411 | not_root: | ||
| 412 | inc di ;point to dir separator char. | ||
| 413 | mov al,0 | ||
| 414 | stosb ;nul terminate directory name | ||
| 415 | pop ax | ||
| 416 | push di ;save pointer to file name | ||
| 417 | mov [fudge],01h ;remember that the current directory | ||
| 418 | ; has been changed. | ||
| 419 | |||
| 420 | ;----- Save current directory for exit ---------------------------------; | ||
| 421 | mov dl,byte ptr ds:[fcb] ;get specified drive if any | ||
| 422 | or dl,dl ;default disk? | ||
| 423 | jz same_drive | ||
| 424 | dec dl ;adjust to real drive (a=0,b=1,...) | ||
| 425 | mov ah,set_default_drive ;change disks | ||
| 426 | int 21h | ||
| 427 | cmp al,-1 ;error? | ||
| 428 | jne same_drive | ||
| 429 | BADDRVSPEC: | ||
| 430 | mov dx,offset dg: baddrv | ||
| 431 | jmp printerr | ||
| 432 | |||
| 433 | same_drive: | ||
| 434 | mov ah,get_default_dpb | ||
| 435 | int 21h | ||
| 436 | |||
| 437 | assume ds:nothing | ||
| 438 | |||
| 439 | cmp al,-1 ;bad drive? (should always be ok) | ||
| 440 | jne drvisok | ||
| 441 | mov dx,offset dg: baddrv | ||
| 442 | jmp printerr | ||
| 443 | |||
| 444 | drvisok: | ||
| 445 | cmp [bx.dpb_current_dir],0 | ||
| 446 | je curr_is_root | ||
| 447 | mov si,bx | ||
| 448 | add si,dpb_dir_text | ||
| 449 | mov di,offset dg: userdir + 1 | ||
| 450 | |||
| 451 | dir_save_loop: | ||
| 452 | lodsb | ||
| 453 | stosb | ||
| 454 | or al,al | ||
| 455 | jnz dir_save_loop | ||
| 456 | |||
| 457 | curr_is_root: | ||
| 458 | push cs | ||
| 459 | pop ds | ||
| 460 | |||
| 461 | assume ds:dg | ||
| 462 | |||
| 463 | |||
| 464 | ;----- Change directories ----------------------------------------------; | ||
| 465 | cmp [the_root],01h | ||
| 466 | mov dx,offset dg: [dirchar] ;assume the root | ||
| 467 | je sj1 | ||
| 468 | mov dx,offset dg: [fname_buffer] | ||
| 469 | sj1: | ||
| 470 | mov ah,chdir ;change directory | ||
| 471 | int 21h | ||
| 472 | mov dx,offset dg: baddrv | ||
| 473 | jnc no_errors | ||
| 474 | jmp printerr | ||
| 475 | no_errors: | ||
| 476 | |||
| 477 | ;----- Set Up int 24 intercept -----------------------------------------; | ||
| 478 | |||
| 479 | mov ax,(get_interrupt_vector shl 8) or 24h | ||
| 480 | int 21h | ||
| 481 | mov word ptr [hardch],bx | ||
| 482 | mov word ptr [hardch+2],es | ||
| 483 | mov ax,(set_interrupt_vector shl 8) or 23h | ||
| 484 | mov dx,offset dg: int_23 | ||
| 485 | int 21h | ||
| 486 | mov ax,(set_interrupt_vector shl 8) or 24h | ||
| 487 | mov dx,offset dg: int_24 | ||
| 488 | int 21h | ||
| 489 | push cs | ||
| 490 | pop es | ||
| 491 | |||
| 492 | ;----- Parse filename to FCB -------------------------------------------; | ||
| 493 | pop si | ||
| 494 | mov di,fcb | ||
| 495 | mov ax,(parse_file_descriptor shl 8) or 1 | ||
| 496 | int 21h | ||
| 497 | push ax | ||
| 498 | ;-----------------------------------------------------------------------; | ||
| 499 | same_dir: | ||
| 500 | pop ax | ||
| 501 | |||
| 502 | mov bx,fcb | ||
| 503 | cmp byte ptr [bx+1],' ' ;must specify file name | ||
| 504 | jnz drvok | ||
| 505 | cmp byte ptr [bx],0 ;or drive specifier | ||
| 506 | jnz drvok | ||
| 507 | noname: mov dx,offset dg: drverr | ||
| 508 | call print | ||
| 509 | jmp int_23 | ||
| 510 | |||
| 511 | drvok: push ds | ||
| 512 | mov dl,drive | ||
| 513 | inc dl | ||
| 514 | mov ah,GET_DPB | ||
| 515 | int bdos | ||
| 516 | mov ax,word ptr [bx+2] ;get physical sector size | ||
| 517 | mov cl,byte ptr [bx+4] ;get sectors/cluster - 1 | ||
| 518 | xor ch,ch | ||
| 519 | inc cx | ||
| 520 | mov cs:secall,cx ;save sectors per cluster | ||
| 521 | mul cx ;ax = bytes per cluster | ||
| 522 | mov bp,word ptr [bx+11] ;get record of first sector | ||
| 523 | mov dx,word ptr [bx+16] ;get record of first directory entry | ||
| 524 | mov si,word ptr [bx+6] ;get record of first fat | ||
| 525 | mov cl,byte ptr [bx+15] ;get size of fat | ||
| 526 | mov di,word ptr [bx+13] ;get number of clusters | ||
| 527 | mov ch,byte ptr [bx+8] ;get number of fats on drive | ||
| 528 | mov bx,word ptr [bx+9] ;get max number of dir entries | ||
| 529 | pop ds | ||
| 530 | |||
| 531 | mov maxent,bx | ||
| 532 | mov firfat,si | ||
| 533 | mov firrec,bp | ||
| 534 | mov firdir,dx | ||
| 535 | mov byte ptr fatsiz,cl | ||
| 536 | mov lastfat,di ;number of fat entries | ||
| 537 | mov byte ptr fatnum,ch ;save number of fats on disk | ||
| 538 | |||
| 539 | mov secsiz,ax | ||
| 540 | |||
| 541 | mov di,table ;di points into constructed directory | ||
| 542 | mov ax,0e5e5h ;deleted file magic number | ||
| 543 | shl bx,1 ;16 words in a dir entry | ||
| 544 | shl bx,1 | ||
| 545 | shl bx,1 | ||
| 546 | shl bx,1 | ||
| 547 | mov cx,bx | ||
| 548 | rep stosw | ||
| 549 | |||
| 550 | call readft | ||
| 551 | mov bx,fcb | ||
| 552 | cmp byte ptr [bx+1],' ' | ||
| 553 | jz recdsk | ||
| 554 | jmp recfil | ||
| 555 | |||
| 556 | recdsk: mov di,table | ||
| 557 | mov fatptr,2 | ||
| 558 | mov ax,fatptr | ||
| 559 | step1: call getfat | ||
| 560 | cmp bx,0fffh | ||
| 561 | jz step1a | ||
| 562 | jmp step6 | ||
| 563 | step1a: mov filsiz,0 | ||
| 564 | mov word ptr filsiz+2,0 | ||
| 565 | mov dx,lastfat | ||
| 566 | mov target,ax | ||
| 567 | step2: mov ax,2 | ||
| 568 | add filsiz,cx | ||
| 569 | adc word ptr filsiz+2,0 | ||
| 570 | step3: call getfat | ||
| 571 | cmp bx,target | ||
| 572 | jne step4 | ||
| 573 | mov target,ax | ||
| 574 | jmp step2 | ||
| 575 | step4: inc ax | ||
| 576 | cmp ax,dx | ||
| 577 | jle step3 | ||
| 578 | ; | ||
| 579 | ; at this point target = head of list, filsiz = file size | ||
| 580 | ; | ||
| 581 | inc filcnt ;increment file count | ||
| 582 | mov ax,maxent | ||
| 583 | cmp filcnt,ax ;compare with max number of entries | ||
| 584 | ja direrr | ||
| 585 | |||
| 586 | mov si,(offset dg: dirent)+7 | ||
| 587 | nam0: inc byte ptr [si] ;increment file name | ||
| 588 | cmp byte ptr [si],'9' | ||
| 589 | jle nam1 | ||
| 590 | mov byte ptr [si],'0' | ||
| 591 | dec si | ||
| 592 | jmp nam0 | ||
| 593 | |||
| 594 | nam1: mov ah,GET_DATE | ||
| 595 | int bdos ;set the date | ||
| 596 | sub cx,1980 | ||
| 597 | add dh,dh | ||
| 598 | add dh,dh | ||
| 599 | add dh,dh | ||
| 600 | add dh,dh | ||
| 601 | add dh,dh | ||
| 602 | rcl cl,1 | ||
| 603 | or dh,dl | ||
| 604 | mov byte ptr dirent+24,dh | ||
| 605 | mov byte ptr dirent+25,cl | ||
| 606 | mov ah,GET_TIME | ||
| 607 | int bdos ;set the time | ||
| 608 | shr dh,1 | ||
| 609 | add cl,cl | ||
| 610 | add cl,cl | ||
| 611 | add cl,cl | ||
| 612 | rcl ch,1 | ||
| 613 | add cl,cl | ||
| 614 | rcl ch,1 | ||
| 615 | add cl,cl | ||
| 616 | rcl ch,1 | ||
| 617 | or dh,cl | ||
| 618 | mov byte ptr dirent+22,dh | ||
| 619 | mov byte ptr dirent+23,ch | ||
| 620 | |||
| 621 | mov ax,filsiz ;set file size | ||
| 622 | mov word ptr dirent+28,ax | ||
| 623 | mov ax,word ptr filsiz+2 | ||
| 624 | mov word ptr dirent+30,ax | ||
| 625 | mov ax,target ;set first cluster location | ||
| 626 | mov word ptr dirent+26,ax | ||
| 627 | |||
| 628 | mov si,offset dg: dirent ;copy in new dir entry | ||
| 629 | mov cx,32 | ||
| 630 | rep movsb | ||
| 631 | |||
| 632 | step6: inc fatptr ;keep looking for eof's | ||
| 633 | mov ax,fatptr | ||
| 634 | cmp ax,lastfat | ||
| 635 | jg step7 | ||
| 636 | jmp step1 | ||
| 637 | |||
| 638 | direrr: dec filcnt | ||
| 639 | mov dx,offset dg: dirmsg | ||
| 640 | call print | ||
| 641 | |||
| 642 | step7: | ||
| 643 | mov al,drive | ||
| 644 | mov dx,firdir ;write out constructed directory | ||
| 645 | mov cx,firrec | ||
| 646 | sub cx,dx | ||
| 647 | mov bx,table | ||
| 648 | call dskwrt | ||
| 649 | call pcrlf | ||
| 650 | mov dx,offset dg: recmsg_pre | ||
| 651 | call print | ||
| 652 | mov bx,offset dg: recmsg_post | ||
| 653 | mov si,filcnt | ||
| 654 | xor di,di ;output number of files created | ||
| 655 | call convert | ||
| 656 | jmp rexit | ||
| 657 | recfil: mov dx,fcb | ||
| 658 | mov ah,FCB_OPEN | ||
| 659 | int bdos | ||
| 660 | inc al | ||
| 661 | jnz recfil0 | ||
| 662 | mov dx,offset dg: opnerr | ||
| 663 | call print | ||
| 664 | jmp rexit | ||
| 665 | |||
| 666 | recfil0:mov lastfat,1 ;indicate location of list head | ||
| 667 | mov di,fcb | ||
| 668 | mov ax,[di+16] ;get file size | ||
| 669 | mov filsiz,ax | ||
| 670 | mov siztmp,ax | ||
| 671 | mov ax,[di+18] | ||
| 672 | mov filsiz+2,ax | ||
| 673 | mov siztmp+2,ax | ||
| 674 | mov ax,[di+25] ;get list head | ||
| 675 | or ax,ax | ||
| 676 | mov fatptr,ax | ||
| 677 | jnz recfil1 | ||
| 678 | recvec: jmp recfil6 | ||
| 679 | |||
| 680 | recfil1:cmp fatptr,0fffh | ||
| 681 | jz recvec ;terminate loop at e-o-f | ||
| 682 | |||
| 683 | mov cx,secall | ||
| 684 | mov ax,fatptr | ||
| 685 | dec ax | ||
| 686 | dec ax | ||
| 687 | mul cx | ||
| 688 | add ax,firrec | ||
| 689 | mov dx,ax | ||
| 690 | mov bx,table | ||
| 691 | mov al,drive | ||
| 692 | int aread | ||
| 693 | pop di ;restore stack pointer | ||
| 694 | mov di,fcb ;restore pointer to fcb | ||
| 695 | jnc recfil4 ;if no error continue reading | ||
| 696 | |||
| 697 | mov ax,fatptr | ||
| 698 | call getfat | ||
| 699 | cmp lastfat,1 | ||
| 700 | jnz recfil2 | ||
| 701 | |||
| 702 | cmp bx,0fffh | ||
| 703 | jnz noteof | ||
| 704 | xor bx,bx | ||
| 705 | noteof: mov word ptr [di+25],bx | ||
| 706 | jmp recfil3 | ||
| 707 | |||
| 708 | recfil2:mov dx,bx ;jump around bad sector | ||
| 709 | mov ax,lastfat | ||
| 710 | call setfat | ||
| 711 | |||
| 712 | recfil3:mov ax,fatptr ;mark sector bad | ||
| 713 | mov dx,0ff7h | ||
| 714 | call setfat | ||
| 715 | mov ax,secsiz ;prepare to dec filsiz by secsiz | ||
| 716 | cmp siztmp+2,0 | ||
| 717 | jnz recfilx | ||
| 718 | cmp siztmp,ax | ||
| 719 | ja recfilx | ||
| 720 | mov ax,siztmp | ||
| 721 | |||
| 722 | recfilx:sub word ptr [di+16],ax | ||
| 723 | sbb word ptr [di+18],0 | ||
| 724 | sub siztmp,ax | ||
| 725 | sbb siztmp,0 | ||
| 726 | |||
| 727 | and byte ptr [di+24],10111111b ;mark file dirty | ||
| 728 | |||
| 729 | mov ax,lastfat ;point to next sector to check | ||
| 730 | jmp recfil5 | ||
| 731 | |||
| 732 | recfil4: | ||
| 733 | mov ax,secsiz ;set bytes remaining to be read | ||
| 734 | sub siztmp,ax | ||
| 735 | sbb siztmp+2,0 | ||
| 736 | jnc recok | ||
| 737 | xor ax,ax ;if < 0, then set to zero | ||
| 738 | mov siztmp,ax | ||
| 739 | mov siztmp+2,ax | ||
| 740 | |||
| 741 | recok: mov ax,fatptr ;get next sector to test | ||
| 742 | mov lastfat,ax | ||
| 743 | recfil5:call getfat | ||
| 744 | mov fatptr,bx | ||
| 745 | jmp recfil1 | ||
| 746 | |||
| 747 | recfil6: ;all done | ||
| 748 | mov dx,fcb | ||
| 749 | mov ah,FCB_CLOSE | ||
| 750 | int bdos ;close the file | ||
| 751 | call pcrlf | ||
| 752 | call report | ||
| 753 | |||
| 754 | ; | ||
| 755 | rexit: mov ah,DISK_RESET | ||
| 756 | int bdos | ||
| 757 | call wrtfat ;save the fat | ||
| 758 | int_23: call rest_dir | ||
| 759 | rabort: int boot ;home, james... | ||
| 760 | |||
| 761 | ;----- Restore INT 24 vector and old current directory -----------------; | ||
| 762 | rest_dir: | ||
| 763 | cmp [fudge],0 | ||
| 764 | je no_fudge | ||
| 765 | |||
| 766 | mov ax,(set_interrupt_vector shl 8) or 24h | ||
| 767 | lds dx,[hardch] | ||
| 768 | int 21h | ||
| 769 | push cs | ||
| 770 | pop ds | ||
| 771 | |||
| 772 | mov dx,offset dg: userdir ;restore directory | ||
| 773 | mov ah,chdir | ||
| 774 | int 21h | ||
| 775 | mov dl,[user_drive] ;restore old current drive | ||
| 776 | mov ah,set_default_drive | ||
| 777 | int 21h | ||
| 778 | |||
| 779 | no_fudge: | ||
| 780 | ret | ||
| 781 | |||
| 782 | ;----- INT 24 Processing -----------------------------------------------; | ||
| 783 | |||
| 784 | int_24_retaddr dw int_24_back | ||
| 785 | |||
| 786 | int_24 proc far | ||
| 787 | assume ds:nothing,es:nothing,ss:nothing | ||
| 788 | |||
| 789 | pushf | ||
| 790 | push cs | ||
| 791 | push [int_24_retaddr] | ||
| 792 | push word ptr [hardch+2] | ||
| 793 | push word ptr [hardch] | ||
| 794 | ret | ||
| 795 | int_24 endp | ||
| 796 | |||
| 797 | int_24_back: | ||
| 798 | cmp al,2 ;abort? | ||
| 799 | jnz ireti | ||
| 800 | push cs | ||
| 801 | pop ds | ||
| 802 | |||
| 803 | assume ds:dg | ||
| 804 | |||
| 805 | call rest_dir | ||
| 806 | int 20h | ||
| 807 | ireti: | ||
| 808 | iret | ||
| 809 | |||
| 810 | IF KANJI | ||
| 811 | TESTKANJ: | ||
| 812 | CMP AL,81H | ||
| 813 | JB NOTLEAD | ||
| 814 | CMP AL,9FH | ||
| 815 | JBE ISLEAD | ||
| 816 | CMP AL,0E0H | ||
| 817 | JB NOTLEAD | ||
| 818 | CMP AL,0FCH | ||
| 819 | JBE ISLEAD | ||
| 820 | NOTLEAD: | ||
| 821 | PUSH AX | ||
| 822 | XOR AX,AX ;Set zero | ||
| 823 | POP AX | ||
| 824 | RET | ||
| 825 | |||
| 826 | ISLEAD: | ||
| 827 | PUSH AX | ||
| 828 | XOR AX,AX ;Set zero | ||
| 829 | INC AX ;Reset zero | ||
| 830 | POP AX | ||
| 831 | RET | ||
| 832 | ENDIF | ||
| 833 | |||
| 834 | code ends | ||
| 835 | |||
| 836 | const segment public byte | ||
| 837 | |||
| 838 | EXTRN BADVER:BYTE,askmsg:BYTE,drvlet:BYTE,dirmsg:BYTE | ||
| 839 | EXTRN recmsg_pre:BYTE,DRVLET1:BYTE,recmsg_post:BYTE | ||
| 840 | EXTRN crlf:BYTE,drverr:BYTE,baddrv:BYTE,opnerr:BYTE | ||
| 841 | |||
| 842 | const ends | ||
| 843 | |||
| 844 | data segment byte | ||
| 845 | |||
| 846 | PUBLIC filsiz | ||
| 847 | |||
| 848 | dirent db 'FILE0000REC' | ||
| 849 | db 21 dup (00) | ||
| 850 | |||
| 851 | fndfat dw 0000 ;sector of first good fat | ||
| 852 | filcnt dw 0000 | ||
| 853 | fatcnt db 00 | ||
| 854 | fatnum db 00 | ||
| 855 | fatsiz dw 0000 | ||
| 856 | firfat dw 0000 | ||
| 857 | fatptr dw 0000 | ||
| 858 | secall dw 0000 ;sectors per cluster | ||
| 859 | target dw 0000 | ||
| 860 | maxent dw 0000 | ||
| 861 | firrec dw 0000 | ||
| 862 | firdir dw 0000 | ||
| 863 | secsiz dw 0000 | ||
| 864 | siztmp dw 0000 | ||
| 865 | dw 0000 | ||
| 866 | filsiz dw 0000 | ||
| 867 | dw 0000 | ||
| 868 | lastfat dw 0000 | ||
| 869 | ; | ||
| 870 | table dw offset dg:fattbl + 6 * 1024 | ||
| 871 | fattbl db 0 | ||
| 872 | |||
| 873 | data ends | ||
| 874 | |||
| 875 | end recover | ||
| 876 | |||