     1                                  ;	SCCSID = @(#)disk2.asm	1.3 85/06/19
     2                                  ;	SCCSID = @(#)disk2.asm	1.3 85/06/19
     3                                  ;TITLE	DISK2 - Disk utility routines
     4                                  ;NAME	Disk2
     5                                  ; Low level Read and write routines for local SFT I/O on files and devs
     6                                  ;
     7                                  ;   DskRead
     8                                  ;   DWRITE
     9                                  ;   DSKWRITE
    10                                  ;   HarderrRW
    11                                  ;   SETUP
    12                                  ;   BREAKDOWN
    13                                  ;   READ_LOCK_VIOLATION
    14                                  ;   WRITE_LOCK_VIOLATION
    15                                  ;   DISKREAD
    16                                  ;   SET_ACC_ERR_DS
    17                                  ;   SET_ACC_ERR
    18                                  ;   SETSFT
    19                                  ;   SETCLUS
    20                                  ;   AddRec
    21                                  ;
    22                                  ;   Revision history:
    23                                  ;
    24                                  ;    AN000  version 4.00 Jan. 1988
    25                                  ;
    26                                  
    27                                  ;
    28                                  ; get the appropriate segment definitions
    29                                  ;
    30                                  [list -]
    30          ******************       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
    32                                  
    33                                  [list +]
    34                                  section DOSCODECODE
    35                                  [list -]
    35          ******************       warning: out: ... for DOS Version 4.00 ... [-w+user]
    35          ******************       warning: out: BPB.INC... [-w+user]
    35          ******************       warning: out: ... CLONE version build switch on ... [-w+user]
    35          ******************       warning: out: DEVSYM.INC... [-w+user]
    35          ******************       warning: out: ... CLONE version build switch on ... [-w+user]
    43                                  
    44                                  %iassign Installed TRUE
    45                                  
    46                                  	i_need	THISSFT,DWORD
    47                                  	i_need	DMAADD,DWORD
    48                                  	i_need	NEXTADD,WORD
    49                                  	i_need	ThisDrv,BYTE
    50                                  	i_need	SecClusPos,BYTE
    51                                  	i_need	ClusNum,WORD
    52                                  	i_need	ReadOp,BYTE
    53                                  	i_need	Trans,BYTE
    54                                  	i_need	BytPos,4
    55                                  	i_need	SecPos,DWORD		 ; DOS 4.00 >32mb			;AN000;
    56                                  	i_need	BytSecPos,WORD
    57                                  	i_need	BytCnt1,WORD
    58                                  	i_need	BytCnt2,WORD
    59                                  	i_need	SecCnt_DOS,WORD
    60                                  	i_need	ThisDPB,DWORD
    61                                  	i_need	LastPos,WORD
    62                                  	i_need	EXTERRPT,DWORD
    63                                  	i_need	CALLVIDRW,DWORD
    64                                  	i_need	ALLOWED,BYTE
    65                                  	i_need	DEVCALL,BYTE
    66                                  	i_need	CALLSCNT,WORD
    67                                  	i_need	DISK_FULL,BYTE		  ; disk full flag for ran blk wrt
    68                                  	i_need	FSeek_drive,BYTE	  ; DOS 4.00	  ;AN000;
    69                                  	i_need	FSeek_firclus,WORD	  ; DOS 4.00	  ;AN000;
    70                                  	i_need	HIGH_SECTOR,WORD	  ; F.C. >32mb	  ;AN000;
    71                                  	i_need	TEMP_VAR2,WORD		  ; LB. 	  ;AN000;
    72                                  	i_need	TEMP_VAR,WORD		  ; LB. 	  ;AN000;
    73                                  	i_need	IFS_DRIVER_ERR,WORD	  ; LB. 	  ;AN000;
    74                                  %ifdef BUF2
    75                                  	i_need	BUF2_Dirty_Count,WORD
    76                                  	i_need	BUFFHEAD,DWORD
    77                                  %else
    78                                  	i_need	CurHashEntry,DWORD	     ; DOS 4.00 current Hash entry	;AN000;
    79                                  	i_need	BUF_HASH_PTR,DWORD	     ; DOS 4.00 Hash table pointer	;AN000;
    80                                  	i_need	BUF_HASH_COUNT,WORD	     ; DOS 4.00 Hash table entries	;AN000;
    81                                  %endif
    82                                  	i_need	LastBuffer,DWORD
    83                                  	i_need	FIRST_BUFF_ADDR,WORD	     ; first buffer address		;AN000;
    84                                  
    85                                  %ifndef BUF2
    86                                  %IF	BUFFERFLAG
    87                                  	EXTRN	SAVE_MAP:NEAR
    88                                  	EXTRN	RESTORE_MAP:NEAR
    89                                  	EXTRN	SAVE_USER_MAP:NEAR
    90                                  	EXTRN	RESTORE_USER_MAP:NEAR
    91                                  	i_need	BUF_EMS_SAFE_FLAG,BYTE
    92                                  	i_need	BUF_EMS_MODE,BYTE
    93                                  	i_need	CURADD,WORD
    94                                  %ENDIF
    95                                  %endif
    96                                  
    97                                  
    98                                   assume nocheck, ss:DOSGROUP
    99                                  
   100                                  Break	<DSKREAD -- PHYSICAL DISK READ>
   101                                  
   102                                  ; Inputs:
   103                                  ;	DS:BX = Transfer addr
   104                                  ;	CX = Number of sectors
   105                                  ;	[HIGH_SECTOR] = Absolute record number (HIGH)
   106                                  ;	DX = Absolute record number	       (LOW)
   107                                  ;	ES:BP = Base of drive parameters
   108                                  ; Function:
   109                                  ;	Call BIOS to perform disk read
   110                                  ; Outputs:
   111                                  ;	DI = CX on entry
   112                                  ;	CX = Number of sectors unsuccessfully transfered
   113                                  ;	AX = Status word as returned by BIOS (error code in AL if error)
   114                                  ;	Zero set if OK (from BIOS) (carry clear)
   115                                  ;	Zero clear if error (carry clear)
   116                                  ; SI Destroyed, others preserved
   117                                  
   118                                  	procedure   DskRead,NEAR
   118          ******************       warning: proc DskRead... [-w+user]
   119                                  ASSUME	DS:NOTHING,ES:NOTHING
   120                                  
   121                                  	Assert	ISDPB,<ES,BP>,"DskRead"
   122 00000000 51                      	PUSH	CX
   123 00000001 268A6617                	MOV	AH,[ES:BP + dpb_media]
   124 00000005 268A4601                	MOV	AL,[ES:BP + dpb_UNIT]
   125 00000009 53                      	PUSH	BX
   126 0000000A 06                      	PUSH	ES
   127 0000000B E8(0000)                	invoke	SETREAD
   128 0000000E EB29                    	JMP	DODSKOP
   129 00000010 90                      	nop	; identicalise
   130                                  
   131                                  Break	<DWRITE -- SEE ABOUT WRITING>
   132                                  
   133                                  ; Inputs:
   134                                  ;	DS:BX = Transfer address
   135                                  ;	CX = Number of sectors
   136                                  ;	[HIGH_SECTOR] = Absolute record number (HIGH)
   137                                  ;	DX = Absolute record number	       (LOW)
   138                                  ;	ES:BP = Base of drive parameters
   139                                  ;	[ALLOWED] must be set in case HARDERR_DOS called
   140                                  ; Function:
   141                                  ;	Calls BIOS to perform disk write. If BIOS reports
   142                                  ;	errors, will call HARDERRRW for further action.
   143                                  ; Output:
   144                                  ;	Carry set if error (currently, user FAILed to I 24)
   145                                  ; BP preserved. All other registers destroyed.
   146                                  
   147                                  	entry	DWRITE
   148                                  ASSUME	DS:NOTHING,ES:NOTHING
   149                                  
   150                                  	Assert	ISDPB,<ES,BP>,"DWrite"
   151 00000011 E81700                  	CALL	DSKWRITE
   152 00000014 7501C3                  	retz			; Carry clear
   153                                  READOP equ ReadOp	; NASM port label
   154 00000017 36C606[0000]01          	MOV	BYTE PTR [ss:READOP],1
   155 0000001D E83E00                  	invoke	HARDERRRW
   156 00000020 3C01                    	CMP	AL,1		; Check for retry
   157 00000022 74ED                    	JZ	DWRITE
   158 00000024 3C03                    	CMP	AL,3		; Check for FAIL
   159 00000026 F8                      	CLC
   160 00000027 7501                    	JNZ	NO_CAR2 	; Ignore
   161 00000029 F9                      	STC
   162                                  NO_CAR2:
   163 0000002A C3                      	return
   164                                  
   165                                  Break	<DSKWRITE -- PHYSICAL DISK WRITE>
   166                                  
   167                                  ; Inputs:
   168                                  ;	DS:BX = Transfer addr
   169                                  ;	CX = Number of sectors
   170                                  ;	DX = Absolute record number	       (LOW)
   171                                  ;	[HIGH_SECTOR] = Absolute record number (HIGH)
   172                                  ;	ES:BP = Base of drive parameters
   173                                  ; Function:
   174                                  ;	Call BIOS to perform disk read
   175                                  ; Outputs:
   176                                  ;	DI = CX on entry
   177                                  ;	CX = Number of sectors unsuccessfully transfered
   178                                  ;	AX = Status word as returned by BIOS (error code in AL if error)
   179                                  ;	Zero set if OK (from BIOS) (carry clear)
   180                                  ;	Zero clear if error (carry clear)
   181                                  ; SI Destroyed, others preserved
   182                                  
   183                                  	entry	DSKWRITE
   184                                  ASSUME	DS:NOTHING,ES:NOTHING
   185                                  
   186                                  	Assert	ISDPB,<ES,BP>,"DskWrite"
   187 0000002B 51                      	PUSH	CX
   188 0000002C 268A6617                	MOV	AH,[ES:BP + dpb_media]
   189 00000030 268A4601                	MOV	AL,[ES:BP + dpb_UNIT]
   190 00000034 53                      	PUSH	BX
   191 00000035 06                      	PUSH	ES
   192 00000036 E8(0000)                	invoke	SETWRITE
   193                                  DODSKOP:
   194 00000039 8CD9                    	MOV	CX,DS		; Save DS
   195 0000003B 1F                      	POP	DS		; DS:BP points to DPB
   196                                   assume ds:DPB
   197 0000003C 1E                      	PUSH	DS
   198 0000003D 3EC57613                	LDS	SI,[DS:BP + dpb_driver_addr]
   199                                   assume ds:nothing
   200 00000041 E8(0000)                	invoke	DEVIOCALL2
   201 00000044 8ED9                    	MOV	DS,CX		; Restore DS
   202                                   assume ds:nothing
   203 00000046 07                      	POP	ES		; Restore ES
   204                                   assume es:nothing
   205 00000047 5B                      	POP	BX
   206 00000048 368B0E[0000]            	MOV	CX,[ss:CALLSCNT]	; Number of sectors transferred
   207 0000004D 5F                      	POP	DI
   208 0000004E 29F9                    	SUB	CX,DI
   209 00000050 F7D9                    	NEG	CX		; Number of sectors not transferred
   210 00000052 36A1[0300]              	MOV	AX,[ss:DEVCALL + REQSTAT]
   211 00000056 36A3[0000]              	MOV	[ss:IFS_DRIVER_ERR],AX ;IFS. save it for IFS			;AN000;
   212 0000005A A90080                  	TEST	AX,STERR
   213 0000005D C3                      	return
   214                                  EndProc DskRead
   215                                  
   216                                  
   217                                  
   218                                  Break	<HardErrRW - map extended errors and call harderr_DOS>
   219                                  
   220                                  ; Inputs:
   221                                  ;	AX is error code from read or write
   222                                  ;	Other registers set as per HARDERR_DOS
   223                                  ; Function:
   224                                  ;	Checks the error code for special extended
   225                                  ;	errors and maps them if needed. Then invokes
   226                                  ;	Harderr_DOS
   227                                  ; Outputs:
   228                                  ;	Of HARDERR_DOS
   229                                  ; AX may be modified prior to call to HARDERR_DOS.
   230                                  ; No other registers altered.
   231                                  
   232                                  	procedure   HARDERRRW,near
   232          ******************       warning: proc HARDERRRW... [-w+user]
   233                                  ASSUME	DS:NOTHING,ES:NOTHING
   234                                  
   235 0000005E 3C0F                    	CMP	AL,error_I24_wrong_disk
   236 00000060 7513                    	JNZ	DO_ERR				; Nothing to do
   237 00000062 1E                      	PUSH	DS
   238 00000063 56                      	PUSH	SI
   239 00000064 36C536[0000]            	LDS	SI,[ss:CALLVIDRW]			; Get pointer from dev
   240                                   assume ds:nothing
   241 00000069 368C1E[0200]            	MOV	WORD PTR [ss:EXTERRPT+2],DS	; Set ext err pointer
   242 0000006E 368936[0000]            	MOV	WORD PTR [ss:EXTERRPT],SI
   243 00000073 5E                      	POP	SI
   244 00000074 1F                      	POP	DS
   245                                   assume ds:nothing
   246                                  DO_ERR:
   247 00000075 E8(0000)                	invoke	HARDERR_DOS
   248 00000078 C3                      	return
   249                                  
   250                                  EndProc HARDERRRW
   251                                  
   252                                  Break	<SETUP -- SETUP A DISK READ OR WRITE FROM USER>
   253                                  
   254                                  ; Inputs:
   255                                  ;	ES:DI point to SFT (value also in THISSFT)
   256                                  ;	[DMAADD] contains transfer address
   257                                  ;	CX = Byte count
   258                                  ;   WARNING Stack must be clean, two ret addrs on stack, 1st of caller,
   259                                  ;		2nd of caller of caller.
   260                                  ; Outputs:
   261                                  ;	    CX = byte count
   262                                  ;	    [THISDPB] = Base of drive parameters if file
   263                                  ;		      = Pointer to device header if device or NET
   264                                  ;	    ES:DI Points to SFT
   265                                  ;	    [NEXTADD] = Displacement of disk transfer within segment
   266                                  ;	    [TRANS] = 0 (No transfers yet)
   267                                  ;	    [BYTPOS] = Byte position in file
   268                                  ;
   269                                  ;	The following fields are relevant to local files (not devices) only:
   270                                  ;
   271                                  ;	    [SECPOS] = Position of first sector (local files only)
   272                                  ;	    [BYTSECPOS] = Byte position in first sector (local files only)
   273                                  ;	    [CLUSNUM] = First cluster (local files only)
   274                                  ;	    [SECCLUSPOS] = Sector within first cluster (local files only)
   275                                  ;	    [THISDRV] = Physical unit number (local files only)
   276                                  ;
   277                                  ;      RETURNS ONE LEVEL UP WITH:
   278                                  ;	   CX = 0
   279                                  ;	   CARRY = Clear
   280                                  ;	IF AN ERROR IS DETECTED
   281                                  ; All other registers destroyed
   282                                  
   283                                  	procedure   SETUP,NEAR
   283          ******************       warning: proc SETUP... [-w+user]
   284                                  	DOSAssume   CS,<DS>,"SetUp"
   285                                  	ASSUME	ES:NOTHING
   286                                  
   287                                  	Assert	    ISSFT,<ES,DI>,"SetUp"
   288 00000079 26C57507                	LDS	SI,[ES:DI + sf_devptr]
   289                                  ASSUME	DS:NOTHING
   290                                  THISDPB equ ThisDPB	; NASM port label
   291 0000007D 368C1E[0200]            	MOV	WORD PTR [ss:THISDPB+2],DS
   292 00000082 161F                    	context DS
   293 00000084 8936[0000]              	MOV	WORD PTR [THISDPB],SI
   294 00000088 8B1E[0000]              	MOV	BX,WORD PTR [DMAADD]
   295 0000008C 891E[0000]              	MOV	[NEXTADD],BX		;Set NEXTADD to start of Xaddr
   296                                  TRANS equ Trans	; NASM port label
   297 00000090 C606[0000]00            	MOV	BYTE PTR [TRANS],0	;No transferes
   298                                  sf_Position equ sf_position	; NASM port equate
   299 00000095 268B4515                	MOV	AX,WORD PTR [ES:DI + sf_Position]
   300 00000099 268B5517                	MOV	DX,WORD PTR [ES:DI + sf_Position+2]
   301                                  BYTPOS equ BytPos	; NASM port label
   302 0000009D 8916[0200]              	MOV	WORD PTR [BYTPOS+2],DX	;Set it
   303 000000A1 A3[0000]                	MOV	WORD PTR [BYTPOS],AX
   304 000000A4 26F745058080            	TEST	word [ES:DI + sf_flags],sf_isnet + devid_device
   305 000000AA 754C                    	JNZ	NOSETSTUFF		;Following not done on devs or NET
   306 000000AC 06                      	PUSH	ES
   307 000000AD C42E[0000]              	LES	BP,[THISDPB]		;Point at the DPB
   308                                   assume es:DPB
   309                                  	Assert	ISDPB,<ES,BP>,"Setup"
   310 000000B1 268A5E00                	MOV	BL,[ES:BP + dpb_drive]
   311                                  THISDRV equ ThisDrv	; NASM port label
   312 000000B5 881E[0000]              	MOV	[THISDRV],BL		;Set THISDRV
   313 000000B9 268B5E02                	MOV	BX,[ES:BP + dpb_sector_size]
   314                                  ;	CMP	DX,BX		; See if divide will overflow
   315                                  ;	JNC	EOFERR		; for 16 bit sector
   316                                  ;; 32 bit divide
   317 000000BD E8(0000)                	invoke	DIV32			      ; F.C. >32mb   ;AN000;
   318                                  SECPOS equ SecPos	; NASM port label
   319 000000C0 A3[0000]                	MOV	WORD PTR [SECPOS],AX	      ; F.C. >32mb   ;AN000;
   320 000000C3 8B1E[0000]              	MOV	BX,[HIGH_SECTOR]	      ; F.C. >32mb   ;AN000;
   321 000000C7 891E[0200]              	MOV	WORD PTR [SECPOS+2],BX	      ; F.C. >32mb   ;AN000;
   322                                  
   323                                  BYTSECPOS equ BytSecPos	; NASM port label
   324 000000CB 8916[0000]              	MOV	[BYTSECPOS],DX
   325 000000CF 89C2                    	MOV	DX,AX
   326 000000D1 26224604                	AND	AL,[ES:BP + dpb_cluster_mask]
   327                                  SECCLUSPOS equ SecClusPos	; NASM port label
   328 000000D5 A2[0000]                	MOV	[SECCLUSPOS],AL
   329 000000D8 89C8                    	MOV	AX,CX		; Save byte count
   330                                  ;	MOV	CL,[ES:BP.dpb_cluster_shift]
   331 000000DA FF36[0200]              	PUSH	WORD PTR [SECPOS+2]	     ; F.C. >32mb	   ;AN000;
   332 000000DE 8F06[0000]              	POP	word [HIGH_SECTOR]		     ; F.C. >32mb	   ;AN000;
   333 000000E2 50                      	PUSH	AX			     ; F.C. >32mb save ax  ;AN000;
   334 000000E3 89D0                    	MOV	AX,DX			     ; F.C. >32mb ax=dx    ;AN000;
   335 000000E5 E8(0000)                	invoke	SHR32			     ; F.C. >32mb shift ax ;AN000;
   336 000000E8 89C2                    	MOV	DX,AX			     ; F.C. >32mb dx=ax    ;AN000;
   337 000000EA 58                      	POP	AX			     ; F.C. >32mb restore dx ;AN000;
   338                                  
   339                                  ;	SHR	DX,CL
   340 000000EB 263B560D                	CMP	DX,[ES:BP + dpb_max_cluster]   ;>32mb  if > disk size ;AN000;	;AN000;
   341 000000EF 771C                    	JA	EOFERR			     ;>32mb    then EOF     ;AN000;	;AN000;
   342                                  
   343                                  CLUSNUM equ ClusNum	; NASM port label
   344 000000F1 8916[0000]              	MOV	[CLUSNUM],DX
   345 000000F5 07                      	POP	ES		; ES:DI point to SFT
   346                                   assume es:nothing
   347 000000F6 89C1                    	MOV	CX,AX		; Put byte count back in CX
   348                                  NOSETSTUFF:
   349 000000F8 89C8                    	MOV	AX,CX		; Need it in AX too
   350 000000FA 0306[0000]              	ADD	AX,WORD PTR [DMAADD]	 ; See if it will fit in one segment
   351 000000FE 730C                    	JNC	OK		; Must be less than 64K
   352 00000100 A1[0000]                	MOV	AX,WORD PTR [DMAADD]
   353 00000103 F7D8                    	NEG	AX		; Amount of room left in segment (know
   354                                  				;    less than 64K since max value of CX
   355                                  				;    is FFFF).
   356 00000105 7501                    	JNZ	NoDec
   357 00000107 48                      	DEC	AX
   358                                  NoDec:
   359 00000108 89C1                    	MOV	CX,AX		; Can do this much
   360 0000010A E304                    	JCXZ	NOROOM		; Silly user gave Xaddr of FFFF in segment
   361                                  OK:
   362 0000010C C3                      	return
   363                                  
   364                                  EOFERR:
   365 0000010D 07                      	POP	ES		; ES:DI point to SFT
   366                                   assume es:nothing
   367 0000010E 31C9                    	XOR	CX,CX		; No bytes read
   368                                  ;;;;;;;;;;; 7/18/86
   369                                  ;	MOV	BYTE PTR [DISK_FULL],1	    ; set disk full flag
   370                                  ;;;;;;;;;;;
   371                                  NOROOM:
   372 00000110 5B                      	POP	BX		; Kill return address
   373 00000111 F8                      	CLC
   374 00000112 C3                      	return			; RETURN TO CALLER OF CALLER
   375                                  EndProc SETUP
   376                                  
   377                                  Break	<BREAKDOWN -- CUT A USER READ OR WRITE INTO PIECES>
   378                                  
   379                                  ; Inputs:
   380                                  ;	CX = Length of disk transfer in bytes
   381                                  ;	ES:BP = Base of drive parameters
   382                                  ;	[BYTSECPOS] = Byte position witin first sector
   383                                  ; Outputs:
   384                                  ;	[BYTCNT1] = Bytes to transfer in first sector
   385                                  ;	[SECCNT_DOS] = No. of whole sectors to transfer
   386                                  ;	[BYTCNT2] = Bytes to transfer in last sector
   387                                  ; AX, BX, DX destroyed. No other registers affected.
   388                                  
   389                                  	procedure   BREAKDOWN,near
   389          ******************       warning: proc BREAKDOWN... [-w+user]
   390                                  	DOSAssume   CS,<DS>,"BreakDown"
   391                                  	ASSUME	ES:NOTHING
   392                                  
   393                                  	Assert	    ISDPB,<ES,BP>,"BreakDown"
   394 00000113 A1[0000]                	MOV	AX,[BYTSECPOS]
   395 00000116 89CB                    	MOV	BX,CX
   396 00000118 09C0                    	OR	AX,AX
   397 0000011A 740E                    	JZ	SAVFIR		; Partial first sector?
   398 0000011C 262B4602                	SUB	AX,[ES:BP + dpb_sector_size]
   399 00000120 F7D8                    	NEG	AX		; Max number of bytes left in first sector
   400 00000122 29C3                    	SUB	BX,AX		; Subtract from total length
   401 00000124 7304                    	JAE	SAVFIR
   402 00000126 01D8                    	ADD	AX,BX		; Don't use all of the rest of the sector
   403 00000128 31DB                    	XOR	BX,BX		; And no bytes are left
   404                                  SAVFIR:
   405                                  BYTCNT1 equ BytCnt1	; NASM port label
   406 0000012A A3[0000]                	MOV	[BYTCNT1],AX
   407 0000012D 89D8                    	MOV	AX,BX
   408 0000012F 31D2                    	XOR	DX,DX
   409 00000131 26F77602                	DIV	word [ES:BP + dpb_sector_size]  ; How many whole sectors?
   410                                  SECCNT_DOS equ SecCnt_DOS	; NASM port label
   411 00000135 A3[0000]                	MOV	[SECCNT_DOS],AX
   412                                  BYTCNT2 equ BytCnt2	; NASM port label
   413 00000138 8916[0000]              	MOV	[BYTCNT2],DX	; Bytes remaining for last sector
   414 0000013C 0B16[0000]              	OR	DX,[BYTCNT1]
   415 00000140 75D0                    	retnz			; NOT (BYTCNT1 = BYTCNT2 = 0)
   416 00000142 83F801                  	CMP	AX,1
   417 00000145 75CB                    	retnz
   418 00000147 268B4602                	MOV	AX,[ES:BP + dpb_sector_size]	 ; Buffer EXACT one sector I/O
   419 0000014B A3[0000]                	MOV	[BYTCNT2],AX
   420 0000014E 8916[0000]              	MOV	[SECCNT_DOS],DX		; DX = 0
   421                                  RET45:
   422 00000152 C3                      	return
   423                                  EndProc BreakDown
   424                                  
   425                                  ; ES:DI points to SFT. This entry used by NET_READ
   426                                  ; Carry set if to return error (CX=0,AX=error_sharing_violation).
   427                                  ; Else do retrys.
   428                                  ; ES:DI,DS,CX preserved
   429                                  
   430                                  	procedure READ_LOCK_VIOLATION,NEAR
   430          ******************       warning: proc READ_LOCK_VIOLATION... [-w+user]
   431                                  	DOSAssume   CS,<DS>,"Read_Lock_Violation"
   432                                  	ASSUME	ES:NOTHING
   433                                  
   434                                  	Assert	    ISSFT,<ES,DI>,"ReadLockViolation"
   435                                  
   436 00000153 C606[0000]00            	MOV	byte [READOP],0
   437                                  ERR_ON_CHECK:
   438 00000158 26F745020080            	TEST	word [ES:DI + sf_mode],sf_isfcb
   439 0000015E 750E                    	JNZ	HARD_ERR
   440 00000160 51                      	PUSH	CX
   441 00000161 268A4D02                	MOV	CL,BYTE PTR [ES:DI + sf_mode]
   442 00000165 80E1F0                  	AND	CL,sharing_mask
   443 00000168 80F900                  	CMP	CL,sharing_compat
   444 0000016B 59                      	POP	CX
   445 0000016C 7505                    	JNE	NO_HARD_ERR
   446                                  HARD_ERR:
   447 0000016E E8(0000)                	invoke	LOCK_VIOLATION
   448 00000171 73DF                    	retnc				; User wants Retrys
   449                                  NO_HARD_ERR:
   450 00000173 31C9                    	XOR	CX,CX			;No bytes transferred
   451 00000175 B82100                  	MOV	AX,error_lock_violation
   452 00000178 F9                      	STC
   453 00000179 C3                      	return
   454                                  
   455                                  EndProc READ_LOCK_VIOLATION
   456                                  
   457                                  ; Same as READ_LOCK_VIOLATION except for READOP.
   458                                  ; This entry used by NET_WRITE
   459                                  	procedure WRITE_LOCK_VIOLATION,NEAR
   459          ******************       warning: proc WRITE_LOCK_VIOLATION... [-w+user]
   460                                  	DOSAssume   CS,<DS>,"Write_Lock_Violation"
   461                                  	ASSUME	ES:NOTHING
   462                                  	Assert	    ISSFT,<ES,DI>,"WriteLockViolation"
   463                                  
   464 0000017A C606[0000]01            	MOV	byte [READOP],1
   465 0000017F EBD7                    	JMP	ERR_ON_CHECK
   466                                  
   467                                  EndProc WRITE_LOCK_VIOLATION
   468                                  
   469                                  
   470                                  Break	<DISKREAD -- PERFORM USER DISK READ>
   471                                  
   472                                  ; Inputs:
   473                                  ;	Outputs of SETUP
   474                                  ; Function:
   475                                  ;	Perform disk read
   476                                  ; Outputs:
   477                                  ;    Carry clear
   478                                  ;	CX = No. of bytes read
   479                                  ;	ES:DI point to SFT
   480                                  ;	SFT offset and cluster pointers updated
   481                                  ;    Carry set
   482                                  ;	CX = 0
   483                                  ;	ES:DI point to SFT
   484                                  ;	AX has error code
   485                                  
   486                                  	procedure   DISKREAD,NEAR
   486          ******************       warning: proc DISKREAD... [-w+user]
   487                                  	DOSAssume   CS,<DS>,"DiskRead"
   488                                  	ASSUME	ES:NOTHING
   489                                  
   490                                  	Assert	ISSFT,<ES,DI>,"DISKREAD"
   491 00000181 26FF750B                	PUSH	word [ES:DI + sf_firclus]	; set up 1st cluster # for FastSeek
   492 00000185 8F06[0000]              	POP	word [FSeek_firclus] 	; 11/5/86
   493                                  
   494 00000189 268B4511                	MOV	AX,WORD PTR [ES:DI + sf_size]
   495 0000018D 268B5D13                	MOV	BX,WORD PTR [ES:DI + sf_size+2]
   496 00000191 2B06[0000]              	SUB	AX,WORD PTR [BYTPOS]
   497 00000195 1B1E[0200]              	SBB	BX,WORD PTR [BYTPOS+2]
   498 00000199 722D                    	JB	RDERR			;Read starts past EOF
   499 0000019B 750A                    	JNZ	ENUF			;More than 64k to EOF
   500 0000019D 09C0                    	OR	AX,AX
   501 0000019F 7427                    	JZ	RDERR			;Read starts at EOF
   502 000001A1 39C8                    	CMP	AX,CX
   503 000001A3 7302                    	JAE	ENUF			;I/O fits
   504 000001A5 89C1                    	MOV	CX,AX			;Limit read to up til EOF
   505                                  ENUF:
   506 000001A7 E8(0000)                	invoke	CHECK_READ_LOCK 	;IFS. check read lock			 ;AN000;
   507                                  Read_Ok equ READ_OK	; NASM port label
   508 000001AA 7301                    	JNC	Read_Ok 		; There are no locks
   509 000001AC C3                      	return
   510                                  
   511                                  READ_OK:
   512 000001AD C42E[0000]              	LES	BP,[THISDPB]
   513                                  	Assert	ISDPB,<ES,BP>,"DISKREAD/ReadOK"
   514 000001B1 268A4600                	MOV	AL,[ES:BP + dpb_drive]	; set up drive # for FastSeek
   515 000001B5 A2[0000]                	MOV	[FSeek_drive],AL	; 11/5/86  ;AN000;
   516                                  
   517 000001B8 E858FF                  	CALL	BREAKDOWN
   518 000001BB 8B0E[0000]              	MOV	CX,[CLUSNUM]
   519 000001BF E8(0000)                	invoke	FNDCLUS
   520                                  ;------------------------------------------------------------------------
   521                                  %IFN IBMCOPYRIGHT
   522 000001C2 7217                    	JC	SET_ACC_ERR_DS		; fix to take care of I24 fail
   523                                  					; migrated from 330a - HKN
   524                                  %ENDIF
   525                                  ;------------------------------------------------------------------------
   526 000001C4 09C9                    	OR	CX,CX
   527 000001C6 741C                    	JZ	SKIPERR
   528                                  RDERR:
   529 000001C8 C606[0000]01            	MOV	byte [DISK_FULL],1		;MS. EOF detection  ;AN000;
   530 000001CD B40E                    	MOV	AH,0EH			;MS. read/data/fail ;AN000;
   531 000001CF E9(0000)                	transfer WRTERR22
   532 000001D2 E90001                  RDLASTJ:JMP	RDLAST
   533 000001D5 E91A01                  SETSFTJ2: JMP	SETSFT
   534                                  
   535                                  CANOT_READ:
   536 000001D8 59                      	POP	CX		; Clean stack
   537 000001D9 59                      	POP	CX
   538 000001DA 5B                      	POP	BX
   539                                  
   540                                  	entry	SET_ACC_ERR_DS
   541                                  ASSUME	DS:NOTHING,ES:NOTHING
   542 000001DB 161F                    	Context DS
   543                                  
   544                                  	entry	SET_ACC_ERR
   545                                  	DOSAssume   CS,<DS>,"SET_ACC_ERR"
   546                                  
   547 000001DD 31C9                    	XOR	CX,CX
   548 000001DF B80500                  	MOV	AX,error_access_denied
   549 000001E2 F9                      	STC
   550 000001E3 C3                      	return
   551                                  
   552                                  SKIPERR:
   553                                  LASTPOS equ LastPos	; NASM port label
   554 000001E4 8916[0000]              	MOV	[LASTPOS],DX
   555 000001E8 891E[0000]              	MOV	[CLUSNUM],BX
   556 000001EC 833E[0000]00            	CMP	word [BYTCNT1],0
   557 000001F1 7405                    	JZ	RDMID
   558 000001F3 E8(0000)                	invoke	BUFRD
   559 000001F6 72E3                    	JC	SET_ACC_ERR_DS
   560                                  RDMID:
   561 000001F8 833E[0000]00            	CMP	word [SECCNT_DOS],0
   562 000001FD 74D3                    	JZ	RDLASTJ
   563 000001FF E8(0000)                	invoke	NEXTSEC
   564 00000202 72D1                    	JC	SETSFTJ2
   565 00000204 C606[0000]01            	MOV	BYTE PTR [TRANS],1	; A transfer is taking place
   566                                  ONSEC:
   567 00000209 8A16[0000]              	MOV	DL,[SECCLUSPOS]
   568 0000020D 8B0E[0000]              	MOV	CX,[SECCNT_DOS]
   569 00000211 8B1E[0000]              	MOV	BX,[CLUSNUM]
   570                                  RDLP:
   571 00000215 E8(0000)                	invoke	OPTIMIZE
   572 00000218 72C1                    	JC	SET_ACC_ERR_DS
   573 0000021A 57                      	PUSH	DI
   574 0000021B 50                      	PUSH	AX
   575 0000021C 53                      	PUSH	BX
   576                                  allowed_RETRY equ Allowed_RETRY	; NASM port equate
   577                                  allowed_FAIL equ Allowed_FAIL	; NASM port equate
   578                                  allowed_IGNORE equ Allowed_IGNORE	; NASM port equate
   579 0000021D C606[0000]38            	MOV	byte [ALLOWED],allowed_RETRY + allowed_FAIL + allowed_IGNORE
   580 00000222 8E1E[0200]              	MOV	DS,WORD PTR [DMAADD+2]
   581                                  ASSUME	DS:NOTHING
   582 00000226 52                      	PUSH	DX
   583 00000227 51                      	PUSH	CX
   584                                  %ifndef BUF2
   585                                  	invoke	SET_RQ_SC_PARMS 	 ;LB. do this for SC		       ;AN000;
   586                                  
   587                                  %IF	BUFFERFLAG
   588                                  	pushf
   589                                  	cmp	byte [ss:BUF_EMS_SAFE_FLAG], 1
   590                                  	je	safe_read
   591                                  save_map equ SAVE_MAP	; NASM port label
   592                                  	call	save_map
   593                                  restore_user_map equ RESTORE_USER_MAP	; NASM port label
   594                                  	call	restore_user_map
   595                                  safe_read:
   596                                  	popf
   597                                  %ENDIF
   598                                  %endif
   599                                  
   600 00000228 E8(0000)                	invoke	DREAD
   601                                  
   602                                  %ifndef BUF2
   603                                  %IF	BUFFERFLAG
   604                                  	pushf
   605                                  	cmp	byte [ss:BUF_EMS_SAFE_FLAG], 1
   606                                  	je	safe_mapping
   607                                  save_user_map equ SAVE_USER_MAP	; NASM port label
   608                                  	call	save_user_map
   609                                  restore_map equ RESTORE_MAP	; NASM port label
   610                                  	call	restore_map
   611                                  safe_mapping:
   612                                  	popf
   613                                  %ENDIF
   614                                  %endif
   615                                  
   616 0000022B 5B                      	POP	BX
   617 0000022C 5A                      	POP	DX
   618 0000022D 7302                    	JNC	SKP_CANOT_READ
   619 0000022F EBA7                    	JMP	CANOT_READ
   620                                  SKP_CANOT_READ:
   621 00000231 36891E[0000]            	MOV	[ss:TEMP_VAR],BX		  ;LB. save sector count		;AN000;
   622 00000236 368916[0000]            	MOV	[ss:TEMP_VAR2],DX		  ;LB. 1st sector			;AN000;
   623                                  SCAN_NEXT:
   624                                  ;;;;;;; invoke	GETCURHEAD		  ;LB. get buffer header		;AN000;
   625 0000023B 52                      	PUSH	DX			  ;LB. save regs			;AN000;
   626 0000023C 50                      	PUSH	AX			  ;LB.					;AN000;
   627 0000023D 53                      	PUSH	BX			  ;LB.					;AN000;
   628                                  %ifdef BUF2
   629 0000023E 36833E[0000]00          	cmp word [ss:BUF2_Dirty_Count], 0
   630 00000244 7505                    	jne yesdirty
   631                                  %else
   632                                  	MOV	AX,DX			  ;LB.
   633                                  ;	MOV	DX,[HIGH_SECTOR]	  ;LB. HASH(sector#) and get entry #	;AN000;
   634                                  	XOR	DX,DX			  ;LB. to avoid divide overflow 	;AN000;
   635                                  	DIV	word [ss:BUF_HASH_COUNT]	  ;LB. get remainder			;AN000;
   636                                  	ADD	DX,DX			  ;LB. 8 bytes per entry		;AN000;
   637                                  	ADD	DX,DX			  ;LB.					;AN000;
   638                                  	ADD	DX,DX			  ;LB. times 8				;AN000;
   639                                  
   640                                  	LDS	DI,[ss:BUF_HASH_PTR]	  ;LB. get Hash Table addr		;AN000;
   641                                  	ADD	DI,DX			  ;LB position to entry 		;AN000;
   642                                  Dirty_Count equ DIRTY_COUNT	; NASM port equate
   643                                  	CMP	byte [DI + Dirty_Count],0	  ;LB dirty hash entry ?		;AN000;
   644                                  	JNZ	yesdirty		  ;LB yes and map it			;AN000;
   645                                  %endif
   646 00000246 5B                      	POP	BX			  ;LB.					;AN000;
   647 00000247 58                      	POP	AX			  ;LB.					;AN000;
   648 00000248 5A                      	POP	DX			  ;LB.					;AN000;
   649                                  %IFN	BUFFERFLAG
   650                                  	JMP	SHORT end_scan		  ;LB.					;AN000;
   651                                  %ELSE
   652                                  END_SCAN equ end_scan	; NASM port label
   653 00000249 EB62                    	JMP	END_SCAN
   654                                  %ENDIF
   655                                  
   656                                  yesdirty:
   657                                  %ifdef BUF2
   658 0000024B 36C53E[0000]            	lds di, [ss:BUFFHEAD]
   659                                  LASTBUFFER equ LastBuffer	; NASM port label
   660 00000250 36830E[0000]FF          	or WORD PTR [ss:LASTBUFFER], -1   ;LB. invalidate last buffer		;AN000;
   661                                  %else
   662                                  	MOV	WORD PTR [ss:CurHashEntry+2],DS ;LB. update current Hash entry ptr ;AN000;
   663                                  	MOV	WORD PTR [ss:CurHashEntry],DI ;LB. 				;AN000;
   664                                  LASTBUFFER equ LastBuffer	; NASM port label
   665                                  	MOV	WORD PTR [ss:LASTBUFFER],-1   ;LB. invalidate last buffer		;AN000;
   666                                  	MOV	BX,[DI + EMS_PAGE_NUM]	  ;LB. logical page			;AN000;
   667                                  
   668                                  %IFN	BUFFERFLAG
   669                                  	LDS	DI,[DI + BUFFER_BUCKET]	  ;LB. ds:di is 1st buffer addr 	;AN000;
   670                                  invalid instruction fixme
   671                                  ; ldos: need seg override?
   672                                  	MOV	[FIRST_BUFF_ADDR],DI	  ;LB. save first buff addr 1/19/88	;AN000;
   673                                  	invoke	SET_MAP_PAGE		  ;LB. activate handle if EMS there	;AN000;
   674                                  %ELSE
   675                                  ;	int	3
   676                                  	push	ds
   677                                  	push	di		; save hash ptr
   678                                  
   679                                  	LDS	DI,[DI + BUFFER_BUCKET]	  ;ds:di is 1st buffer addr
   680                                  	POP	AX		; Recall transfer address
   681                                  	PUSH	AX
   682                                  	PUSH	DI		; Save search environment
   683                                  	PUSH	DX		     ; F.C. no need for high sector, <64K
   684                                  	push	cx
   685                                  
   686                                  	MOV	DX,[ss:TEMP_VAR2]	     ;LB. get 1st sector #
   687                                  	SUB	DX,WORD PTR [DI + buf_sector]   ; How far into transfer?
   688                                  	NEG	DX
   689                                  	MOV	DI,AX
   690                                  	MOV	AX,DX
   691                                  	MOV	CX,[ES:BP + dpb_sector_size]
   692                                  	MUL	CX
   693                                  	ADD	DI,AX		; Put the buffer here
   694                                  	mov	[ss:CURADD], di
   695                                  	
   696                                  	pop	cx
   697                                  	pop	dx
   698                                  	pop	di
   699                                  
   700                                  	invoke	SET_MAP_PAGE		  ;LB. activate handle if EMS there	;AN000;
   701                                  	pop	di			; restore hash ptr.
   702                                  	pop	ds
   703                                  	LDS	DI,[DI + BUFFER_BUCKET]	  ;LB. ds:di is 1st buffer addr 	;AN000;
   704                                  	MOV	[ss:FIRST_BUFF_ADDR],DI	  ;LB. save first buff addr 1/19/88	;AN000;
   705                                  %ENDIF
   706                                  										;AN000;
   707                                  %endif	; BUF2
   708 00000256 5B                      	POP	BX			  ;LB.					;AN000;
   709 00000257 58                      	POP	AX			  ;LB.					;AN000;
   710 00000258 5A                      	POP	DX			  ;LB.					;AN000;
   711                                  
   712                                  
   713                                  	Assert	ISDPB,<ES,BP>,"DISKREAD/RdLp"
   714 00000259 268A4600                	MOV	AL,[ES:BP + dpb_drive]
   715                                  NXTBUF: 			; Must see if one of these sectors is buffered
   716 0000025D E8(0000)                	invoke	BUFF_RANGE_CHECK			   ;F.C. >32mb
   717 00000260 7305                    	JNC	inrange 		   ;LB. 				;AN000;
   718                                  %ifdef BUF2
   719 00000262 C53D                    	lds di, [di + NEXTBUF]
   720                                  %else
   721                                  	mov	DI,[DI + buf_next]	   ;LB. get next buffer 1/19/88 	;AN000;
   722                                  %endif
   723 00000264 EB42                    	JMP	DONXTBUF		   ;LB. 				;AN000;
   724 00000266 90                      	nop	; identicalise
   725                                  inrange:
   726 00000267 F6450540                	TEST	byte [DI + buf_flags],buf_dirty
   727 0000026B 7438                    	JZ	CLBUFF			; Buffer is clean, so OK
   728                                  ; A sector has been read in when a dirty copy of it is in a buffer
   729                                  ; The buffered sector must now be read into the right place
   730 0000026D 58                      	POP	AX		; Recall transfer address
   731 0000026E 50                      	PUSH	AX
   732 0000026F 57                      	PUSH	DI		; Save search environment
   733 00000270 52                      	PUSH	DX		     ; F.C. no need for high sector, <64K
   734                                  
   735 00000271 368B16[0000]            	MOV	DX,[ss:TEMP_VAR2]	     ;LB. get 1st sector #
   736 00000276 2B5508                  	SUB	DX,WORD PTR [DI + buf_sector]   ; How far into transfer?
   737 00000279 F7DA                    	NEG	DX
   738 0000027B 89FE                    	MOV	SI,DI
   739 0000027D 89C7                    	MOV	DI,AX
   740 0000027F 89D0                    	MOV	AX,DX
   741 00000281 268B4E02                	MOV	CX,[ES:BP + dpb_sector_size]
   742 00000285 F7E1                    	MUL	CX
   743 00000287 01C7                    	ADD	DI,AX		; Put the buffer here
   744 00000289 8D7410                  	LEA	SI,[SI + BUFINSIZ]
   745 0000028C D1E9                    	SHR	CX,1
   746 0000028E 06                      	PUSH	ES
   747 0000028F 368E06[0200]            	MOV	ES,WORD PTR [ss:DMAADD+2]
   748                                   assume es:nothing
   749 00000294 F3A5                    	REP	MOVSW
   750 00000296 7301                    	JNC	EVENMOV
   751 00000298 A4                      	MOVSB
   752                                  EVENMOV:
   753 00000299 07                      	POP	ES
   754                                   assume es:DPB
   755 0000029A 5A                      	POP	DX
   756 0000029B 5F                      	POP	DI
   757 0000029C 268A4600                	MOV	AL,[ES:BP + dpb_drive]
   758 000002A0 E8(0000)                	invoke	SCANPLACE		 ;LB. done with this chain		;AN000;
   759 000002A3 EB08                    	JMP	SHORT end_scan		 ;LB.					;AN000;
   760                                  CLBUFF:
   761 000002A5 E8(0000)                	invoke	SCANPLACE
   762                                  DONXTBUF:
   763                                  %ifdef BUF2
   764 000002A8 83FFFF                  	cmp di, -1
   765                                  %else
   766                                  	CMP	DI,[ss:FIRST_BUFF_ADDR]	 ;LB. end of buffers			;AN000;
   767                                  %endif
   768 000002AB 75B0                    	JNZ	NXTBUF
   769                                  end_scan:
   770 000002AD 83C201                  	ADD	DX,1			 ;LB. next sector #			;AN000;
   771 000002B0 368316[0000]00          	ADC	word [ss:HIGH_SECTOR],0 	 ;LB.					;AN000;
   772 000002B6 36FF0E[0000]            	DEC	word [ss:TEMP_VAR]		 ;LB. decrement count			;AN000;
   773 000002BB 7403                    	JZ	SCAN_DONE		 ;LB. scan next sector			;AN000;
   774 000002BD E97BFF                  	JMP	SCAN_NEXT		 ;LB. scan next sector			;AN000;
   775                                  SCAN_DONE:
   776 000002C0 161F                    	Context DS
   777 000002C2 59                      	POP	CX
   778 000002C3 59                      	POP	CX
   779 000002C4 5B                      	POP	BX
   780 000002C5 E30E                    	JCXZ	RDLAST
   781 000002C7 E8(0000)                	invoke	IsEOF			; test for eof on fat size
   782 000002CA 7326                    	JAE	SETSFT
   783 000002CC B200                    	MOV	DL,0
   784 000002CE FF06[0000]              	INC	word [LASTPOS]	; We'll be using next cluster
   785 000002D2 E940FF                  	JMP	RDLP
   786                                  
   787                                  RDLAST:
   788 000002D5 A1[0000]                	MOV	AX,[BYTCNT2]
   789 000002D8 09C0                    	OR	AX,AX
   790 000002DA 7416                    	JZ	SETSFT
   791 000002DC A3[0000]                	MOV	[BYTCNT1],AX
   792 000002DF E8(0000)                	invoke	NEXTSEC
   793 000002E2 720E                    	JC	SETSFT
   794 000002E4 C706[0000]0000          	MOV	word [BYTSECPOS],0
   795 000002EA E8(0000)                	invoke	BUFRD
   796 000002ED 7303                    	JNC	SETSFT
   797 000002EF E9E9FE                  	JMP	SET_ACC_ERR_DS
   798                                  
   799                                  ; Inputs:
   800                                  ;	[NEXTADD],[CLUSNUM],[LASTPOS] set to determine transfer size
   801                                  ;		and set cluster fields
   802                                  ; Function:
   803                                  ;	Update [THISSFT] based on the transfer
   804                                  ; Outputs:
   805                                  ;	sf_position, sf_lstclus, and sf_cluspos updated
   806                                  ;	ES:DI points to [THISSFT]
   807                                  ;	CX No. of bytes transferred
   808                                  ;	Carry clear
   809                                  
   810                                  	entry	SETSFT
   811                                  	DOSAssume   CS,<DS>,"SetSFT"
   812                                  	ASSUME	ES:NOTHING
   813                                  
   814 000002F2 C43E[0000]              	LES	DI,[THISSFT]
   815                                  
   816                                  ; Same as SETSFT except ES:DI already points to SFT
   817                                  	entry	SETCLUS
   818                                  	DOSAssume   CS,<DS>,"SetClus"
   819                                  	ASSUME	ES:NOTHING
   820                                  
   821                                  	Assert	ISSFT,<ES,DI>,"SetClus"
   822 000002F6 8B0E[0000]              	MOV	CX,[NEXTADD]
   823 000002FA 2B0E[0000]              	SUB	CX,WORD PTR [DMAADD]	 ; Number of bytes transfered
   824 000002FE 26F745058000            	TEST	word [ES:DI + sf_flags],devid_device
   825                                  ADDREC equ AddRec	; NASM port label
   826 00000304 750E                    	JNZ	ADDREC			 ; don't set clusters if device
   827 00000306 A1[0000]                	MOV	AX,[CLUSNUM]
   828 00000309 26894535                	MOV	[ES:DI + sf_lstclus],AX
   829 0000030D A1[0000]                	MOV	AX,[LASTPOS]
   830 00000310 26894519                	MOV	[ES:DI + sf_cluspos],AX
   831                                  
   832                                  ; Inputs:
   833                                  ;	ES:DI points to SFT
   834                                  ;	CX is No. Bytes transferred
   835                                  ; Function:
   836                                  ;	Update the SFT offset based on the transfer
   837                                  ; Outputs:
   838                                  ;	sf_position updated to point to first byte after transfer
   839                                  ;	ES:DI points to SFT
   840                                  ;	CX No. of bytes transferred
   841                                  ;	Carry clear
   842                                  
   843                                  	entry	AddRec
   844                                  	DOSAssume   CS,<DS>,"AddRec"
   845                                  	ASSUME	ES:NOTHING
   846                                  
   847                                  	Assert	ISSFT,<ES,DI>,"AddRec"
   848 00000314 E309                    	JCXZ	RET28		; If no records read,  don't change position
   849 00000316 26014D15                	ADD	WORD PTR [ES:DI + sf_position],CX  ; Update current position
   850 0000031A 2683551700              	ADC	WORD PTR [ES:DI + sf_position+2],0
   851 0000031F F8                      RET28:	CLC
   852 00000320 C3                      	return
   853                                  EndProc DISKREAD
   854                                  
   855                                      END
   856                                  
   857                                  
