
Captulo 39 - unit overlay

  Nesta unidade, podemos gerenciar as atividades de overlays de um programa.
O processo chamado de overlay nada mais  do que se aproveitar uma mesma rea
de memria para vrias rotinas diferentes. Com este procedimento podemos 
diminuir consideravelmente a memria requerida para execuo de um programa.
As partes geradas pelo Turbo Pascal como overlay tm extenso. OVR, e para
que 
esta unidade possa ser executada com correo, deveremos utilizar as diretivas
de compilao $O+ e $F+. a primeira permite a gerao de cdigo overlay e a 
segunda permite as chamadas distantes(FAR CALLS). A posio do programa em que
dever ser colocada a rotina que utiliza overlay deve usar a diretiva de compi-
lao {$O nomeunit}. Para uma rotina poder ser carregada na memria em overlay,
esta dever ser previamente compilada como uma UNIT. 

OVRINIT - este procedimento permite a inicializao do gerenciador de
overlays e tambm abrir um arquivo OVR. Este arquivo ser procurado no
diretrio corrente, e caso esteja rodando em uma verso de sistema operacional
compatvel com DOS 3.xx, alm do diretrio corrente, ser pesquisado tambm
no PATH especificado no ambiente DOS. Caso haja algum erro, este ser informado
em uma varivel INTEGER predefinida nesta UNIT de nome OVRRESULT. Este
resultado po variar entre 0 a -6 e podem ser utilizadas as seguintes constan-
tes predefinidas para estes valores:
CONST
    OVROK    =  0;  {no houve erro}
    OVRERROR  = -1; {Programa no  OVERLAY}
    OVRONOTFOUND  = -2;  {Arquivo overlay no existe}
    OVRONOMEMORY  = -3;  {Memoria no  suficiente} 
    OVRIOERROR  = -4;  {Erro de entrada ou saida}
    OVRNOEMSDRIVER = -5;  {No h driver EMS}
    OVRNOEMSMEMORY = -6;  {No h memria EMS suficiente}
  Caso no seja testado o erro na inicializao e esta  no ocorrer perfei-
tamente, poder gerar um erro de execuo nmero 208. Sua sintaxe:
OVRINIT 
Vamos para um exemplo:
{$F+,O+}
PROGRAM teste_ovrinit;
USES   OVERLAY;
CONST  
    mens  :  ARRAY [-6..0] OF STRING [30]=( no h memria EMS    ,
                Driver EMS no instalado   ,Erro de I/O    ,
                No h memria p/ Overlay,
                Arquivo  .OVR no existe   ,
                Overlay no instalado    ,
                Bem sucedido      );
BEGIN
    OVRINIT ( TESTE.OVR);
    WRITELN (Resultado da inicializao  , mens [OVRRESULT];
    READLN;
END.
  Neste procedimento, teremos um erro de instalao, pois no existe rotina
alguma, a ser levada para memria. Para que possamos ter uma memria, deve-
ramos preparar anteriormente a rotina como uma unidade (UNIT). Vejamos um 
outro exemplo:
{ $O+, F+}
UNIT teste;
INTERFACE
    PROCEDURE INICIA;
IMPLEMENTATION
USES OVERLAY;
PROCEDURE INICIA;
BEGIN
    IF OVRRESULT <> OVROK
      THEN
        WRITELN(erro de OVR nmero: ,OVRRESULT);
      ELSE
        WRITELN(OVR bem sucedid);
    READLN;
  END;
END.  
{$F+}
PROGRAM teste_ovrinit;
USES OVERLAY, TESTE;
{$O TESTE}
BEGIN
  OVRINIT(TESTE.OVR);
  INICIA;
END.

OVRINITEMS - este procedimento  bastante similar ao procedimento OVRINIT,
exceto que neste caso, a rotina ser levada  memria expandida, porm este
procedimento s tem suporte em padro EMSLIMEXTENDEDMEMORYSPECIFICATION,
LOTOS/INTEL/MICROSOFT. Sua sintaxe:
OVRINITEMS;
Vamos a um exemplo:
{$O+,F+}
UNIT teste1;
INTERFACE
PROCEDURE INCIO1;
IMPLEMENTATION
USES OVERLAY;
PROCEDURE INCIO1;
BEGIN
  IF OVRRESULT <> OVROK
    THEN
      BEGIN
        WRITELN(erro nmer,OVRRESULT);
        READLN;
        HALT (1);
      END
  ELSE
    WRITELN(inicializao bem sucedid);
END;
END.

{$O+,F+}
UNIT teste2;
INTERFACE
PROCEDURE INCIO2;
IMPLEMENTATION
USES OVERLAY;
PROCEDURE INCIO2;
BEGIN
  IF OVRRESULT <> OVROK
    THEN
      BEGIN
        WRITELN(erro na EMS nmer,OVRRESULT);
        READLN;
        HALT (1);
      END
  ELSE
    WRITELN(inicializao bem sucedid);
  END;
END.

{$F+,O+}
PROGRAM teste_ovrinitems;
USES OVERLAY, CRT, TESTE1, TESTE2;
{$O teste1}
{$O teste2}
BEGIN
  CLRSCR;
  OVRINIT(teste.ovr);
  INCIO1;
  OVRINITEMS;
  INICIO2;
END.  

OVRGETBUF - esta funo nos retorna o valor em bytes da memria ocupada pela
rotina de overlay. Este valor  ajustado automaticamente quando o programa
 executado. Sua sintaxe:
ORVGETBUF : LONGINT;
Vejamos um exemplo:
{$O+,F+}
UNIT teste1;
INTERFACE
PROCEDURE incio1;
IMPLEMENTATION
USES OVERLAY;
PROCEDURE incio1;
BEGIN
  IF OVRRESULT <> OVROK
    THEN
      BEGIN
        WRITELN(erro nmer,OVRRESULT);
        READLN;
        HALT (1);
      END
  ELSE
    WRITELN(inicializao bem sucedid);
END;
END.

{$O+,F+}
UNIT teste2;
INTERFACE
PROCEDURE resultado;
IMPLEMENTATION
USES    OVERLAY;
PROCEDURE resultado;
BEGIN
    IF OVRRESULT <> OVROK
      THEN
        BEGIN;
        HALT (1);
      END
    ELSE
       WRITELN (termino bem sucedid);
  END;
END.

PROGRAM teste_ovrgetbuf;
USES OVERLAY, TESTE1, TESTE2;
{$O teste1}  
{$O teste2}
BEGIN
  OVRINIT (TESTE.OVR);
  INCIO1;
  WRITELN(a memria alocada  ,OVRGETBUF,(bytes);
    RESULTADO;
  READLN;
END.

OVRSETBUF - este procedimento permite-nos alocar uma rea de memria maior ou
igual  memria alocada pelo programa. Haver um erro no caso de estarmos
utilizando tambm os procedimentos NEW ou GETMEM. No caso de haver um erro
na execuo deste procedimento, o programa ter sua continuidade normal,
porm o tamanho do BUFFER de memria no ser trocado. Sua sintaxe:
OVRSETBUF(<tamanho> : LONGINT);
Vejamos um exemplo:
PROGRAM teste_ovrsetbuf;
{$M 16384,65536,655360}
USES OVERLAY, TESTE1, TESTE2;
{$O TESTE1}
{$O TESTE2}
BEGIN
  OVRINIT (TESTE.OVR);
  INCIO1;
  WRITELN(a memria alocada  ,OVRGETBUF,bytes);
  OVRSETBUF(OVRGETBUF + 1024 * 3);
  WRITELN (a nova memria  ,OVRGETBUF,bytes);
  RESULTADO;
  READLN;
END.

OVRCLEARBUF - este procedimento libera a memria alocada pelo OVERLAY. 
Ele nunca dever ser chamado de dentro de uma rotina em OVERLAY. sua sintaxe:
OVRCLEARBUF;
Vejamos um exemplo:
PROGRAM teste_ovrclearbuf;
{$M 16384,65536,655360}
USES OVERLAY, TESTE1, TESTE2;
{$O teste1}
{$O teste2}
BEGIN
  OVRINIT(TESTE.OVR);
  INCIO1;
  OVRCLEARBUF;
  RESULTADO;
  READLN;
END.

OVRGETRETRY - esta funo nos retorna o valor em bytes livres da rea alocada
pelo OVERLAY. Sua sintaxe:
OVRGETRETRY : LONGINT;
PROGRAM teste_ovrgetretry;
{$M 16384,65536,655360}
USES OVERLAY, TESTE1, TESTE2;
{$O teste1}
{$O teste2}
BEGIN
  OVRINIT(TESTE.OVR);
  OVRSETBUF(OVRGETBUF + 1024);
  INCIO1;
  WRITELN(a memria livre aps a ltim,rotina  ,OVRGETRETRY,bytes);
  RESULTADO;
  WRITELN(a memria livre aps a ltim,rotina  ,OVRGETRETRY,bytes);
  READLN;
END.  

OVRSETRETRY - este procedimento permite-nos determinar o quanto de memria 
podemos deixar livre dentro da rea alocada OVERLAY. Sua sintaxe:
OVRSETRETRY(<tamanho> : LONGINT);
Vamos a um exemplo:
PROGRAM teste_ovrsetretry;
{$M 16384,65536,655360}
USES OVERLAY, TESTE1, TESTE2;
{$O teste1}
{$O teste2}
BEGIN
  OVRINIT(TESTE.OVR);
  INCIO1;
  WRITELN(a memria livre aps a ltim,rotina  ,OVRGETRETRY,bytes);
  OVRSETRETRY(1024);
  WRITELN(a memria livre aps a ltim,rotina  ,OVRGETRETRY,bytes);
  RESULTADO;
READLN;
END.
