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/CMD/COMMAND/TCMD1A.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/CMD/COMMAND/TCMD1A.ASM')
| -rw-r--r-- | v4.0/src/CMD/COMMAND/TCMD1A.ASM | 598 |
1 files changed, 598 insertions, 0 deletions
diff --git a/v4.0/src/CMD/COMMAND/TCMD1A.ASM b/v4.0/src/CMD/COMMAND/TCMD1A.ASM new file mode 100644 index 0000000..fd662b3 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TCMD1A.ASM | |||
| @@ -0,0 +1,598 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tcmd1a.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)tcmd1a.asm 1.1 85/05/14 | ||
| 4 | TITLE PART4 COMMAND Transient routines. | ||
| 5 | |||
| 6 | ; Internal commands DIR,PAUSE,ERASE,TYPE,VOL,VER | ||
| 7 | |||
| 8 | INCLUDE comsw.asm | ||
| 9 | .xlist | ||
| 10 | .xcref | ||
| 11 | INCLUDE DOSSYM.INC | ||
| 12 | INCLUDE comseg.asm | ||
| 13 | INCLUDE comequ.asm ;AC000; | ||
| 14 | include ioctl.inc ;AN000; | ||
| 15 | .list | ||
| 16 | .cref | ||
| 17 | |||
| 18 | DATARES SEGMENT PUBLIC BYTE ;AN020; | ||
| 19 | EXTRN append_flag:byte ;AN020; | ||
| 20 | EXTRN append_state:word ;AN020; | ||
| 21 | DATARES ENDS ;AN020; | ||
| 22 | |||
| 23 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 24 | EXTRN BadCD_ptr:word | ||
| 25 | EXTRN bits:word | ||
| 26 | EXTRN Bytmes_ptr:word | ||
| 27 | EXTRN comsw:word | ||
| 28 | EXTRN dir_w_syn:word ;AC000; | ||
| 29 | EXTRN dirdat_mo_day:word ;AC000; | ||
| 30 | EXTRN dirdat_yr:word ;AC000; | ||
| 31 | EXTRN dirdattim_ptr:word | ||
| 32 | EXTRN dirhead_ptr:word | ||
| 33 | EXTRN dirtim_hr_min:word ;AC000; | ||
| 34 | EXTRN Dirmes_ptr:word | ||
| 35 | EXTRN disp_file_size_ptr:word | ||
| 36 | EXTRN Dmes_ptr:word | ||
| 37 | EXTRN Extend_buf_ptr:word ;AN000; | ||
| 38 | EXTRN msg_disp_class:byte ;AN000; | ||
| 39 | EXTRN parse_dir:byte ;AC000; | ||
| 40 | EXTRN slash_p_syn:word ;AC000; | ||
| 41 | EXTRN string_buf_ptr:word | ||
| 42 | EXTRN tab_ptr:word ;AC000; | ||
| 43 | TRANDATA ENDS | ||
| 44 | |||
| 45 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 46 | EXTRN bytes_free:word | ||
| 47 | EXTRN charbuf:byte | ||
| 48 | EXTRN COM:byte | ||
| 49 | EXTRN Destisdir:byte | ||
| 50 | EXTRN Desttail:word | ||
| 51 | EXTRN dir_num:word | ||
| 52 | EXTRN Dirbuf:byte | ||
| 53 | EXTRN dirflag:byte ;AN015; | ||
| 54 | EXTRN display_ioctl:word ;AC000; | ||
| 55 | EXTRN display_mode:byte ;AC000; | ||
| 56 | EXTRN filecnt:word | ||
| 57 | EXTRN file_size_high:word | ||
| 58 | EXTRN file_size_low:word | ||
| 59 | EXTRN fullscr:word | ||
| 60 | EXTRN ID:byte | ||
| 61 | EXTRN lincnt:byte ;AC000; | ||
| 62 | EXTRN linlen:byte | ||
| 63 | EXTRN linperpag:word ;AC000; | ||
| 64 | EXTRN msg_numb:word ;AN022; | ||
| 65 | EXTRN parse1_addr:dword ;AC000; | ||
| 66 | EXTRN parse1_syn:word ;AC000; | ||
| 67 | EXTRN parse1_type:byte ;AC000; | ||
| 68 | EXTRN pathcnt:word ;AN000; | ||
| 69 | EXTRN pathpos:word ;AN000; | ||
| 70 | EXTRN resseg:word ;AN020; | ||
| 71 | EXTRN srcbuf:byte ;AC000; | ||
| 72 | EXTRN string_ptr_2:word | ||
| 73 | TRANSPACE ENDS | ||
| 74 | |||
| 75 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 76 | |||
| 77 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 78 | |||
| 79 | ;--------------- | ||
| 80 | |||
| 81 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 82 | EXTRN arg:byte ; the arg structure! | ||
| 83 | TRANSPACE ENDS | ||
| 84 | ;--------------- | ||
| 85 | |||
| 86 | EXTRN cerror:near | ||
| 87 | EXTRN std_printf:near | ||
| 88 | |||
| 89 | |||
| 90 | PUBLIC catalog | ||
| 91 | |||
| 92 | |||
| 93 | break Catalog - Directory command | ||
| 94 | assume ds:trangroup,es:trangroup | ||
| 95 | |||
| 96 | ; | ||
| 97 | ; The DIR command displays the contents of a directory. | ||
| 98 | ; | ||
| 99 | ; **************************************************************** | ||
| 100 | ; * | ||
| 101 | ; * ROUTINE: CATALOG - display file(s) in directory | ||
| 102 | ; * | ||
| 103 | ; * FUNCTION: PARSE command line for drive, file, or path name. | ||
| 104 | ; * DIR allows two switches, /P (pause) and /W (wide). | ||
| 105 | ; * If an error occurs issue and error message and | ||
| 106 | ; * transfer control to CERROR. | ||
| 107 | ; * | ||
| 108 | ; * INPUT: command line at offset 81H | ||
| 109 | ; * | ||
| 110 | ; * OUTPUT: none | ||
| 111 | ; * | ||
| 112 | ; **************************************************************** | ||
| 113 | |||
| 114 | CATALOG: | ||
| 115 | |||
| 116 | ; | ||
| 117 | ; Set up DTA for dir search firsts | ||
| 118 | ; | ||
| 119 | mov dx,offset trangroup:Dirbuf ;AC000; Set Disk transfer address | ||
| 120 | mov ah,Set_DMA ;AC000; | ||
| 121 | int int_command ;AC000; | ||
| 122 | ; | ||
| 123 | ; Set up defaults for switches and parse the command line. | ||
| 124 | ; | ||
| 125 | mov msg_numb,0 ;AN022; initialize message flag | ||
| 126 | mov di,offset trangroup:srcbuf ;AN000; get address of srcbuf | ||
| 127 | mov [pathpos],di ;AN000; this is start of path | ||
| 128 | mov [pathcnt],1 ;AN000; initialize length to 1 char | ||
| 129 | mov al,star ;AN000; initialize srcbuf to *,0d | ||
| 130 | stosb ;AN000; | ||
| 131 | mov al,end_of_line_in ;AN000; | ||
| 132 | stosb ;AN000; | ||
| 133 | mov si,81H ;AN000; Get command line | ||
| 134 | mov di,offset trangroup:parse_dir ;AN000; Get adderss of PARSE_DIR | ||
| 135 | xor cx,cx ;AC000; clear counter for positionals | ||
| 136 | mov ComSw,cx ;AC000; initialize flags | ||
| 137 | mov bits,cx ;AC000; initialize switches | ||
| 138 | mov linperpag,linesperpage ;AC000; Set default for lines per page | ||
| 139 | mov linlen,normperlin ;AC000; Set number of entries per line | ||
| 140 | mov lincnt,normperlin ;AC000; | ||
| 141 | |||
| 142 | dirscan: | ||
| 143 | xor dx,dx ;AN000; | ||
| 144 | invoke parse_with_msg ;AC018; call parser | ||
| 145 | cmp ax,end_of_line ;AN000; are we at end of line? | ||
| 146 | jne dirscan_cont ;AN000; No - continue parsing | ||
| 147 | jmp scandone ;AN000; yes - go process | ||
| 148 | |||
| 149 | dirscan_cont: | ||
| 150 | cmp ax,result_no_error ;AN000; did we have an error? | ||
| 151 | jz dirscan_cont2 ;AN000; No - continue parsing | ||
| 152 | jmp badparm ;AN000; yes - exit | ||
| 153 | |||
| 154 | dirscan_cont2: | ||
| 155 | cmp parse1_syn,offset trangroup:dir_w_syn ;AN000; was /W entered? | ||
| 156 | je set_dir_width ;AN000; yes - go set wide lines | ||
| 157 | cmp parse1_syn,offset trangroup:slash_p_syn ;AN000; was /P entered? | ||
| 158 | je set_dir_pause ;AN000; yes - go set pause at end of screen | ||
| 159 | ; | ||
| 160 | ; Must be filespec since no other matches occurred. move filename to srcbuf | ||
| 161 | ; | ||
| 162 | push si ;AC000; save position in line | ||
| 163 | lds si,parse1_addr ;AC000; get address of filespec | ||
| 164 | push si ;AN000; save address | ||
| 165 | invoke move_to_srcbuf ;AC000; move to srcbuf | ||
| 166 | pop dx ;AC000; get address in DX | ||
| 167 | |||
| 168 | ; | ||
| 169 | ; The user may have specified a device. Search for the path and see if the | ||
| 170 | ; attributes indicate a device. | ||
| 171 | ; | ||
| 172 | mov ah,Find_First ;AC000; find the file | ||
| 173 | int int_command ;AC000; | ||
| 174 | jnc Dir_check_device ;AN022; if no error - check device | ||
| 175 | invoke get_ext_error_number ;AN022; get the extended error | ||
| 176 | cmp ax,error_no_more_files ;AN022; was error no file found | ||
| 177 | jz Dir_fspec_end ;AC022; yes -> obviously not a device | ||
| 178 | cmp ax,error_path_not_found ;AN022; was error no file found | ||
| 179 | jz Dir_fspec_end ;AC022; yes -> obviously not a device | ||
| 180 | jmp dir_err_setup ;AN022; otherwise - go issue error message | ||
| 181 | |||
| 182 | dir_check_device: ;AN022; | ||
| 183 | test byte ptr (DirBuf+find_buf_attr),attr_device ;AC000; | ||
| 184 | jz Dir_fspec_end ;AC000; no, go do normal operation | ||
| 185 | mov ComSw,-2 ;AC000; signal device | ||
| 186 | |||
| 187 | dir_fspec_end: | ||
| 188 | pop si ;AC000; restore position in line | ||
| 189 | jmp short dirscan ;AC000; keep parsing | ||
| 190 | |||
| 191 | set_dir_width: | ||
| 192 | test byte ptr[bits],SwitchW ;AN018; /W already set? | ||
| 193 | jz ok_set_width ;AN018; no - okay to set width | ||
| 194 | mov ax,moreargs_ptr ;AN018; set up too many arguments | ||
| 195 | invoke setup_parse_error_msg ;AN018; set up an error message | ||
| 196 | jmp badparm ;AN018; exit | ||
| 197 | |||
| 198 | ok_set_width: | ||
| 199 | or bits,switchw ;AC000; indicate /w was selected | ||
| 200 | mov linlen,wideperlin ;AC000; Set number of entries per line | ||
| 201 | mov lincnt,wideperlin ;AC000; | ||
| 202 | jmp short dirscan ;AC000; keep parsing | ||
| 203 | |||
| 204 | set_dir_pause: | ||
| 205 | test byte ptr[bits],SwitchP ;AN018; /p already set? | ||
| 206 | jz ok_set_pause ;AN018; no - okay to set width | ||
| 207 | mov ax,moreargs_ptr ;AN018; set up too many arguments | ||
| 208 | invoke setup_parse_error_msg ;AN018; set up an error message | ||
| 209 | jmp badparm ;AN018; exit | ||
| 210 | |||
| 211 | ok_set_pause: | ||
| 212 | or bits,switchp ;AC000; indicate /p was selected | ||
| 213 | push cx ;AN000; save necessary registers | ||
| 214 | push si ;AN000; | ||
| 215 | mov ax,(IOCTL SHL 8) + generic_ioctl_handle ;AN000; get lines per page on display | ||
| 216 | mov bx,stdout ;AN000; lines for stdout | ||
| 217 | mov ch,ioc_sc ;AN000; type is display | ||
| 218 | mov cl,get_generic ;AN000; get information | ||
| 219 | mov dx,offset trangroup:display_ioctl ;AN000; | ||
| 220 | int int_command ;AN000; | ||
| 221 | |||
| 222 | lines_set: | ||
| 223 | dec linperpag ;AN000; lines per actual page should | ||
| 224 | dec linperpag ;AN000; two less than the max | ||
| 225 | mov ax,linperpag ;AN000; get number of lines into | ||
| 226 | mov [fullscr],ax ;AC000; screen line counter | ||
| 227 | pop si ;AN000; restore registers | ||
| 228 | pop cx ;AN000; | ||
| 229 | jmp dirscan ;AC000; keep parsing | ||
| 230 | |||
| 231 | ; | ||
| 232 | ; The syntax is incorrect. Report only message we can. | ||
| 233 | ; | ||
| 234 | BadParm: | ||
| 235 | jmp cerror ;AC000; invalid switches get displayed | ||
| 236 | |||
| 237 | ScanDone: | ||
| 238 | |||
| 239 | ; | ||
| 240 | ; Find and display the volume ID on the drive. | ||
| 241 | ; | ||
| 242 | |||
| 243 | invoke okvolarg ;AC000; | ||
| 244 | mov [filecnt],0 ;AC000; Keep track of how many files found | ||
| 245 | cmp comsw,0 ;AC000; did an error occur? | ||
| 246 | jnz doheader ;AC000; yes - don't bother to fix path | ||
| 247 | |||
| 248 | mov dirflag,-1 ;AN015; set pathcrunch called from DIR | ||
| 249 | invoke pathcrunch ;AC000; set up FCB for dir | ||
| 250 | mov dirflag,0 ;AN015; reset dirflag | ||
| 251 | jc DirCheckPath ;AC015; no CHDIRs worked. | ||
| 252 | jz doheader ;AC015; chdirs worked - path\*.* | ||
| 253 | mov si,[desttail] ;AN015; get filename back | ||
| 254 | jmp short DoRealParse ;AN015; go parse it | ||
| 255 | |||
| 256 | DirCheckPath: | ||
| 257 | mov ax,[msg_numb] ;AN022; get message number | ||
| 258 | cmp ax,0 ;AN022; Is there a message? | ||
| 259 | jnz dir_err_setup ;AN022; yes - there's an error | ||
| 260 | cmp [destisdir],0 ;AC000; Were pathchars found? | ||
| 261 | jz doparse ;AC000; no - no problem | ||
| 262 | inc comsw ;AC000; indicate error | ||
| 263 | jmp short doheader ;AC000; go print header | ||
| 264 | |||
| 265 | DirNF: | ||
| 266 | mov ax,error_file_not_found ;AN022; get message number in control block | ||
| 267 | |||
| 268 | dir_err_setup: | ||
| 269 | mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class | ||
| 270 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 271 | mov extend_buf_ptr,ax ;AN022; | ||
| 272 | |||
| 273 | DirError: | ||
| 274 | jmp Cerror | ||
| 275 | |||
| 276 | ; | ||
| 277 | ; We have changed to something. We also have a file. Parse it into a | ||
| 278 | ; reasonable form, leaving drive alone, leaving extention alone and leaving | ||
| 279 | ; filename alone. We need to special case ... If we are at the root, the | ||
| 280 | ; parse will fail and it will give us a file not found instead of file not | ||
| 281 | ; found. | ||
| 282 | ; | ||
| 283 | DoParse: | ||
| 284 | mov si,offset trangroup:srcbuf ;AN000; Get address of source | ||
| 285 | cmp byte ptr [si+1],colon_char ;AN000; Is there a drive? | ||
| 286 | jnz dir_no_drive ;AN000; no - keep going | ||
| 287 | lodsw ;AN000; bypass drive | ||
| 288 | |||
| 289 | dir_no_drive: | ||
| 290 | cmp [si],".." | ||
| 291 | jnz DoRealParse | ||
| 292 | cmp byte ptr [si+2],0 | ||
| 293 | jnz DoRealParse | ||
| 294 | inc ComSw | ||
| 295 | jmp short DoHeader | ||
| 296 | |||
| 297 | DoRealParse: | ||
| 298 | mov di,FCB ; where to put the file name | ||
| 299 | mov ax,(Parse_File_Descriptor SHL 8) OR 0EH | ||
| 300 | int int_command | ||
| 301 | |||
| 302 | ; | ||
| 303 | ; Check to see if APPEND installed. If it is installed, set all flags | ||
| 304 | ; off. This will be reset in the HEADFIX routine | ||
| 305 | ; | ||
| 306 | |||
| 307 | DoHeader: | ||
| 308 | mov ax,AppendInstall ;AN020; see if append installed | ||
| 309 | int 2fh ;AN020; | ||
| 310 | cmp al,0 ;AN020; append installed? | ||
| 311 | je DoHeaderCont ;AN020; no - continue | ||
| 312 | mov ax,AppendDOS ;AN020; see if append DOS version right | ||
| 313 | int 2fh ;AN020; | ||
| 314 | cmp ax,-1 ;AN020; append version correct? | ||
| 315 | jne DoHeaderCont ;AN020; no - continue | ||
| 316 | mov ax,AppendGetState ;AN020; Get the state of Append | ||
| 317 | int 2fh ;AN020; | ||
| 318 | push ds ;AN020; save current data segment | ||
| 319 | mov ds,[resseg] ;AN020; get resident segment | ||
| 320 | assume ds:resgroup ;AN020; | ||
| 321 | mov append_state,bx ;AN020; save append state | ||
| 322 | mov append_flag,-1 ;AN020; set append flag | ||
| 323 | xor bx,bx ;AN020; clear out state | ||
| 324 | mov ax,AppendSetState ;AN020; Set the state of Append | ||
| 325 | int 2fh ;AN020; set everything off | ||
| 326 | pop ds ;AN020; save current data segment | ||
| 327 | assume ds:trangroup ;AN020; | ||
| 328 | |||
| 329 | ; | ||
| 330 | ; Display the header | ||
| 331 | ; | ||
| 332 | |||
| 333 | DoHeaderCont: | ||
| 334 | mov al,blank ;AN051; Print out a blank | ||
| 335 | invoke print_char ;AN051; before DIR header | ||
| 336 | invoke build_dir_string ; get current dir string | ||
| 337 | mov dx,offset trangroup:Dirhead_ptr | ||
| 338 | invoke printf_crlf ; bang! | ||
| 339 | |||
| 340 | ; | ||
| 341 | ; If there were chars left after parse or device, then invalid file name | ||
| 342 | ; | ||
| 343 | cmp ComSw,0 | ||
| 344 | jz DoSearch ; nothing left; good parse | ||
| 345 | jl DirNFFix ; not .. => error file not found | ||
| 346 | invoke RestUDir | ||
| 347 | mov dx,offset TranGroup:BadCD_ptr | ||
| 348 | jmp Cerror ; was .. => error directory not found | ||
| 349 | DirNFFix: | ||
| 350 | invoke RestUDir | ||
| 351 | jmp DirNF | ||
| 352 | ; | ||
| 353 | ; We are assured that everything is correct. Let's go and search. Use | ||
| 354 | ; attributes that will include finding directories. perform the first search | ||
| 355 | ; and reset our directory afterward. | ||
| 356 | ; | ||
| 357 | DoSearch: | ||
| 358 | mov byte ptr DS:[FCB-7],0FFH | ||
| 359 | mov byte ptr DS:[FCB-1],010H | ||
| 360 | ; | ||
| 361 | ; Caution! Since we are using an extended FCB, we will *also* be returning | ||
| 362 | ; the directory information as an extended FCB. We must bias all fetches into | ||
| 363 | ; DIRBUF by 8 (Extended FCB part + drive) | ||
| 364 | ; | ||
| 365 | mov ah,Dir_Search_First | ||
| 366 | mov dx,FCB-7 | ||
| 367 | int int_command | ||
| 368 | |||
| 369 | push ax ;AN022; save return state | ||
| 370 | inc al ;AN022; did an error occur? | ||
| 371 | pop ax ;AN022; get return state back | ||
| 372 | jnz found_first_file ;AN022; no error - start dir | ||
| 373 | invoke set_ext_error_msg ;AN022; yes - set up error message | ||
| 374 | push dx ;AN022; save message | ||
| 375 | invoke restudir ;AN022; restore user's dir | ||
| 376 | pop dx ;AN022; restore message | ||
| 377 | cmp word ptr Extend_Buf_Ptr,Error_No_More_Files ;AN022; convert no more files to | ||
| 378 | jnz DirCerrorJ ;AN022; file not found | ||
| 379 | mov Extend_Buf_Ptr,Error_File_Not_Found ;AN022; | ||
| 380 | |||
| 381 | DirCerrorJ: ;AN022; | ||
| 382 | jmp Cerror ;AN022; exit | ||
| 383 | |||
| 384 | ; | ||
| 385 | ; Restore the user's directory. We preserve, though, the return from the | ||
| 386 | ; previous system call for later checking. | ||
| 387 | ; | ||
| 388 | |||
| 389 | found_first_file: | ||
| 390 | push ax | ||
| 391 | invoke restudir | ||
| 392 | pop ax | ||
| 393 | ; | ||
| 394 | ; Main scanning loop. Entry has AL = Search first/next error code. Test for | ||
| 395 | ; no more. | ||
| 396 | ; | ||
| 397 | DIRSTART: | ||
| 398 | inc al ; FF = file not found | ||
| 399 | jnz Display | ||
| 400 | jmp DirDone ; Either an error or we are finished | ||
| 401 | ; | ||
| 402 | ; Note that we've seen a file and display the found file. | ||
| 403 | ; | ||
| 404 | |||
| 405 | Display: | ||
| 406 | inc [filecnt] ; Keep track of how many we find | ||
| 407 | mov si,offset trangroup:dirbuf+8 ; SI -> information returned by sys call | ||
| 408 | call shoname | ||
| 409 | ; | ||
| 410 | ; If we are displaying in wide mode, do not output the file info | ||
| 411 | ; | ||
| 412 | test byte ptr[bits],SwitchW ; W switch set? | ||
| 413 | jz DirTest | ||
| 414 | jmp nexent ; If so, no size, date, or time | ||
| 415 | |||
| 416 | ; | ||
| 417 | ; Test for directory. | ||
| 418 | ; | ||
| 419 | DirTest: | ||
| 420 | test [dirbuf+8].dir_attr,attr_directory | ||
| 421 | jz fileent | ||
| 422 | ; | ||
| 423 | ; We have a directory. Display the <DIR> field in place of the file size | ||
| 424 | ; | ||
| 425 | mov dx,offset trangroup:Dmes_ptr | ||
| 426 | call std_printf | ||
| 427 | jmp short nofsiz | ||
| 428 | ; | ||
| 429 | ; We have a file. Display the file size | ||
| 430 | ; | ||
| 431 | fileent: | ||
| 432 | mov dx,[DirBuf+8].dir_size_l | ||
| 433 | mov file_size_low,dx | ||
| 434 | mov dx,[DirBuf+8].dir_size_h | ||
| 435 | mov file_size_high,dx | ||
| 436 | mov dx,offset trangroup:disp_file_size_ptr | ||
| 437 | call std_printf | ||
| 438 | ; | ||
| 439 | ; Display time and date of last modification | ||
| 440 | ; | ||
| 441 | nofsiz: | ||
| 442 | mov ax,[DirBuf+8].dir_date ; Get date | ||
| 443 | ; | ||
| 444 | ; If the date is 0, then we have found a 1.x level diskette. We skip the | ||
| 445 | ; date/time fields as 1.x did not have them. | ||
| 446 | ; | ||
| 447 | or ax,ax | ||
| 448 | jz nexent ; Skip if no date | ||
| 449 | mov bx,ax | ||
| 450 | and ax,1FH ; get day | ||
| 451 | mov dl,al | ||
| 452 | mov ax,bx | ||
| 453 | mov cl,5 | ||
| 454 | shr ax,cl ; Align month | ||
| 455 | and al,0FH ; Get month | ||
| 456 | mov dh,al | ||
| 457 | mov cl,bh | ||
| 458 | shr cl,1 ; Align year | ||
| 459 | xor ch,ch | ||
| 460 | add cx,80 ; Relative 1980 | ||
| 461 | cmp cl,100 | ||
| 462 | jb millenium | ||
| 463 | sub cl,100 | ||
| 464 | |||
| 465 | millenium: | ||
| 466 | xchg dh,dl ;AN000; switch month & day | ||
| 467 | mov DirDat_yr,cx ;AC000; put year into message control block | ||
| 468 | mov DirDat_mo_day,dx ;AC000; put month and day into message control block | ||
| 469 | mov cx,[DirBuf+8].dir_time ; Get time | ||
| 470 | jcxz prbuf ; Time field present? | ||
| 471 | shr cx,1 | ||
| 472 | shr cx,1 | ||
| 473 | shr cx,1 | ||
| 474 | shr cl,1 | ||
| 475 | shr cl,1 ; Hours in CH, minutes in CL | ||
| 476 | xchg ch,cl ;AN000; switch hours & minutes | ||
| 477 | mov DirTim_hr_min,cx ;AC000; put hours and minutes into message subst block | ||
| 478 | |||
| 479 | prbuf: | ||
| 480 | mov dx,offset trangroup:DirDatTim_ptr | ||
| 481 | call std_printf | ||
| 482 | invoke crlf2 ;AC066;end the line | ||
| 483 | dec byte ptr [fullscr] ;AC066;count the line | ||
| 484 | jnz endif04 ;AN066;IF the last on the screen THEN | ||
| 485 | call check_for_P ;AN066; pause if /P requested | ||
| 486 | endif04: ;AN066; | ||
| 487 | jmp scroll ; If not, just continue | ||
| 488 | ;AD061; mov DirDat_yr,0 ;AC000; reset year, month and day | ||
| 489 | ;AD061; mov DirDat_mo_day,0 ;AC000; in control block | ||
| 490 | ;AD061; mov DirTim_hr_min,0 ;AC000; reset hour & minute in control block | ||
| 491 | ; | ||
| 492 | ; We are done displaying an entry. The code between "noexent:" and "scroll:" | ||
| 493 | ; is only for /W case. | ||
| 494 | ; | ||
| 495 | nexent: | ||
| 496 | mov bl,[lincnt] ;AN066;save for check for first entry on line | ||
| 497 | dec [lincnt] ;count this entry on the line | ||
| 498 | jnz else01 ;AX066;IF last entry on line THEN | ||
| 499 | mov al,[linlen] | ||
| 500 | mov [lincnt],al | ||
| 501 | invoke crlf2 | ||
| 502 | cmp [fullscr],0 ;AC066;IF have filled the screen THEN | ||
| 503 | jnz endif02 ;AN066; | ||
| 504 | call check_for_P ;AN066; reinitialize fullscr, | ||
| 505 | endif02: ;AN066; IF P requested THEN pause | ||
| 506 | jmp short endif01 ;AN066; | ||
| 507 | else01: ;AN066;ELSE since screen not full | ||
| 508 | cmp bl,[linlen] ;AN066; IF starting new line THEN | ||
| 509 | jne endif03 ; count the line | ||
| 510 | dec byte ptr [fullscr] ;AN066; ENDIF | ||
| 511 | endif03: ;AC066;We are outputting on the same line, between fields, we tab. | ||
| 512 | mov dx,offset trangroup:tab_ptr ;Output a tab | ||
| 513 | call std_printf | ||
| 514 | endif01: ;AX066; | ||
| 515 | ; | ||
| 516 | ; All we need to do now is to get the next directory entry. | ||
| 517 | ; | ||
| 518 | scroll: | ||
| 519 | mov ah,Dir_Search_Next | ||
| 520 | mov dx,FCB-7 ; DX -> Unopened FCB | ||
| 521 | int int_command ; Search for a file to match FCB | ||
| 522 | jmp DirStart | ||
| 523 | ; | ||
| 524 | ; If no files have been found, display a not-found message | ||
| 525 | ; | ||
| 526 | DirDone: | ||
| 527 | invoke get_ext_error_number ;AN022; get the extended error number | ||
| 528 | cmp ax,error_no_more_files ;AN022; was error file not found? | ||
| 529 | jnz dir_err_setup_jmp ;AN022; no - setup error message | ||
| 530 | test [filecnt],-1 | ||
| 531 | jnz Trailer | ||
| 532 | mov ax,error_file_not_found ;AN022; | ||
| 533 | |||
| 534 | dir_err_setup_jmp: ;AN022; | ||
| 535 | jmp dir_err_setup ;AN022; go setup error msg & print it | ||
| 536 | ; | ||
| 537 | ; If we have printed the maximum number of files per line, terminate it with | ||
| 538 | ; CRLF. | ||
| 539 | ; | ||
| 540 | Trailer: | ||
| 541 | mov al,[linlen] | ||
| 542 | cmp al,[lincnt] ; Will be equal if just had CR/LF | ||
| 543 | jz mmessage | ||
| 544 | invoke crlf2 | ||
| 545 | cmp [fullscr],0 ;AN066;IF on last line of screen THEN | ||
| 546 | jnz endif06 ;AN066; pause before going on | ||
| 547 | call check_for_P ;AN066; to number and freespace | ||
| 548 | endif06: ;AN066; displays | ||
| 549 | |||
| 550 | mmessage: | ||
| 551 | mov dx,offset trangroup:Dirmes_ptr | ||
| 552 | mov si,[filecnt] | ||
| 553 | mov dir_num,si | ||
| 554 | call std_printf | ||
| 555 | mov ah,Get_Drive_Freespace | ||
| 556 | mov dl,byte ptr DS:[FCB] | ||
| 557 | int int_command | ||
| 558 | cmp ax,-1 | ||
| 559 | retz | ||
| 560 | mul cx ; AX is bytes per cluster | ||
| 561 | mul bx | ||
| 562 | mov bytes_free,ax ;AC000; | ||
| 563 | mov bytes_free+2,dx ;AC000; | ||
| 564 | MOV DX,OFFSET TRANGROUP:BYTMES_ptr | ||
| 565 | jmp std_printf | ||
| 566 | |||
| 567 | shoname: | ||
| 568 | mov di,offset trangroup:charbuf | ||
| 569 | mov cx,8 | ||
| 570 | rep movsb | ||
| 571 | mov al,' ' | ||
| 572 | stosb | ||
| 573 | mov cx,3 | ||
| 574 | rep movsb | ||
| 575 | xor ax,ax | ||
| 576 | stosb | ||
| 577 | push dx | ||
| 578 | mov dx,offset trangroup:charbuf | ||
| 579 | mov string_ptr_2,dx | ||
| 580 | mov dx,offset trangroup:string_buf_ptr | ||
| 581 | call std_printf | ||
| 582 | pop DX | ||
| 583 | return | ||
| 584 | |||
| 585 | check_for_P PROC NEAR ;AN066; | ||
| 586 | |||
| 587 | test byte ptr[bits],SwitchP ;P switch present? | ||
| 588 | jz endif05 ;AN066; | ||
| 589 | mov ax,linperpag ;AN000; transfer lines per page | ||
| 590 | mov [fullscr],ax ;AC000; to fullscr | ||
| 591 | invoke Pause | ||
| 592 | endif05: | ||
| 593 | ret ;AN066; | ||
| 594 | |||
| 595 | check_for_P ENDP ;AN066; | ||
| 596 | |||
| 597 | trancode ends | ||
| 598 | end | ||