]> wirehaze git hosting - MS-DOS.git/blob - v2.0/source/XENIX.ASM

wirehaze git hosting

rewrote Readme in proper German.
[MS-DOS.git] / v2.0 / source / XENIX.ASM
1 ;
2 ; xenix file calls for MSDOS
3 ;
4
5 INCLUDE DOSSEG.ASM
6
7 IFNDEF KANJI
8 KANJI EQU 0 ;FALSE
9 ENDIF
10
11 CODE SEGMENT BYTE PUBLIC 'CODE'
12 ASSUME SS:DOSGROUP,CS:DOSGROUP
13
14 .xlist
15 .xcref
16 INCLUDE DOSSYM.ASM
17 INCLUDE DEVSYM.ASM
18 .cref
19 .list
20
21 TITLE XENIX - IO system to mimic UNIX
22 NAME XENIX
23
24 i_need NoSetDir,BYTE
25 i_need CURDRV,BYTE
26 i_need IOCALL,BYTE
27 i_need IOMED,BYTE
28 i_need IOSCNT,WORD
29 i_need IOXAD,DWORD
30 i_need DIRSTART,WORD
31 i_need ATTRIB,BYTE
32 i_need THISFCB,DWORD
33 i_need AuxStack,BYTE
34 i_need Creating,BYTE
35 i_need ThisDRV,BYTE
36 i_need NAME1,BYTE
37 i_need LastEnt,WORD
38 i_need ThisDPB,DWORD
39 i_need EntLast,WORD
40 i_need CurrentPDB,WORD
41 i_need sft_addr,DWORD ; pointer to head of table
42 i_need CURBUF,DWORD ; pointer to current buffer
43 i_need DMAADD,DWORD ; pointer to current dma address
44
45 BREAK <Local data>
46
47 CODE ENDS
48 DATA SEGMENT BYTE PUBLIC 'DATA'
49
50 open_name DW ?
51 DW ?
52 open_access DB ?
53 open_jfn DW ? ; accessed as DD
54 open_jfn_b DW ? ; accessed as DD with above
55 open_sfn DW ?
56 open_sfoff DW ? ; accessed as DD
57 open_sfn_b DW ? ; accessed as DD with above
58 open_devid DB ?
59 Cr_read_only DB ?
60 rename_source DD ?
61 rename_dest DD ?
62
63 DATA ENDS
64 CODE SEGMENT BYTE PUBLIC 'CODE'
65
66 BREAK <Validate_path - check to see if there are meta characters in path>
67
68 ;
69 ; Input: DS:DX is an ASCIZ path
70 ; Output: Carry set if meta-characters present or path malformed and
71 ; Zero is set if the only problem is that meta-characters
72 ; are present in the last element of the path
73 procedure Validate_path,near
74 ASSUME DS:NOTHING,ES:NOTHING
75 PUSH AX
76 PUSH CX
77 PUSH SI
78 MOV SI,DX
79 MOV CX,0FFH ;No path seps yet
80 MOV AX,[SI] ; Get first two bytes
81 OR AL,AL
82 JZ validate_malformed ; NUL path
83 CMP AH,':'
84 JNZ validate_loop ; OK so far
85 CMP BYTE PTR [SI+2],0
86 JZ validate_malformed ; NUL path (just d:)
87 validate_loop:
88 LODSB
89 validate_loop1:
90
91 IF KANJI
92 invoke TESTKANJ
93 JZ NOTKANJ6
94 INC SI
95 JMP validate_loop
96
97 NOTKANJ6:
98 ENDIF
99
100 OR AL,AL
101 JZ validate_end
102 CMP AL,"?"
103 JZ validate_error
104 CMP AL,"*"
105 JZ validate_error
106 invoke PathChrCmp
107 JNZ validate_loop
108 JCXZ validate_malformed ;If path sep, cannot have meta yet
109 LODSB ;Look ahead one char
110 OR AL,AL
111 JZ validate_checktslsh ;Trailing path sep
112 invoke PathChrCmp
113 JNZ validate_loop1 ;Double path sep?
114 validate_malformed:
115 INC CX
116 OR CX,CX ;Reset zero
117 JMP SHORT validate_set_carry
118
119 validate_error:
120 XOR CX,CX ;Flag metas found
121 JMP validate_loop
122
123 validate_checktslsh:
124 ;A bizarre case, "/" is OK, "d:/" is OK, anything else is an error
125 SUB SI,DX
126 CMP SI,2
127 JZ validate_end ;Two chars, the '/' and the NUL
128 CMP SI,4
129 JNZ validate_malformed ;Four chars, "D:/<NUL>"
130 MOV SI,DX
131 CMP BYTE PTR [SI+1],':'
132 JNZ validate_malformed ;Second char must be a ':'
133
134 validate_end:
135 OR CX,CX ;Clears carry
136 JNZ validate_ok ;No metas found, leave carry clear
137 validate_set_carry:
138 STC
139 validate_ok:
140 POP SI
141 POP CX
142 POP AX
143 return
144 validate_path ENDP
145
146 BREAK <Access_path - determine if file found>
147
148 ;
149 ; Input: DS:DX point to a path
150 ; Output: Carry reset - outputs of GetPath
151 ; carry set - AL has error code
152 ;
153 procedure Access_path,NEAR
154 ASSUME DS:NOTHING,ES:NOTHING
155 CALL Validate_path
156 JC access_no_path
157 MOV SI,DX
158 invoke GetPath
159 retnc
160 MOV AL,error_file_not_found
161 OR CL,CL
162 JNZ access_ret
163 access_no_path:
164 MOV AL,error_path_not_found
165 access_ret:
166 STC
167 return
168 access_path ENDP
169
170 BREAK <Find_free_jfn - return a free jfn in users PDB>
171 ;
172 ; system file table data
173 ;
174
175 ;
176 ; The system file table is two linear tables. The first table is the
177 ; DOS initialization table containing a default number of FCBs. The
178 ; first word in the table is a link to the second table, which
179 ; SYSINIT sets up, the second word is the number of FCBs in the table.
180 ;
181
182 ;
183 ; find_free_jfn
184 ; input: none
185 ; output: JNC <found>
186 ; ES:DI is pointer to free JFN
187 ; JC <no free jfns>
188 ; ES,DI indeterminate
189 ;
190 procedure Find_free_jfn,NEAR
191 ASSUME DS:NOTHING,ES:NOTHING
192 PUSH AX
193 PUSH CX
194 MOV AL,0FFh
195 MOV ES,[CurrentPDB]
196 MOV DI,PDB_JFN_Table
197 MOV CX,FilPerProc
198 REPNE SCASB
199 STC
200 JNZ Find_jfn_ret
201 DEC DI
202 CLC
203 Find_jfn_ret:
204 POP CX
205 POP AX
206 return
207 Find_free_jfn ENDP
208
209 BREAK <find_free_sfn - return a free sfn and sf pointer>
210 ;
211 ; find_free_sfn
212 ; input: none
213 ; output: JNC <found>
214 ; ES:DI is free sf entry
215 ; SI is sfn
216 ; JC <not found>
217 ; ES,DI,SI indeterminate
218 ;
219 ; sft_addr --> (link) count (fcbs)
220 ; links = -1 means end of list
221 ;
222 procedure Find_free_sfn,NEAR
223 ASSUME DS:NOTHING,ES:NOTHING
224 PUSH BX
225 PUSH CX
226 LES BX,sft_addr ; head of chain of tables
227 XOR SI,SI ; count of sfn
228
229 ; ES:BX points to table... search through table
230 Find_sfn_in_table:
231 CMP BX,-1 ; end of chain
232 JZ Find_no_free_sfns
233 MOV DI,sft_table ; offset to sf entry
234 MOV CX,ES:[BX].sft_count ; count of fcbs in table
235
236 Find_sfn:
237 CMP ES:BYTE PTR [BX+DI].sf_ref_count,0h
238 JZ Find_got_sfn ; ref count is 0 -> free entry
239 ADD DI,SIZE sf_entry ; look to next entry
240 INC SI ; bump sfn
241 LOOP Find_sfn
242 LES BX,ES:[BX].sft_link ; link to next
243 JMP SHORT Find_sfn_in_table ; look for more
244
245 Find_no_free_sfns:
246 STC
247 JMP SHORT find_ret
248 Find_got_sfn:
249 ADD DI,BX
250 CLC
251 Find_ret:
252 POP CX
253 POP BX
254 RET
255 Find_free_sfn ENDP
256
257 BREAK <$Open - open a file handle>
258 ;
259 ; Assembler usage:
260 ; LDS DX, Name
261 ; MOV AH, Open
262 ; MOV AL, access
263 ; INT int_command
264 ;
265 ; ACCESS Function
266 ; ------ --------
267 ; open_for_read file is opened for reading
268 ; open_for_write file is opened for writing
269 ; open_for_both file is opened for both reading and writing.
270 ;
271 ; Error returns:
272 ; AX = error_invalid_access
273 ; = error_file_not_found
274 ; = error_access_denied
275 ; = error_too_many_open_files
276 ;
277
278 procedure $Open,NEAR
279 ASSUME DS:NOTHING,ES:NOTHING
280 MOV [Cr_read_only],0
281 Open_create:
282 CMP AL,open_for_both ; validate access
283 JBE OPEN_get_jfn
284 error error_invalid_access
285
286 OPEN_get_jfn:
287 MOV [open_name+2],DS
288 context DS
289 MOV open_name,DX
290 MOV open_access,AL
291
292 invoke Find_free_jfn ; scan through user's area
293 ; ES:DI is the jfn entry
294 JNC OPEN_get_sfn
295 OPEN_too_many:
296 error error_too_many_open_files
297
298 OPEN_get_sfn:
299 MOV OPEN_jfn_b,ES
300 MOV OPEN_jfn,DI
301 invoke Find_free_sfn ; get a free sft entry
302 ; ES:DI is the SFT entry that's free, SI is the sfn
303 JC OPEN_too_many
304
305 OPEN_file:
306 MOV OPEN_sfn,SI
307 MOV OPEN_sfoff,DI
308 MOV OPEN_sfn_b,ES
309 ;
310 ; open the file
311 ;
312 PUSH DS
313 LDS DX,DWORD PTR [open_name]
314 ASSUME DS:NOTHING
315 CALL access_path
316 POP DS
317 ASSUME DS:DOSGROUP
318 JNC open_check_access ; carry set -> error
319 transfer SYS_RET_ERR
320
321 open_check_access:
322 MOV ES,WORD PTR [CURBUF+2] ; get buffer location
323 MOV open_devid,AH
324 TEST AH,080h
325 JNZ open_set_FCB_dev ;is a device
326 MOV AL,ES:[BX].dir_attr
327 TEST AL,attr_directory ; can't open directories
328 JZ open_try_volid
329
330 open_bad_access:
331 error error_access_denied
332
333 open_try_volid:
334 TEST AL,attr_volume_id ; can't open volume ids
335 JNZ open_bad_access
336 TEST AL,attr_read_only ; check write on read only
337 JZ open_set_FCB
338 CMP [Cr_read_only],0
339 JNZ open_set_FCB ; ok if creating read only file
340 CMP open_access, open_for_read
341 JNZ open_bad_access ; writing on a read only file
342 JMP SHORT open_set_FCB
343
344 open_set_FCB_dev:
345 PUSH SS
346 POP ES ;Device opens are DOSGROUP relative
347
348 open_set_FCB:
349 MOV CX,11 ; copy name into FCB...
350 PUSH SI ; ES:BX is source, must change
351 MOV SI,BX ; ES:SI is source
352 MOV DI,open_sfoff ; ??:DI is dest
353 PUSH DS
354 PUSH ES
355 MOV ES,open_sfn_b ; ES:DI is dest
356 POP DS ; DS:SI is source
357 ASSUME DS:NOTHING
358 ;
359 ; need to save attribute for the close operation
360 ;
361 MOV AH,DS:[BX.dir_attr] ; save attribute for close
362 MOV ES:[DI.sf_attr],AH
363
364 ADD DI,sf_fcb+1 ; point to name
365
366 IF KANJI
367 MOVSB
368 CMP BYTE PTR ES:[DI-1],5
369 JNZ NOTKTRAN
370 MOV BYTE PTR ES:[DI-1],0E5H
371 NOTKTRAN:
372 DEC CX
373 ENDIF
374
375 REP MOVSB ; move in parsed name
376 POP DS
377 ASSUME DS:DOSGROUP
378 POP SI
379 LES DI,DWORD PTR [open_sfoff]
380 ADD DI,sf_fcb ; offset on fcb in sf entry
381 MOV AH,open_devid
382 invoke DOOPEN ; let open code fill in blanks
383 context DS
384 LES DI,DWORD PTR [open_sfoff]
385 INC ES:[DI].sf_ref_count ; reference this FCB
386 MOV AL,open_access ; stash the access
387 MOV ES:BYTE PTR [DI].sf_mode,AL
388 XOR AX,AX
389 MOV ES:WORD PTR [DI.sf_FCB.fcb_RR],AX ; beginning of file
390 MOV ES:WORD PTR [DI.sf_FCB.fcb_RR+2],AX
391 INC AX
392 MOV ES:WORD PTR [DI.sf_FCB.fcb_RECSIZ],AX ; byte io only
393 LES DI,DWORD PTR [open_jfn]
394 MOV AX,open_sfn
395 MOV ES:BYTE PTR [DI],AL ; stash sfn in PDB
396 SUB DI,PDB_jfn_table ; get jfn for user
397 MOV AX,DI
398 transfer SYS_RET_OK
399 $Open ENDP
400
401
402 BREAK <$UNLINK - delete a file entry>
403 ;
404 ; Assembler usage:
405 ; LDS DX, name
406 ; MOV AH, Unlink
407 ; INT 21h
408 ;
409 ; Error returns:
410 ; AX = error_file_not_found
411 ; = error_access_denied
412 ;
413 procedure $UNLINK,NEAR
414 ASSUME DS:NOTHING,ES:NOTHING
415 CALL access_path
416 JNC unlink_check_attr
417 transfer SYS_RET_ERR
418
419 unlink_check_attr:
420 JZ unlink_dir
421 LDS DI,DWORD PTR [CURBUF] ; get directory entry
422 TEST DS:[BX.dir_attr],attr_read_only
423 JZ unlink_doit
424
425 unlink_dir:
426 error error_access_denied
427
428 unlink_doit:
429 MOV BYTE PTR DS:[BX.dir_name],0E5h ; delete dir entry
430 MOV BYTE PTR DS:[DI.BUFDIRTY],1 ; dirty the buffer
431 LODSW
432 MOV BX,AX
433 AND BX,0FFFh
434 context DS
435 JZ unlink_flush
436 invoke RELEASE
437 unlink_flush:
438 MOV AL,BYTE PTR ES:[BP.DPB_drive]
439 invoke FLUSHBUF
440 transfer SYS_RET_OK
441 $UNLINK ENDP
442
443 BREAK <$CREAT - creat a new file and open him for input>
444 ;
445 ; Assembler usage:
446 ; LDS DX, name
447 ; MOV AH, Creat
448 ; MOV CX, access
449 ; INT 21h
450 ; ; AX now has the handle
451 ;
452 ; Error returns:
453 ; AX = error_access_denied
454 ; = error_path_not_found
455 ; = error_too_many_open_files
456 ;
457
458
459 procedure $CREAT,NEAR
460 ASSUME DS:NOTHING,ES:NOTHING
461 CALL Validate_path
462 JNC unlink_do_make
463 error error_path_not_found
464 unlink_do_make:
465 PUSH DX
466 PUSH DS
467 context DS
468 MOV WORD PTR [CREATING],0E5FFh
469 MOV WORD PTR [ThisFCB+2],SS
470 MOV WORD PTR [ThisFCB],OFFSET DOSGROUP:AUXSTACK-40
471 MOV SI,DX
472 MOV AL,CL
473 AND CL,attr_read_only
474 MOV [Cr_read_only],CL
475 POP DS
476 PUSH DS
477 ASSUME DS:NOTHING
478 invoke MakeNode
479 POP DS
480 POP DX
481 OR AL,AL
482 JZ creat_open
483 CMP AL,3
484 JZ creat_open
485 creat_no_access:
486 error error_access_denied
487 creat_open:
488 MOV AL,open_for_both
489 JMP Open_create
490
491 $CREAT ENDP
492
493
494 BREAK <$DUP - duplicate a jfn>
495 ;
496 ; Assembler usage:
497 ; MOV BX, fh
498 ; MOV AH, Dup
499 ; INT int_command
500 ; AX has the returned handle
501 ; Errors:
502 ; AX = dup_invalid_handle
503 ; = dup_too_many_open_files
504 procedure $DUP,NEAR
505 ASSUME DS:NOTHING,ES:NOTHING
506 context DS
507 invoke Find_free_jfn
508 JC dup_no_free_handles
509
510 dup_force:
511 PUSH ES
512 PUSH DI
513 invoke Get_sf_from_jfn
514 POP SI
515 POP DS
516 JC dup_bad_handle
517 ; ES:DI is pointer to sf entry
518 ; DS:DI is pointer to jfn
519 INC ES:[DI].sf_ref_count ; another jfn reference...
520 MOV AL,[BX].PDB_JFN_table ; get old sfn
521 MOV [SI],AL ; store in new place
522 SUB SI,PDB_JFN_table ; get jfn
523 MOV AX,SI
524 transfer SYS_RET_OK
525
526 dup_no_free_handles:
527 error error_too_many_open_files
528
529 dup_bad_handle:
530 error error_invalid_handle
531 $DUP ENDP
532
533 BREAK <$DUP2 - force a dup on a particular jfn>
534 ;
535 ; Assembler usage:
536 ; MOV BX, fh
537 ; MOV CX, newfh
538 ; MOV AH, Dup2
539 ; INT int_command
540 ; Error returns:
541 ; AX = error_invalid_handle
542 ;
543 procedure $DUP2,NEAR
544 ASSUME DS:NOTHING,ES:NOTHING
545 XCHG BX,CX ; BX < destination jfn
546 PUSH BX
547 PUSH CX
548 invoke $CLOSE ; close BX
549 context DS
550 POP CX
551 POP BX
552 invoke Get_jfn_pointer
553 XCHG BX,CX
554 JNC dup_force
555 lseek_bad_handle:
556 error error_invalid_handle
557 $DUP2 ENDP
558
559
560 BREAK <$CHMOD - change file attributes>
561 ;
562 ; Assembler usage:
563 ; LDS DX, name
564 ; MOV CX, attributes
565 ; INT 21h
566 ; Error returns:
567 ; AX = error_path_not_found
568 ; AX = error_access_denied
569 ;
570 procedure $CHMOD,NEAR
571 ASSUME DS:NOTHING,ES:NOTHING
572 CMP AL,1
573 JBE chmod_save
574 error error_invalid_function
575 chmod_save:
576 JB chmod_try_file
577 MOV BX,CX
578 AND BX,NOT attr_changeable
579 JZ chmod_try_file
580
581 chmod_bad:
582 error error_access_denied
583
584 chmod_bye:
585 transfer SYS_RET_ERR
586 chmod_try_file:
587 PUSH CX
588 PUSH AX
589 CALL access_path
590 POP DX
591 POP CX
592 JC chmod_bye
593 LES DI,[CURBUF]
594 context DS
595 OR DL,DL
596 JZ chmod_fetch
597 AND BYTE PTR ES:[BX].dir_attr,NOT attr_changeable
598 OR BYTE PTR ES:[BX].dir_attr,CL
599 MOV ES:[DI.BUFDIRTY],1
600 MOV AL,-1
601 invoke FlushBuf
602 transfer SYS_RET_OK
603 chmod_fetch:
604 XOR CX,CX
605 MOV CL,BYTE PTR ES:[BX].dir_attr
606 invoke Get_user_stack
607 MOV [SI.user_CX],CX
608 transfer SYS_RET_OK
609 $chmod ENDP
610
611 BREAK <$CURRENT_DIR - dump the current directory into user space>
612 ;
613 ; Assembler usage:
614 ; LDS SI,area
615 ; MOV DL,drive
616 ; INT 21h
617 ; ; DS:SI is a pointer to 64 byte area that contains drive
618 ; ; current directory.
619 ; Error returns:
620 ; AX = error_invalid_drive
621 ;
622 procedure $CURRENT_DIR,NEAR
623 ASSUME DS:NOTHING,ES:NOTHING
624 PUSH DS
625 PUSH BX
626 PUSH SI
627 invoke $get_DPB
628 ;
629 ; ES:BP points to DPB. DS:SI points to user stack, unless error
630 ;
631 CMP AL,0FFh
632 JNZ current_copy
633 POP AX ; Clean Stack
634 POP AX
635 POP AX
636 error error_invalid_drive
637
638 current_copy:
639 POP DI ; where to move to
640 POP [SI.user_BX] ; restore old BX
641 POP BX
642 MOV [SI.user_DS],BX ; and restore old DS
643 ;
644 ; ES:BP is pointer to DPB. BX:DI is pointer to destination
645 ;
646 CMP ES:[BP.dpb_current_dir],-1
647 JNZ current_ok
648 PUSH BX
649 PUSH DI
650 MOV [ATTRIB],attr_all
651 invoke GETCURRDIR
652 POP DI
653 POP BX
654 current_ok:
655 MOV SI,BP ; ES:SI is source
656 PUSH ES
657 POP DS ; DS:SI is source
658 MOV ES,BX ; ES:DI is destination
659 CMP [SI.dpb_current_dir],0
660 JNZ current_move
661 MOV BYTE PTR [SI.dpb_dir_text],0
662
663 current_move:
664 ADD SI,dpb_dir_text
665 MOV CX,DIRSTRLEN
666 current_loop:
667 LODSB
668 STOSB
669 OR AL,AL
670 LOOPNZ current_loop
671 transfer SYS_RET_OK
672 $CURRENT_DIR ENDP
673
674
675 BREAK <$RENAME - move directory entries around>
676 ;
677 ; Assembler usage:
678 ; LDS DX, source
679 ; LES DI, dest
680 ; MOV AH, Rename
681 ; INT 21h
682 ;
683 ; Error returns:
684 ; AX = error_file_not_found
685 ; = error_not_same_device
686 ; = error_access_denied
687 procedure $RENAME,near
688
689 MOV WORD PTR [rename_source],DX
690 MOV WORD PTR [rename_source+2],DS
691 MOV WORD PTR [rename_dest],DI
692 MOV WORD PTR [rename_dest+2],ES
693 CALL Access_path
694 JNC rename_check_dir
695 transfer SYS_RET_ERR
696
697 rename_check_dir:
698 JZ rename_no_access
699 MOV DS,WORD PTR [CurBuf+2]
700 PUSH [BX.dir_date]
701 PUSH [BX.dir_first]
702 PUSH [BX.dir_size_h]
703 PUSH [BX.dir_size_l]
704 PUSH [BX.dir_time]
705 PUSH WORD PTR [BX.dir_attr]
706 PUSH WORD PTR [ThisDrv]
707 LDS SI,[rename_dest]
708 invoke GetPath
709 POP AX
710 JC rename_check_drives
711 rename_bad_access:
712 ADD SP,12
713 rename_no_access:
714 error error_access_denied
715 rename_check_drives:
716 CMP AL,[ThisDrv]
717 JZ rename_create
718 ADD SP,12
719 error error_not_same_device
720 rename_create:
721 LDS SI,[rename_dest]
722 POP AX
723 PUSH AX
724 MOV WORD PTR [Creating],0E5FFh
725 MOV WORD PTR [ThisFCB+2],SS
726 MOV WORD PTR [ThisFCB],OFFSET DOSGROUP:AUXStack-40
727 invoke MakeNode
728 JC rename_bad_access
729 LDS SI,[CurBuf]
730 POP AX
731 MOV [BX.dir_attr],AL
732 POP [BX.dir_time]
733 POP [BX.dir_size_l]
734 POP [BX.dir_size_h]
735 POP [BX.dir_first]
736 POP [BX.dir_date]
737 MOV [SI.BUFDIRTY],1
738 LDS SI,[rename_source]
739 invoke GetPath
740 LDS SI,[CurBuf]
741 MOV BYTE PTR [BX],0E5h
742 MOV [SI.BUFDIRTY],1
743 context DS
744 MOV AL,0FFh
745 invoke FlushBuf
746 transfer SYS_RET_OK
747
748 $RENAME ENDP
749
750 BREAK <$FIND_FIRST - find first matching xenix filename>
751 ;
752 ; Assembler usage:
753 ; MOV AH, FindFirst
754 ; LDS DX, name
755 ; MOV CX, attr
756 ; INT 21h
757 ; ; DMA address has datablock
758 ;
759 ; Error Returns:
760 ; AX = error_file_not_found
761 ; = error_no_more_files
762 ;
763 procedure $FIND_FIRST,near
764 ASSUME DS:NOTHING,ES:NOTHING
765 CALL Validate_path
766 JNC find_get
767 JZ find_get
768 error error_file_not_found
769 find_get:
770 MOV SI,DX
771 PUSH CX
772 INC BYTE PTR [NoSetDir] ; if we find a dir, don't change to it
773 MOV WORD PTR [Creating],0E500h
774 CALL GetPath
775 POP CX
776 MOV [Attrib],CL
777 find_check:
778 JNC find_check_attr
779 find_no_more:
780 error error_no_more_files
781 find_check_attr:
782 MOV DS,WORD PTR [CURBUF+2]
783 MOV CH,[BX.dir_attr]
784 invoke MatchAttributes
785 JZ found_it
786 PUSH [LastEnt]
787 MOV BX,[DirStart]
788 JMP find_it_next
789 found_it:
790 LES DI,[DMAADD]
791 MOV AL,[Attrib]
792 STOSB ; find_buf 0 = attribute in search
793 MOV AL,[ThisDrv]
794 STOSB ; find_buf 1 = drive
795 MOV CX,11
796 PUSH BX
797 MOV SI,OFFSET DOSGROUP:NAME1; find_buf 2 = formatted name
798 PUSH DS
799 PUSH SS
800 POP DS
801
802 IF KANJI
803 MOVSB
804 CMP BYTE PTR ES:[DI-1],5
805 JNZ NOTKANJB
806 MOV BYTE PTR ES:[DI-1],0E5H
807 NOTKANJB:
808 DEC CX
809 ENDIF
810
811 REP MOVSB
812 POP DS
813 MOV AX,[LastEnt]
814 STOSW ; find_buf 13 = LastEnt
815 MOV AX,WORD PTR [ThisDPB]
816 STOSW ; find_buf 15 = ThisDPB
817 MOV AX,WORD PTR [ThisDPB+2]
818 STOSW
819 MOV AX,[DirStart]
820 STOSW ; find_buf 19 = DirStart
821 MOV AL,[BX].dir_attr
822 STOSB ; find_buf 21 = attribute found
823 MOV AX,[BX].dir_time
824 STOSW ; find_buf 22 = time
825 MOV AX,[BX].dir_date
826 STOSW ; find_buf 24 = date
827 MOV AX,[BX].dir_size_l
828 STOSW ; find_buf 26 = low(size)
829 MOV AX,[BX].dir_size_h
830 STOSW ; find_buf 28 = high(size)
831 POP SI
832 MOV CX,8 ; find_buf 30 = packed name
833 find_loop_name:
834 LODSB
835 STOSB
836 CMP AL," "
837 LOOPNZ find_loop_name
838 JNZ find_check_dot
839 DEC DI
840 find_check_dot:
841 ADD SI,CX
842 CMP BYTE PTR [SI]," "
843 JZ find_done
844 MOV AL,"."
845 STOSB
846 MOV CX,3
847 find_loop_ext:
848 LODSB
849 STOSB
850 CMP AL," "
851 LOOPNZ find_loop_ext
852 JNZ find_done
853 DEC DI
854 find_done:
855 XOR AL,AL
856 STOSB
857 transfer SYS_RET_OK
858 $FIND_FIRST ENDP
859
860 BREAK <$FIND_NEXT - scan for match in directory>
861 ;
862 ; Assembler usage:
863 ; ; dma points at area returned by find_first
864 ; MOV AH, findnext
865 ; INT 21h
866 ; ; next entry is at dma
867 ;
868 ; Error Returns:
869 ; AX = error_no_more_files
870 ;
871 procedure $FIND_NEXT,near
872 ASSUME DS:NOTHING,ES:NOTHING
873 LDS SI,[DMAADD]
874 MOV DX,SI
875 INC DX
876 PUSH SI
877 invoke MOVNAMENOSET
878 POP SI
879 JNC find_load
880 findnext_no_more:
881 error error_no_more_files
882 find_load:
883 MOV AX,[SI.find_buf_LastEnt]
884 LES BP,[SI.find_buf_ThisDPB]
885 OR AX,AX
886 JS findnext_no_more
887 MOV BX,[SI.find_buf_DirStart]
888 MOV DL,[SI.find_buf_sattr]
889 MOV [Attrib],DL
890 PUSH AX
891 MOV WORD PTR [ThisDPB],BP
892 MOV WORD PTR [ThisDPB+2],ES
893 find_it_next:
894 invoke SetDirSrch
895 ASSUME DS:DOSGROUP
896 POP AX
897 MOV [ENTLAST],-1
898 invoke GetEnt
899 invoke NextEnt
900 JMP find_check
901 $find_next ENDP
902
903 do_ext
904
905 CODE ENDS
906 END
907