/*********************************************************************
*
*	TITLE:	RMXFUNCS
*
*	DATE:	10-05-90
*
*	ABSTRACT: This module contains functions for the sub menu options
*             for the DOSRMX Real Time Extensions demo program.
*
*
*   MODIFIED: 
*
***********************************************************************/

/*
 *			 INTEL CORPORATION PROPRIETARY INFORMATION
 *
 *		  This software is supplied under the terms of a 
 *		  license agreement or nondisclosure agreement with
 *		  Intel Corporation and may not be copied or disclosed
 *		  except in accordance with the terms of that agreement.
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <rmxc.h>
#include <rmxerr.h>

#include "rwdosrte.h"
#include "demoutil.h"

#define TRUE        0xff
#define FALSE       0x00
#define WAITFOREVER 0xffff
#define NOWAITING   0x0
#define fifoobjmbx  0
#define fifodatmbx  0x20
#define STRINGLEN   128
#define SixtyFourK  0x10000

/* get object literals */

#define fifo            0
#define objmailboxtype  1
#define datmailboxtype  2
#define descriptortype  3
#define semaphoretype   4
#define segmenttype     6

/* rmx types returned by rqgettype */

#define rmxjobtype      1
#define rmxtasktype     2
#define rmxmbxtype      3
#define rmxsemtype      4
#define rmxregtype      5
#define rmxsegtype      6
#define rmxexttype      7


typedef struct rmxstring {
	BYTE  numb_char;
	char string[STRINGLEN];
} RMXSTRING;


extern TOKEN my_job; /* this jobs token used to catalogue the created
						objects under */

/* RMX type strings */

static char *rmx_type_ptr[7] = {"JOB",
								"TASK",
								"MAILBOX",
								"SEMAPHORE",
								"REGION",
								"SEGMENT",
								"EXTENSION"};


static char send_obj_msg[] = {"\n\n\n"
"                        SEND OBJECT TO MAILBOX\n"
"                        ======================\n\n"};

static char recv_obj_msg[] = {"\n\n\n"
"                        RECEIVE OBJECT FROM MAILBOX\n"
"                        ===========================\n\n"};

static char send_dat_msg[] = {"\n\n\n"
"                        SEND DATA TO MAILBOX\n"
"                        ====================\n\n"};

static char recv_dat_msg[] = {"\n\n\n"
"                        RECEIVE DATA FROM MAILBOX\n"
"                        =========================\n\n"};

static char send_uns_msg[] = {"\n\n\n"
"                        SEND UNITS TO A SEMAPHORE\n"
"                        =========================\n\n"};

static char recv_uns_msg[] = {"\n\n\n"
"                        RECEIVE UNITS FROM A SEMAPHORE\n"
"                        ==============================\n\n"};

static char cret_seg_msg[] = {"\n\n\n"
"                        CREATE PVAM SEGMENT\n"
"                        ===================\n\n"};

static char delt_seg_msg[] = {"\n\n\n"
"                        DELETE PVAM SEGMENT\n"
"                        ===================\n\n"};

static char cret_des_msg[] = {"\n\n\n"
"                        CREATE DESCRIPTOR\n"
"                        =================\n\n"};

static char delt_des_msg[] = {"\n\n\n"
"                        DELETE DESCRIPTOR\n"
"                        =================\n\n"};

static char disp_seg_msg[] = {"\n\n\n"
"                        DISPLAY SEGEMENT\n"
"                        ================\n\n"};

static char copy_pvm_msg[] = {"\n\n\n"
"                        COPY PVAM TO REAL MODE MEMORY\n"
"                        =============================\n\n"};

static char copy_rel_msg[] = {"\n\n\n"
"                        COPY REAL MODE TO PVAM MEMORY\n"
"                        =============================\n\n"};

static char mbx_req_msg[] = {"\n Enter the mailbox name (10 characters max) :- "};

static char sph_req_msg[] = {"\n Enter the semaphore name (10 characters max) :- "};

static char seg_req_msg[] = {"\n Enter the segment name (10 characters max) :- "};

static char des_req_msg[] = {"\n Enter the descriptor name (10 characters max) :- "};

static char obj_req_msg[] = {"\n\n"
"Enter the object name to be sent (10 characters max) :- "};

static char nul_message[] = {0};

static char error_name_no_obj[] = "ERROR - name is cataloged for an invalid object\n";

static char no_obj_waiting[] = "E$TIME - No objects waiting at the mailbox.\n\n";

static char mbx_not_found[] = "ERROR - unable to locate the mailbox token.\n\n";

static char sph_not_found[] = "ERROR - unable to locate the semaphore token.\n\n";

static char seg_not_found[] = "ERROR - unable to locate the segment token.\n\n";

static char too_much_text[] = "ERROR - Too many characters, 127 max.\n\n";

static char no_data_waiting[] = "E$TIME - No data waiting at the mailbox.\n\n";

/******************************************************************
*
*    TITLE: SEND_OBJECT_TO_MAILBOX
*
*    CALLING SEQUENCE: send_object_to_mailbox();
*
*    INTERFACE VARIABLES: NONE
*
*    PARAMETERS:
*
*    GLOBAL VARIABLES:
*
*    ABSTRACT:
*     Sends an RMX  segment to a  named mailbox, if  the mailbox or
*     segment are  not present it creates  them and catalogues them
*     under their names in the my_job directory.
*
******************************************************************/
send_object_to_mailbox()
{
TOKEN mbx_tkn;
TOKEN obj_tkn;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
}  mbx_params;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
DWORD segsize;
} obj_params;
WORD except;

	clear_screen();

	printf("%s",send_obj_msg);

	mbx_params.name.numb_char = read_cat_name(mbx_req_msg,&mbx_params.name.string[2]);

	/*
	** Prefix the name with D? and see if it is catalogued.
	*/
	mbx_params.name.numb_char += 2; /* string length */
	mbx_params.name.string[0] = 'D';
	mbx_params.name.string[1] = '?';

	mbx_params.objecttype = objmailboxtype;
	mbx_params.objdir = my_job;

	mbx_tkn = get_rmx_object(&mbx_params,&except);

	/* if mailbox doesn't exist create it */

	if ( except == ETIME) mbx_tkn = create_object(&mbx_params,&except);

	else if (except == EEXIST) error_message(error_name_no_obj);

	else if (except !=EOK) /* all other exception print the number only */
	{
		printf("\n\nException code %04XH, looking up the mailbox\n",except);
		error_message(nul_message); /* wait for CR, no message */
	}

	if (except == EOK)
	{
		obj_params.name.numb_char = read_cat_name(obj_req_msg,&obj_params.name.string[2]);

		obj_params.name.numb_char += 2; /* string length */
		obj_params.name.string[0] = 'D';
		obj_params.name.string[1] = '?';

		obj_params.objecttype = descriptortype;

		/* name length plus char count and null character */

		obj_params.segsize = obj_params.name.numb_char + 2;
		obj_params.objdir = my_job;

		obj_tkn = get_rmx_object(&obj_params,&except);

		if (except != EOK) /* not a descriptor check for segment */
		{
			obj_params.objecttype = segmenttype;

			obj_tkn = get_rmx_object(&obj_params,&except);
		}

		if (except == ETIME) /* doesn't already, exist create it */
		{
			printf("\nEnter the Segment size :- ");
#ifdef DOS
			scanf("%lx",&obj_params.segsize);
#else
			scanf("%x",&obj_params.segsize);
#endif
			while(getchar() !='\n') ;

			obj_params.segsize += (obj_params.name.numb_char + 2);

			obj_tkn = create_object(&obj_params,&except);

			if (except == EOK)
			{
#ifdef DOS
				rqewritesegment(&obj_params.name,obj_tkn,(DWORD)0,
								(WORD)(obj_params.name.numb_char + 2),&except);

#else
				memcpy((buildptr(obj_tkn,0)),
						&obj_params.name,
						(obj_params.name.numb_char + 2));
#endif
			}
		}
		else if (except == EEXIST) error_message(error_name_no_obj);

		else if (except !=EOK) /* all other exception print the number only */
		{
			printf("\n\nException code %04XH, looking up the object\n",except);
			error_message(nul_message); /* wait for CR, no message */
		}

		if (except == EOK)
		{
			rqsendmessage(mbx_tkn,obj_tkn,0,&except);

			if (except !=EOK)
			{
				printf("\n\nRQSENDMESSAGE of object failed exception is %04XH\n",
                       except);
				error_message(nul_message); /* wait for CR, no message */
			}
			else
			{
				printf("\n\nSend object successfully completed\n");
				error_message(nul_message); /* wait for CR, no message */
			}
		}
	}
}

/******************************************************************
*
*    TITLE: RECEIVE_OBJECT_FROM_MAILBOX
*
*    CALLING SEQUENCE: receive_object_from_mailbox();
*
*    INTERFACE VARIABLES: NONE
*
*    PARAMETERS:
*
*    GLOBAL VARIABLES:
*
*    ABSTRACT:
*     Receives an RMX object from a named mailbox, if the mailbox
*     doesn't exist an error is printed.
*
******************************************************************/
receive_object_from_mailbox()
{
RMXSTRING far * namptr;
TOKEN response;
TOKEN mbx_tkn;
TOKEN obj_tkn;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
}  mbx_params;
WORD objtype;
RMXSTRING text_buff;
DWORD segsize;
WORD except;

	clear_screen();

	printf("%s",recv_obj_msg);

	mbx_params.name.numb_char = read_cat_name(mbx_req_msg,&mbx_params.name.string[2]);

	/*
	** Prefix the name with D? and see if it is catalogued.
	*/
	mbx_params.name.numb_char += 2; /* string length */
	mbx_params.name.string[0] = 'D';
	mbx_params.name.string[1] = '?';

	mbx_params.objecttype = objmailboxtype;
	mbx_params.objdir = my_job;

	mbx_tkn = get_rmx_object(&mbx_params,&except);

	if (except == ETIME) error_message(mbx_not_found);

	else if (except == EEXIST) error_message(error_name_no_obj);

	else if (except !=EOK) /* all other exception print the number only */
	{
		printf("\n\nException code %04XH, looking up the mailbox\n",except);
		error_message(nul_message); /* wait for CR, no message */
	}
	else if (except == EOK)
	{
		obj_tkn = rqreceivemessage(mbx_tkn,NOWAITING,&response,&except);

		if (except == ETIME) error_message(no_obj_waiting);

		else if (except != EOK)
		{
			printf("\n\nException code %04XH, from RQRECEIVEMESSAGE system call\n",except);
			error_message(nul_message); /* wait for CR, no message */
		}
		else if (except == EOK)
		{
			/* Received an object now display it some way */
			objtype = rqgettype(obj_tkn,&except);

			if (except == EOK)
			{
				if (objtype == rmxsegtype)
				{
					segsize = rqgetsize(obj_tkn,&except);

#ifdef RMX
					namptr = buildptr(obj_tkn,0); /* point to segment */
#else
					namptr = &text_buff;

					rqereadsegment(obj_tkn,(DWORD)0,&text_buff,
									(WORD)(segsize<129?segsize:129),&except);
#endif

					if (segsize == 0) segsize = SixtyFourK;

					if (checkseg(obj_tkn,segsize) == TRUE)
						printf("\n\nThe received object is a segment, name %s\n",
															&namptr->string[2]);
					else
					{
						printf("\n\nThe received object is a descriptor,");
						printf(" name unknown, value %04XH\n",(WORD)obj_tkn);
					}
					error_message(nul_message); /* wait for CR, no message */
				}
				else
				{
					printf("\n\nThe object token value received is %04XH, ",
                           (WORD)obj_tkn);
					if (objtype <= rmxexttype)
						printf("RMX type %s\n",rmx_type_ptr[objtype]);
					else
						printf("RMX type %04XH\n",objtype);
					error_message(nul_message); /* wait for CR, no message */
				}
			}
			else
			{
				printf("\n\nException code %04XH, from RQGETTYPE system call\n",
                       except);
				error_message(nul_message); /* wait for CR, no message */
			}
		}
	}
}

/******************************************************************
*
*    TITLE: SEND_DATA_TO_MAILBOX
*
*    CALLING SEQUENCE: send_data_to_mailbox();
*
*    INTERFACE VARIABLES: NONE
*
*    PARAMETERS:
*
*    GLOBAL VARIABLES:
*
*    ABSTRACT:
*     Sends a string entered from the keyboard to a  named mailbox,
*     if  the mailbox is not present it createsthe mailbox and
*     catalogues the under its name in the my_job directory.
*
******************************************************************/
send_data_to_mailbox()
{
TOKEN mbx_tkn;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
}  mbx_params;
RMXSTRING text_buffer;
WORD except;

	clear_screen();

	printf("%s",send_dat_msg);

	mbx_params.name.numb_char = read_cat_name(mbx_req_msg,&mbx_params.name.string[2]);

	/*
	** Prefix the name with D? and see if it is catalogued.
	*/
	mbx_params.name.numb_char += 2; /* string length */
	mbx_params.name.string[0] = 'D';
	mbx_params.name.string[1] = '?';

	mbx_params.objecttype = datmailboxtype;
	mbx_params.objdir = my_job;

	mbx_tkn = get_rmx_object(&mbx_params,&except);

	/* if mailbox doesn't exist create it */

	if ( except == ETIME) mbx_tkn = create_object(&mbx_params,&except);

	else if (except == EEXIST) error_message(error_name_no_obj);

	else if (except !=EOK) /* all other exception print the number only */
	{
				printf("\n\nException code %04XH, looking up the mailbox\n",except);
				error_message(nul_message); /* wait for CR, no message */
	}

	if (except == EOK)
	{
		printf("\nEnter the text to be sent via the mailbox (127 MAX)\n\n :-");
		text_buffer.numb_char = 0;
		while(((text_buffer.numb_char < (STRINGLEN - 1)) && 
			(text_buffer.string[text_buffer.numb_char] = getchar()) !='\n'))
											text_buffer.numb_char++;

		if (text_buffer.numb_char < (STRINGLEN - 1))
		{
			text_buffer.string[text_buffer.numb_char] = 0; /* terminate string */

			rqsenddata(mbx_tkn,&text_buffer,(text_buffer.numb_char + 1),&except);

			if (except !=EOK)
			{
				printf("\n\nRQSENDMESSAGE of data failed exception is %04XH\n",
                       except);
				error_message(nul_message); /* wait for CR, no message */
			}
			else
			{
				printf("\n\nSend data successfully completed\n");
				error_message(nul_message); /* wait for CR, no message */
			}
		}
		else
        { /* purge buffer */

    		while((text_buffer.string[text_buffer.numb_char] = getchar()) !='\n') ;

            error_message(too_much_text);
        }
	}
}

/******************************************************************
*
*    TITLE: RECEIVE_DATA_FROM_MAILBOX
*
*    CALLING SEQUENCE: receive_data_from_mailbox();
*
*    INTERFACE VARIABLES: NONE
*
*    PARAMETERS:
*
*    GLOBAL VARIABLES:
*
*    ABSTRACT:
*     Receives a string from the named mailbox and displays it on the
*     screen. If the mailbox doesn't exist an error is reported.
*
******************************************************************/
receive_data_from_mailbox()
{
TOKEN mbx_tkn;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
}  mbx_params;
RMXSTRING text_buffer;
WORD actual;
WORD except;

	clear_screen();

    printf("%s",recv_dat_msg);

	mbx_params.name.numb_char = read_cat_name(mbx_req_msg,&mbx_params.name.string[2]);

	/*
	** Prefix the name with D? and see if it is catalogued.
	*/
	mbx_params.name.numb_char += 2; /* string length */
	mbx_params.name.string[0] = 'D';
	mbx_params.name.string[1] = '?';

	mbx_params.objecttype = datmailboxtype;
	mbx_params.objdir = my_job;

	mbx_tkn = get_rmx_object(&mbx_params,&except);

	if (except == ETIME) error_message(mbx_not_found);

	else if (except == EEXIST) error_message(error_name_no_obj);

	else if (except !=EOK) /* all other exception print the number only */
	{
		printf("\n\nException code %04XH, looking up the mailbox\n",except);
		error_message(nul_message); /* wait for CR, no message */
	}
	else if (except == EOK)
	{
		actual = rqreceivedata(mbx_tkn,&text_buffer,NOWAITING,&except);

		if (except == ETIME) error_message(no_data_waiting);

		else if (except != EOK)
		{
			printf("\n\nException code %04XH, from RQRECEIVEDATA system call\n",except);
			error_message(nul_message); /* wait for CR, no message */
		}
		else if (except == EOK)
		{
			printf("\n\nThe data received was %d bytes long\nand contained a text",
					(text_buffer.numb_char + 1));
			printf(" message as follows :- \n\n%s\n",&text_buffer.string[0]);
			error_message(nul_message); /* wait for CR, no message */
		}
	}
}

/******************************************************************
*
*    TITLE: SEND_UNITS_TO_SEMAPHORE
*
*    CALLING SEQUENCE: send_units_to_semaphore();
*
*    INTERFACE VARIABLES: NONE
*
*    PARAMETERS:
*
*    GLOBAL VARIABLES:
*
*    ABSTRACT:
*     Sends a requested number of units to a named semaphore, if the
*     semaphore doesn't exist then it is created and catalogued under
*     the name in the my_job directory.
*
******************************************************************/
send_units_to_semaphore()
{
TOKEN sph_tkn;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
}  sph_params;
WORD units;
WORD except;

	clear_screen();

	printf("%s",send_uns_msg);

	sph_params.name.numb_char = read_cat_name(sph_req_msg,&sph_params.name.string[2]);

	/*
	** Prefix the name with D? and see if it is catalogued.
	*/
	sph_params.name.numb_char += 2; /* string length */
	sph_params.name.string[0] = 'D';
	sph_params.name.string[1] = '?';

	sph_params.objecttype = semaphoretype;
	sph_params.objdir = my_job;

	sph_tkn = get_rmx_object(&sph_params,&except);

	/* if mailbox doesn't exist create it */

	if ( except == ETIME) sph_tkn = create_object(&sph_params,&except);

	else if (except == EEXIST) error_message(error_name_no_obj);

	else if (except !=EOK) /* all other exception print the number only */
	{
				printf("\n\nException code %04XH, looking up the semphore\n",except);
				error_message(nul_message); /* wait for CR, no message */
	}

	if (except == EOK)
	{
		printf("\n\nEnter the number of units to be sent (max 10) :- ");
#ifdef DOS
		scanf("%u",&units); /* read in number of units, unsigned */
#else
		scanf("%hu",&units); /* read in number of units, unsigned */
#endif
   		while(getchar() !='\n') ;

		if (units <= 10)
		{
			rqsendunits(sph_tkn,units,&except);

			if (except == ELIMIT)
			{
				printf("\n\nSemaphore is full unable to send your units.\n");
				error_message(nul_message); /* wait for CR, no message */
			}
			else if (except !=EOK)
			{
				printf("\n\nRQSENDUNITS failed exception is %04XH\n",except);
				error_message(nul_message); /* wait for CR, no message */
			}
			else
			{
				printf("\n\nSend units successfully completed\n");
				error_message(nul_message); /* wait for CR, no message */
			}
		}
		else
		{
			printf("\n\nToo many units for the semaphore.\n");
			error_message(nul_message);
		}
	}
}

/******************************************************************
*
*    TITLE: RECEIVE_UNITS_FROM_SEMAPHORE
*
*    CALLING SEQUENCE: receive_units_from_semaphore();
*
*    INTERFACE VARIABLES: NONE
*
*    PARAMETERS:
*
*    GLOBAL VARIABLES:
*
*    ABSTRACT:
*     receives a requested number of units from a named semaphore, if the
*     semaphore doesn't exist an error message is printed. The number
*     of units remaining are printed on the screen.
*
******************************************************************/
receive_units_from_semaphore()
{
TOKEN sph_tkn;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
}  sph_params;
WORD actual;
WORD units;
WORD except;

	clear_screen();

    printf("%s",recv_uns_msg);

	sph_params.name.numb_char = read_cat_name(sph_req_msg,&sph_params.name.string[2]);

	/*
	** Prefix the name with D? and see if it is catalogued.
	*/
	sph_params.name.numb_char += 2; /* string length */
	sph_params.name.string[0] = 'D';
	sph_params.name.string[1] = '?';

	sph_params.objecttype = semaphoretype;
	sph_params.objdir = my_job;

	sph_tkn = get_rmx_object(&sph_params,&except);

	if (except == ETIME) error_message(sph_not_found);

	else if (except == EEXIST) error_message(error_name_no_obj);

	else if (except !=EOK) /* all other exception print the number only */
	{
		printf("\n\nException code %04XH, looking up the semaphore\n",except);
		error_message(nul_message); /* wait for CR, no message */
	}
	else if (except == EOK)
	{
		printf("\n\nEnter the number of units to be sent (max 10) :- ");
#ifdef DOS
		scanf("%u",&units); /* read in number of units, unsigned */
#else
		scanf("%hu",&units); /* read in number of units, unsigned */
#endif
   		while(getchar() !='\n') ;

		if (units <= 10)
		{
			actual = rqreceiveunits(sph_tkn,units,NOWAITING,&except);

			if (except == ETIME)
			{
				if (actual > 0)
				{
					printf("\nUnable to receive the number of units requested,\n");
					printf("the number of units available are %d\n\n",actual);
				}
				else
					printf("\nThere are no units available at this semaphore\n\n");
				error_message(nul_message);
			}
			else if (except !=EOK)
			{
				printf("\n\nRQRECEIVEUNITS failed exception is %04XH\n",except);
				error_message(nul_message); /* wait for CR, no message */
			}
			else
			{
				printf("\n\nReceived requested units,");
				if (actual > 1)
					printf(" there are %d units remaining.\n",actual);
				else if (actual == 1)
					printf(" there is %d unit remaining.\n",actual);
				else
					printf(" the semaphore is now empty.\n");
				error_message(nul_message); /* wait for CR, no message */
			}
		}
		else
		{
			printf("\n\nToo many units requested from the semaphore, 10 MAX.\n");
			error_message(nul_message);
		}
	}
}

/******************************************************************
*
*    TITLE: CREATE_PVAM_SEGMENT
*
*    CALLING SEQUENCE: create_PVAM_segment();
*
*    INTERFACE VARIABLES: NONE
*
*    PARAMETERS:
*
*    GLOBAL VARIABLES:
*
*    ABSTRACT:
*     Creates a protected mode segment of a requested size that is 
*     entered from the keyboard. It is catalogued under a name, entered
*     at the keyboard in the my_job directory.
*
******************************************************************/
create_PVAM_segment()
{
TOKEN seg_tkn;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
DWORD segsize;
}  seg_params;
WORD except;

	clear_screen();

    printf("%s",cret_seg_msg);


	seg_params.name.numb_char = read_cat_name(seg_req_msg,&seg_params.name.string[2]);

	seg_params.name.numb_char += 2; /* string length */
	seg_params.name.string[0] = 'D';
	seg_params.name.string[1] = '?';

	seg_params.objecttype = segmenttype;

	/* name length plus char count and null character */

	printf("\nEnter the Segment size :- ");
#ifdef DOS
			scanf("%lx",&seg_params.segsize);
#else
			scanf("%x",&seg_params.segsize);
#endif
	while(getchar() !='\n') ;

	seg_params.segsize += (seg_params.name.numb_char + 2);
	seg_params.objdir = my_job;

	seg_tkn = get_rmx_object(&seg_params,&except);

	if (except == ETIME) /* doesn't already, exist create it */
	{
		seg_tkn = create_object(&seg_params,&except);

		if (except == EOK)
		{
#ifdef RMX
			memcpy((buildptr(seg_tkn,0)),
					&seg_params.name,
					(seg_params.name.numb_char + 2));
#else
			rqewritesegment(&seg_params.name,seg_tkn,(DWORD)0,
							(WORD)(seg_params.name.numb_char + 2),&except);
#endif

			printf("\n\nSegment %s created successfully\n\n",
											&seg_params.name.string[2]);
			error_message(nul_message);

		}
	}
	else if (except == EEXIST) error_message(error_name_no_obj);

	else if (except !=EOK) /* all other exception print the number only */
	{
		printf("\n\nException code %04XH, creating object\n\n",except);
		error_message(nul_message); /* wait for CR, no message */
	}
	else if (except == EOK)
	{
		printf("\n\nThe Segment name requested already exists.\n\n");
		error_message(nul_message); /* wait for CR, no message */
	}
}

/******************************************************************
*
*    TITLE: DELETE_PVAM_SEGMENT
*
*    CALLING SEQUENCE: delete_PVAM_segment();
*
*    INTERFACE VARIABLES: NONE
*
*    PARAMETERS:
*
*    GLOBAL VARIABLES:
*
*    ABSTRACT:
*     deletes a named protected mode segment that is catalogued in
*     my_job directory or the other_job direectory (other operating
*     system, DOS or RMX).
*
******************************************************************/
delete_PVAM_segment()
{
TOKEN seg_tkn;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
DWORD segsize;
}  seg_params;
WORD except;

	clear_screen();

    printf("%s",delt_seg_msg);


	seg_params.name.numb_char = read_cat_name(seg_req_msg,&seg_params.name.string[2]);

	seg_params.name.numb_char += 2; /* string length */
	seg_params.name.string[0] = 'D';
	seg_params.name.string[1] = '?';

	seg_params.objecttype = segmenttype;

	/* name length plus char count and null character */

	seg_params.segsize = seg_params.name.numb_char + 2;
	seg_params.objdir = my_job;

	seg_tkn = get_rmx_object(&seg_params,&except);

	if (except == ETIME)
	{
		printf("\n\nThe segment name does not exist\n\n");
		error_message(nul_message); /* wait for CR, no message */
	}
	else if (except == EEXIST) error_message(error_name_no_obj);

	else if (except != EOK) /* all other exception print the number only */
	{
		printf("\n\nException code %04XH, creating object\n\n",except);
		error_message(nul_message); /* wait for CR, no message */
	}
	else if (except == EOK)
	{
		remove_object(&seg_params.name); /* delete the object */
		printf("\n\nSegment %s deleted\n\n",&seg_params.name.string[2]);
		error_message(nul_message); /* wait for CR, no message */
	}
}

/******************************************************************
*
*    TITLE: CREATE_DESCRIPTOR
*
*    CALLING SEQUENCE: create_descriptor
*
*    INTERFACE VARIABLES: NONE
*
*    PARAMETERS:
*
*    GLOBAL VARIABLES:
*
*    ABSTRACT:
*     Creates a descriptor for an absolute address an size that are
*     entered from the keyboard. It is catalogued under a name, entered
*     at the keyboard in the my_job directory.
*
******************************************************************/
create_descriptor()
{
TOKEN des_tkn;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
DWORD absaddr;
DWORD segsize;
}  des_params;
WORD except;

	clear_screen();

    printf("%s",cret_des_msg);

	des_params.name.numb_char = read_cat_name(des_req_msg,&des_params.name.string[2]);

	des_params.name.numb_char += 2; /* string length */
	des_params.name.string[0] = 'D';
	des_params.name.string[1] = '?';

	des_params.objecttype = descriptortype;
	des_params.objdir = my_job;

	printf("\nEnter the Absolute Address for the Descriptor :- ");
#ifdef DOS
	scanf("%lx",&des_params.absaddr); /* read in descriptor address */
#else
	scanf("%x",&des_params.absaddr); /* read in descriptor address */
#endif
	while(getchar() !='\n') ;

	printf("\nEnter the Segment size for the Descriptor :- ");
#ifdef DOS
	scanf("%lx",&des_params.segsize); /* read in descriptor address */
#else
	scanf("%x",&des_params.segsize); /* read in descriptor address */
#endif
	while(getchar() !='\n') ;

	des_tkn = get_rmx_object(&des_params,&except);

	if (except == ETIME) /* doesn't already, exist create it */
	{
		des_tkn = create_object(&des_params,&except);

		if (except == EOK)
		{
			printf("\n\nDescriptor %s created successfully\n\n",
											&des_params.name.string[2]);
			error_message(nul_message);
		}
	}
	else if (except == EEXIST) error_message(error_name_no_obj);

	else if (except !=EOK) /* all other exception print the number only */
	{
		printf("\n\nException code %04XH, creating object\n\n",except);
		error_message(nul_message); /* wait for CR, no message */
	}
	else if (except == EOK)
	{
		printf("\n\nThe Segment name requested already exists.\n\n");
		error_message(nul_message); /* wait for CR, no message */
	}

}

/******************************************************************
*
*    TITLE: DISPLAY_SEGMENT
*
*    CALLING SEQUENCE: display_segment
*
*    INTERFACE VARIABLES: NONE
*
*    PARAMETERS:
*
*    GLOBAL VARIABLES:
*
*    ABSTRACT:
*     Displays a named PVAM segment or descriptor on the screen.
*     It has to exist and be catalogued under my_job or other_job.
*
******************************************************************/
display_segment()
{
TOKEN dis_tkn;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
DWORD absaddr;
DWORD segsize;
}  dis_params;
WORD except;

	clear_screen();

    printf("%s",disp_seg_msg);

	dis_params.name.numb_char = read_cat_name(seg_req_msg,&dis_params.name.string[2]);

	dis_params.name.numb_char += 2; /* string length */
	dis_params.name.string[0] = 'D';
	dis_params.name.string[1] = '?';

	dis_params.objecttype = descriptortype;
	dis_params.objdir = my_job;

	/* name length plus char count and null character */

	dis_params.objdir = my_job;

	dis_tkn = get_rmx_object(&dis_params,&except);

	if (except == EOK)
	{
		dis_params.segsize = rqgetsize(dis_tkn,&except);

		if (dis_params.segsize == 0) dis_params.segsize = SixtyFourK;

		if (checkseg(dis_tkn,dis_params.segsize) == TRUE)
		{
			display_memory(dis_tkn,(DWORD)(dis_params.name.numb_char + 2),
							(dis_params.segsize -
							 (dis_params.name.numb_char + 2)));
		}
		else
			display_memory(dis_tkn,(DWORD)0,dis_params.segsize);
	}
	else if (except == ETIME)
	{
		printf("\n\nSegment %s does not exist\n\n",
											&dis_params.name.string[2]);
		error_message(nul_message);
	}
	else if (except == EEXIST) error_message(error_name_no_obj);

	else if (except !=EOK) /* all other exception print the number only */
	{
		printf("\n\nException code %04XH, creating object\n\n",except);
		error_message(nul_message); /* wait for CR, no message */
	}
}


/******************************************************************
*
*    TITLE: DELETE_DESCRIPTOR
*
*    CALLING SEQUENCE: delete_descriptor
*
*    INTERFACE VARIABLES: NONE
*
*    PARAMETERS:
*
*    GLOBAL VARIABLES:
*
*    ABSTRACT:
*     Deletes a named descriptor entered from the keyboard.
*     The descriptor must exist in either my_job or other_job 
*     directories.
*
******************************************************************/
delete_descriptor()
{
TOKEN des_tkn;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
DWORD absaddr;
DWORD segsize;
}  des_params;
WORD except;

	clear_screen();

    printf("%s",delt_des_msg);

	des_params.name.numb_char = read_cat_name(des_req_msg,&des_params.name.string[2]);

	des_params.name.numb_char += 2; /* string length */
	des_params.name.string[0] = 'D';
	des_params.name.string[1] = '?';

	des_params.objecttype = descriptortype;
	des_params.objdir = my_job;

	/* name length plus char count and null character */

	des_params.segsize = des_params.name.numb_char + 2;
	des_params.objdir = my_job;

	des_tkn = get_rmx_object(&des_params,&except);

	if (except == ETIME)
	{
		printf("\n\nThe segment name does not exist\n\n");
		error_message(nul_message); /* wait for CR, no message */
	}
	else if (except == EEXIST) error_message(error_name_no_obj);

	else if (except != EOK) /* all other exception print the number only */
	{
		printf("\n\nException code %04XH, creating object\n\n",except);
		error_message(nul_message); /* wait for CR, no message */
	}
	else if (except == EOK)
	{
		remove_object(&des_params.name); /* delete the object */
		printf("\n\nDescriptor %s deleted\n\n",&des_params.name.string[2]);
		error_message(nul_message); /* wait for CR, no message */
	}
}

/******************************************************************
*
*    TITLE: COPY_PVAM_TO_REAL_MEM
*
*    CALLING SEQUENCE: copy_PVAM_to_real_mem();
*
*    INTERFACE VARIABLES: NONE
*
*    PARAMETERS:
*
*    GLOBAL VARIABLES:
*
*    ABSTRACT:
*     Copies a protected mode segment to a real mode segment of
*     a given size. The protected mode segment has to be named and
*     in either my_job or other_job directories. The real mode
*     segment and offset are entered at the keyboard along with the
*     size of data to be transfered.
*
******************************************************************/
copy_PVAM_to_real_mem()
{
TOKEN seg_tkn;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
DWORD segsize;
}  seg_params;
WORD realmodesegsize;
WORD realmodeseg;
WORD realmodeoffset;
DWORD realmodeaddr;
unsigned int dummy;
WORD objtype;
WORD except;

	clear_screen();

    printf("%s",copy_pvm_msg);


	seg_params.name.numb_char = read_cat_name(seg_req_msg,&seg_params.name.string[2]);

	seg_params.name.numb_char += 2; /* string length */
	seg_params.name.string[0] = 'D';
	seg_params.name.string[1] = '?';

	seg_params.objecttype = segmenttype;

	seg_params.objdir = my_job;

	seg_tkn = get_rmx_object(&seg_params,&except);

	if (except == EOK)
	{
		objtype = rqgettype(seg_tkn,&except);
		seg_params.segsize = rqgetsize(seg_tkn,&except);
		if ((objtype == rmxsegtype) &&
			(checkseg(seg_tkn,seg_params.segsize) == TRUE))
		{
			printf("\nEnter the real mode segment :- ");
#ifdef DOS
			scanf("%x",&realmodeseg);
#else
			scanf("%hx",&realmodeseg);
#endif
			while(getchar() !='\n') ;

			printf("\nEnter the real mode offset :- ");
#ifdef DOS
			scanf("%x",&realmodeoffset);
#else
			scanf("%hx",&realmodeoffset);
#endif
			while(getchar() !='\n') ;

			printf("\nEnter the size of data to copy :- ");
#ifdef DOS
			scanf("%x",&realmodesegsize);
#else
			scanf("%hx",&realmodesegsize);
#endif
			while(getchar() !='\n') ;

			/* create the realmode pointer */

			realmodeaddr = realmodeseg;

			realmodeaddr = (realmodeaddr * 0x10000) + realmodeoffset;

			if ((seg_params.segsize -
				 (seg_params.name.numb_char + 2)) < realmodesegsize)
			{
				realmodesegsize = seg_params.segsize -
								 (seg_params.name.numb_char + 2);
				printf("\n%s Segment is not large enough ",
                                        &seg_params.name.string[2]);
				printf("only %04XH bytes will be copied\n",&realmodesegsize);
			}
			rqereadsegment(seg_tkn,
						(DWORD)(seg_params.name.numb_char + 2), /* offset past name */
#ifdef RMX
						realmodeaddr,
#else
						(void far * )realmodeaddr,
#endif
						realmodesegsize,
						&except);

			if (except == EOK)
				printf("\nThe PVAM data was copied successfully");
			else
				printf("\nThe copy failed, exception %04XH",&except);
			error_message(nul_message);
		}
		else
		{
			printf("\n\n%s is not a segment, its token is %04XH,, ",
											&seg_params.name,(WORD)&seg_tkn);
			if (objtype <= rmxexttype)
				printf("RMX type %s\n",rmx_type_ptr[objtype]);
			else
				printf("RMX type %04XH\n",objtype);
			error_message(nul_message); /* wait for CR, no message */
		}
	}
	else error_message(seg_not_found);
}

/******************************************************************
*
*    TITLE: COPY_REAL_TO_PVAM_MEM
*
*    CALLING SEQUENCE: copy_real_to_PVAM_mem();
*
*    INTERFACE VARIABLES: NONE
*
*    PARAMETERS:
*
*    GLOBAL VARIABLES:
*
*    ABSTRACT:
*     Copies a real mode segment to a protected mode segment of
*     a given size. The protected mode segment has to be named and
*     in either my_job or other_job directories. The real mode
*     segment and offset are entered at the keyboard along with the
*     size of data to be transfered.
*
******************************************************************/
copy_real_to_PVAM_mem()
{
TOKEN seg_tkn;
struct {
WORD objecttype;
TOKEN objdir;
RMXSTRING name;
DWORD segsize;
}  seg_params;
WORD realmodesegsize;
WORD realmodeseg;
WORD realmodeoffset;
DWORD realmodeaddr;
unsigned int dummy;
WORD objtype;
WORD except;

	clear_screen();

    printf("%s",copy_rel_msg);


	seg_params.name.numb_char = read_cat_name(seg_req_msg,&seg_params.name.string[2]);

	seg_params.name.numb_char += 2; /* string length */
	seg_params.name.string[0] = 'D';
	seg_params.name.string[1] = '?';

	seg_params.objecttype = segmenttype;

	seg_params.objdir = my_job;

	seg_tkn = get_rmx_object(&seg_params,&except);

	if (except == EOK)
	{
		objtype = rqgettype(seg_tkn,&except);
		seg_params.segsize = rqgetsize(seg_tkn,&except);
		if ((objtype == rmxsegtype) &&
			(checkseg(seg_tkn,seg_params.segsize) == TRUE))
		{
			printf("\nEnter the real mode segment :- ");
#ifdef DOS
			scanf("%x",&realmodeseg);
#else
			scanf("%hx",&realmodeseg);
#endif
			while(getchar() !='\n') ;

			printf("\nEnter the real mode offset :- ");
#ifdef DOS
			scanf("%x",&realmodeoffset);
#else
			scanf("%hx",&realmodeoffset);
#endif
			while(getchar() !='\n') ;

			printf("\nEnter the size of data to copy :- ");
#ifdef DOS
			scanf("%x",&realmodesegsize);
#else
			scanf("%hx",&realmodesegsize);
#endif
			while(getchar() !='\n') ;

			/* create the realmode pointer */

			realmodeaddr = realmodeseg;

			realmodeaddr = (realmodeaddr * 0x10000) + realmodeoffset;

			if ((seg_params.segsize -
				 (seg_params.name.numb_char + 2)) < realmodesegsize)
			{
				realmodesegsize = seg_params.segsize -
								 (seg_params.name.numb_char + 2);
				printf("\n%s Segment is not large enough ",
                                        &seg_params.name.string[2]);
				printf("only %04XH bytes will be copied\n",&realmodesegsize);
			}
#ifdef RMX
			rqewritesegment(realmodeaddr,
#else
			rqewritesegment((void far * )realmodeaddr,
#endif
						seg_tkn,
						(DWORD)(seg_params.name.numb_char + 2), /* offset past name */
						realmodesegsize,
						&except);

			if (except == EOK)
				printf("\nThe real mode data was copied successfully");
			else
				printf("\nThe copy failed, exception %04XH",&except);
			error_message(nul_message);
		}
		else
		{
			printf("\n\n%s is not a segment, its token is %04XH,, ",
											&seg_params.name,(WORD)&seg_tkn);
			if (objtype <= rmxexttype)
				printf("RMX type %s\n",rmx_type_ptr[objtype]);
			else
				printf("RMX type %04XH\n",objtype);
			error_message(nul_message); /* wait for CR, no message */
		}
	}
	else error_message(seg_not_found);
}

