program mput;
{$NOMAIN}
{$NOWALKBACK}

{
File		: DE:[22,310]MPUT.PAS
Author		: Peter Stadick
Date		: Aug 29,89
Edit History	:

       Last Edit: 30-AUG-1989 15:16:48 

Description:

	This routine stores an array element in the shared region.

}

%include lb:[22,320]general3.typ;
%include de:[22,320]marray.typ;

%include de:[22,320]marray.ext;
%include de:[22,320]bytmov.ext;
%include de:[22,320]mappa.ext;
%include de:[22,320]elawpa.ext;
%include de:[22,320]crawpa.ext;

procedure mput;

const
  debug = false;

type
  apr_block_point = ^apr_use_type;

var
  window_number		: integer;
  offset_to_element	: integer;
  apr_address		: address;
  element_address	: address;
  remap			: boolean;
  wdb			: wdb_type;
  apr_use_block		: apr_block_point;

begin
  error_code := 1;
  { check to see if pointers are used. If they are, the person using this
    routine does not realise he is directly writing to the data in the
    shared region and the put operation is meaningless. }
  if not m_array.use_pointer then
  begin
    remap := false;
    if (element_number < 1) or (element_number > m_array.max_elements) then
      error_code := -1003
    else
    begin
      apr_use_block := loophole(apr_block_point,m_array.apr_use_address);
      if not ((apr_use_block^[m_array.apr_to_use][1] = m_array.rdb[3]) and
        (apr_use_block^[m_array.apr_to_use][2] = m_array.rdb[4])) then
      begin
        { correct region is not mapped so we eliminate the old address window
	and create a new one for this region }
        if debug then
          writeln('REMAP-PUT');
        remap := true;
        wdb[1] := apr_use_block^[m_array.apr_to_use][3];
        elawpa(wdb);
        crawpa(m_array.wdb);
        if $dsw < 0 then
          error_code := $dsw - 400;

        { Update apr use block }
        apr_use_block^[m_array.apr_to_use][1] := m_array.rdb[3];
        apr_use_block^[m_array.apr_to_use][2] := m_array.rdb[4];
        apr_use_block^[m_array.apr_to_use][3] := m_array.wdb[1];
      end;
      element_number := element_number - 1;
      window_number := element_number div m_array.elements_per_window;

      { Check to see if we have the write window mapped }
      if remap or not (window_number = m_array.current_window) then
      begin
        { Opps, don't have the correct mapped so lets remap it }
        m_array.wdb[5] := window_number * m_array.blocks_per_window;
        mappa(m_array.wdb);
        if $dsw < 0 then
        begin
          error_code := $dsw - 600;
          m_array.current_window := -1;
        end
        else
          m_array.current_window := window_number;
      end;

      { Now lets find the element in the window }
      if error_code > 0 then
      begin
        { Compute offset in number of bytes into window the element in question 
          is }
        offset_to_element := 
          (element_number mod m_array.elements_per_window)*m_array.element_size;

        { Now we need to region from data located at buffer_address }
        apr_address := m_array.apr_to_use * 20000B;
        element_address := loophole(address,apr_address) + offset_to_element;
        bytmov(m_array.buffer_address,element_address,m_array.element_size);
      end;
    end;
  end;
end;
