MODULE osm$monitor_boot;
?? PUSH (LISTEXT := ON) ??
*copyc osc$purge_map_and_cache
*copyc osd$default_pragmats
*copyc dft$queue_interface_directory
*copyc gft$locked_file_desc_entry_p
*copyc iot$io_error
*copyc iot$io_function
*copyc iot$logical_unit
*copyc iot$tape_collected_pp_response
*copyc jmt$active_job_list
*copyc jmt$ijl_ordinal
*copyc jmt$ijl_p
*copyc mmt$active_segment_table
*copyc mmt$buffer_descriptor
*copyc mmt$io_identifier
*copyc mmt$make_pt_entry_status
*copyc mmt$page_frame_index
*copyc mmt$page_frame_table
*copyc mmt$reassignable_page_frames
*copyc mmt$rma_list
*copyc mmt$segment_descriptor_table
*copyc mmt$segment_descriptor_table_ex
*copyc ost$boot_update_page_table
*copyc ost$cpu_definitions
*copyc ost$cpu_state_table
*copyc ost$execution_control_block
*copyc ost$heap
*copyc ost$page_size
*copyc ost$rb_system_error
*copyc ost$segment_access_control
*copyc pmt$initialization_value
*copyc rmt$recorded_vsn
*copyc syt$debug_control
*copyc syt$monitor_status
*copyc tmt$primary_task_list
*copyc tmt$ptl_lock
*copyc tmt$rb_cycle
*copyc tmt$rb_delay
*copyc tmt$system_task_id
?? POP ??
*copyc mmp$get_sdt_entry_p
*copyc mmp$get_sdtx_entry_p
*copyc mmp$preset_real_memory
*copyc mtp$cst_p
*copyc mtp$error_stop
*copyc mtv$monitor_segment_table
*copyc osv$180_memory_limits
*copyc i#real_memory_address

  VAR
    dfv$file_server_info_enabled: [XDCL] boolean := FALSE,
    dfv$monitor_io_start_time: [XDCL] integer,
    dfv$p_queue_interface_directory: [XDCL] dft$p_queue_interface_directory
         := NIL,
    dmv$external_interrupt_selector: [XDCL, #GATE] 0 .. 0ff(16) := 1,
    jmv$ajl_p: [XDCL, #GATE] ^jmt$active_job_list := NIL,
    jmv$null_ijl_ordinal: [XDCL, #GATE] jmt$ijl_ordinal := [0, 0],
    mmv$pt_length: [XDCL, #GATE] integer,
    mmv$pt_p: [XDCL, #GATE] ^ost$page_table,
    mmv$tables_initialized: [XDCL, #GATE] boolean := FALSE,
    syv$debug_control: [XDCL, #GATE] syt$debug_control,
    null_pva: 0 .. 0ffffffffffff(16),
    tmv$system_job_monitor_gtid: [XDCL] ost$global_task_id,
    mmv$next_free_page: [XDCL] integer := 0,
    mmv$free_pages: [XDCL] ^array [ * ] of 0 .. osc$max_page_frames := NIL,
    mmv$multiple_caches: [XDCL] boolean := FALSE,
    mmv$multiple_page_maps: [XDCL] boolean := FALSE,
    mtv$operator_console_hung: [XDCL] boolean := FALSE,
    osv$multiprocessor_running: [XDCL] boolean := FALSE,
    osv$page_size: [XDCL, #GATE] ost$page_size;

{ The following variables are stubs.

  VAR
    jmv$ijl_p: [XDCL] jmt$ijl_p := [NIL, 0, 0],
    mmv$pages_to_dump_p: [XDCL] ^packed array [0 .. *] of boolean,
    osv$cpus_logically_on: [XDCL] 0 .. osc$max_number_of_processors;

{Note:
{  Read_priority is invorked, when mmv$reassignable_page_frames.now > mmv$min_avail_pages

  VAR
    mmv$min_avail_pages: [XDCL] integer := 800,
    mmv$reassignable_page_frames: [XDCL] mmt$reassignable_page_frames := [1000, 0, 0, 0];

?? EJECT ??

  PROCEDURE [INLINE] clear_continue_bits (xpti: ost$page_table_index);


    VAR
      pfti: mmt$page_frame_index,
      ipti: integer;


{Clear 'continue' bits as required.  No bits can be cleared if the 'continue'
{bit in the entry just cleared
{is set or if the actual index to the entry is the same as the hash index.
{Otherwise, scan backward from
{the current entry and clear all
{'continue' bits until either an entry with a zero 'contiue
{Bit' is reached or until another 'moved' entry is found.

    ipti := xpti;
    WHILE TRUE DO
      ipti := ipti - 1;
      IF ipti < 0 THEN
        ipti := mmv$pt_length - 1;
      IFEND;
      IF NOT mmv$pt_p^ [ipti].c THEN
        RETURN
      IFEND;
      mmv$pt_p^ [ipti].c := FALSE;
      IF mmv$pt_p^ [ipti].pageid.asid <> 0 THEN
        pfti := mmv$pt_p^ [ipti].rma * 512 DIV osv$page_size;
{!!  HELP. What do the following really mean?
{!!     IF NOT mmv$initial_hash_table_p^ [ipti] THEN
{!!       RETURN;
{!!     IFEND;
      IFEND;
    WHILEND;

  PROCEND clear_continue_bits;
?? EJECT ??

  PROCEDURE pf_proc_tables_not_initialized (xcb_p:
    ^ost$execution_control_block);

    VAR
      sva: ost$system_virtual_address,
      ste_p: ^mmt$segment_descriptor,
      mpt_status: mmt$make_pt_entry_status,
      pfte: mmt$page_frame_table_entry,
      aste: mmt$active_segment_table_entry,
      last_rma: [STATIC] integer := 0ffffffffffff(16),
      pte_rma: integer,
      full_scan_has_been_done: boolean,
      pt_length: integer,
      pt_p: ^ost$page_table,
      pti: 0 .. osc$max_page_table_entries;

    pt_p := mmv$pt_p;
    pt_length := mmv$pt_length;
    aste.pages_in_memory := 0;
    ste_p := mmp$get_sdt_entry_p (xcb_p, xcb_p^.xp.untranslatable_pointer.seg);
    sva.asid := ste_p^.ste.asid;
    sva.offset := xcb_p^.xp.untranslatable_pointer.offset;
    sva.offset := (sva.offset DIV osv$page_size) * osv$page_size;

    IF mmv$free_pages = NIL THEN
      full_scan_has_been_done := FALSE;
      REPEAT
        IF last_rma >= osv$180_memory_limits.deadstart_upper THEN
          IF full_scan_has_been_done THEN
            mtp$error_stop ('MM - not enough mem to deadstart');
          IFEND;
          last_rma := osv$180_memory_limits.lower;
          full_scan_has_been_done := TRUE;
          pti := pt_length;
          REPEAT
            pti := pti - 1;
            IF (pt_p^ [pti].pageid.asid <> 0) AND (pt_p^ [pti].rma * 512 >
                  last_rma) AND (pt_p^ [pti].rma * 512 < osv$180_memory_limits.deadstart_upper) THEN
              last_rma := pt_p^ [pti].rma * 512;
            IFEND;
          UNTIL pti = 0;
        IFEND;
        last_rma := last_rma + osv$page_size;
        pti := 0;
        pte_rma := last_rma DIV 512;
        WHILE (pti < pt_length) AND ((pte_rma <> pt_p^ [pti].rma) OR (pt_p^
              [pti].pageid.asid = 0)) DO
          pti := pti + 1;
        WHILEND;
      UNTIL pti = pt_length;
    ELSE
      IF mmv$next_free_page = 0 THEN
        mtp$error_stop ('No free pages');
      IFEND;
      last_rma := mmv$next_free_page * osv$page_size;
      mmv$next_free_page := mmv$free_pages^ [mmv$next_free_page];
    IFEND;

    aste.in_use := TRUE;
    mmp$make_pt_entry (sva, last_rma DIV osv$page_size, ^aste, ^pfte,
          mpt_status);
    IF mpt_status <> mmc$mpt_done THEN
      mtp$error_stop ('MM - make PT entry reject');
    IFEND;
    mmp$preset_real_memory (sva, pmc$initialize_to_zero);
    mmv$pt_p^ [pfte.pti].v := TRUE;

  PROCEND pf_proc_tables_not_initialized;

  ?? EJECT ??

  VAR
    mmv$page_table_miss_count: [XDCL] array [1 .. 34] of integer;



  PROCEDURE [XDCL] mmp$make_pt_entry (sva: ost$system_virtual_address;
        pfti: mmt$page_frame_index;
        aste_p: ^mmt$active_segment_table_entry;
        pfte_p: ^mmt$page_frame_table_entry;
    VAR mpt_status: mmt$make_pt_entry_status);

    VAR
      default_pte: [STATIC, READ] ost$page_table_entry := [FALSE, FALSE, TRUE,
        FALSE, [0, 0], 0],
      pte: ost$page_table_entry,
      pt_p: ^ost$page_table,
      c32: boolean,
      ipti: integer,
      count: 1 .. 32,
      found: boolean;



{Calculate the hash index for the page table entry and determine if the page
{already exists. Return an error
{code if an entry already exists.

    #hash_sva (sva, ipti, count, found);
    IF found THEN
      mpt_status := mmc$mpt_page_already_exists;
      RETURN;
    IFEND;
    ipti := ipti - count + 1;
    IF ipti < 0 THEN
      ipti := ipti + mmv$pt_length;
    IFEND;

{Set up page table entry word, and SVA of page.

    pte := default_pte;
    pte.pageid.asid := sva.asid;
    pte.pageid.pagenum := sva.offset DIV 512;
    pte.rma := pfti * osv$page_size DIV 512;



{Find an available slot for the new page table entry. Set 'continue' bits as
{required.  Return error if no
{space is found within 32 entries.

    count := 1;
    pt_p := mmv$pt_p;
    WHILE pt_p^ [ipti].pageid.asid <> 0 DO
      IF count >= 31 THEN
        IF count = 31 THEN
          c32 := pt_p^ [ipti].c;
        ELSE
          mpt_status := mmc$mpt_page_table_full;
          mmv$page_table_miss_count [33] := mmv$page_table_miss_count [33] + 1;
          IF NOT c32 THEN
            clear_continue_bits (ipti);
          IFEND;
          RETURN;
        IFEND;
      IFEND;
      count := count + 1;
      pt_p^ [ipti].c := TRUE;
      ipti := ipti + 1;
      IF ipti = mmv$pt_length THEN
        ipti := 0;
      IFEND;
    WHILEND;
    mmv$page_table_miss_count [count] := mmv$page_table_miss_count [count] + 1;


{Make the new page table entry, preserving the 'continue' bit in the old page
{table entry.

    pte.c := pt_p^ [ipti].c;
    pt_p^ [ipti] := pte;
    pfte_p^.pti := ipti;
    IF NOT aste_p^.in_use THEN
      mtp$error_stop ('MM--MAKE_PT_ENTRY--AST NOT IN USE');
    IFEND;
    aste_p^.pages_in_memory := aste_p^.pages_in_memory + 1;
    mpt_status := mmc$mpt_done;

  PROCEND mmp$make_pt_entry;
  ?? EJECT ??

  PROCEDURE [XDCL] pr_pf (dummy: ^cell;
        cst_p: ^ost$cpu_state_table);

    pf_proc_tables_not_initialized (cst_p^.xcb_p);

  PROCEND pr_pf;
?? EJECT ??

  PROCEDURE [XDCL] mmp$unlock_rma_list (iotype: iot$io_function;
        list_p: ^mmt$rma_list;
        list_length: mmt$rma_list_length;
        io_identifier: mmt$io_identifier;
        mf_job_file: boolean;
    VAR normal: iot$io_error;
    VAR status: syt$monitor_status);

    status.normal := TRUE;

  PROCEND mmp$unlock_rma_list;
?? EJECT ??

  PROCEDURE [XDCL] mmp$build_lock_rma_list (buffer_descriptor:
    mmt$buffer_descriptor;
        length: ost$byte_count;
        iotype: iot$io_function;
        list_p: ^mmt$rma_list;
        list_length: mmt$rma_list_length;
    VAR status: syt$monitor_status);

    VAR
      list_i: mmt$rma_list_index,
      hash_count: 1 .. 32,
      found: boolean,
      page_count: integer,
      io_error: iot$io_error,
      ioid: mmt$io_identifier,
      page_offset: 0 .. 65535,
      sva: ost$system_virtual_address,
      pti: integer;


    status.normal := TRUE;
    list_i := 1;


{  Lock the pages depending on format of the buffer descriptor.

    CASE buffer_descriptor.buffer_descriptor_type OF

    = mmc$bd_paging_io, mmc$bd_explicit_io =
      sva := buffer_descriptor.sva;
      page_offset := sva.offset MOD osv$page_size;
      page_count := ((page_offset + length - 1) DIV osv$page_size) + 1;
      IF list_length < page_count THEN
        mtp$error_stop ('MM - rma list too small');
      IFEND;

    /lp/
      WHILE TRUE DO
        #hash_sva (sva, pti, hash_count, found);
        IF NOT found THEN
          EXIT /lp/
        IFEND;

        list_p^ [list_i].rma := (mmv$pt_p^ [pti].rma * 512) + page_offset;
        page_count := page_count - 1;
        IF page_count <= 0 THEN
          list_p^ [list_i].length := ((buffer_descriptor.sva.offset + length -
                1) MOD osv$page_size) - page_offset + 1;
          IF list_i < list_length THEN
            list_p^ [list_i + 1].length := 0;
          IFEND;
          RETURN
        IFEND;
        list_p^ [list_i].length := osv$page_size - page_offset;
        sva.offset := sva.offset + osv$page_size;
        page_offset := 0;
        list_i := list_i + 1;
      WHILEND /lp/;


{Control gets here only if a page frame is not assigned to a page that is being
{locked.  Unlock the pages (if
{any) that have already been locked.

      IF list_i > 1 THEN
        ioid.specified := false;
        io_error := ioc$no_error;
        mmp$unlock_rma_list (ioc$no_io, list_p, list_i - 1, ioid,
              {mf_job_file} FALSE, io_error, status);
      IFEND;
      mtp$error_stop ('Page frame not assigned - lock rma list');

    ELSE
      mtp$error_stop ('Bad buffer descr in lock rma list');
    CASEND;

  PROCEND mmp$build_lock_rma_list;

?? EJECT ??

  PROCEDURE [XDCL] mmp$build_lock_rma_list_tape (
         tape_request_p: ^iot$wired_tape_request;   {input/output
     VAR status: syt$monitor_status);

    VAR
      command_index: iot$tape_command_index,
      found: boolean,
      hash_count: 1 .. 32,
      length: ost$byte_count,
      list_i: mmt$rma_list_index,
      list_p: ^mmt$rma_list,
      loop_count_index: 1 .. 2,
      page_count: integer,
      page_offset: 0 .. 65535,
      pti: integer,
      pva: ^cell,
      rma: integer,
      sva: ost$system_virtual_address,
      total_list_entries: mmt$rma_list_index;

    status.normal := TRUE;
    total_list_entries := 1;
    list_p := #LOC (tape_request_p^.wired_command_heap_p^.rma_list [1]);

    IF NOT (tape_request_p^.io_type = ioc$explicit_read) THEN
      mtp$error_stop ('MM - boot lock tape rma list, write not supported');
    IFEND;

    FOR loop_count_index := 1 TO 2 DO

    /lock_loop/
      FOR command_index := 1 TO tape_request_p^.no_of_data_commands DO
        list_i := 1;
        IF loop_count_index = 1 THEN {data buffer
          length := tape_request_p^.max_input_count;
          pva := tape_request_p^.wired_read_description_p^ [command_index].buffer_area;
        ELSE {store transfer count buffer
          length := 8;
          pva := tape_request_p^.wired_read_description_p^ [command_index].block_transfer_length;
        IFEND;
        mmp$xtask_pva_to_sva (pva, sva, status);
        IF NOT status.normal THEN
          mtp$error_stop ('MM - boot lock tape rma list, pva to sva convert error');
        IFEND;

        page_offset := sva.offset MOD osv$page_size;
        page_count := ((page_offset + length - 1) DIV osv$page_size) + 1;
        IF page_count + total_list_entries - 1 > tape_request_p^.allocated_address_pair_count THEN
          mtp$error_stop ('MM - boot lock tape rma list, list too small');
        IFEND;

        REPEAT
          #HASH_SVA (sva, pti, hash_count, found);
          IF NOT found THEN
            mtp$error_stop ('MM - boot lock tape rma list, page frame not assigned');
          IFEND;

          list_p^ [total_list_entries].rma := (mmv$pt_p^ [pti].rma * 512) + page_offset;
          page_count := page_count - 1;
          IF page_count > 0 THEN
            list_p^ [total_list_entries].length := osv$page_size - page_offset;
            sva.offset := sva.offset + osv$page_size;
            page_offset := 0;
            list_i := list_i + 1;
          ELSE
            list_p^ [total_list_entries].length := ((sva.offset + length - 1) MOD osv$page_size) -
                  page_offset + 1;
          IFEND;
          total_list_entries := total_list_entries + 1;
        UNTIL page_count <= 0;

        IF loop_count_index = 1 THEN
          i#real_memory_address (^list_p^ [total_list_entries - list_i], rma);
          tape_request_p^.request.tape_command [command_index * 2].address := rma;
          tape_request_p^.request.tape_command [command_index * 2].length := list_i * 8;
        ELSE
          tape_request_p^.request.tape_command [command_index * 2 + 1].address := list_p^
                [total_list_entries - 1].rma;
          EXIT /lock_loop/;
        IFEND;
      FOREND /lock_loop/;

    FOREND;

    IF total_list_entries - 1 < tape_request_p^.allocated_address_pair_count THEN
      list_p^ [total_list_entries].length := 0;
    IFEND;

    tape_request_p^.list_p := list_p;
    tape_request_p^.address_pair_count := total_list_entries - 1;

  PROCEND mmp$build_lock_rma_list_tape;

?? EJECT ??

  PROCEDURE [XDCL] mmp$xtask_pva_to_sva (p: ^cell;
    VAR sva: ost$system_virtual_address;
    VAR status: syt$monitor_status);

    VAR
      cst_p: ^ost$cpu_state_table,
      ste_p: ^mmt$segment_descriptor,
      stxe_p: ^mmt$segment_descriptor_extended,
      aste_p: ^mmt$active_segment_table_entry;

    status.normal := TRUE;
    mtp$cst_p (cst_p);
    mmp$convert_pva (p, cst_p, sva, aste_p, ste_p, stxe_p);

  PROCEND mmp$xtask_pva_to_sva;

  PROCEDURE mmp$convert_pva (p: ^cell;
        cst_p: ^ost$cpu_state_table;
    VAR sva: ost$system_virtual_address;
    VAR aste_p: ^mmt$active_segment_table_entry;
    VAR ste_p: ^mmt$segment_descriptor;
    VAR stxe_p: ^mmt$segment_descriptor_extended);


    VAR
      asid: ost$asid,
      asti: mmt$ast_index,
      segnum: ost$segment;


    segnum := #segment (p);
    ste_p := mmp$get_sdt_entry_p (cst_p^.xcb_p, segnum);
    stxe_p := mmp$get_sdtx_entry_p (cst_p^.xcb_p, segnum);

    IF (segnum > cst_p^.xcb_p^.xp.segment_table_length) OR
          (ste_p^.ste.vl = osc$vl_invalid_entry) THEN
      mtp$error_stop ('MM - invalid PVA');
    IFEND;
    sva.asid := ste_p^.ste.asid;
    sva.offset := #offset (p);
    aste_p := NIL;
  PROCEND mmp$convert_pva;
?? EJECT ??



  PROCEDURE [XDCL] mmp$periodic_call;
  PROCEND mmp$periodic_call;




  PROCEDURE [XDCL] mtp$inject_hardware_fault
    (    processor_id: ost$processor_id);
  PROCEND mtp$inject_hardware_fault;



  PROCEDURE [XDCL] dmp$transfer_unit_completed ALIAS 'dmxtuc' (
        job_id: jmt$ijl_ordinal;
        system_file_id: gft$system_file_identifier;
        byte_address: amt$file_byte_address;
        write_tu_status: dmt$write_tu_status;
        au_was_previously_written: boolean;
        media_error: boolean;
        cylinder: iot$cylinder;
        mau_offset_in_cylinder: dmt$maus_per_position;
        iotype: iot$io_function;
    VAR status: syt$monitor_status);
    status.normal := TRUE;
  PROCEND dmp$transfer_unit_completed;
?? PUSH (LISTEXT := ON) ??
*copyc amt$file_byte_address
*copyc gft$system_file_identifier
*copyc syt$monitor_request_code
*copyc jmt$ijl_ordinal
*copyc dmt$ms_logical_device_address
*copyc iot$cylinder
*copyc dmt$minimum_allocation_unit
*copyc iot$io_function
  ?? POP ??

  PROCEDURE [XDCL] mmp$mtr_process_io_completion (io_id: mmt$io_identifier;
        io_function: iot$io_function;
        io_status: syt$monitor_status);
  PROCEND mmp$mtr_process_io_completion;

?? PUSH (LISTEXT := ON) ??
*copyc mmt$io_identifier
*copyc syt$monitor_status
?? POP ??

  PROCEDURE [XDCL] mmp$mtr_process_server_complete (
        remote_request: dft$remote_request;
        io_id: mmt$io_identifier;
        server_iocb_p: ^mmt$server_iocb_entry;
        io_status: syt$monitor_status );
  PROCEND mmp$mtr_process_server_complete;

?? PUSH (LISTEXT:=ON) ??
*copyc dft$remote_request
*copyc mmt$io_identifier
*copyc mmt$server_io_control_block
*copyc syt$monitor_status
?? POP ??

  PROCEDURE [XDCL] mmp$process_read_ahead_complete
    (    io_id: mmt$io_identifier;
     VAR status: syt$monitor_status);
    status.normal := TRUE;
  PROCEND mmp$process_read_ahead_complete;


?? PUSH (LISTEXT := ON) ??
*copyc ost$global_task_id
*copyc pmt$signal
*copyc syt$monitor_status
?? POP ??

  PROCEDURE [XDCL] tmp$send_signal
    (    recipient: ost$global_task_id;
         signal: pmt$signal;
     VAR status: syt$monitor_status);

    status.normal := TRUE;
  PROCEND tmp$send_signal;


?? PUSH (LISTEXT := ON) ??
*copyc mmt$io_identifier
*copyc syt$monitor_status
?? POP ??

  PROCEDURE [XDCL] dfp$process_error_log_response
    (    p_fs_pp_response: ^dft$fs_pp_response;
         p_fs_error_log_response: ^dft$fs_error_log_response;
         pp_number: 1 .. ioc$pp_count;
     VAR status: syt$monitor_status);
    status.normal := TRUE;
  PROCEND dfp$process_error_log_response;

?? PUSH (LISTEXT := ON) ??
*copyc dft$fs_pp_response
*copyc dft$fs_error_log_response
*copyc iot$pp_interface_table
*copyc syt$monitor_status
?? POP ??

  PROCEDURE [XDCL] dmp$read ALIAS 'dmxread'
    (    fde_p: gft$locked_file_desc_entry_p;
         byte_address: amt$file_byte_address;
         length: amt$file_byte_address;
     VAR device_address: dmt$ms_logical_device_address;
     VAR status: syt$monitor_status);
    status.normal := TRUE;
  PROCEND dmp$read;
?? PUSH (LISTEXT := ON) ??
*copyc amt$file_byte_address
*copyc gft$system_file_identifier
*copyc jmt$ijl_ordinal
*copyc dmt$ms_logical_device_address
*copyc syt$monitor_request_code
  ?? POP ??

  PROCEDURE [XDCL] dmp$write ALIAS 'dmxwrit'
    (    fde_p: gft$locked_file_desc_entry_p;
         byte_address: amt$file_byte_address;
         length: amt$file_byte_address;
         io_function: iot$io_function;
     VAR device_address: dmt$ms_logical_device_address;
     VAR status: syt$monitor_status);
    status.normal := TRUE;
  PROCEND dmp$write;
?? PUSH (LISTEXT := ON) ??
*copyc amt$file_byte_address
*copyc jmt$ijl_ordinal
*copyc gft$system_file_identifier
*copyc dmt$ms_logical_device_address
*copyc syt$monitor_request_code
  ?? POP ??
?? EJECT ??

  PROCEDURE [XDCL] tmp$delay (VAR rb: tmt$rb_delay;
        cst_p: ^ost$cpu_state_table);

    rb.status.normal := TRUE;
    cst_p^.max_cptime := 20000;

  PROCEND tmp$delay;

  PROCEDURE [XDCL] tmp$cycle (VAR rb: tmt$rb_cycle;
        cst_p: ^ost$cpu_state_table);

    cst_p^.max_cptime := 20000;

  PROCEND tmp$cycle;

  VAR
    tmv$ptl_lock: [XDCL, #GATE] tmt$ptl_lock := [FALSE, 0];

  PROCEDURE [XDCL] tmp$switch_task (dummy: ^cell;
        cst_p: ^ost$cpu_state_table);

    cst_p^.max_cptime := 20000;

  PROCEND tmp$switch_task;

  PROCEDURE [XDCL] pr_ascii_coded_keyboard (line: string ( * ));
  PROCEND pr_ascii_coded_keyboard;

  PROCEDURE [XDCL] mtp$deconfigure_divide_unit
    (    processor_id: ost$processor_id);
  PROCEND mtp$deconfigure_divide_unit;

  PROCEDURE [XDCL] mtp$manage_processor_with_due
    (    processor_id: ost$processor_id);
  PROCEND mtp$manage_processor_with_due;
?? PUSH (LISTEXT := ON) ??
*copyc ost$processor_id
?? POP ??

  PROCEDURE [XDCL] mtp$monitor_processor_status;
  PROCEND mtp$monitor_processor_status;
?? EJECT ??

  PROCEDURE [XDCL] tmp$set_system_flag (task_id {input} : ost$global_task_id;
        flag_id {input} : ost$system_flag;
    VAR status {output} : syt$monitor_status);
    status.normal := TRUE;
  PROCEND tmp$set_system_flag;

?? PUSH (LISTEXT := ON) ??
*copyc ost$global_task_id
*copyc ost$system_flag
*copyc syt$monitor_request_code
?? POP ??
?? EJECT ??

  PROCEDURE [XDCL] tmp$flag_all_tasks (flag_id {input} : ost$system_flag;
    VAR status {output} : syt$monitor_status);
    status.normal := TRUE;
  PROCEND tmp$flag_all_tasks;
?? PUSH (LISTEXT := ON) ??
*copyc ost$system_flag
*copyc syt$monitor_status
?? POP ??
?? EJECT ??

  PROCEDURE [XDCL] tmp$process_task_mcr_fault;

    VAR
      cst_p: ^ost$cpu_state_table,
      xcb_p: ^ost$execution_control_block,
      preg: ost$pva,
      pregp: ^^cell,
      mcrp: ^0 .. 0ffff(16),
      st: string (80),
      stl: integer,
      mcr: ost$monitor_conditions,
      zero_pva: [STATIC] ost$pva := [0, 0, 0];


    mtp$cst_p (cst_p);
    xcb_p := cst_p^.xcb_p;
    preg := xcb_p^.xp.p_register.pva;
    pregp := #LOC (preg);
    mcr := xcb_p^.xp.monitor_condition_register;
    mcrp := #LOC (mcr);
    STRINGREP (st, stl, 'Job mode mcr fault: ', pregp^: 16: #(16), mcrp^: 6:
          #(16));
    mtp$error_stop (st (1, stl));
  PROCEND tmp$process_task_mcr_fault;

  PROCEDURE [XDCL] tmp$mtr_process_system_error (rb: ost$rb_system_error);

    VAR
      cst_p: ^ost$cpu_state_table,
      st: string (80),
      stl: integer;


    mtp$cst_p (cst_p);
    STRINGREP (st, stl, rb.text);
    mtp$error_stop (st (1, stl));

  PROCEND tmp$mtr_process_system_error;

  PROCEDURE [XDCL] tmp$process_unknown_req_fault;

    VAR
      cst_p: ^ost$cpu_state_table,
      st: string (80),
      stl: integer;


    mtp$cst_p (cst_p);
    STRINGREP (st, stl, 'Unknown monitor request');
    mtp$error_stop (st (1, stl));

  PROCEND tmp$process_unknown_req_fault;

  PROCEDURE [XDCL] dpp$process_monitor_command (line: string (*));
  PROCEND dpp$process_monitor_command;

  PROCEDURE [XDCL] tmp$check_taskid (taskid: ost$global_task_id;
        option: tmt$option;
    VAR status: syt$monitor_status);
    status.normal := TRUE;
  PROCEND tmp$check_taskid;

  PROCEDURE [XDCL] tmp$monitor_ready_system_task (stid: tmt$system_task_id;
    VAR status: syt$monitor_status);
    status.normal := TRUE;
  PROCEND tmp$monitor_ready_system_task;

  PROCEDURE [XDCL] tmp$set_task_ready (task_id: ost$global_task_id;
        readying_task_priority: jmt$dispatching_priority;
        ready_condition: tmt$ready_condition);
  PROCEND tmp$set_task_ready;

  PROCEDURE [XDCL] osp$boot_update_page_table (VAR rb: ost$boot_update_page_table;
        cst_p: ^ost$cpu_state_table);

    VAR
      sva: ost$system_virtual_address,
      ste_p: ^mmt$segment_descriptor,
      pfte: mmt$page_frame_table_entry,
      mpt_status: mmt$make_pt_entry_status,
      aste: mmt$active_segment_table_entry,
      length: integer;

    length := rb.length;
    aste.pages_in_memory := 0;
    aste.in_use := TRUE;
    ste_p := mmp$get_sdt_entry_p (cst_p^.xcb_p, #segment (rb.pva));
    sva.asid := ste_p^.ste.asid;
    sva.offset := #offset (rb.pva);
    sva.offset := (sva.offset DIV osv$page_size) * osv$page_size;

    WHILE length > 0 DO
      mmp$make_pt_entry (sva, 0, ^aste, ^pfte, mpt_status);
      IF mpt_status = mmc$mpt_page_table_full THEN
        mtp$error_stop ('Page table full');
      IFEND;
      IF mpt_status = mmc$mpt_done THEN
        mmv$pt_p^ [pfte.pti].v := TRUE;
      IFEND;
      sva.offset := sva.offset + osv$page_size;
      length := length - osv$page_size;
    WHILEND;

  PROCEND osp$boot_update_page_table;

{ The following procedure is a stub for mtp$process_due_errors.

  PROCEDURE [XDCL] tmp$cause_task_switch;
  PROCEND tmp$cause_task_switch;

?? PUSH (LISTEXT := ON) ??
*copyc iot$logical_unit
?? POP ??

  PROCEDURE [XDCL] dmp$volume_up (lun: iot$logical_unit);
  PROCEND dmp$volume_up;

  PROCEDURE [XDCL] dmp$volume_down
    (    lun: iot$logical_unit;
         VAR critical: boolean);
    mtp$error_stop ('A disk volume has failed');
  PROCEND dmp$volume_down;

  PROCEDURE [XDCL] dmp$get_recorded_vsn
    (    lun: iot$logical_unit;
         VAR recorded_vsn: rmt$recorded_vsn);
    recorded_vsn := '      ';
  PROCEND dmp$get_recorded_vsn;

  PROCEDURE [XDCL] mmp$determine_error_state (
         list_p: ^mmt$rma_list;
         list_length: mmt$rma_list_length;
     VAR io_error: boolean);

    io_error := FALSE;

  PROCEND mmp$determine_error_state;

  PROCEDURE [XDCL] mmp$include_p_reg_in_dump;

  PROCEND mmp$include_p_reg_in_dump;

  PROCEDURE [XDCL] mmp$mark_page_flawed
    (    pfti: mmt$page_frame_index);

  PROCEND mmp$mark_page_flawed;

MODEND osm$monitor_boot;
