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