program mope;
{$NOMAIN}
{$NOWALKBACK}

{

File		: DE:[22,310]MOPEN.PAS;
Author		: Peter Stadick
Date		: Aug 28,89
Edit History	:

       Last Edit: 30-AUG-1989 11:51:31 

Description:
	This routine initializes the shared region and determines the 
	correct parameters.
}
%include lb:[22,320]general3.typ;
%include de:[22,320]marray.typ;

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

procedure mopen;

var
  region_rad56	: rad56;
  par_rad56	: rad56;

  apr_address	: address;
  apr_add_add	: address;

begin
  error_code := 1;
  { Verify that APR is valid }
  if (apr < 1) or (apr > 7) then
    error_code := -1000;

  if (element_size > 8192) or (element_size < 1) then
    error_code := -1001;

  if max_elements < 1 then
    error_code := -1002;

  if error_code > 0 then
  begin
    m_array.apr_to_use := apr;
    m_array.max_elements := max_elements;
    m_array.element_size := element_size;
    m_array.buffer_address := buffer_address;
    m_array.use_pointer := pointer_in_use;
    m_array.current_window := 0;
    m_array.apr_use_address := loophole(address,ref(apr_use_block));

    { compute number of elements per window }
    m_array.elements_per_window := 8192 div element_size;

    { compute number of 64 byte blocks per window }
    m_array.blocks_per_window := 
      (m_array.elements_per_window * element_size) div 64;
    if (m_array.elements_per_window * element_size) mod 64 > 0 then
      m_array.blocks_per_window := m_array.blocks_per_window + 1;

    { compute number of windows }
    m_array.number_of_windows := 
      m_array.max_elements div m_array.elements_per_window;
    if (m_array.max_elements mod m_array.elements_per_window) > 0 then
      m_array.number_of_windows := m_array.number_of_windows + 1;

    { compute region size }
    m_array.rdb[2] := m_array.number_of_windows * m_array.blocks_per_window;
    { Convert region name to rad56 }
    catr56(region_name,region_rad56);
    m_array.rdb[3] := region_rad56[1];
    m_array.rdb[4] := region_rad56[2];
    { Add in partition name. Use GEN }
    catr56('GEN   ',par_rad56);
    m_array.rdb[5] := par_rad56[1];  
    m_array.rdb[6] := par_rad56[2];
    { Region status word. Set RS.MDL,RS.ATT,RS.NEX,RS.WRT,RS.RED }
    m_array.rdb[7] := 200B + 40B + 20B + 2 + 1;
    { Region protection word. Set W:RWED, G:RWED, O:RWED, S:RWED}
    m_array.rdb[8] := 0;

    crrgpa(m_array.rdb);
  end;

  if ($dsw < 0) and (error_code > 0) then
    error_code := $dsw;

  { now attach region }
  if error_code > 0 then
    atrgpa(m_array.rdb);

  if ($dsw < 0) and (error_code > 0) then
    error_code := $dsw-200;

  { now create address window }
  if error_code > 0 then
  begin
    { check for existing address window }
    if not ((apr_use_block[m_array.apr_to_use][1] = 0) and
      (apr_use_block[m_array.apr_to_use][2] = 0)) then
    begin
      { Must first eliminate old window }
      m_array.wdb[1] := apr_use_block[m_array.apr_to_use][3];
      elawpa(m_array.wdb);
    end;

    m_array.wdb[1] := m_array.apr_to_use * 256;
    m_array.wdb[3] := m_array.blocks_per_window;
    m_array.wdb[4] := m_array.rdb[1];
    m_array.wdb[5] := 0;
    m_array.wdb[6] := m_array.blocks_per_window;
    { Window status word: WS.64B,WS.WRT }
    { If we use ID space then WS.UDS }
    if id_space_used then
      m_array.wdb[7] := 400B + 20B + 2
    else
      m_array.wdb[7] := 400B + 2;
    m_array.wdb[8] := 0;
    crawpa(m_array.wdb);

    { Since we created a new window we need to update the 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;

  if ($dsw < 0) and (error_code > 0) then
    error_code := $dsw - 400;

  { now lets map to the first window so we have a place to start }
  if error_code > 0 then
  begin
    m_array.wdb[5] := 0;
    mappa(m_array.wdb);
    { now that something is mapped lets check to see if they are using
      pointers. If so we make it a valid pointer value. }
    if m_array.use_pointer then
    begin
      apr_address := m_array.apr_to_use * 20000B;
      apr_add_add := loophole(address,ref(apr_address));
      bytmov(apr_add_add,m_array.buffer_address,2);
    end;
  end;

  if ($dsw < 0) and (error_code > 0) then
    error_code := $dsw - 600;
end;
