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).
|
|||
|
|
|||
|
|