     1                                  ;	SCCSID = @(#)disk3.asm	1.3 85/07/26
     2                                  ;	SCCSID = @(#)disk3.asm	1.3 85/07/26
     3                                  ;TITLE	DISK3 - Disk utility routines
     4                                  ;NAME	Disk3
     5                                  ; Low level Read and write routines for local SFT I/O on files and devs
     6                                  ;
     7                                  ;   DISKWRITE
     8                                  ;   WRTERR
     9                                  ;
    10                                  ;   Revision history:
    11                                  ;
    12                                  ;    AN000 version 4.00 Jan. 1988
    13                                  ;
    14                                  
    15                                  ;
    16                                  ; get the appropriate segment definitions
    17                                  ;
    18                                  [list -]
    18          ******************       warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi]
    14                              <4> [list -]
    14                              <3> [list -]
     3                              <2> 
     4                              <2> addsection DOSSTART, align=16 PUBLIC class=DOSSTART
     5                              <2> ; (no prior section) ; DOSSTART		ENDS
     6                              <2> 
     7                              <2> addsection DOSSTARTJUMP, align=1 PUBLIC class=START
     8                              <2> ; (no prior section) ; DOSSTARTJUMP		ENDS
     9                              <2> 
    10                              <2> addsection CONSTANTS, align=2 PUBLIC class=CONST
    11                              <2> ; (no prior section) ; CONSTANTS	ENDS
    12                              <2> 
    13                              <2> addsection DATA, align=2 PUBLIC class=DATA
    14                              <2> ; (no prior section) ; DATA		ENDS
    15                              <2> 
    16                              <2> addsection TABLE, align=2 PUBLIC class=TABLE
    17                              <2> ; (no prior section) ; TABLE		ENDS
    18                              <2> 
    19                              <2> addsection DOSDATATABLE, align=2 PUBLIC class=DOSDATACODE
    20                              <2> ; (no prior section) ; DOSDATATABLE		ENDS
    21                              <2> 
    22                              <2> addsection DOSDATACODE, align=1 PUBLIC class=DOSDATACODE
    23                              <2> ; (no prior section) ; DOSDATACODE		ENDS
    24                              <2> 
    25                              <2> addsection DOSBIODATA, align=2 PUBLIC class=DOSBIODATA
    26                              <2> 
    27                              <2> addsection LAST, align=16 PUBLIC class=LAST
    28                              <2> ; (no prior section) ; LAST		ENDS
    29                              <2> 
    30                              <2> group DOSGROUP DOSSTART DOSSTARTJUMP CONSTANTS DATA TABLE DOSDATATABLE DOSDATACODE DOSBIODATA LAST
     8                              <1> 
     9                              <1> %include "dcodeseg.nas"
     1                              <2> 
     2                              <2> %ifndef DCODESEGNAS
     3                              <2> %assign DCODESEGNAS 1
     4                              <2> 
     5                              <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE
     6                              <2> ; (no prior section) ; DOSCODETABLE		ENDS
     7                              <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE
     8                              <2> ; (no prior section) ; DOSCODECODE		ENDS
     9                              <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE
    10                              <2> section BIOCODE	align=2 PUBLIC class=DOSCODE
    11                              <2> 
    12                              <2> %ifnidni DOSENTRYGROUP, DOSCODEGROUP
    13                              <2>  group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE
    14                              <2> %endif
    15                              <2> 
    16                              <2> %endif
    10                              <1> 
    11                              <1> section LAST
    12                              <1> ; (no prior section) ; LAST		ENDS
    20                                  
    21                                  [list +]
    22                                  section DOSCODECODE
    23                                  [list -]
    23          ******************       warning: out: ... for DOS Version 4.00 ... [-w+user]
    23          ******************       warning: out: BPB.INC... [-w+user]
    23          ******************       warning: out: ... CLONE version build switch on ... [-w+user]
    23          ******************       warning: out: DEVSYM.INC... [-w+user]
    23          ******************       warning: out: ... CLONE version build switch on ... [-w+user]
    31                                  
    32                                  %iassign Installed TRUE
    33                                  
    34                                  	i_need	THISSFT,DWORD
    35                                  	i_need	DMAADD,DWORD
    36                                  	i_need	SecClusPos,BYTE
    37                                  	i_need	ClusNum,WORD
    38                                  	i_need	Trans,BYTE
    39                                  	i_need	BytPos,4
    40                                  	i_need	SecPos,DWORD		  ;F.C. >32mb	;AN000;
    41                                  	i_need	BytSecPos,WORD
    42                                  	i_need	BytCnt1,WORD
    43                                  	i_need	BytCnt2,WORD
    44                                  	i_need	SecCnt_DOS,WORD
    45                                  	i_need	ThisDPB,DWORD
    46                                  	i_need	LastPos,WORD
    47                                  	i_need	ValSec,WORD		  ;F.C. >32mb	       ;AN000;
    48                                  	i_need	GrowCnt,DWORD
    49                                  	i_need	ALLOWED,BYTE
    50                                  	I_need	JShare,DWORD
    51                                  	I_need	FSeek_drive,BYTE	  ; DOS 4.00	       ;AN000;
    52                                  	I_need	FSeek_firclus,WORD	  ; DOS 4.00	       ;AN000;
    53                                  	I_need	FSeek_logclus,WORD	  ; DOS 4.00	       ;AN000;
    54                                  	I_need	HIGH_SECTOR,WORD	  ;F.C. >32mb	       ;AN000;
    55                                  	I_need	HIGH_SECTOR_TEMP,WORD	  ;F.C. >32mb	       ;AN000;
    56                                  	I_need	EXTERR,WORD			   ; DOS 4.00   ;AN000;
    57                                  	I_need	EXTERR_LOCUS,BYTE		   ; DOS 4.00   ;AN000;
    58                                  	I_need	EXTERR_ACTION,BYTE		   ; DOS 4.00   ;AN000;
    59                                  	I_need	EXTERR_CLASS,BYTE		   ; DOS 4.00   ;AN000;
    60                                  	I_need	EXITHOLD,DWORD			   ; DOS 4.00   ;AN000;
    61                                  	I_need	DISK_FULL,BYTE			   ; DOS 4.00   ;AN000;
    62                                  	I_need	SC_DRIVE,BYTE			   ; DOS 4.00   ;AN000;
    63                                  	I_need	SC_CACHE_COUNT,WORD		   ; DOS 4.00   ;AN000;
    64                                  	I_need	ThisDRV,BYTE			   ; DOS 4.00   ;AN000;
    65                                  	I_need	User_In_AX,WORD 		   ; DOS 4.00   ;AN000;
    66                                  	I_need	DOS34_FLAG,WORD 		   ; DOS 4.00   ;AN000;
    67                                  	I_need	FIRST_BUFF_ADDR,WORD		   ; DOS 4.00   ;AN000;
    68                                  
    69                                  %ifndef BUF2
    70                                  %IF	BUFFERFLAG
    71                                  	EXTRN	SAVE_MAP:NEAR
    72                                  	EXTRN	RESTORE_MAP:NEAR
    73                                  	EXTRN	SAVE_USER_MAP:NEAR
    74                                  	EXTRN	RESTORE_USER_MAP:NEAR
    75                                  	i_need	BUF_EMS_SAFE_FLAG,BYTE
    76                                  	i_need	BUF_EMS_MODE,BYTE
    77                                  %ENDIF
    78                                  %else
    79                                  	i_need	BUFFHEAD,dword
    80                                  %endif
    81                                  	
    82                                  
    83                                   assume nocheck, ss:DOSGROUP
    84                                  
    85                                  Break	<DISKWRITE -- PERFORM USER DISK WRITE>
    86                                  
    87                                  ; Inputs:
    88                                  ;	Outputs of SETUP
    89                                  ; Function:
    90                                  ;	Perform disk write
    91                                  ; Outputs:
    92                                  ;    Carry clear
    93                                  ;	CX = No. of bytes read
    94                                  ;	ES:DI point to SFT
    95                                  ;	SFT offset and cluster pointers updated
    96                                  ;    Carry set
    97                                  ;	CX = 0
    98                                  ;	ES:DI point to SFT
    99                                  ;	AX has error code
   100                                  
   101                                  	procedure   DISKWRITE,NEAR
   101          ******************       warning: proc DISKWRITE... [-w+user]
   102                                  	DOSAssume   CS,<DS>,"DiskWrite"
   103                                  	ASSUME	ES:NOTHING
   104                                  
   105                                  	Assert	ISSFT,<ES,DI>,"DiskWrite"
   106 00000000 26FF750B                	PUSH	word [ES:DI + sf_firclus]	  ; set up 1st cluster # for FastSeek
   107 00000004 8F06[0000]              	POP	word [FSeek_firclus]
   108                                  
   109 00000008 E8(0000)                	invoke	CHECK_WRITE_LOCK	  ;IFS. check write lock		 ;AN000;
   110 0000000B 7304                    	JNC	WRITE_OK		  ;IFS. lock check ok			 ;AN000;
   111 0000000D C3                      	return
   112                                  
   113                                  WRTEOFJ:
   114 0000000E E94802                  	JMP	WRTEOF
   115                                  
   116                                  WRITE_OK:
   117 00000011 26816505BFBF            	AND	word [ES:DI + sf_flags],~ (sf_close_nodate | devid_file_clean)
   118                                  				; Mark file as dirty, clear no date on close
   119                                  THISDPB equ ThisDPB	; NASM port label
   120 00000017 C42E[0000]              	LES	BP,[THISDPB]
   121                                  	Assert	ISDPB,<ES,BP>,"DiskWrite/WriteOk"
   122 0000001B 268A4600                	MOV	AL,[ES:BP + dpb_drive]   ; set up drive # for FastSeek
   123 0000001F A2[0000]                	MOV	[FSeek_drive],AL       ; 11/5/86 DOS 4.00
   124                                  
   125 00000022 E8(0000)                	invoke	BREAKDOWN
   126                                  BYTPOS equ BytPos	; NASM port label
   127 00000025 A1[0000]                	MOV	AX,WORD PTR [BYTPOS]
   128 00000028 8B16[0200]              	MOV	DX,WORD PTR [BYTPOS+2]
   129 0000002C E3E0                    	JCXZ	WRTEOFJ 		;Make the file length = sf_position
   130 0000002E 01C8                    	ADD	AX,CX
   131 00000030 83D200                  	ADC	DX,0			; AX:DX=byte after last byte accessed
   132                                  ;
   133                                  ; Make sure divide won't overflow
   134                                  ;
   135 00000033 268B5E02                	MOV	BX,[ES:BP + dpb_sector_size]
   136                                  ;	CMP	DX,BX			;F.C. >32mb  16 bit sector check	;AN000;
   137                                  ;	JAE	WrtErr			;F.C. >32mb				;AN000;
   138                                  
   139 00000037 E8C002                  	CALL	DIV32			;F.C. perform 32 bit divide		;AN000;
   140 0000003A 89C3                    	MOV	BX,AX			; Save last full sector
   141 0000003C 09D2                    	OR	DX,DX
   142 0000003E 7508                    	JNZ	CALCLUS
   143 00000040 83E801                  	SUB	AX,1			; AX must be zero base indexed		;AC000;
   144 00000043 831E[0000]00            	SBB	word [HIGH_SECTOR],0 	;F.C. >32mb				;AN000;
   145                                  CALCLUS:
   146 00000048 FF36[0000]              	PUSH	word [HIGH_SECTOR]		;F.C. >32mb				;AN000;
   147 0000004C E8BA02                  	CALL	SHR32			;F.C. >32mb				;AN000;
   148 0000004F 390E[0000]              	cmp word [HIGH_SECTOR], cx
   149 00000053 8F06[0000]              	POP	word [HIGH_SECTOR]		;F.C. >32mb				;AN000;
   150 00000057 7408                    	je .16bit
   151 00000059 C606[0000]01            	mov byte [DISK_FULL], 1
   152 0000005E E9A100                  	jmp WRTERR
   153                                  .16bit:
   154                                  
   155                                  ;	SHR	AX,CL			; Last cluster to be accessed
   156 00000061 50                      	PUSH	AX
   157 00000062 52                      	PUSH	DX			; Save the size of the "tail"
   158 00000063 06                      	PUSH	ES
   159 00000064 C43E[0000]              	LES	DI,[THISSFT]
   160                                   assume es:nothing
   161                                  	Assert	ISSFT,<ES,DI>,"DiskWrite/CalClus"
   162 00000068 268B4511                	MOV	AX,WORD PTR [ES:DI + sf_size]
   163 0000006C 268B5513                	MOV	DX,WORD PTR [ES:DI + sf_size+2]
   164 00000070 07                      	POP	ES
   165                                   assume es:DPB
   166                                  
   167                                  
   168 00000071 50                      	PUSH	AX			;F.C. >32mb				;AN000;
   169 00000072 89D0                    	MOV	AX,DX			;F.C. >32mb				;AN000;
   170 00000074 31D2                    	XOR	DX,DX			;F.C. >32mb				;AN000;
   171 00000076 26F77602                	DIV	word [ES:BP + dpb_sector_size] ;F.C. >32mb				;AN000;
   172 0000007A A3[0000]                	MOV	[HIGH_SECTOR_TEMP],AX	;F.C. >32mb				;AN000;
   173 0000007D 58                      	POP	AX			;F.C. >32mb				;AN000;
   174                                  
   175 0000007E 26F77602                	DIV	word [ES:BP + dpb_sector_size]
   176 00000082 89C1                    	MOV	CX,AX		; Save last full sector of current file
   177 00000084 09D2                    	OR	DX,DX
   178 00000086 7408                    	JZ	NORNDUP
   179 00000088 83C001                  	ADD	AX,1		; Round up if any remainder			;AC000;
   180 0000008B 8316[0000]00            	ADC	word [HIGH_SECTOR_TEMP],0	;F.C. >32mb				;AN000;
   181                                  NORNDUP:
   182 00000090 FF36[0000]              	PUSH	word [HIGH_SECTOR_TEMP]	;F.C. >32mb				;AN000;
   183                                  VALSEC equ ValSec	; NASM port label
   184 00000094 8F06[0200]              	POP	WORD PTR [VALSEC+2]	;F.C. >32mb				;AN000;
   185 00000098 A3[0000]                	MOV	WORD PTR [VALSEC],AX  ;Number of sectors that have been written
   186 0000009B 31C0                    	XOR	AX,AX
   187                                  GROWCNT equ GrowCnt	; NASM port label
   188 0000009D A3[0000]                	MOV	WORD PTR [GROWCNT],AX
   189 000000A0 A3[0200]                	MOV	WORD PTR [GROWCNT+2],AX
   190 000000A3 58                      	POP	AX
   191                                  
   192 000000A4 8B3E[0000]              	MOV	DI,[HIGH_SECTOR]	;F.C. >32mb				;AN000;
   193 000000A8 3B3E[0000]              	CMP	DI,[HIGH_SECTOR_TEMP]	;F.C. >32mb				;AN000;
   194 000000AC 7277                    	JB	NOGROW			;F.C. >32mb				;AN000;
   195 000000AE 7409                    	JZ	lowsec			;F.C. >32mb				;AN000;
   196 000000B0 29CB                    	SUB	BX,CX			;F.C. >32mb				;AN000;
   197 000000B2 1B3E[0000]              	SBB	DI,[HIGH_SECTOR_TEMP]	;F.C. >32mb di:bx no. of sectors	;AN000;
   198 000000B6 EB0A                    	JMP	yesgrow 		;F.C. >32mb				;AN000;
   199 000000B8 90                      	nop	; identicalise
   200                                  lowsec:
   201 000000B9 BF0000                  	MOV	DI,0		;F.C. >32mb
   202 000000BC 29CB                    	SUB	BX,CX		; Number of full sectors
   203 000000BE 7265                    	JB	NOGROW
   204 000000C0 7456                    	JZ	TESTTAIL
   205                                  yesgrow:
   206 000000C2 89D1                    	MOV	CX,DX
   207 000000C4 93                      	XCHG	AX,BX
   208 000000C5 26F76602                	MUL	word [ES:BP + dpb_sector_size]  ; Bytes of full sector growth
   209 000000C9 8916[0000]              	MOV	[HIGH_SECTOR],DX	 ;F.C. >32mb save dx			;AN000;
   210 000000CD A3[0000]                	MOV	[HIGH_SECTOR_TEMP],AX	 ;F.C. >32mb save ax			;AN000;
   211 000000D0 89F8                    	MOV	AX,DI			 ;F.C. >32mb				;AN000;
   212 000000D2 26F76602                	MUL	word [ES:BP + dpb_sector_size]  ;F.C. >32mb do higher word multiply	;AN000;
   213 000000D6 0306[0000]              	ADD	AX,[HIGH_SECTOR]	 ;F.C. >32mb add lower value		;AN000;
   214 000000DA 89C2                    	MOV	DX,AX			 ;F.C. >32mb DX:AX is the result of	;AN000;
   215 000000DC A1[0000]                	MOV	AX,[HIGH_SECTOR_TEMP]	 ;F.C. >32mb a 32 bit multiply		;AN000;
   216                                  
   217 000000DF 29C8                    	SUB	AX,CX		; Take off current "tail"
   218 000000E1 83DA00                  	SBB	DX,0		; 32-bit extension
   219 000000E4 01D8                    	ADD	AX,BX		; Add on new "tail"
   220 000000E6 83D200                  	ADC	DX,0		; ripple tim's head off
   221 000000E9 EB33                    	JMP	SHORT SETGRW
   222                                  HAVSTART:
   223                                  ;int 3
   224 000000EB 89C1                    	MOV	CX,AX
   225 000000ED E8(0000)                	invoke	SKPCLP
   226 000000F0 E320                    	JCXZ	DOWRTJ
   227                                  ;;; 11/5/86 FastSeek
   228 000000F2 8916[0000]              	MOV	[FSeek_logclus],DX   ; delete EOF (FFFFH)
   229 000000F6 FF06[0000]              	INC	word [FSeek_logclus]
   230 000000FA E8(0000)                	invoke	FastSeek_Truncate    ;
   231                                  ;;; 11/5/86 FastSeek
   232 000000FD E8(0000)                	invoke	ALLOCATE
   233 00000100 7310                    	JNC	DOWRTJ
   234                                  
   235                                  	entry	WRTERR
   236                                  	DOSAssume   CS,<DS>,"DiskWrite/WrtErr"
   237                                  	ASSUME	ES:NOTHING
   238                                  
   239 00000102 B40F                    	MOV	AH,0FH				;MS. write/data/fail/abort	;AN000;
   240                                   entry WRTERR22
   241                                  THISDRV equ ThisDRV	; NASM port label
   242 00000104 A0[0000]                	MOV	AL,[THISDRV]			;MS.				;AN000;
   243 00000107 E81102                  	CALL	File_Handle_Fail_Error	;MS. issue disk full I24
   244 0000010A B90000                  	MOV	CX,0			;No bytes transferred
   245                                  ;	XOR	CX,CX			; will be deleted
   246 0000010D C43E[0000]              	LES	DI,[THISSFT]
   247                                  	Assert	ISSFT,<ES,DI>,"DiskWrite/WrtErr"
   248                                  ;	CLC
   249 00000111 C3                      	return
   250                                  
   251 00000112 EB66                    DOWRTJ: JMP	DOWRT
   252 00000114 90                      	nop	; identicalise
   253                                  
   254                                  ACC_ERRWJ:
   255 00000115 E93E01                  	JMP	SET_ACC_ERRW
   256                                  
   257                                  TESTTAIL:
   258 00000118 29D0                    	SUB	AX,DX
   259 0000011A 7609                    	JBE	NOGROW
   260 0000011C 31D2                    	XOR	DX,DX
   261                                  SETGRW:
   262 0000011E A3[0000]                	MOV	WORD PTR [GROWCNT],AX
   263 00000121 8916[0200]              	MOV	WORD PTR [GROWCNT+2],DX
   264                                  NOGROW:
   265 00000125 58                      	POP	AX
   266                                  CLUSNUM equ ClusNum	; NASM port label
   267 00000126 8B0E[0000]              	MOV	CX,[CLUSNUM]	; First cluster accessed
   268 0000012A E8(0000)                	invoke	FNDCLUS
   269 0000012D 72E6                    	JC	ACC_ERRWJ
   270 0000012F 891E[0000]              	MOV	[CLUSNUM],BX
   271                                  LASTPOS equ LastPos	; NASM port label
   272 00000133 8916[0000]              	MOV	[LASTPOS],DX
   273                                  ;;; 11/5/86 FastSeek
   274 00000137 A3[0000]                	MOV	[FSeek_logclus],AX    ; set up last position
   275 0000013A 29D0                    	SUB	AX,DX		; Last cluster minus current cluster
   276 0000013C 743C                    	JZ	DOWRT		; If we have last clus, we must have first
   277 0000013E E3AB                    	JCXZ	HAVSTART	; See if no more data
   278 00000140 51                      	PUSH	CX		; No. of clusters short of first
   279 00000141 89C1                    	MOV	CX,AX
   280                                  
   281                                  ;;; 11/5/86 FastSeek
   282 00000143 833E[0000]00            	CMP	word [CLUSNUM],0	      ;FS. null file				;AN000;
   283 00000148 740B                    	JZ	NULL_FILE	      ;FS. yes					;AN000;
   284 0000014A 8916[0000]              	MOV	[FSeek_logclus],DX    ;FS. delete EOF (FFFFH)			;AN000;
   285 0000014E FF06[0000]              	INC	word [FSeek_logclus]       ;FS.					;AN000;
   286 00000152 E8(0000)                	invoke	FastSeek_Truncate     ;FS.					;AN000;
   287                                  NULL_FILE:
   288                                  ;;; 11/5/86 FastSeek
   289 00000155 E8(0000)                	invoke	ALLOCATE
   290 00000158 58                      	POP	AX
   291 00000159 72A7                    	JC	WRTERR
   292 0000015B 89C1                    	MOV	CX,AX
   293 0000015D 8B16[0000]              	MOV	DX,[LASTPOS]
   294 00000161 42                      	INC	DX
   295 00000162 49                      	DEC	CX
   296 00000163 740D                    	JZ	NOSKIP
   297                                  ;;; 11/5/86 FastSeek
   298 00000165 8916[0000]              	MOV	[FSeek_logclus],DX    ;
   299 00000169 010E[0000]              	ADD	[FSeek_logclus],CX    ; set up last position
   300 0000016D E8(0000)                	invoke	SKPCLP
   301 00000170 72A3                    	JC	ACC_ERRWJ
   302                                  NOSKIP:
   303 00000172 891E[0000]              	MOV	[CLUSNUM],BX
   304 00000176 8916[0000]              	MOV	[LASTPOS],DX
   305                                  DOWRT:
   306                                  BYTCNT1 equ BytCnt1	; NASM port label
   307 0000017A 833E[0000]00            	CMP	word [BYTCNT1],0
   308 0000017F 7409                    	JZ	WRTMID
   309 00000181 8B1E[0000]              	MOV	BX,[CLUSNUM]
   310 00000185 E8(0000)                	invoke	BUFWRT
   311 00000188 728B                    	JC	ACC_ERRWJ
   312                                  WRTMID:
   313                                  SECCNT_DOS equ SecCnt_DOS	; NASM port label
   314 0000018A A1[0000]                	MOV	AX,[SECCNT_DOS]
   315 0000018D 09C0                    	OR	AX,AX
   316 0000018F 7503                    	JNZ	havemid
   317 00000191 E98500                  	JMP	WRTLAST
   318                                  havemid:
   319                                  SECPOS equ SecPos	; NASM port label
   320 00000194 0106[0000]              	ADD	WORD PTR [SECPOS],AX
   321 00000198 8316[0200]00            	ADC	WORD PTR [SECPOS+2],0	 ;F.C. >32mb				;AN000;
   322 0000019D E8(0000)                	invoke	NEXTSEC
   323 000001A0 7303                    	JNC	gotok
   324 000001A2 E970FF                  	JMP	ACC_ERRWJ
   325                                  gotok:
   326                                  TRANS equ Trans	; NASM port label
   327 000001A5 C606[0000]01            	MOV	BYTE PTR [TRANS],1	 ; A transfer is taking place
   328                                  SECCLUSPOS equ SecClusPos	; NASM port label
   329 000001AA 8A16[0000]              	MOV	DL,[SECCLUSPOS]
   330 000001AE 8B1E[0000]              	MOV	BX,[CLUSNUM]
   331 000001B2 8B0E[0000]              	MOV	CX,[SECCNT_DOS]
   332                                  WRTLP:
   333 000001B6 E8(0000)                	invoke	OPTIMIZE
   334 000001B9 7303                    	JNC	wokok
   335 000001BB E957FF                  	JMP	ACC_ERRWJ
   336                                  wokok:
   337 000001BE 57                      	PUSH	DI
   338 000001BF 50                      	PUSH	AX
   339 000001C0 52                      	PUSH	DX
   340 000001C1 53                      	PUSH	BX
   341                                  	Assert	ISDPB,<ES,BP>,"DiskWrite/WrtLp"
   342 000001C2 268A4600                	MOV	AL,[ES:BP + dpb_drive]
   343 000001C6 A2[0000]                	MOV	[SC_DRIVE],AL		  ;LB. save it for INVALIDATE_SC	;AN000;
   344 000001C9 51                      	PUSH	CX			  ;LB.					;AN000;
   345 000001CA FF36[0000]              	PUSH	word [HIGH_SECTOR]		  ;LB.					;AN000;
   346                                  %ifndef BUF2
   347                                  SCANNEXT:				  ;LB.					;AN000;
   348                                  	invoke	GETCURHEAD		  ;LB.					;AN000;
   349                                  %else
   350 000001CE 36C53E[0000]            	lds di, [ss:BUFFHEAD]
   351                                  %endif
   352                                  ASSUME	DS:NOTHING
   353                                  NEXTBUFF:			; Search for buffers
   354                                  %ifndef BUF2
   355                                  	CMP	word [ss:SC_CACHE_COUNT],0	    ;LB. SC support ?			;AN000;
   356                                  	JZ	nosc			    ;LB. no				;AN000;
   357                                  	PUSH	AX			    ;LB. save reg			;AN000;
   358                                  	PUSH	CX			    ;LB. save reg			;AN000;
   359                                  	PUSH	DX			    ;LB. save reg			;AN000;
   360                                  	invoke	INVALIDATE_SC		    ;LB. invalidate SC			;AN000;
   361                                  	POP	DX			    ;LB. save reg			;AN000;
   362                                  	POP	CX			    ;LB. save reg			;AN000;
   363                                  	POP	AX			    ;LB. save reg			;AN000;
   364                                  nosc:
   365                                  %endif
   366 000001D3 E8BC01                  	CALL	BUFF_RANGE_CHECK	    ;F.C. >32mb 			;AN000;
   367 000001D6 7305                    	JNC	inrange2		    ;F.C. >32mb 			;AN000;
   368                                  %ifdef BUF2
   369 000001D8 C53D                    	lds di, [di + NEXTBUF]
   370                                  %else
   371                                  	mov	DI,[DI + buf_next]	    ;LB. get next buffer 1/19/88	;AN000;
   372                                  %endif
   373 000001DA EB12                    	JMP	DONEXTBUFF		    ;LB.				;AN000;
   374 000001DC 90                      	nop	; identicalise
   375                                  inrange2:
   376 000001DD F6450540                	TEST	byte [DI + buf_flags],buf_dirty    ;LB. if dirty			;AN000;
   377 000001E1 7403                    	JZ	not_dirty		    ;LB.				;AN000;
   378 000001E3 E8(0000)                	invoke	DEC_DIRTY_COUNT 	    ;LB. then decrement dirty count	;AN000;
   379                                  not_dirty:
   380                                  %ifdef BUF2
   381 000001E6 C74504FF00              	MOV	WORD PTR [DI + BUFDRV], 00FFH
   382                                  					; Free the buffer, it is being over written
   383                                  %else
   384                                  	MOV	WORD PTR [DI + buf_ID], 00FFH	  ; Free the buffer, it is being over written
   385                                  %endif
   386 000001EB E8(0000)                	invoke	SCANPLACE
   387                                  DONEXTBUFF:
   388                                  %ifdef BUF2
   389 000001EE 83FFFF                  	cmp di, -1
   390                                  %else
   391                                  	CMP	DI,[ss:FIRST_BUFF_ADDR]	  ;LB. end of chain			;AN000;
   392                                  %endif
   393 000001F1 75E0                    	JNZ	NEXTBUFF		  ;LB. no				;AN000;
   394                                  %ifndef BUF2
   395                                  	ADD	DX,1			  ;LB. next sector number		;AN000;
   396                                  	ADC	word [ss:HIGH_SECTOR],0 	  ;LB.					;AN000;
   397                                  	LOOP	SCANNEXT		  ;LB. check again			;AN000;
   398                                  %endif
   399 000001F3 368F06[0000]            	POP	word [ss:HIGH_SECTOR]		  ;LB.					;AN000;
   400 000001F8 59                      	POP	CX			  ;LB. get count back			;AN000;
   401                                  
   402 000001F9 5B                      	POP	BX
   403 000001FA 5A                      	POP	DX
   404 000001FB 368E1E[0200]            	MOV	DS,WORD PTR [ss:DMAADD+2]
   405                                   assume ds:nothing
   406                                  allowed_RETRY equ Allowed_RETRY	; NASM port equate
   407                                  allowed_FAIL equ Allowed_FAIL	; NASM port equate
   408                                  allowed_IGNORE equ Allowed_IGNORE	; NASM port equate
   409 00000200 36C606[0000]38          	MOV	byte [ss:ALLOWED],allowed_RETRY + allowed_FAIL + allowed_IGNORE
   410                                  
   411                                  %ifndef BUF2
   412                                  %IF	BUFFERFLAG
   413                                  	pushf
   414                                  	cmp	byte [ss:BUF_EMS_MODE], -1
   415                                  	je	safe_write	
   416                                  save_map equ SAVE_MAP	; NASM port label
   417                                  	call	save_map
   418                                  restore_user_map equ RESTORE_USER_MAP	; NASM port label
   419                                  	call	restore_user_map
   420                                  safe_write:
   421                                  	popf
   422                                  %ENDIF	
   423                                  %endif
   424                                  
   425 00000206 E8(0000)                	invoke	DWRITE
   426                                  
   427                                  %ifndef BUF2
   428                                  %IF	BUFFERFLAG
   429                                  	pushf
   430                                  	cmp	byte [ss:BUF_EMS_MODE], -1
   431                                  	je	safe_map	
   432                                  save_user_map equ SAVE_USER_MAP	; NASM port label
   433                                  	call	save_user_map
   434                                  restore_map equ RESTORE_MAP	; NASM port label
   435                                  	call	restore_map
   436                                  safe_map:
   437                                  	popf
   438                                  %ENDIF
   439                                  %endif
   440                                  
   441 00000209 59                      	POP	CX
   442 0000020A 5B                      	POP	BX
   443 0000020B 161F                    	Context DS
   444 0000020D 7247                    	JC	SET_ACC_ERRW
   445 0000020F E308                    	JCXZ	WRTLAST
   446 00000211 B200                    	MOV	DL,0
   447 00000213 FF06[0000]              	INC	word [LASTPOS]	; We'll be using next cluster
   448 00000217 EB9D                    	JMP	WRTLP
   449                                  
   450                                  WRTLAST:
   451                                  BYTCNT2 equ BytCnt2	; NASM port label
   452 00000219 A1[0000]                	MOV	AX,[BYTCNT2]
   453 0000021C 09C0                    	OR	AX,AX
   454 0000021E 7413                    	JZ	FINWRT
   455 00000220 A3[0000]                	MOV	[BYTCNT1],AX
   456 00000223 E8(0000)                	invoke	NEXTSEC
   457 00000226 722E                    	JC	SET_ACC_ERRW
   458                                  BYTSECPOS equ BytSecPos	; NASM port label
   459 00000228 C706[0000]0000          	MOV	word [BYTSECPOS],0
   460 0000022E E8(0000)                	invoke	BUFWRT
   461 00000231 7223                    	JC	SET_ACC_ERRW
   462                                  FINWRT:
   463 00000233 C43E[0000]              	LES	DI,[THISSFT]
   464                                  	Assert	ISSFT,<ES,DI>,"DiskWrite/FinWrt"
   465 00000237 A1[0000]                	MOV	AX,WORD PTR [GROWCNT]
   466 0000023A 8B0E[0200]              	MOV	CX,WORD PTR [GROWCNT+2]
   467 0000023E 09C0                    	OR	AX,AX
   468                                  UPDATE_size equ Update_size	; NASM port label
   469 00000240 7502                    	JNZ	UPDATE_size
   470 00000242 E30F                    	JCXZ	SAMSIZ
   471                                  Update_size:
   472 00000244 26014511                	ADD	WORD PTR [ES:DI + sf_size],AX
   473 00000248 26114D13                	ADC	WORD PTR [ES:DI + sf_size+2],CX
   474                                  ;
   475                                  ; Make sure that all other SFT's see this growth also.
   476                                  ;
   477 0000024C B80100                  	MOV	AX,1
   478                                  %if installed
   479 0000024F FF1E[3800]              	call	far [JShare + 14 * 4]
   480                                  %else
   481                                  	Call	ShSU
   482                                  %endif
   483                                  SAMSIZ:
   484 00000253 E9(0000)                	transfer SETCLUS		  ; ES:DI already points to SFT
   485                                  
   486                                  SET_ACC_ERRW:
   487 00000256 E9(0000)                	transfer SET_ACC_ERR_DS
   488                                  
   489                                  WRTEOF:
   490 00000259 89C1                    	MOV	CX,AX
   491 0000025B 09D1                    	OR	CX,DX
   492 0000025D 7460                    	JZ	KILLFIL
   493 0000025F 83E801                  	SUB	AX,1
   494 00000262 83DA00                  	SBB	DX,0
   495                                  
   496 00000265 53                      	PUSH	BX
   497 00000266 268B5E02                	MOV	BX,[ES:BP + dpb_sector_size]    ;F.C. >32mb			;AN000;
   498 0000026A E88D00                  	CALL	DIV32			      ;F.C. >32mb			;AN000;
   499 0000026D 5B                      	POP	BX			      ;F.C. >32mb			;AN000;
   500 0000026E E89800                  	CALL	SHR32			      ;F.C. >32mb			;AN000;
   501                                  
   502 00000271 390E[0000]              	cmp word [HIGH_SECTOR], cx
   503 00000275 7408                    	je .16bit
   504 00000277 C606[0000]01            	mov byte [DISK_FULL], 1
   505 0000027C E983FE                  	jmp WRTERR
   506                                  .16bit:
   507                                  
   508                                  ;	SHR	AX,CL
   509 0000027F 89C1                    	MOV	CX,AX
   510 00000281 E8(0000)                	invoke	FNDCLUS
   511                                  SET_ACC_ERRWJ2:
   512 00000284 72D0                    	JC	SET_ACC_ERRW
   513                                  ;;; 11/5/86 FastSeek
   514 00000286 8916[0000]              	MOV	[FSeek_logclus],DX    ; truncate clusters starting from DX
   515 0000028A E8(0000)                	invoke	FastSeek_Truncate
   516                                  ;;; 11/5/86 FastSeek
   517 0000028D E326                    	JCXZ	RELFILE
   518 0000028F E8(0000)                	invoke	ALLOCATE
   519 00000292 721E                    	JC	WRTERRJ 	     ;;;;;;;;; disk full
   520                                  UPDATE:
   521 00000294 C43E[0000]              	LES	DI,[THISSFT]
   522                                  	Assert	ISSFT,<ES,DI>,"DiskWrite/update"
   523 00000298 A1[0000]                	MOV	AX,WORD PTR [BYTPOS]
   524 0000029B 26894511                	MOV	WORD PTR [ES:DI + sf_size],AX
   525 0000029F A1[0200]                	MOV	AX,WORD PTR [BYTPOS+2]
   526 000002A2 26894513                	MOV	WORD PTR [ES:DI + sf_size+2],AX
   527                                  ;
   528                                  ; Make sure that all other SFT's see this growth also.
   529                                  ;
   530 000002A6 B80200                  	MOV	AX,2
   531                                  %if installed
   532 000002A9 FF1E[3800]              	Call	far [JShare + 14 * 4]
   533                                  %else
   534                                  	Call	ShSU
   535                                  %endif
   536 000002AD 31C9                    	XOR	CX,CX
   537 000002AF E9(0000)                	transfer ADDREC
   538                                  
   539 000002B2 E94DFE                  WRTERRJ: JMP	 WRTERR
   540                                  ;;;;;;;;;;;;;;;; 7/18/86
   541                                  ;;;;;;;;;;;;;;;;;
   542                                  RELFILE:
   543 000002B5 BAFFFF                  	MOV	DX,0FFFFH
   544 000002B8 E8(0000)                	invoke	RELBLKS
   545                                  Set_Acc_ERRWJJ:
   546 000002BB 72C7                    	JC	SET_ACC_ERRWJ2
   547 000002BD EBD5                    	JMP	SHORT UPDATE
   548                                  
   549                                  KILLFIL:
   550 000002BF 31DB                    	XOR	BX,BX
   551 000002C1 06                      	PUSH	ES
   552 000002C2 C43E[0000]              	LES	DI,[THISSFT]
   553                                   assume es:nothing
   554                                  	Assert	ISSFT,<ES,DI>,"DiskWrite/KillFil"
   555 000002C6 26895D19                	MOV	[ES:DI + sf_cluspos],BX
   556 000002CA 26895D35                	MOV	[ES:DI + sf_lstclus],BX
   557 000002CE 26875D0B                	XCHG	BX,[ES:DI + sf_firclus]
   558 000002D2 07                      	POP	ES
   559                                   assume es:nothing
   560                                  ;; 11/5/86 FastSeek
   561 000002D3 E8(0000)                	invoke	Delete_FSeek   ; delete fastseek entry
   562                                  
   563 000002D6 09DB                    	OR	BX,BX
   564                                  UPDATEJ equ UpDateJ	; NASM port label
   565 000002D8 741E                    	JZ	UPDATEJ
   566                                  ;; 10/23/86 FastOpen update
   567 000002DA 06                      	PUSH	ES		; since first cluster # is 0
   568 000002DB 55                      	PUSH	BP		; we must delete the old cache entry
   569 000002DC 50                      	PUSH	AX
   570 000002DD 51                      	PUSH	CX
   571 000002DE 52                      	PUSH	DX
   572 000002DF C42E[0000]              	LES	BP,[THISDPB]		 ; get current DPB
   573                                   assume es:DPB
   574 000002E3 268A5600                	MOV	DL,[ES:BP + dpb_drive]	 ; get current drive
   575 000002E7 89D9                    	MOV	CX,BX			 ; first cluster #
   576 000002E9 B402                    	MOV	AH,2			 ; delete cache entry by drive:firclus
   577 000002EB E8(0000)                	invoke	FastOpen_Update 	 ; call fastopen
   578 000002EE 5A                      	POP	DX
   579 000002EF 59                      	POP	CX
   580 000002F0 58                      	POP	AX
   581 000002F1 5D                      	POP	BP
   582 000002F2 07                      	POP	ES
   583                                   assume es:nothing
   584                                  ;; 10/23/86 FastOpen update
   585                                  
   586 000002F3 E8(0000)                	invoke	RELEASE
   587                                  SET_ACC_ERRWJJ equ Set_Acc_ERRWJJ	; NASM port label
   588 000002F6 72C3                    	JC	SET_ACC_ERRWJJ
   589                                  UpDateJ:
   590 000002F8 EB9A                    	JMP	UPDATE
   591                                  EndProc DISKWRITE
   592                                  
   593                                  
   594                                  
   595                                  Break	<DIV32 -- PERFORM 32 BIT DIVIDE>
   596                                  
   597                                  ; Inputs:
   598                                  ;	DX:AX = 32 bit dividend   BX= divisor
   599                                  ; Function:
   600                                  ;	Perform 32 bit division
   601                                  ; Outputs:
   602                                  ;	[HIGH_SECTOR]:AX = quotiend , DX= remainder
   603                                  
   604                                  	procedure   DIV32,NEAR
   604          ******************       warning: proc DIV32... [-w+user]
   605                                  	ASSUME	DS:NOTHING,ES:NOTHING
   606                                  
   607                                  
   608 000002FA 50                      	PUSH	AX			;F.C. >32mb				;AN000;
   609 000002FB 89D0                    	MOV	AX,DX			;F.C. >32mb				;AN000;
   610 000002FD 31D2                    	XOR	DX,DX			;F.C. >32mb				;AN000;
   611 000002FF F7F3                    	DIV	BX			;F.C. >32mb				;AN000;
   612 00000301 36A3[0000]              	MOV	[ss:HIGH_SECTOR],AX	;F.C. >32mb				;AN000;
   613 00000305 58                      	POP	AX			;F.C. >32mb				;AN000;
   614                                  
   615                                  
   616 00000306 F7F3                    	DIV	BX			; AX=last sector accessed
   617 00000308 C3                      	return
   618                                  
   619                                  EndProc DIV32
   620                                  
   621                                  Break	<SHR32 -- PERFORM 32 BIT SHIFT RIGHT>
   622                                  
   623                                  ; Inputs:
   624                                  ;	[HIGH_SECTOR]:AX = 32 bit sector number
   625                                  ; Function:
   626                                  ;	Perform 32 bit shift right
   627                                  ; Outputs:
   628                                  ;	AX= cluster number
   629                                  
   630                                  	procedure   SHR32,NEAR
   630          ******************       warning: proc SHR32... [-w+user]
   631                                  	ASSUME	DS:NOTHING,ES:NOTHING
   632                                  
   633 00000309 31C9                    	xor cx, cx
   634 0000030B 268A4E05                	MOV	CL,[ES:BP + dpb_cluster_shift]
   635                                  entry ROTASHFT				;F.C. >32mb				;AN000;
   636 0000030F E309                    	jcxz	norota			;F.C. >32mb				;AN000;
   637                                  ROTASHFT2:
   638 00000311 36D12E[0000]            	shr	word [ss:HIGH_SECTOR],1 	;F.C. >32mb				;AN000;
   639 00000316 D1D8                    	RCR	AX,1			;F.C. >32mb				;AN000;
   640 00000318 E2F7                    	LOOP	ROTASHFT2		;F.C. >32mb:				;AN000;
   641                                  norota:
   642 0000031A C3                      	return
   643                                  
   644                                  EndProc SHR32
   645                                  
   646                                  
   647                                  ; Issue File Handle Fail INT 24 Critical Error
   648                                  ; Input: Disk_Full=0  ok
   649                                  ;		   1  disk full or EOF
   650                                  ; Function: issue critical error for disk full or EOF error
   651                                  ;
   652                                  ; OutPut: carry clear , no I24
   653                                  ;	  carry set, fail from I24
   654                                  
   655                                  procedure File_Handle_Fail_Error,NEAR						;AN000;
   655          ******************       warning: proc File_Handle_Fail_Error... [-w+user]
   656                                  	ASSUME	ES:NOTHING,DS:NOTHING						;AN000;
   657                                  										;AN000;
   658 0000031B 36803E[0000]00          	CMP	byte [ss:DISK_FULL],0	 ;MS. disk full or EOF				;AN000;
   659 00000321 746D                    	JZ	Fexit		 ;MS. no					;AN000;
   660 00000323 36F706[0000]4000        	TEST	word [ss:DOS34_FLAG],Disable_EOF_I24   ;MS. check input status ?	;AN000;
   661 0000032A 7564                    	JNZ	Fexit		 ;MS. yes					;AN000;
   662                                  										;AN000;
   663 0000032C 36C43E[0000]            	LES	DI,[ss:THISSFT]	 ;MS. get current SFT				;AN000;
   664                                  ;	LES	DI,[ES:DI.sf_DEVPTR];MS. get device header			;AN000;
   665 00000331 26F745050001            	TEST	word [ES:DI + sf_flags],Handle_Fail_I24  ;MS. gen I24 ?		;AN000;
   666 00000337 7457                    	JZ	Fexit		 ;MS. no					;AN000;
   667 00000339 1E                      	PUSH	DS		 ;MS. save DS					;AN000;
   668 0000033A F6C401                  	TEST	AH,1				;MS. READ ?			;AN000;
   669 0000033D 7409                    	JZ	readeof 			;MS. yes			;AN000;
   670                                  error_Handle_Disk_Full equ error_handle_Disk_Full	; NASM port equate
   671 0000033F 36C706[0000]2700        	MOV	word [ss:EXTERR],error_Handle_Disk_Full ;MS. set extended error 	;AN000;
   672 00000346 EB07                    	JMP	SHORT errset			;MS. set extended error 	;AN000;
   673                                  readeof:
   674                                  error_Handle_EOF equ error_handle_EOF	; NASM port equate
   675 00000348 36C706[0000]2600        	MOV	word [ss:EXTERR],error_Handle_EOF	;MS. set extended error 	;AN000;
   676                                  errset:
   677 0000034F 36C606[0000]01          	MOV	byte [ss:EXTERR_CLASS],errCLASS_OutRes	;MS. set class			;AN000;
   678 00000355 36C606[0000]04          	MOV	byte [ss:EXTERR_ACTION],errACT_Abort	;MS. set action 		;AN000;
   679 0000035B 36C606[0000]01          	MOV	byte [ss:EXTERR_LOCUS],errLOC_Unk	;MS. set locus			;AN000;
   680 00000361 368C06[0200]            	MOV	word ptr [ss:EXITHOLD + 2],ES	;MS. save es:bp in exithold	;AN000;
   681 00000366 36892E[0000]            	MOV	word ptr [ss:EXITHOLD],BP		;MS.				;AN000;
   682 0000036B 26F745058000            	TEST	word [ES:DI + sf_flags],devid_device	  ;MS. device  ?		;AN000;
   683 00000371 7509                    	JNZ	chardev2			  ;MS. yes			;AN000;
   684                                  sf_DEVPTR equ sf_devptr	; NASM port equate
   685 00000373 26C57507                	LDS	SI,[ES:DI + sf_DEVPTR]		  ;MS. get dpb			;AN000;
   686 00000377 C57413                  	LDS	SI,[SI + dpb_driver_addr] 	  ;MS. get drive device haeder	;AN000;
   687 0000037A EB04                    	JMP	SHORT doi24			  ;MS. gen I24 ?		;AN000;
   688                                  chardev2:
   689 0000037C 26C57507                	LDS	SI,[ES:DI + sf_DEVPTR]		  ;MS. get chr dev header	;AN000;
   690                                  doi24:
   691 00000380 8CDD                    	MOV	BP,DS				  ;MS. bp:si -> device header	;AN000;
   692 00000382 BF0C00                  	MOV	DI,error_I24_gen_failure	;MS. general error		;AN000;
   693 00000385 E8(0000)                	invoke	NET_I24_ENTRY			;MS. issue I24			;AN000;
   694 00000388 F9                      	STC					;MS. must be fail		;AN000;
   695 00000389 1F                      	POP	DS				;MS. restore DS 		;AN000;
   696                                   assume ds:nothing
   697 0000038A 36A1[0000]              	MOV	AX,[ss:EXTERR]			;MS. set error			;AN000;
   698 0000038E EB01                    	JMP	SHORT Fend			;MS. exit			;AN000;
   699                                  Fexit:										;AN000;
   700 00000390 F8                      	CLC					;MS. clear carry		;AN000;
   701                                  Fend:										;AN000;
   702 00000391 C3                      	return					;MS.				;AN000;
   703                                  										;AN000;
   704                                  EndProc File_Handle_Fail_Error							;AN000;
   705                                  
   706                                  
   707                                  Break	<BUFF_RANGE_CHECK- buffer range checkink>
   708                                  
   709                                  ; Inputs:
   710                                  ;	DS:DI -> buffer. AL= drive #
   711                                  ;	[HIGH_SECTOR]:DX = sector #
   712                                  ; Function:
   713                                  ;	check if sector is in the buffer
   714                                  ; Outputs:
   715                                  ;	carry clear= in the range
   716                                  ;	      set  = not in the range
   717                                  
   718                                  	procedure   BUFF_RANGE_CHECK,NEAR
   718          ******************       warning: proc BUFF_RANGE_CHECK... [-w+user]
   719                                  	ASSUME	DS:NOTHING,ES:NOTHING
   720                                  
   721 00000392 395508                  	CMP	WORD PTR [DI + buf_sector],DX					;AN000;
   722 00000395 750F                    	JNZ	DONEXTBUFF2	; not this sector	   ;F.C. >32mb		;AN000;
   723 00000397 368B36[0000]            	MOV	SI,[ss:HIGH_SECTOR]			   ;F.C. >32mb		;AN000;
   724 0000039C 39750A                  	CMP	WORD PTR [DI + buf_sector+2],SI		   ;F.C. >32mb		;AN000;
   725 0000039F 7505                    	JNZ	DONEXTBUFF2	; Not for this drive
   726 000003A1 3A4504                  	CMP	AL,[DI + buf_ID]
   727 000003A4 7401                    	JZ	secfound	; Buffer has the sector 			;AN000;
   728                                  DONEXTBUFF2:
   729 000003A6 F9                      	STC
   730                                  secfound:
   731 000003A7 C3                      	return
   732                                  
   733                                  EndProc BUFF_RANGE_CHECK
   734                                  
   735                                      END
   736                                  
   737                                  
