1*6808Srrh #
2*6808Srrh static char sccsid[] = "	unixstart.c	1.1	82/05/12	";
3*6808Srrh /*	Start up a version 6 or version 7 pdp-11 UNIX compatability mode
4*6808Srrh  *	program. Must set up the memory layout with args etc.
5*6808Srrh  *	Art Wetzel	August 1979
6*6808Srrh  */
7*6808Srrh #include <stdio.h>
8*6808Srrh #include "defs.h"
9*6808Srrh #define	MAXARGS	100
10*6808Srrh start(argv, envp) unsigned char **argv, **envp; {
11*6808Srrh 	register unsigned char *sp, *ap;
12*6808Srrh 	register unsigned short *ssp;
13*6808Srrh 	register int i, argc, envc;
14*6808Srrh 	unsigned char *envps[MAXARGS], *argps[MAXARGS], **av, *p1, *p2;
15*6808Srrh 	extern unsigned char *progname, *nameend;
16*6808Srrh 	/* set up initial memory layout for unix */
17*6808Srrh 	/* set stack pointer to top of memory */
18*6808Srrh 	sp = memsiz;
19*6808Srrh #ifdef	V7UNIX
20*6808Srrh 	/* zero top 2 bytes */
21*6808Srrh 	*(--sp) = 0;
22*6808Srrh 	*(--sp) = 0;
23*6808Srrh 	/* point to environment pointer list */
24*6808Srrh 	av = envp;
25*6808Srrh 	envc = 0;
26*6808Srrh 	/* count up number of env elements */
27*6808Srrh 	while(*(av++)) envc++;
28*6808Srrh 	/* last UNIX V7 env ptr is 0 */
29*6808Srrh 	envps[envc] = (unsigned char *)0;
30*6808Srrh 	/* copy actual environment (assume byte text) - last first */
31*6808Srrh 	for(i=envc-1; i>=0; i--) {
32*6808Srrh 		ap = envp[i];
33*6808Srrh 		while(*(ap++)) ;
34*6808Srrh 		while(ap != envp[i]) *(--sp) = *(--ap);
35*6808Srrh 		/* force stack word alignment - required per arg in v7 */
36*6808Srrh 		if((int)sp & 1) {
37*6808Srrh 			ap = sp--;
38*6808Srrh 			while((*(ap-1) = *ap)) ap++;
39*6808Srrh 		}
40*6808Srrh 		envps[i] = sp;
41*6808Srrh 	}
42*6808Srrh #endif
43*6808Srrh 	/* point to argument pointer list */
44*6808Srrh 	av = argv;
45*6808Srrh 	argc = 0;
46*6808Srrh 	/* count up number of args */
47*6808Srrh 	while(*(av++)) argc++;
48*6808Srrh #ifdef V7UNIX
49*6808Srrh 	/* last UNIX V7 arg ptr is 0 */
50*6808Srrh 	argps[argc] = (unsigned char *)0;
51*6808Srrh #endif
52*6808Srrh #ifdef V6UNIX
53*6808Srrh 	/* last UNIX V6 arg ptr is -1 */
54*6808Srrh 	argps[argc] = (unsigned char *)-1;
55*6808Srrh #endif
56*6808Srrh 	/* copy actual arguments (assume byte text) - last first */
57*6808Srrh 	for(i=argc-1; i>=0; i--) {
58*6808Srrh 		ap = argv[i];
59*6808Srrh 		while(*(ap++)) ;
60*6808Srrh 		while(ap != argv[i]) *(--sp) = *(--ap);
61*6808Srrh 		/* force stack word alignment - required per arg in v7 */
62*6808Srrh 		if((int)sp & 1) {
63*6808Srrh 			ap = sp--;
64*6808Srrh 			while((*(ap-1) = *ap)) ap++;
65*6808Srrh 		}
66*6808Srrh 		argps[i] = sp;
67*6808Srrh 	}
68*6808Srrh 	ssp = (unsigned short *)sp;
69*6808Srrh #ifdef	V7UNIX
70*6808Srrh 	/* clear a word */
71*6808Srrh 	*(--ssp) = 0;
72*6808Srrh 	/* set up environment pointers */
73*6808Srrh 	for(i=envc; i>=0; i--) {
74*6808Srrh 		*(--ssp) = (short)(long)envps[i];
75*6808Srrh 	}
76*6808Srrh 	/* clear another word */
77*6808Srrh 	*(--ssp) = 0;
78*6808Srrh #endif
79*6808Srrh 	/* set up argument pointers */
80*6808Srrh 	for(i=argc; i>=0; i--) {
81*6808Srrh 		*(--ssp) = (short)(long)argps[i];
82*6808Srrh 	}
83*6808Srrh 	/* then argument count */
84*6808Srrh 	*(--ssp) = argc;
85*6808Srrh 	/* set up stack pointer */
86*6808Srrh 	regs[6] = (int)ssp;
87*6808Srrh 	/* set up a psl with cleared condition codes */
88*6808Srrh 	psl = 0x83c00000;
89*6808Srrh 	/* copy out part of the program name and args where ps can get them */
90*6808Srrh 	/* flag it with a * so it shows up as a compatability mode process */
91*6808Srrh 	/* check for case with no env and reset nameend */
92*6808Srrh 	if(nameend < progname) nameend = (unsigned char *)2147483647;
93*6808Srrh 	for(p1=progname, *p1++ = '*', i=1, p2=argv[0]; p1<nameend; p1++) {
94*6808Srrh 		if((*p1 = *p2))
95*6808Srrh 			p2++;
96*6808Srrh 		else if(argv[i])
97*6808Srrh 			p2 = argv[i++];
98*6808Srrh 		else break;
99*6808Srrh 	}
100*6808Srrh 	while(p1 < nameend) *p1++ = ' ';
101*6808Srrh 	*p1 = 0;
102*6808Srrh 	/* clear out registers other than sp */
103*6808Srrh 	regs[0] = 0;
104*6808Srrh 	regs[1] = 0;
105*6808Srrh 	regs[2] = 0;
106*6808Srrh 	regs[3] = 0;
107*6808Srrh 	regs[4] = 0;
108*6808Srrh 	regs[5] = 0;
109*6808Srrh 	/* finally get around to actually starting up in compatability mode */
110*6808Srrh 	incompat++;
111*6808Srrh 	compat();
112*6808Srrh }
113