diff options
| -rw-r--r-- | comhan.c | 10 | ||||
| -rw-r--r-- | main.c | 65 | ||||
| -rw-r--r-- | mpx.h | 27 | ||||
| -rw-r--r-- | pcb.c | 22 | ||||
| -rw-r--r-- | sys_req.c | 30 | ||||
| -rw-r--r-- | sys_reqc.c | 30 | ||||
| -rw-r--r-- | sys_sppt.c | 83 | ||||
| -rw-r--r-- | testn.c | 119 | 
8 files changed, 333 insertions, 53 deletions
| @@ -46,10 +46,10 @@ char *aliases[] = {"        ", "        ", "        ", "        ",   */
  void comhan() {
 -	char *args[5];
 +	static char *args[7]; //one more than expected number of arguments
  	int argc;
  	int cmd_num;
 -	char buffer[BUF_SIZE];
 +	static char buffer[BUF_SIZE];
  	int do_stop = 0;
  	do {
 @@ -102,7 +102,7 @@ int get_cmd(char cmd[]){  int set_args(char buffer[], char *args[]) {
    /* use string tok to set the contents of args from buffer
  	 and return the number of args (will go into argc) */
 -  char separators[4] = " =/"; //Characters that separate tokens
 +  char separators[5] = " =/,"; //Characters that separate tokens
    int i = 0; //loop control
    args[i] = strtok(buffer, separators); //Get first token
 @@ -178,7 +178,6 @@ int cmd_stop(){  	printf("**COMHAN execution complete **\n");
  	return 1;
    } else {
 -	printf("Okay! \n");
  	return 0;
    }
  }
 @@ -413,7 +412,8 @@ void cmd_allocate(char *args[]) {  	return;
    }
 -  result = build_pcb(new, args[1], type, state, suspend, priority);
 +  result = build_pcb(new, args[1], type, state, suspend, priority,
 +					 NULL, NULL, NULL, NULL);
    switch (result) {
  	case 1:  break;
 @@ -11,6 +11,7 @@  pcb * pcb_list;
  pcb * ready_queue;
  pcb * io_init_queue;
 +pcb * cop;
  pcb pcb0;
  pcb pcb1;
 @@ -25,7 +26,10 @@ pcb pcb9;  pcb pcb10;
  pcb pcb11;
 +unsigned sys_stack[STACK_SIZE];
 +
  int main(void) {
 +	pcb * pcb_addr;
  	printf("Booting MPX... \n");
  	/* Put initialization code here */
 @@ -43,21 +47,58 @@ int main(void) {  	pcb10.chain = &pcb11;
  	pcb11.chain = NULL;
 -	build_pcb(&pcb0, "        ", FREE, -1, -1, 0);
 -	build_pcb(&pcb1, "        ", FREE, -1, -1, 0);
 -	build_pcb(&pcb2, "        ", FREE, -1, -1, 0);
 -	build_pcb(&pcb3, "        ", FREE, -1, -1, 0);
 -	build_pcb(&pcb4, "        ", FREE, -1, -1, 0);
 -	build_pcb(&pcb5, "        ", FREE, -1, -1, 0);
 -	build_pcb(&pcb6, "        ", FREE, -1, -1, 0);
 -	build_pcb(&pcb7, "        ", FREE, -1, -1, 0);
 -	build_pcb(&pcb8, "        ", FREE, -1, -1, 0);
 -	build_pcb(&pcb9, "        ", FREE, -1, -1, 0);
 -	build_pcb(&pcb10, "        ", FREE, -1, -1, 0);
 -	build_pcb(&pcb11, "        ", FREE, -1, -1, 0);
 +	build_pcb(&pcb0,  "        ", FREE, -1, -1, 0, NULL, NULL, NULL, NULL);
 +	build_pcb(&pcb1,  "        ", FREE, -1, -1, 0, NULL, NULL, NULL, NULL);
 +	build_pcb(&pcb2,  "        ", FREE, -1, -1, 0, NULL, NULL, NULL, NULL);
 +	build_pcb(&pcb3,  "        ", FREE, -1, -1, 0, NULL, NULL, NULL, NULL);
 +	build_pcb(&pcb4,  "        ", FREE, -1, -1, 0, NULL, NULL, NULL, NULL);
 +	build_pcb(&pcb5,  "        ", FREE, -1, -1, 0, NULL, NULL, NULL, NULL);
 +	build_pcb(&pcb6,  "        ", FREE, -1, -1, 0, NULL, NULL, NULL, NULL);
 +	build_pcb(&pcb7,  "        ", FREE, -1, -1, 0, NULL, NULL, NULL, NULL);
 +	build_pcb(&pcb8,  "        ", FREE, -1, -1, 0, NULL, NULL, NULL, NULL);
 +	build_pcb(&pcb9,  "        ", FREE, -1, -1, 0, NULL, NULL, NULL, NULL);
 +	build_pcb(&pcb10, "        ", FREE, -1, -1, 0, NULL, NULL, NULL, NULL);
 +	build_pcb(&pcb11, "        ", FREE, -1, -1, 0, NULL, NULL, NULL, NULL);
  	pcb_list = &pcb0;
 +	// initialize the currently running process
 +	cop = NULL;
 +
 +	// initialize the mod3 test pcbs
 +	pcb_addr = get_pcb(pcb_list);
 +	build_pcb(pcb_addr, "test1", APP_PROCESS, READY, NOT_SUSPENDED, 0, _CS,
 +			  (unsigned)test1, _DS, 0x200);
 +	insert_pcb(&ready_queue, pcb_addr, 0);
 +
 +	pcb_addr = get_pcb(pcb_list);
 +	build_pcb(pcb_addr, "test2",APP_PROCESS, READY, NOT_SUSPENDED, 0, _CS,
 +			  (unsigned)test2, _DS, 0x200);
 +	insert_pcb(&ready_queue, pcb_addr, 0);
 +
 +	pcb_addr = get_pcb(pcb_list);
 +	build_pcb(pcb_addr, "test3", APP_PROCESS, READY, NOT_SUSPENDED, 0, _CS,
 +			  (unsigned)test3, _DS, 0x200);
 +	insert_pcb(&ready_queue, pcb_addr, 0);
 +
 +	pcb_addr = get_pcb(pcb_list);
 +	build_pcb(pcb_addr, "test4", APP_PROCESS, READY, NOT_SUSPENDED, 0, _CS,
 +			  (unsigned)test4, _DS, 0x200);
 +	insert_pcb(&ready_queue, pcb_addr, 0);
 +
 +	pcb_addr = get_pcb(pcb_list);
 +	build_pcb(pcb_addr, "test5",  APP_PROCESS, READY, NOT_SUSPENDED, 0, _CS,
 +			  (unsigned)test5, _DS, 0x200);
 +	insert_pcb(&ready_queue, pcb_addr, 0);
 +
 +	// initialize the system stack
 +	_SP = (unsigned) &sys_stack[STACK_SIZE -1];
 +
 +	//get the show on the road!
 +	sys_init();
 +	dispatch();
 +
 +	//never gonna get here
  	comhan();    /* Execute the command handler */
  	return 0;
 @@ -43,7 +43,7 @@ typedef struct dirstruct dir;  /* Use dir as the data typer name.     */  #define BLOCKED       2
  #define NOT_SUSPENDED 0
  #define SUSPENDED     1
 -
 +#define STACK_SIZE  400
  struct pcbstruct {
  	struct pcbstruct * chain;
 @@ -55,8 +55,9 @@ struct pcbstruct {  	short state;
  	short suspend;
  	unsigned stack_ptr;
 -	unsigned stack[400];
 +	unsigned stack[STACK_SIZE];
  	unsigned loadaddr;
 +	unsigned parm_add; // added during mod because sys_call said so
  	int mem_size;
  };
  typedef struct pcbstruct pcb;
 @@ -89,10 +90,28 @@ int  directory(dir *, int);           /* Support function to load the */  pcb * search_pcb(pcb *, char[]);
  pcb * get_pcb(pcb *);
  int free_pcb(pcb *, pcb *);
 -int build_pcb(pcb *, char[], int, int, int, int);
 +int build_pcb(pcb *, char[] /*name*/, int /*type*/, int /*state*/,
 +	int /*suspend*/, int /*priority*/, unsigned /*_cs*/, unsigned /*_ip*/,
 +	unsigned /*_ds*/, unsigned /*psw*/);
  int insert_pcb(pcb**, pcb *, int);
  int remove_pcb(pcb**, pcb *);
 +/**
 + * TestN.C
 + */
 +void test1(void);
 +void test2(void);
 +void test3(void);
 +void test4(void);
 +void test5(void);
 +
 +/**
 + * Sys_sppt.c
 + */
 +void sys_inti(void);
 +void sys_exit(void);
 +void interrupt dispatch(void);
 +void interrupt sys_call(void);
  /*
   *   Global variable EXTERN directives.
 @@ -109,3 +128,5 @@ extern int directory(dir *direct, int dir_size);  extern pcb * pcb_list;
  extern pcb * ready_queue;
  extern pcb * io_init_queue;
 +extern pcb * cop; /* The currently operating process. */
 +extern unsigned sys_stack[];
\ No newline at end of file @@ -2,6 +2,12 @@  #include <string.h>
  #include <stdio.h>
 +#define STK_PSW    (STACK_SIZE - 1)
 +#define STK_CS     (STACK_SIZE - 2)
 +#define STK_IP     (STACK_SIZE - 3)
 +#define STK_DS     (STACK_SIZE - 9)
 +#define INIT_STACK (STACK_SIZE - 12)
 +
  /**
   * Returns the address of the PCB with the specified name
   */
 @@ -54,7 +60,7 @@ int free_pcb(pcb * list, pcb * addr) {  		return -2;
  	  } else {
  		// we need to free the PCB
 -		build_pcb(current, "        ", 0, -1, -1, 0);
 +		build_pcb(current, "        ", 0, -1, -1, 0, NULL, NULL, NULL, NULL);
  		return 1;
  	  }
  	}
 @@ -69,7 +75,8 @@ int free_pcb(pcb * list, pcb * addr) {   * Sets the properties of the given PCB.
   */
  int build_pcb(pcb * addr, char name[], int type, int state,
 -			  int suspend, int priority) {
 +			  int suspend, int priority, unsigned cs, unsigned ip,
 +			  unsigned ds, unsigned psw) {
    // check that address is valid
    if (addr == 0 || addr == NULL) {
  	return -1;
 @@ -99,6 +106,13 @@ int build_pcb(pcb * addr, char name[], int type, int state,    addr->prev = NULL;
    addr->priority = priority;
 +  // set up the stack
 +  addr->stack[STK_PSW] = psw;
 +  addr->stack[STK_CS] = cs;
 +  addr->stack[STK_IP] = ip;
 +  addr->stack[STK_DS] = ds;
 +
 +  addr->stack_ptr =(unsigned) &(addr->stack[INIT_STACK]);
    return 1;
  }
 @@ -172,7 +186,9 @@ int remove_pcb(pcb **queue, pcb * addr) {    // are we removing the head?
    if (addr == *queue) {
  	*queue = addr->next;
 -	(addr->next)->prev = NULL;
 +	if (addr->next != NULL) {
 +	  (addr->next)->prev = NULL;
 +	}
  	return 0;
    }
 diff --git a/sys_req.c b/sys_req.c new file mode 100644 index 0000000..b48a7bb --- /dev/null +++ b/sys_req.c @@ -0,0 +1,30 @@ +/***********************************************************************
 +*
 +*	Procedure Name:  sys_req
 +*
 +*
 +*	Purpose: System request for round robin dispatcher test.
 +*
 +*	Sample Call: sys_req(op_num,op_type,&buffer,&len)
 +*                    where
 +*                          op_num specifies the operation requested
 +*                          op_type specifies read or write
 +*                          buffer is the data buffer
 +*                          length is the number of characters to read or write
 +*
 +*	Algorithm:  Request to sys_call is made via an int 60.  Parameters
 +*                   passed to sys_req remain on the stack for use by sys_call.
 +*
 +************************************************************************/
 +
 +
 +#include <dos.h>
 +
 +extern void interrupt sys_call();
 +
 +
 +void sys_req(int op_number,int op_type,char *buff_add,int *length)
 +{
 +  geninterrupt(0x60);   /* If all is set up right, this should      */
 +}                       /* invoke sys_call() to handle the request. */
 +
 diff --git a/sys_reqc.c b/sys_reqc.c deleted file mode 100644 index 7856032..0000000 --- a/sys_reqc.c +++ /dev/null @@ -1,30 +0,0 @@ -/*
 - *   file:  sys_reqc.c
 - *
 - *   This is the MPX system request function which
 - *   uses the C gets function.
 - */
 -
 -
 -
 -/*    sys_req   - implements the MPX system request function.
 - *
 - *    Parameters: number - request number: a device or exit code.
 - *                type   - request type: read, write, wait, signal.
 - *                s      - address of read/write buffer.
 - *                length - address of buffer length variable.
 - *
 - *    Return value: None
 - *
 - *    In this module, the only system request allowed is to
 - *    read from the console (keyboard).  This is done using
 - *    the standard C function gets().
 - */
 -
 -
 -void sys_req(int number, int type, char *s, int *length)
 -{
 -    gets(s);                /* Read a string from the keyboard.       */
 -    *length = strlen(s);    /* Get its length.                        */
 -}
 -
 diff --git a/sys_sppt.c b/sys_sppt.c new file mode 100644 index 0000000..be03d7d --- /dev/null +++ b/sys_sppt.c @@ -0,0 +1,83 @@ +/***********************************************************************
 +*
 +*	Name:   sys_sppt.c
 +*
 +*	Purpose:  Support Routines for Modules 3 and 4 of MPX-PC
 +*
 +*	Sample Call:
 +*                     sys_init()
 +*                     sys_exit()
 +*
 +* 	Procedures In Module:
 +*                     sys_init - Sets up interrupt vector 60 for MPX-PC
 +*                     sys_exit - Resets interrupt vector 60 and exits to DOS
 +*
 +*
 +****************************************************************************/
 +
 +#include <stdio.h>
 +#include <dos.h>
 +#include "mpx.h"
 +
 +void interrupt (*vect60)();  /* Storage for DOS int 60h */
 +			                 /* interrupt vector.       */
 +
 +void sys_init()
 +{
 +    /* set up interrupt vector for MPX sys_calls */
 +
 +	vect60 = getvect(0x60);
 +	setvect(0x60,&sys_call);
 +}
 +
 +
 +void sys_exit()
 +{
 +	/* restore interrupt vector 60 and exit */
 +
 +	setvect(0x60,vect60);
 +	exit();
 +}
 +
 +
 +void interrupt dispatch()
 +{
 + /* your dispatcher code */
 + if (ready_queue == NULL) {
 +   sys_exit();
 + } else {
 +   cop = ready_queue; // make the front of the queue the running process
 +   remove_pcb(&ready_queue, cop);
 +   _SP = cop->stack_ptr;
 + }
 +}
 +
 +
 +void interrupt sys_call()
 +{
 +	struct parm {
 +		int op_number;
 +		int op_type;
 +		char *buffer;
 +		int *length;
 +	};
 +
 +	static struct parm *parm_add;
 +
 +	/* Save stack pointer for current process */
 +	cop->stack_ptr = _SP;
 +
 +	/* Get address of sys_call parameters */
 +	parm_add = _SP + 0x1c; // parameter offset = 0x1C
 +
 +	/* Note that you should save this parameter address
 +	   somewhere in the pcb as suggested below*/
 +	cop->parm_add = parm_add;
 +
 +	// find out if the process wants to die... and kill it
 +	if(parm_add->op_number != EXIT_CODE) {
 +	  insert_pcb(&ready_queue, cop, 0);
 +	}
 +
 +	dispatch();
 +}
 @@ -0,0 +1,119 @@ +/***********************************************************************
 +*
 +*	Name:  testn.c
 +*
 +*	Purpose:  Provides statically-loaded (via linker) test processes
 +*                 for Round Robin Dispatcher of Module 3.
 +*
 +* 	Procedures In Module:
 +*                             test1 - test process
 +*                             test2 - test process
 +*                             test3 - test process
 +*                             test4 - test process
 +*                             test5 - test process
 +*
 +*       Name:       Processes test1, test2, test3, test4, and test5.
 +*
 +*	Algorithm:  Each process prints a message to the screen and gives up
 +*                   control to the dispatcher using sys_req.  Each process
 +*                   loops a certain number of times, displaying a message to
 +*                   the screen inside the loop.  (test1 loops 5 times, test2
 +*                   loops 10, test3 loops 15, test4 loops 20, and test5 loops
 +*                   25 times).  Each test process eventually requests
 +*                   termination.  If a dispatcher dispatches a test process
 +*                   after it requested termination, it prints a message
 +*                   indicating so, and the process starts over.
 +*
 +*****************************************************************************/
 +
 +#include <dos.h>
 +#include "mpx.h"
 +
 +#define op       1               /* dummy operation request code */
 +#define type     1               /* dummy operation type */
 +
 +void test1(void)
 +{
 +     char buffer[8];
 +     int len;
 +     int i;
 +
 +     while (1) {
 +	 	 for (i=1; i <= 5; i++) {
 +	       printf("\ntest1 dispatched; Value of i = %d",i);
 +	     	/* give up control to the dispatcher */
 +	       sys_req(op,type,buffer,&len);
 +	     }
 +	     sys_req(EXIT_CODE,0,buffer,&len);
 +	     printf ("\ntest1 dispatched after it exited!!!");
 +     }
 +}
 +
 +
 +void test2(void)
 +{
 +    char buffer[8];
 +    int len;
 +    int i;
 +
 +    while (1) {
 +		for (i=1; i <= 10; i++) {
 +	    	printf("\ntest2 dispatched; Value of i = %d",i);
 +	    	/* give up control to the dispatcher */
 +	    	sys_req(op,type,buffer,&len);
 +	}
 +		sys_req(EXIT_CODE,0,buffer,&len);
 +		printf ("\ntest1 dispatched after it exited!!!");
 +    }
 +}
 +
 +void test3(void)
 +{
 +    char buffer[8];
 +    int len;
 +    int i;
 +    while (1) {
 +		for (i=1; i <= 15; i++) {
 +	    	printf("\ntest3 dispatched; Value of i = %d",i);
 +	    	/* give up control to the dispatcher */
 +	    	sys_req(op,type,buffer,&len);
 +		}
 +		sys_req(EXIT_CODE,0,buffer,&len);
 +		printf ("\ntest3 dispatched after it exited!!!");
 +    }
 +}
 +
 +void test4(void)
 +{
 +    char buffer[8];
 +    int len;
 +    int i;
 +
 +    while (1) {
 +		for (i=1; i <= 20; i++) {
 +	    	printf("\ntest4 dispatched; Value of i = %d",i);
 +	    	/* give up control to the dispatcher */
 +	    	sys_req(op,type,buffer,&len);
 +		}
 +		sys_req(EXIT_CODE,0,buffer,&len);
 +		printf ("\ntest4 dispatched after it exited!!!");
 +    }
 +}
 +
 +void test5(void)
 +{
 +    char buffer[8];
 +    int len;
 +    int i;
 +
 +    while (1) {
 +		for (i=1; i <= 25; i++) {
 +	    	printf("\ntest5 dispatched; Value of i = %d",i);
 +	    	/* give up control to the dispatcher */
 +	    	sys_req(op,type,buffer,&len);
 +		}
 +		sys_req(EXIT_CODE,0,buffer,&len);
 +		printf ("\ntest5 dispatched after it exited!!!");
 +    }
 +}
 +
 | 
