(* * * * * * * * * * * * * * * * * * *
 *
 * prog3-3.pas
 *
 *      Demonstrates
 *          - Mapping EMS pages
 *          - Transfer of memory from/to EMS
 *
 * * * * * * * * * * * * * * * * * * *)


program prog3_3;

uses    _globals,
        _ems;

type
    BigArea=        array[0..65534] of Byte;
    BigPtr=        ^BigArea;

var
    ems:            EMS_Ems;
    pageFrame:      EMS_PageFrame;
    handle1:        EMS_EmBlk;
    handle2:        EMS_EmBlk;

    text:           String;

    i:              Word;

    three:          Word;

begin

    three:= 3;


    (*
     *  First check for presence of EMS
     *)
    if ems.init then begin
        writeln('EMS is not present');
        Halt;
        end;

    (*
     *  Get the Page Frame Address.
     *)
    if ems.getPFA(pageFrame) then begin
        ems_demoError('EMS_Ems.getPFA');
        end;

    (*
     *  Get a couple of 4 page blocks of memory (64K each).
     *)
    if handle1.allocEM(4) then begin
        ems_demoError('EMS_EmBlk.allocEM');
        end;
    if handle2.allocEM(4) then begin
        ems_demoError('EMS_EmBlk.allocEM');
        end;

    (*
     *  Now let's map the first.
     *)
    for i:= 0 to 3 do begin
        if handle1.mapPage(i, i) then begin
            ems_demoError('EMS_EmBlk.mapPage'); 
            end;
        end;

    (*
     *  The memory is now mapped into the page frame. Let's
     *  move some text into random spots in it.
     *)
    StrPtr(@pageFrame^[0][400])^:=
        '     I took a speed reading course and I';

    StrPtr(@pageFrame^[1][801])^:=
        '     read "War and Peace".';

    StrPtr(@pageFrame^[2][4000])^:=
        '     It involves Russia.';

    StrPtr(@pageFrame^[three][2000])^:=
        '                 -- Woody Allen'#13#10;

    (*
     *  Now print it back.
     *)
    writeln(StrPtr(@pageFrame^[0][400])^);
    writeln(StrPtr(@pageFrame^[1][801])^);
    writeln(StrPtr(@pageFrame^[2][4000])^);
    writeln(StrPtr(@pageFrame^[three][2000])^);

    (*
     *  Now let's map the second block
     *)
    for i:= 0 to 3 do begin
        if handle2.mapPage(i, i) then begin
            ems_demoError('EMS_EmBlk.mapPage'); 
            end;
        end;

    (*
     *  The memory is now mapped into the page frame. Let's
     *  move some text into random spots in it.
     *)
    StrPtr(@pageFrame^[0][400])^:=
        '     Children make the most desireable opponents';

    StrPtr(@pageFrame^[1][801])^:=
        '     in Scrabble as they are both easy to beat';

    StrPtr(@pageFrame^[2][4000])^:=
        '     and fun to cheat.';

    StrPtr(@pageFrame^[three][2000])^:=
        '                 -- Fran Lebowitz'#13#10;

    (*
     *  Now print it back.
     *)
    writeln(StrPtr(@pageFrame^[0][400])^);
    writeln(StrPtr(@pageFrame^[1][801])^);
    writeln(StrPtr(@pageFrame^[2][4000])^);
    writeln(StrPtr(@pageFrame^[three][2000])^);
        
    (*
     *  Now let's map the first, backwards this time.
     *)
    for i:= 0 to 3 do begin
        if handle1.mapPage(i, 3-i) then begin
            ems_demoError('EMS_EmBlk.mapPage'); 
            end;
        end;

    (*
     *  Now print it back.
     *)
    writeln(StrPtr(@pageFrame^[three][400])^);
    writeln(StrPtr(@pageFrame^[2][801])^);
    writeln(StrPtr(@pageFrame^[1][4000])^);
    writeln(StrPtr(@pageFrame^[0][2000])^);

    (*
     *  Now let's map the second block backwards.
     *)
    for i:= 0 to 3 do begin
        if handle2.mapPage(i, 3-i) then begin
            ems_demoError('EMS_EmBlk.mapPage'); 
            end;
        end;

    (*
     *  Now print it back. This time, we're going to calculate
     *  the offset from the beginning of the page frame area.
     *)
    writeln(StrPtr(@BigPtr(pageFrame)^[3*EMS_STD_PAGE_SIZE + 400])^);
    writeln(StrPtr(@BigPtr(pageFrame)^[2*EMS_STD_PAGE_SIZE + 801])^);
    writeln(StrPtr(@BigPtr(pageFrame)^[1*EMS_STD_PAGE_SIZE + 4000])^);
    writeln(StrPtr(@BigPtr(pageFrame)^[0*EMS_STD_PAGE_SIZE + 2000])^);
        
    (*
     *  We're done. Free the memory we've allocated.
     *)
    if handle1.freeEM then begin
        ems_demoError('EMS_EmBlk.freeEM');
        end;
    if handle2.freeEM then begin
        ems_demoError('EMS_EmBlk.freeEM');
        end;
end.


