www.pudn.com > czxtsycx1.zip > GFAT16_P.ASM


;////////////////// use by tos task 
TURN_TO_REAL PROC FAR 
            cli 
            MOV AX,REAL_SEL 
            MOV ES,AX 
            MOV FS,AX 
            MOV GS,AX 
            MOV DS,AX 
            MOV SS,AX 
 
            MOV EAX,CR0 
            AND EAX,0FFFFFFFEH 
            MOV CR0,EAX 
            DB 0EAH 
            DW OFFSET REAL_MODE 
            DW CODE 
            RET 
TURN_TO_REAL ENDP 
DISP_TOS_IN_TOS PROC FAR 
            ; DISP 'COS' 
            MOV AH,24H;07 for white/black 
            mov al,43h 
            mov es:320,ax 
            mov al,4fh 
            mov es:322,ax 
            mov al,53h 
            mov es:324,ax 
            RET 
            ; DISP 'COS' 
DISP_TOS_IN_TOS ENDP 
 
GINT21H     PROC FAR 
            cli 
            PUSH BX 
            PUSH CX 
            PUSH DX 
            PUSH SI 
            PUSH ES 
            PUSH DS 
 
            CMP AH,4CH 
            JE  GINT21H_4C 
            CMP AH,9 
            JE  GINT21H_9 
            JNE GINT21H_END 
GINT21H_4C: 
            POP DS 
            POP ES 
            POP SI 
            POP DX 
            POP CX 
            POP BX 
 
            db 0eah 
            dw COMEBACK_TO_TOS 
            dw ps_TO_TOS_SEL 
GINT21H_9:             
            MOV AX,G_VRAM_SEL 
            MOV ES,AX 
            MOV SI,DX 
            MOV DX,CX 
            MOV DH,0 
 
            PUSH DX 
            MOV CL,CH 
            MOV CH,0 
            MOV AX,CX 
            MOV CX,160 
            MUL CX 
            MOV BX,AX 
            POP DX 
 
            ADD BX,DX 
            ADD BX,DX 
            MOV AH,24H;07 for white/black 
LGINT21H1:  MOV AL,DS:[SI] 
            CMP AL,'$' 
            JE GINT21H_END 
            MOV ES:[BX],AX 
            ADD BX,2 
            INC SI 
            LOOP LGINT21H1 
GINT21H_END: 
            POP DS 
            POP ES 
            POP SI 
            POP DX 
            POP CX 
            POP BX 
            IRETD 
GINT21H     ENDP 
 
DISP2_16    PROC FAR 
            ;in al code 2 using ah 
            ;out ah:al:code 16 
            mov ah,al 
            shr ah,4 
            cmp ah,9 
            jle disp2_16_1 
            add ah,7     
disp2_16_1: add ah,30h 
            and al,0fh 
            cmp al,9 
            jle disp2_16_2 
            add al,7 
disp2_16_2: add al,30h 
            RET 
DISP2_16    ENDP 
 
;;;;;;;;;;;; file changed 
DISP_AX     PROC FAR 
            ;in cx:position call inner tos_seg  
            PUSH DS 
            PUSH AX 
            PUSH BX 
            PUSH DX 
 
            MOV DX,V_TOS_DATA_SEL 
            MOV DS,DX 
            MOV BX,AX 
            mov al,BH 
            CALL DISP2_16 
            mov DS:V_DISP_AX,ah 
            mov DS:V_DISP_AX[1],al 
            MOV AL,BL 
            CALL DISP2_16 
            mov DS:V_DISP_AX[2],ah 
            mov DS:V_DISP_AX[3],al 
            mov DS:V_DISP_AX[4],'$' 
            MOV AH,9 
            MOV DX,OFFSET V_DISP_AX 
            INT 21H 
            POP DX 
            POP BX 
            POP AX 
            POP DS 
            RET 
DISP_AX     ENDP 
 
DISP_EXT_AX PROC FAR 
            ;in cx:position call out tos_seg 
            PUSH AX 
            PUSH BX 
            PUSH DX 
            MOV BX,AX 
            mov al,BH 
            db 9ah 
            dw DISP2_16 
            dw TOS_CODE_SEL 
            mov DS:t_string,ah 
            mov DS:t_string[1],al 
            MOV AL,BL 
            db 9ah 
            dw DISP2_16 
            dw TOS_CODE_SEL 
            mov DS:t_string[2],ah 
            mov DS:t_string[3],al 
            mov DS:t_string[4],'$' 
            MOV AH,9 
            MOV DX,OFFSET t_string 
            ;add dx,16 
            INT 21H 
            POP DX 
            POP BX 
            POP AX 
            RET 
DISP_EXT_AX     ENDP 
             
            ;*******************************FILE 
EAX_STR     PROC FAR 
            ;in : eax      ds:dx string_address 
            ;out: ds:dx string_address  use str3 
            ; read cursor 
            PUSH EBX 
            PUSH ECX 
            PUSH EDX 
            PUSH SI 
            PUSH DI 
            PUSH DS 
 
            PUSH DX       ;dest string_address 
            ;EAX-->ds:dx ASCIIZ STRING 
            PUSH EAX      ;remains 
 
            MOV SI,OFFSET STR3 
            MOV DS:[SI+13],0 
            MOV EBX,1000000000 
            PUSH EBX 
DISP_EAX1:  POP EBX  
            POP EAX 
            CMP EBX,10 
            JL  DISP_EAX_END1 
            XOR EDX,EDX 
            DIV EBX 
            PUSH EDX         ;next remains 
DISP_EAX2:  ADD AL,30H 
            MOV DS:[SI],AL 
            INC SI 
            MOV EAX,EBX 
            XOR EDX,EDX 
            MOV ECX,10 
            DIV ECX 
            PUSH EAX         ; next diveder 
            JMP DISP_EAX1 
DISP_EAX_END1: 
            ADD AL,30H 
            MOV DS:[SI],AL 
 
            ;;;;;;; STR3: add ','-->dest address 
            MOV SI,OFFSET STR3 
            POP  DI           ;dest address 
            PUSH DI 
            MOV AL,DS:[SI] 
            MOV DS:[DI],AL 
            INC SI 
            INC DI 
 
            MOV BL,3 
DISP_EAX_END2: 
            MOV AL,"," 
            MOV DS:[DI],AL 
            INC DI 
            CLD 
            MOV CX,3 
DISP_EAX_END3: 
            MOVSB 
            LOOP DISP_EAX_END3 
            DEC BL 
            CMP BL,0 
            JA  DISP_EAX_END2 
            MOV DS:[DI],0 
            ;;;;;;; STR3: add ',' -->dest address 
 
            ;;;;;;; cut first'0' or ',' 
            POP SI                  ;dest address 
            MOV CX,12 
DISP_EAX_END4: 
            MOV AL,DS:[SI] 
            CMP AL,'0' 
            JE  DISP_EAX_END5 
            CMP AL,',' 
            JE  DISP_EAX_END5 
            JMP DISP_EAX_END6 
DISP_EAX_END5: 
            MOV AL,' ' 
            MOV DS:[SI],AL 
            INC SI 
            LOOP DISP_EAX_END4 
DISP_EAX_END6: 
            ;;;;;;;STR2 cut first'0' or ',' 
 
            POP DS 
            POP DI 
            POP SI 
            POP EDX 
            POP ECX 
            POP EBX 
            RET   
EAX_STR     ENDP 
 
STRIPOS     PROC FAR 
            PUSH DS 
            PUSH ES 
            PUSH SI 
            PUSH DI 
            PUSH AX 
            PUSH CX 
            PUSH BP       ;7 
            MOV BP,SP 
            MOV DI,WORD PTR [BP+24]       ; 4 PARAMETER 
            MOV ES,WORD PTR [BP+22]       ; str2 
            MOV SI,WORD PTR [BP+20] 
            MOV DS,WORD PTR [BP+18]       ; str1 
 
            MOV AX,WORD PTR [BP+16] 
            MOV WORD PTR [BP+24],AX        ;CS 
            MOV AX,WORD PTR [BP+14] 
            MOV WORD PTR [BP+22],AX        ;IP 
            MOV AX,WORD PTR [BP] 
            MOV WORD PTR [BP+18],AX        ;OLD BP 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
            PUSH GS 
            PUSH DI 
 
            PUSH DX 
            MOV DX,SI 
            CALL STRLEN         ;get length of str1 
            MOV DX,V_TOS_DATA_SEL 
            MOV GS,DX 
            MOV GS:TTDW1,AX     ;length of str1--->GS:TTDW1   ok 
            POP DX 
            ;find str1 in str2 
            MOV WORD PTR GS:TTDW2,DI 
            ; out loop 
SICMP0:     ;         <----------------------------------------- 
            MOV DI,WORD PTR GS:TTDW2                          ;| 
            MOV AH,ES:[DI] 
            CMP AH,0 
            JE  SICMP_ERROR           ;not found 
            MOV SI,WORD PTR [BP+20] 
            MOV CX,WORD PTR GS:TTDW1  ;length of str1 
            INC CX 
            ; inner loop 
SICMP1:     ;         <----------------------------------------- 
 
            MOV AL,DS:[SI] 
            CMP AL,0 
            JE SICMP_OK 
            MOV AH,ES:[DI] 
            CMP AH,0 
            JE SICMP_ERROR 
            ; upper/lower 
            CMP AL,61H 
            JL  SICMP11 
            CMP AL,7AH 
            JA  SICMP11 
            SUB AL,20H 
SICMP11:   
            CMP AH,61H 
            JL  SICMP12 
            CMP AH,7AH 
            JA  SICMP12 
            SUB AH,20H 
            ; upper/lower 
SICMP12:    ;  
            CMP AL,AH    ;al=str1       ah=str2 
            JE  SICMP2 
            JMP  SICMP22 ;to next position in str2 
SICMP2: 
            INC SI 
            INC DI 
            LOOP SICMP1 
SICMP22:    INC WORD PTR GS:TTDW2 
            JMP SICMP0 
SICMP_OK:                 ;end  have found 
            MOV AX,WORD PTR GS:TTDW2 
            POP DI 
            SUB AX,DI   ;str1'offset in str2 
            JMP SICMP_END 
            ;;;;;;;;;;; 
SICMP_ERROR: 
            MOV AX,65535 
            POP DI 
SICMP_END: 
            POP GS 
SICMP3:     ;MOV WORD PTR [BP+4],AX        ;OLD BP 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
            POP CX       ;OLD BP 
            POP CX 
            POP DI       ;AX = position of return 
            POP DI 
            POP SI 
            POP ES 
            POP DS 
             
            MOV SP,BP 
            MOV BP,WORD PTR [BP+4]        ;OLD BP  -7*2 of above 
            ADD SP,22 
            RET 
STRIPOS     ENDP 
 
STRLEN PROC FAR 
       ;in : ds:dx addr of string 
       PUSH DI 
       PUSH ES 
       PUSH CX 
       MOV DI,DX 
       MOV CX,DS 
       MOV ES,CX 
       MOV AL,0 
       MOV CX,0FFFFH 
       REPNE SCASB 
       MOV AX,DI 
       SUB AX,DX 
       DEC AX 
       POP CX 
       POP ES 
       POP DI 
       RET 
STRLEN ENDP 
 
DISP_COS_HEAD PROC FAR 
            MOV AX,G_VRAM_SEL 
            MOV ES,AX 
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX 
 
            MOV AH,7H       ;COVER OLD "COS" 
            MOV AL,20H 
            MOV ES:320,AX 
            MOV ES:322,AX 
            MOV ES:324,AX 
 
            MOV CX,21 
            MOV AH,24H 
            MOV DI,0 
            MOV AL,20H 
DISP_COS_HEAD0:             
            MOV ES:[DI],AX 
            INC DI 
            INC DI 
            LOOP DISP_COS_HEAD0 
 
            MOV SI,OFFSET COS_HEAD 
            MOV CX,37 
DISP_COS_HEAD1:             
            MOV AL,DS:[SI] 
            MOV ES:[DI],AX 
            INC DI 
            INC DI 
            INC SI 
            LOOP DISP_COS_HEAD1 
 
            MOV CX,22 
            MOV AL,20H 
DISP_COS_HEAD2:             
            MOV ES:[DI],AX 
            INC DI 
            INC DI 
            LOOP DISP_COS_HEAD2 
            ; setup cursor 
            MOV BH,0 
            MOV DX,0000H 
            MOV AH,2 
            INT 80H 
            ;; begin command line mode 
            ;;;;;;            display "C:\>" 
            ; read cursor 
            MOV AH,03H  
            MOV BH,0 
            INT 80H 
            ; set cursor 
            MOV AH,02H  
            MOV BH,0 
            INC DH 
            MOV DL,0 
            INT 80H 
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX 
            MOV DX,OFFSET COS_FLAG 
            CALL STRDISP           ;display "C:\>" 
            ;;;;;;;;;;;;;;;;set "C:\" as current directory 
            RET 
DISP_COS_HEAD ENDP 
 
STRNCPY     PROC FAR 
            PUSH DS 
            PUSH ES 
            PUSH SI 
            PUSH DI 
            PUSH AX 
            PUSH CX 
            PUSH BP       ;7 
            MOV BP,SP 
            MOV DI,WORD PTR [BP+26]       ;5 PARAMETER 
            MOV ES,WORD PTR [BP+24] 
            MOV SI,WORD PTR [BP+22] 
            MOV DS,WORD PTR [BP+20] 
            MOV CX,WORD PTR [BP+18] 
 
            MOV AX,WORD PTR [BP+16] 
            MOV WORD PTR [BP+26],AX        ;CS 
            MOV AX,WORD PTR [BP+14] 
            MOV WORD PTR [BP+24],AX        ;IP 
            MOV AX,WORD PTR [BP] 
            MOV WORD PTR [BP+22],AX        ;OLD BP 
 
            ;str1-->str2 
STRNCPY1: 
            MOV AL,DS:[SI] 
            MOV ES:[DI],AL 
            INC SI 
            INC DI 
            LOOP STRNCPY1 
 
            POP CX       ;OLD BP 
            POP CX 
            POP AX 
            POP DI 
            POP SI 
            POP ES 
            POP DS 
             
            MOV SP,BP 
            MOV BP,WORD PTR [BP+22]        ;OLD BP 
            ADD SP,24 
            RET 
STRNCPY     ENDP 
 
STRDISP     PROC FAR 
            ;    input ds:dx  string address   0-->'$' 
            PUSH ES 
            PUSH AX 
            PUSH BX 
            PUSH CX 
            PUSH DI 
            PUSH DS 
 
; 
            MOV AX,DS 
            MOV ES,AX 
            MOV DI,DX 
 
STRDISP0:   MOV AL,0 
            MOV DX,DI 
            MOV CX,4096 
            CLD 
STRDISP1:   SCASB 
            LOOPNZ STRDISP1 
            JNZ STRDISP2      ;<>0 AT 4095 
            MOV AL,0 
            ;dec di 
            JMP STRDISP3 
STRDISP2:             
            MOV AL,ES:[DI] 
STRDISP3:    
            PUSH AX 
            PUSH DI 
            PUSH ES 
            PUSH DS 
            MOV AL,24H 
            MOV ES:[DI],AL 
            MOV AL,0 
            MOV AH,09H 
            INT 21H 
            POP DS 
            POP ES 
            POP DI 
            POP AX 
            CMP AL,0 
            JE  STRDISP_END 
            MOV ES:[DI],AL 
            JMP STRDISP0 
 
STRDISP_END: 
            POP DS 
            POP DI 
            POP CX 
            POP BX 
            POP AX 
            POP ES 
            RET 
STRDISP     ENDP 
 
STRCPY      PROC FAR 
            PUSH DS 
            PUSH ES 
            PUSH SI 
            PUSH DI 
            PUSH AX 
            PUSH CX 
            PUSH BP       ;7 
            MOV BP,SP 
            MOV DI,WORD PTR [BP+24]       ;4 PARAMETER 
            MOV ES,WORD PTR [BP+22] 
            MOV SI,WORD PTR [BP+20] 
            MOV DS,WORD PTR [BP+18] 
 
            MOV AX,WORD PTR [BP+16] 
            MOV WORD PTR [BP+24],AX        ;CS 
            MOV AX,WORD PTR [BP+14] 
            MOV WORD PTR [BP+22],AX        ;IP 
            MOV AX,WORD PTR [BP] 
            MOV WORD PTR [BP+20],AX        ;OLD BP 
 
            ;str1-->str2 
            MOV CX,0FFFFH 
STRCPY1: 
            MOV AL,DS:[SI] 
            MOV ES:[DI],AL 
            CMP AL,0 
            JLE STRCPY2 
            INC SI 
            INC DI 
            LOOP STRCPY1 
STRCPY2: 
 
            POP CX       ;OLD BP 
            POP CX 
            POP AX 
            POP DI 
            POP SI 
            POP ES 
            POP DS 
             
            MOV SP,BP 
            MOV BP,WORD PTR [BP+20]        ;OLD BP 
            ADD SP,22 
            RET 
STRCPY      ENDP 
             
STRCMP      PROC FAR 
            PUSH DS 
            PUSH ES 
            PUSH SI 
            PUSH DI 
            PUSH AX 
            PUSH CX 
            PUSH BP       ;7 
            MOV BP,SP 
            MOV DI,WORD PTR [BP+24]       ;4 PARAMETER 
            MOV ES,WORD PTR [BP+22] 
            MOV SI,WORD PTR [BP+20] 
            MOV DS,WORD PTR [BP+18] 
 
            MOV AX,WORD PTR [BP+16] 
            MOV WORD PTR [BP+24],AX        ;CS 
            MOV AX,WORD PTR [BP+14] 
            MOV WORD PTR [BP+22],AX        ;IP 
            MOV AX,WORD PTR [BP] 
            MOV WORD PTR [BP+20],AX        ;OLD BP 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
            ;str1-->str2 
            MOV CX,0FFFFH 
STRCMP1: 
            MOV AL,DS:[SI] 
            MOV AH,ES:[DI] 
            CMP AL,AH 
            JE  STRCMP2 
            JL  STRCMP22 
            MOV AL,2 
            JMP STRCMP3 
STRCMP2: 
            CMP AL,0 
            JE  STRCMP3 
            INC SI 
            INC DI 
            LOOP STRCMP1 
STRCMP22:   MOV AL,1 
STRCMP3:    MOV WORD PTR [BP+4],AX        ;OLD BP 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
            POP CX       ;OLD BP 
            POP CX 
            POP AX 
            POP DI 
            POP SI 
            POP ES 
            POP DS 
             
            MOV SP,BP 
            MOV BP,WORD PTR [BP+20]        ;OLD BP 
            ADD SP,22 
            RET 
STRCMP      ENDP 
 
STRICMP     PROC FAR 
            PUSH DS 
            PUSH ES 
            PUSH SI 
            PUSH DI 
            PUSH AX 
            PUSH CX 
            PUSH BP       ;7 
            MOV BP,SP 
            MOV DI,WORD PTR [BP+24]       ;4 PARAMETER 
            MOV ES,WORD PTR [BP+22] 
            MOV SI,WORD PTR [BP+20] 
            MOV DS,WORD PTR [BP+18] 
 
            MOV AX,WORD PTR [BP+16] 
            MOV WORD PTR [BP+24],AX        ;CS 
            MOV AX,WORD PTR [BP+14] 
            MOV WORD PTR [BP+22],AX        ;IP 
            MOV AX,WORD PTR [BP] 
            MOV WORD PTR [BP+20],AX        ;OLD BP 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
            ;str1-->str2 
            MOV CX,0FFFFH 
STRICMP1: 
            MOV AL,DS:[SI] 
            MOV AH,ES:[DI] 
            ; upper/lower 
            CMP AL,61H 
            JL  STRICMP11 
            CMP AL,7AH 
            JA  STRICMP11 
            SUB AL,20H 
STRICMP11:   
            CMP AH,61H 
            JL  STRICMP12 
            CMP AH,7AH 
            JA  STRICMP12 
            SUB AH,20H 
            ; upper/lower 
STRICMP12:   
            CMP AL,AH 
            JE  STRICMP2 
            JL  STRICMP22 
            MOV AL,2 
            JMP STRICMP3 
STRICMP2: 
            CMP AL,0 
            JE  STRICMP3 
            INC SI 
            INC DI 
            LOOP STRICMP1 
STRICMP22:  MOV AL,1 
STRICMP3:   MOV WORD PTR [BP+4],AX        ;OLD BP 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
            POP CX       ;OLD BP 
            POP CX 
            POP AX 
            POP DI 
            POP SI 
            POP ES 
            POP DS 
             
            MOV SP,BP 
            MOV BP,WORD PTR [BP+20]        ;OLD BP 
            ADD SP,22 
            RET 
STRICMP     ENDP 
 
LSECTOR_NO_ADDR PROC FAR 
            ; in: DS:DX=DOSBOOT or extdosboot EAX=logic sector_no 
            ; out ch:cylinder,cl:sector,dh:head 
 
            PUSH EBX 
            PUSH ESI 
            PUSH EDI 
 
            INC EAX 
            MOV SI,DX              ;OFFSET DOSBOOT 
 
            MOV EBX,DS:[SI+1CH]    ;hidden sector_count 
            ADD EAX,EBX 
            MOV EBX,DS:HIDDEN_SECTOR 
            ADD EAX,EBX 
            PUSH EAX               ;logic sector_no+1+hidden sector_count 
            MOV AX,DS:[SI+1AH]     ;head_count_per cylinder 
            MOV BX,DS:[SI+18H]     ;sector_count per head 
            XOR DX,DX 
            MUL BX                 ;DX:AX head_count * sector_count 
            MOVZX EAX,AX 
            MOVZX EDX,DX 
            SHL   EDX,16 
            ADD   EAX,EDX          ;EAX=head_count * sector_count 
            MOV   EDI,EAX          ;EDI=head_count * sector_count ---OK 
            POP   EAX 
            PUSH  EAX 
            XOR   EDX,EDX 
            DIV   EDI              ;EAX=cylinder_NO 
            MOV   EBX,EAX          ;EBX=cylinder_NO -----OK 
            XOR   EDX,EDX 
            MUL   EDI                
            MOV   ECX,EAX          ;ECX=cylinder_NO * head_count * sector_count 
            POP   EAX               
            SUB   EAX,ECX    
            PUSH  EAX              ;logic sector_no+1+hidden sector_count - 
                                   ; cylinder_NO * head_count * sector_count 
            MOV CX,DS:[SI+18H]    ;sectors per sector 
            MOVZX ECX,CX 
            XOR EDX,EDX 
            DIV ECX                 
            MOV ESI,EAX            ;ESI=EAX=head_ON   ----OK 
            XOR EDX,EDX 
            MUL ECX 
            MOV EDI,EAX            ;EDI=head_ON * sectorS per head 
            POP EAX 
            SUB EAX,EDI            ;AX=sector_ON  --OK 
            MOV CL,AL              ;CL=sector_ON  --OK 
            MOV DX,SI              ;DL=head_ON 
            MOV DH,DL              ;DH=head_ON 
            MOV CH,BL              ;CH=low 8 bit cylinder 
            SHL BH,6 
            AND CL,3FH 
            ADD CL,BH 
 
            POP EDI 
            POP ESI 
            POP EBX 
            RET 
LSECTOR_NO_ADDR ENDP 
 
DO_DIR      PROC FAR 
            MOV AX,V_TOS_DATA_SEL 
            MOV ES,AX 
            MOV DS,AX 
            ;;;;; next for FAT16 file system 
             
            MOV EAX,0 
            MOV DS:HIDDEN_SECTOR,EAX 
            MOV DS:TTDB,AL  ;subs directory 
            MOV DS:TTDD1,EAX ;used bytes 
            MOV DS:TTDD2,EAX ;free bytes 
            MOV DS:TTDD3,EAX ;files_count 
            MOV DS:TTDD4,EAX ;directory_count 
            ;;;;; disk free bytes 
            MOV BX,OFFSET DOSBOOT 
            XOR EAX,EAX           
            MOV  EAX,DS:[BX+20H] 
            CMP  EAX,0 
            JA   DO_DIR00 
            MOV  AX,DS:[BX+13H] 
DO_DIR00:   DEC  EAX                   ;toatl sectors -1 
            MOV  DX,DS:[BX+16H]       ;sectors per FAT 
            MOVZX EDX,DX 
            SUB  EAX,EDX 
            SUB  EAX,EDX 
            MOV  DS:TTDD2,EAX           ;toatl sectors - 1 -2*FAT_sectors  
            ;;;;; disk free bytes 
 
            ;;;;;;;;;;;;;;;;;;;; display head line 1 
            ; read cursor 
            MOV AH,03H  
            MOV BH,0 
            INT 80H 
            ; set cursor 
            MOV AH,02H  
            MOV BH,0 
            INC DH 
            MOV DL,0 
            INT 80H 
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX 
            MOV DX,OFFSET T_DIR1 
            CALL STRDISP 
            ;;;;;;;;;;;;;;;; display volume_serial_number 
            ;display  volume_serial_number part 1 
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX 
            MOV BX,OFFSET DOSBOOT 
            ADD BX,27H 
            MOV AL,DS:[BX+2] 
            MOV AH,DS:[BX+3] 
            CALL DISP_AX 
 
            ;display '-' 
            MOV BH,0 
            MOV AL,'-' 
            MOV BL,07 
            MOV CX,1 
            MOV AH,9 
            INT 80H 
            ; read cursor 
            MOV AH,03H  
            MOV BH,0 
            INT 80H 
            ; set cursor 
            MOV AH,02H  
            MOV BH,0 
            INC DL 
            INT 80H 
            ;display volume_serial_number part 2 
            MOV BX,OFFSET DOSBOOT 
            ADD BX,27H 
            MOV AL,DS:[BX] 
            MOV AH,DS:[BX+1] 
            CALL DISP_AX 
            ;;;;;;;;;;; display volume_serial_number 
            ;display head line 2 
            ; read cursor 
            MOV AH,03H  
            MOV BH,0 
            INT 80H 
            ; set cursor 
            MOV AH,02H  
            MOV BH,0 
            INC DH 
            MOV DL,0 
            INT 80H 
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX 
            MOV DX,OFFSET T_DIR2 
            CALL STRDISP 
            ;;;;;;;;;;;;;;;; 
            ;;;;;;;;;;;;;;;;;;; first sector_no of root dir 
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX 
            MOV AL,0 
            MOVZX EAX,AL 
            MOV DS:HIDDEN_SECTOR,EAX 
            MOV BX,OFFSET DOSBOOT 
            MOV AX,DS:[BX+16H] ;sectors per FAT 
            MOV CX,DS:[BX+10H] ;FAT count 
            MUL CX 
            INC AX               
            ADC DX,0            ;DX:AX =first sector_no of root dir 
            MOVZX ECX,AX 
            MOVZX EAX,DX 
            SHL EAX,16 
            ADD EAX,ECX 
            MOV DS:ROOTDIR_FS_NO,EAX  ; first sector_no of root dir 
            ;;;;;;;;;;;;;;;;;;; sectors in root dir 
            MOV AX,DS:[BX+11H] 
            MOV CX,32 
            MUL CX              ;DX:AX bytes in root dir 
            MOV CX,DS:[BX+0BH]  ; bytes oer sector 
            DIV CX              ;AX= sectors in root dir 
            ;;;;;;;;;;;;;;;;;;;         last sector_no of root dir 
            MOVZX EAX,AX              ; EAX= sectors in root dir 
            ;; disk free 
            PUSH  EAX 
            MOV   EBX,EAX 
            MOV   EAX,DS:TTDD2 
            SUB   EAX,EBX 
 
            MOV   DS:TTDD2,EAX        ;sectors in file area 
            MOV   DX,OFFSET DOSBOOT 
            CALL  DISK_FREE 
            MOV   DS:TTDD2,EAX        ;disk free 
            POP   EAX 
            ;; disk free 
 
            MOV EBX,DS:ROOTDIR_FS_NO  ; EBX= first sector_no of root dir 
            ADD EAX,EBX 
            DEC EAX 
            MOV DS:ROOTDIR_LS_NO,EAX  ; last sector_no of root dir 
            ;;;;;;;;;;;;;;;;;;   loop read root_dir sector 
            MOV EAX,DS:ROOTDIR_FS_NO   
            MOV DS:TTSECTOR_NO,EAX    ; first sector_no of root dir 
DO_DIR_1:    
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX 
            MOV EAX,DS:TTSECTOR_NO 
            CMP EAX,DS:ROOTDIR_LS_NO   
            JA  DO_DIR_END 
            INC EAX 
            MOV DS:TTSECTOR_NO,EAX 
            DEC EAX 
            MOV DX,OFFSET DOSBOOT 
            CALL DISPDIR_ONE_SECTOR 
            JMP DO_DIR_1 
DO_DIR_END:  
            ;;;;;;;;;;;display last 2 lines 
            MOV EAX,DS:TTDD3        ;files count 
            MOV DX,OFFSET STR1 
            CALL EAX_STR    ;eax ->str1 
            MOV DI,OFFSET STR1 
            MOV AL,' ' 
            MOV DS:[DI+13],AL 
            MOV AL,'f' 
            MOV DS:[DI+14],AL 
            MOV AL,'i' 
            MOV DS:[DI+15],AL 
            MOV AL,'l' 
            MOV DS:[DI+16],AL 
            MOV AL,'e' 
            MOV DS:[DI+17],AL 
            MOV AL,'(' 
            MOV DS:[DI+18],AL 
            MOV AL,'s' 
            MOV DS:[DI+19],AL 
            MOV AL,')' 
            MOV DS:[DI+20],AL 
 
            MOV EAX,DS:TTDD1      ;used byts 
            MOV DX,OFFSET STR2 
            CALL EAX_STR    ;eax ->str2 
            MOV SI,OFFSET STR2 
            MOV DI,OFFSET STR1 
            ADD DI,21 
            MOV CX,13 
            REP MOVSB 
             
            MOV AL,' ' 
            MOV DS:[DI],AL 
            MOV AL,'b' 
            MOV DS:[DI+1],AL 
            MOV AL,'y' 
            MOV DS:[DI+2],AL 
            MOV AL,'t' 
            MOV DS:[DI+3],AL 
            MOV AL,'e' 
            MOV DS:[DI+4],AL 
            MOV AL,'s' 
            MOV DS:[DI+5],AL 
            MOV DS:[DI+6],0 
            ; read cursor 
            MOV AH,03H  
            MOV BH,0 
            INT 80H 
            ; set cursor 
            MOV AH,02H  
            MOV BH,0 
            INC DH      ;line 
            MOV DL,0    ;column 
            INT 80H 
            MOV DX,OFFSET STR1 
            CALL STRDISP            ;display last 2 line 
 
            MOV EAX,DS:TTDD4        ;directory count 
            MOV DX,OFFSET STR1 
            CALL EAX_STR    ;eax ->str1 
 
            MOV DI,OFFSET STR1 
            MOV AL,' ' 
            MOV DS:[DI+13],AL 
            MOV AL,'d' 
            MOV DS:[DI+14],AL 
            MOV AL,'i' 
            MOV DS:[DI+15],AL 
            MOV AL,'r' 
            MOV DS:[DI+16],AL 
            MOV AL,'(' 
            MOV DS:[DI+17],AL 
            MOV AL,'s' 
            MOV DS:[DI+18],AL 
            MOV AL,')' 
            MOV DS:[DI+19],AL 
            MOV AL,' ' 
            MOV DS:[DI+20],AL 
 
            MOV EAX,DS:TTDD2      ;used byts 
            MOV DX,OFFSET STR2 
            CALL EAX_STR    ;eax ->str2 
            MOV SI,OFFSET STR2 
            MOV DI,OFFSET STR1 
            ADD DI,21 
            MOV CX,13 
            REP MOVSB 
             
            MOV AL,' ' 
            MOV DS:[DI],AL 
            MOV AL,'f' 
            MOV DS:[DI+1],AL 
            MOV AL,'r' 
            MOV DS:[DI+2],AL 
            MOV AL,'e' 
            MOV DS:[DI+3],AL 
            MOV AL,'e' 
            MOV DS:[DI+4],AL 
            MOV DS:[DI+5],0 
 
            ; read cursor 
            MOV AH,03H  
            MOV BH,0 
            INT 80H 
            ; set cursor 
            MOV AH,02H  
            MOV BH,0 
            INC DH      ;line 
            MOV DL,0    ;column 
            INT 80H 
            MOV DX,OFFSET STR1 
            CALL STRDISP 
            RET 
DO_DIR      ENDP 
 
DISPDIR_ONE_SECTOR PROC FAR 
            ; in: DS:DX=DOSBOOT or extdosboot EAX=logic sector_no 
            ;;;;;;;;;;;;;;;;;;;;;; read ONE sector to DS:TTSECOR 
 
            CALL LSECTOR_NO_ADDR  ;in: DS:DOSBOOT EAX=logic sector_no 
                                  ; out ch:cylinder,cl:sector,dh:head 
            ;MOV CH,0       ;cylinder 
            ;MOV CL,10      ;sector 
            ;MOV DH,9       ;head 
            MOV AX,V_TOS_DATA_SEL 
            MOV ES,AX 
            MOV DS,AX 
            MOV BX,OFFSET TTSECTOR 
            MOV AH,2 
            MOV AL,1 
            MOV DL,80H     ;driver: hard disk 1 
            INT 83H        ;=bios 13h 
            ;;;;;;;;;;;;;;;;;;;;; display dir in one sector 
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX 
            MOV BX,OFFSET TTSECTOR 
 
            MOV CX,16    ;16 directories per sector,begin to display 
DISPDIR_ONE_SECTOR1: 
            ;;;;;;;;;;;;; ds:bx is directory item 
            ;;;;;;;;;;;;; at first put string into str1,and display 
            PUSH CX 
            PUSH BX 
            MOV AH,DS:[BX] 
            CMP AH,0E5H 
            JE DISPDIR_ONE_SECTOR2 
            CMP AH,0 
            JNE DISPDIR_ONE_SECTOR4 
            POP BX 
            POP CX 
            JMP DISPDIR_ONE_SECTOR3 
DISPDIR_ONE_SECTOR4: 
            MOV AH,DS:[BX+11]   ; 
            AND AH,04H          ;system file 
            CMP AH,04H 
            JE DISPDIR_ONE_SECTOR2 
;; 
            MOV AH,DS:[BX+11]   ; 
            AND AH,02H          ;hidden file 
            CMP AH,02H 
            JE DISPDIR_ONE_SECTOR2 
 
            MOV AH,DS:[BX+11]   ; 
            AND AH,08H          ;10G_C 
            CMP AH,08H 
            JE DISPDIR_ONE_SECTOR2 
 
            ;8 chars_name->STR1 
            MOV AX,OFFSET STR1 
            PUSH AX 
            PUSH DS 
            PUSH BX 
            PUSH DS 
            MOV AX,8 
            PUSH AX 
            CALL STRNCPY 
 
            POP  BX 
            PUSH BX 
            MOV  DI,OFFSET STR1 
            MOV DS:[DI+44],0 
            MOV AL,' ' 
            MOV DS:[DI+8],AL 
 
            ADD DI,9 
            MOV SI,BX 
            ADD SI,8 
            MOV CX,3     ;exe name is moved to str1 DS:SI->ES:DI 
DISPDIR_ONE_SECTOR5: 
            MOVSB 
            LOOP DISPDIR_ONE_SECTOR5 
 
            MOV AH,DS:[BX+11]   ; 
            AND AH,10H          ;subs directory 
            CMP AH,10H 
            JNE DISPDIR_ONE_SECTOR55 
            MOV DI,OFFSET STR1 
            MOV AL,'<' 
            MOV ES:[DI+13],AL 
            MOV AL,'D' 
            MOV ES:[DI+14],AL 
            MOV AL,'I' 
            MOV ES:[DI+15],AL 
            MOV AL,'R' 
            MOV ES:[DI+16],AL 
            MOV AL,'>' 
            MOV ES:[DI+17],AL 
            ADD DI,18 
            MOV CX,9 
            MOV AL,' ' 
            REP STOSB 
            MOV EAX,DS:TTDD4      ;directory_count + 1 
            INC EAX 
            MOV DS:TTDD4,EAX 
            JMP DISPDIR_ONE_SECTOR7 
 
DISPDIR_ONE_SECTOR55: 
            MOV EAX,DS:[BX+1CH]  ;eax=file_size 
            MOV DX,OFFSET STR2 
            PUSH EAX 
            MOV  ESI,DS:TTDD1 
            ADD  EAX,ESI 
            MOV  DS:TTDD1,EAX 
            POP  EAX 
            PUSH EAX 
            MOV EAX,DS:TTDD3   ;file_count + 1 
            INC EAX 
            MOV DS:TTDD3,EAX 
            POP  EAX 
            CALL EAX_STR    ;eax ->str2 
 
            MOV SI,OFFSET STR2 
            MOV DI,OFFSET STR1 
            ADD DI,12 
            MOV AL,' ' 
            MOV ES:[DI],AL 
            INC DI 
            CLD 
            MOV CX,13     ; DS:SI->ES:DI 
DISPDIR_ONE_SECTOR6: 
            MOVSB 
            LOOP DISPDIR_ONE_SECTOR6 
 
DISPDIR_ONE_SECTOR7: 
            ;;;;;;;;;;;;year_month_day 
            MOV SI,OFFSET STR1 
            POP  BX 
            PUSH BX 
            MOV CX,DS:[BX+18H]   ;AX=date 
            MOV AL,CH 
            SHR AL,1 
            MOV AH,0 
            ADD AX,1980 
            XOR DX,DX 
            MOV BX,1000 
            DIV BX 
            ADD AL,30H 
 
            MOV DS:[SI+27],AL 
            MOV AL,' ' 
            MOV DS:[SI+26],AL 
            MOV AX,DX 
            XOR DX,DX 
            MOV BX,100 
            DIV BX 
            ADD AL,30H 
            MOV DS:[SI+28],AL 
            MOV AX,DX 
            XOR DX,DX 
            MOV BX,10 
            DIV BX 
            ADD AL,30H 
            MOV DS:[SI+29],AL 
            ADD DL,30H 
            MOV DS:[SI+30],DL 
            MOV AL,'-' 
            MOV DS:[SI+31],AL 
;;          ;;;;;;;;;;;;;;;;;;; month 
            MOV AX,CX 
            SHR AX,5 
            AND AL,0FH 
            MOV AH,0 
            XOR DX,DX 
            MOV BX,10 
            DIV BX 
            ADD AL,30H 
            MOV DS:[SI+32],AL 
            ADD DL,30H 
            MOV DS:[SI+33],DL 
            MOV AL,'-' 
            MOV DS:[SI+34],AL 
;;          ;;;;;;;;;;;;;;;;;;; day 
            MOV AL,CL 
            AND AL,1FH 
            MOV AH,0 
            XOR DX,DX 
            MOV BX,10 
            DIV BX 
            ADD AL,30H 
            MOV DS:[SI+35],AL 
            ADD DL,30H 
            MOV DS:[SI+36],DL 
            MOV AL,' ' 
            MOV DS:[SI+37],AL 
            MOV DS:[SI+38],AL 
            ;;;;;;;;;;;;;; hour minute second 
            POP  BX 
            PUSH BX 
            MOV CX,DS:[BX+16H]   ;AX=time 
 
            MOV AL,CH            ;hour 
            SHR AL,3 
            MOV AH,0 
            XOR DX,DX 
            MOV BX,10 
            DIV BX 
            ADD AL,30H 
            MOV DS:[SI+39],AL 
            ADD DL,30H 
            MOV DS:[SI+40],DL 
            MOV AL,':' 
            MOV DS:[SI+41],AL 
;;          ;;;;;;;;;;;;;;;;;;; minute 
            MOV AX,CX 
            SHR AX,5 
            AND AL,3FH 
            MOV AH,0 
            XOR DX,DX 
            MOV BX,10 
            DIV BX 
            ADD AL,30H 
            MOV DS:[SI+42],AL 
            ADD DL,30H 
            MOV DS:[SI+43],DL 
             
            ; read cursor 
            MOV AH,03H  
            MOV BH,0 
            INT 80H 
            ; set cursor 
            MOV AH,02H  
            MOV BH,0 
            INC DH      ;line 
            MOV DL,0    ;column 
            INT 80H 
            MOV DX,OFFSET STR1 
            CALL STRDISP      ;display name 
 
DISPDIR_ONE_SECTOR2:       
            POP BX 
            POP CX 
            ADD BX,32  
            DEC CX 
            CMP CX,1 
            JE DISPDIR_ONE_SECTOR3 
            JMP DISPDIR_ONE_SECTOR1 
DISPDIR_ONE_SECTOR3:       
            RET 
DISPDIR_ONE_SECTOR ENDP 
 
DISK_FREE  PROC FAR 
           ; in: ds:dx is address of DOSBOOT  ttdd2=sectors in file area 
           ; out eax = free bytes 
           PUSH EBX 
           PUSH ECX 
           PUSH EDX 
           PUSH DI 
           PUSH SI 
           PUSH ES 
           PUSH DS 
 
           ; count end_cluster_NO 
           MOV BX,DX             ; ds:dx is address of DOSBOOT 
           MOV DS:TTDW3,DX 
           MOV EAX,DS:TTDD2      ;sectors in file area 
           MOV CL,DS:[BX+0DH]    ;sectors per cluster 
           MOVZX ECX,CL 
           XOR EDX,EDX 
           DIV ECX               ;ax=clusters in file area 
           MOV DS:TTDW2,AX       ;TTDW2=clusters in file area 
           MOV AX,0               
           MOV DS:TTDW3,AX       ;TTDW3=begin_cluster_NO in file area 
 
           MOV SI,0      ; DI=free cluster 
           MOV EAX,0     ; EAX=logic sector_no -1 :first in FAT  
           MOV CX,DS:[BX+16H]  
           MOV DS:TTDW1,CX    ;TTDW1=sectors per FAT end_condition 
DISK_FREE1: 
           INC EAX       ; logic sector 
           CMP AX,DS:TTDW1 
           JA  DISK_FREE_END 
           PUSH EAX 
           MOV  DX,DS:OFFSET DOSBOOT ;TTDW3 
           CALL LSECTOR_NO_ADDR  ;in: DS:DX=DOSBOOT EAX=logic sector_no 
                                 ; out ch:cylinder,cl:sector,dh:head 
 
           ;MOV CH,0       ;cylinder 
           ;MOV CL,10       ;sector 
           ;MOV DH,9       ;head 
           MOV AX,V_TOS_DATA_SEL 
           MOV ES,AX 
           MOV DS,AX 
           MOV BX,OFFSET TTSECTOR 
           MOV AH,2 
           MOV AL,1 
           MOV DL,80H     ;driver: hard disk 1 
           INT 83H        ;=bios 13h 
 
           ; cluster_NOs per sector 
           MOV BX,OFFSET DOSBOOT 
           XOR DX,DX 
           MOV AX,DS:[BX+0BH] ;bytes per sector  =512 
           MOV CX,2 
           DIV CX   ;AX= cluster_NOs per sector =256 
           MOV CX,AX      
           MOV BX,DS:TTDW3  ;begin_cluster 
           MOV DX,DS:TTDW2  ;end_cluster 
           MOV DI,OFFSET TTSECTOR 
DISK_FREE2:            
           MOV AX,DS:[DI] 
           CMP AX,0H 
           JA  DISK_FREE22 
           INC SI 
DISK_FREE22: 
           CMP BX,DX 
           JA  DISK_FREE_END0 
           INC BX 
           INC DI 
           INC DI 
           DEC CX 
           CMP CX,0 
           JA  DISK_FREE2 
           POP EAX 
           MOV DS:TTDW3,BX 
           JMP DISK_FREE1 
DISK_FREE_END0: 
           POP EAX 
DISK_FREE_END: 
 
           MOV BX,OFFSET DOSBOOT 
           MOV AL,DS:[BX+0DH]  ;setctors per cluster 
           MOVZX EAX,AL 
           MOV CX,DS:[BX+0BH]  ;bytes per sector 
           MOVZX ECX,CX 
           MUL ECX             ;eax=bytes per cluster 
           MOV CX,SI           ;free cluster count 
           MOVZX ECX,CX 
           MUL ECX             ;free bytes  
 
           POP DS 
           POP ES 
           POP SI 
           POP DI 
           POP EDX 
           POP ECX 
           POP EBX 
           RET 
DISK_FREE  ENDP 
             
FILE_INIT   PROC FAR 
            ; out AL=1 is not FAT16 
            PUSH EAX 
            PUSH BX 
            PUSH CX 
            PUSH DX 
            PUSH DS 
            PUSH ES 
;jmp FILE_INIT_END 
            ; sft init 
            MOV AX,V_SFT_SEL 
            MOV ES,AX 
            MOV DI,0 
            MOV CX,16384 
            MOV EAX,0 
            REP STOSD 
            ;;;;;;;;;;;;;;;;;;;;; read priboot use INT13H 02 
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX 
            MOV ES,AX 
            MOV BX,OFFSET PRIBOOT 
            MOV AH,2 
            MOV AL,1 
            MOV CH,0       ;cylinder 
            MOV CL,1       ;sector 
            MOV DH,0       ;head 
            MOV DL,80H     ;driver: hard disk 1 
            INT 83H        ;=bios 13h 
            ;;;;;;;;;;;;;;;;;;;;;; read DOSboot use INT13H 02 
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX 
            MOV BX,OFFSET PRIBOOT 
            ADD BX,447             ;part 1 begin position 446 
            MOV CH,DS:[BX+2]       ;cylinder 
            MOV CL,DS:[BX+1]       ;sector 
            MOV DH,DS:[BX]         ;head 
            MOV BX,OFFSET DOSBOOT 
            MOV AH,2 
            MOV AL,1 
            MOV DL,80H     ;driver: hard disk 1 
            INT 83H        ;=bios 13h 
            ;;;;;;;;;;;;;;;;;;;;;; is FAT16 ? 
            MOV BX,OFFSET DOSBOOT 
            MOV AL,DS:[BX+36H] 
            CMP AL,'F' 
            JNE DO_DIR_END 
            MOV AL,DS:[BX+37H] 
            CMP AL,'A' 
            JNE DO_DIR_END 
            MOV AL,DS:[BX+38H] 
            CMP AL,'T' 
            JNE DO_DIR_END 
            MOV AL,DS:[BX+39H] 
            CMP AL,'1' 
            JNE DO_DIR_END 
            MOV AL,DS:[BX+3AH] 
            CMP AL,'6' 
            JNE FILE_INIT_ENDE 
 
            ;;;;;;;;;;;;;;;;;;;  Next is FAT16 
            ;;;;;;;;;;;;;;;;;;; Set up SYS_curret_dir as:c:\ etc. 
            MOV AL,'C' 
            MOV AH,':' 
            MOV WORD PTR DS:[SYS_CURRENT_DIR],AX ; "C:" 
            MOV AL,'\' 
            MOV AH,0 
            MOV WORD PTR DS:[SYS_CURRENT_DIR+2],AX ; "\",0 
            MOV AX,70H 
            MOV WORD PTR DS:[SYS_CURRENT_DIR+67],AX ; driver 
            MOV BX,OFFSET DOSBOOT 
            ADD BX,0BH                          ;BPB offset 
            MOV AX,DS 
            MOV WORD PTR DS:[SYS_CURRENT_DIR+69],AX ;ds 
            MOV WORD PTR DS:[SYS_CURRENT_DIR+71],BX ;offset 
            MOV AL,2 
            MOV DS:[SYS_CURRENT_DIR+80],AL ; offset for \ 
 
 
            JMP FILE_INIT_END 
FILE_INIT_ENDE: 
            MOV AL,1 
            JMP FILE_INIT_ENDOK 
FILE_INIT_END: 
            MOV AL,0 
FILE_INIT_ENDOK: 
            POP ES 
            POP DS 
            POP DX 
            POP CX 
            POP BX 
            POP EAX 
            RET 
FILE_INIT   ENDP 
 
GET_HANDLE  PROC FAR 
            ;in: ds:dx address of directory item 
            ;out : ax=handle 
            PUSH EBX 
            PUSH ECX 
            PUSH EDX 
            PUSH DS 
            PUSH ES 
            PUSH SI 
            PUSH DI 
            PUSH DX 
            ;;;;;;;; 
 
            ; find free item in sft 
            MOV SI,DX 
            MOV AX,V_SFT_SEL 
            MOV ES,AX 
            MOV DI,40 
            MOV CX,1637        ;1638 items in sft 
            MOV AL,0 
GET_HANDLE_1:  
            CMP ES:[DI],AL 
            JE GET_HANDLE_2   
            ADD DI,40 
            LOOP GET_HANDLE_1 
            JMP GET_HANDLE_ERROR 
 
GET_HANDLE_2: 
            ; FOUND a free item 
            MOV AX,DI 
            XOR DX,DX 
            MOV CX,40 
            DIV CX          ;ax=sft_no 
            PUSH AX 
            ; find free item in sft 
 
            ; ;;;;;;;;;;;;;;; fill sft 
            ; 
            ; DI=sft_start_addr 
            MOV AL,1 
            MOV ES:[DI],AL   ; use the item 
            MOV AL,0 
            MOV ES:[DI+1],AL ; only read 
            MOV AL,DS:[SI+0BH] 
            MOV ES:[DI+2],AL ; file property 
            PUSH DS 
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX 
            MOV AL,DS:STR1 
            SUB AL,40H 
            POP DS 
            MOV ES:[DI+3],AL ; Driver_NO 
            PUSH SI 
            PUSH DI 
            ADD DI,4 
            MOV CX,11 
            REP MOVSB     ;move file name and extended name to sft 
            POP DI 
            POP SI 
            MOV EAX,DWORD PTR DS:[SI+1CH] 
            MOV DWORD PTR ES:[DI+19],EAX  ;file length 
            MOV AX,WORD PTR DS:[SI+1AH]   ;begin cluster_no 
            MOVZX EAX,AX 
            MOV DWORD PTR ES:[DI+27],EAX  ;begin cluster_no 
            MOV AX,WORD PTR DS:[SI+18H] ;date 
            MOV WORD PTR ES:[DI+23],AX  ;date 
            MOV AX,WORD PTR DS:[SI+16H] ;time 
            MOV WORD PTR ES:[DI+25],AX  ;time 
            MOV EAX,0 
            MOV DWORD PTR ES:[DI+36],EAX  ;POINTER 
 
            ; find free item in opt 
            MOV AX,V_TOS_DATA_SEL  
            MOV ES,AX 
            MOV DI,OFFSET OPT 
            MOV CX,512 
            MOV AX,0 
GET_HANDLE_3:  
            SCASW 
            JE GET_HANDLE_4 
            LOOP GET_HANDLE_3 
            JMP GET_HANDLE_ERROR 
GET_HANDLE_4: 
            ; find free item in OPT 
            POP AX        ;ax=sft_no 
            SUB DI,2 
            MOV WORD PTR ES:[DI],AX 
            MOV AX,DI 
            MOV DI,OFFSET OPT 
            SUB AX,DI 
            JMP GET_HANDLE_RET 
GET_HANDLE_ERROR: 
            MOV AX,65535 
 
GET_HANDLE_RET: 
            POP DX 
            POP DI 
            POP SI 
            POP ES 
            POP DS 
            POP EDX 
            POP ECX 
            POP EBX 
            RET 
GET_HANDLE  ENDP 
 
READ_ONE_SECTOR PROC FAR 
            ; in: DS:DX=dosboot or extdosboot EAX=logic sector_no 
            ;;;;;;;;;;;;;;;;;;;;;; read ONE sector to DS:TTSECOR 
            PUSH AX 
            PUSH BX 
            PUSH CX 
            PUSH DX 
            PUSH ES 
            CALL LSECTOR_NO_ADDR  ; in: DS:DOSBOOT  OR EXTDOSBOOT EAX=logic sector_no 
                                  ; out ch:cylinder,cl:sector,dh:head 
            ;MOV CH,0       ;cylinder 
            ;MOV CL,10      ;sector 
            ;MOV DH,9       ;head 
            MOV AX,DS 
            MOV ES,AX 
            MOV BX,OFFSET TTSECTOR 
            MOV AH,2 
            MOV AL,1 
            MOV DL,80H     ;driver: hard disk 1 
            INT 83H        ;=bios 13h 
            ;;;;;;;;;;;;;;;;;;;;; display dir in one sector 
            POP ES 
            POP DX 
            POP CX 
            POP BX 
            POP AX 
            RET 
READ_ONE_SECTOR ENDP 
 
NEXT_CLUSTER PROC FAR 
             PUSH SI 
             PUSH EBX 
             PUSH ECX 
             PUSH EDX 
 
             PUSH DX 
             MOV SI,DX           ;offset of logcal DOSBOOT 
             MOV CX,WORD PTR DS:[SI+0BH]  ;bytes per setctor 
             MOVZX ECX,CX 
             MOV EBX,EAX 
             ADD EAX,EBX         ;eax=offset of the cluster_no  
             XOR EDX,EDX 
             DIV ECX             ;eax=sectors before the cluster_no  
             INC EAX             ;ADD boot now eax=logical sector_no 
NEXT_CLUSTER1:                   ;EAX=sector_no of the cluster 
             ;;;;;;; 
             POP CX 
             PUSH DX            ;remains = offset of cluster_no 
             MOV DX,CX 
             CALL READ_ONE_SECTOR 
             MOV BX,OFFSET TTSECTOR 
             POP DX 
             ADD BX,DX 
             MOV AX,DS:[BX]     ;next cluster 
             MOVZX EAX,AX 
             POP EDX 
             POP ECX 
             POP EBX 
             POP SI 
             RET 
NEXT_CLUSTER ENDP 
 
FIND_DIR    PROC FAR 
            ;in:ttdw1 =start dir  ttdw2=end dir 
            ;   ttsector_no =start logical sector_NO 
            ;   rootdir_ls_NO = end logical sector_NO 
            ;   ttdw6=end offset for dir_item 
            ;   ttdw6=bytes_per_sector -32(480) 
            ;out: ax=0 ->OK ax=1 not found 
            ;use ttdw5 =start offset =(OFFSET TTSECTOR) 
            ;    ttdw7 =end_total offset =(OFFSET TTSECTOR+ttdw6) 
 
            ;;;;;;;;;;;;;;;;;;   loop read sector 
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX 
            MOV ES,AX 
            MOV AX,OFFSET TTSECTOR 
            MOV BX,DS:TTDW6 
            ADD AX,BX 
            MOV DS:TTDW7,AX 
FIND_DIR_1:    
            MOV EAX,DS:TTSECTOR_NO 
            CMP EAX,DS:ROOTDIR_LS_NO   
            JA  FIND_DIR_END_ERROR 
            INC DS:TTSECTOR_NO 
            MOV  DX,OFFSET WORKBOOT 
            CALL READ_ONE_SECTOR  ; read to ->ttsector 
            ;;;;;;;;;;;;;;;;;;;;; find dir(=str2) in ttsector  
            CLD 
            MOV SI,OFFSET TTSECTOR 
            MOV DS:TTDW5,SI 
FIND_DIR_10: 
            MOV SI,DS:TTDW5 
            CMP SI,DS:TTDW7 
            JA  FIND_DIR_NEXT_SECTOR 
            MOV CX,32 
            ADD DS:TTDW5,CX 
            MOV CX,11               ;DS:TTDW4 
            MOV DI,OFFSET STR2 
FIND_DIR_11:             
            CMPSB 
            LOOPE FIND_DIR_11 
            JE FIND_DIR_FOUND 
            ;compare next 
            JMP FIND_DIR_10 
            ;;;;;;;;;;;;;;;;;;;;; find dir(=str2) in ttsector  
 
FIND_DIR_NEXT_SECTOR: 
            JMP FIND_DIR_1 
FIND_DIR_FOUND: 
            MOV SI,DS:TTDW5          ;position of found dir 
            SUB SI,32 
FIND_DIR_FOUND_1:             
            MOV CX,32 
            MOV DI,OFFSET DAT 
            ADD DI,80 
            REP MOVSB 
             
            ;;;;;;;;;;;;;;;;;after found the dir-->start 
            ;;;;;;;;;;;;;;;;;after found the dir-->end 
            MOV AX,0 
            JMP FIND_DIR_END 
FIND_DIR_END_ERROR: 
            MOV AX,1 
FIND_DIR_END: 
            RET 
FIND_DIR    ENDP 
 
FIND_DIR_FILE PROC FAR 
            ; in: directory file is in v_file_buf_sel 
            ;     dat is in v_tos_data_sel 
            ;     STR2=NAME to find 
            ; out: 
 
            CALL FREAD_DAT 
            ;save length of diretory file(CHIS) to ttdd1 
            PUSH DS 
 
             
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX 
            MOV EAX,DWORD PTR DS:TTDD1 
            MOV CX,40 
            MUL CX                     ;AX=offset of sft 
            MOV SI,AX 
            MOV DX,V_SFT_SEL 
            MOV DS,DX 
            MOV EDX,DWORD PTR DS:[SI+36]     ;write pointer of file 
 
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX 
            MOV DWORD PTR DS:TTDD1,EDX 
 
            POP DS 
            CMP EDX,0 
            JLE FIND_DIR_FILE_ERROR 
            ;save length of diretory file(CHIS) to ttdd1   ok! 
 
            ;;;find 'ttt' in directory file:chis 
            PUSH DS 
            PUSH ES 
 
            MOV AX,V_FILE_BUF_SEL 
            MOV DS,AX 
            MOV AX,V_TOS_DATA_SEL 
            MOV ES,AX 
            MOV DI,OFFSET STR2 
            PUSH DI 
            MOV CX,80 
            MOV AL,0 
            REPNZ SCASB 
            MOV AX,DI 
            POP DI 
            SUB AX,DI 
            DEC AX 
            MOV ES:TTDW5,AX          ;end_offset    ok 
            CLD 
            MOV ESI,0 
FIND_DIR_FILE_10: 
            CMP ESI,DWORD PTR ES:ttdd1 
            JAE  FIND_DIR_FILE_ERROR1 
            MOV CX,11                 ;ES:TTDW5 
            MOV DI,OFFSET STR2 
            PUSH SI 
            REPE CMPSB 
            JE  FIND_DIR_FILE_FOUND 
            POP SI 
            ADD SI,32 
            JMP FIND_DIR_FILE_10      ;compare next 
FIND_DIR_FILE_FOUND: 
            POP SI 
            MOV CX,32 
            MOV DI,OFFSET DAT 
            ADD DI,80 
            REP MOVSB 
            MOV AX,0 
            POP ES 
            POP DS 
            MOV AX,0 
            JMP FIND_DIR_FILE_END 
 
FIND_DIR_FILE_ERROR1: 
            POP ES 
            POP DS 
FIND_DIR_FILE_ERROR: 
            MOV AX,1 
            ;;;;;;;;;;;;;;;;;;;;; find dir(=str2) in v_file_buf_sel 
FIND_DIR_FILE_END: 
            RET 
            ;;;;;;;;;;;;;;;;;;;;; find dir(=str2) in v_file_buf_sel 
FIND_DIR_FILE ENDP 
 
FREAD  PROC FAR 
       ;in: ds:dx address of buf cx=count to read  ax=handle    
       ;    es:bx address of opt 
       ;out : cl=0 ok ax=real count have read  
       ;      cl=1 error ax=error_no 
       ;CX AX will be changed 
       PUSH EBP 
       MOV EBP,ESP 
       ADD EBP,4            ;ebp= ori esp 
 
       PUSH SI 
       PUSH DI 
       ;;;;;;;;;;parameter into stack 
       PUSH DS 
       PUSH DX 
       PUSH ES 
       PUSH BX 
       PUSH FS 
       ;;;;;;;;;;;;;;;;;;;;;;;;;;; 
       PUSH CX                 ;ebp -20 
       ;;; GET file_len 
       MOV SI,OFFSET OPT 
       ADD SI,AX               ;SI=offset+handle=offset in sft 
       MOV AX,ES:[SI]          ;ax=sft_no 
       MOV CX,40 
       XOR DX,DX 
       MUL CX                  ;ax=offset of the handle in sft 
       PUSH AX                 ;Paramter offset in sft 
       MOV SI,AX               ;Paramter offset in sft     ebp-22 
 
       ;;;; NOW have found the position in sft 
       ; get file_len 
       ; es change to sft 
       MOV AX,V_SFT_SEL 
       MOV ES,AX               ;ES:SI change to sft 
       MOV AX,DS 
       MOV GS,AX               ;GS:USER BUF 
       MOV EAX,ES:[SI+19]      ; file_len 
       PUSH EAX                ; reserve 
       MOV AX,V_TOS_DATA_SEL  
       MOV FS,AX 
       MOV AL,ES:[SI+3]        ; driver_no  4=D 
       DEC AL 
       MOVZX AX,AL 
       XOR DX,DX 
       MOV CX,512 
       MUL CX                  ;ax=offset of Logical boot sector  
       MOV BX,OFFSET DOSBOOTA 
       ADD BX,AX 
                               ; FS:BX logical boot sector addr 
       MOV AX,FS:[BX+0BH]      ; bytes per sector 
       PUSH AX                 ; bytes per sector into statck ebp-28 
       MOVZX EAX,AX 
       MOV CL,FS:[BX+0DH]      ; sectors per cluster 
       MOVZX ECX,CL 
       XOR EDX,EDX 
       MUL CX                  ; Eax=bytes per cluster 
       MOV ECX,EAX             ; ECX==bytes per cluster 
       MOV AX,[EBP-20] 
       MOVZX EAX,AX 
       XOR EDX,EDX 
       DIV ECX                  
       CMP EDX,0 
       JLE FREAD1 
       INC EAX                 ; EAX=clusters to read 
FREAD1:        
       MOV ECX,DWORD PTR ES:[SI+27] 
       PUSH ECX                ; begin cluster_no into stack EBP-32 
       INC EAX        
 
       MOV CL,ES:[SI+2]        ; property of dir 
       ADD CL,10H 
       CMP CL,10H 
       JNE FREAD1_2 
       MOV EAX,0FFFFH          ;=subs directory :end cluster_NO=0FFFFH 
FREAD1_2: 
       PUSH EAX                ; EAX=cluster_nos to read+1 into stack EBP-36 
       ;; 
       MOV CL,FS:[BX+0DH] 
       MOVZX CX,CL 
       PUSH CX                  ;setctors per cluster into stack EBP -38(64) 
       MOV AX,FS:[BX+11H]      ; root directory items(512) 
       MOVZX EAX,AX 
       MOV CX,32 
       MOVZX ECX,CX 
       XOR EDX,EDX 
       MUL ECX                 ;eax=bytes of root directory 
       MOV CX,[EBP-28] 
       XOR EDX,EDX 
       MOVZX ECX,CX 
       DIV ECX                 ;eax=sectors of root directory 
 
       PUSH EAX 
       MOV AL,FS:[BX+10H]       ;FAT_COUNT 
       MOVZX EAX,AL 
       MOV CX,FS:[BX+16H]       ;sectors per FAT 
       MOVZX ECX,CX 
       XOR EDX,EDX 
       MUL ECX                  ;eax=sectors of 2 FATS 
       POP ECX 
       ADD EAX,ECX              
       INC EAX                  ;first logical sector_no of file area 
       PUSH EAX                 ;first logical sector_no of file area ebp-42 
       MOV  AX,1 
       PUSH AX                  ;current sector_no per cluster  EBP-44 
       PUSH EAX      ;                                          EBP-48 
       MOV DWORD PTR [EBP-26],1   ;begin cluster             ;|,1 
       ;;;loop read 
;jmp fread_end 
FREAD2:           ;<-----------------------------------cluster loop              
       MOV EAX,DWORD PTR [EBP-26] ;begin cluster       (1)   ;| 
       CMP EAX,DWORD PTR [EBP-36] ;clusters to read +1   (2) 
       JG  FREAD_END 
 
       INC DWORD PTR [EBP-26]     ; 
       MOV EAX,DWORD PTR [EBP-32] ;begin cluster_no  (3c29)  ;| 
       DEC EAX 
       DEC EAX 
       MOV CX,WORD PTR [EBP-38]   ;40h 
       MOVZX ECX,CX 
       XOR EDX,EDX 
       MUL ECX                    ;eax=0F0980h 
       ADD EAX,DWORD PTR [EBP-42] ;first logical sector_no (0f0ba1h) 
       MOV DWORD PTR [EBP-48],EAX 
       MOV WORD PTR [EBP-44],1 
FREAD22:          ;<------------------------------sectors per cluster loop 
       MOV CX,WORD PTR WORD PTR [EBP-44]                      ;| 
       CMP CX,WORD PTR [EBP-38] 
       JA  FREAD4 
       INC WORD PTR WORD PTR [EBP-44]                       
       PUSH DS 
       PUSH BX    ;offset of logical boot sector 
       MOV  CX,FS 
       MOV  DS,CX 
       MOV  DX,BX 
       MOV  EAX,DWORD PTR [EBP-48] 
       INC  DWORD PTR [EBP-48] 
       CALL READ_ONE_SECTOR   ;into V_TOS_DATA_SEL:ttsector 
       POP  BX 
       POP  DS 
       ;;;;;;;;;;;;;;;;;;;;;;;;move ttsector -->buf 
       MOV EAX,DWORD PTR ES:[SI+36] 
       MOV EDI,EAX            ;here simply: file pointer=user buf pointer 
       MOV CX,[EBP-28]        ;bytes per sector 
       MOVZX ECX,CX 
       ADD EAX,ECX 
       ;; 
       MOV CL,ES:[SI+2]        ; property of dir 
       AND CL,10H 
       CMP CL,10H 
       JE FREAD3 
       ;; 
       CMP EAX,DWORD PTR ES:[SI+19] 
       JLE FREAD3 
       MOV EAX,DWORD PTR ES:[SI+19]   ;is not directory  
FREAD3: 
       MOV DWORD PTR ES:[SI+36],EAX ;save current file pointer 
       PUSH SI 
       PUSH DS 
       PUSH ES 
       MOV SI,OFFSET TTSECTOR 
       MOV AX,FS 
       MOV DS,AX 
       MOV AX,GS 
       MOV ES,AX 
       REP MOVSB 
       POP ES 
       POP DS 
       POP SI 
 
       ;;;;;; file_end check      
       ;; directory file continue 
       MOV CL,ES:[SI+2]        ; property of dir 
       AND CL,10H 
       CMP CL,10H 
       JE FREAD22              ; next sector in one cluster 
       ;; 
       MOV EAX,DWORD PTR ES:[SI+36]      ; current pointer 
       CMP EAX,DWORD PTR ES:[SI+19]      ; file length 
       JAE FREAD_END 
       JMP FREAD22 
FREAD4: 
       ;;    find next cluster_no in FAT 
       PUSH DS 
       PUSH BX 
       PUSH DX 
       MOV AX,FS 
       MOV DS,AX 
       MOV DX,BX 
       MOV EAX,DWORD PTR [EBP-32] ;current cluster_no  
       CALL NEXT_CLUSTER 
       POP DX 
       POP BX 
       POP DS 
       CMP EAX,0FFF8H                 ;EAX=0FFF8H :last cluster 
       JAE  FREAD_END 
       ;;;; eax=next cluster_no  into EBP-32 
       MOV DWORD PTR [EBP-32],EAX 
       JMP FREAD2 
 
FREAD_END: 
       ;;;;;;;;;;;;;;;;;;;;;;;;;;; 
       SUB EBP,18 
       MOV ESP,EBP 
       POP FS 
       POP BX 
       POP ES 
       POP DX 
       POP DS 
       POP DI 
       POP SI 
       POP EBP 
       RET 
FREAD  ENDP 
 
FREAD_DAT   PROC FAR 
            ;in: directory in dat structure 
            ; setup file handle 
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX 
            MOV DX,OFFSET DAT 
            ADD DX,80 
            CALL GET_HANDLE     ;out ax=handle 
            CMP AX,65535 
            JE FIND_DIR_END_ERROR    ;no sft or opt free item 
            ; setup file handle 
            ;;;read the file 
            PUSH DS 
            PUSH ES 
            PUSH AX                  ;handle 
            MOV AX,V_TOS_DATA_SEL  
            MOV ES,AX 
            MOV BX,OFFSET OPT 
            POP AX 
            PUSH AX 
            ADD BX,AX 
            MOV DX,ES:[BX] 
            MOVZX EDX,DX 
            MOV DWORD PTR ES:TTDD1,EDX      ;subs in sft -->ttdd1 =1:CHIS 
            MOV BX,OFFSET OPT 
            MOV DX,V_FILE_BUF_SEL 
            MOV DS,DX 
            MOV DX,0        ;ds:dx read buffer = 2M -128K 
            MOV CX,0FFFFH   ;read 32K per time 
            POP AX 
            CALL FREAD       ;ok 
            POP ES 
            POP DS 
            ;;;read the file 
            ret 
FREAD_DAT   ENDP 
 
DO_DOS21H4E PROC FAR 
            ;in : ds:dx file_name asciiz string cx=0 normal file 
            ;out ax=0 ok information-->file_info ax<>0:error 
            ;"D:\CHIS\TTT\MODE_BIG.TXT"-----file_name 
            PUSH DX 
             
             
            ;;;;;;;;;;;; move file_name string to str1 
            MOV BX,OFFSET STR1 
            PUSH BX 
            PUSH DS 
            PUSH DX 
            PUSH DS 
            CALL STRCPY 
            ;;;;;;;;;;;; move file_name string to str1 
 
            POP DX 
            PUSH DX 
            MOV BX,DX 
            MOV CL,DS:[BX]    ;driver for example: C 
            CMP CL,61H 
            JL  DOS21H4E_1 
            SUB CL,20H         ;change to lower 
DOS21H4E_1: 
            MOV DS:TTDB,CL 
            CMP CL,'C' 
            JE  DOS21H4E_2     ;root directory (c:\) 
 
            ;;;;;;;;;;;;;;;; Read DOS logical part table sector in EXTpart 
            ;; for one hard disk 
            SUB CL,43H         ;cx=2 driver E  loop_count 
            MOV DS:TTDB1,CL    ;TTBD1=loop_count 
            MOV CL,1 
            MOV DS:TTDB,CL     ;TTDB=loop begin 
DOS21H4E_10: 
            MOV CL,DS:TTDB 
            CMP CL,DS:TTDB1 
            JA  DOS21H4E_22    ;end 
            ;;;;;;;;;;;;;;;; read Part table in EXTpart use INT13H 02 
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX 
            MOV ES,AX 
            MOV CL,1 
            CMP CL,DS:TTDB 
            JNE DOS21H4E_11 
            MOV BX,OFFSET PRIBOOT 
            JMP DOS21H4E_12 
DOS21H4E_11: 
            MOV BX,OFFSET WORKBOOT 
DOS21H4E_12: 
            ADD BX,1CFH            ;part 2 
            MOV CH,DS:[BX+2]       ;cylinder 
            MOV DS:TTDBX,CH 
            MOV CL,DS:[BX+1]       ;sector 
            MOV DS:[TTDBX+1],CL 
            MOV DH,DS:[BX]         ;head 
            MOV DS:[TTDB+2],DH 
            MOV BX,OFFSET WORKBOOT 
            MOV AH,2 
            MOV AL,1 
            MOV DL,80H     ;driver: hard disk 1 
            INT 83H        ;=bios 13h 
            INC  DS:TTDB 
            LOOP DOS21H4E_10 
            ;;;;;;;;;;;;;;;; Read DOS logical part table sector in EXTpart 
 
            ;;;;;;;;;;;;;;;; Read EXTDOSboot sector 
DOS21H4E_22: ;;;;;;;;;;;;;;;  is not "C:\...." 
            MOV BX,OFFSET WORKBOOT  ;part 1 begin position 446 
            JMP DOS21H4E_29 
DOS21H4E_2: ;;;;;;;;;;;;;;;   is     "C:\...." 
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX 
            MOV ES,AX 
            MOV BX,OFFSET PRIBOOT 
            MOV AL,0 
            MOVZX EAX,AL 
            MOV DS:HIDDEN_SECTOR,EAX 
DOS21H4E_29: 
            ADD BX,447 
            MOV CH,DS:[BX+2]       ;cylinder 
            MOV CL,DS:[BX+1]       ;sector 
            MOV DH,DS:[BX]         ;head 
            MOV BX,OFFSET WORKBOOT 
            MOV AH,2 
            MOV AL,1 
            MOV DL,80H     ;driver: hard disk 1 
            INT 83H        ;=bios 13h 
 
            ;;;;;;;;;;;;;;;; Read EXTDOSboot sector----->END 
            ; now DOSboot or EXTdosboot -->workboot 
 
            ;;; logical_boot_sector --> DOSBOOTA 
            PUSH EAX 
            PUSH EBX 
            PUSH ECX 
            PUSH EDX 
            PUSH SI 
            PUSH DI 
            PUSH DS 
            PUSH ES 
 
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX 
            MOV ES,AX 
            MOV DI,OFFSET DOSBOOTA 
            XOR DX,DX 
            MOV AX,512 
            MOV CL,DS:STR1     ;file_name in str1 AL=driver_C(D) 
            SUB CL,40H         ;al=driver_no   (1=A 3=C 4=D) 
            DEC CL 
            MOV CH,0 
            MUL CX             ;AX=OFFSET from DOSBOOTA 
            ADD DI,AX          ;to ADDRESS 
            MOV SI,OFFSET WORKBOOT 
            MOV CX,256 
            REP MOVSW 
            POP ES 
            POP DS 
            POP DI 
            POP SI 
            POP EDX 
            POP ECX 
            POP EBX 
            POP EAX 
            ;;; logical_boot_sector --> DOSBOOTA 
 
;KKKKKKKKKKKKKKKK Count hidden sectors before the logcal (D) 
            CMP DS:TTDB,'C' 
            JE  DOS21H4E_30 
            PUSH EAX 
            PUSH EBX 
            PUSH ECX 
            PUSH EDX 
            ;MOV DS:TTDBX,CH ;cylinder 
            ;MOV DS:TTDBX+1,CL ;sector 
            ;MOV DS:TTDBX+2,DH ;head 
            MOV CH,DS:TTDBX 
            MOV CL,DS:[TTDBX+1] 
            MOV DH,DS:[TTDBX+2] 
 
            MOV AH,CL 
            MOV AL,CH 
            SHR AH,6                 ;ax=cylinder--ok 
            AND CL,3FH               ;begin sector--ok 
            MOV CH,DH                ;begin head---ok 
            PUSH CX 
 
            MOVZX EAX,AX 
            XOR EDX,EDX 
            MOV CX,DS:[BX+18H]       ;sectors per head 
            MOVZX ECX,CX 
            MUL ECX 
            MOV CX,DS:[BX+1AH]       ;heads per cylinder 
            MOVZX ECX,CX 
            XOR EDX,EDX 
            MUL ECX                  ;eax=sectors of cylinders 
 
            POP CX 
            PUSH EAX 
            PUSH CX 
            SHR CX,8                 ;head_no 
            MOVZX ECX,CX 
            MOV AX,DS:[BX+18H]       ;sectors per head 
            MOVZX EAX,AX 
            MUL ECX 
 
            POP DX 
            POP EAX 
            ADD EAX,ECX 
            DEC DL 
            MOVZX EDX,DL 
            ADD EAX,EDX 
            MOV DS:HIDDEN_SECTOR,EAX 
            POP EDX 
            POP ECX 
            POP EBX 
            POP EAX 
;KKKKKKKKKKKKKKKK 
DOS21H4E_30: 
            ;;;;;;;;;;;begin to D:\CHIS\TTT\XXXX.TXT 
            ;;;;;;;;;;; info in WORKBOOT 
            MOV AL,3 
            MOV DS:TTDB,AL       ;pointer to \ 
            MOV AL,'\' 
            MOV DS:STR3,AL        
 
            ;;count length of str1 
            MOV DI,OFFSET STR1 
            PUSH ES 
            MOV BX,DS 
            MOV ES,BX 
            PUSH DI 
            MOV AL,0 
            MOV CX,80 
            CLD 
            REPNZ SCASB 
            MOV BX,DI 
            POP DI 
            SUB BX,DI 
            SUB BX,3              ;cut off "D:\ 
            MOV DS:STR3+8,BL     ;next time search length in str1 
            POP ES 
            ;;count length of str1 
DOS21H4E_3:                      ;outer loop begin_position 
            ;;;;;;;;;;;;;;;;;;;;; look for next_\_begin_position 
 
            MOV BL,DS:TTDB 
            MOVZX BX,BL 
            MOV DI,OFFSET STR1 
 
            ADD  DI,BX            
            MOV  CL,DS:STR3+8 
            MOVZX CX,CL          ;loop+count 
            MOV DX,DS 
            MOV ES,DX 
            CMP CX,0 
            JE  DOS21H4E_ERROR 
DOS21H4E_31:  
            MOV AL,'\' 
            CLD 
            SCASB 
            LOOPNZ DOS21H4E_31 
            JE DOS21H4E_319       ;is not last one 
 
            ;NO '\' is last: MODE_X.TXT ---> 11 chars:MODE_X  TXT-->str2 
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX 
            MOV ES,AX 
            MOV SI,OFFSET STR1 
            MOV AL,DS:TTDB 
            MOVZX AX,AL 
            ADD SI,AX              ;si-->M 
            MOV DI,OFFSET STR2 
            MOV CX,8 
DOS21H4E_310: 
            CLD 
            MOV AL,DS:[SI]        ; str1 
            CMP AL,0 
            JE DOS21H4E_311 
            CMP AL,'.' 
            JE DOS21H4E_312 
            CMP CX,1 
            JLE DOS21H4E_313 
            MOV ES:[DI],AL 
            INC DI 
            INC SI 
            LOOP DOS21H4E_310 
DOS21H4E_311: 
            MOV AL,20H 
            ADD CX,3 
            DEC CX 
            CLD 
            REP STOSB 
            JMP DOS21H4E_318 
DOS21H4E_312:            ; '.' 
            CLD 
            MOV AL,20H 
            INC SI 
            REP STOSB 
            MOV CX,3 
            JMP DOS21H4E_312_1    
DOS21H4E_313: 
            MOV ES:[DI],AL 
            INC SI 
            INC DI 
            MOV AL,DS:[SI] 
            CMP AL,'.'         ;ok 
            JNE DOS21H4E_316   ;continue to add 3 blanks 
            INC SI 
            MOV CX,3 
DOS21H4E_312_1:                
            ;extended name 
            MOV AL,DS:[SI] 
            CMP AL,0 
            JE DOS21H4E_312_2 
            MOV ES:[DI],AL 
            INC DI 
            INC SI 
            LOOP DOS21H4E_312_1 
DOS21H4E_312_2: 
            MOV AL,20H 
            CLD 
            REP STOSB 
            JMP DOS21H4E_318 
DOS21H4E_316: 
            MOV CX,3 
            MOV AL,20H 
            REP STOSB 
DOS21H4E_318: 
            MOV DS:[DI],0 
            JMP DOS21H4E_LAST 
            ;   ---last search 
 
            ;;;;;;;;;;;;;;;;;;;;;   look for next_\_begin_position 
DOS21H4E_319: 
            ;            found   CHIS--> STR2 add 0 in the end 
            MOV AX,DI             ; next time position of finding 
            MOV DX,OFFSET STR1 
            SUB AX,DX 
            MOV DS:TTDB1,AL       ; svae next time position of finding  
            MOV SI,OFFSET STR1 
            MOV AX,SI 
            MOV BL,DS:TTDB 
            MOVZX BX,BL 
            ADD AX,BX 
            MOV SI,AX 
            MOV AX,DI 
            DEC AX 
            MOV DX,OFFSET STR1 
            SUB AX,BX             ;look for \_begin_position 
            SUB AX,DX 
            MOV CX,AX             ;CHIS LEN=4 CX=4=to move_len 
            MOV DS:TTDW4,AX       ;save CHIS_len 
 
            MOV DI,OFFSET STR2 
            REP MOVSB 
            MOV DS:[DI],0 
            MOV AL,DS:STR3+8 
            ADD AL,DS:TTDB 
            SUB AL,DS:TTDB1 
            MOV DS:STR3+8,AL 
            MOV AL,DS:TTDB1 
            MOV DS:TTDB,AL        ; svae next time position of finding  
 
            ;str2=CHIS add 7 blanks   8(name)+3(extend) 
            MOV CX,11 
            SUB CX,WORD PTR DS:TTDW4 
            MOV DI,OFFSET STR2 
            ADD DI,WORD PTR DS:TTDW4 
            MOV AL,20H 
            REP STOSB 
            JMP DOS21H4E_32 
            ;            found   CHIS--> STR2 add 0 in the end 
DOS21H4E_32: 
            ;;;;;;;;;;;;;find chis in directory file 
            MOV AX,V_TOS_DATA_SEL 
            MOV ES,AX 
            MOV DS,AX 
            ;;;; str3="\"-> find in root directory  <>"\"-> find in CHIS directory 
            MOV AL,"\" 
            CMP AL,DS:STR3 
            JNE DOS21H4E_5           ;<>"\"-> find in CHIS directory 
            MOV AL,"X" 
            MOV DS:STR3,AL 
 
DOS21H4E_32_1: 
            ;str3="\"-> find in root directory 
            MOV BX,OFFSET WORKBOOT 
            MOV AX,DS:[BX+11H] 
            MOV DS:TTDW2,AX     ;end dir=root directory_items 
            MOV AX,1 
            MOV DS:TTDW1,AX     ;begin dir 
 
            ;;;;;;;;;;;;;;;;;;; first sector_no of root dir 
            MOV BX,OFFSET WORKBOOT 
            MOV AX,DS:[BX+0BH] ;bytes per sectors 
            SUB AX,32 
            MOV DS:TTDW6,AX    ;bytes per sectors -32 
            MOV AX,DS:[BX+16H] ;sectors per FAT 
            MOV CX,DS:[BX+10H] ;FAT count 
            MUL CX 
            INC AX               
            ADC DX,0            ;DX:AX =first sector_no of root dir 
            MOVZX ECX,AX 
            MOVZX EAX,DX 
            SHL EAX,16 
            ADD EAX,ECX 
            MOV DS:ROOTDIR_FS_NO,EAX  ; first sector_no of root dir 
            MOV DS:TTSECTOR_NO,EAX    ; first sector_no of root dir 
            ;;;;;;;;;;;;;;;;;;; sectors in root dir 
            MOV AX,DS:[BX+11H] 
            MOV CX,32 
            MUL CX                    ; DX:AX bytes in root dir 
            MOV CX,DS:[BX+0BH]        ; bytes oer sector 
            DIV CX                    ; AX= sectors in root dir 
            ;;;;;;;;;;;;;;;;;;;         last sector_no of root dir 
            MOVZX EAX,AX              ; EAX= sectors in root dir 
            MOV EBX,DS:ROOTDIR_FS_NO  ; EBX= first sector_no of root dir 
            ADD EAX,EBX 
            DEC EAX 
            MOV DS:ROOTDIR_LS_NO,EAX  ; last sector_no of root dir 
 
            CALL FIND_DIR 
            CMP AX,0 
            JNE DOS21H4E_ERROR    ;error 
            ;;;;;; have Found chis          
            MOV AX,V_TOS_DATA_SEL 
            ;MOV DS,AX 
            MOV AL,DS:DAT+5BH 
            AND AL,10H 
            CMP AL,10H 
            JNE DOS21H4E_OK 
;            JNE DOS21H4E_OK 
            JMP DOS21H4E_3     ; have found chis ,want to Find next TTT\ 
DOS21H4E_5:  
            ;;;; "STR3<>"\"-> find in CHIS directory 
            ;;;;;;;;;;;;;find chis in directory file 
            CALL FIND_DIR_FILE 
            CMP AX,0 
            JNE DOS21H4E_ERROR    ;error 
            ;;;;;; have Found chis          
            MOV AX,V_TOS_DATA_SEL 
            MOV AL,DS:DAT+5BH 
            AND AL,10H 
            CMP AL,10H 
            JNE DOS21H4E_LAST 
            JMP DOS21H4E_3        ; Find MODE_BIG in TTT 
            ;;;;;;;;;;;;;find chis in directory file 
DOS21H4E_LAST: 
            MOV AL,3 
            CMP AL,DS:TTDB 
            JNE FFF 
            JMP DOS21H4E_32_1 
FFF: 
            CALL FIND_DIR_FILE 
            CMP AX,0 
            JNE DOS21H4E_ERROR 
            JMP DOS21H4E_END 
DOS21H4E_ERROR: 
            MOV DS:DAT,1 
            JMP DOS21H4E_END 
DOS21H4E_OK: 
            MOV DS:DAT,0          ;found the file "D:\CHIS...." 
DOS21H4E_END: 
            POP DX 
            RET 
DO_DOS21H4E ENDP 
 
TYPE_FILE   PROC FAR 
            ;;;;;;;;;;;DOS int21h 4eh 
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX  
            ;;;;;  asciiz change to upper 
            MOV SI,OFFSET G_WORK    ;FILE_NAME0 
            ADD SI,7 
TYPE_FILE1:     ;         <----------------------------------------- 
            MOV AL,DS:[SI] 
            CMP AL,0 
            JE TYPE_FILE_OK 
            ; upper/lower 
            CMP AL,61H 
            JL  TYPE_FILE11 
            CMP AL,7AH 
            JA  TYPE_FILE11 
            SUB AL,20H 
            MOV DS:[SI],AL 
TYPE_FILE11:                  ; upper/lower   
            INC SI 
            LOOP TYPE_FILE1 
TYPE_FILE_OK: 
            ;;;;;  asciiz change to upper 
 
            MOV DX,OFFSET G_WORK    ;FILE_NAME0 
            ADD DX,7 
            MOV CX,0                ;search normal file 
            MOV AH,4EH 
            INT 21H 
            ;;;;;;;;;;;DOS int21h 4eh 
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX  
            CMP DS:DAT,0            ;get diretory to DAT 
            JNE GGERROR 
 
            CALL FREAD_DAT 
            MOV AX,V_FILE_BUF_SEL  
            MOV DS,AX  
            MOV DX,0 
            CALL STRDISP 
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX  
            JMP TYPE_FILE_END            ;OK 
GGERROR: 
            ; read cursor 
            MOV AH,03H  
            MOV BH,0 
            INT 80H 
            ; set cursor 
            MOV AH,02H  
            MOV BH,0 
            INC DH 
            MOV DL,0 
            INT 80H 
            MOV DX,OFFSET CMD_ERROR 
            CALL STRDISP 
TYPE_FILE_END: 
            RET 
TYPE_FILE   ENDP 
 
DO_CMD      PROC FAR 
            ; in:  string in ds:g_work 
            ; copy g_work-->str 
            ;;;  next no used 
            ;MOV AX,V_TOS_DATA_SEL   
            ;MOV DS,AX 
            ;MOV DX,OFFSET STR1 
            ;PUSH DX 
            ;PUSH DS 
            ;MOV BX,OFFSET G_WORK 
            ;INC BX 
            ;INC BX 
            ;PUSH BX 
            ;PUSH DS 
            ;DEC BX 
            ;MOV AL,DS:[BX] 
            ;INC AL 
            ;MOV AH,0 
            ;PUSH AX 
            ;CALL STRNCPY           ;G_WORK--->STR1 
 
            ;"enter" 
            MOV AX,V_TOS_DATA_SEL  ;string in ds:STR1 
            MOV DS,AX 
            MOV DL,DS:G_WORK 
            CMP DL,0DH             ;input 0DH:return 
            JNE DO_CMD0 
            MOV AL,0 
            JMP DO_CMD_RETURN 
 
DO_CMD0:    ; deal inputed command_line 
            ;;;;;;;;;;; get command in g_work 
 
            ;;;;;;;;;;;; find ' ' in input string 
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX 
            MOV DX,OFFSET G_WORK 
            ADD DX,2           ;first 2 chars in input buffer 
            PUSH DX            ;offset of input string 
            PUSH DS 
            MOV AL,' ' 
            MOV SI,OFFSET STR3 
            MOV DS:[SI],AL     ;str3 is a ' ' 
            MOV AX,0 
            MOV DS:[SI+1],AL 
            PUSH SI 
            PUSH DS 
            CALL STRIPOS       ;Out: ax=position   ax=0ffffh no ' ' 
            ;;;;;;;;;;;; find ' ' in input string 
            MOV CX,AX 
            MOV DX,OFFSET G_WORK 
            ADD DX,2           ;first 2 chars in input buffer 
            CALL STRLEN 
            DEC AX             ;ax=iuput_length   cut off 'enter' in the end 
            MOV BX,V_TOS_DATA_SEL  
            MOV DS,BX 
            MOV DI,OFFSET G_WORK 
            ADD DI,2 
            MOV BYTE PTR DS:[DI+BX],0 
            ;;;;;;;;;;;;  command part -->str1 
            PUSH ES 
            CMP CX,0FFFFH 
            JE  CMD_EXIT0_0 
            CMP AX,CX 
            JA  CMD_EXIT0_1     
CMD_EXIT0_0:                     ;NO ' '           
            MOV CX,AX 
            MOV SI,OFFSET G_WORK  
            ADD SI,2 
            MOV AX,DS 
            MOV ES,AX 
            MOV DI,OFFSET STR1 
            REP MOVSB 
            MOV DS:[DI],0 
            POP ES 
            JMP CMD_EXIT0_2 
CMD_EXIT0_1:                   ; have ' ' 
            MOV SI,OFFSET G_WORK 
            ADD SI,2 
            MOV AX,DS 
            MOV ES,AX 
            MOV DI,OFFSET STR1 
            REP MOVSB 
            MOV DS:[DI],0 
            POP ES 
CMD_EXIT0_2:                   
            ; command part have been moved to str1 
            MOV  SI,OFFSET CMD_WORDS 
            PUSH SI 
            PUSH DS 
            MOV DI,OFFSET STR1 
            PUSH DI 
            PUSH DS 
            CALL STRIPOS       ;Out: ax=position   ax=0ffffh no ' ' 
;;;;;;;;;;;;CMD_WORDS   DB ",EXIT,DIR,TYPE,RUN,",0,0H 
            ;AX=            ;1    6   10   15 Command part position 
            ;;;;;;;;;;; get command in g_work-->END 
            CMP AX,1 
            JE  DO_CMD_RETURN    ;return to parent and exit 
            CMP AX,6 
            JE  CMD_DIR     ;dir 
            CMP AX,10 
            JE  CMD_TYPE     
            CMP AX,15 
            JE  CMD_RUN 
 
            MOV AL,1 
            JMP DO_CMD_RETURN 
            ;;;;;;;;;;;;;;;;;dir 
CMD_DIR:     
            CALL DO_DIR 
            MOV AL,0 
            JMP DO_CMD_RETURN 
CMD_TYPE: 
            CALL TYPE_FILE 
            MOV AL,0 
            JMP DO_CMD_RETURN 
CMD_RUN: 
            CALL MAKE_EXE 
            CMP AL,0 
            JNE EXE_ERROR 
;mmmmmmmmmmmmmmmm 
            ; setup U2 process  2# 
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX 
            MOV AX,USER_PSTSS_D_SEL 
            MOV DS:[PCB_TSS],AX 
            MOV EAX,100 
            MOV DS:[PCB_PRIORITY],EAX 
            MOV DS:[PCB_NAME],'U' 
            MOV DS:[PCB_NAME+1],'2' 
            MOV DS:[PCB_NAME+2],0 
            CALL FORK 
;mmmmmmmmmmmmmmmm 
 
;mov eax,2fffffffh 
;s444: 
;dec eax 
;jnz s444 
 
;test 
;            ;;;;;;;kkkkkkkkkkkkkkkk   run u1.exe 
;            MOV AX,V_PCB_SEL  
;            MOV FS,AX 
;            MOV EBP,512    ;u1.exe process 
;            ;; 
;            ;setup user_desc:stack\tss\ldt 
;;            PUSH EBP 
;            PUSH GS 
;            PUSH CX 
;            MOV  CX,32 
;            MOV  BX,OFFSET V_USER_PSTSS 
;            MOV  AX,V_GDT_ASDATA_SEL  
;            MOV  GS,AX 
;SCHED_2_20: 
;            MOV  AL,FS:[EBP+306] 
;            MOV  GS:[BX],AL 
;mov ah,0 
;call disp_ax 
;            INC  BX 
;            INC  EBP 
;            LOOP SCHED_2_20 
;            POP  CX 
;            POP  GS 
;            POP  EBP 
;            ;setup user_desc:stack\tss\ldt 
;            ;;;;;;;kkkkkkkkkkkkkkkk 
;test 
            MOV AX,V_TOS_DATA_SEL  
            MOV DS,AX 
            MOV BYTE PTR DS:[NEED_RESCHED],1   ;start schedule 4gggggg 
            MOV DS:[CURRENT],1024              ;user U2.EXE    5gggggg 
 
 
            DB 0EAH                  ;通过U.EXE的任务状态段,执行U.EXE 
            DW 0  
            dw V_USER_PsTSS_SEL 
 
            MOV AX,0 
            JMP DO_CMD_RETURN 
            ;;;;;;MMMMMMMMMMMM 
EXE_ERROR: 
            MOV AX,0 
            JMP DO_CMD_RETURN 
            ;;;;;;;;;;;;;;;;;;dir 
CMD_ERR0:   MOV AL,2 
DO_CMD_RETURN:  
            MOV AX,V_TOS_DATA_SEL             ;5ggggggg 
            MOV DS,AX                         ;5ggggggg 
            MOV BYTE PTR DS:[NEED_RESCHED],0   ;start schedule 5gggggg 
 
            RET 
DO_CMD      ENDP