📄 gfat16_p.asm
字号:
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -