1*16442Smckusick #ifndef lint
2*16442Smckusick static char sccsid[] = "	unixstart.c	4.2	84/05/05	";
3*16442Smckusick #endif
4*16442Smckusick 
5*16442Smckusick /* From Lou Salkind: compat/RCS/unixstart.c,v 1.2 84/01/31 13:34:27 */
6*16442Smckusick 
76808Srrh /*	Start up a version 6 or version 7 pdp-11 UNIX compatability mode
86808Srrh  *	program. Must set up the memory layout with args etc.
96808Srrh  *	Art Wetzel	August 1979
106808Srrh  */
116808Srrh #include <stdio.h>
126808Srrh #include "defs.h"
136808Srrh #define	MAXARGS	100
start(argv,envp)146808Srrh start(argv, envp) unsigned char **argv, **envp; {
156808Srrh 	register unsigned char *sp, *ap;
166808Srrh 	register unsigned short *ssp;
176808Srrh 	register int i, argc, envc;
186808Srrh 	unsigned char *envps[MAXARGS], *argps[MAXARGS], **av, *p1, *p2;
196808Srrh 	extern unsigned char *progname, *nameend;
206808Srrh 	/* set up initial memory layout for unix */
216808Srrh 	/* set stack pointer to top of memory */
226808Srrh 	sp = memsiz;
236808Srrh #ifdef	V7UNIX
246808Srrh 	/* zero top 2 bytes */
256808Srrh 	*(--sp) = 0;
266808Srrh 	*(--sp) = 0;
276808Srrh 	/* point to environment pointer list */
286808Srrh 	av = envp;
296808Srrh 	envc = 0;
306808Srrh 	/* count up number of env elements */
316808Srrh 	while(*(av++)) envc++;
326808Srrh 	/* last UNIX V7 env ptr is 0 */
336808Srrh 	envps[envc] = (unsigned char *)0;
346808Srrh 	/* copy actual environment (assume byte text) - last first */
356808Srrh 	for(i=envc-1; i>=0; i--) {
366808Srrh 		ap = envp[i];
376808Srrh 		while(*(ap++)) ;
386808Srrh 		while(ap != envp[i]) *(--sp) = *(--ap);
396808Srrh 		/* force stack word alignment - required per arg in v7 */
406808Srrh 		if((int)sp & 1) {
416808Srrh 			ap = sp--;
426808Srrh 			while((*(ap-1) = *ap)) ap++;
436808Srrh 		}
446808Srrh 		envps[i] = sp;
456808Srrh 	}
466808Srrh #endif
476808Srrh 	/* point to argument pointer list */
486808Srrh 	av = argv;
496808Srrh 	argc = 0;
506808Srrh 	/* count up number of args */
516808Srrh 	while(*(av++)) argc++;
526808Srrh #ifdef V7UNIX
536808Srrh 	/* last UNIX V7 arg ptr is 0 */
546808Srrh 	argps[argc] = (unsigned char *)0;
556808Srrh #endif
566808Srrh #ifdef V6UNIX
576808Srrh 	/* last UNIX V6 arg ptr is -1 */
586808Srrh 	argps[argc] = (unsigned char *)-1;
596808Srrh #endif
606808Srrh 	/* copy actual arguments (assume byte text) - last first */
616808Srrh 	for(i=argc-1; i>=0; i--) {
626808Srrh 		ap = argv[i];
636808Srrh 		while(*(ap++)) ;
646808Srrh 		while(ap != argv[i]) *(--sp) = *(--ap);
656808Srrh 		/* force stack word alignment - required per arg in v7 */
666808Srrh 		if((int)sp & 1) {
676808Srrh 			ap = sp--;
686808Srrh 			while((*(ap-1) = *ap)) ap++;
696808Srrh 		}
706808Srrh 		argps[i] = sp;
716808Srrh 	}
726808Srrh 	ssp = (unsigned short *)sp;
736808Srrh #ifdef	V7UNIX
746808Srrh 	/* set up environment pointers */
756808Srrh 	for(i=envc; i>=0; i--) {
766808Srrh 		*(--ssp) = (short)(long)envps[i];
776808Srrh 	}
786808Srrh #endif
796808Srrh 	/* set up argument pointers */
806808Srrh 	for(i=argc; i>=0; i--) {
816808Srrh 		*(--ssp) = (short)(long)argps[i];
826808Srrh 	}
836808Srrh 	/* then argument count */
846808Srrh 	*(--ssp) = argc;
856808Srrh 	/* set up stack pointer */
866808Srrh 	regs[6] = (int)ssp;
876808Srrh 	/* set up a psl with cleared condition codes */
886808Srrh 	psl = 0x83c00000;
896808Srrh 	/* copy out part of the program name and args where ps can get them */
906808Srrh 	/* flag it with a * so it shows up as a compatability mode process */
916808Srrh 	/* check for case with no env and reset nameend */
926808Srrh 	if(nameend < progname) nameend = (unsigned char *)2147483647;
936808Srrh 	for(p1=progname, *p1++ = '*', i=1, p2=argv[0]; p1<nameend; p1++) {
946808Srrh 		if((*p1 = *p2))
956808Srrh 			p2++;
966808Srrh 		else if(argv[i])
976808Srrh 			p2 = argv[i++];
986808Srrh 		else break;
996808Srrh 	}
1006808Srrh 	while(p1 < nameend) *p1++ = ' ';
1016808Srrh 	*p1 = 0;
1026808Srrh 	/* clear out registers other than sp */
1036808Srrh 	regs[0] = 0;
1046808Srrh 	regs[1] = 0;
1056808Srrh 	regs[2] = 0;
1066808Srrh 	regs[3] = 0;
1076808Srrh 	regs[4] = 0;
1086808Srrh 	regs[5] = 0;
1096808Srrh 	/* finally get around to actually starting up in compatability mode */
1106808Srrh 	incompat++;
1116808Srrh 	compat();
1126808Srrh }
113