FT_REBOOT

FT_REBOOT()
 Force a warm or cold boot

 Syntax

      FT_REBOOT( <nBootType> ) -> NIL

 Arguments

     <nBootType> is used to indicate the type of reboot.  A value of zero
     will cause a cold boot, while any other value will cause a warm boot.

 Returns

     NIL

 Description

     This function is valuable if you need to reboot the PC for some
     reason; e.g. an installation routine that modifies CONFIG.SYS or
     AUTOEXEC.BAT.

     The source code is written to adhere to Turbo Assembler's IDEAL mode.
     To use another assembler, you will need to rearrange the PROC and
     SEGMENT directives, and also the ENDP and ENDS directives (a very
     minor task).

 Examples

     #define COLD 0
     #define WARM 1

     // Issue a warm boot

     FT_Reboot(WARM)

 Source: REBOOT.ASM

 Author: Ted Means

 

FT_POKE

FT_POKE()
 Write a byte to a specified memory location

 Syntax

      FT_POKE( <nSegment>, <nOffset>, <nValue> ) -> lResult

 Arguments

     <nSegment> is the segment of the desired memory address.

     <nOffset>  is the offset of the desired memory address.

     <nValue>   is the value to write to the desired memory address.

 Returns

     <lResult> will be .T. if all parameters were valid and the function was
               able to write the desired byte.
     <lResult> will be .F. if invalid parameters were passed.

 Description

     Use this function if you have a need to change the value at a specific
     memory location.  The function will write the specified byte to the
     specified address.  The value must be passed as a numeric; if the byte
     you wish to use is stored as a character, use the Asc() function
     to convert it.

     This function was written for version 5.1 of MicroSoft C.  You may
     have to modify the source code to use another compiler.

 Examples

     FT_POKE( 0, 1047, 64)  // Turn CapsLock on

 Source: POKE.C

 Author: Ted Means

 

FT_PEEK

FT_PEEK()
 Retrieve a byte from a specified memory location.
------------------------------------------------------------------------------

 Syntax

      FT_PEEK( <nSegment>, <nOffset> ) -> nValue

 Arguments

     <nSegment> is the segment of the desired memory address.

     <nOffset>  is the offset of the desired memory address.

 Returns

     <nValue> will be a value from 0 to 255 if all parameters were valid and
              the function was able to retrieve the desired byte.
     <nValue> will be -1 if invalid parameters were passed.

 Description

     Use this function if you have a need to examine a specific memory
     location.  The function will return the byte at the specified
     address as a numeric value.  If you need this value as a character,
     use the Chr() function to convert it.

     This function was written for version 5.1 of MicroSoft C.  You may
     have to modify the source code to use another compiler.

 Examples

     local nVMode := FT_PEEK( 0, 1097 )  // Get the current video mode

 Source: PEEK.C

 Author: Ted Means

 

FT_OUTP

FT_OUTP()
 Write a byte to a specified I/O port
------------------------------------------------------------------------------

 Syntax

     FT_OUTP( <nPort>, <nValue> ) -> lResult

 Arguments

     <nPort> is the port from which to retrieve the byte.

     <nValue> is the value between 0 and 255 to write to the port.

 Returns

    .T. if all parameters were valid and the byte was written to
        the port.
    .F. if invalid parameters were passed.

 Description

    It may sometimes be useful to write a byte to a port without having
    to resort to C or assembler.  This function allows you to do so.

    The source code is written to adhere to Turbo Assembler's IDEAL mode.
    To use another assembler, you will need to rearrange the PROC and
    SEGMENT directives, and also the ENDP and ENDS directives (a very
    minor task).

 Examples

    lOk := FT_OUTP( 100, 0 )   // send a Chr(0) to port 100 (064h)

 Source: OUTP.ASM

 Author: Ted Means

See Also: FT_INP()

 

FT_MKDIR

FT_MKDIR()
 Create a subdirectory

 Syntax

     FT_MKDIR(  <cDirName> ) -> nResult

 Arguments

    <cDirName> is the name of the directory to create.

 Returns

     0  if successful
     3  if Path Not Found
     5  if Access Denied or directory already exists
    99  if invalid parameters passed

 Description

    Use this function to create the subdirectories needed by your
    application.  It might be especially useful in an installation
    program.

    The source code is written to adhere to Turbo Assembler's IDEAL mode.
    To use another assembler, you will need to rearrange the PROC and
    SEGMENT directives, and also the ENDP and ENDS directives (a very
    minor task).

 Examples

    FT_MKDIR( "C:\CLIPPER" )
    FT_MKDIR( "\EXAMPLE" )
    FT_MKDIR( "..\SOURCE" )

 Source: MKDIR.ASM

 Author: Ted Means

 

FT_ISSHARE

FT_ISSHARE()
 Determine if DOS "Share" is installed

 Syntax

       FT_ISSHARE() -> nRetCode

 Arguments

      None

 Returns

      nRetcode will be set as follows on exit:

          0 if SHARE not loaded but ok to load
          1 if SHARE not loaded and not ok to load
        255 if SHARE loaded

 Description

      Uses DOS interrupt 2Fh (MultiPlex interrupt), service 10h
      to determine if DOS SHARE.COM is loaded.

 Examples

     IF FT_ISSHARE() != 255
        Qout("SHARE must be loaded!")
     ENDIF

 Source: ISSHARE.PRG

 Author: Glenn Scott (from Tom Leylan C source)

See Also: FT_INT86()


			

FT_ISPRINT

FT_ISPRINT()
 Check printer status
------------------------------------------------------------------------------

 Syntax

     FT_ISPRINT( [ <cDevice> ] ) -> lResult

 Arguments

    <cDevice> is optional and is the device to test (LPT2, COM1, etc.).
    If omitted, the function will default to the PRN device.

 Returns

    .T.  if device is ready for output.
    .F.  if one of the following conditions occurs:
         1)  The device is not ready.
         2)  The device does not exist.
         3)  DOS couldn't open the device for some reason
             (such as no file handles available).

 Description

    The Clipper IsPrinter() function is somewhat limited because it only
    works with LPT1.  Furthermore, it talks directly to the hardware, so
    if you have redirected LPT1 via the DOS MODE command, the IsPrinter()
    function will return erroneous results.

    This function offers a better alternative.  Instead of talking to the
    hardware, it issues a DOS call that checks to see if the device is
    ready or not.  That gives DOS an opportunity to deal with any
    redirections, and since you pass the device name as a parameter, you
    can test any device, not just LPT1 (note that the function defaults
    to PRN if you fail to pass a valid parameter).

    The function also temporarily traps the DOS critical error handler so
    you don't get any nasty error messages if the device isn't ready.  It
    restores the old critical error handler before exiting.

    Note that although this function is mainly designed for testing
    printers, you can also check to see if a drive is ready.  Since DOS
    thinks the NUL device exists on every drive, you can pass a drive
    letter followed by NUL as a parameter.  If DOS is able to open the
    NUL device, then the drive is ready, otherwise the door is open or
    something else is wrong.

    The source code is written to adhere to Turbo Assembler's IDEAL mode.
    To use another assembler, you will need to rearrange the PROC and
    SEGMENT directives, and also the ENDP and ENDS directives (a very
    minor task).

 Examples

    IF ! FT_ISPRINT()
       Qout( "PRN is not ready!" )
    ENDIF

    IF ! FT_ISPRINT( "COM2" )
       Qout( "Check the device on COM2.  Something is wrong." )
    ENDIF

    IF ! FT_ISPRINT( "A:\NUL" )
       Qout( "Oops, better check drive A!" )
    ENDIF

 Source: ISPRINT.ASM

 Author: Ted Means

 

FT_INT86

FT_INT86()
 Execute a software interrupt
------------------------------------------------------------------------------

 Syntax

       FT_INT86( <nInterruptNumber>, <aRegisterValues> ) -> lResult

 Arguments

      <nInterruptNumber> is the interrupt to execute.

      <aRegisterValues> is an array that contains values to be loaded
      into the various CPU registers.  The correspondence between
      registers and array elements is as follows:

               aElement[1]  ==  AX register
               aElement[2]  ==  BX register
               aElement[3]  ==  CX register
               aElement[4]  ==  DX register
               aElement[5]  ==  SI register
               aElement[6]  ==  DI register
               aElement[7]  ==  BP register
               aElement[8]  ==  DS register
               aElement[9]  ==  ES register
               aElement[10] ==  Flags register

 Returns

      .T. if all parameters valid and the function was able
          to execute the desired interrupt.
      .F. if invalid parameters passed.

     In addition, the array elements will contain whatever values were in
     the CPU registers immediately after the interrupt was executed.  If
     either of the string parameters were altered by the interrupt, these
     changes will be reflected as well.

 Description

     It is occasionally useful to be able to call interrupts directly from
     Clipper, without having to write a separate routine in C or ASM.  This
     function allows you that capability.

     Given Clipper's high-level orientation, this function is necessarily
     somewhat messy to use.  First, declare an array of ten elements to
     hold the eight values for the CPU registers and two string parameters.
     Then initialize the array elements with the values that you want the
     CPU registers to contain when the interrupt is executed.  You need not
     initialize all the elements.  For example, if the interrupt requires
     you to specify values for AX, DX, and DS, you would only need to
     initialize elements 1, 4, and 8.

     Once you have done the required register setup, call FT_INT86(),
     passing the interrupt number and the register array as parameters.
     The function will load the CPU with your specified values, execute the
     interrupt, and then store the contents of the CPU registers back into
     your array.  This will allow you to evaluate the results of the
     interrupt.

     Some interrupt services require you to pass the address of a string in
     a pair of registers.  This function is capable of handling these sorts
     of situations, but it will take a little work on your part.  If you need
     to pass a string that uses the DS register, store the string in element
     8;  if you need to pass a string that uses the ES register, store the
     string in element 9.  FT_INT86() will detect that you've supplied a
     string instead of a numeric value and will behave accordingly.

     That takes care of obtaining the segment portion of the pointer.  To
     specify which register is to contain the offset, use the values REG_DS
     and REG_ES which are defined in the FTINT86.CH file.  When one of these
     values is found in an array element, it alerts FT_Int86() to use the
     offset portion of a pointer instead of a numeric value.  REG_DS tells
     FT_Int86() to use the offset of the string in element 8, while REG_ES
     tells FT_Int86() to use the offset of the string in element 9.

     All the CPU registers are sixteen bits in size.  Some, however, are
     also split into two 8-bit registers.  This function is only capable of
     receiving and returning registers that are 16 bits in size.  To split
     a 16-bit register into two 8-bit values, you can use the
     pseudo-functions HighByte() and LowByte(), contained in the .CH file.

     To alter an 8-bit number so it will appear in the high-order byte of a
     register when passed to the FT_INT86() function, use the MakeHI()
     pseudo-function contained in the .CH file.

     This function is a shell for __ftint86(), which is written in assembler
     and does the actual work of executing the interrupt.  __ftint86() is
     callable from C, so feel free to incorporate it into any C routines
     for which it might be useful.  The source for __ftint86() can be found
     in the file AINT86.ASM.

 Examples

     * This example shows how to call the DOS "create file" service.  Take
     * special note of how to set up string parameters.

     #include "FTINT86.CH"

     local aRegs[10]              && Declare the register array
     aRegs[ AX ] := makehi(60)    && DOS service, create file
     aRegs[ CX ] := 0             && Specify file attribute

     * Pay attention here, this is crucial.  Note how to set up the string
     * so it appears in DS:DX.

     aRegs[ DS ] := "C:\MISC\MYFILE.XXX"
     aRegs[ DX ] := REG_DS
     FT_INT86( 33, aRegs)         && Make the call to the DOS interrupt

     * This example shows how to call the DOS "get current directory"
     * service.  This one also uses a string parameter, but note that it
     * uses a different offset register.

     #include "FTINT86.CH"

     local aRegs[10]
     aRegs[ AX ] := makehi(71)
     aRegs[ DX ] := 0           // Choose default drive

     * This service requires a 64-byte buffer whose address is in DS:SI.  DOS
     * will fill the buffer with the current directory.

     aRegs[ DS ] := space(64)
     aRegs[ SI ] := REG_DS
     FT_INT86( 33, aRegs)

     ? aRegs[ DS ]       // Display the directory name

     * For the sake of completeness, here's an example that doesn't use a
     * string.  This one changes the video mode.

     #include "FTINT86.CH"

     local aRegs[10]

     aRegs[ AX ] := 16          && Choose hi-res graphics
     FT_INT86( 16, aRegs)

 Header File: FTINT86.CH

 Source: CINT86.C

 Author: Ted Means

FT_INP

FT_INP()
 Retrieve a byte from a specified I/O port
------------------------------------------------------------------------------

 Syntax

      FT_INP( <nPort> ) -> nValue

 Arguments

    <nPort> is the port from which to retrieve the byte.  If it is
    invalid in any way, the function will return zero.

 Returns

    The byte retrieved.

 Description

    It may sometimes be useful to read a byte from a port without having
    to resort to C or assembler.  This function allows you to do so.

    The source code is written to adhere to Turbo Assembler's IDEAL mode.
    To use another assembler, you will need to rearrange the PROC and
    SEGMENT directives, and also the ENDP and ENDS directives (a very
    minor task).

 Examples

    byte := FT_INP( 100 )   // read a byte from port 100 (064h)

 Source: INP.ASM

 Author: Ted Means

See Also: FT_OUTP()

FT_HANDCNT

FT_HANDCNT()
 Count number of available DOS (not network) file handles

 Syntax

    FT_HANDCNT() -> nHandles

 Arguments

   None

 Returns

   numeric, long integer

 Description

   FT_HANDCNT() finds the internal DOS Device Control Blocks used for
   storing file information and counts the number of DCB entries.  The
   DCB is set up by reading the FILES= line in CONFIG.SYS, and there
   is one DCB entry for each file handle.

   NOTE: For Novell networks, the number of network file handles is
         controlled by SHELL.CFG.  To date, I know where this information
         is stored after SHELL.CFG has been read, but have not come up
         with a reliable way to retrieve the information.  There is no
         public variable associated with the storage location, and the
         location can change from version to version of NETx.EXE.
         Novell Tech Support's response, though friendly, was "Nope, we
         don't know of a way for you to do it, either.  Good luck."

 Examples

   nHandles := FT_HANDCNT()
   ? "This PC has " + LTRIM( STR( nHandles ) ) + " set by CONFIG.SYS."

 Source: HANDCNT.ASM

 Author: Bob Clarke