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