⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 disk3.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	page	,164
	TITLE   DISK3 - Disk utility routines
	NAME    Disk3

;
;	Microsoft Confidential
;	Copyright (C) Microsoft Corporation 1991
;	All Rights Reserved.
;

;**     Low level Read and write routines for local SFT I/O on files and devs
;
;       DISKWRITE
;       WRTERR
;
;       Revision history:
;
;           1.  AN000 version 4.00 Jan. 1988
;           2.  SR; 10/12/89; Fixed bug in DISKWRITE that caused incorrect
;               calculation of filesizes when they cross the 32M boundary
;               if the filesize is not a multiple of 512 bytes
;             AN002 - Sept. 1988, PTM#4977 fix (writing cluster bug)  Bill Lawton
;		M017 MD 8/30/90 - Rewrite SHR32 for better speed
;        	M039 DB 10/17/90 - Disk write optimization

	.xlist
	.xcref
	include version.inc
	include dosseg.inc
	INCLUDE DOSSYM.INC
	INCLUDE DEVSYM.INC
	include dpb.inc
	include sf.inc
        include dosmac.inc              ;M039
	.cref
	.list

Installed = TRUE

	i_need	READOP,BYTE
	i_need	DISK_FULL,BYTE
	i_need  THISSFT,DWORD
	i_need  DMAADD,DWORD
	i_need  SecClusPos,BYTE
	i_need  ClusNum,WORD
	i_need  Trans,BYTE
	i_need  BytPos,4
	i_need  SecPos,DWORD              ;F.C. >32mb   ;AN000;
	i_need  BytSecPos,WORD
	i_need  BytCnt1,WORD
	i_need  BytCnt2,WORD
	i_need  SecCnt,WORD
	i_need  ThisDPB,DWORD
	i_need  LastPos,WORD
	i_need  ValSec,WORD               ;F.C. >32mb          ;AN000;
	i_need  GrowCnt,DWORD
	i_need  ALLOWED,BYTE
	I_need  JShare,DWORD


	I_need  HIGH_SECTOR,WORD          ;F.C. >32mb          ;AN000;
;	I_need  HIGH_SECTOR_TEMP,WORD     ;M039: Removed; F.C. >32mb ;AN000;

	I_need  EXTERR,WORD                        ; DOS 4.00   ;AN000;
	I_need  EXTERR_LOCUS,BYTE                  ; DOS 4.00   ;AN000;
	I_need  EXTERR_ACTION,BYTE                 ; DOS 4.00   ;AN000;
	I_need  EXTERR_CLASS,BYTE                  ; DOS 4.00   ;AN000;
	I_need  EXITHOLD,DWORD                     ; DOS 4.00   ;AN000;

;**RMFHFE**     I_need  DISK_FULL,BYTE                     ; DOS 4.00   ;AN000;

	I_need  SC_DRIVE,BYTE                      ; DOS 4.00   ;AN000;
	I_need  SC_CACHE_COUNT,WORD                ; DOS 4.00   ;AN000;

        I_need  SC_STATUS,WORD                     ;M039
        I_need  CURSC_SECTOR,WORD                  ;M039
        I_need  CURSC_DRIVE,BYTE                   ;M039

	I_need  ThisDRV,BYTE                       ; DOS 4.00   ;AN000;
	I_need  User_In_AX,WORD                    ; DOS 4.00   ;AN000;
	I_need  DOS34_FLAG,WORD                    ; DOS 4.00   ;AN000;
	I_need  FIRST_BUFF_ADDR,WORD               ; DOS 4.00   ;AN000;

        I_need  TEMP_VAR,WORD                      ;M039
        I_need  TEMP_VAR2,WORD                     ;M039


DOSCODE Segment
	ASSUME  SS:DOSDATA,CS:DOSCODE

Break   <DISKWRITE -- PERFORM USER DISK WRITE>
;----------------------------------------------------------------------------
;
; Procedure Name : DISKWRITE
;
; Inputs:
;       Outputs of SETUP
; Function:
;       Perform disk write
; Outputs:
;    Carry clear
;       CX = No. of bytes read
;       ES:DI point to SFT
;       SFT offset and cluster pointers updated
;    Carry set
;       CX = 0
;       ES:DI point to SFT
;       AX has error code
;----------------------------------------------------------------------------

;hkn; called by DOS_WRITE. DS already set up at this point.

procedure   DISKWRITE,NEAR
	DOSAssume   <DS>,"DiskWrite"

	Assert  ISSFT,<ES,DI>,"DiskWrite"


	invoke  CHECK_WRITE_LOCK          ;IFS. check write lock                 ;AN000;
	JNC     WRITE_OK                  ;IFS. lock check ok                    ;AN000;
	return

WRTEOFJ:
	JMP     WRTEOF

WRITE_OK:
	AND     ES:[DI].SF_FLAGS,NOT (sf_close_nodate OR devid_file_clean)
				; Mark file as dirty, clear no date on close

	MOV	AX,WORD PTR ES:[DI.sf_size]		;M039
        MOV     [TEMP_VAR],AX                           ;M039
	MOV	AX,WORD PTR ES:[DI.sf_size+2]		;M039
        MOV     [TEMP_VAR2],AX                          ;M039

;	TEMP_VAR2:TEMP_VAR = Current file size (sf_size);M039

	LES     BP,[THISDPB]
	Assert  ISDPB,<ES,BP>,"DiskWrite/WriteOk"

	invoke  BREAKDOWN
	MOV     AX,WORD PTR [BYTPOS]
	MOV     DX,WORD PTR [BYTPOS+2]
	JCXZ    WRTEOFJ                 ;Make the file length = sf_position
	ADD     AX,CX
	ADC     DX,0                    ;DX:AX = last byte to write + 1.

	MOV     BX,ES:[BP.dpb_sector_size]

	CALL    DIV32                   ;DX:AX/BX = CX:AX + DX (rem.).
	MOV     SI,AX
        MOV     [HIGH_SECTOR],CX

;       [HIGH_SECTOR]:SI = Last full sector to write.

	OR	DX,DX
	PUSH	DX			;M039: Free DX for use by SHR32
	MOV	DX,CX			;M039
	JNZ     CALCLUS
	SUB     AX,1                    ;AX must be zero base indexed          ;AC000;
	SBB	DX,0			;M039 ;F.C. >32mb			       ;AN000;

CALCLUS:
	CALL    SHR32                   ;F.C. >32mb                             ;AN000;
	POP	DX

;       AX = Last cluster to write.
;       DX = # of bytes in last sector to write (the "tail").
;       BX = ES:[BP.dpb_sector_size]

	PUSH    AX
	PUSH	DX

;M039
        mov     dx,[TEMP_VAR2]
        mov     ax,[TEMP_VAR]           ;DX:AX = current file size (in bytes).
        call    DIV32           	;DX:AX/BX = CX:AX + DX (rem.)
        mov     [TEMP_VAR2],cx
        mov     [VALSEC+2],cx
        mov     cx,ax
        mov     bx,si

;       [HIGH_SECTOR]:BX = Last full sector to write.
;          [VALSEC+2]:CX = Last full sector of current file.
;         [TEMP_VAR2]:CX = Last full sector of current file.
;                     DX = # of bytes in last sector of current file.
;M039

	OR      DX,DX
	JZ      NORND
	ADD     AX,1            	;Round up if any remainder                     ;AC000;
	ADC     [VALSEC+2],0
NORND:	MOV     WORD PTR [VALSEC],AX

;       [VALSEC] = Last sector of current file.

	XOR     AX,AX
	MOV     WORD PTR [GROWCNT],AX
	MOV     WORD PTR [GROWCNT+2],AX
	POP     AX

	MOV     DI,[HIGH_SECTOR]        ;F.C. >32mb                             ;AN000;
	CMP     DI,[TEMP_VAR2]		;M039; F.C. >32mb				;AN000;
	DLJB    NOGROW                  ;F.C. >32mb                             ;AN000;
	JZ      lowsec                  ;F.C. >32mb                             ;AN000;
	SUB     BX,CX                   ;F.C. >32mb                             ;AN000;
	SBB     DI,[TEMP_VAR2]   	;M039; F.C. >32mb di:bx no. of sectors    ;AN000;
	JMP     short yesgrow           ;F.C. >32mb                             ;AN000;
lowsec:
	MOV     DI,0            ;F.C. >32mb
	SUB     BX,CX           ; Number of full sectors
	JB      NOGROW
	JZ      TESTTAIL
yesgrow:
	MOV     CX,DX
	XCHG    AX,BX
	MUL     ES:[BP.dpb_sector_size]  ; Bytes of full sector growth
	MOV     [HIGH_SECTOR],DX         ;F.C. >32mb save dx                    ;AN000;
	MOV     [TEMP_VAR2],AX    	 ;M039; F.C. >32mb save ax                ;AN000;
	MOV     AX,DI                    ;F.C. >32mb                            ;AN000;
	MUL     ES:[BP.dpb_sector_size]  ;F.C. >32mb do higher word multiply    ;AN000;
	ADD     AX,[HIGH_SECTOR]         ;F.C. >32mb add lower value            ;AN000;
	MOV     DX,AX                    ;F.C. >32mb DX:AX is the result of     ;AN000;
	MOV     AX,[TEMP_VAR2]    	 ;M039; F.C. >32mb a 32 bit multiply      ;AN000;

	SUB     AX,CX           ; Take off current "tail"
	SBB     DX,0            ; 32-bit extension
	ADD     AX,BX           ; Add on new "tail"
	ADC     DX,0            ; ripple tim's head off
	JMP     SHORT SETGRW
HAVSTART:
;int 3
	MOV     CX,AX
	invoke  SKPCLP
	JCXZ    DOWRTJ


	invoke  ALLOCATE
	JNC     DOWRTJ

entry   WRTERR
	DOSAssume   <DS>,"DiskWrite/WrtErr"
	ASSUME  ES:NOTHING

	MOV     AH,0FH                          ;MS. write/data/fail/abort      ;AN000;
entry WRTERR22
	MOV     AL,[THISDRV]                    ;MS.                            ;AN000;

;**RMFHFE**     CALL    File_Handle_Fail_Error  ;MS. issue disk full I24

;**RMFHFE**     MOV     CX,0                    ;No bytes transferred
	XOR     CX,CX                   ; will be deleted

	LES     DI,[THISSFT]
	Assert  ISSFT,<ES,DI>,"DiskWrite/WrtErr"
	CLC
	return

DOWRTJ: JMP     short DOWRT

ACC_ERRWJ:
	JMP     SET_ACC_ERRW

TESTTAIL:
	SUB     AX,DX
	JBE     NOGROW
	XOR     DX,DX
SETGRW:
	MOV     WORD PTR [GROWCNT],AX
	MOV     WORD PTR [GROWCNT+2],DX
NOGROW:
	POP     AX
	MOV     CX,[CLUSNUM]    ; First cluster accessed
	invoke  FNDCLUS
	JC      ACC_ERRWJ
	MOV     [CLUSNUM],BX
	MOV     [LASTPOS],DX


	SUB     AX,DX           ; Last cluster minus current cluster
	JZ      DOWRT           ; If we have last clus, we must have first
	JCXZ    HAVSTART        ; See if no more data
	PUSH    CX              ; No. of clusters short of first
	MOV     CX,AX

	invoke  ALLOCATE
	POP     CX
	JC      WRTERR
	MOV     DX,[LASTPOS]
	INC     DX
	DEC     CX
	JZ      NOSKIP
	invoke  SKPCLP
	JC      ACC_ERRWJ
NOSKIP:
	MOV     [CLUSNUM],BX
	MOV     [LASTPOS],DX
DOWRT:
	CMP     [BYTCNT1],0
	JZ      WRTMID
	MOV     BX,[CLUSNUM]
	invoke  BUFWRT
	JC      ACC_ERRWJ
WRTMID:
	MOV     AX,[SECCNT]
	OR      AX,AX
	JZ      WRTLAST                  ;M039
	ADD     WORD PTR [SECPOS],AX
	ADC     WORD PTR [SECPOS+2],0    ;F.C. >32mb                            ;AN000;
	invoke  NEXTSEC
	JC      SET_ACC_ERRW             ;M039
	MOV     BYTE PTR [TRANS],1       ; A transfer is taking place
	MOV     DL,[SECCLUSPOS]
	MOV     BX,[CLUSNUM]
	MOV     CX,[SECCNT]
WRTLP:
	invoke  OPTIMIZE
	JC     	SET_ACC_ERRW

;M039
;       DI = Next physical cluster.
;       AX = # sectors remaining.
;       [DMAADD+2]:BX = transfer address (source data address).
;       CX = # of contiguous sectors to write. (These constitute a block of
;	     sectors, also termed an "Extent".)
;       [HIGH_SECTOR]:DX = physical sector # of first sector in extent.
;       ES:BP -> Drive Parameter Block (DPB).
;
;       Purge the Buffer Queue and the Secondary Cache of any buffers which
;	are in Extent; they are being over-written.

	push    di
	push    ax
        call    DskWrtBufPurge          ;DS trashed.
ASSUME DS:NOTHING
;M039

;hkn; SS override for DMAADD and ALLOWED
	MOV     DS,WORD PTR [DMAADD+2]
	MOV	[ALLOWED],allowed_RETRY + allowed_FAIL + allowed_IGNORE

;	put logic from DWRITE in-line here so we can modify it
;	for DISK FULL conditions.

DWRITE_LUP:
	invoke	DSKWRITE
	jz	DWRITE_OKAY

;	int	3
	cmp	al,error_handle_Disk_Full	; compressed volume full?
	jz	DWRITE_DISK_FULL

;hkn; SS override
	MOV	BYTE PTR [READOP],1
	invoke	HARDERRRW
	CMP	AL,1		; Check for retry
	JZ	DWRITE_LUP
	CMP	AL,3		; Check for FAIL
	CLC
	JNZ	DWRITE_OKAY 	; Ignore
	STC

DWRITE_OKAY:


	POP     CX
	POP     BX

;       CX = # sectors remaining.
;       BX = Next physical cluster.

;hkn; SS override
	Context DS

	JC      SET_ACC_ERRW
	JCXZ    WRTLAST
	MOV     DL,0
	INC     [LASTPOS]       ; We'll be using next cluster
	JMP     WRTLP

DWRITE_DISK_FULL:
        Context DS		;SQ 3-5-93 DS must be setup on return!
	pop	cx		; unjunk stack
	pop	bx

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -