aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Burwell <ben@benburwell.com>2015-04-01 20:22:48 -0400
committerBen Burwell <ben@benburwell.com>2015-04-01 20:22:48 -0400
commite781fb26fdd422ea72c3a0eeba817e4faa5f663b (patch)
tree7f73aa21426320dc13d74c1dde1e591ef97fb44a
parente468dc911189e71509012fb0ed228cc765f641fa (diff)
as of 2013-10-172013-10-17
-rw-r--r--comhan.c10
-rw-r--r--main.c65
-rw-r--r--mpx.h27
-rw-r--r--pcb.c22
-rw-r--r--sys_req.c30
-rw-r--r--sys_reqc.c30
-rw-r--r--sys_sppt.c83
-rw-r--r--testn.c119
8 files changed, 333 insertions, 53 deletions
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 <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();
+}
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 <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!!!");
+ }
+}
+