     1                                  ;	SCCSID = @(#)fat.asm	1.3 85/08/15
     2                                  ;	SCCSID = @(#)fat.asm	1.3 85/08/15
     3                                  ;TITLE	FAT - FAT maintenance routines
     4                                  ;NAME	FAT
     5                                  ; Low level local device routines for performing disk change sequence,
     6                                  ;   setting cluster validity, and manipulating the FAT
     7                                  ;
     8                                  ;   IsEof
     9                                  ;   UNPACK
    10                                  ;   PACK
    11                                  ;   MAPCLUSTER
    12                                  ;   FATREAD_SFT
    13                                  ;   FATREAD_CDS
    14                                  ;   FAT_operation
    15                                  ;
    16                                  ;   Revision history:
    17                                  ;
    18                                  ;   AN000  version Jan. 1988
    19                                  ;    A001  PTM	      -- disk changed for look ahead buffers
    20                                  ;
    21                                  
    22                                  ;
    23                                  ; get the appropriate segment definitions
    24                                  ;
    25                                  [list -]
    25          ******************       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
    27                                  
    28                                  [list +]
    29                                  section DOSCODECODE
    30                                  [list -]
    30          ******************       warning: out: ... for DOS Version 4.00 ... [-w+user]
    30          ******************       warning: out: BPB.INC... [-w+user]
    30          ******************       warning: out: ... CLONE version build switch on ... [-w+user]
    30          ******************       warning: out: DEVSYM.INC... [-w+user]
    37                                  
    38                                  FastDiv equ TRUE
    39                                  
    40                                  	i_need	CURBUF,DWORD
    41                                  	i_need	CLUSSPLIT,BYTE
    42                                  	i_need	CLUSSAVE,WORD
    43                                  	i_need	CLUSSEC,DWORD		;F.C. >32mb  ;AN000;
    44                                  	i_need	THISDRV,BYTE
    45                                  	i_need	THISDPB,DWORD
    46                                  	i_need	DEVCALL,BYTE
    47                                  	i_need	CALLMED,BYTE
    48                                  	i_need	CALLRBYT,BYTE
    49                                  	i_need	BUFFHEAD,DWORD
    50                                  	i_need	CALLXAD,DWORD
    51                                  	i_need	CALLBPB,DWORD
    52                                  	i_need	CDSADDR,DWORD
    53                                  	i_need	CDSCOUNT,BYTE
    54                                  	i_need	EXTERR,WORD
    55                                  	i_need	EXTERRPT,DWORD
    56                                  	i_need	CALLVIDM,DWORD
    57                                  	i_need	ReadOp,BYTE
    58                                  	i_need	FAILERR,BYTE
    59                                  	i_need	ALLOWED,BYTE
    60                                  	i_need	VOLCHNG_FLAG,BYTE
    61                                  	i_need	HIGH_SECTOR,WORD
    62                                  %ifdef BUF2
    63                                  	i_need	BUF2_Dirty_Count,WORD
    64                                  %else
    65                                  	i_need	BUF_HASH_COUNT,WORD
    66                                  	i_need	BUF_HASH_PTR,DWORD
    67                                  	i_need	FIRST_BUFF_ADDR,WORD
    68                                  	i_need	SC_CACHE_COUNT,WORD	       ;AN001;
    69                                  %endif
    70                                  	i_need	CURSC_DRIVE,BYTE	       ;AN001;
    71                                  
    72                                  
    73                                  Break <IsEOF - check the quantity in BX for EOF>
    74                                  
    75                                  ;
    76                                  ; IsEOF - check the fat value in BX for eof.
    77                                  ;
    78                                  ;   Inputs:	ES:BP point to DPB
    79                                  ;		BX has fat value
    80                                  ;   Outputs:	JAE eof
    81                                  ;   Registers modified: none
    82                                  Procedure IsEof,NEAR
    82          ******************       warning: proc IsEof... [-w+user]
    83                                  	ASSUME	SS:DOSGROUP,DS:NOTHING,ES:NOTHING
    84                                  	Assert	    ISDPB,<ES,BP>,"IsEOF"
    85 00000000 26817E0DF60F            	CMP	word [ES:BP + dpb_max_cluster],4096-10 ; is this 16 bit fat?
    86 00000006 730B                    	JAE	EOF16			; yes, check for eof there
    87                                  ;J.K. 8/27/86
    88                                  ;Modified to accept 0FF0h as an eof. This is to handle the diskfull case
    89                                  ;of any media that has "F0"(Other) as a MediaByte.
    90                                  ;Hopely, this does not create any side effect for those who may use any value
    91                                  ;other than "FF8-FFF" as an Eof for their own file.
    92 00000008 81FBF00F                	cmp	bx,0FF0h
    93 0000000C 7404                    	je	IsEOF_other
    94 0000000E 81FBF80F                	CMP	BX,0FF8h		; do the 12 bit compare
    95                                  IsEOF_other:
    96 00000012 C3                      	return
    97                                  EOF16:
    98 00000013 83FBF8                  	CMP	BX,0FFF8h		; 16 bit compare
    99 00000016 C3                      	return
   100                                  EndProc IsEof
   101                                  
   102                                  Break	<UNPACK -- UNPACK FAT ENTRIES>
   103                                  
   104                                  ; Inputs:
   105                                  ;	BX = Cluster number (may be full 16-bit quantity)
   106                                  ;	ES:BP = Base of drive parameters
   107                                  ; Outputs:
   108                                  ;	DI = Contents of FAT for given cluster (may be full 16-bit quantity)
   109                                  ;	Zero set means DI=0 (free cluster)
   110                                  ;	Carry set means error (currently user FAILed to I 24)
   111                                  ; SI Destroyed, No other registers affected. Fatal error if cluster too big.
   112                                  
   113                                  	procedure   UNPACK,NEAR
   113          ******************       warning: proc UNPACK... [-w+user]
   114                                  	DOSAssume   CS,<DS>,"UnPack"
   115                                  	ASSUME	ES:NOTHING
   116                                  
   117                                  	Assert	    ISDPB,<ES,BP>,"Unpack"
   118 00000017 263B5E0D                	CMP	BX,[ES:BP + dpb_max_cluster]
   119 0000001B 7726                    	JA	HURTFAT
   120 0000001D E8D300                  	CALL	MAPCLUSTER
   121                                  ASSUME	DS:NOTHING
   122 00000020 721E                    	jc	DoContext
   123 00000022 8B3D                    	MOV	DI,[DI]
   124 00000024 750E                    	JNZ	High12			; MZ if high 12 bits, go get 'em
   125 00000026 268B760D                	MOV	SI,[ES:BP + dpb_max_cluster]  ; MZ is this 16-bit fat?
   126 0000002A 81FEF60F                	CMP	SI,4096-10
   127 0000002E 720C                    	JB	Unpack12		; MZ No, go 'AND' off bits
   128 00000030 85FF                    	test	DI,DI			; MZ set zero condition code, clears carry
   129 00000032 EB0C                    	JMP	SHORT DoContext 	; MZ go do context
   130                                  
   131                                  High12:
   132 00000034 D1EF                    	SHR	DI,1
   133 00000036 D1EF                    	SHR	DI,1
   134 00000038 D1EF                    	SHR	DI,1
   135 0000003A D1EF                    	SHR	DI,1
   136                                  Unpack12:
   137 0000003C 81E7FF0F                	AND	DI,0FFFH		; Clears carry
   138                                  DoContext:
   139 00000040 16                      	PUSH	SS
   140 00000041 1F                      	POP	DS
   141                                   assume ds:DOSGROUP
   142 00000042 C3                      	return
   143                                  
   144                                  HURTFAT:
   145 00000043 26C7461FFFFF            	MOV	word [ES:BP + dpb_free_cnt],-1 ; Err in FAT must force recomp of freespace
   146 00000049 50                      	PUSH	AX
   147                                  allowed_fail equ Allowed_FAIL	; NASM port equate
   148 0000004A B488                    	MOV	AH,allowed_fail + 80h
   149                                  Allowed equ ALLOWED	; NASM port label
   150 0000004C 36C606[0000]08          	MOV	byte [ss:Allowed],allowed_fail
   151                                  ;
   152                                  ; Signal Bad FAT to INT int_fatal_abort handler.  We have an invalid cluster.
   153                                  ;
   154 00000052 BFFF0F                  	MOV	DI,0FFFH		; In case INT int_fatal_abort returns (it shouldn't)
   155 00000055 E8(0000)                	invoke	FATAL
   156 00000058 3C03                    	CMP	AL,3
   157 0000005A F8                      	CLC
   158 0000005B 7501                    	JNZ	OKU_RET 		; Try to ignore bad FAT
   159 0000005D F9                      	STC				; User said FAIL
   160                                  OKU_RET:
   161 0000005E 58                      	POP	AX
   162 0000005F C3                      	return
   163                                  EndProc UNPACK
   164                                  
   165                                  Break	<PACK -- PACK FAT ENTRIES>
   166                                  
   167                                  ; Inputs:
   168                                  ;	BX = Cluster number
   169                                  ;	DX = Data
   170                                  ;	ES:BP = Pointer to drive DPB
   171                                  ; Outputs:
   172                                  ;	The data is stored in the FAT at the given cluster.
   173                                  ;	SI,DX,DI all destroyed
   174                                  ;	Carry set means error (currently user FAILed to I 24)
   175                                  ;	No other registers affected
   176                                  
   177                                  	procedure   PACK,NEAR
   177          ******************       warning: proc PACK... [-w+user]
   178                                  	DOSAssume   CS,<DS>,"Pack"
   179                                  	ASSUME	ES:NOTHING
   180                                  
   181                                  	Assert	    ISDPB,<ES,BP>,"Pack"
   182 00000060 E89000                  	CALL	MAPCLUSTER
   183                                  ASSUME	DS:NOTHING
   184 00000063 72DB                    	JC	DoContext
   185 00000065 8B35                    	MOV	SI,[DI]
   186                                  Aligned equ ALIGNED	; NASM port label
   187 00000067 740B                    	JZ	Aligned 		; byte (not nibble) aligned
   188 00000069 51                      	PUSH	CX			; move data to upper 12 bits
   189 0000006A B104                    	MOV	CL,4
   190 0000006C D3E2                    	SHL	DX,CL
   191 0000006E 59                      	POP	CX
   192 0000006F 83E60F                  	AND	SI,0FH			; leave in original low 4 bits
   193 00000072 EB14                    	JMP	SHORT PACKIN
   194                                  ALIGNED:
   195 00000074 26817E0DF60F            	CMP	word [ES:BP + dpb_max_cluster],4096-10 ; MZ 16 bit fats?
   196 0000007A 730A                    	JAE	Pack16			; MZ yes, go clobber original data
   197 0000007C 81E600F0                	AND	SI,0F000H		; MZ leave in upper 4 bits of original
   198 00000080 81E2FF0F                	AND	DX,0FFFh		; MZ store only 12 bits
   199                                  PackIn equ PACKIN	; NASM port label
   200 00000084 EB02                    	JMP	SHORT PackIn		; MZ go store
   201                                  Pack16:
   202 00000086 31F6                    	XOR	SI,SI			; MZ no original data
   203                                  PACKIN:
   204 00000088 09D6                    	OR	SI,DX
   205 0000008A 8935                    	MOV	[DI],SI
   206 0000008C 36C536[0000]            	LDS	SI,[ss:CURBUF]
   207 00000091 F6440540                	TEST	byte [SI + buf_flags],buf_dirty  ;LB. if already dirty 		;AN000;
   208 00000095 7507                    	JNZ	yesdirty		  ;LB.	  don't increment dirty count   ;AN000;
   209 00000097 E8(0000)                	invoke	INC_DIRTY_COUNT 	  ;LB.					;AN000;
   210 0000009A 804C0540                	OR	byte [SI + buf_flags],buf_dirty  ;LB.					;AN000;
   211                                  yesdirty:				  ;LB.					;AN000;
   212 0000009E 36803E[0000]00          	CMP	BYTE PTR [ss:CLUSSPLIT],0
   213 000000A4 161F                    	Context DS
   214 000000A6 74B7                    	retz				; Carry clear
   215 000000A8 50                      	PUSH	AX
   216 000000A9 53                      	PUSH	BX
   217 000000AA 51                      	PUSH	CX
   218 000000AB A1[0000]                	MOV	AX,[CLUSSAVE]
   219 000000AE 8E1E[0200]              	MOV	DS,WORD PTR [CURBUF+2]
   220                                  ASSUME	DS:NOTHING
   221 000000B2 83C610                  	ADD	SI,BUFINSIZ
   222 000000B5 8824                    	MOV	[SI],AH
   223 000000B7 161F                    	Context DS
   224 000000B9 50                      	PUSH	AX
   225 000000BA 8B16[0200]              	MOV	DX,WORD PTR [CLUSSEC+2] 	   ;F.C. >32mb		       ;AN000;
   226 000000BE 8916[0000]              	MOV	WORD PTR [HIGH_SECTOR],DX	   ;F.C. >32mb		       ;AN000;
   227                                  
   228 000000C2 8B16[0000]              	MOV	DX,WORD PTR [CLUSSEC]
   229 000000C6 BE0100                  	MOV	SI,1
   230 000000C9 30C0                    	XOR	AL,AL
   231 000000CB E8(0000)                	invoke	GETBUFFRB
   232 000000CE 58                      	POP	AX
   233 000000CF 721C                    	JC	POPP_RET
   234 000000D1 C53E[0000]              	LDS	DI,[CURBUF]
   235                                  ASSUME	DS:NOTHING
   236 000000D5 F6450540                	TEST	byte [DI + buf_flags],buf_dirty  ;LB. if already dirty 		;AN000;
   237 000000D9 7507                    	JNZ	yesdirty2		  ;LB.	  don't increment dirty count   ;AN000;
   238 000000DB E8(0000)                	invoke	INC_DIRTY_COUNT 	  ;LB.					;AN000;
   239 000000DE 804D0540                	OR	byte [DI + buf_flags],buf_dirty
   240                                  yesdirty2:
   241 000000E2 83C710                  	ADD	DI,BUFINSIZ
   242 000000E5 4F                      	DEC	DI
   243 000000E6 26037E02                	ADD	DI,[ES:BP + dpb_sector_size]
   244 000000EA 8805                    	MOV	[DI],AL
   245 000000EC F8                      	CLC
   246                                  POPP_RET:
   247 000000ED 16                      	PUSH	SS
   248 000000EE 1F                      	POP	DS
   249                                   assume ds:DOSGROUP
   250 000000EF 59                      	POP	CX
   251 000000F0 5B                      	POP	BX
   252 000000F1 58                      	POP	AX
   253 000000F2 C3                      	return
   254                                  
   255                                  EndProc PACK
   256                                  
   257                                  Break	<MAPCLUSTER - BUFFER A FAT SECTOR>
   258                                  
   259                                  ; Inputs:
   260                                  ;	ES:BP Points to DPB
   261                                  ;	BX Is cluster number
   262                                  ; Function:
   263                                  ;	Get a pointer to the cluster
   264                                  ; Outputs:
   265                                  ;	DS:DI Points to contents of FAT for given cluster
   266                                  ;	DS:SI Points to start of buffer
   267                                  ;	Zero Not set if cluster data is in high 12 bits of word
   268                                  ;	Zero set if cluster data is in low 12 or 16 bits
   269                                  ;	Carry set if failed.
   270                                  ; SI is destroyed.
   271                                  
   272                                  	procedure   MAPCLUSTER,NEAR
   272          ******************       warning: proc MAPCLUSTER... [-w+user]
   273                                  	DOSAssume   CS,<DS>,"MapCluster"
   274                                  	ASSUME	ES:NOTHING
   275                                  
   276                                  	Assert	    ISDPB,<ES,BP>,"MapCluster"
   277 000000F3 C606[0000]00            	MOV	BYTE PTR [CLUSSPLIT],0
   278 000000F8 50535152                	SaveReg <AX,BX,CX,DX>
   279 000000FC 89D8                    	MOV	AX,BX			; AX = BX
   280 000000FE B9F60F                  	MOV	CX,4096-10
   281 00000101 26394E0D                	CMP	[ES:BP + dpb_max_cluster],CX  ; MZ 16 bit fat?
   282 00000105 7302                    	JAE	Map16			; MZ yes, do 16 bit algorithm
   283 00000107 D1E8                    	SHR	AX,1			; AX = BX/2
   284                                  Map16:					; MZ skip prev => AX=2*BX
   285 00000109 31FF                    	XOR	DI,DI			; >32mb     fat 			;AN000;
   286 0000010B 01D8                    	ADD	AX,BX			; AX = 1.5*fat = byte offset in fat
   287 0000010D 83D700                  	ADC	DI,0			; >32mb     fat 			;AN000;
   288                                  DoConvert:
   289 00000110 268B4E02                	MOV	CX,[ES:BP + dpb_sector_size]
   290                                  %IF FastDiv
   291                                  ;
   292                                  ; Gross hack:  99% of all disks have 512 bytes per sector.  We test for this
   293                                  ; case and apply a really fast algorithm to get the desired results
   294                                  ;
   295                                  ; Divide method takes 158 (XOR and DIV)
   296                                  ; Fast method takes 20
   297                                  ;
   298                                  ; This saves a bunch.
   299                                  ;
   300 00000114 81F90002                	CMP	CX,512			; 4	Is this 512 byte sector?
   301 00000118 7403                    	JZ	Nodiv			;F.C. >32mb				;AN000;
   302 0000011A E98B00                  	JMP	DoDiv			; 4/16	No, go do divide
   303                                  Nodiv:					;F.C. >32mb				;AN000;
   304 0000011D 89C2                    	MOV	DX,AX			; 2	get set for remainder
   305 0000011F 81E2FF01                	AND	DX,512-1		; 4	Form remainder
   306 00000123 88E0                    	MOV	AL,AH			; 2
   307 00000125 D0E8                    	SHR	AL,1			; 2
   308 00000127 98                      	CBW				; 2	Fast divide by 512
   309 00000128 09FF                    	OR	DI,DI			;>32mb	>64k ?				;AN000;
   310 0000012A 7403                    	JZ	g64k			;>32mb	no				;AN000;
   311 0000012C 0D8000                  	OR	AX,80H			;>32mb					;AN000;
   312                                  g64k:
   313                                  %ELSE
   314                                  	XOR	DX,DX			; 3
   315                                  	DIV	CX			; 155 AX is FAT sector # DX is sector index
   316                                  %ENDIF
   317                                  DivDone:
   318 0000012F 26034606                	ADD	AX,[ES:BP + dpb_first_FAT]
   319 00000133 49                      	DEC	CX			; CX is sector size - 1
   320 00000134 505251                  	SaveReg <AX,DX,CX>
   321 00000137 89C2                    	MOV	DX,AX
   322 00000139 C706[0000]0000          	MOV	word [HIGH_SECTOR],0 	;F.C. >32mb  low sector #
   323 0000013F 30C0                    	XOR	AL,AL
   324 00000141 BE0100                  	MOV	SI,1
   325 00000144 E8(0000)                	invoke	GETBUFFRB
   326 00000147 59585A                  	RestoreReg  <CX,AX,DX>		; CX is sec siz-1, AX is offset in sec
   327 0000014A 7257                    	JC	MAP_POP
   328 0000014C C536[0000]              	LDS	SI,[CURBUF]
   329                                  ASSUME	DS:NOTHING
   330                                  BufInSiz equ BUFINSIZ	; NASM port equate
   331 00000150 8D7C10                  	LEA	DI,[SI + BufInSiz]
   332 00000153 01C7                    	ADD	DI,AX
   333 00000155 39C8                    	CMP	AX,CX
   334 00000157 7537                    	JNZ	MAPRET
   335 00000159 8A05                    	MOV	AL,[DI]
   336 0000015B 161F                    	Context DS
   337 0000015D FE06[0000]              	INC	BYTE PTR [CLUSSPLIT]
   338 00000161 A2[0000]                	MOV	BYTE PTR [CLUSSAVE],AL
   339 00000164 8916[0000]              	MOV	WORD PTR [CLUSSEC],DX
   340 00000168 C706[0200]0000          	MOV	WORD PTR [CLUSSEC+2],0	      ;F.C. >32mb			;AN000;
   341 0000016E 42                      	INC	DX
   342 0000016F C706[0000]0000          	MOV	word [HIGH_SECTOR],0 	      ;F.C. >32mb  FAT sector <32mb	;AN000;
   343 00000175 30C0                    	XOR	AL,AL
   344 00000177 BE0100                  	MOV	SI,1
   345 0000017A E8(0000)                	invoke	GETBUFFRB
   346 0000017D 7224                    	JC	MAP_POP
   347 0000017F C536[0000]              	LDS	SI,[CURBUF]
   348                                  ASSUME	DS:NOTHING
   349 00000183 8D7C10                  	LEA	DI,[SI + BufInSiz]
   350 00000186 8A05                    	MOV	AL,[DI]
   351 00000188 161F                    	Context DS
   352 0000018A A2[0100]                	MOV	BYTE PTR [CLUSSAVE+1],AL
   353 0000018D BF[0000]                	MOV	DI,OFFSET CLUSSAVE wrt DOSGROUP
   354                                  MAPRET:
   355 00000190 5A595B                  	RestoreReg  <DX,CX,BX>
   356 00000193 31C0                    	XOR	AX,AX			; MZ allow shift to clear carry
   357 00000195 26817E0DF60F            	CMP	word [ES:BP + dpb_max_cluster],4096-10 ; MZ is this 16-bit fat?
   358 0000019B 7302                    	JAE	MapSet			; MZ no, set flags
   359 0000019D 89D8                    	MOV	AX,BX
   360                                  MapSet:
   361 0000019F A801                    	TEST	AL,1			; set zero flag if not on boundary
   362 000001A1 58                      	RestoreReg  <AX>
   363 000001A2 C3                      	return
   364                                  
   365                                  MAP_POP:
   366 000001A3 5A595B58                	RestoreReg  <DX,CX,BX,AX>
   367 000001A7 C3                      	return
   368                                  %IF FastDiv
   369                                  DoDiv:
   370 000001A8 31D2                    	XOR	DX,DX			; 3
   371 000001AA F7F1                    	DIV	CX			; 155 AX is FAT sector # DX is sector index
   372 000001AC EB81                    	JMP	DivDone 		;15 total=35
   373                                  %ENDIF
   374                                  
   375                                  EndProc MAPCLUSTER
   375          ******************       warning: ***** Possible stack size error in MAPCLUSTER ***** [-w+user]
   376                                  
   377                                  Break	<FATREAD_SFT/FATREAD_CDS -- CHECK DRIVE GET FAT>
   378                                  
   379                                  ; Inputs:
   380                                  ;	ES:DI points to an SFT for the drive of intrest (local only,
   381                                  ;		giving a NET SFT will produce system crashing results).
   382                                  ;	DS DOSGROUP
   383                                  ; Function:
   384                                  ;	Can be used by an SFT routine (like CLOSE) to invalidate buffers
   385                                  ;	if disk changed.
   386                                  ;	In other respects, same as FATREAD_CDS.
   387                                  ;	(note ES:DI destroyed!)
   388                                  ; Outputs:
   389                                  ;	Carry set if error (currently user FAILed to I 24)
   390                                  ; NOTE: This routine may cause FATREAD_CDS to "miss" a disk change
   391                                  ;	as far as invalidating curdir_ID is concerned.
   392                                  ;	Since getting a true disk changed on this call is a screw up
   393                                  ;	anyway, that's the way it goes.
   394                                  
   395                                  	procedure  FATREAD_SFT,NEAR
   395          ******************       warning: proc FATREAD_SFT... [-w+user]
   396                                  	DOSAssume   CS,<DS>,"FATRead_SFT"
   397                                  	ASSUME	ES:NOTHING
   398                                  
   399 000001AE 26C46D07                	LES	BP,[ES:DI + sf_devptr]
   400                                  	Assert	    ISDPB,<ES,BP>,"FatReadSFT"
   401 000001B2 268A4600                	MOV	AL,[ES:BP + dpb_drive]
   402 000001B6 A2[0000]                	MOV	[THISDRV],AL
   403 000001B9 E8(0000)                	invoke	GOTDPB			;Set THISDPB
   404 000001BC E87900                  	CALL	FAT_GOT_DPB
   405 000001BF C3                      	return
   406                                  EndProc FATREAD_SFT
   407                                  
   408                                  ; Inputs:
   409                                  ;	DS:DOSGROUP
   410                                  ;	ES:DI points to an CDS for the drive of intrest (local only,
   411                                  ;		giving a NET or NUL CDS will produce system crashing results).
   412                                  ; Function:
   413                                  ;	If disk may have been changed, media is determined and buffers are
   414                                  ;	flagged invalid. If not, no action is taken.
   415                                  ; Outputs:
   416                                  ;	ES:BP = Drive parameter block
   417                                  ;	[THISDPB] = ES:BP
   418                                  ;	[THISDRV] set
   419                                  ;	Carry set if error (currently user FAILed to I 24)
   420                                  ; DS preserved , all other registers destroyed
   421                                  
   422                                  	procedure   FATREAD_CDS,NEAR
   422          ******************       warning: proc FATREAD_CDS... [-w+user]
   423                                  	DOSAssume   CS,<DS>,"FATRead_CDS"
   424                                  	ASSUME	ES:NOTHING
   425                                  
   426 000001C0 06                      	PUSH	ES
   427 000001C1 57                      	PUSH	DI
   428 000001C2 26C46D45                	LES	BP,[ES:DI + curdir_devptr]
   429                                   assume es:DPB
   430                                  	Assert	ISDPB,<ES,BP>,"FatReadCDS"
   431 000001C6 268A4600                	MOV	AL,[ES:BP + dpb_drive]
   432 000001CA A2[0000]                	MOV	[THISDRV],AL
   433 000001CD E8(0000)                	invoke	GOTDPB			;Set THISDPB
   434 000001D0 E86500                  	CALL	FAT_GOT_DPB
   435 000001D3 5F                      	POP	DI			;Get back CDS pointer
   436 000001D4 07                      	POP	ES
   437                                   assume es:nothing
   438 000001D5 72E8                    	retc
   439 000001D7 7538                    	JNZ	NO_CHANGE		;Media NOT changed
   440                                  ; Media changed. We now need to find all CDS structures which use this
   441                                  ; DPB and invalidate their ID pointers.
   442                                  MED_CHANGE:
   443 000001D9 31C0                    	XOR	AX,AX
   444 000001DB 48                      	DEC	AX			;AX = -1
   445 000001DC 1E                      	PUSH	DS
   446 000001DD 8A0E[0000]              	MOV	CL,[CDSCOUNT]
   447 000001E1 30ED                    	XOR	CH,CH			; CX is number of structures
   448 000001E3 26C57545                	LDS	SI,[ES:DI + curdir_devptr] ; Find all CDS with this devptr
   449                                   assume ds:DPB
   450 000001E7 36C43E[0000]            	LES	DI,[ss:CDSADDR]		; Start here
   451                                   assume es:nothing
   452                                  CHECK_CDS:
   453 000001EC 26F745430080            	TEST	word [ES:DI + curdir_flags],curdir_isnet
   454 000001F2 7517                    	JNZ	NEXTCDS 		; Leave NET guys alone!!
   455 000001F4 06                      	PUSH	ES
   456 000001F5 57                      	PUSH	DI
   457 000001F6 26C47D45                	LES	DI,[ES:DI + curdir_devptr]
   458                                   assume es:DPB
   459 000001FA E8(0000)                	invoke	POINTCOMP
   460 000001FD 5F                      	POP	DI
   461 000001FE 07                      	POP	ES
   462                                   assume es:nothing
   463 000001FF 750A                    	JNZ	NEXTCDS 		; CDS not for this drive
   464 00000201 26854549                	TEST	[ES:DI + curdir_ID],AX
   465 00000205 7404                    	JZ	NEXTCDS 		; If root, leave root
   466 00000207 26894549                	MOV	[ES:DI + curdir_ID],AX	; else invalid
   467                                  NEXTCDS:
   468 0000020B 83C758                  	ADD	DI,curdir_list_struc_size	; Point to next CDS
   469 0000020E E2DC                    	LOOP	CHECK_CDS
   470 00000210 1F                      	POP	DS
   471                                  	DOSAssume   CS,<DS>,"FAT/NextCDS"
   472                                  NO_CHANGE:
   473 00000211 C42E[0000]              	LES	BP,[THISDPB]
   474                                   assume es:DPB
   475 00000215 F8                      	CLC
   476 00000216 C3                      	return
   477                                  EndProc FATREAD_CDS
   478                                  
   479                                  Break	<Fat_Operation - miscellaneous fat stuff>
   480                                  
   481                                  	procedure   FAT_operation,NEAR
   481          ******************       warning: proc FAT_operation... [-w+user]
   482                                  FATERR:
   483                                  	DOSAssume   CS,<DS>,"FATERR"
   484 00000217 26C7461FFFFF            	MOV	word [ES:BP + dpb_free_cnt],-1 ; Err in FAT must force recomp of freespace
   485 0000021D 81E7FF00                	AND	DI,STECODE		; Put error code in DI
   486                                  allowed_FAIL equ Allowed_FAIL	; NASM port equate
   487                                  allowed_RETRY equ Allowed_RETRY	; NASM port equate
   488 00000221 C606[0000]18            	MOV	byte [ALLOWED],allowed_FAIL + allowed_RETRY
   489 00000226 B41A                    	MOV	AH,2 + allowed_FAIL + allowed_RETRY ; While trying to read FAT
   490 00000228 A0[0000]                	MOV	AL,BYTE PTR [THISDRV]	 ; Tell which drive
   491 0000022B E8(0000)                	invoke	FATAL1
   492 0000022E C42E[0000]              	LES	BP,[THISDPB]
   493                                   assume es:DPB
   494 00000232 3C03                    	CMP	AL,3
   495 00000234 7502                    	JNZ	FAT_GOT_DPB		; User said retry
   496 00000236 F9                      	STC				; User said FAIL
   497 00000237 C3                      	return
   498                                  
   499                                  FAT_GOT_DPB:
   500 00000238 161F                    	Context DS
   501 0000023A B00F                    	MOV	AL,DMEDHL
   502 0000023C 268A6601                	MOV	AH,[ES:BP + dpb_UNIT]
   503 00000240 A3[0000]                	MOV	WORD PTR [DEVCALL],AX
   504 00000243 C606[0200]01            	MOV	BYTE PTR [DEVCALL + REQFUNC],DEVMDCH
   505 00000248 C706[0300]0000          	MOV	word [DEVCALL + REQSTAT],0
   506 0000024E 268A4617                	MOV	AL,[ES:BP + dpb_media]
   507 00000252 A2[0000]                	MOV	BYTE PTR [CALLMED],AL
   508 00000255 06                      	PUSH	ES
   509 00000256 1E                      	PUSH	DS
   510 00000257 BB[0000]                	MOV	BX,OFFSET DEVCALL wrt DOSGROUP
   511 0000025A 26C57613                	LDS	SI,[ES:BP + dpb_driver_addr]  ; DS:SI Points to device header
   512                                  ASSUME	DS:NOTHING
   513 0000025E 07                      	POP	ES			; ES:BX Points to call header
   514                                   assume es:nothing
   515 0000025F E8(0000)                	invoke	DEVIOCALL2
   516 00000262 161F                    	Context DS
   517 00000264 07                      	POP	ES			; Restore ES:BP
   518                                   assume es:DPB
   519 00000265 8B3E[0300]              	MOV	DI,[DEVCALL + REQSTAT]
   520 00000269 F7C70080                	TEST	DI,STERR
   521 0000026D 75A8                    	JNZ	FATERR
   522 0000026F 30E4                    	XOR	AH,AH
   523 00000271 26866618                	XCHG	AH,[ES:BP + dpb_first_access] ; Reset dpb_first_access
   524 00000275 A0[0000]                	MOV	AL,BYTE PTR [THISDRV]	; Use physical unit number
   525                                  ; See if we had changed volume id by creating one on the diskette
   526 00000278 3806[0000]              	cmp	[VOLCHNG_FLAG],AL
   527 0000027C 7508                    	jnz	CHECK_BYT
   528 0000027E C606[0000]FF            	mov	byte [VOLCHNG_FLAG],-1
   529 00000283 E99700                  	jmp	GOGETBPB		; Need to get device driver to read in
   530                                  					; new volume label.
   531                                  CHECK_BYT:
   532 00000286 0A26[0000]              	OR	AH,BYTE PTR [CALLRBYT]
   533 0000028A 7903                    	JNS	CHECK_ZR		; ns = 0 or 1
   534 0000028C EB66                    	JMP	NEWDSK
   535 0000028E 90                      	nop	; identicalise
   536                                  
   537                                  CHECK_ZR:
   538 0000028F 743D                    	JZ	CHKBUFFDIRT		; jump if I don't know
   539 00000291 F8                      	CLC
   540 00000292 C3                      	return				; If Media not changed (NZ)
   541                                  
   542                                  DISK_CHNG_ERR:
   543                                  ASSUME	DS:NOTHING
   544                                   assume es:DPB
   545 00000293 06                      	PUSH	ES
   546 00000294 55                      	PUSH	BP
   547 00000295 26C46E13                	LES	BP,[ES:BP + dpb_driver_addr]  ; Get device pointer
   548                                   assume es:nothing
   549 00000299 26F746040008            	TEST	word [ES:BP + SDEVATT],DEVOPCL ; Did it set vol id?
   550 0000029F 5D                      	POP	BP
   551 000002A0 07                      	POP	ES
   552                                   assume es:DPB
   553 000002A1 7426                    	JZ	FAIL_OPJ2		; Nope, FAIL
   554 000002A3 1E                      	PUSH	DS			; Save buffer pointer for ignore
   555 000002A4 57                      	PUSH	DI
   556 000002A5 161F                    	Context DS
   557 000002A7 C606[0000]18            	MOV	byte [ALLOWED],allowed_FAIL + allowed_RETRY
   558 000002AC 06                      	PUSH	ES
   559 000002AD C43E[0000]              	LES	DI,[CALLVIDM]		; Get volume ID pointer
   560                                   assume es:nothing
   561 000002B1 8C06[0200]              	MOV	WORD PTR [EXTERRPT+2],ES
   562 000002B5 07                      	POP	ES
   563                                   assume es:DPB
   564 000002B6 893E[0000]              	MOV	WORD PTR [EXTERRPT],DI
   565 000002BA B80F00                  	MOV	AX,error_I24_wrong_disk
   566                                  READOP equ ReadOp	; NASM port label
   567 000002BD C606[0000]01            	MOV	byte [READOP],1		; Write
   568 000002C2 E8(0000)                	invoke	HARDERR_DOS
   569 000002C5 5F                      	POP	DI			; Get back buffer for ignore
   570 000002C6 1F                      	POP	DS
   571                                  ASSUME	DS:NOTHING
   572 000002C7 3C03                    	CMP	AL,3
   573                                  FAIL_OPJ2:
   574 000002C9 741E                    	JZ	FAIL_OP
   575 000002CB E96AFF                  	JMP	FAT_GOT_DPB		; Retry
   576                                  
   577                                  CHKBUFFDIRT:
   578                                  	DOSAssume   CS,<DS>,"FAT/ChkBuffDirt"
   579                                  %ifdef BUF2
   580 000002CE C53E[0000]              	LDS	DI,[BUFFHEAD]
   581                                  ASSUME	DS:NOTHING
   582 000002D2 36833E[0000]00          	CMP	word [ss:BUF2_Dirty_Count], 0	 ;LB. if not dirty		;AN000;
   583 000002D8 741A                    	je NEWDSK
   584                                  %else
   585                                  	XOR	DX,DX				 ;LB.				;AN000;
   586                                  	LDS	DI,[ss:BUF_HASH_PTR]		 ;LB. scan from 1st entry	;AN000;
   587                                  	MOV	CX,[ss:BUF_HASH_COUNT]		 ;LB. get Hash entry count	;AN000;
   588                                  
   589                                  scan_dirty:
   590                                  Dirty_Count equ DIRTY_COUNT	; NASM port equate
   591                                  	CMP	byte [DI + Dirty_Count],0		 ;LB. if not dirty		;AN000;
   592                                  	JZ	GETNEXT 			 ;LB.	 get next hash entry	;AN000;
   593                                  	PUSH	DS				 ;LB. save hash entry addr	;AN000;
   594                                  	PUSH	DI				 ;LB.				;AN000;
   595                                  	invoke	Map_Entry			 ;LB.				;AN000;
   596                                  %endif
   597                                  NBUFFER:				; Look for dirty buffers
   598 000002DA 3A4504                  	CMP	AL,[DI + buf_ID]
   599 000002DD 750E                    	JNZ	LFNXT			; Not for this unit
   600 000002DF F6450540                	TEST	byte [DI + buf_flags],buf_dirty
   601 000002E3 7408                    	JZ	LFNXT
   602                                  %ifndef BUF2
   603                                  	POP	DI				  ;LB. restore regs		 ;AN000;
   604                                  	POP	DS				  ;LB.				 ;AN000;
   605                                  %endif
   606 000002E5 161F                    	Context DS
   607 000002E7 F8                      	CLC
   608 000002E8 C3                      	return				; There is a dirty buffer, assume Media OK (NZ)
   609                                  
   610                                  FAIL_OP:
   611 000002E9 161F                    	Context DS
   612 000002EB F9                      	STC
   613 000002EC C3                      	return
   614                                  
   615                                  ASSUME	DS:NOTHING
   616                                  LFNXT:
   617                                  %ifdef BUF2
   618 000002ED C53D                    	lds di, [di + NEXTBUF]
   619 000002EF 83FFFF                  	cmp di, -1
   620                                  %else
   621                                  	mov	DI,[DI + buf_next]	    ;; 1/19/88
   622                                  	CMP	DI,[ss:FIRST_BUFF_ADDR]	    ;; 1/19/88
   623                                  %endif
   624 000002F2 75E6                    	JNZ	NBUFFER
   625                                  %ifndef BUF2
   626                                  	POP	DI				  ;LB. restore regs		 ;AN000;
   627                                  	POP	DS				  ;LB.				 ;AN000;
   628                                  GETNEXT:
   629                                  	ADD	DI,BUFFER_HASH_ENTRY_struc_size	  ;LB. next entry		 ;AN000;
   630                                  	LOOP	scan_dirty			  ;LB. scan next entry		 ;AN000;
   631                                  %endif
   632                                  ; If no dirty buffers, assume Media changed
   633                                  NEWDSK:
   634 000002F4 26C7461FFFFF            	MOV	word [ES:BP + dpb_free_cnt],-1 ; Media changed, must re-compute
   635                                  					; NOTE: It is TECHNICALLY more correct
   636                                  ASSUME DS:NOTHING
   637                                  %ifdef BUF2
   638 000002FA 36C53E[0000]            	lds di, [ss:BUFFHEAD]
   639                                  %else
   640                                  	XOR	DX,DX			;LB.					  ;AN000;
   641                                  	MOV	[ss:HIGH_SECTOR],DX	;LB. scan from 1st entry		  ;AN000;
   642                                  	MOV	CX,[ss:BUF_HASH_COUNT]	;LB. get Hash entry count		  ;AN000;
   643                                  
   644                                  NxtHash:
   645                                  	invoke	GETCURHEAD		;LB. get Hash entry buffer header	  ;AN000;
   646                                  					;  to do this AFTER the check for
   647                                  %endif
   648                                  ASSUME	DS:NOTHING
   649                                  NXBUFFER:
   650 000002FF 3A4504                  	CMP	AL,[DI + buf_ID]		; For this drive?
   651 00000302 7404                    	JZ	OLDDRV2 		;LB.  yes				  ;AN000;
   652                                  %ifdef BUF2
   653 00000304 C53D                    	lds di, [di + NEXTBUF]
   654                                  %else
   655                                  	mov	DI,[DI + buf_next]	    ;LB. get next buffer 1/19/88	;AN000;
   656                                  %endif
   657 00000306 EB10                    	JMP	SHORT SKPBUFF		;LB.					  ;AN000;
   658                                  OLDDRV2:
   659 00000308 F6450540                	TEST	byte [DI + buf_flags],buf_dirty
   660                                  OldDrv equ OLDDRV	; NASM port label
   661 0000030C 7402                    	JZ	OldDrv
   662                                  Disk_Chng_Err equ DISK_CHNG_ERR	; NASM port label
   663 0000030E EB83                    	JMP	Disk_Chng_Err		; Disk changed but dirty buffers
   664                                  OLDDRV:
   665                                  %ifdef BUF2
   666 00000310 C74504FF00              	MOV	WORD PTR [DI + BUFDRV], 00FFH
   667                                  %else
   668                                  	MOV	WORD PTR [DI + buf_ID], 00FFH	; Free up buffer
   669                                  %endif
   670 00000315 E8(0000)                	invoke	SCANPLACE
   671                                  SKPBUFF:
   672                                  %ifdef BUF2
   673 00000318 83FFFF                  	cmp di, -1
   674                                  %else
   675                                  	CMP	DI,[ss:FIRST_BUFF_ADDR]	;LB.  end of chain  1/19/88		  ;AN000;
   676                                  %endif
   677 0000031B 75E2                    	JNZ	NXBUFFER		;LB.  no				  ;AN000;
   678                                  %ifndef BUF2
   679                                  	INC	DX			;LB.					  ;AN000;
   680                                  	LOOP	NxtHash 		;LB.					  ;AN000;
   681                                  	CMP	word [ss:SC_CACHE_COUNT],0	;LB.  look ahead buffers ?		  ;AN001;
   682                                  	JZ	GOGETBPB		;LB.  no				  ;AN001;
   683                                  	CMP	AL,[ss:CURSC_DRIVE]	;LB.  same as changed drive		  ;AN001;
   684                                  	JNZ	GOGETBPB		;LB.  no				  ;AN001;
   685                                  	MOV	byte [ss:CURSC_DRIVE],-1	;LB.  invalidate look ahead buffers	  ;AN000;
   686                                  %endif
   687                                  GOGETBPB:
   688 0000031D 26C57E13                	LDS	DI,[ES:BP + dpb_driver_addr]
   689                                   assume ds:nothing
   690 00000321 F745040020              	TEST	word [DI + SDEVATT],ISFATBYDEV
   691 00000326 7510                    	JNZ	GETFREEBUF
   692 00000328 161F                    	context DS
   693 0000032A BB0200                  	MOV	BX,2
   694 0000032D E8E7FC                  	CALL	UNPACK			; Read the first FAT sector into CURBUF
   695                                  FAIL_OPJ:
   696 00000330 72B7                    	JC	FAIL_OP
   697 00000332 C53E[0000]              	LDS	DI,[CURBUF]
   698                                  ASSUME	DS:NOTHING
   699 00000336 EB15                    	JMP	SHORT GOTGETBUF
   700                                  
   701                                  GETFREEBUF:
   702                                  ASSUME	DS:NOTHING
   703 00000338 06                      	PUSH	ES			; Get a free buffer for BIOS to use
   704 00000339 55                      	PUSH	BP
   705 0000033A 31D2                    	XOR	DX,DX			     ;LB.  fake to get 1st		  ;AN000;
   706 0000033C 368916[0000]            	MOV	[ss:HIGH_SECTOR],DX	     ;LB.  buffer addr			  ;AN000;
   707                                  %ifdef BUF2
   708 00000341 36C53E[0000]            	lds di, [ss:BUFFHEAD]
   709                                  %else
   710                                  	invoke	GETCURHEAD		     ;LB.				  ;AN000;
   711                                  %endif
   712                                  
   713 00000346 E8(0000)                	invoke	BUFWRITE
   714 00000349 5D                      	POP	BP
   715 0000034A 07                      	POP	ES
   716                                   assume es:DPB
   717 0000034B 72E3                    	JC	FAIL_OPJ
   718                                  GOTGETBUF:
   719 0000034D 83C710                  	ADD	DI,BUFINSIZ
   720 00000350 368C1E[0200]            	MOV	WORD PTR [ss:CALLXAD+2],DS
   721 00000355 161F                    	Context DS
   722 00000357 893E[0000]              	MOV	WORD PTR [CALLXAD],DI
   723 0000035B B016                    	MOV	AL,DBPBHL
   724 0000035D 268A6601                	MOV	AH,BYTE PTR [ES:BP + dpb_UNIT]
   725 00000361 A3[0000]                	MOV	WORD PTR [DEVCALL],AX
   726 00000364 C606[0200]02            	MOV	BYTE PTR [DEVCALL + REQFUNC],DEVBPB
   727 00000369 C706[0300]0000          	MOV	word [DEVCALL + REQSTAT],0
   728 0000036F 268A4617                	MOV	AL,BYTE PTR [ES:BP + dpb_media]
   729 00000373 A2[0000]                	MOV	[CALLMED],AL
   730 00000376 06                      	PUSH	ES
   731 00000377 1E                      	PUSH	DS
   732 00000378 26FF7615                	PUSH	WORD PTR [ES:BP + dpb_driver_addr+2]
   733 0000037C 26FF7613                	PUSH	WORD PTR [ES:BP + dpb_driver_addr]
   734 00000380 BB[0000]                	MOV	BX,OFFSET DEVCALL wrt DOSGROUP
   735 00000383 5E                      	POP	SI
   736 00000384 1F                      	POP	DS			; DS:SI Points to device header
   737                                  ASSUME	DS:NOTHING
   738 00000385 07                      	POP	ES			; ES:BX Points to call header
   739                                   assume es:nothing
   740 00000386 E8(0000)                	invoke	DEVIOCALL2
   741 00000389 07                      	POP	ES			; Restore ES:BP
   742                                   assume es:DPB
   743 0000038A 161F                    	Context DS
   744 0000038C 8B3E[0300]              	MOV	DI,[DEVCALL + REQSTAT]
   745 00000390 F7C70080                	TEST	DI,STERR
   746 00000394 751F                    	JNZ	FATERRJ
   747 00000396 268A4617                	MOV	AL,BYTE PTR [ES:BP + dpb_media]
   748 0000039A C536[0000]              	LDS	SI,[CALLBPB]
   749                                  ASSUME	DS:NOTHING
   750                                  DPB_next_free equ dpb_next_free	; NASM port equate
   751 0000039E 26C7461D0000            	MOV	word [ES:BP + DPB_next_free],0 ; recycle scanning pointer
   752 000003A4 E8(0000)                	invoke	D_SETDPB
   753 000003A7 36C53E[0000]            	LDS	DI,[ss:CALLXAD]		; Get back buffer pointer
   754                                  %ifdef BUF2
   755 000003AC 804DF502                	or byte [di - BUFINSIZ + buf_flags], buf_isFAT
   756                                  %else
   757                                  	MOV	AL,BYTE PTR [ES:BP + dpb_FAT_count]
   758                                  	MOV	[DI + buf_wrtcnt-BUFINSIZ],AL   ;>32mb				;AN000;
   759                                  	MOV	AX,[ES:BP + dpb_FAT_size]       ;>32mb				;AC000;
   760                                  	MOV	[DI + buf_wrtcntinc-BUFINSIZ],AX	 ;>32mb Correct buffer info	;AC000;
   761                                  %endif
   762                                  
   763 000003B0 161F                    	Context DS
   764 000003B2 30C0                    	XOR	AL,AL			;Media changed (Z), Carry clear
   765 000003B4 C3                      	return
   766                                  
   767 000003B5 E95FFE                  FATERRJ: JMP	FATERR
   768                                  
   769                                  EndProc FAT_operation
   770                                  
   771                                      END
