The SimpleFork system call

/* simplified version of fork() */
pid_t SimpleFork () {
	pid_t pid, caller_pid;
	extern process_descriptor_t pd[MAX_PID];

	/* look for a free process descriptor */
	for (pid = 1; pid < MAX_PID; ++pid) {
		if (pd[pid].allocted == FALSE)
			break;
	}

	if (pid >= MAX_PID) {
		/* no free slots */
		return -1;
	}

	/*
	 * Find out which process invoked SimpleFork;
	 * assumes SimpleFork was invoked directly by a syscall, 
	 * otherwise, getpid() would not return correct pid
	 */
	caller_pid = getpid();	

	/* now set up control registers */
	pd[pid].allocted = TRUE;  /* mark descriptor as allocated */
	pd[pid].state = READY;	/* process is ready to run */

	/* assume for simplicity that each process gets equal piece of pie */
	pd[pid].cr.base = pid * PROCESS_SIZE;	
	pd[pid].cr.bound = PROCESS_SIZE;

	/*
	 * look at register for return address from system call 
	 * NOTE: This is not a variable but the actual CPU register
	 */
	pd[pid].cr.pc = register[return_address];

	/* make sure child begins life with normal USER priviledges */
	pd[pid].cr.psw = USER_MODE | INTERRUPTS_ENABLED;

	/* return value from function call is 0 for child */
	pd[pid].gp.ret_val = 0;	

	/* now copy address space from parent */
	memcpy (pd[pid].base, pd[caller_pid].base, PROCESS_SIZE);

	/* we're done... give parent the pid of child */
	return (pid);
}