From e781fb26fdd422ea72c3a0eeba817e4faa5f663b Mon Sep 17 00:00:00 2001 From: Ben Burwell Date: Wed, 1 Apr 2015 20:22:48 -0400 Subject: as of 2013-10-17 --- comhan.c | 10 +++--- main.c | 65 ++++++++++++++++++++++++++------- mpx.h | 27 ++++++++++++-- pcb.c | 22 ++++++++++-- sys_req.c | 30 ++++++++++++++++ sys_reqc.c | 30 ---------------- sys_sppt.c | 83 ++++++++++++++++++++++++++++++++++++++++++ testn.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 333 insertions(+), 53 deletions(-) create mode 100644 sys_req.c delete mode 100644 sys_reqc.c create mode 100644 sys_sppt.c create mode 100644 testn.c diff --git a/comhan.c b/comhan.c index febb503..21a3448 100644 --- a/comhan.c +++ b/comhan.c @@ -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; diff --git a/main.c b/main.c index c6d567f..0aa8505 100644 --- a/main.c +++ b/main.c @@ -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; diff --git a/mpx.h b/mpx.h index 7d64022..d9af678 100644 --- a/mpx.h +++ b/mpx.h @@ -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 diff --git a/pcb.c b/pcb.c index 8f4034a..c383a37 100644 --- a/pcb.c +++ b/pcb.c @@ -2,6 +2,12 @@ #include #include +#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 + +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 +#include +#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(); +} diff --git a/testn.c b/testn.c new file mode 100644 index 0000000..2d09d82 --- /dev/null +++ b/testn.c @@ -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 +#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!!!"); + } +} + -- cgit v1.2.3