let rec page_fault system_state page_nb =
  let p = system_state.current in
  if !verbose then Printf.eprintf "Page %d faulted (size=%d)\n%!"
      page_nb p.ptable_size;
  if page_nb < p.ptable_size then
    begin
      allocate_page p.preg.(ptpage_nb;
      run system_state
    end
  else
    begin
      print_endline "Segmentation fault";
      p.preg.(a0) <- 1;
      system_traps.(sys_Exitsystem_state
    end

and run system_state =
  if !verbose then
    Printf.eprintf "pid=%d  code=%d starts running\n%!"
      system_state.current.pid
      system_state.current.pcode;
  let code = system_state.current.pcode in
  try process  system_state.codes.(codewith
    Trap -> syscall system_state
  | Signal -> signal system_state
  | Invalid_argument _ -> raise Invalid_code
  | Segmentation_fault -> segmentation_fault system_state
  | Page_fault page_nb  -> page_fault system_state page_nb

and signal system_state =
  incr time;
  if !time mod update_frequency = 0 then
    Hashtbl.iter (update_quantum system_state.currentsystem_state.processes;
  let p = system_state.current in
  p.quantum <- p.quantum + 1;
  if p.quantum == max_quantum then
    begin
      if !verbose then
        Printf.eprintf "pid=%d  preempted\n%!" system_state.current.pid;
      schedule system_state
    end
  else
    run system_state

and schedule system_state =
  let p = elect_process system_state in
  if !verbose then
    Printf.eprintf "resuming=%d\n%!" p.pid;
  system_state.current <- p;
  machine.reg <- p.preg;
  run system_state


and segmentation_fault system_state =
  print_endline "Segmentation fault";
  system_state.current.preg.(a0) <- 1;
  system_traps.(sys_Exitsystem_state;;