/* This procedure is called when a process makes a system call 
 * Note, stub run in user space would setup the interrupt.
 * Load the system call number into R8.  Switch to kernel mode.
 * Return type is in R1.
 */

void SystemCallInterruptHandler(void) {

  /* Save the process state of the caller */
  /* Dispatcher will later use this to restart the process */
  struct SaveArea *savearea;
  int saveTimer;
  int system_call_number;

  savearea = &(pd[current_process].sa);
  asm {
    /* stop the interval timer and clear any pending timer interrupt */
    store timer, saveTimer;
    load #0, timer;
    /* process's ia and psw are saved in iia and ipsw */
    store iia, savearea + 0;
    store ipsw, savearea + 4;
    /* save the base and bound registers */
    store base, savearea + 8;
    store bound, savearea + 12;
    /* save all the general registers */
    storeall savearea + 16;
    /* set up the stack */
    load SystemStack + SYSTEM_STACK_SIZE, r30;
  }
  pd[current_process].timeLeft = saveTimer;
  pd[current_process].state = Ready;

  /* fetch system call number and switch on it */
  asm {
    store r8, system_call_number;
  }
  switch(system_call_number) {

  case CreateProcessSystemCall:
    /* get the system call args from the registers */
    int block_number;
    asm {
      store r9, block_number;
    }
    /* put the return code in R1 */
    pd[current_process].sa.reg[1] = 
      CreateProcessSysProc(block_number, number_of_blocks);
    break;

  case ExitProcessSystemCall:
    /* we don't save the return code in this OS so just free slot */
    pd[current_process].slotAllocated = FALSE;
    break;

  }

  /* System call complete.  Pick another process to run. */
  Dispatcher();

}

