?? RIGHT := 110 ??                                                                                            
?? NEWTITLE := 'NOS/VE Dump Analyzer : Copy Memory Command' ??                                                
MODULE dum$copy_memory_command;                                                                               
                                                                                                              
{ PURPOSE:                                                                                                    
{   This module contains the code for the copy_memory command.                                                
                                                                                                              
?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??                                      
?? PUSH (LISTEXT := ON) ??                                                                                    
*copyc due$exception_condition_codes                                                                          
?? POP ??                                                                                                     
*copyc amp$get_segment_pointer                                                                                
*copyc amp$set_segment_eoi                                                                                    
*copyc dup$access_real_memory                                                                                 
*copyc dup$copy_virtual_memory_pva                                                                            
*copyc dup$copy_virtual_memory_sva                                                                            
*copyc dup$display_message                                                                                    
*copyc dup$evaluate_parameters                                                                                
*copyc dup$retrieve_exchange_package                                                                          
*copyc fsp$close_file                                                                                         
*copyc fsp$open_file                                                                                          
*copyc osp$append_status_integer                                                                              
*copyc osp$disestablish_cond_handler                                                                          
*copyc osp$establish_block_exit_hndlr                                                                         
*copyc osp$set_status_abnormal                                                                                
?? EJECT ??                                                                                                   
*copyc duv$dump_environment_p                                                                                 
*copyc duv$execution_environment                                                                              
?? OLDTITLE ??                                                                                                
?? NEWTITLE := 'dup$copy_memory_command', EJECT ??                                                            
                                                                                                              
{ PURPOSE:                                                                                                    
{   This procedure copies memory from the restart file to the output file.                                    
                                                                                                              
  PROCEDURE [XDCL] dup$copy_memory_command                                                                    
    (    parameter_list: clt$parameter_list;                                                                  
     VAR status: ost$status);                                                                                 
                                                                                                              
{ PROCEDURE copy_memory, copm (                                                                               
{   address, a: integer = $required                                                                           
{   file, f: file = $required                                                                                 
{   bytes, b, byte_count, bc: integer 0..osc$max_segment_length = 100000(16)                                  
{   exchange, e: any of                                                                                       
{       key                                                                                                   
{         (active a) (monitor m) (job j)                                                                      
{       keyend                                                                                                
{       integer 0..0ffffffff(16)                                                                              
{     anyend = 0ffffffff(16)                                                                                  
{   processor, p: integer 0..3 = 0                                                                            
{   address_mode, am: key                                                                                     
{       (process_virtual_address pva) (system_virtual_address sva) (real_memory_address rma)                  
{     keyend = process_virtual_address                                                                        
{   status)                                                                                                   
                                                                                                              
?? PUSH (LISTEXT := ON) ??                                                                                    
?? FMT (FORMAT := OFF) ??                                                                                     
  VAR                                                                                                         
    pdt: [STATIC, READ, cls$declaration_section] record                                                       
      header: clt$pdt_header,                                                                                 
      names: array [1 .. 15] of clt$pdt_parameter_name,                                                       
      parameters: array [1 .. 7] of clt$pdt_parameter,                                                        
      type1: record                                                                                           
        header: clt$type_specification_header,                                                                
        qualifier: clt$integer_type_qualifier,                                                                
      recend,                                                                                                 
      type2: record                                                                                           
        header: clt$type_specification_header,                                                                
      recend,                                                                                                 
      type3: record                                                                                           
        header: clt$type_specification_header,                                                                
        qualifier: clt$integer_type_qualifier,                                                                
        default_value: string (10),                                                                           
      recend,                                                                                                 
      type4: record                                                                                           
        header: clt$type_specification_header,                                                                
        qualifier: clt$union_type_qualifier,                                                                  
        type_size_1: clt$type_specification_size,                                                             
        element_type_spec_1: record                                                                           
          header: clt$type_specification_header,                                                              
          qualifier: clt$keyword_type_qualifier,                                                              
          keyword_specs: array [1 .. 6] of clt$keyword_specification,                                         
        recend,                                                                                               
        type_size_2: clt$type_specification_size,                                                             
        element_type_spec_2: record                                                                           
          header: clt$type_specification_header,                                                              
          qualifier: clt$integer_type_qualifier,                                                              
        recend,                                                                                               
        default_value: string (13),                                                                           
      recend,                                                                                                 
      type5: record                                                                                           
        header: clt$type_specification_header,                                                                
        qualifier: clt$integer_type_qualifier,                                                                
        default_value: string (1),                                                                            
      recend,                                                                                                 
      type6: record                                                                                           
        header: clt$type_specification_header,                                                                
        qualifier: clt$keyword_type_qualifier,                                                                
        keyword_specs: array [1 .. 6] of clt$keyword_specification,                                           
        default_value: string (23),                                                                           
      recend,                                                                                                 
      type7: record                                                                                           
        header: clt$type_specification_header,                                                                
      recend,                                                                                                 
    recend := [                                                                                               
    [1,                                                                                                       
    [90, 6, 26, 8, 25, 1, 312],                                                                               
    clc$command, 15, 7, 2, 0, 0, 0, 7, ''], [                                                                 
    ['A                              ',clc$abbreviation_entry, 1],                                            
    ['ADDRESS                        ',clc$nominal_entry, 1],                                                 
    ['ADDRESS_MODE                   ',clc$nominal_entry, 6],                                                 
    ['AM                             ',clc$abbreviation_entry, 6],                                            
    ['B                              ',clc$alias_entry, 3],                                                   
    ['BC                             ',clc$abbreviation_entry, 3],                                            
    ['BYTES                          ',clc$nominal_entry, 3],                                                 
    ['BYTE_COUNT                     ',clc$alias_entry, 3],                                                   
    ['E                              ',clc$abbreviation_entry, 4],                                            
    ['EXCHANGE                       ',clc$nominal_entry, 4],                                                 
    ['F                              ',clc$abbreviation_entry, 2],                                            
    ['FILE                           ',clc$nominal_entry, 2],                                                 
    ['P                              ',clc$abbreviation_entry, 5],                                            
    ['PROCESSOR                      ',clc$nominal_entry, 5],                                                 
    ['STATUS                         ',clc$nominal_entry, 7]],                                                
    [                                                                                                         
{ PARAMETER 1                                                                                                 
    [2, clc$normal_usage_entry, clc$non_secure_parameter,                                                     
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],                               
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 20, clc$required_parameter, 
  0, 0],                                                                                                      
{ PARAMETER 2                                                                                                 
    [12, clc$normal_usage_entry, clc$non_secure_parameter,                                                    
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],                               
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3, clc$required_parameter, 0
  , 0],                                                                                                       
{ PARAMETER 3                                                                                                 
    [7, clc$normal_usage_entry, clc$non_secure_parameter,                                                     
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],                               
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 20,                         
  clc$optional_default_parameter, 0, 10],                                                                     
{ PARAMETER 4                                                                                                 
    [10, clc$normal_usage_entry, clc$non_secure_parameter,                                                    
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],                               
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 269,                        
  clc$optional_default_parameter, 0, 13],                                                                     
{ PARAMETER 5                                                                                                 
    [14, clc$normal_usage_entry, clc$non_secure_parameter,                                                    
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],                               
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 20,                         
  clc$optional_default_parameter, 0, 1],                                                                      
{ PARAMETER 6                                                                                                 
    [3, clc$normal_usage_entry, clc$non_secure_parameter,                                                     
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],                               
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 229,                        
  clc$optional_default_parameter, 0, 23],                                                                     
{ PARAMETER 7                                                                                                 
    [15, clc$normal_usage_entry, clc$non_secure_parameter,                                                    
    $clt$parameter_spec_methods[clc$specify_by_name],                                                         
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,                      
  clc$optional_parameter, 0, 0]],                                                                             
{ PARAMETER 1                                                                                                 
    [[1, 0, clc$integer_type], [clc$min_integer, clc$max_integer, 10]],                                       
{ PARAMETER 2                                                                                                 
    [[1, 0, clc$file_type]],                                                                                  
{ PARAMETER 3                                                                                                 
    [[1, 0, clc$integer_type], [0, osc$max_segment_length, 10],                                               
    '100000(16)'],                                                                                            
{ PARAMETER 4                                                                                                 
    [[1, 0, clc$union_type], [[clc$integer_type, clc$keyword_type],                                           
    FALSE, 2],                                                                                                
    229, [[1, 0, clc$keyword_type], [6], [                                                                    
      ['A                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],                 
      ['ACTIVE                         ', clc$nominal_entry, clc$normal_usage_entry, 1],                      
      ['J                              ', clc$abbreviation_entry, clc$normal_usage_entry, 3],                 
      ['JOB                            ', clc$nominal_entry, clc$normal_usage_entry, 3],                      
      ['M                              ', clc$abbreviation_entry, clc$normal_usage_entry, 2],                 
      ['MONITOR                        ', clc$nominal_entry, clc$normal_usage_entry, 2]]                      
      ],                                                                                                      
    20, [[1, 0, clc$integer_type], [0, 0ffffffff(16), 10]]                                                    
    ,                                                                                                         
    '0ffffffff(16)'],                                                                                         
{ PARAMETER 5                                                                                                 
    [[1, 0, clc$integer_type], [0, 3, 10],                                                                    
    '0'],                                                                                                     
{ PARAMETER 6                                                                                                 
    [[1, 0, clc$keyword_type], [6], [                                                                         
    ['PROCESS_VIRTUAL_ADDRESS        ', clc$nominal_entry, clc$normal_usage_entry, 1],                        
    ['PVA                            ', clc$abbreviation_entry, clc$normal_usage_entry, 1],                   
    ['REAL_MEMORY_ADDRESS            ', clc$nominal_entry, clc$normal_usage_entry, 3],                        
    ['RMA                            ', clc$abbreviation_entry, clc$normal_usage_entry, 3],                   
    ['SVA                            ', clc$abbreviation_entry, clc$normal_usage_entry, 2],                   
    ['SYSTEM_VIRTUAL_ADDRESS         ', clc$nominal_entry, clc$normal_usage_entry, 2]]                        
    ,                                                                                                         
    'process_virtual_address'],                                                                               
{ PARAMETER 7                                                                                                 
    [[1, 0, clc$status_type]]];                                                                               
?? FMT (FORMAT := ON) ??                                                                                      
?? POP ??                                                                                                     
                                                                                                              
    CONST                                                                                                     
      p$address = 1,                                                                                          
      p$file = 2,                                                                                             
      p$bytes = 3,                                                                                            
      p$exchange = 4,                                                                                         
      p$processor = 5,                                                                                        
      p$address_mode = 6,                                                                                     
      p$status = 7;                                                                                           
                                                                                                              
    VAR                                                                                                       
      pvt: array [1 .. 7] of clt$parameter_value;                                                             
                                                                                                              
    VAR                                                                                                       
      access_data: dut$access_data,                                                                           
      address: dut$ee_address_parameter,                                                                      
      byte_count: ost$segment_length,                                                                         
      bytes_returned: ost$segment_length,                                                                     
      default_list: ARRAY [1 .. 3] OF dut$default_change_list_entry,                                          
      display_control: clt$display_control,                                                                   
      exchange_package_p: ^dut$exchange_package,                                                              
      fa_p: ^fst$attachment_options,                                                                          
      file_buffer_p: ^SEQ ( * ),                                                                              
      file_identifier: amt$file_identifier,                                                                   
      file_pointer: amt$segment_pointer,                                                                      
      ignore_status: ost$status,                                                                              
      invalid_segment_issued: boolean,                                                                        
      local_status: ost$status,                                                                               
      mca_p: ^fst$file_cycle_attributes,                                                                      
      memory_file_buffer_p: ^SEQ ( * ),                                                                       
      memory_file_p: ^cell,                                                                                   
      memory_skipped: ost$segment_offset,                                                                     
      new_byte_size: ost$segment_length,                                                                      
      output_file_opened: boolean,                                                                            
      page_fault_encountered: boolean,                                                                        
      skip_start: ost$segment_offset,                                                                         
      skipping_page_faulted_memory: boolean,                                                                  
      some_memory_copied: boolean,                                                                            
      starting_offset: ost$segment_offset;                                                                    
                                                                                                              
*copy dup$abort_handler                                                                                       
?? NEWTITLE := 'clean_up', EJECT ??                                                                           
                                                                                                              
{ PURPOSE:                                                                                                    
{   This procedure is called from the abort handler to close the file.                                        
                                                                                                              
    PROCEDURE [INLINE] clean_up;                                                                              
                                                                                                              
      VAR                                                                                                     
        ignore_status: ost$status;                                                                            
                                                                                                              
      IF output_file_opened THEN                                                                              
        fsp$close_file (file_identifier, ignore_status);                                                      
      IFEND;                                                                                                  
                                                                                                              
    PROCEND clean_up;                                                                                         
?? OLDTITLE, EJECT ??                                                                                         
                                                                                                              
    status.normal := TRUE;                                                                                    
                                                                                                              
    { Change the default value for the EXCHANGE, PROCESSOR and ADDRESS_MODE parameters.                       
                                                                                                              
    default_list [1].default_name := duc$dp_exchange;                                                         
    default_list [1].number := p$exchange;                                                                    
    default_list [2].default_name := duc$dp_processor;                                                        
    default_list [2].number := p$processor;                                                                   
    default_list [3].default_name := duc$dp_address_mode;                                                     
    default_list [3].number := p$address_mode;                                                                
    dup$evaluate_parameters (parameter_list, default_list, #SEQ (pdt), ^pvt, status);                         
    IF NOT status.normal THEN                                                                                 
      RETURN;  {---->                                                                                         
    IFEND;                                                                                                    
                                                                                                              
    IF duv$dump_environment_p = NIL THEN                                                                      
      osp$set_status_abnormal (duc$dump_analyzer_id, due$no_restart_file, '', status);                        
      RETURN;  {---->                                                                                         
    IFEND;                                                                                                    
                                                                                                              
    { Retrieve the exchange package if needed.                                                                
                                                                                                              
    IF (pvt [p$address_mode].value^.keyword_value <> 'PROCESS_VIRTUAL_ADDRESS') AND                           
          pvt [p$exchange].specified THEN                                                                     
      osp$set_status_abnormal (duc$dump_analyzer_id, due$rma_and_exc_specified, '', status);                  
      RETURN;  {---->                                                                                         
    IFEND;                                                                                                    
    IF pvt [p$address_mode].value^.keyword_value = 'PROCESS_VIRTUAL_ADDRESS' THEN                             
      dup$retrieve_exchange_package (pvt [p$processor].value^.integer_value.value, pvt [p$exchange].value^,   
            exchange_package_p, status);                                                                      
      IF NOT status.normal THEN                                                                               
        RETURN;  {---->                                                                                       
      IFEND;                                                                                                  
    IFEND;                                                                                                    
                                                                                                              
    output_file_opened := FALSE;                                                                              
    osp$establish_block_exit_hndlr (^abort_handler);                                                          
                                                                                                              
   /file_opened/                                                                                              
    BEGIN                                                                                                     
                                                                                                              
      { Open the output file.                                                                                 
                                                                                                              
      PUSH fa_p: [1 .. 1];                                                                                    
      fa_p^ [1].selector := fsc$access_and_share_modes;                                                       
      fa_p^ [1].access_modes.selector := fsc$specific_access_modes;                                           
      fa_p^ [1].access_modes.value :=                                                                         
            $fst$file_access_options [fsc$read, fsc$shorten, fsc$append, fsc$modify];                         
      fa_p^ [1].share_modes.selector := fsc$specific_share_modes;                                             
      fa_p^ [1].share_modes.value := $fst$file_access_options [fsc$read, fsc$shorten, fsc$append, fsc$modify];
                                                                                                              
      PUSH mca_p: [1 .. 2];                                                                                   
      mca_p^ [1].selector := fsc$record_type;                                                                 
      mca_p^ [1].record_type := amc$undefined;                                                                
      mca_p^ [2].selector := fsc$preset_value;                                                                
      mca_p^ [2].preset_value := -1;                                                                          
                                                                                                              
      fsp$open_file (pvt [p$file].value^.file_value^, amc$segment, fa_p, NIL, mca_p, NIL, NIL,                
            file_identifier, status);                                                                         
      IF NOT status.normal THEN                                                                               
        EXIT /file_opened/;  {---->                                                                           
      IFEND;                                                                                                  
      output_file_opened := TRUE;                                                                             
                                                                                                              
      amp$get_segment_pointer (file_identifier, amc$sequence_pointer, file_pointer, status);                  
      IF NOT status.normal THEN                                                                               
        EXIT /file_opened/;  {---->                                                                           
      IFEND;                                                                                                  
      IF file_pointer.sequence_pointer = NIL THEN                                                             
        osp$set_status_abnormal (duc$dump_analyzer_id, due$nil_pointer, '', status);                          
        EXIT /file_opened/;  {---->                                                                           
      IFEND;                                                                                                  
      RESET file_pointer.sequence_pointer;                                                                    
                                                                                                              
      display_control := duv$execution_environment.output_file.display_control;                               
      display_control.line_number := display_control.page_length + 1;                                         
      address.rma_part := pvt [p$address].value^.integer_value.value;                                         
      starting_offset := address.pva_part.offset;                                                             
      byte_count := pvt [p$bytes].value^.integer_value.value;                                                 
                                                                                                              
      IF (pvt [p$address_mode].value^.keyword_value = 'PROCESS_VIRTUAL_ADDRESS') OR                           
            (pvt [p$address_mode].value^.keyword_value = 'SYSTEM_VIRTUAL_ADDRESS') THEN                       
        page_fault_encountered := FALSE;                                                                      
        skipping_page_faulted_memory := FALSE;                                                                
        some_memory_copied := FALSE;                                                                          
        invalid_segment_issued := FALSE;                                                                      
                                                                                                              
        REPEAT                                                                                                
          NEXT file_buffer_p: [[REP byte_count OF cell]] IN file_pointer.sequence_pointer;                    
          IF file_buffer_p = NIL THEN                                                                         
            osp$set_status_abnormal (duc$dump_analyzer_id, due$nil_pointer, '', status);                      
            EXIT /file_opened/;  {---->                                                                       
          IFEND;                                                                                              
          RESET file_buffer_p;                                                                                
                                                                                                              
          IF pvt [p$address_mode].value^.keyword_value = 'PROCESS_VIRTUAL_ADDRESS' THEN                       
            dup$copy_virtual_memory_pva (address.pva_part, exchange_package_p^,                               
                  pvt [p$processor].value^.integer_value.value, byte_count, TRUE, bytes_returned,             
                  file_buffer_p, access_data, status);                                                        
          ELSE                                                                                                
            dup$copy_virtual_memory_sva (address.sva_part, pvt [p$processor].value^.integer_value.value,      
                  byte_count, TRUE, bytes_returned, file_buffer_p, access_data, status);                      
          IFEND;                                                                                              
          IF NOT status.normal AND (status.condition <> due$memory_partially_avail) THEN                      
            EXIT /file_opened/;  {---->                                                                       
          IFEND;                                                                                              
                                                                                                              
          IF NOT access_data.valid_segment AND NOT invalid_segment_issued THEN                                
            invalid_segment_issued := TRUE;                                                                   
            osp$set_status_abnormal (duc$dump_analyzer_id, due$invalid_seg_trans_poss, '', local_status);     
            dup$display_message (local_status, display_control);                                              
          IFEND;                                                                                              
                                                                                                              
          page_fault_encountered := (access_data.page_fault AND NOT access_data.memory_found);                
                                                                                                              
          IF bytes_returned > 0 THEN                                                                          
            some_memory_copied := TRUE;                                                                       
            IF skipping_page_faulted_memory THEN                                                              
              skipping_page_faulted_memory := FALSE;                                                          
              osp$set_status_abnormal (duc$dump_analyzer_id, due$pages_skipped, '', local_status);            
              osp$append_status_integer (osc$status_parameter_delimiter, skip_start, 16, TRUE, local_status); 
              osp$append_status_integer (osc$status_parameter_delimiter, address.pva_part.offset - 1, 16,     
                    TRUE, local_status);                                                                      
              dup$display_message (local_status, display_control);                                            
            IFEND;                                                                                            
            byte_count := byte_count - bytes_returned;                                                        
          IFEND;                                                                                              
                                                                                                              
          IF page_fault_encountered THEN                                                                      
            address.pva_part.offset := access_data.next_page_offset;                                          
            IF NOT skipping_page_faulted_memory THEN                                                          
              skipping_page_faulted_memory := TRUE;                                                           
              skip_start := access_data.page_fault_offset;                                                    
            IFEND;                                                                                            
            RESET file_pointer.sequence_pointer TO file_buffer_p;                                             
            IF bytes_returned > 0 THEN                                                                        
              NEXT file_buffer_p: [[REP bytes_returned OF cell]] IN file_pointer.sequence_pointer;            
              IF file_buffer_p = NIL THEN                                                                     
                osp$set_status_abnormal (duc$dump_analyzer_id, due$nil_pointer, '', status);                  
                EXIT /file_opened/;  {---->                                                                   
              IFEND;                                                                                          
            IFEND;                                                                                            
            memory_skipped := access_data.next_page_offset - access_data.page_fault_offset;                   
            IF memory_skipped < byte_count THEN                                                               
              NEXT file_buffer_p: [[REP memory_skipped OF cell]] IN file_pointer.sequence_pointer;            
              byte_count := byte_count - memory_skipped;                                                      
            ELSE                                                                                              
              NEXT file_buffer_p: [[REP byte_count OF cell]] IN file_pointer.sequence_pointer;                
              byte_count := 0;                                                                                
            IFEND;                                                                                            
            IF file_buffer_p = NIL THEN                                                                       
              osp$set_status_abnormal (duc$dump_analyzer_id, due$nil_pointer, '', status);                    
              EXIT /file_opened/;  {---->                                                                     
            IFEND;                                                                                            
          IFEND;                                                                                              
        UNTIL byte_count <= 0;                                                                                
                                                                                                              
        IF page_fault_encountered THEN                                                                        
          IF skipping_page_faulted_memory THEN                                                                
            osp$set_status_abnormal (duc$dump_analyzer_id, due$pages_skipped, '', local_status);              
            osp$append_status_integer (osc$status_parameter_delimiter, skip_start, 16, TRUE, local_status);   
            osp$append_status_integer (osc$status_parameter_delimiter,                                        
                  (access_data.next_page_offset + byte_count - 1), 16, TRUE, local_status);                   
            dup$display_message (local_status, display_control);                                              
            RESET file_pointer.sequence_pointer;                                                              
            IF (skip_start - starting_offset) > 0 THEN                                                        
              NEXT file_buffer_p: [[REP skip_start - starting_offset OF cell]] IN                             
                    file_pointer.sequence_pointer;                                                            
              IF file_buffer_p = NIL THEN                                                                     
                osp$set_status_abnormal (duc$dump_analyzer_id, due$nil_pointer, '', status);                  
                EXIT /file_opened/;  {---->                                                                   
              IFEND;                                                                                          
            IFEND;                                                                                            
          IFEND;                                                                                              
          amp$set_segment_eoi (file_identifier, file_pointer, status);                                        
          IF NOT status.normal THEN                                                                           
            EXIT /file_opened/;  {---->                                                                       
          IFEND;                                                                                              
          IF some_memory_copied THEN                                                                          
            osp$set_status_abnormal (duc$dump_analyzer_id, due$incomplete_memory_copy,                        
                  ' a page fault was encountered.', status);                                                  
          ELSE                                                                                                
            osp$set_status_abnormal (duc$dump_analyzer_id, due$no_memory_copied,                              
                  ' a page fault was encountered.', status);                                                  
          IFEND;                                                                                              
        IFEND;                                                                                                
                                                                                                              
      ELSE  { address_mode = REAL_MEMORY_ACCESS                                                               
                                                                                                              
        dup$access_real_memory (byte_count, address.rma_part, memory_file_p, new_byte_size, status);          
        IF NOT status.normal AND (status.condition <> due$memory_partially_avail) THEN                        
          EXIT /file_opened/;  {---->                                                                         
        IFEND;                                                                                                
        bytes_returned := new_byte_size;                                                                      
                                                                                                              
        RESET duv$execution_environment.memory_file_p^.segment_pointer.sequence_pointer TO memory_file_p;     
        NEXT memory_file_buffer_p: [[REP bytes_returned OF cell]] IN                                          
              duv$execution_environment.memory_file_p^.segment_pointer.sequence_pointer;                      
        IF memory_file_buffer_p = NIL THEN                                                                    
          osp$set_status_abnormal (duc$dump_analyzer_id, due$nil_pointer, '', status);                        
          EXIT /file_opened/;  {---->                                                                         
        IFEND;                                                                                                
                                                                                                              
        NEXT file_buffer_p: [[REP bytes_returned OF cell]] IN file_pointer.sequence_pointer;                  
        IF file_buffer_p = NIL THEN                                                                           
          osp$set_status_abnormal (duc$dump_analyzer_id, due$nil_pointer, '', status);                        
          EXIT /file_opened/;  {---->                                                                         
        IFEND;                                                                                                
                                                                                                              
        file_buffer_p^ := memory_file_buffer_p^;                                                              
        amp$set_segment_eoi (file_identifier, file_pointer, status);                                          
        IF NOT status.normal THEN                                                                             
          EXIT /file_opened/;  {---->                                                                         
        IFEND;                                                                                                
        IF bytes_returned < byte_count THEN                                                                   
          osp$set_status_abnormal (duc$dump_analyzer_id, due$incomplete_memory_copy,                          
                ' the remaining memory is not contained in the dump.', status);                               
        IFEND;                                                                                                
      IFEND;                                                                                                  
                                                                                                              
    END /file_opened/;                                                                                        
                                                                                                              
    IF output_file_opened THEN                                                                                
      fsp$close_file (file_identifier, ignore_status);                                                        
    IFEND;                                                                                                    
    osp$disestablish_cond_handler;                                                                            
                                                                                                              
  PROCEND dup$copy_memory_command;                                                                            
MODEND dum$copy_memory_command;                                                                               
