
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Nanforum Toolkit v2.1 Reference Guide - <b>ft_int86()</b>
[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
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
Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson