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