
                      Loading Fryers Into Your Own Program
                                03/25/93 -med
                                02/27/97 -med revised  

        This method of operation is for real mode MSDOS programs only. It 
        will not work in Windows or protected mode MSDOS. For 16 bit 
        Protected mode, or Windows 3.1x, you should use the FRYERS.COM 
        TSR. For 32 bit Windows, you should use the FRYERS32 DLL.

        Fryers operates as a TSR when loaded from the MSDOS prompt, but 
        with V3.10 a new feature has been added which allows you to 
        include FRYERS.COM directly in your program instead of requiring 
        the load as a TSR. This capability only works in real mode, it 
        will not work in a protected mode because FRYERS.COM is a real 
        mode program. If you need to use the Fryers driver with protected 
        mode programs, you must load it as a TSR at the MSDOS prompt.  

        To load Fryers into your program, you will first need to prepare 
        an array of bytes to store the Fryers Driver in. The size of the 
        array will be the size of the FRYERS.COM file plus 256 bytes. 
        There is a limitation in that FRYERS.COM *must* be loaded to an 
        area exactly 256 bytes above the segment boundary of the array it 
        is loaded in. 

        Once loaded into memory, you should check that the Fryers program 
        is a valid version. You can do this by looking at location $105 
        and $106. This location will contain a word value indicating the 
        program version number in binary form. ie if the version is 
        V3.10, the value in the memory location will be 310. You may also 
        want to double check the locations at $103 and $104 which contain 
        the major portion of the version number as a hex number. Thus 
        version V3.10 would appear as 49 decimal.

        Once loaded and verified, you can initialize Fryers by placing a 
        call to offset $108 in the segment with AX containing a value of 
        Zero. This will tell Fryers to attach itself to the system 
        interrupt. Fryers will return a 0 if for some reason it could not 
        connect itself to the system interrupt. Otherwise it will return 
        a 1 indicating a successful install. If an external Fryers TSR is 
        already attached to the interrupt $14, the internal Fryers will 
        not be attached to it. 

        Note that since Fryers attaches itself to a system interrupt, it 
        is extremely critical that you properly remove Fryers from the 
        program before closing (exiting) the program. You remove the 
        Fryers driver by placing a call to offset $108 with AX = non-zero 
        value. If the removal worked, you will be returned a 1 indicating 
        success. If the removal failed, AX will return a 0.

        The following Pascal unit shows an example of loading Fryers into 
        a Pascal program.






                                        1

        {$O-,F+,I-}
        unit FRSunit;
        interface 

        function LoadFryers:integer;
        function ReleaseFryers:integer;

        implementaion

        type ByteArray = array[0..64000] of byte;
        const FryersStorage : pointer = nil;
              FryersISR : ^ByteArray = nil;
              FryersSize : word = 0;
              OldInt14 : pointer = nil; 

        {---------------------------------------------------------------}
        {check to see if Fryers is active as a TSR. }
        {If it is, then we are done, if not active, }
        {try to load it as an ISR }
        {call this routine once at the start of your program}
        {Note: This doesn't work in protected mode}
        {returns  1 = fryers loaded internally and available}
        {reutrns  0 = already loaded and available}
        {returns -1 = not loaded, not available.
        {returns -2 = FRYERS.COM file not found or damaged}
        {returns -3 = not enough memory to load fryers.
        {returns -4 = heap manager problem }
        {returns -5 = non-loadable fryers version}
        {returns -6 = fryers install init call failed }

        function LoadFryers:integer;
        var RegAX,RegDX:word;
            Error : word;
            LoadSize : word;
            Entry : pointer;
            f:file;
        label ErrorExit;
        begin
           LoadFryers := -1;
           if NoAutoLoadFryers then Exit;

           asm
             mov ax,$ffff
             mov dx,0
             int $14
             mov [RegDX],DX
             mov [RegAX],AX
           end;
           if (RegDX = $ffff) and (RegAX > $24) and (RegAX < $99) then
           begin
             LoadFryers := 0;
             Exit;
           end;




                                        2

          {$IFDEF MSDOS}
            if IOresult <> 0 then nop;
            assign(f,'FRYERS.COM');
            reset(f,1);
            if IOresult <> 0 then
            begin
              LoadFryers := -2;
              Exit;
            end;
            LoadSize := FileSize(f);
            FryersSize := LoadSize + 256 + 16;
            if MaxAvail <= FryersSize then
            begin
              FryersSize := 0;
              LoadFryers := -3;
              Exit;
            end;
            GetMem(FryersStorage,FryersSize);
            if ofs(FryersStorage^) > 15 then
            begin
              LoadFryers := -4;
              goto ErrorExit;
            end;
            FryersISR := ptr(seg(FryersStorage^)+1,0);
            BlockRead(f,FryersISR^[$100],LoadSize,Error);
            close(f);
            if IOresult <> 0 then
            begin
              LoadFryers := -2;
              goto ErrorExit;
            end;
            RegAX := FryersISR^[$103] + (word(FryersISR^[$104])*256);
            if (RegAX < $31) or (RegAX > $999) then
            begin
              LoadFryers := -5;
              goto ErrorExit;
            end;
            RegAX := FryersISR^[$105] + (word(FryersISR^[$106])*256);
            if (RegAX < 308) or (RegAX > 9999) then
            begin
              LoadFryers := -5;
              goto ErrorExit;
            end;
            Entry := @FryersISR^[$108];
            asm
              mov AX,0
              call [Entry]
              mov [RegAX],AX
            end;
            if RegAX < 1 then
            begin
              LoadFryers := -6;
              goto ErrorExit;
            end;
            LoadFryers := 1;
            Exit;

                                        3

          ErrorExit:
            FreeMem(FryersStorage,FryersSize);
            FryersStorage := nil;
            FryersISR := nil;
            FryersSize := 0;
          {$ENDIF}
        end;


        {--------------------------------------------------------------}
        function ReleaseFryers:integer;
        begin
           if (FryersSize > 0) and (FryersStorage <> nil) then
           begin
             Enter := @FryersISR^[$108]; {was Fryers was loaded?}
             asm
               mov ax,1         {release fryers}
               call [Enter]
             end;
             freemem(FryersStorage,FryersSize);
           end;
           SetIntVec($14,OldInt14); {restore original rs232 int vector}
        end;


        {--------------------------------------------------------------}
        {ProgramExit is called by the exit procedure to restore}
        {the system to normal when the program terminates}
        procedure ProgramExit; far;
        var Enter : pointer;
        begin
           ExitProc := ExitSave;   {restore exit proc pointer}
           if ReleaseFryers then {nop};
        end;

        {-------------------}
        {intialization}
        begin
           ExitSave := ExitProc;      {save current exit proc pointer}
           ExitProc := @ProgramExit;  {point it to our exit procedure}
           GetIntVec($14,OldInt14);   {save current int$14 vector}
        end.















                                        4

        ----------------------------------------------------------------
        Loading FRYERS.BIN

        To make life a little easier, the program MFB.EXE has been 
        provided to allow you to convert the FRYERS.COM program to a BIN 
        program. What this does is to automatically add 256 bytes to the 
        beginning of the FRYERS.COM program so that you only need to 
        insure that it is loaded on a segment boundary. No need to tweak 
        things to leave the 256 byte space in front yourself. 

        Unlike the FRYERS.COM version, FRYERS.BIN is designed to allow 
        use with a Dbase compatible interface. What this means is that it 
        expects a string to be passed to it after being loaded. The 
        FRYERS.BIN program expects the string "INSTALL" to be passed to 
        it in the character array pointed at by DS:BX in order to install 
        the Fryers driver after it has been loaded. 

        Example:

           LOAD FRYERS         <-- load fryers driver into memory 
           CALL FRYERS with "INSTALL"  <-- installs fryers driver
           CALL FRYERS with "RELEASE"  <-- releases fryers driver

        Note: it is important that you load the FRYERS driver and install 
        it before running any code that tries to use it.  

        When you are done with the FRYERS program, you *must* release it 
        from memory. Failure to release the fryers driver may cause other 
        programs to crash when they try to access the RS232 interrupt.
        Never terminate your program until you have released the fryers 
        driver. 

        You can release the Fryers drive from within Dbase with a call 
        like this:  

           CALL FRYERS with "RELEASE"

        for other programs, you would pass the string "RELEASE" in a 
        character array pointed at by DS:BX. 

        The FRYERS.BIN program is a MSDOS real mode only program. It will 
        not work in protected mode.

        Sometimes you cannot prevent a program from crashing early. Two 
        programs are provided to deal with this. FSAVE.EXE and 
        FRESTORE.EXE. The FSAVE program saves the current state of the 
        RS232 interrupt vectors that FRYERS uses into the file 
        FRYERSI.DAT The FRESTORE.EXE program then uses that file to 
        restore the interrupts. It is very important not to run the 
        FRESTORE program before running the FSAVE program or else the 
        interrupts may be damaged causing the computer to lock up. 

        If you load FRYERS as a TSR, you should not call the FSAVE 
        program. 

        <eof>

                                        5
