[net.lang.prolog] Adapting PDP-11 Prolog NU-7 for the VAX

kh (12/12/82)

We have installed Clocksin & Mellish's PDP-11 version of Prolog NU-7
on a VAX-11/780 with the compat package that came with 4BSD. Some
changes to the compat package were needed to make it work correctly.
I have made the following changes to create a "v7run" that will work
better, but it still isn't perfect.

	(1) The way NU-7 used the stack memory, compat thought
		that an overflow occurs when there is a BRK
		system call. We just removed the check 
		(around line 365 of unixtraps.c). This fix
		was suggested by John Lloyd at the Univ.
		of Melbourne.

	(2) Signals, specifically those generated by hitting <BREAK>,
		can cause an illegal instruction. I have reduced
		the chance of this happening, but I haven't eliminated
		it. The rest of this article deals with this problem.


The problem (or at least part of the problem), is that
when you are in native mode (simulating a system call or a floating point op),
and a signal is received, sigcatch is called, and it in turn calls
dosig(). Unfortunately, the "pc" that dosig() pushes onto the stack to
may not point to the next instruction, but may instead point to a system
call argument.

There are several possible solutions to this:

	(1) Update "pc" as soon as possible.
		Unfortunately, this only reduces the chance that
		a signal will be caught when pc is bad.
		To do this, move the code:
			if (indirflg == 0)
				pc = argp;
		from (approx) line 428 of unixtraps.c
		to (approx) line 135 (right before "switch(code)")

	(2) Ignore signals entirely in native (VAX) mode.
		I haven't had much success with this.

	(3) Delay signals till end of illtrap() when we know pc is okay.
		This, in combination with (1), has been my best
		result so far.  More on this later.

	(4) Do signal routine immediately, then return to native
		mode to finish simulated system call.
		This is rather complicated, and needs an assembly
		language routine. I haven't tried it yet.

Delaying signal handling until end of illtrap():
To do this, I changed sigcatch() so that it read:
{
	unsigned short *pcptr;
	extern getregs;
	extern int sigs, caught[25];
	if (incompat) {
		/* hurry ... */
		getregs();
	} else {
		signal(signum,SIG_IGN); /* ignore for rest of "system call" */
		caught[sigs++] = signum;
		return;
	}

	/* and the rest of sigcatch ... */
}
	I just declared the globals sigs and caught[];
	caught[] holds all the signals that have been caught;
	"sigs" is the number of signals that have been caught.
	Then, I changed illtrap() (in runcompat.c) so that the end of
	it reads like this:

	while ( sigs )
	{
		dosig(caught[--sigs],pc);
		signal(caught[sigs], SIG_DFL); /* restore signal */
		/* Restoring to SIG_DFL may not always be the best thing. */
	}
	incompat++;
	compat();
}
	Of course, you have to declare caught and sigs at the
	top of illtrap(). 

I'm still working on the problem. If you have any questions, or if you
think of something better, please let me know.

		Kenny Hirsch
		duke!unc!kh
		kh.unc@UDel-Relay

The pdp-11 compatibility mode package "compat" was originally written
by Art Wetzel at the University of Pittsburgh. It can be found
in /usr/src/games on 4.1BSD.

P.S. I am now convinced that the other problem is not the fault of
     the compat program or Prolog. Hooray for kernel bugs!

VAX is a trademark of Digital Equipment Corporation.
PDP is a trademark of Digital Equipment Corporation.
UNIX is a trademark of Bell Telephone Laboratories.
Coke is a trademark of the Coca-Cola Company.