***************************************
README FOR UPDATED DELPHI 2 SYSTEM UNIT
***************************************

The updated System.dcu for Delphi 2.01 addresses two problems:

  * The behavior of the FileMode system variable was modified for
    greater backward compatibility.  Non-text files opened
    with Reset() now support all DOS file modes, not only the
    documented 0, 1 and 2. In particular, you can now use shared
    file modes.

  * A bug was fixed in the memory suballocator which caused a
    16-byte memory leak for every freed block.

Install the updated System.dcu by copying it to your Delphi 2.0\Lib
directory.  Then update your component library by selecting
Component|Rebuild Library from the main menu.

*******************
SOURCE CODE CHANGES
*******************

The GetMem.inc and OpenFile.asm modules were modified to accommodate
the above changes to System.dcu.  If you own Delphi Developer or
Delphi Client/Server Suite, then you will find these files in the
...\Delphi 2.0\source\rtl\sys subdirectory.

If you wish to update your installation of the source code to reflect
the changes to System.dcu, then you can follow the directions below
for hand-modification of GetMem.inc and OpenFile.asm.

**********
GETMEM.INC
**********

* Remove FreeBlockDesc() procedure (line 142).

* Replace DeleteBlock() procedure (line 179) with the following code:

  procedure DeleteBlock(bd: PBlockDesc);
  var
    prev, next: PBlockDesc;
  begin
    prev := bd.prev;
    next := bd.next;
    prev.next := next;
    next.prev := prev;
    bd.next := blockDescFreeList;
    blockDescFreeList := bd;
  end;

* Replace MergeBlockAfter() function (line 190) with the following code:

  function MergeBlockAfter(prev: PBlockDesc; const b: TBlock) : TBlock;
  var
    bd, bdNext: PBlockDesc;
  begin
    bd := prev.next;
    result := b;
    repeat
      bdNext := bd.next;
      if bd.addr + bd.size = result.addr then begin
        DeleteBlock(bd);
        result.addr := bd.addr;
        inc(result.size, bd.size);
      end else if result.addr + result.size = bd.addr then begin
        DeleteBlock(bd);
        inc(result.size, bd.size);
      end;
      bd := bdNext;
    until bd = prev;
    if not AddBlockAfter(prev, result) then
      result.addr := nil;
  end;

* Replace FreeSpace() function (line 303) with the following code:

  function FreeSpace(addr: Pointer; maxSize: Integer): TBlock;
  // Free at most maxSize bytes of address space at addr.
  // Returns the block that was actually freed.
  var
    bd, bdNext: PBlockDesc;
    minAddr, maxAddr, startAddr, endAddr: PChar;
  begin
    minAddr := PChar($FFFFFFFF);
    maxAddr := nil;
    startAddr := addr;
    endAddr   := startAddr + maxSize;
    bd := spaceRoot.next;
    while bd <> @spaceRoot do begin
      bdNext := bd.next;
      if (bd.addr >= startAddr) and (bd.addr + bd.size <= endAddr) then begin
        if minAddr > bd.addr then
          minAddr := bd.addr;
        if maxAddr < bd.addr + bd.size then
          maxAddr := bd.addr + bd.size;
        if not VirtualFree(bd.addr, 0, MEM_RELEASE) then
          heapErrorCode := cReleaseErr;
        DeleteBlock(bd);
      end;
      bd := bdNext;
    end;
    result.addr := nil;
    if maxAddr <> nil then begin
      result.addr := minAddr;
      result.size := maxAddr - minAddr;
    end;
  end;

************
OPENFILE.ASM
************

* Replace line 63: 

    MOV    EDX,FILE_SHARE_READ

  with the following four lines:

    MOV    DL,FileMode
    AND    EDX,070H
    SHR    EDX,4-2
    MOV    EDX,dword ptr [@@shareTab+EDX]

* After line 131:

    JMP    @@exit

  and before line 133:

    OpenFile ENDP

  insert the following nine lines:

    @@shareTab:
      DD    FILE_SHARE_READ OR FILE_SHARE_WRITE   ; OF_SHARE_COMPAT     0x00000000
      DD    0                                     ; OF_SHARE_EXCLUSIVE  0x00000010
      DD    FILE_SHARE_READ                       ; OF_SHARE_DENY_WRITE 0x00000020
      DD    FILE_SHARE_WRITE                      ; OF_SHARE_DENY_READ  0x00000030
      DD    FILE_SHARE_READ OR FILE_SHARE_WRITE   ; OF_SHARE_DENY_NONE  0x00000040
      DD    0
      DD    0
      DD    0

* After line 144:

    MOV    CL,FileMode

  and before line 145:

    CMP    CL,2

  insert the following line:

    AND    CL,3
