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