/******************************************************************************
 *
 *                                   Mem
 *
 * This module contains the routines which control the different memory
 * operations done by CMON.
 *
 * History:
 *   +----------+------------+------------------------------------------------+
 *   |   Date   |     by     |     Description                                |
 *   +----------+------------+------------------------------------------------+
 *   |          | Coby       | Written                                        |
 *   +----------+------------+------------------------------------------------+
 *
 *****************************************************************************/


#include "cc_def.h"
#include "global_f.h"
#include "io.h"
#include "mem.h"
#ifdef MMU_SUPPORT
#   include "mmu_d.h"
#endif

/*-----------------------------------------------------------------------------
 *                                 
 *                                 Variable definitions
 * 
 *---------------------------------------------------------------------------*/

/*
 * The maximum number of bytes which can be dumped in one hexadecimal dump
 * and in one line of binary dump.
 */

#define MAX_HEX_BYTES    16
#define MAX_BIN_BYTES    256

/*
 * Define local functions
 */

private void process_lh(/* hex_addr, data, checksum, verify, response */);
private void process_bl(/* hex_addr, verify, response */);
private void bin_load  (/* data, addr, count, verify, response */);
private void process_dh(/* addr, count, port */);
private void process_db(/* addr, count, port */);
private void bin_dump  (/* data, addr, count, response */);
private void process_mm(/* addr1, addr2, hex_count, verify, response */);
private void process_mf_ms(/* addr1, addr2, hex_count, verify, response */);

/*^L*/
/*-----------------------------------------------------------------------------
 *
 *                    Mem_read__(size, addr, read_value)
 *
 * This function reads the data from addr, according to size.
 *
 *---------------------------------------------------------------------------*/

public void mem_read__(size, addr, read_value)
    char     size;
    address  addr;
    unsigned *read_value;
{

    /*
     * Read according to the length specified in the command.
     */

    switch (size) {
        case 'B':
            *read_value = * (byte *) addr;
            return;
        case 'W':
            *read_value = * (word *) addr;
            return;
        case 'D':
            *read_value = * (double_word *) addr;
    }

} /* mem_read__ */





/*-----------------------------------------------------------------------------
 *
 *           Mem_write__(size, addr, write_value, verify)
 *
 * This function write the data to addr, according to size. If verification
 * is requested, it is done.
 *
 *---------------------------------------------------------------------------*/

public void mem_write__(size, addr, write_value, verify)
    char     size;
    address  addr;
    unsigned write_value;
    boolean  verify;
{
    unsigned read_value;
    s_str    tmp_str;

    /*
     * Check the length of the value. If o.k. write it.
     */

    switch (size) {
        case 'B':
            if (write_value > MAX_UBYTE) {
                ERROR( e_syntax__);
            }
            * (byte *) addr = write_value;
            break;
        case 'W':
            if (write_value > MAX_UWORD) {
                ERROR( e_syntax__);
            }
            * (word *) addr = write_value;
            break;
        case 'D':
            * (double_word *) addr = write_value;
    }

    /*
     * If verify requested, reread the value.
     */

    if (verify) {
        mem_read__(size, addr, &read_value);
        if (read_value != write_value) {
	    strcpy (tmp_str, e_verify__);
            bin_to_hex__( addr, &tmp_str[strlen(tmp_str)], 'D');
            ERROR(tmp_str);
        }
    }

} /* mem_write__ */

/*^L*/
/*-----------------------------------------------------------------------------
 *
 *                    Pm_decode__(cmd, response)
 *
 * This function decodes and executes the print memory byte/word/double 
 * command.
 *
 *---------------------------------------------------------------------------*/

public void pm_decode__(cmd, response)
    str      cmd, response;
{ 
    s_str    hex_addr;
    unsigned addr, read_value, len;
    boolean  err;

    response[0] = '\0';

    /*
     * Get the address
     */

    get_first_arg__(&cmd[3], hex_addr, &len, S_SIZE,
                   /* accept null arg */ FALSE);
    hex_to_bin__( hex_addr, &addr, 'D');
    if (len + 3 < strlen(cmd)) {
        ERROR( e_syntax__);
    }

    /*
     * Read the value, translate it to hex and put it in the response
     */

    mem_read__(cmd[2], addr, &read_value);

    response[0] = '=';
    bin_to_hex__( read_value, &response[1], cmd[2]);

} /* pm_decode__ */

/*^L*/
/*-----------------------------------------------------------------------------
 *
 *                    Cm_decode__(cmd, response)
 *
 * This function decodes and executes the change memory byte/word/double 
 * command.
 *
 *---------------------------------------------------------------------------*/

public void cm_decode__(cmd, response)
    str      cmd, response;
{ 
    s_str    hex_addr, value;
    unsigned cur_char, write_value, len;
    address  addr;
    boolean  verify, err;

    response[0] = '\0';

    /*
     * Get the address
     */

    cur_char = 3;
    get_first_arg__(&cmd[cur_char], hex_addr, &len, S_SIZE,
                   /* accept null arg */ FALSE);
    cur_char += len;
    hex_to_bin__( hex_addr, &addr, 'D');
    /*
     * Get the value and verify parameters. Translate the value to binary.
     */

    get_value_for_change__(&cmd[cur_char], value, &verify);
    hex_to_bin__( value, &write_value, cmd[2]);

    /*
     * Write the value, verify if needed.
     */

    mem_write__(cmd[2], addr, write_value, verify);

} /* cm_decode__ */

/*^L*/
/*-----------------------------------------------------------------------------
 *
 *                    Lh_decode__(cmd, response)
 *
 * This function decodes the hexadecimal load command.
 *
 *---------------------------------------------------------------------------*/

public void lh_decode__(cmd, response)
    str      cmd, response;
{ 
    unsigned cur_char, len;
    s_str    hex_addr, checksum;
    l_str    data;
    boolean  verify, err;

    response[0] = '\0';

    /*
     * Get the address
     */

    cur_char = 2;
    get_first_arg__(&cmd[cur_char], hex_addr, &len, S_SIZE,
                   /* accept null arg */ FALSE);
    cur_char += len;

    /*
     * Get the contents and checksum. It must contain at least 4 bytes 
     * (2 contents and 2 checksum), and must contain an even number of 
     * characters (a byte is 2 hex-characters long).
     */

    get_first_arg__(&cmd[cur_char], data, &len, L_SIZE,
                   /* accept null arg */ FALSE);
    len = strlen(data);
    if (len < 4) {
        ERROR( e_syntax__);
    }
    if (BIT_ON(0, len)) {
        ERROR( e_syntax__);
    }

    strcpy(checksum, &data[len-2]);
    data[len-2] = '\0';

    /*
     * Get the verify flag on new spec (cmd is "LH ...")
     */

    if (cmd[1] == 'H'){
	get_verify_flag__(&cmd[cur_char], &verify);
    }
    else {
	verify = TRUE;
    }

    /*
     * Execute the command.
     */

    process_lh(hex_addr, data, checksum, verify);

} /* lh_decode__ */

/*^L*/
/*-----------------------------------------------------------------------------
 *
 *           Process_lh(hex_addr, data, checksum, verify)
 *
 * This function executes the hexadecimal load command.
 *
 *---------------------------------------------------------------------------*/

private void process_lh(hex_addr, data, checksum, verify)
    str      hex_addr, data, checksum;
    boolean  verify;
{
    unsigned  bin_byte, bin_checksum, temp_checksum, len, cur_byte, i;
    address   addr;
    char     tmp_char;
    boolean  err;

    /*
     * Load the data
     */

    bin_checksum = 0;    
    cur_byte     = 0;
    hex_to_bin__( hex_addr, &addr, 'D');

    while (data[cur_byte] != '\0') {
        tmp_char = data[cur_byte + 2];
	data[cur_byte + 2] = '\0';
        hex_to_bin__( &data[cur_byte], &bin_byte, 'B');
	data[cur_byte + 2] = tmp_char;
        mem_write__('B', addr, bin_byte, verify);
        bin_checksum += bin_byte;
        bin_checksum &= 0xff;

        cur_byte += 2;
        addr++;
    
    }

    /*
     * Check the checksum
     */

    hex_to_bin__( checksum, &temp_checksum, 'B');
    if (temp_checksum != bin_checksum) {
        ERROR( e_load_crc__);
    }

} /* process_lh */

/*^L*/
/*-----------------------------------------------------------------------------
 *
 *                    Bl_decode__(cmd, response)
 *
 * This function decodes the binary load command.
 *
 *---------------------------------------------------------------------------*/

public void bl_decode__(cmd, response)
    str      cmd, response;
{ 
    unsigned cur_char, len;
    s_str    hex_addr, hex_lines;
    boolean  verify, err;

    response[0] = '\0';

    /*
     * Get the address
     */

    cur_char = 3;
    get_first_arg__(&cmd[cur_char], hex_addr, &len, S_SIZE,
                   /* accept null arg */ FALSE);
    cur_char += len;

    /*
     * Get the verify flag

    get_verify_flag__(&cmd[cur_char], &verify);
     */

    /*
     * Execute the command.
     */

    process_bl(hex_addr, /*verify*/ TRUE);

} /* bl_decode__ */

/*^L*/
/*-----------------------------------------------------------------------------
 *
 *             Process_bl(hex_addr, verify)
 *
 * This function executes the binary load command.
 *
 *---------------------------------------------------------------------------*/

private void process_bl(hex_addr, verify)
    str      hex_addr;
    boolean  verify;
{
    unsigned count, i;
    vl_str   line;
    address  addr;
    boolean  err;

    /*
     * Translate the address to binary. Actually the address isn't used,
     * and just checked for syntax.
     */

    hex_to_bin__(hex_addr, &addr, 'D');
    /*
     * Initate sending of data by sending a ready prompt
     */
    write_message__(ready_prompt__);
    /*
     * Loop on the load commands until a end load command is reached.
     */

    while (read_bl_line__(line, &addr, &count )){
        bin_load(line, addr, count, verify);
        write_message__(ready_prompt__);
    }

} /* process_bl */

/*^L*/
/*-----------------------------------------------------------------------------
 *
 *               Bin_load(data, addr, count, verify)
 *
 * This function executes one line of the binary load command.
 *
 *---------------------------------------------------------------------------*/

private void bin_load(data, addr, count, verify)
    str      data;
    address  addr;
    unsigned count;
    boolean  verify;
{
    unsigned len, bin_byte, cur_byte, i;
    s_str    hex_addr;


    bcopy(data,addr,count);
    if (verify){
        if (bcmp(data,addr,count) != 0){
            ERROR( e_verify__);
        }
    }

} /* bin_load */

/*^L*/
/*-----------------------------------------------------------------------------
 *
 *                    D_decode__(cmd, response)
 *
 * This function decodes the hexadecimal and binary dump commands.
 *
 *---------------------------------------------------------------------------*/

public void d_decode__(cmd, response)
    str      cmd, response;
{ 
    unsigned cur_char, len, addr, count;
    int      port;
    s_str    hex_addr, hex_count;

    response[0] = '\0';

    /*
     * Get the port (if specified), and address 
     */

    cur_char = 2;
    get_first_arg__(&cmd[cur_char], hex_addr, &len, S_SIZE,
                   /* accept null arg */ FALSE);
    port = CUR_PORT;
    if (hex_addr[0] == 'T') {
        if ((hex_addr[1] != 'R') OR (len != 3)) {
            ERROR( e_syntax__);
        }
        switch (hex_addr[2]) {
            case '1':
                port = 0;
                break;
            case '2':
                port = 1;
                break;
            case 'L':
                port = LAN_PORT;
                break;
            default :
                ERROR( e_syntax__);
        }
        cur_char += 3;
        get_first_arg__(&cmd[cur_char], hex_addr, &len, S_SIZE,
	               /* accept null arg */ FALSE);
    }
    cur_char += len;

    hex_to_bin__( hex_addr, &addr, 'D');

    /*
     * Get the number of bytes
     */

    get_first_arg__(&cmd[cur_char], hex_count, &len, S_SIZE,
                   /* accept null arg */ FALSE);

    if (hex_count[0] != '*' ) {     /* Check if its binary or hex format */
        hex_to_bin__( hex_count, &count, 'D');
        process_dh(addr, count, port); /* Dump hex format */
    }
    else {
	cur_char += len;
        get_first_arg__(&cmd[cur_char], hex_count, &len, S_SIZE,
                   /* accept null arg */ FALSE);
        hex_to_bin__( hex_count, &count, 'D');
        process_db(addr, count, port); /* Dump Binary format */
    }



} /* d_decode__ */

/*^L*/
/*-----------------------------------------------------------------------------
 *
 *                  Process_dh(addr, count, port)
 *
 * This function executes the hexadecimal dump command.
 *
 *---------------------------------------------------------------------------*/

private void process_dh(addr, count, port)
    unsigned addr;
    unsigned count;
    int	     port;
{
    vl_str   output_line;
    s_str    temp_str, hex_addr;
    unsigned bin_byte, checksum, len, cur_byte, i;

    while (count > 0) {
        /*
         * Set the number of characters
         */
        if (count > MAX_HEX_BYTES) {
             len = MAX_HEX_BYTES;
        }
	else {
	     len = count; 
	}
	count -= len;

	bin_to_hex__(addr, hex_addr, 'D');

        /*
         * Start buildng the output line
         */
    	strcpy(output_line, "L ");
    	strcpy(&output_line[2], hex_addr);
    	strcat(output_line, " ");

    	/*
     	 * Dump the data
     	 */

    	checksum = 0;    
    	cur_byte = strlen(output_line);
    	for (i = 0 ; i < len; i++ ){
        	mem_read__('B', addr, &bin_byte);
        	bin_to_hex__( bin_byte, temp_str, '2');
        	strcpy(&output_line[cur_byte], temp_str);

        	checksum = (checksum + bin_byte) & 0xff;
        	cur_byte += 2;
        	addr++;
	}
 
    	/*
    	 * Add the checksum
    	 */
    	bin_to_hex__( checksum, temp_str, '2');
    	strcpy(&output_line[cur_byte], temp_str);

    	/*
    	 * Write the line. We can't return it since it has to be written to a 
    	 * specific port.
    	 */
    	write_dump_line__(port, output_line);

    }
} /* process_dh */


/*-----------------------------------------------------------------------------
 *
 *              Process_db(addr, count, port)
 *
 * This function executes the binary dump command.
 *
 *---------------------------------------------------------------------------*/

private void process_db(addr, count, port)
    unsigned addr, count;
    int port;
{
    vl_str   output_line;
    s_str    hex_addr;
    unsigned cur_char, len;
    
    while (count > 0) {
        /*
         * Set the number of characters
         */
        if (count > MAX_HEX_BYTES) {
             len = MAX_HEX_BYTES;
        }
	else {
	     len = count; 
	}
	count -= len;

	bin_to_hex__(addr, hex_addr, 'D');
    	/*
    	 * Send opening line
    	 */
    	output_line[0] = 'L';
    	output_line[1] = ' ';
    	strcpy(&output_line[2], hex_addr);
    	strcat(output_line, " * ");
    	cur_char = strlen(output_line);

        /*
         * Write number of data bytes
         */
        bin_to_hex__(len, &output_line[cur_char],  'D');
        cur_char = strlen(output_line);

        /*
         * Start binary data with <CTRL-L>
         */
        output_line[cur_char++] = CTRL_L;

        /*
         * Add the data to the output line
         */
        bcopy (addr,&output_line[cur_char], len);

        /*
         * Terminate binary data with <CTRL-L>
         */
        output_line[cur_char+len] = CTRL_L;
        output_line[cur_char+len+1] = '\0';

        /*
         * Write the line. We can't return it since it has to be written to a 
         * specific port.
         */
        write_dump_line__(port, output_line);

	addr += len;
    }

} /* process_db */



/*^L*/
/*-----------------------------------------------------------------------------
 *
 *                    M_decode__(cmd, response)
 *
 * This function decodes the memory move, fill and search commands.
 *
 *---------------------------------------------------------------------------*/

public void m_decode__(cmd, response)
    str cmd, response;
{ 
    unsigned cur_char, len;
    s_str    addr1, addr2, value;
    boolean  verify, err;

    response[0] = '\0';

    /*
     * Get the addresses and value
     */

    cur_char = 3;
    get_first_arg__(&cmd[cur_char], addr1, &len, S_SIZE,
                   /* accept null arg */ FALSE);

    cur_char += len;
    get_first_arg__(&cmd[cur_char], addr2, &len, S_SIZE,
                   /* accept null arg */ FALSE);
    cur_char += len;
    get_first_arg__(&cmd[cur_char], value, &len, L_SIZE,
                   /* accept null arg */ FALSE);
    cur_char += len;

    /*
     * Get the verify flag
     */

    get_verify_flag__(&cmd[cur_char], &verify);

    /*
     * Execute the command.
     */

    switch (cmd[1]) {
        case 'M':
            process_mm(addr1, addr2, value, verify);
            return;
        case 'F':
            process_mf_ms('B',addr1, addr2, value, verify, TRUE, response);
            return;
        case 'S':
            process_mf_ms('B',addr1, addr2, value, verify, FALSE,response);
    }

} /* m_decode__ */

/*^L*/

/*-----------------------------------------------------------------------------
 *
 *                F_m_sr_decode__(cmd, response)
 *
 * This function decodes the memory fill command old spec
 *
 *---------------------------------------------------------------------------*/
 
public void f_m_sr_decode__(cmd, response)
    str            cmd, response;
{
    s_str   addr1, addr2, data, tmp_str;
    char    ch2, size;
    boolean verify, err;
    unsigned len, cur_char;
    
    /*
     * Get commands arguments.
     */
     
    if (cmd[0] == 'S') {
        cur_char = 2;
    }
    else {
        cur_char = 1;
    }
    get_first_arg__(&cmd[cur_char], addr1, &len, S_SIZE,
                   /* accept null arg */ FALSE);
    cur_char += len;
    get_first_arg__(&cmd[cur_char], addr2, &len, S_SIZE,
                   /* accept null arg */ FALSE);
    cur_char += len;
    get_first_arg__(&cmd[cur_char], data, &len, S_SIZE,
                   /* accept null arg */ FALSE);
    cur_char += len;
    
    /*
     * Default data size BYTE
     * Default verify
     */
     
    size = 'B';
    verify = TRUE;
    
    /*
     * Try to get up to two charcters flag
     */

    get_first_arg__(&cmd[cur_char], tmp_str, &len, S_SIZE,
                   /* accept null arg */ TRUE);
    if (len != 0) {
        cur_char += len;
        if (strchr("BWD",tmp_str[0]) != (char *) NULL) {
            size = tmp_str[0];
            if  (cmd[0] == 'F') {
                get_first_arg__(&cmd[cur_char], tmp_str, &len, S_SIZE,
		               /* accept null arg */ TRUE);
                cur_char += len;
            }
        }
    }
    switch (cmd[0]) {
        
        /*
         *  Fill memory
         */
        case 'F':
            if (tmp_str[0] == 'N') 
                verify = FALSE;
            process_mf_ms (size, addr1, addr2, data, verify, TRUE,response);
            break;
        
        /*
         * Move memory
         */
        case 'M':
            if (tmp_str[0] == 'N')
                verify = FALSE;
            process_mm (addr1, addr2, data, verify);
            break;
        
        /*
         * Search memory
         */
        case 'S':
            process_mf_ms(size, addr1, addr2, data, verify, FALSE,response);
    } /* switch */
    

} /* f_m_sr_decode__ */



/*^L*/
/*-----------------------------------------------------------------------------
 *
 *           Process_mm(addr1, addr2, hex_count, verify)
 *
 * This function executes the memory move command.
 *
 *---------------------------------------------------------------------------*/

private void process_mm(addr1, addr2, hex_count, verify)
    str      addr1, addr2, hex_count;
    boolean  verify;
{
    unsigned i,count, data, read_value;
    address  src_addr, dst_addr;
    s_str    tmp_str;

    /*
     * Translate the count to binary
     */

    hex_to_bin__( hex_count, &count, 'D');
    hex_to_bin__( addr1, &src_addr, 'D');
    hex_to_bin__( addr2, &dst_addr, 'D');
    
    /*
     * Move the data
     */
    if (verify) {
	for (i = 0 ; i < count; i ++){
            data = * (byte *) src_addr;
            * (byte *) dst_addr = data;
            read_value = * (byte *) dst_addr;
	    if (read_value != data) {
		strcpy (tmp_str, e_verify__);
		bin_to_hex__( dst_addr, &tmp_str[strlen(tmp_str)], 'D');
		ERROR(tmp_str);
	    }
	    src_addr++;
	    dst_addr++;
	}
    }
    else { /* not verify */
	for (i = 0 ; i < count; i ++){
            data = * (byte *) src_addr;
            * (byte *) dst_addr = data;
	    src_addr++;
	    dst_addr++;
	}
    }
} /* process_mm */

/*^L*/

/*-----------------------------------------------------------------------------
 *
 *           Process_mf_ms(size, addr1, addr2, data, verify, fill,response)
 *
 * This function executes the memory fill and memory search commands.
 * If fill is TRUE this is a fill command, otherwise - search.
 *
 *---------------------------------------------------------------------------*/

private void process_mf_ms(size, addr1, addr2, data, verify, fill,response)
    char    size;
    str            addr1, addr2, data, response;
    boolean verify;
{
    address        cur_addr, high_addr;
    boolean        err;
    unsigned        bin_data, cur_value, read_value, num_of_byte;
    s_str	    tmp_str;
    
    /*
     * Translate string parameters to binary
     */
    hex_to_bin__( data, &bin_data, 'D');
    hex_to_bin__( addr1, &cur_addr, 'D');
    hex_to_bin__(addr2, &high_addr, 'D');
    switch (size) {
        case 'B':
            if (bin_data > MAX_UBYTE) {
                ERROR( e_syntax__);
            }
            num_of_byte = 1;
            break;
        case 'W':
            if (bin_data > MAX_UWORD) {
                ERROR( e_syntax__);
            }
            num_of_byte = 2;
            break;
        case 'D':
            num_of_byte = 4;
            break;
        default :
            ERROR( e_syntax__);
    }
    if (fill) {
	if (verify) {
	    switch (size) {
		case 'B':
		    for (;cur_addr <= high_addr;cur_addr += num_of_byte) {
			* (byte *) cur_addr = bin_data;
			read_value = * (byte *) cur_addr;
			if (read_value != bin_data) {
			    strcpy (tmp_str, e_verify__);
			    bin_to_hex__( cur_addr, &tmp_str[strlen(tmp_str)], 'D');
			    ERROR(tmp_str);
			}
		    }
	    	    break;
		case 'W':
		    for (;cur_addr <= high_addr;cur_addr += num_of_byte) {
			* (word *) cur_addr = bin_data;
			read_value = * (word *) cur_addr;
			if (read_value != bin_data) {
			    strcpy (tmp_str, e_verify__);
			    bin_to_hex__( cur_addr, &tmp_str[strlen(tmp_str)], 'D');
			    ERROR(tmp_str);
			}
		    }
		    break;
		case 'D':
		    for (;cur_addr <= high_addr;cur_addr += num_of_byte) {
			* (double_word *) cur_addr = bin_data;
			read_value = * (double_word *) cur_addr;
			if (read_value != bin_data) {
			    strcpy (tmp_str, e_verify__);
			    bin_to_hex__( cur_addr, &tmp_str[strlen(tmp_str)], 'D');
			    ERROR(tmp_str);
			}
		    }
	    } /* switch(size) */
	}
	else { /* no verify */
	    switch (size) {
		case 'B':
		    for (;cur_addr <= high_addr;cur_addr += num_of_byte) {
			* (byte *) cur_addr = bin_data;
		    }
	    	    break;
		case 'W':
		    for (;cur_addr <= high_addr;cur_addr += num_of_byte) {
			* (word *) cur_addr = bin_data;
		    }
		    break;
		case 'D':
		    for (;cur_addr <= high_addr;cur_addr += num_of_byte) {
			* (double_word *) cur_addr = bin_data;
		    }
	    }
	}
    }
    else { /* Search */
	switch (size) {
	    case 'B':
		for(;cur_addr <= high_addr; cur_addr++) {
		    cur_value = * (byte *) cur_addr;
		    if (cur_value == bin_data) {
			response[0] = '=';
			bin_to_hex__( (unsigned) cur_addr, &response[1], 'D');
			return;
		    }
		}
	    	break;
	    case 'W':
		for(;cur_addr <= high_addr; cur_addr++) {
		    cur_value = * (word *) cur_addr;
		    if (cur_value == bin_data) {
			response[0] = '=';
			bin_to_hex__( (unsigned) cur_addr, &response[1], 'D');
			return;
		    }
		}
		break;
	    case 'D':
		for(;cur_addr <= high_addr; cur_addr++) {
		    cur_value = * (double_word *) cur_addr;
		    if (cur_value == bin_data) {
			response[0] = '=';
			bin_to_hex__( (unsigned) cur_addr, &response[1], 'D');
			return;
		    }
		}
        } /* switch(size) */
	strcpy(response, e_search_failed__);
    }
} /* process_mf_ms */

/*^L*/
