home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1993 #2
/
Image.iso
/
clipper
/
exoapi.zip
/
EXOINT86.ZIP
/
EXOINT86.DOC
< prev
Wrap
Text File
|
1993-06-07
|
5KB
|
100 lines
This file documents how the NanForum Toolkit function FT_INT86 was
modified to support ExoSpace.
FT_INT86 is usually called to invoke software interrupts which execute
in real mode. Modification of FT_INT86 for ExoSpace required changes in
two areas:
o The call to __ftint86() was replaced by a call to the ExoSpace API
function ExoRMInterrupt(). A side effect of this was that the
FT_INT86 register structure had to be mapped onto the ExoSpace
EXOREGS register structure.
o Pointers to strings or buffers had to be converted to real-mode
pointers which pointed to memory below 640K. This was done using
the ExoSpace API function _xalloclow(), ExoRealPtr(), and
_xfreelow().
o After the interrupt has returned, any buffers that were copied to
low memory are copied back so that if they were modified by the
interrupt handler, the results will be visible to the Clipper
application.
These changes are described in more detail below.
__ftint86 -> ExoRMInterrupt()
-----------------------------
The original real-mode FT_INT86 relied on a function called __ftint86(),
implemented in assembler, to invoke the specified interrupt. The
ExoSpace API contains an equivalent function, ExoRMInterrupt, which was
used instead of __ftint86(). ExoRMInterrupt is designed to invoke a
real-mode interrupt from protected mode.
This change was necessary, among other reasons, because real-mode
segment values cannot safely be loaded into the segment registers when
in protected mode. By loading the required register values into an
instance of the EXOREGS register structure, this problem is circumvented.
Since FT_INT86 already made use of such an approach for other reasons,
it was relatively easy to replace the call to __ftint86 with a call to
ExoRMInterrupt. The biggest issue that had to be handled was mapping
the register structure used by FT_INT86 onto the structure required by
ExoRMInterrupt. This was done with an array of offsets, regOff. The
macros setReg() and getReg() were used to clean up the syntax of
register access via this array.
Buffer copying and pointer conversion (_xalloclow(), ExoRealPtr())
------------------------------------------------------------------
If a pointer to a string is passed to FT_INT86, in either the DS:rr or
ES:rr registers (where rr is a register containing an offset value),
action must be taken to ensure that the string being pointed to exists
in the first 640K, and a real-mode pointer to the string must be passed
to the interrupt being invoked.
In the ExoSpace version of FT_INT86, this has been done by using the API
function _xalloclow() to allocate the required amount of memory in the
first 640K. _xalloclow() returns a protected-mode pointer to the allocated
memory, which can then be used to copy the data into newly allocated memory.
Finally, the protected-mode pointer returned by _xallocnew() is converted
into a real-mode pointer using the function ExoRealPtr(). The real-mode
pointer is placed into the EXOREGS register structure in the appropriate
place.
Note that the approach used here is a conservative one suited to the
generic nature of FT_INT86. When strings are involved, memory is
allocated and deallocated each time an interrupt is invoked. In other
circumstances, a more efficient alternative might be to allocate permanent
buffers in low memory using _xalloclow(). These buffers could be made
large enough to accomodate the largest string that you would ever pass to
the software interrupts you are using. You could then avoid continually
allocating and deallocating these buffers. Another area which can be
optimized is the need to copy the string from extended memory into low
memory. If you have sufficient control over the software concerned, you
can ensure that the initial allocation uses _xalloclow(), obviating the
need to copy the string before signalling the interrupt. In all cases,
however, ExoRealPtr() must be used to obtain a real-mode pointer to the
buffers. If permament buffers were maintained, however, you would only
need to call ExoRealPtr() once for each such buffer.
Copying the buffers back
------------------------
After the interrupt has returned, any buffers that were copied to low
memory are copied back so that if they were modified by the interrupt
handler, the results will be visible to the Clipper application.
_storclen with a NULL pointer is used to prevent any changes to the
string from affecting other references to the same string. This is
also done in the original version of FT_INT86.
The low memory buffer is then copied back to the correct place.
Finally, the memory which was allocated with _xalloclow() is freed using
the ExoSpace API function _xfreelow().
<*** End of File ***>