(* * * * * * * * * * * * * * * * * * *
 *
 * _xms.pas
 *
 * XMS related definitions,
 * structures and function prototypes
 *
 * * * * * * * * * * * * * * * * * * *)

unit    _Xms;

interface

uses    _Globals;


const

    {*
     *  Define the XMS page size
     *}
    XMS_PAGE_SIZE=      1024;

    {*
     *  Define the XMS error codes.
     *}
    XMSErrOK=           $00;    { No Error }
    XMSErrUnimp=        $80;    { Unimplemented function }
    XMSErrVDISK=        $81;    { VDISK device detected }
    XMSErrA20=          $82;    { A20 error }
    XMSErrNoHMA=        $90;    { HMA does not exist }
    XMSErrHMAInUse=     $91;    { HMA already in use }
    XMSErrHMAMin=       $92;    { HMA space req. < /HMAMIN= parameter }
    XMSErrHMANotAll=    $93;    { HMA not allocated }
    XMSErrA20Enab=      $94;    { A20 still enabled }
    XMSErrNoXMLeft=     $0A0;   { All XM allocated }
    XMSErrNoHandles=    $0A1;   { All handles are allocated }
    XMSErrHandInv=      $0A2;   { Invalid handle }
    XMSErrSHandInv=     $0A3;   { Invalid Source Handle }
    XMSErrSOffInv=      $0A4;   { Invalid Source Offset }
    XMSErrDHandInv=     $0A5;   { Invalid Dest Handle }
    XMSErrDOffInv=      $0A6;   { Invalid Dest Offset }
    XMSErrLenInv=       $0A7;   { Invalid Length }
    XMSErrOverlap=      $0A8;   { Invalid move overlap }
    XMSErrParity=       $0A9;   { Parity error }
    XMSErrNoLock=       $0AA;   { Handle not locked }
    XMSErrLock=         $0AB;   { Handle Locked }
    XMSErrLockOvflo=    $0AC;   { Lock count overflo }
    XMSErrLockFail=     $0AD;   { Lock fail }
    XMSErrSmUMB=        $0B0;   { Smaller UMB available }
    XMSErrNoUMB=        $0B1;   { No UMB's available }
    XMSErrUMBInv=       $0B2;   { Invalid UMB segment }


type
    {*
     *  Define a type or two:
     *}

    XMS_MovePacket = record    
        length:         DWord;      { length of transfer }
        srcHandle:      Word;       { source handle (0 means < 1MB boundary) }
        srcOffset:      DWord;      { source offset }
        destHandle:     Word;       { destination handle (0 means < 1MB) }
        destOffset:     DWord;      { destination offset }
        end;

    {*
     *  Define the Xms object type.
     *}
    XMS_xms = object
        function        init
                            : Boolean;
        function        getVersion(
                            var xmsVersion: Word;
                            var xmmVersion: Word;
                            var hmaFlag:    Word)
                            : Boolean;
        function        rawMove(
                            dest:           DWord;
                            source:         DWord;
                            length:         Word)
                            : Boolean;
        function        moveXM(
                            var packet:     XMS_MovePacket)
                            : Boolean;
        function        allocHMA(
                            hmaBytes:       Word)
                            : Boolean;
        function        freeHMA
                            : Boolean;
        function        globEnabA20
                            : Boolean;
        function        globDisabA20
                            : Boolean;
        function        getA20State(
                            var a20State:   Word)
                            : Boolean;
        function        getFreeXM(
                            var totalFree:  Word;
                            var largestFree:Word)
                            : Boolean;
        function        allocUM(
                            size:           Word;
                            var address:    Pointer;
                            var actualSize: Word)
                            : Boolean;
        function        freeUM(
                            address:        Pointer)
                            : Boolean;

        function        errorText(
                            err:            Word)
                            : String;

        end;


    XMS_XmBlk = object

        handle:         Word;

        function        allocXM(
                            blockSize:      Word)
                            : Boolean;
        function        freeXM
                            : Boolean;
        function        lockXM(
                            var physAddr:   DWord)
                            : Boolean;
        function        unlockXM
                            : Boolean;
        function        getHandInfo(
                            var blockSize:  Word;
                            var handlesLeft:Word;
                            var lockCount:  Word)
                            : Boolean;
        function        resizeXM(
                            newSize:        Word)
                            : Boolean;

        end;

    xmsHandlerType= procedure;

    procedure xms_defaultHandler;

var
    xms:        XMS_Xms;

const
    xmshandler: ^xmsHandlerType= @xms_defaultHandler;

procedure   xms_demoError(funcName: String);



{*
 *  Start the implementation
 *}
implementation


{*
 *  Load in all of the assembly modules:
 *}
{$L XMS00}
{$L XMS01}
{$L XMS02}
{$L XMS03}
{$L XMS04}
{$L XMS07}
{$L XMS08}
{$L XMS09}
{$L XMS0A}
{$L XMS0B}
{$L XMS0C}
{$L XMS0D}
{$L XMS0E}
{$L XMS0F}
{$L XMS10}
{$L XMS11}
{$L XMSINIT}
{$L XMSRAW}

{*
 *  Now define all of the XMS externals:
 *}
function        XMS_Xms.init
                    : Boolean;
                    external;
function        XMS_Xms.getVersion(
                    var xmsVersion: Word;
                    var xmmVersion: Word;
                    var hmaFlag:    Word)
                    : Boolean;
                    external;
function        XMS_Xms.rawMove(
                    dest:           DWord;
                    source:         DWord;
                    length:         Word)
                    : Boolean;
                    external;
function        XMS_Xms.moveXM(
                    var packet:     XMS_MovePacket)
                    : Boolean;
                    external;
function        XMS_Xms.allocHMA(
                    hmaBytes:       Word)
                    : Boolean;
                    external;
function        XMS_Xms.freeHMA
                    : Boolean;
                    external;
function        XMS_Xms.globEnabA20
                    : Boolean;
                    external;
function        XMS_Xms.globDisabA20
                    : Boolean;
                    external;
function        XMS_Xms.getA20State(
                    var a20State:   Word)
                    : Boolean;
                    external;
function        XMS_Xms.getFreeXM(
                    var totalFree:  Word;
                    var largestFree:Word)
                    : Boolean;
                    external;
function        XMS_Xms.allocUM(
                    size:           Word;
                    var address:    Pointer;
                    var actualSize: Word)
                    : Boolean;
                    external;
function        XMS_Xms.freeUM(
                    address:        Pointer)
                    : Boolean;

                    external;
   
{*
 *  Now define the XMB externalals:
 *}
function        XMS_XmBlk.allocXM(
                    blockSize:      Word)
                    : Boolean;
                    external;
function        XMS_XmBlk.freeXM
                    : Boolean;
                    external;
function        XMS_XmBlk.lockXM(
                    var physAddr:   DWord)
                    : Boolean;
                    external;
function        XMS_XmBlk.unlockXM
                    : Boolean;
                    external;
function        XMS_XmBlk.getHandInfo(
                    var blockSize:  Word;
                    var handlesLeft:Word;
                    var lockCount:  Word)
                    : Boolean;
                    external;
function        XMS_XmBlk.resizeXM(
                    newSize:        Word)
                    : Boolean;
                    external;

{*
 *  And define the sole Pascal function: errorText
 *}
function        XMS_Xms.errorText(
                    err:            Word)
                    : String;
begin
    case err of
        XMSErrOK:
            errorText:= 'No Error';
        XMSErrUnimp:
            errorText:= 'Unimplemented function';
        XMSErrVDISK:
            errorText:= 'VDISK device detected';
        XMSErrA20:
            errorText:= 'A20 error';
        XMSErrNoHMA:
            errorText:= 'HMA does not exist';
        XMSErrHMAInUse:
            errorText:= 'HMA already in use';
        XMSErrHMAMin:
            errorText:= 'HMA space requested < /HMAMIN= parameter';
        XMSErrHMANotAll:
            errorText:= 'HMA not allocated';
        XMSErrA20Enab:
            errorText:= 'A20 still enabled';
        XMSErrNoXMLeft:
            errorText:= 'All eXtended Memory allocated';
        XMSErrNoHandles:
            errorText:= 'All handles are allocated';
        XMSErrHandInv:
            errorText:= 'Invalid handle';
        XMSErrSHandInv:
            errorText:= 'Invalid Source Handle';
        XMSErrSOffInv:
            errorText:= 'Invalid Source Offset';
        XMSErrDHandInv:
            errorText:= 'Invalid Destination Handle';
        XMSErrDOffInv:
            errorText:= 'Invalid Destination Offset';
        XMSErrLenInv:
            errorText:= 'Invalid Length';
        XMSErrOverlap:
            errorText:= 'Invalid move overlap';
        XMSErrParity:
            errorText:= 'Parity error';
        XMSErrNoLock:
            errorText:= 'Handle not locked';
        XMSErrLock:
            errorText:= 'Handle Locked';
        XMSErrLockOvflo:
            errorText:= 'Lock count overflo';
        XMSErrLockFail:
            errorText:= 'Lock fail';
        XMSErrSmUMB:
            errorText:= 'Smaller UMB available';
        XMSErrNoUMB:
            errorText:= 'No UMB''s available';
        XMSErrUMBInv:
            errorText:= 'Invalid UMB segment';
        else
            errorText:= 'Unknown error';
        end;
end;

(*
 *  Define xms_demoerr, which is used to report errors in the demo
 *  programs.
 *)
procedure   xms_demoError(funcName: String);
begin

    {*
     *  Report the error:
     *}
    writeln('Error on ', funcName, '(): "',
                xms.errorText(errno), '"');
    Halt;
end;

       
procedure   xms_defaultHandler; external;


end.
 
