(* * * * * * * * * * * * * * * * * * */
 *
 * prog3-2.pas
 *
 *      Demonstrates
 *          - Alloc/Free of EMS pages
 *          - Get # available EMS pages
 *          - Get # pages for each handle
 *          - Get # active handles
 *
 * * * * * * * * * * * * * * * * * * *)

program prog3_2;

uses    crt,
        _globals,
        _ems;


var
    ems:                EMS_Ems;


procedure displayActiveHandles;

type
    EMS_HandleInfoArrPtr= ^EMS_HandleInfoArr;


var
    handleInfoArray:    EMS_HandleInfoArrPtr;
    numActiveHandles:   Word;
    numActiveHandles2:  Word;

    i:                  Word;

begin
    (*
     *  First find out how many active handles there are:
     *)
    if ems.getNumActiveHandles(numActiveHandles) then begin
        ems_demoError('EMS_Ems.getNumActiveHandles');
        end;

    (*
     *  Now allocate a block of handleInfo packets big enough to
     *  hold them.
     *)
    GetMem(handleInfoArray, numActiveHandles * sizeof(EMS_HandleInfo));

    (*
     *  Now get the info.
     *)
    if ems.getPagesAllHandles(handleInfoArray^, numActiveHandles2) then begin
        ems_demoError('EMS_Ems.getNumActiveHandles');
        end;

    (*
     *  The following is a brief sanity clause (Everybody knows
     *  there ain't no sanity clause).
     *)
    if numActiveHandles2 <> numActiveHandles then begin
        writeln('A most unusual situation has occured...');
        Halt;
        end;

    (*
     *  Finally, display it.
     *)
    writeln('                        └─────────────┼──────────┬─────────┤');

    for i:= 0 to numActiveHandles - 1 do begin
        writeln(
            '                                      │   ',
            handleInfoArray^[i].handle:3,
            '    │   ',
            handleInfoArray^[i].numPages:3,
            '   │');

        if i+1 < numActiveHandles then begin
            writeln(
                '                                      ├──────────┼─────────┤');
            end;
        end;

    writeln('══════════════════════════════════════╧══════════╧═════════╛');

    (*
     *  Now free up the array.
     *)
    FreeMem(handleInfoArray, numActiveHandles * sizeof(EMS_HandleInfo));

end;

procedure pause;

var
    c:                  char;

begin

    (*
     *  Display a little message:
     *)
    writeln('Hit <CR> to continue...');

    (*
     *  Wait for a <CR>
     *)
    c:= ReadKey;
    while c <> #13 do begin
        c:= ReadKey;
        end;

end;


var

    totalPages:         Word;
    freePages:          Word;
    handle1:            EMS_EmBlk;
    handle2:            EMS_EmBlk;

begin

    (*
     *  First check for presence of EMS
     *)
    if ems.init then begin
        writeln('EMS is not present');
        Halt;
        end;

    (*
     *  Get the number of free pages
     *)
    if ems.getFreeEM(totalPages, freePages) then begin
        ems_demoError('EMS_Ems.getFreeEM');
        end;

    (*
     *  Print header:
     *)
    writeln('       Operation          Avail Pages     Active Handles');
    writeln('════════════════════════╤═════════════╤════════════════════╕');
    writeln('After initialization    │     ',
                freePages:3,
                '     │   Handle    Pages  │');

    displayActiveHandles;
    pause;

    (*
     *  Now allocate 5 pages.
     *)
    if handle1.allocEM(5) then begin
        ems_demoError('EMS_Ems.allocEM');
        end;

    (*
     *  Get the number of free pages
     *)
    if ems.getFreeEM(totalPages, freePages) then begin
        ems_demoError('EMS_Ems.getFreeEM');
        end;

    (*
     *  Print header:
     *)
    writeln('       Operation          Avail Pages     Active Handles');
    writeln('════════════════════════╤═════════════╤════════════════════╕');
    writeln('After 5 page allocate   │     ',
                freePages:3,
                '     │   Handle    Pages  │');

    displayActiveHandles;
    pause;

    (*
     *  Now allocate 7 pages.
     *)
    if handle2.allocEM(7) then begin
        ems_demoError('EMS_EmBlk.allocEM');
        end;

    (*
     *  Get the number of free pages
     *)
    if ems.getFreeEM(totalPages, freePages) then begin
        ems_demoError('EMS_Ems.getFreeEM');
        end;

    (*
     *  Print header:
     *)
    writeln('       Operation          Avail Pages     Active Handles');
    writeln('════════════════════════╤═════════════╤════════════════════╕');
    writeln('After 7 page allocate   │     ',
                freePages:3,
                '     │   Handle    Pages  │');

    displayActiveHandles;
    pause;

    (*
     *  Now free the 5 page block.
     *)
    if handle1.freeEM then begin
        ems_demoError('EMS_EmBlk.freeEM');
        end;

    (*
     *  Get the number of free pages
     *)
    if ems.getFreeEM(totalPages, freePages) then begin
        ems_demoError('EMS_Ems.getFreeEM');
        end;

    (*
     *  Print header:
     *)
    writeln('       Operation          Avail Pages     Active Handles');
    writeln('════════════════════════╤═════════════╤════════════════════╕');
    writeln('After 5 page free       │     ',
                freePages:3,
                '     │   Handle    Pages  │');

    displayActiveHandles;
    pause;

    (*
     *  Now free the 7 page block.
     *)
    if handle2.freeEM then begin
        ems_demoError('EMS_EmBlk.freeEM');
        end;

    (*
     *  Get the number of free pages
     *)
    if ems.getFreeEM(totalPages, freePages) then begin
        ems_demoError('EMS_Ems.getFreeEM');
        end;

    (*
     *  Print header:
     *)
    writeln('       Operation          Avail Pages     Active Handles');
    writeln('════════════════════════╤═════════════╤════════════════════╕');
    writeln('After 7 page free       │     ',
                freePages:3,
                '     │   Handle    Pages  │');

    displayActiveHandles;

end.

