?? RIGHT := 110 ??

  PROCEDURE [INLINE] nap$get_request_block (rma_list_length: integer;
    VAR request_block: ^nat$request_block);
?? PUSH (LISTEXT := ON) ??

    VAR
      initial: nat$preallocated_rb_control,
      new: nat$preallocated_rb_control,
      actual: nat$preallocated_rb_control,
      cs_status: osc$cs_successful .. osc$cs_variable_locked,
      io_request: ^iot$io_request,
      request_block_length: integer,
      complete_request: ^nat$complete_request_block,
      complete_request_block: ^SEQ ( * ),
      peripheral_request: ^nat$peripheral_request,
      peripheral_request_rma: integer;

    request_block := NIL;
    IF ((rma_list_length > 0) AND (rma_list_length <= UPPERVALUE (nat$fixed_rma_list))) THEN
      initial.first_free_block := UPPERVALUE (nat$request_block_identifier);
      initial.sequence_number := 0;
      new := initial;
      REPEAT
        #compare_swap (nav$preallocated_rb_control, initial, new, actual, cs_status);
      UNTIL (cs_status <> osc$cs_variable_locked);

    /get_preallocated_block/
      BEGIN
        IF (actual.first_free_block <> 0) THEN
          initial := actual;
          new.first_free_block := nav$preallocated_request_block^ [initial.first_free_block]^.
                allocation_description.next_block_identifier;
          new.sequence_number := initial.sequence_number + 1;
          REPEAT
            #compare_swap (nav$preallocated_rb_control, initial, new, actual, cs_status);
            CASE cs_status OF
            = osc$cs_successful =
              request_block := nav$preallocated_request_block^ [initial.first_free_block];
            = osc$cs_failed =
              IF (actual.first_free_block <> 0) THEN
                initial := actual;
                new.first_free_block := nav$preallocated_request_block^ [initial.first_free_block]^.
                      allocation_description.next_block_identifier;
                new.sequence_number := initial.sequence_number + 1;
              ELSE
                EXIT /get_preallocated_block/;
              IFEND;
            = osc$cs_variable_locked =
              ;
            CASEND;
          UNTIL (cs_status = osc$cs_successful);
        IFEND;
      END /get_preallocated_block/;
    IFEND;

    IF (request_block = NIL) THEN
      request_block_length := ((((#SIZE (nat$request_block) + #SIZE (ost$word) - 1) DIV #SIZE (ost$word)) *
            #SIZE (ost$word)) + (#SIZE (mmt$rma_list_entry) * rma_list_length));
      ALLOCATE complete_request: [[REP request_block_length OF cell]] IN osv$mainframe_wired_cb_heap^;
      complete_request_block := ^complete_request^.complete_sequence;
      RESET complete_request_block;
      NEXT request_block IN complete_request_block;
      request_block^.complete_request_block := complete_request;

      IF (rma_list_length = 0) THEN
        request_block^.network_request.rma_list := NIL;
      ELSE
        NEXT request_block^.network_request.rma_list: [1 .. rma_list_length] IN complete_request_block;
      IFEND;

      request_block^.io_request.response_processor_p := nav$network_response_processor;
      request_block^.io_request.device_request_p := #LOC (request_block^.network_request);
      request_block^.io_request.pp_request_p := ^request_block^.network_request.peripheral_request;

      request_block^.network_request.request_block_link := NIL;
      request_block^.network_request.peripheral_request.recovery := ioc$attempt_recovery;
      request_block^.network_request.peripheral_request.interrupt.value := TRUE;
      request_block^.network_request.peripheral_request.priority := 1;

      request_block^.allocation_description.preallocated := FALSE;

      i#real_memory_address (^request_block^.network_request.peripheral_request, peripheral_request_rma);
      request_block^.peripheral_request_rma := peripheral_request_rma;
    IFEND;
    request_block^.network_request.peripheral_request.next_pp_request_rma := 0;
    request_block^.network_request.peripheral_request.pp_request := ^request_block^.io_request;
    request_block^.network_request.message_id.descriptor := NIL;
    request_block^.network_request.peripheral_request.request_length := #SIZE (nat$peripheral_request);
    request_block^.network_request.peripheral_request.interrupt.port_number :=
          osv$external_interrupt_selector;
  PROCEND nap$get_request_block;

*copy nah$get_request_block
*copyc iot$io_request
*copyc iot$request_recovery
*copyc nat$preallocated_rb_control
*copyc nat$request_block
*copyc nav$preallocated_rb_control
*copyc nav$preallocated_request_block
*copyc ost$hardware_subranges
*copyc ost$signature_lock
*copyc osv$mainframe_wired_cb_heap
*copyc osv$external_interrupt_selector
*copyc i#real_memory_address
?? POP ??
