168 lines
7.1 KiB
Plaintext
168 lines
7.1 KiB
Plaintext
|
||
READ.ME file for XLI examples
|
||
|
||
|
||
|
||
----- Introduction
|
||
|
||
|
||
The XLI directory contains source code examples of XLI interfaces
|
||
implemented in the following languages:
|
||
|
||
Lattice C, version 3.0
|
||
Microsoft C, version 4.0
|
||
Turbo Pascal, version 3.0
|
||
Turbo C, version 1.0
|
||
Microsoft Macro Assembler, version 4.0
|
||
|
||
Instructions for building each executable file are contained in the source
|
||
file. The TRIG_xx files build functional duplicates of NEWTRIG.EXE, the
|
||
file that implements the transcendental functions in PC Scheme 3.0. If
|
||
you have the Lattice C compiler, the instructions given will build the
|
||
exact duplicate of NEWTRIG.EXE.
|
||
|
||
Two other files, EXEC.C and SOUND.ASM, are XLI programs, distinct from
|
||
the above, that you may find useful in their own right. Corresponding
|
||
.EXE's are provided so you can use them immediately just by inserting
|
||
their pathnames in your .XLI control file.
|
||
|
||
|
||
----- Description of files in XLI directory
|
||
|
||
READ.ME this file
|
||
|
||
TRIG_LC.C Lattice C source (small model)
|
||
GLUE_LC.ASM asm routine to link with above; implements far calls to XLI
|
||
for small model program
|
||
TRIG_LC.XLI XLI control file for above
|
||
|
||
TRIG_MS.C Microsoft C source (small model)
|
||
GLUE_MS.ASM asm routine to link with above; implements far calls to XLI
|
||
for small model program
|
||
TRIG_MS.XLI XLI control file for above
|
||
|
||
TRIG_TP.PAS Turbo Pascal source
|
||
Note: Due to floating point representation differences
|
||
between Turbo Pascal and PC Scheme, this file implements
|
||
simple add, subtract, and multiply of integers, so the
|
||
"trig" designation is a misnomer.
|
||
TRIG_TP.XLI XLI control file for above
|
||
|
||
TRIG_TC.PAS Turbo C source (small model)
|
||
TRIG_TC.XLI XLI control file for above
|
||
|
||
PMATH.S Scheme source file that interfaces with NEWTRIG.EXE.
|
||
Since XLI routine names inside XCALL's are independent
|
||
of the names of the underlying functions that implement
|
||
them, this one file should work with any of the executable
|
||
files generated from the different sources (except Turbo
|
||
Pascal, which implements a different set of examples).
|
||
|
||
SOUND.ASM Microsoft Macro Assembler source for
|
||
generating sounds on the PC
|
||
SOUND.DOC user documentation for SOUND.ASM
|
||
SOUND.EXE executable version of SOUND.ASM
|
||
|
||
EXEC.C Lattice C source (small model) for running executable
|
||
programs via XLI rather than DOS-CALL
|
||
EXEC.DOC user documentation for EXEC.C
|
||
EXEC.EXE executable version of EXEC.C
|
||
|
||
|
||
|
||
----- Debugging XLI external routines - I
|
||
|
||
|
||
During the first stages of developing an XLI interface there may be
|
||
problems with connecting the external program to PC Scheme (PCS).
|
||
This is awkward to debug because XLI bids an external program as a
|
||
child task, and the child is not yet in memory where a machine
|
||
breakpoint can be installed. The following may help to localize
|
||
where such problems lie.
|
||
|
||
First enter PC Scheme normally, specifying a non-existant .XLI file
|
||
to prevent the non-functioning interface from loading. Then enter
|
||
(%XLI-DEBUG 0) and remember the number that is returned. This will
|
||
become the offset value we will use below. Exit PCS and reenter
|
||
with:
|
||
|
||
DEBUG <Scheme's .exe filename> <whatever args>
|
||
R
|
||
|
||
DEBUG's R command dumps the processor registers. Note the value of
|
||
the ES register and add 10 (hex) to it; we will use this as a segment
|
||
value. Now if you disassemble PC Scheme with the U command at the
|
||
segment:offset, you will see a series of JMP instructions. The first
|
||
one represents the completion of bidding the child and is for use
|
||
only by XLI. The second and third JMP instructions are the "wait"
|
||
and "bye" entry points into XLI for your program.
|
||
|
||
Now you can put a breakpoint at the "wait" JMP, then proceed. If
|
||
this address is never reached, it says that your program is not
|
||
jumping to XLI at the correct spot, and not much else can be done
|
||
from the Scheme side to help you. However, if you print the value of
|
||
the DOS termination address in your initialization code, it should
|
||
match the segment:address that we derived above for the U command.
|
||
This provides a useful check that you are indeed peeking into the PSP
|
||
at the proper place. Remember that this address is not itself used,
|
||
but offsets 3 and 6 from it, to connect with the "wait" and "bye" JMP
|
||
instructions.
|
||
|
||
Once you can jump to the "wait" address, you can do other consistency
|
||
checks. Dumping the stack at SS:SP, the top two words (4 bytes) are
|
||
the far return address to your program. If you disassemble the
|
||
instructions around this location, you should see the 2 pushes, the
|
||
far call, and the 2 pops required to pass information to XLI. The
|
||
next word down on the stack is the program's length as calculated by
|
||
your program. Oftentimes this may be the hardest quantity to
|
||
determine; you should find the examples included on the PC Scheme
|
||
diskettes very helpful here, as the different languages listed each
|
||
have different ways of determining this value. The next word down on
|
||
the stack is the address of your PSP. At location PSP+5C (hex)
|
||
should be the file block far pointer. That location, in turn, starts
|
||
with the characters "RB" followed by the flags field and the lookup
|
||
table and parameter block pointers. At this early stage the
|
||
parameter block will probably contain garbage, but the lookup table
|
||
should be reasonable, and don't forget the double slashes at its end.
|
||
|
||
The code executed up to the point of jumping to the "wait" entry
|
||
point will be the same for every XLI interface you write (except
|
||
maybe for the file block flags). This makes it straightforward to
|
||
use an existing interface as a template for the next one and feel
|
||
certain that establishing the connection with XLI will go smoothly.
|
||
|
||
Once you are past the initial call to "wait" and you have verified
|
||
the above points, you can be certain that XLI has the proper
|
||
information for talking with your program. Then you can move on to
|
||
getting the individual XCALL's working. Some hints on this are given
|
||
in the next section.
|
||
|
||
|
||
----- Debugging XLI external routines - II
|
||
|
||
|
||
To debug XCALL's, you can do the following:
|
||
|
||
DEBUG <Scheme's .exe filename> <whatever args>
|
||
G
|
||
|
||
This takes you into PC Scheme. To test an XCALL, do (%XLI-DEBUG arg)
|
||
where arg=0 says turn off debug, and arg=1 says turn on debug. Then
|
||
do your XCALL. You'll enter the debugger positioned at an INT 3
|
||
instruction. (If you just get the Scheme prompt, you forgot to run
|
||
PC Scheme under DEBUG.) DEBUG won't let you proceed through this
|
||
instruction correctly (P won't move and T steps into DEBUG itself),
|
||
but note the IP register. Increment it by 1 to get past the INT 3.
|
||
Then step past the RETF. Immediately after the RETF, you are back in
|
||
your own code. Segment and base registers are correct, but remember
|
||
XCALL doesn't preserve AX through DI registers. The stack should
|
||
contain your program length (on top) and PSP segment address. From
|
||
your PSP you should be able to find all your other data structures
|
||
and verify their contents.
|
||
|
||
Don't use DEBUG's Q command to stop PCS and return to DOS. This
|
||
aborts PCS and prevents XLI from clearing the external routines from
|
||
memory, which reduces the amount of usable memory considerably.
|
||
Return instead to Scheme and use (EXIT).
|
||
|
||
|