     1                                  ;	SCCSID = @(#)buf.asm	1.1 85/04/09
     2                                  ;TITLE	BUF - MSDOS buffer management
     3                                  ;NAME	BUF
     4                                  ; Low level routines for buffer cache management
     5                                  ;
     6                                  ;   GETCURHEAD
     7                                  ;   SET_MAP_PAGE
     8                                  ;   SAVE_MAP
     9                                  ;   RESTORE_MAP
    10                                  ;   SETVISIT
    11                                  ;   ScanPlace
    12                                  ;   PLACEBUF
    13                                  ;   PLACEHEAD
    14                                  ;   PointComp
    15                                  ;   GETBUFFR
    16                                  ;   GETBUFFRB
    17                                  ;   FlushBuf
    18                                  ;   BufWrite
    19                                  ;   SKIPVISIT
    20                                  ;   SET_RQ_SC_PARMS
    21                                  ;
    22                                  ;   Revision history:
    23                                  ;
    24                                  ;	AN000  version 4.00  Jan. 1988
    25                                  ;	A004   PTM 3765 -- Disk reset failed
    26                                  
    27                                  ;	NEW PROCS FOR BUFFERS FIX:
    28                                  
    29                                  ;		SAVE_USER_MAP
    30                                  ;		RESTORE_USER_MAP
    31                                  ;		DETECT_COLLISION
    32                                  ;		SETUP_EMS_BUFFERS
    33                                  ;
    34                                  
    35                                  
    36                                  ;
    37                                  ; get the appropriate segment definitions
    38                                  ;
    39                                  [list -]
    39          ******************       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
    41                                  
    42                                  [list +]
    43                                  section DOSCODECODE
    44                                  [list -]
    44          ******************       warning: out: ... for DOS Version 4.00 ... [-w+user]
    44          ******************       warning: out: BPB.INC... [-w+user]
    44          ******************       warning: out: ... CLONE version build switch on ... [-w+user]
    44          ******************       warning: out: DEVSYM.INC... [-w+user]
    44          ******************       warning: out: ... CLONE version build switch on ... [-w+user]
    52                                  
    53                                  %ifdef BUF2
    54                                   %define FROMBUFNAS
    55                                   %include "buf2.nas"
     1                              <1> %ifdef FROMBUFNAS
     2                              <1> [list -]
     6                              <1> %else
     7                              <1> ;
     8                              <1> ; buffer management for MSDOS
     9                              <1> ;
    10                              <1> 
    11                              <1> %include "dosseg.nas"
    12                              <1> 
    13                              <1> section DOSCODECODE
    14                              <1> 
    15                              <1> [list -]
    16                              <1> ;.xcref
    17                              <1> %define BUF2 1
    18                              <1> %include "dossym.mac"
    19                              <1> %include "devsym.mac"
    20                              <1> %include "dosmac.mac"
    21                              <1> ;.cref
    22                              <1> [list +]
    23                              <1> %endif
    24                              <1> 
    25                              <1>         i_need  BuffHead,DWORD
    26                              <1>         i_need  BuffFree,DWORD
    27                              <1>         i_need  PreRead,WORD
    28                              <1>         i_need  LastBuffer,DWORD
    29                              <1>         i_need  CurBuf,DWORD
    30                              <1>         i_need  WPErr,BYTE
    31                              <1> 	i_need	ALLOWED,BYTE
    32                              <1> 	i_need	FAILERR,BYTE
    33                              <1> 	i_need	HIGH_SECTOR,WORD	     ; DOS 4.00 >32mb			;AN000;
    34                              <1> 	i_need	DOS34_FLAG,WORD 	     ; DOS 4.00 common flag		;AN000;
    35                              <1> 	i_need  BUF2_Dirty_Count,WORD
    36                              <1> 
    37                              <1> 
    38                              <1> BUFFHEAD equ BuffHead	; NASM port label
    39                              <1> 
    40                              <1> ;SUBTTL SCANPLACE, PLACEBUF -- PUT A BUFFER BACK IN THE POOL
    41                              <1> ;PAGE
    42                              <1>         procedure   ScanPlace,near
    42          ******************  <1>  warning: proc ScanPlace... [-w+user]
    43                              <1>  assume ds:nothing, es:nothing, ss:DOSGROUP
    44                              <1> 
    45                              <1> ; Inputs:
    46                              <1> ;       Same as PLACEBUF
    47                              <1> ; Function:
    48                              <1> ;       Save scan location and call PLACEBUF
    49                              <1> ; Outputs:
    50                              <1> ;       DS:DI Points to saved scan location
    51                              <1> ; SI destroyed, other registers unchanged
    52                              <1> 
    53 00000000 06                  <1>         PUSH    ES
    54 00000001 C435                <1>         LES     SI,[DI + NEXTBUF]         ; Save scan location
    55                              <1>  assume es:nothing
    56 00000003 E80800              <1>         CALL    PLACEBUF
    57 00000006 06                  <1>         PUSH    ES
    58 00000007 1F                  <1>         POP     DS                      ; Restore scan location
    59                              <1>  assume ds:nothing
    60 00000008 89F7                <1>         MOV     DI,SI
    61 0000000A 07                  <1>         POP     ES
    62                              <1>  assume es:nothing
    63 0000000B C3                  <1>         return
    64                              <1> ScanPlace   ENDP
    65                              <1> 
    66 0000000C EB57                <1> NRETJ:  JMP     SHORT NRET
    67                              <1> 
    68                              <1>         procedure   PLACEBUF,NEAR
    68          ******************  <1>  warning: proc PLACEBUF... [-w+user]
    69                              <1>  assume ds:nothing, es:nothing, ss:DOSGROUP
    70                              <1> 
    71                              <1> ; Input:
    72                              <1> ;       DS:DI points to buffer
    73                              <1> ; Function:
    74                              <1> ;       Remove buffer from queue and re-insert it in proper place.
    75                              <1> ;       If buffer doesn't go at end, and isn't free, decrement
    76                              <1> ;       priorities.
    77                              <1> ; NO registers altered
    78                              <1> ;
    79                              <1> ; DS:SI -- Curbuf, current buffer in list
    80                              <1> ; ES:DI -- Buf, buffer passed as argument
    81                              <1> ; BP:CX -- Pointsave, saved Buf.nextbuf
    82                              <1> ; DX:BX -- Lastbuf, previous buffer in list
    83                              <1> ; AL    -- Inserted, Buf has been inserted
    84                              <1> ; AH    -- Removed, Buf has been removed
    85                              <1> 
    86                              <1>         %IF      IBM
    87                              <1>         %IFN IBM
    88                              <1>         invoke  save_world
    89                              <1>         XOR     AX,AX           ; Inserted = Removed = FALSE
    90                              <1>         LES     CX,[DI + NEXTBUF]
    91                              <1>         MOV     BP,ES           ; Pointsave = Buf.nextbuf
    92                              <1>         MOV     SI,DS
    93                              <1>         MOV     ES,SI           ; Buf is ES:DI
    94                              <1>         LDS     SI,[ss:BUFFHEAD]   ; Curbuf = HEAD
    95                              <1>         CALL    POINTCOMP       ; Buf == HEAD?
    96                              <1>         JNZ     TNEWHEAD
    97                              <1>         CMP     CX,-1           ; Buf is LAST?
    98                              <1>         JZ      NRETJ           ; Only one buffer, nothing to do
    99                              <1>         MOV     WORD PTR [ss:BUFFHEAD],CX
   100                              <1>         MOV     WORD PTR [ss:BUFFHEAD+2],BP        ; HEAD = Pointsave
   101                              <1>         INC     AH              ; Removed = TRUE
   102                              <1>         MOV     DS,BP
   103                              <1>         MOV     SI,CX           ; Curbuf = HEAD
   104                              <1> TNEWHEAD:
   105                              <1>         MOV     BL,[ES:DI + BUFPRI]
   106                              <1>         CMP     BL,[SI + BUFPRI]
   107                              <1>         JGE     BUFLOOP
   108                              <1> NEWHEAD:                        ; If Buf.pri < HEAD.pri
   109                              <1>         MOV     WORD PTR [ES:DI + NEXTBUF],SI
   110                              <1>         MOV     WORD PTR [ES:DI + NEXTBUF+2],DS   ; Buf.nextbuf = HEAD
   111                              <1>         MOV     WORD PTR [ss:BUFFHEAD],DI
   112                              <1>         MOV     WORD PTR [ss:BUFFHEAD+2],ES        ; HEAD = Buf
   113                              <1>         INC     AL                              ; Inserted = TRUE
   114                              <1>         OR      AH,AH
   115                              <1>         JNZ     NRET            ; If Removed == TRUE
   116                              <1> BUFLOOP:
   117                              <1>         PUSH    DS
   118                              <1>         PUSH    SI
   119                              <1>         LDS     SI,[SI + NEXTBUF]
   120                              <1>         CALL    POINTCOMP
   121                              <1>         POP     SI
   122                              <1>         POP     DS
   123                              <1>         JNZ     TESTINS
   124                              <1>         MOV     WORD PTR [SI + NEXTBUF],CX        ; If Curbuf.nextbuf == buf
   125                              <1>         MOV     WORD PTR [SI + NEXTBUF+2],BP      ; Curbuf.nextbuf = Pointsave
   126                              <1>         INC     AH              ; Removed = TRUE
   127                              <1>         OR      AL,AL
   128                              <1>         JNZ     SHUFFLE         ; If Inserted == TRUE
   129                              <1> TESTINS:
   130                              <1>         OR      AL,AL
   131                              <1>         JNZ     LOOKBUF
   132                              <1>         PUSH    CX              ; If NOT Inserted
   133                              <1>         MOV     CL,[ES:DI + BUFPRI]
   134                              <1>         CMP     CL,[SI + BUFPRI]
   135                              <1>         POP     CX
   136                              <1>         JGE     LOOKBUF
   137                              <1>         PUSH    DS              ; If Buf.pri < Curbuf.pri
   138                              <1>         MOV     DS,DX
   139                              <1>         MOV     WORD PTR [BX + NEXTBUF],DI
   140                              <1>         MOV     WORD PTR [BX + NEXTBUF+2],ES      ; Lastbuf.nextbuf = Buf
   141                              <1>         POP     DS
   142                              <1>         MOV     WORD PTR [ES:DI + NEXTBUF],SI
   143                              <1>         MOV     WORD PTR [ES:DI + NEXTBUF+2],DS   ; Buf.nextbuf = Curbuf
   144                              <1>         INC     AL              ; Inserted = TRUE
   145                              <1>         OR      AH,AH
   146                              <1>         JNZ     SHUFFLE         ; If Removed == TRUE
   147                              <1> LOOKBUF:
   148                              <1>         MOV     BX,SI
   149                              <1>         MOV     DX,DS           ; Lastbuf = Curbuf
   150                              <1>         CMP     WORD PTR [SI + NEXTBUF],-1
   151                              <1>         JZ      ISLAST
   152                              <1>         LDS     SI,[SI + NEXTBUF] ; Curbuf = Curbuf.nextbuf
   153                              <1>         JMP     SHORT BUFLOOP
   154                              <1> ISLAST:                 ; If Curbuf is LAST
   155                              <1>         MOV     WORD PTR [SI + NEXTBUF],DI
   156                              <1>         MOV     WORD PTR [SI + NEXTBUF+2],ES      ; Curbuf.nextbuf = Buf
   157                              <1>         MOV     WORD PTR [ES:DI + NEXTBUF],-1
   158                              <1>         MOV     WORD PTR [ES:DI + NEXTBUF+2],-1      ; Buf is LAST
   159                              <1> NRET:
   160                              <1>         invoke  restore_world
   161                              <1>         return
   162                              <1> 
   163                              <1> SHUFFLE:
   164                              <1>         LDS     DI,[ss:BUFFHEAD]
   165                              <1> DECLOOP:
   166                              <1>         CMP     byte [DI + BUFPRI],FREEPRI
   167                              <1>         JZ      NODEC
   168                              <1>         DEC     byte [DI + BUFPRI]
   169                              <1> NODEC:
   170                              <1>         LDS     DI,[DI + NEXTBUF]
   171                              <1>  assume ds:nothing
   172                              <1>         CMP     DI,-1
   173                              <1>         JNZ     DECLOOP
   174                              <1>         JMP     SHORT NRET
   175                              <1>         %ENDIF
   176                              <1>         %ENDIF
   177                              <1> 
   178 0000000E E8(0000)            <1>         invoke  save_world
   179 00000011 C40D                <1>         LES     CX,[DI + NEXTBUF]
   180 00000013 83F9FF              <1>         CMP     CX,-1           ; Buf is LAST?
   181 00000016 744D                <1>         JZ      NRET            ; Buffer already last
   182 00000018 8CC5                <1>         MOV     BP,ES           ; Pointsave = Buf.nextbuf
   183 0000001A 1E                  <1>         PUSH    DS
   184 0000001B 07                  <1>         POP     ES              ; Buf is ES:DI
   185                              <1>  assume es:nothing
   186 0000001C 36C536[0000]        <1>         LDS     SI,[ss:BUFFHEAD]   ; Curbuf = HEAD
   187                              <1>  assume ds:nothing
   188                              <1> POINTCOMP equ PointComp	; NASM port label
   189 00000021 E87A00              <1>         CALL    POINTCOMP       ; Buf == HEAD?
   190 00000024 750C                <1>         JNZ     BUFLOOP
   191 00000026 36890E[0000]        <1>         MOV     WORD PTR [ss:BUFFHEAD],CX
   192 0000002B 36892E[0200]        <1>         MOV     WORD PTR [ss:BUFFHEAD+2],BP        ; HEAD = Pointsave
   193 00000030 EB14                <1>         JMP     SHORT LOOKEND
   194                              <1> 
   195                              <1> BUFLOOP:
   196 00000032 1E                  <1>         PUSH    DS
   197 00000033 56                  <1>         PUSH    SI
   198 00000034 C534                <1>         LDS     SI,[SI + NEXTBUF]
   199                              <1>  assume ds:nothing
   200 00000036 E86500              <1>         CALL    POINTCOMP
   201 00000039 7404                <1>         JZ      GOTTHEBUF
   202 0000003B 58                  <1>         POP     AX
   203 0000003C 58                  <1>         POP     AX
   204 0000003D EBF3                <1>         JMP     SHORT BUFLOOP
   205                              <1> 
   206                              <1> GOTTHEBUF:
   207 0000003F 5E                  <1>         POP     SI
   208 00000040 1F                  <1>         POP     DS
   209                              <1>  assume ds:nothing
   210 00000041 890C                <1>         MOV     WORD PTR [SI + NEXTBUF],CX        ; If Curbuf.nextbuf == buf
   211 00000043 896C02              <1>         MOV     WORD PTR [SI + NEXTBUF+2],BP      ; Curbuf.nextbuf = Pointsave
   212                              <1> LOOKEND:
   213 00000046 1E                  <1>         PUSH    DS
   214 00000047 56                  <1>         PUSH    SI
   215 00000048 C534                <1>         LDS     SI,[SI + NEXTBUF]
   216 0000004A 83FEFF              <1>         CMP     SI,-1
   217 0000004D 7404                <1>         JZ      GOTHEEND
   218 0000004F 58                  <1>         POP     AX
   219 00000050 58                  <1>         POP     AX
   220 00000051 EBF3                <1>         JMP     SHORT LOOKEND
   221                              <1> 
   222                              <1> GOTHEEND:
   223 00000053 5E                  <1>         POP     SI
   224 00000054 1F                  <1>         POP     DS
   225                              <1>  assume ds:nothing
   226 00000055 893C                <1>         MOV     WORD PTR [SI + NEXTBUF],DI
   227 00000057 8C4402              <1>         MOV     WORD PTR [SI + NEXTBUF+2],ES      ; Curbuf.nextbuf = Buf
   228 0000005A 26C705FFFF          <1>         MOV     WORD PTR [ES:DI + NEXTBUF],-1
   229 0000005F 26C74502FFFF        <1>         MOV     WORD PTR [ES:DI + NEXTBUF+2],-1      ; Buf is LAST
   230                              <1> NRET:
   231 00000065 E8(0000)            <1>         invoke  restore_world
   232 00000068 C3                  <1>         return
   233                              <1> 
   234                              <1> PLACEBUF    ENDP
   235                              <1> 
   236                              <1>         procedure   PLACEHEAD,NEAR
   236          ******************  <1>  warning: proc PLACEHEAD... [-w+user]
   237                              <1>  assume ds:nothing, es:nothing, ss:DOSGROUP
   238                              <1> 
   239                              <1> ; SAME AS PLACEBUF except places buffer at head
   240                              <1> 
   241 00000069 E8(0000)            <1>         invoke  save_world
   242 0000006C 1E                  <1>         PUSH    DS
   243 0000006D 07                  <1>         POP     ES
   244                              <1>  assume es:nothing
   245 0000006E 36C536[0000]        <1>         LDS     SI,[ss:BUFFHEAD]
   246                              <1>  assume ds:nothing
   247 00000073 36893E[0000]        <1>         MOV     WORD PTR [ss:BUFFHEAD],DI
   248 00000078 368C06[0200]        <1>         MOV     WORD PTR [ss:BUFFHEAD+2],ES
   249 0000007D 268935              <1>         MOV     WORD PTR [ES:DI + NEXTBUF],SI
   250 00000080 268C5D02            <1>         MOV     WORD PTR [ES:DI + NEXTBUF+2],DS
   251                              <1> LOOKEND2:
   252 00000084 1E                  <1>         PUSH    DS
   253 00000085 56                  <1>         PUSH    SI
   254 00000086 C534                <1>         LDS     SI,[SI + NEXTBUF]
   255                              <1>  assume ds:nothing
   256 00000088 E81300              <1>         CALL    POINTCOMP
   257 0000008B 7404                <1>         JZ      GOTHEEND2
   258 0000008D 58                  <1>         POP     AX
   259 0000008E 58                  <1>         POP     AX
   260 0000008F EBF3                <1>         JMP     SHORT LOOKEND2
   261                              <1> 
   262                              <1> GOTHEEND2:
   263 00000091 5E                  <1>         POP     SI
   264 00000092 1F                  <1>         POP     DS
   265                              <1>  assume ds:nothing
   266 00000093 C704FFFF            <1>         MOV     WORD PTR [SI + NEXTBUF],-1
   267 00000097 C74402FFFF          <1>         MOV     WORD PTR [SI + NEXTBUF+2],-1      ; Buf is LAST
   268 0000009C EBC7                <1>         JMP     SHORT NRET
   269                              <1> 
   270                              <1> PLACEHEAD   ENDP
   271                              <1> 
   272                              <1> ;SUBTTL POINTCOMP -- 20 BIT POINTER COMPARE
   273                              <1> ;PAGE
   274                              <1>         procedure   PointComp,NEAR
   274          ******************  <1>  warning: proc PointComp... [-w+user]
   275                              <1>  assume ds:nothing, es:nothing, ss:nothing
   276                              <1> 
   277                              <1> ; Compare DS:SI to ES:DI (or DS:DI to ES:SI) for equality
   278                              <1> ; DO NOT USE FOR < or >
   279                              <1> ; No Registers altered
   280                              <1> 
   281 0000009E 39FE                <1>         CMP     SI,DI
   282 000000A0 75C6                <1>         retnz
   283 000000A2 51                  <1>         PUSH    CX
   284 000000A3 52                  <1>         PUSH    DX
   285 000000A4 8CD9                <1>         MOV     CX,DS
   286 000000A6 8CC2                <1>         MOV     DX,ES
   287 000000A8 39D1                <1>         CMP     CX,DX
   288 000000AA 5A                  <1>         POP     DX
   289 000000AB 59                  <1>         POP     CX
   290 000000AC C3                  <1>         return
   291                              <1> PointComp   ENDP
   292                              <1> 
   293                              <1> ;SUBTTL GETBUFFR -- GET A SECTOR INTO A BUFFER
   294                              <1> ;PAGE
   295                              <1>         procedure   GETBUFFR,NEAR
   295          ******************  <1>  warning: proc GETBUFFR... [-w+user]
   296                              <1>  assume ds:nothing, es:DPB, ss:DOSGROUP
   297                              <1> 
   298                              <1> ; Input:
   299                              <1> ;       AH = Priority buffer is to have
   300                              <1> ;       AL = 0 means sector must be pre-read
   301                              <1> ;          ELSE no pre-read
   302                              <1> ;       DX = Desired physical sector number
   303                              <1> ;       ES:BP = Pointer to drive parameters
   304                              <1> ; Function:
   305                              <1> ;       Get the specified sector into one of the I/O buffers
   306                              <1> ;       And shuffle the queue
   307                              <1> ; Output:
   308                              <1> ;       [CURBUF] Points to the Buffer for the sector
   309                              <1> ;	CY iff error (user selected FAIL on int 24h)
   310                              <1> ; DX,ES:BP unchanged, all other registers destroyed
   311                              <1> 
   312 000000AD 31F6                <1>         XOR     SI,SI
   313                              <1>         entry   GETBUFFRB
   314                              <1>  assume ds:DOSGROUP
   315                              <1> PREREAD equ PreRead	; NASM port label
   316 000000AF A3[0000]            <1>         MOV     [PREREAD],AX
   317 000000B2 268A4600            <1>         MOV     AL,[ES:BP + dpb_drive]
   318 000000B6 830E[0000]FF        <1> 	or word [BuffFree], -1
   319                              <1> LASTBUFFER equ LastBuffer	; NASM port label
   320 000000BB C53E[0000]          <1>         LDS     DI,[LASTBUFFER]
   321                              <1>  ASSUME DS:NOTHING
   322 000000BF 368B0E[0000]        <1> 	MOV	CX,[ss:HIGH_SECTOR]		; F.C. >32mb			;AN000;
   323 000000C4 83FFFF              <1> 	CMP	DI,-1				; Recency pointer valid?
   324 000000C7 7412                <1> 	JZ	SKBUF				; No
   325 000000C9 3B5508              <1> 	CMP	DX,WORD PTR [DI + BUFSECNO]
   326 000000CC 750D                <1> 	JNZ	SKBUF				; Wrong sector
   327 000000CE 3B4D0A              <1> 	CMP	CX,WORD PTR [DI + BUFSECNO+2]	; F.C. >32mb			;AN000;
   328 000000D1 7508                <1> 	JNZ	SKBUF				; F.C. >32mb			;AN000;
   329 000000D3 3A4504              <1>         CMP     AL,[DI + BUFDRV]
   330 000000D6 7503E99200          <1>         jz JUSTBUF				; Just asked for same buffer
   331                              <1> 						; Wrong Drive
   332                              <1> SKBUF:
   333 000000DB 36C53E[0000]        <1>         LDS     DI,[ss:BUFFHEAD]
   334                              <1>  assume ds:nothing
   335                              <1> NXTBFF:
   336 000000E0 807D04FF            <1> 	cmp byte [di + BUFDRV], 0FFh
   337 000000E4 750A                <1> 	jne .notfree
   338 000000E6 36893E[0000]        <1> 	mov word [ss:BuffFree], di
   339 000000EB 368C1E[0200]        <1> 	mov word [ss:BuffFree + 2], ds
   340                              <1> .notfree:
   341 000000F0 3B5508              <1> 	CMP	DX,WORD PTR [DI + BUFSECNO]	; F.C. >32mb			;AN000;
   342 000000F3 750A                <1> 	jne	BUMP
   343 000000F5 3B4D0A              <1> 	CMP	CX,WORD PTR [DI + BUFSECNO+2]	; F.C. >32mb			;AN000;
   344 000000F8 7505                <1> 	jne	BUMP				; F.C. >32mb			;AN000;
   345 000000FA 3A4504              <1>         CMP     AL,[DI + BUFDRV]
   346 000000FD 746B                <1> 	je SETINF
   347                              <1> BUMP:
   348 000000FF C53D                <1>         LDS     DI,[DI + NEXTBUF]
   349                              <1>  assume ds:nothing
   350 00000101 83FFFF              <1>         CMP     DI,-1
   351 00000104 75DA                <1>         JNZ     NXTBFF
   352 00000106 36C53E[0000]        <1> 	lds di, [ss:BuffFree]
   353                              <1>  assume ds:nothing
   354 0000010B 83FFFF              <1> 	cmp di, -1
   355 0000010E 7505                <1> 	jne .gotfree
   356 00000110 36C53E[0000]        <1>         LDS     DI,[ss:BUFFHEAD]
   357                              <1>  assume ds:nothing
   358                              <1> .gotfree:
   359 00000115 36FF36[0000]        <1> 	PUSH	word [ss:HIGH_SECTOR]			;F.C. >32mb			;AN000;
   360 0000011A 56                  <1>         PUSH    SI
   361 0000011B 52                  <1>         PUSH    DX
   362 0000011C 55                  <1>         PUSH    BP
   363 0000011D 06                  <1>         PUSH    ES
   364                              <1> BUFWRITE equ BufWrite	; NASM port label
   365 0000011E E8BF00              <1>         CALL    BUFWRITE        ; Write out the dirty buffer
   366 00000121 07                  <1>         POP     ES
   367                              <1>  assume es:DPB
   368 00000122 5D                  <1>         POP     BP
   369 00000123 5A                  <1>         POP     DX
   370 00000124 5E                  <1>         POP     SI
   371 00000125 368F06[0000]        <1> 	POP	word [ss:HIGH_SECTOR]			;F.C. >32mb			;AN000;
   372                              <1> RDSEC:                          ; Read in the new sector
   373 0000012A 7255                <1> 	JC	GETBERR
   374 0000012C 36F606[0000]FF      <1>         TEST    BYTE PTR [ss:PREREAD],-1
   375 00000132 751E                <1>         JNZ     SETBUF
   376                              <1> BufInSiz equ BUFINSIZ	; NASM port equate
   377 00000134 8D5D10              <1>         LEA     BX,[DI + BufInSiz]        ; Point at buffer
   378 00000137 B90100              <1>         MOV     CX,1
   379 0000013A 56                  <1>         PUSH    SI
   380 0000013B 57                  <1>         PUSH    DI
   381 0000013C 52                  <1>         PUSH    DX
   382 0000013D 85F6                <1>         test    SI,SI
   383 0000013F 7407                <1>         JZ      NORMSEC
   384 00000141 E8(0000)            <1> 	invoke	FATSECRD
   385 00000144 B402                <1> 	MOV	AH,buf_isFAT		; Set buf_flags
   386 00000146 EB05                <1> 	JMP	SHORT GOTTHESEC 	; Buffer is marked free if read barfs
   387                              <1> NORMSEC:
   388 00000148 E8(0000)            <1> 	invoke	DREAD			; Buffer is marked free if read barfs
   389 0000014B B400                <1> 	MOV	AH,0			; Set buf_flags to no type, DO NOT XOR!
   390                              <1> GOTTHESEC:				; Carry set by either FATSECRD or DREAD
   391 0000014D 5A                  <1>         POP     DX
   392 0000014E 5F                  <1>         POP     DI
   393 0000014F 5E                  <1>         POP     SI
   394 00000150 722F                <1>         jc GETBERR
   395                              <1> SETBUF:
   396 00000152 368B0E[0000]        <1> 	MOV	CX,[ss:HIGH_SECTOR]	       ; F.C. >32mb			;AN000;
   397 00000157 894D0A              <1> 	MOV	WORD PTR [DI + BUFSECNO+2],CX  ; F.C. >32mb			;AN000;
   398 0000015A 895508              <1> 	MOV	WORD PTR [DI + BUFSECNO],DX    ; F.C. >32mb			;AN000;
   399 0000015D 896D0C              <1>         MOV     WORD PTR [DI + BUFDRVDP],BP
   400 00000160 8C450E              <1>         MOV     WORD PTR [DI + BUFDRVDP+2],ES
   401 00000163 268A4600            <1>         MOV     AL,[ES:BP + dpb_drive]
   402 00000167 894504              <1>         MOV     WORD PTR [DI + BUFDRV],AX	; set buf_flags too
   403                              <1> SETINF:
   404 0000016A E8A1FE              <1>         CALL    PLACEBUF
   405                              <1> JUSTBUF:
   406                              <1> CURBUF equ CurBuf	; NASM port label
   407 0000016D 368C1E[0200]        <1>         MOV     WORD PTR [ss:CURBUF+2],DS
   408 00000172 368C1E[0200]        <1>         MOV     WORD PTR [ss:LASTBUFFER+2],DS
   409 00000177 16                  <1>         PUSH    SS
   410 00000178 1F                  <1>         POP     DS
   411                              <1>  ASSUME DS:DOSGROUP
   412 00000179 893E[0000]          <1>         MOV     WORD PTR [CURBUF],DI
   413 0000017D 893E[0000]          <1>         MOV     WORD PTR [LASTBUFFER],DI
   414                              <1> GETBERR:
   415 00000181 16                  <1>         PUSH    SS
   416 00000182 1F                  <1>         POP     DS
   417                              <1>  ASSUME DS:DOSGROUP
   418 00000183 C3                  <1>         return
   419                              <1> GETBUFFR    ENDP
   420                              <1> 
   421                              <1> 
   422                              <1> ;SUBTTL FLUSHBUF -- WRITE OUT DIRTY BUFFERS
   423                              <1> ;PAGE
   424                              <1>         procedure   FlushBuf,NEAR
   424          ******************  <1>  warning: proc FlushBuf... [-w+user]
   425                              <1>  assume ds:DOSGROUP, es:nothing, ss:DOSGROUP
   426                              <1> 
   427                              <1> ; Input:
   428                              <1> ;       DS = DOSGROUP
   429                              <1> ;       AL = Physical unit number
   430                              <1> ;          = -1 for all units
   431                              <1> ; Function:
   432                              <1> ;       Write out all dirty buffers for unit, and flag them as clean
   433                              <1> ; DS Preserved, all others destroyed (ES too)
   434                              <1> 
   435 00000184 C53E[0000]          <1>         LDS     DI,[BUFFHEAD]
   436                              <1>  ASSUME DS:NOTHING
   437 00000188 B4FF                <1>         MOV     AH,-1
   438                              <1> NXTBUFF:
   439 0000018A E82C00              <1> 	CALL	CHECKFLUSH	; Ignore Carry return from CHECKFLUSH.
   440                              <1> 				; FAILERR is set if user FAILed.
   441 0000018D 50                  <1> 	PUSH	AX
   442 0000018E 8A4504              <1> 	MOV	AL,[DI + BUFDRV]
   443                              <1> WPERR equ WPErr	; NASM port label
   444 00000191 363A06[0000]        <1> 	CMP	AL,BYTE PTR [ss:WPERR]
   445                              <1> ZAP equ Zap	; NASM port label
   446 00000196 7409                <1> 	JZ	ZAP
   447 00000198 36F706[0000]0400    <1> 	TEST	word [ss:DOS34_FLAG],FROM_DISK_RESET ;MS. from disk reset ?
   448 0000019F 7405                <1> 	jz NOZAP
   449                              <1> Zap:
   450 000001A1 C74504FF00          <1> 	MOV WORD PTR [DI + BUFDRV], 00FFh
   451                              <1> 				; (clears buf_flags as well)
   452                              <1> 				; Invalidate buffer, it is inconsistent
   453                              <1> NOZAP:
   454 000001A6 58                  <1> 	POP	AX
   455 000001A7 C53D                <1>         LDS     DI,[DI + NEXTBUF]
   456 000001A9 83FFFF              <1>         CMP     DI,-1
   457 000001AC 75DC                <1>         JNZ     NXTBUFF
   458 000001AE 16                  <1>         PUSH    SS
   459 000001AF 1F                  <1>         POP     DS
   460                              <1>  assume ds:DOSGROUP
   461 000001B0 803E[0000]00        <1> 	CMP	byte [FAILERR],0
   462 000001B5 7401                <1> 	je .good		; if no int 24h fail --> (NC)
   463 000001B7 F9                  <1> 	STC			; Return error if user FAILed (CY)
   464                              <1> .good:
   465 000001B8 C3                  <1>         return
   466                              <1> FlushBuf    ENDP
   467                              <1> 
   468                              <1> 
   469                              <1> 	procedure CHECKFLUSH,NEAR
   469          ******************  <1>  warning: proc CHECKFLUSH... [-w+user]
   470                              <1>  assume ds:nothing, es:nothing, ss:DOSGROUP
   471                              <1> ; Carry set if problem (currently user FAILed to I 24)
   472                              <1> 
   473                              <1> 	Assert	ISBUF,<DS,DI>,"CheckFlush"
   474 000001B9 386504              <1> 	CMP	[DI + BUFDRV],AH
   475 000001BC 74FA                <1> 	retz				; Skip free buffers, carry clear
   476 000001BE 38C4                <1> 	CMP	AH,AL
   477 000001C0 7406                <1> 	JZ	DOBUFFER		; Do all dirty buffers
   478 000001C2 3A4504              <1> 	CMP	AL,[DI + BUFDRV]
   479 000001C5 F8                  <1> 	CLC
   480 000001C6 75F0                <1> 	retnz				; Buffer not for this unit or SFT
   481                              <1> DOBUFFER:
   482 000001C8 F6450540            <1> 	TEST	byte [DI + buf_flags],buf_dirty
   483 000001CC 74EA                <1> 	retz				; Buffer not dirty, carry clear by TEST
   484 000001CE 50                  <1> 	PUSH	AX
   485 000001CF FF7504              <1> 	PUSH	WORD PTR [DI + BUFDRV]	; (reads buf_flags as well)
   486 000001D2 E80B00              <1> 	CALL	BUFWRITE
   487 000001D5 58                  <1> 	POP	AX
   488 000001D6 7206                <1> 	JC	LEAVE_BUF		; Leave buffer marked free (lost).
   489 000001D8 80E4BF              <1> 	and ah, ~ buf_dirty		; Buffer is clean
   490 000001DB 894504              <1> 	MOV	WORD PTR [DI + BUFDRV],AX
   491                              <1> 					; (sets buf_flags as well)
   492                              <1> LEAVE_BUF:
   493 000001DE 58                  <1> 	POP	AX			; Search info
   494 000001DF C3                  <1> 	return
   495                              <1> EndProc CHECKFLUSH
   496                              <1> 
   497                              <1> 
   498                              <1> ;SUBTTL BUFWRITE -- WRITE OUT A BUFFER IF DIRTY
   499                              <1> ;PAGE
   500                              <1>         procedure   BufWrite,NEAR
   500          ******************  <1>  warning: proc BufWrite... [-w+user]
   501                              <1>  assume ds:nothing, es:nothing, ss:DOSGROUP
   502                              <1> 
   503                              <1> ; Input:
   504                              <1> ;       DS:DI Points to the buffer
   505                              <1> ; Function:
   506                              <1> ;       Write out all the buffer if dirty.
   507                              <1> ; Output:
   508                              <1> ;       Buffer marked free
   509                              <1> ;	Carry set if error (currently user FAILed to I 24)
   510                              <1> ; DS:DI Preserved, ALL others destroyed (ES too)
   511                              <1> 
   512 000001E0 B8FF00              <1>         MOV     AX,00FFH
   513 000001E3 874504              <1>         XCHG    AX,WORD PTR [DI + BUFDRV] ; Free, in case write barfs
   514                              <1> 					; (sets buf_flags as well)
   515 000001E6 3CFF                <1>         CMP     AL,0FFH
   516 000001E8 74F5                <1>         retz                            ; Buffer is free. (NC)
   517 000001EA F6C440              <1> 	test ah, buf_dirty
   518 000001ED 74F0                <1>         retz                            ; Buffer is clean. (NC)
   519 000001EF E86400              <1> 	invoke	DEC_DIRTY_COUNT		; LB. decrement dirty count
   520 000001F2 363A06[0000]        <1>         CMP     AL,BYTE PTR [ss:WPERR]
   521 000001F7 74E6                <1>         retz                            ; If in WP error zap buffer
   522 000001F9 C46D0C              <1>         LES     BP,[DI + BUFDRVDP]
   523 000001FC 8D5D10              <1>         LEA     BX,[DI + BufInSiz]        ; Point at buffer
   524 000001FF 8B5508              <1> 	MOV	DX,WORD PTR [DI + BUFSECNO]	;F.C. >32mb			;AN000;
   525 00000202 8B4D0A              <1> 	MOV	CX,WORD PTR [DI + BUFSECNO+2]	;F.C. >32mb			;AN000;
   526 00000205 36890E[0000]        <1> 	MOV	[ss:HIGH_SECTOR],CX		;F.C. >32mb			;AN000;
   527                              <1> 
   528 0000020A B90100              <1> 	mov cx, 1			; Default to not a FAT sector
   529 0000020D F6450502            <1> 	test byte [di + buf_flags], buf_isFAT
   530 00000211 7408                <1> 	jz .notfat
   531 00000213 268B460F            <1> 	mov ax, [es:bp + dpb_FAT_size]
   532 00000217 268A4E08            <1> 	mov cl, [es:bp + dpb_FAT_count]
   533                              <1> .notfat:
   534                              <1> 
   535                              <1> allowed_RETRY equ Allowed_RETRY	; NASM port equate
   536                              <1> allowed_FAIL equ Allowed_FAIL	; NASM port equate
   537 0000021B 36C606[0000]18      <1> 	MOV	byte [ss:ALLOWED],allowed_RETRY + allowed_FAIL
   538 00000221 F6450508            <1> 	TEST	byte [DI + buf_flags],buf_isDATA
   539 00000225 7406                <1> 	JZ	NO_IGNORE
   540                              <1> allowed_IGNORE equ Allowed_IGNORE	; NASM port equate
   541 00000227 36800E[0000]20      <1> 	OR	byte [ss:ALLOWED],allowed_IGNORE
   542                              <1> NO_IGNORE:
   543 0000022D 57                  <1> 	PUSH	DI		; Save buffer pointer
   544 0000022E 31FF                <1> 	XOR	DI,DI		; Indicate failure
   545                              <1> WRTAGAIN:
   546 00000230 575150              <1> 	SaveReg <DI,CX,AX>
   547 00000233 B90100              <1> 	MOV	CX,1
   548 00000236 53521E              <1> 	SaveReg <BX,DX,DS>
   549                              <1> 
   550 00000239 E8(0000)            <1> 	invoke	DWRITE		; Write out the dirty buffer
   551                              <1> 
   552 0000023C 1F5A5B              <1> 	RestoreReg  <DS,DX,BX>
   553 0000023F 58595F              <1> 	RestoreReg  <AX,CX,DI>
   554 00000242 7201                <1> 	JC	NOSET
   555 00000244 47                  <1> 	INC	DI		; If at least ONE write succeedes, the operation
   556                              <1> NOSET:				;	succeedes.
   557 00000245 01C2                <1> 	ADD	DX,AX
   558 00000247 E2E7                <1> 	LOOP	WRTAGAIN
   559 00000249 85FF                <1> 	test	DI,DI		; Clears carry
   560 0000024B 7501                <1> 	JNZ	BWROK		; At least one write worked --> (NC)
   561 0000024D F9                  <1> 	STC			; DI never got INCed, all writes failed.
   562                              <1> BWROK:
   563 0000024E 5F                  <1> 	POP	DI
   564 0000024F C3                  <1> 	return
   565                              <1> BufWrite    ENDP
   566                              <1> 
   567                              <1> Break	<INC_DIRTY_COUNT-increment dirty count>
   568                              <1> 
   569                              <1> ; Input:
   570                              <1> ;	none
   571                              <1> ; Function:
   572                              <1> ;	increment dirty buffers count
   573                              <1> ; Output:
   574                              <1> ;	dirty buffers count in the current hash entry is incremented
   575                              <1> ;
   576                              <1> ; All registers preserved
   577                              <1> 
   578                              <1> 	procedure   INC_DIRTY_COUNT,NEAR
   578          ******************  <1>  warning: proc INC_DIRTY_COUNT... [-w+user]
   579                              <1>  assume ds:nothing, es:nothing, ss:DOSGROUP
   580 00000250 36FF06[0000]        <1> 	INC	word [ss:BUF2_Dirty_Count]    ;LB. add 1					;AN000;
   581 00000255 C3                  <1> 	return
   582                              <1> EndProc INC_DIRTY_COUNT 	    ;LB. return 				;AN000;
   583                              <1> 
   584                              <1> Break	<DEC_DIRTY_COUNT-decrement dirty count>
   585                              <1> 
   586                              <1> ; Input:
   587                              <1> ;	none
   588                              <1> ; Function:
   589                              <1> ;	decrement dirty buffers count
   590                              <1> ; Output:
   591                              <1> ;	dirty buffers count in the current hash entry is decremented
   592                              <1> ;
   593                              <1> ; All registers preserved
   594                              <1> 
   595                              <1> 	procedure   DEC_DIRTY_COUNT,NEAR
   595          ******************  <1>  warning: proc DEC_DIRTY_COUNT... [-w+user]
   596                              <1>  assume ds:nothing, es:nothing, ss:DOSGROUP
   597 00000256 36833E[0000]00      <1> 	CMP	word [ss:BUF2_Dirty_Count],0  ;LB. in case if 0				;AN000;
   598 0000025C 7405                <1> 	je	nodec		    ;LB. do nothing				;AN000;
   599 0000025E 36FF0E[0000]        <1> 	DEC	word [ss:BUF2_Dirty_Count]    ;LB. sub 1					;AN000;
   600                              <1> nodec:
   601 00000263 C3                  <1> 	return
   602                              <1> EndProc DEC_DIRTY_COUNT 	    ;LB. return 				;AN000;
   603                              <1> 
   604                              <1>     END
    56                                  %else
    57                                  
    58                                  %iassign Installed TRUE
    59                                  
    60                                  	i_need	BuffHead,DWORD
    61                                  	i_need	PreRead,WORD
    62                                  	i_need	LastBuffer,DWORD
    63                                  	i_need	CurBuf,DWORD
    64                                  	i_need	WPErr,BYTE
    65                                  	i_need	ALLOWED,BYTE
    66                                  	i_need	FAILERR,BYTE
    67                                  	i_need	HIGH_SECTOR,WORD	     ; DOS 4.00 >32mb			;AN000;
    68                                  	i_need	CurHashEntry,DWORD	     ; DOS 4.00 current Hash entry	;AN000;
    69                                  	i_need	BUF_HASH_PTR,DWORD	     ; DOS 4.00 Hash table pointer	;AN000;
    70                                  	i_need	BUF_HASH_COUNT,WORD	     ; DOS 4.00 Hash table entries	;AN000;
    71                                  	i_need	SC_CACHE_PTR,DWORD	     ; DOS 4.00 seconadary cache table	;AN000;
    72                                  	i_need	SC_CACHE_COUNT,WORD	     ; DOS 4.00 secondary cache entries	;AN000;
    73                                  	i_need	BUF_EMS_MODE,BYTE	     ; DOS 4.00 EMS mode 		;AN000;
    74                                  	i_need	BUF_EMS_HANDLE,WORD	     ; DOS 4.00 buffer EMS handle	;AN000;
    75                                  	i_need	SC_SECTOR_SIZE,WORD	     ; DOS 4.00 sector size		;AN000;
    76                                  	i_need	SC_DRIVE,BYTE		     ; DOS 4.00 drive			;AN000;
    77                                  	i_need	ACT_PAGE,WORD		     ; DOS 4.00 active logical EMS page	;AN000;
    78                                  	i_need	DOS34_FLAG,WORD 	     ; DOS 4.00 common flag		;AN000;
    79                                  	i_need	BUF_EMS_SEG_CNT,WORD	     ; DOS 4.00 EMS seg count		;AN000;
    80                                  	i_need	BUF_EMS_MAP_BUFF,BYTE	     ; DOS 4.00 EMS map buffer		;AN000;
    81                                  	i_need	FIRST_BUFF_ADDR,WORD	     ; DOS 4.00 beginning of the chain	;AN000;
    82                                  	i_need	BUF_EMS_PAGE_FRAME,WORD      ; DOS 4.00 EMS page frame		;AN000;
    83                                  
    84                                  %IF	BUFFERFLAG
    85                                  	i_need	BUF_EMS_PFRAME,WORD
    86                                  	i_need 	BUF_EMS_LAST_PAGE,WORD
    87                                  	i_need	BUF_EMS_FIRST_PAGE,WORD
    88                                  	i_need	BUF_EMS_SAFE_FLAG,byte
    89                                  	i_need	BUF_EMS_NPA640,WORD
    90                                  	i_need	NEXTADD,WORD
    91                                  	i_need	DMAADD,DWORD
    92                                  	i_need	BYTCNT1,WORD
    93                                  	i_am	BUF_EMS_MAP_BUF,12,<0,0,0,0,0,0,0,0,0,0,0,0>	     
    94                                  	i_am	CURADD,WORD
    95                                  	i_am	low_ems_buf,512
    96                                  	extrn	SAVE_USER_MAP:near
    97                                  	extrn	RESTORE_USER_MAP:near
    98                                  %ENDIF
    99                                  
   100                                  
   101                                  Break	<GETCURHEAD -- Get current buffer header>
   102                                  
   103                                  ; Inputs:
   104                                  ;	DX= sector number (LOW)
   105                                  ;	[HIGH_SECTOR]= sector number (HIGH)
   106                                  ; Function:
   107                                  ;	Hash into a buffer group and activate the extended memory if
   108                                  ;	necessary
   109                                  ; Outputs:
   110                                  ;	[CurHashEntry] = current Hash entry addr
   111                                  ;	DS:DI = 1st buffer addr of the current Hash entry
   112                                  ; No other registers altered
   113                                  
   114                                  	procedure   GETCURHEAD,NEAR
   115                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   116                                  
   117                                  	PUSH	DX			  ;LB. save regs			;AN000;
   118                                  	PUSH	AX			  ;LB.					;AN000;
   119                                  	PUSH	BX			  ;LB.					;AN000;
   120                                  	MOV	AX,DX			  ;LB.					;AN000;
   121                                  ;	MOV	DX,[HIGH_SECTOR]	  ;LB. HASH(sector#) and get entry #	;AN000;
   122                                  	XOR	DX,DX			  ;LB. to avoid divide overflow 	;AN000;
   123                                  	DIV	word [ss:BUF_HASH_COUNT]	  ;LB. get remainder			;AN000;
   124                                  	ADD	DX,DX			  ;LB. 8 bytes per entry		;AN000;
   125                                  	ADD	DX,DX			  ;LB.					;AN000;
   126                                  	ADD	DX,DX			  ;LB. times 8				;AN000;
   127                                  
   128                                  	LDS	DI,[ss:BUF_HASH_PTR]	  ;LB. get Hash Table addr		;AN000;
   129                                  	ADD	DI,DX			  ;LB position to entry 		;AN000;
   130                                  Map_Entry2:
   131                                  	MOV	WORD PTR [ss:CurHashEntry+2],DS ;LB. update current Hash entry ptr ;AN000;
   132                                  	MOV	WORD PTR [ss:CurHashEntry],DI ;LB. 				;AN000;
   133                                  LASTBUFFER equ LastBuffer	; NASM port label
   134                                  	MOV	WORD PTR [ss:LASTBUFFER],-1   ;LB. invalidate last buffer		;AN000;
   135                                  	MOV	BX,[DI + EMS_PAGE_NUM]	  ;LB. logical page			;AN000;
   136                                  
   137                                  %IFN	BUFFERFLAG
   138                                  	LDS	DI,[DI + BUFFER_BUCKET]	  ;LB. ds:di is 1st buffer addr 	;AN000;
   139                                  	MOV	[ss:FIRST_BUFF_ADDR],DI	  ;LB. 1/19/88 save first buffer addr	;AN000;
   140                                  	CALL	SET_MAP_PAGE		  ;LB. activate handle if EMS there	;AN000;
   141                                  %ELSE
   142                                  	push	ax
   143                                  	mov	ax, [ss:NEXTADD]
   144                                  	mov	[ss:CURADD], ax
   145                                  	pop	ax
   146                                  	CALL	SET_MAP_PAGE		  ;LB. activate handle if EMS there	;AN000;
   147                                  	LDS	DI,[DI + BUFFER_BUCKET]	  ;LB. ds:di is 1st buffer addr 	;AN000;
   148                                  	MOV	[ss:FIRST_BUFF_ADDR],DI	  ;LB. 1/19/88 save first buffer addr	;AN000;
   149                                  %ENDIF
   150                                  
   151                                  										;AN000;
   152                                  	POP	BX			  ;LB.					;AN000;
   153                                  	POP	AX			  ;LB.					;AN000;
   154                                  	POP	DX			  ;LB.					;AN000;
   155                                  	return				  ;LB.					;AN000;
   156                                  EndProc GETCURHEAD								;AN000;
   157                                  
   158                                  										;AN000;
   159                                  Break	<SET_MAP_PAGE - map handle and page >					;AN000;
   160                                  ; Inputs:									;AN000;
   161                                  ;	BX= logical page							;AN000;
   162                                  ; Function:									;AN000;
   163                                  ;	Map handle and logical page to frame 0 page 0				;AN000;
   164                                  ; Outputs:									;AN000;
   165                                  ;	AH=0 success								;AN000;
   166                                  ; No other registers altered							;AN000;
   167                                  										;AN000;
   168                                  Procedure   SET_MAP_PAGE,NEAR							;AN000;
   169                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   170                                  
   171                                  ;	int	3
   172                                  										;AN000;
   173                                  	CMP	byte [ss:BUF_EMS_MODE],-1	  ;LB. EMS support			;AN000;
   174                                  	JZ	No_map			  ;LB. no				;AN000;
   175                                  
   176                                  %IFN BUFFERFLAG
   177                                  	CMP	[ss:ACT_PAGE],BX		  ;LB. already mapped ? 		;AN000;
   178                                  	JZ	No_map			  ;LB. yes				;AN000;
   179                                  %ENDIF
   180                                  	MOV	[ss:ACT_PAGE],BX		  ;LB. save active page mapped		;AN000;
   181                                  
   182                                  %IF	BUFFERFLAG	
   183                                  	cmp	byte [ss:BUF_EMS_SAFE_FLAG], 1
   184                                  	je	no_coll
   185                                  ;	int	3
   186                                  	call	detect_collision
   187                                  no_coll:
   188                                  %ENDIF
   189                                  
   190                                  	MOV	DX,[ss:BUF_EMS_HANDLE]	  ;LB.					;AN000;
   191                                  	MOV	AH,44H			  ;LB. activate current handle		;AN000;
   192                                  	MOV	AL,BYTE PTR [ss:BUF_EMS_PAGE_FRAME]  ;LB. page frame number	;AN000;
   193                                  	INT	67H			  ;LB.					;AN000;
   194                                  No_map: 									;AN000;
   195                                  	return									;AN000;
   196                                  EndProc SET_MAP_PAGE								;AN000;
   197                                  										;AN000;
   198                                  
   199                                  %IF	BUFFERFLAG
   200                                  
   201                                  Break	<SAVE_MAP - save map >							;AN000;
   202                                  ; Inputs:									;AN000;
   203                                  ;	none									;AN000;
   204                                  ; Function:									;AN000;
   205                                  ;	save map								;AN000;
   206                                  ; Outputs:									;AN000;
   207                                  ;	none									;AN000;
   208                                  ; No other registers altered							;AN000;
   209                                  										;AN000;
   210                                  Procedure   SAVE_MAP,NEAR							 ;AN000;
   211                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   212                                  										;AN000;
   213                                  	CMP	byte [ss:BUF_EMS_MODE],-1	  ;LB. EMS support			;AN000;
   214                                  	JZ	No_save 		  ;LB. no				;AN000;
   215                                  	MOV	word [ss:ACT_PAGE],-1		  ;LB. invalidate active page		;AN000;
   216                                  	MOV	WORD PTR [ss:LASTBUFFER],-1  ;LB.	and last buffer pointer 	;AN000;
   217                                  	PUSH	AX			  ;LB. save regs			;AN000;
   218                                  	PUSH	DS			  ;LB. save regs			;AN000;
   219                                  	PUSH	ES			  ;LB.					;AN000;
   220                                  	PUSH	SI			  ;LB.					;AN000;
   221                                  	PUSH	DI			  ;LB.					;AN000;
   222                                  	MOV	SI,OFFSET BUF_EMS_SEG_CNT wrt DOSGROUP     ;LB.			;AN000;
   223                                  	MOV	DI,OFFSET BUF_EMS_MAP_BUF wrt DOSGROUP     ;LB.			;AN000;
   224                                  
   225                                  	PUSH	ss
   226                                  	POP	ES
   227                                  	PUSH	ss			  ;LB.					;AN000;
   228                                  	POP	DS			  ;LB. ds:si -> ems seg count		;AN000;
   229                                  
   230                                  	MOV	AX,4F00H		  ;LB. save map 			;AN000;
   231                                  	EnterCrit  critDisk		  ;LB. enter critical section		;AN000;
   232                                  	INT	67H			  ;LB.					;AN000;
   233                                  	LeaveCrit  critDisk		  ;LB. leave critical section		;AN000;
   234                                  	POP	DI			  ;LB.					;AN000;
   235                                  	POP	SI			  ;LB. restore regs			;AN000;
   236                                  	POP	ES			  ;LB.					;AN000;
   237                                  	POP	DS			  ;LB.					;AN000;
   238                                  	POP	AX			  ;LB. restore				;AN000;
   239                                  No_save:									 ;AN000;
   240                                  	return									;AN000;
   241                                  EndProc SAVE_MAP								 ;AN000;
   242                                  										;AN000;
   243                                  
   244                                  Break	<RESTORE_MAP- retore map >						;AN000;
   245                                  ; Inputs:									;AN000;
   246                                  ;	none									;AN000;
   247                                  ; Function:									;AN000;
   248                                  ;	restore_map								;AN000;
   249                                  ; Outputs:									;AN000;
   250                                  ;	none									;AN000;
   251                                  ; No other registers altered							;AN000;
   252                                  										;AN000;
   253                                  Procedure   RESTORE_MAP,NEAR							 ;AN000;
   254                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   255                                  										;AN000;
   256                                  	CMP	byte [ss:BUF_EMS_MODE],-1	  ;LB. EMS support			;AN000;
   257                                  	JZ	No_restore		  ;LB. no				;AN000;
   258                                  	PUSH	AX			  ;LB. save regs			;AN000;
   259                                  	PUSH	DS			  ;LB. save regs			;AN000;
   260                                  	PUSH	SI			  ;LB.					;AN000;
   261                                  	MOV	SI,OFFSET BUF_EMS_MAP_BUF wrt DOSGROUP     ;LB.			;AN000;
   262                                  
   263                                  	PUSH	ss
   264                                  	POP	DS
   265                                  	MOV	AX,4F01H		  ;LB. restore map			;AN000;
   266                                  	EnterCrit  critDisk		  ;LB. enter critical section		;AN000;
   267                                  	INT	67H			  ;LB.					;AN000;
   268                                  	LeaveCrit  critDisk		  ;LB. leave critical section		;AN000;
   269                                  	POP	SI			  ;LB. restore regs			;AN000;
   270                                  	POP	DS			  ;LB.					;AN000;
   271                                  	POP	AX			  ;LB.					;AN000;
   272                                  No_restore:									 ;AN000;
   273                                  	return									;AN000;
   274                                  EndProc RESTORE_MAP								 ;AN000;
   275                                  
   276                                  %ENDIF
   277                                  										;AN000;
   278                                  										;AN000;
   279                                  
   280                                  Break	<SCANPLACE, PLACEBUF -- PUT A BUFFER BACK IN THE POOL>
   281                                  
   282                                  ; Inputs:
   283                                  ;	Same as PLACEBUF
   284                                  ; Function:
   285                                  ;	Save scan location and call PLACEBUF
   286                                  ; Outputs:
   287                                  ;	DS:DI Points to saved scan location
   288                                  ; SI destroyed, other registers unchanged
   289                                  
   290                                  	procedure   ScanPlace,near
   291                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   292                                  
   293                                  ;;	PUSH	ES
   294                                  ;;	LES	SI,[DI.buf_link]	; Save scan location
   295                                  	MOV	SI,[DI + buf_next]	; Save scan location
   296                                  	CALL	PLACEBUF
   297                                  ;;	PUSH	ES
   298                                  ;;	POP	DS			; Restore scan location
   299                                  	MOV	DI,SI
   300                                  ;;	POP	ES
   301                                  	return
   302                                  EndProc ScanPlace
   303                                  
   304                                  ; Rewritten PLACEBUF (LKR), eliminates loops
   305                                  ;
   306                                  ; Input:
   307                                  ;	DS:DI points to buffer (DS->BUFFINFO array, DI=offset in array)
   308                                  ; Function:
   309                                  ;	Remove buffer from queue and re-insert it in proper place.
   310                                  ; NO registers altered
   311                                  
   312                                  	procedure   PLACEBUF,NEAR
   313                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   314                                  
   315                                  ;	invoke	save_world
   316                                  	push	AX				;Save only regs we modify	;AN000;
   317                                  	push	BX								;AN000;
   318                                  	push	SI								;AN000;
   319                                  	push	ES								;AN000;
   320                                  
   321                                  	les	SI,[ss:CurHashEntry]		;ES:SI -> Current Hash entry	;AN000;
   322                                  	mov	BX,word ptr [ES:SI + BUFFER_BUCKET] ;BX = offset of head of list	;AN000;
   323                                  
   324                                  	cmp	[DI + buf_next],BX		;Buf = last?			;AN000;
   325                                  	je	nret				;Yes, special case		;AN000;
   326                                  	cmp	DI,BX				;Buf = first?			;AN000;
   327                                  	je	bufloop 			;Yes, special case		;AN000;
   328                                  	mov	SI,[DI + buf_prev]		;No, SI = prior Buf		;AN000;
   329                                  	mov	AX,[DI + buf_next]		;Now delete Buf from list	;AN000;
   330                                  	mov	[SI + buf_next],AX						;AN000;
   331                                  	push	SI				;Save si			;AN000;
   332                                  	mov	SI,[DI + buf_next]		;Update backward pointer	;AN000;
   333                                  	mov	AX,[DI + buf_prev]		;				;AN000;
   334                                  	mov	[SI + buf_prev],AX		;				;AN000;
   335                                  	pop	si				;Restore si			;AN000;
   336                                  lookend:				;(label is now a misnomer)		;AN000;
   337                                  	mov	SI,[BX + buf_prev]		;SI-> last buffer		;AN000;
   338                                  	mov	[SI + buf_next],DI		;Add Buf to end of list 	;AN000;
   339                                  	mov	[BX + buf_prev],DI						;AN000;
   340                                  	mov	[DI + buf_prev],SI		;Update linkage in Buf too	;AN000;
   341                                  	mov	[DI + buf_next],BX						;AN000;
   342                                  nret:										;AN000;
   343                                  										;AN000;
   344                                  ;	invoke	restore_world							;AN000;
   345                                  	pop	ES				;Restore regs we modified	;AN000;
   346                                  	pop	SI								;AN000;
   347                                  	pop	BX								;AN000;
   348                                  	pop	AX								;AN000;
   349                                  										;AN000;
   350                                  	cmp	byte [DI + buf_ID],-1			; Buffer FREE?			;AN000;
   351                                  	retnz					; No				;AN000;
   352                                  	invoke	PLACEHEAD			; Buffer is free, belongs at hea;AN000;
   353                                  	return									;AN000;
   354                                  bufloop:				;(label is now a misnomer)		;AN000;
   355                                  	mov	BX,[DI + buf_next]		;Set new head position		;AN000;
   356                                  	mov	word ptr [ES:SI + BUFFER_BUCKET],BX				;AN000;
   357                                  	jmp	nret				;Continue with repositioning	;AN000;
   358                                  
   359                                  EndProc PLACEBUF
   360                                  
   361                                  ; SAME AS PLACEBUF except places buffer at head
   362                                  ;  NOTE:::::: ASSUMES THAT BUFFER IS CURRENTLY THE LAST
   363                                  ;	ONE IN THE LIST!!!!!!!
   364                                  ; Rewritten PLACEBUF, takes buffer from end of list to head of list
   365                                  
   366                                  	procedure   PLACEHEAD,NEAR						;AN000;
   367                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   368                                  	push	ES								;AN000;
   369                                  	push	SI								;AN000;
   370                                  	les	SI,[ss:CurHashEntry]						;AN000;
   371                                  	mov	word ptr [ES:SI + BUFFER_BUCKET],DI				;AN000;
   372                                  	pop	SI								;AN000;
   373                                  	pop	ES								;AN000;
   374                                  	return									;AN000;
   375                                  EndProc PLACEHEAD								;AN000;
   376                                  
   377                                  
   378                                  Break	<POINTCOMP -- 20 BIT POINTER COMPARE>
   379                                  
   380                                  ; Compare DS:SI to ES:DI (or DS:DI to ES:SI) for equality
   381                                  ; DO NOT USE FOR < or >
   382                                  ; No Registers altered
   383                                  
   384                                  	procedure   PointComp,NEAR
   385                                   assume ds:nothing, es:nothing, ss:nothing
   386                                  
   387                                  	CMP	SI,DI
   388                                  	retnz
   389                                  	PUSH	CX
   390                                  	PUSH	DX
   391                                  	MOV	CX,DS
   392                                  	MOV	DX,ES
   393                                  	CMP	CX,DX
   394                                  	POP	DX
   395                                  	POP	CX
   396                                  	return
   397                                  EndProc PointComp
   398                                  
   399                                  Break	<GETBUFFR -- GET A SECTOR INTO A BUFFER>
   400                                  
   401                                  ; Input:
   402                                  ;	AL = 0 means sector must be pre-read
   403                                  ;	   ELSE no pre-read
   404                                  ;	DX = Desired physical sector number	      (LOW)
   405                                  ;	[HIGH_SECTOR]= Desired physical sector number (HIGH)
   406                                  ;	ES:BP = Pointer to drive parameters
   407                                  ;	[ALLOWED] set in case of INT 24
   408                                  ; Function:
   409                                  ;	Get the specified local sector into one of the I/O buffers
   410                                  ;	And shuffle the queue
   411                                  ; Output:
   412                                  ;	[CURBUF] Points to the Buffer for the sector
   413                                  ;	THE BUFFER TYPE FIELD OF buf_flags = 0, caller must set it
   414                                  ;	Carry set if error (currently user FAILed to INT 24)
   415                                  ; DS,DX,ES:BP unchanged, all other registers destroyed
   416                                  
   417                                  	procedure   GETBUFFR,NEAR
   418                                   assume ds:DOSGROUP, es:nothing, ss:DOSGROUP
   419                                  
   420                                  	XOR	SI,SI
   421                                  
   422                                  	entry	GETBUFFRB
   423                                   assume ds:DOSGROUP, es:nothing, ss:DOSGROUP
   424                                  
   425                                  	Assert	ISDPB,<ES,BP>,"GetBuffr"
   426                                  PREREAD equ PreRead	; NASM port label
   427                                  	MOV	[PREREAD],AX
   428                                  	MOV	AL,[ES:BP + dpb_drive]
   429                                  	LDS	DI,[LASTBUFFER]
   430                                   ASSUME DS:NOTHING
   431                                  	MOV	CX,[ss:HIGH_SECTOR]		; F.C. >32mb			;AN000;
   432                                  	CMP	DI,-1				; Recency pointer valid?
   433                                  	JZ	SKBUF				; No
   434                                  
   435                                  	CMP	DX,WORD PTR [DI + buf_sector]
   436                                  	JNZ	SKBUF				; Wrong sector
   437                                  	CMP	CX,WORD PTR [DI + buf_sector+2]	; F.C. >32mb			;AN000;
   438                                  	JNZ	SKBUF				; F.C. >32mb			;AN000;
   439                                  	CMP	AL,[DI + buf_ID]
   440                                  	JNZ	SKBUF				; Wrong Drive
   441                                  
   442                                  	JMP	JUSTBUF 			; Just asked for same buffer
   443                                  SKBUF:
   444                                  	CALL	GETCURHEAD			;LB. get cuurent Hash entry	;AN000;
   445                                  ;	LDS	DI,[BUFFHEAD]
   446                                  NXTBFF:
   447                                  	CMP	DX,WORD PTR [DI + buf_sector]	; F.C. >32mb			;AN000;
   448                                  	JNZ	BUMP
   449                                  	CMP	CX,WORD PTR [DI + buf_sector+2]	; F.C. >32mb			;AN000;
   450                                  	JNZ	BUMP				; F.C. >32mb			;AN000;
   451                                  	CMP	AL,[DI + buf_ID]
   452                                  %ifn BUFFERFLAG
   453                                  	JZ	SETINF
   454                                  %else
   455                                  bump equ BUMP	; NASM port label
   456                                  	jnz	bump
   457                                  setinf equ SETINF	; NASM port label
   458                                  	jmp	setinf
   459                                  %endif
   460                                  BUMP:
   461                                  	mov	DI,[DI + buf_next]		;;;;;;1/19/88			;AN000;
   462                                  	cmp	DI,[ss:FIRST_BUFF_ADDR]		;;;;;;1/19/88			;AN000;
   463                                  	JNZ	NXTBFF
   464                                  ;;;;	LDS	DI,[CurHashEntry]		;LB. secondary cache's use      ;AN000;
   465                                  ;;;;	LDS	DI,[DI.BUFFER_BUCKET]		;LB.				;AN000;
   466                                   ;	LDS	DI,[BUFFHEAD]
   467                                  	PUSH	word [ss:HIGH_SECTOR]			;F.C. >32mb			;AN000;
   468                                  	PUSH	SI
   469                                  	PUSH	DX
   470                                  	PUSH	BP
   471                                  	PUSH	ES
   472                                  BUFWRITE equ BufWrite	; NASM port label
   473                                  	CALL	BUFWRITE	; Write out the dirty buffer
   474                                  	POP	ES
   475                                  	POP	BP
   476                                  	POP	DX
   477                                  	POP	SI
   478                                  	POP	word [ss:HIGH_SECTOR]			;F.C. >32mb			;AN000;
   479                                  %ifn BUFFERFLAG
   480                                  	JC	GETBERR
   481                                  %else
   482                                  	jnc	skip_getberr
   483                                  getberr equ GETBERR	; NASM port label
   484                                  	jmp	getberr
   485                                  skip_getberr:
   486                                  %endif
   487                                  	CALL	SET_RQ_SC_PARMS 		;LB. set parms			;AN000;
   488                                  	XOR	AH,AH			; initial flags
   489                                  	TEST	BYTE PTR [ss:PREREAD],-1	; Read in the new sector
   490                                  	JNZ	SETBUF
   491                                  BufInSiz equ BUFINSIZ	; NASM port equate
   492                                  	LEA	BX,[DI + BufInSiz]	; Point at buffer
   493                                  	MOV	CX,1
   494                                  	PUSH	SI
   495                                  	PUSH	DI
   496                                  	PUSH	DX
   497                                  ; Note:  As far as I can tell, all disk reads into buffers go through this point.  -mrw 10/88
   498                                  %if	BUFFERFLAG
   499                                  ;	int	3
   500                                  buf_ems_mode equ BUF_EMS_MODE	; NASM port label
   501                                  	cmp	byte [ss:buf_ems_mode], -1
   502                                  	jz	normread
   503                                  	push	bx
   504                                  	push	ds		; save ds:bx --> ems_buffer
   505                                  	push	ss
   506                                  	pop	ds
   507                                  dosgroup equ DOSGROUP	; NASM port equate
   508                                  	mov	bx, offset low_ems_buf wrt dosgroup	; ds:bx --> low_ems_buffer
   509                                  normread:
   510                                  %endif
   511                                  	OR	SI,SI
   512                                  	JZ	NORMSEC
   513                                  	invoke	FATSECRD
   514                                  	MOV	AH,buf_isFAT		; Set buf_flags
   515                                  	JMP	SHORT GOTTHESEC 	; Buffer is marked free if read barfs
   516                                  NORMSEC:
   517                                  	invoke	DREAD			; Buffer is marked free if read barfs
   518                                  	MOV	AH,0			; Set buf_flags to no type, DO NOT XOR!
   519                                  GOTTHESEC:				; Carry set by either FATSECRD or DREAD
   520                                  %if	BUFFERFLAG
   521                                  	pushf
   522                                  	jc	skipreadtrans
   523                                  	cmp	byte [ss:buf_ems_mode], -1
   524                                  	je	skipreadtrans
   525                                  
   526                                  	popf
   527                                  	pop	ds
   528                                  	pop	bx		; restore ems_buffer pointer
   529                                  	pushf
   530                                  
   531                                  	push	cx		; save regs to be used by rep mov
   532                                  	push	ds
   533                                  	push	es
   534                                  
   535                                  	mov	di, bx
   536                                  	push	ds		
   537                                  	pop	es		; es:di --> ems_buf
   538                                  	mov	si, offset low_ems_buf wrt dosgroup
   539                                  	push	ss
   540                                  	pop	ds		; ds:si --> low_ems_buf
   541                                  	mov	cx, 512/2
   542                                  	rep movsw
   543                                  
   544                                  	pop	es		; restore regs.
   545                                  	pop	ds
   546                                  	pop	cx
   547                                  skipreadtrans:
   548                                  	popf
   549                                  %endif
   550                                  	POP	DX
   551                                  	POP	DI
   552                                  	POP	SI
   553                                  	JC	GETBERR
   554                                  SETBUF:
   555                                  	MOV	CX,[ss:HIGH_SECTOR]	       ; F.C. >32mb			;AN000;
   556                                  	MOV	WORD PTR [DI + buf_sector+2],CX  ; F.C. >32mb			;AN000;
   557                                  	MOV	WORD PTR [DI + buf_sector],DX    ; F.C. >32mb			;AN000;
   558                                  	MOV	WORD PTR [DI + buf_DPB],BP
   559                                  	MOV	WORD PTR [DI + buf_DPB+2],ES
   560                                  	MOV	AL,[ES:BP + dpb_drive]
   561                                  	MOV	WORD PTR [DI + buf_ID],AX 	; Sets buf_flags too, to AH
   562                                  SETINF:
   563                                  	MOV	byte [DI + buf_wrtcnt],1		; Default to not a FAT sector	;AC000;
   564                                  	XOR	AX,AX				;>32mb				;AN000;
   565                                  	OR	SI,SI
   566                                  	JZ	SETSTUFFOK
   567                                  	MOV	AL,[ES:BP + dpb_FAT_count]
   568                                  	MOV	[DI + buf_wrtcnt],AL		;>32mb				;AN000;
   569                                  	MOV	AX,[ES:BP + dpb_FAT_size]
   570                                  SETSTUFFOK:
   571                                  	MOV	[DI + buf_wrtcntinc],AX		;>32mb				;AC000;
   572                                  	CALL	PLACEBUF
   573                                  JUSTBUF:
   574                                  CURBUF equ CurBuf	; NASM port label
   575                                  	MOV	WORD PTR [ss:CURBUF+2],DS
   576                                  	MOV	WORD PTR [ss:LASTBUFFER+2],DS
   577                                  	MOV	WORD PTR [ss:CURBUF],DI
   578                                  	MOV	WORD PTR [ss:LASTBUFFER],DI
   579                                  	CLC
   580                                  GETBERR:
   581                                  	Context DS
   582                                  	return
   583                                  EndProc GETBUFFR
   584                                  
   585                                  Break	<FLUSHBUF -- WRITE OUT DIRTY BUFFERS>
   586                                  
   587                                  ; Input:
   588                                  ;	DS = DOSGROUP
   589                                  ;	AL = Physical unit number local buffers only
   590                                  ;	   = -1 for all units and all remote buffers
   591                                  ; Function:
   592                                  ;	Write out all dirty buffers for unit, and flag them as clean
   593                                  ;	Carry set if error (user FAILed to I 24)
   594                                  ;	    Flush operation completed.
   595                                  ; DS Preserved, all others destroyed (ES too)
   596                                  
   597                                  	procedure   FlushBuf,NEAR
   598                                   assume ds:DOSGROUP, es:nothing, ss:DOSGROUP
   599                                  
   600                                  	MOV	AH,-1
   601                                  ;	LDS	DI,[BUFFHEAD]
   602                                   ASSUME DS:NOTHING
   603                                  
   604                                  	LDS	DI,[ss:BUF_HASH_PTR]	  ;LB. get Hash Table addr		;AN000;
   605                                  	MOV	CX,[ss:BUF_HASH_COUNT]	  ;LB. get Hash entry count		;AN000;
   606                                  	XOR	DX,DX			  ;LB. set initial index to 0		;AN000;
   607                                  
   608                                  NXTBUFF2:
   609                                  	PUSH	CX			     ;LB. save Hash entry count 	;AN000;
   610                                  	TEST	word [ss:DOS34_FLAG],FROM_DISK_RESET ;MS. from disk reset		;AN004;
   611                                  	JNZ	Zapzap			     ;MS. yes				;AN004;
   612                                  Dirty_Count equ DIRTY_COUNT	; NASM port equate
   613                                  	CMP	byte [DI + Dirty_Count],0	     ;LB. dirty entry ? 		;AN000;
   614                                  	JZ	getnext 		     ;LB. no				;AN000;
   615                                  Zapzap: 									;AN004;
   616                                  	PUSH	DS			     ;LB. save regs			;AN000;
   617                                  	PUSH	DI			     ;LB.				;AN000;
   618                                  	invoke	Map_Entry		     ;LB. ds:di -> first buffer addr	;AN000;
   619                                  NXTBUFF:
   620                                  	CALL	CHECKFLUSH	; Ignore Carry return from CHECKFLUSH.
   621                                  				; FAILERR is set if user FAILed.
   622                                  	PUSH	AX
   623                                  	MOV	AL,[DI + buf_ID]
   624                                  WPERR equ WPErr	; NASM port label
   625                                  	CMP	AL,BYTE PTR [ss:WPERR]
   626                                  ZAP equ Zap	; NASM port label
   627                                  	JZ	ZAP
   628                                  	TEST	word [ss:DOS34_FLAG],FROM_DISK_RESET ;MS. from disk reset		;AN000;
   629                                  	JNZ	Zap			     ;MS. yes				;AN000;
   630                                  
   631                                  NOZAP:
   632                                  	POP	AX
   633                                  	mov	DI,[DI + buf_next]	     ;;;;1/19/88			;AN000;
   634                                  	CMP	DI,[ss:FIRST_BUFF_ADDR]	     ;;;;1/19/88			;AN000;
   635                                  	JNZ	NXTBUFF
   636                                  
   637                                  	POP	DI			     ;LB.				;AN000;
   638                                  	POP	DS			     ;LB.				;AN000;
   639                                  getnext:
   640                                  	ADD	DI,BUFFER_HASH_ENTRY_struc_size    ;LB. position to next entry	;AN000;
   641                                  	POP	CX			     ;LB. restore entry count		;AN000;
   642                                  	LOOP	NXTBUFF2		     ;LB. get next entry buffer 	;AN000;
   643                                  	Context DS
   644                                  	CMP	byte [FAILERR],0
   645                                  FLSHBad equ FlshBad	; NASM port label
   646                                  	JNZ	FLSHBad 	; Carry clear if JMP
   647                                  	return
   648                                  FlshBad:
   649                                  	STC			; Return error if user FAILed
   650                                  	return
   651                                  Zap:
   652                                  	MOV	WORD PTR [DI + buf_ID],00FFH ; Invalidate buffer, it is inconsistent
   653                                  NoZap equ NOZAP	; NASM port label
   654                                  	JMP	NoZap
   655                                  
   656                                  EndProc FlushBuf
   657                                  
   658                                  	procedure CHECKFLUSH,NEAR
   659                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   660                                  ; Carry set if problem (currently user FAILed to I 24)
   661                                  
   662                                  	Assert	ISBUF,<DS,DI>,"CheckFlush"
   663                                  	CMP	[DI + buf_ID],AH
   664                                  	retz				; Skip free buffers, carry clear
   665                                  	CMP	AH,AL
   666                                  	JZ	DOBUFFER		; Do all dirty buffers
   667                                  	CMP	AL,[DI + buf_ID]
   668                                  	CLC
   669                                  	retnz				; Buffer not for this unit or SFT
   670                                  DOBUFFER:
   671                                  	TEST	byte [DI + buf_flags],buf_dirty
   672                                  	retz				; Buffer not dirty, carry clear by TEST
   673                                  	PUSH	AX
   674                                  	PUSH	WORD PTR [DI + buf_ID]
   675                                  	CALL	BUFWRITE
   676                                  	POP	AX
   677                                  	JC	LEAVE_BUF		; Leave buffer marked free (lost).
   678                                  	AND	AH,~ buf_dirty	; Buffer is clean, clears carry
   679                                  	MOV	WORD PTR [DI + buf_ID],AX
   680                                  LEAVE_BUF:
   681                                  	POP	AX			; Search info
   682                                  	return
   683                                  EndProc CHECKFLUSH
   684                                  
   685                                  Break	<BUFWRITE -- WRITE OUT A BUFFER IF DIRTY>
   686                                  
   687                                  ; Input:
   688                                  ;	DS:DI Points to the buffer
   689                                  ; Function:
   690                                  ;	Write out all the buffer if dirty.
   691                                  ; Output:
   692                                  ;	Buffer marked free
   693                                  ;	Carry set if error (currently user FAILed to I 24)
   694                                  ; DS:DI Preserved, ALL others destroyed (ES too)
   695                                  
   696                                  	procedure   BufWrite,NEAR
   697                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   698                                  
   699                                  	Assert	ISBUF,<DS,DI>,"BufWrite"
   700                                  	MOV	AX,00FFH
   701                                  	XCHG	AX,WORD PTR [DI + buf_ID] ; Free, in case write barfs
   702                                  	CMP	AL,0FFH
   703                                  	retz				; Buffer is free, carry clear.
   704                                  	TEST	AH,buf_dirty
   705                                  	retz				; Buffer is clean, carry clear.
   706                                  	invoke	DEC_DIRTY_COUNT 	; LB. decrement dirty count
   707                                  	CMP	AL,BYTE PTR [ss:WPERR]
   708                                  	retz				; If in WP error zap buffer
   709                                  	MOV	[ss:SC_DRIVE],AL		;LB. set it for invalidation		;AN000;
   710                                  	LES	BP,[DI + buf_DPB]
   711                                  	LEA	BX,[DI + BufInSiz]	; Point at buffer
   712                                  	MOV	DX,WORD PTR [DI + buf_sector]	;F.C. >32mb			;AN000;
   713                                  	MOV	CX,WORD PTR [DI + buf_sector+2]	;F.C. >32mb			;AN000;
   714                                  	MOV	[ss:HIGH_SECTOR],CX		;F.C. >32mb			;AN000;
   715                                  	MOV	CL,[DI + buf_wrtcnt]		;>32mb				;AC000;
   716                                  ;	MOV	AL,CH			; [DI.buf_wrtcntinc]
   717                                  	XOR	CH,CH
   718                                  	MOV	AX,[DI + buf_wrtcntinc]		;>32mb				;AC000;
   719                                  allowed_RETRY equ Allowed_RETRY	; NASM port equate
   720                                  allowed_FAIL equ Allowed_FAIL	; NASM port equate
   721                                  	MOV	byte [ss:ALLOWED],allowed_RETRY + allowed_FAIL
   722                                  	TEST	byte [DI + buf_flags],buf_isDATA
   723                                  	JZ	NO_IGNORE
   724                                  allowed_IGNORE equ Allowed_IGNORE	; NASM port equate
   725                                  	OR	byte [ss:ALLOWED],allowed_IGNORE
   726                                  NO_IGNORE:
   727                                  	PUSH	DI		; Save buffer pointer
   728                                  	XOR	DI,DI		; Indicate failure
   729                                  WRTAGAIN:
   730                                  	SaveReg <DI,CX,AX>
   731                                  	MOV	CX,1
   732                                  	SaveReg <BX,DX,DS>
   733                                  ; Note:  As far as I can tell, all disk reads into buffers go through this point.  -mrw 10/88
   734                                  
   735                                  %if	BUFFERFLAG
   736                                  ;	int	3
   737                                  	cmp	byte [ss:buf_ems_mode], -1
   738                                  	jz	skipwritetrans
   739                                  
   740                                  	push	es
   741                                  	push	di
   742                                  	push	si
   743                                  	push	cx
   744                                  
   745                                  	mov	si, bx		; ds:si --> ems_buffer
   746                                  	mov	di, offset low_ems_buf wrt dosgroup
   747                                  	push	ss
   748                                  	pop	es		; es:di --> low_ems_buffer
   749                                  	mov	cx, 512/2
   750                                  	rep	movsw
   751                                  
   752                                  	pop	cx
   753                                  	pop	si
   754                                  	pop	di
   755                                  	pop	es
   756                                  
   757                                  	push	ds
   758                                  	push	bx
   759                                  	mov	bx, offset low_ems_buf wrt dosgroup
   760                                  	push	ss
   761                                  	pop	ds		; ds:bx --> low_ems_buffer
   762                                  skipwritetrans:
   763                                  %endif
   764                                  
   765                                  	invoke	DWRITE		; Write out the dirty buffer
   766                                  
   767                                  %if	BUFFERFLAG
   768                                  	pushf			; save carry flag from DWRITE
   769                                  	cmp	byte [ss:buf_ems_mode], -1
   770                                  	jz	normwrite
   771                                  	popf			; need to get at stack
   772                                  	pop	bx		; ds:bx --> ems_buffer
   773                                  	pop	ds
   774                                  	pushf			; put it back, so we can pop it
   775                                  normwrite:
   776                                  	popf			; restore carry flag
   777                                  %endif
   778                                  
   779                                  	RestoreReg  <DS,DX,BX>
   780                                  	RestoreReg  <AX,CX,DI>
   781                                  	JC	NOSET
   782                                  	INC	DI		; If at least ONE write succeedes, the operation
   783                                  NOSET:				;	succeedes.
   784                                  	ADD	DX,AX
   785                                  	LOOP	WRTAGAIN
   786                                  	OR	DI,DI		; Clears carry
   787                                  	JNZ	BWROK		; At least one write worked
   788                                  	STC			; DI never got INCed, all writes failed.
   789                                  BWROK:
   790                                  	POP	DI
   791                                  	return
   792                                  EndProc BufWrite
   793                                  
   794                                  Break	<SET_RQ_SC_PARMS-set requesting drive for SC>
   795                                  
   796                                  ; Input:
   797                                  ;	ES:BP = drive parameter block
   798                                  ; Function:
   799                                  ;	Set requesting drive, and sector size
   800                                  ; Output:
   801                                  ;	[SC_SECTOR_SIZE]= drive sector size
   802                                  ;	[SC_DRIVE]= drive #
   803                                  ;
   804                                  ; All registers preserved
   805                                  
   806                                  	procedure   SET_RQ_SC_PARMS,NEAR
   807                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   808                                  
   809                                  	CMP	word [ss:SC_CACHE_COUNT],0  ;LB. do it only secondary cache exists	;AN000;
   810                                  	JZ	nosec		    ;LB.					;AN000;
   811                                  	PUSH	DX		    ;LB. save dx				;AN000;
   812                                  	MOV	DX,[ES:BP + dpb_sector_size]	      ;LB. save sector size	;AN000;
   813                                  	MOV	[ss:SC_SECTOR_SIZE],DX		      ;LB.			;AN000;
   814                                  	MOV	DL,[ES:BP + dpb_drive]		      ;LB. save drive # 	;AN000;
   815                                  	MOV	[ss:SC_DRIVE],DL			      ;LB.			;AN000;
   816                                  										;AN000;
   817                                  	POP	DX				      ;LB. restore dx		;AN000;
   818                                  
   819                                  nosec:
   820                                  	return
   821                                  EndProc SET_RQ_SC_PARMS 			      ;LB. return		;AN000;
   822                                  
   823                                  Break	<INC_DIRTY_COUNT-increment dirty count>
   824                                  
   825                                  ; Input:
   826                                  ;	none
   827                                  ; Function:
   828                                  ;	increment dirty buffers count
   829                                  ; Output:
   830                                  ;	dirty buffers count in the current hash entry is incremented
   831                                  ;
   832                                  ; All registers preserved
   833                                  
   834                                  	procedure   INC_DIRTY_COUNT,NEAR
   835                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   836                                  
   837                                  	PUSH	DS		    ;LB. save regs				;AN000;
   838                                  	PUSH	SI		    ;LB.					;AN000;
   839                                  	LDS	SI,[ss:CurHashEntry]   ;LB. get current hash entry 		;AN000;
   840                                  	INC	byte [SI + Dirty_Count]    ;LB. add 1					;AN000;
   841                                  	POP	SI		    ;LB. restore regs				;AN000;
   842                                  	POP	DS		    ;LB.					;AN000;
   843                                  	return
   844                                  EndProc INC_DIRTY_COUNT 	    ;LB. return 				;AN000;
   845                                  
   846                                  Break	<DEC_DIRTY_COUNT-decrement dirty count>
   847                                  
   848                                  ; Input:
   849                                  ;	none
   850                                  ; Function:
   851                                  ;	decrement dirty buffers count
   852                                  ; Output:
   853                                  ;	dirty buffers count in the current hash entry is decremented
   854                                  ;
   855                                  ; All registers preserved
   856                                  
   857                                  	procedure   DEC_DIRTY_COUNT,NEAR
   858                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   859                                  
   860                                  	PUSH	DS		    ;LB. save regs				;AN000;
   861                                  	PUSH	SI		    ;LB.					;AN000;
   862                                  	LDS	SI,[ss:CurHashEntry]   ;LB. get current hash entry 		;AN000;
   863                                  	CMP	byte [SI + Dirty_Count],0  ;LB. in case if 0				;AN000;
   864                                  	JZ	nodec		    ;LB. do nothing				;AN000;
   865                                  	DEC	byte [SI + Dirty_Count]    ;LB. sub 1					;AN000;
   866                                  nodec:
   867                                  	POP	SI		    ;LB. restore regs				;AN000;
   868                                  	POP	DS		    ;LB.					;AN000;
   869                                  	return
   870                                  EndProc DEC_DIRTY_COUNT 	    ;LB. return 				;AN000;
   871                                  
   872                                  
   873                                  Break	<MAP_ENTRY- map the buffers of this entry>
   874                                  
   875                                  ; Input:
   876                                  ;	DS:DI ponits to hash entry
   877                                  ; Function:
   878                                  ;	map the buferrs of this entry
   879                                  ; Output:
   880                                  ;	the buffers are mapped
   881                                  ;
   882                                  ; All registers preserved
   883                                  
   884                                  	procedure   Map_Entry,NEAR
   885                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   886                                  
   887                                  	PUSH	DX			  ;LB. save regs			;AN000;
   888                                  	PUSH	AX			  ;LB.					;AN000;
   889                                  	PUSH	BX			  ;LB.					;AN000;
   890                                  	JMP	Map_Entry2		  ;LB.					;AN000;
   891                                  EndProc Map_Entry			  ;LB.					;AN000;
   892                                  
   893                                  
   894                                  %IF	BUFFERFLAG
   895                                  
   896                                  ;-------------------------------------------------------------------------
   897                                  ;	Procedure name	:	detect collision
   898                                  ;	Inputs		:	[DMAADD] - user Xaddr
   899                                  ;				[CURADD] - current offset
   900                                  ;				[BYTCNT1] - for partial sector read
   901                                  ;				SAFE_FLAG - cleared - indicating that the
   902                                  ;				current page is unsafe.
   903                                  ;
   904                                  ;	Outputs		:	es - physical page segment to use
   905                                  ;				di - corresponding page number
   906                                  ;				SAFE_FLAG is set is a collision is detected
   907                                  ;				and the current page is switched form 
   908                                  ;				LAST_PAGE to FIRST_PAGE.
   909                                  ;---------------------------------------------------------------------------
   910                                  ;				
   911                                  
   912                                  Procedure	detect_collision, near
   913                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   914                                  
   915                                  	push	ax
   916                                  	push	bx
   917                                  	push	cx
   918                                  
   919                                  	cmp	byte [ss:BUF_EMS_MODE], -1
   920                                  	jz	fin_detect_coll
   921                                  
   922                                  	mov	ax, [ss:CURADD]	; current offset 
   923                                  
   924                                  	cmp	word [ss:BYTCNT1], 0
   925                                  	je	no_partial_sector
   926                                  	add	ax, [ss:BYTCNT1]
   927                                  
   928                                  no_partial_sector:
   929                                  	mov	cl, 4
   930                                  	shr	ax, cl		; convert to paragraphs
   931                                  	mov	bx, word ptr [ss:DMAADD+2]	; get original segment 
   932                                  	add	ax, bx		; get current segment
   933                                  
   934                                  	and	ax, 0fc00h	; get ems page of current segment
   935                                  	cmp	ax, [ss:BUF_EMS_LAST_PAGE]	; is the current segment = last segment
   936                                  	jne	fin_detect_coll	; page is still safe
   937                                  
   938                                  ;	int	3
   939                                  	push	ax
   940                                  	mov	ax, word ptr [ss:DMAADD]
   941                                  	mov	ax, [ss:NEXTADD]
   942                                  	mov	ax, [ss:CURADD]
   943                                  	mov	ax, [ss:BYTCNT1]
   944                                  	pop	ax
   945                                  
   946                                  restore_user_map equ RESTORE_USER_MAP	; NASM port label
   947                                  	call	restore_user_map
   948                                  	mov	word ptr [ss:LASTBUFFER], -1
   949                                  	mov	ax, [ss:BUF_EMS_FIRST_PAGE]
   950                                  	mov	[ss:BUF_EMS_PFRAME], ax
   951                                  	mov	ax, [ss:BUF_EMS_FIRST_PAGE+2]
   952                                  	mov	[ss:BUF_EMS_PAGE_FRAME], ax
   953                                  	mov	byte [ss:BUF_EMS_SAFE_FLAG], 1
   954                                  Setup_EMS_buffers equ Setup_EMS_Buffers	; NASM port label
   955                                  	call	Setup_EMS_buffers
   956                                  save_user_map equ SAVE_USER_MAP	; NASM port label
   957                                  	call	save_user_map
   958                                  
   959                                  fin_detect_coll:
   960                                  	pop	cx
   961                                  	pop	bx
   962                                  	pop	ax
   963                                  	ret
   964                                  
   965                                  EndProc	detect_collision
   966                                  
   967                                  Procedure Setup_EMS_Buffers,Near
   968                                   assume ds:nothing, es:nothing, ss:DOSGROUP
   969                                  
   970                                  	cmp	byte [ss:BUF_EMS_MODE], -1
   971                                  	jz	setup_ems_ret
   972                                  
   973                                  	push	bx
   974                                  	push	cx
   975                                  	push	ax
   976                                  	push	ds
   977                                  	push	di
   978                                  
   979                                  	mov	bx, [ss:BUF_HASH_COUNT]	; # of hash table entries
   980                                  	lds	di, [ss:BUF_HASH_PTR]	; ds:di -> hash table
   981                                  
   982                                  	xor	cx, cx
   983                                  
   984                                  next_bucket:
   985                                  	mov	ax, [ss:BUF_EMS_PFRAME]
   986                                  	mov	word ptr [di + BUFFER_BUCKET+2], ax
   987                                  	add	di, 8			; next has entry.
   988                                  	inc	cx
   989                                  	cmp	cx, bx
   990                                  	jne	next_bucket
   991                                  
   992                                  	pop	di
   993                                  	pop	ds
   994                                  	pop	ax
   995                                  	pop	cx
   996                                  	pop	bx
   997                                  
   998                                  setup_ems_ret:
   999                                  	ret
  1000                                  
  1001                                  EndProc	Setup_EMS_Buffers
  1002                                  
  1003                                  %ENDIF
  1004                                  
  1005                                      END
  1006                                  
  1007                                  %endif	; BUF2
