aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Burwell <ben@benburwell.com>2015-04-01 20:26:26 -0400
committerBen Burwell <ben@benburwell.com>2015-04-01 20:26:26 -0400
commite282a861d5868868940b449681f2ee5da3e439e8 (patch)
treedc1fb0b3708d717e6c3695fffc77d5df7a0934a8
parente781fb26fdd422ea72c3a0eeba817e4faa5f663b (diff)
as of 2013-10-292013-10-29
-rw-r--r--comhan.c422
-rw-r--r--load.c93
-rw-r--r--main.c6
-rw-r--r--mpx.h20
-rw-r--r--pcb.c7
-rw-r--r--proc1.asm62
-rw-r--r--proc2.asm63
-rw-r--r--proc3.asm63
-rw-r--r--proc4.asm63
-rw-r--r--proc5.asm62
-rw-r--r--sys_sppt.c20
11 files changed, 774 insertions, 107 deletions
diff --git a/comhan.c b/comhan.c
index 21a3448..7d02799 100644
--- a/comhan.c
+++ b/comhan.c
@@ -8,32 +8,48 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <math.h>
#include "mpx.h"
#define BUF_SIZE 80 /* Size of the command line buffer. */
-#define VERSION 0
-#define DATE 1
-#define DIRECTORY 2
-#define STOP 3
-#define HELP 4
-#define PROMPT 5
-#define ALIAS 6
-#define SHOW 7
-#define ALLOCATE 8
-#define CMD_FREE 9
+#define VERSION 0
+#define DATE 1
+#define DIRECTORY 2
+#define STOP 3
+#define HELP 4
+#define PROMPT 5
+#define ALIAS 6
+#define SHOW 7
+#define ALLOCATE 8
+#define CMD_FREE 9
+#define CMD_LOAD 10
+#define CMD_RESUME 11
+#define CMD_RUN 12
+#define CMD_SUSPEND 13
+#define CMD_TERMINATE 14
+#define CMD_SETPRI 15
+#define CMD_DISPATCH 16
+
+#define NUM_CMDS 17
int length; /* Length of the command line. */
+unsigned sp_save; /* A stack save for mod 4 dispatch. */
char prompt[20] = "mpx>";
const char version[] = "MPX OS - Version 1.0\n";
char date[] = "01/09/1991";
-char *cmds[] = {"version", "date", "directory","stop","help",
- "prompt", "alias", "show", "allocate", "free", NULL};
+char *cmds[] = { "version", "date", "directory", "stop",
+ "help", "prompt", "alias", "show",
+ "allocate", "free", "load", "resume",
+ "run", "suspend", "terminate", "setpriority",
+ "dispatch", NULL};
char *aliases[] = {" ", " ", " ", " ",
" ", " ", " ", " ",
- " ", " ", NULL};
+ " ", " ", " ", " ",
+ " ", " ", " ", " ",
+ " ", NULL};
/*
* comhan() This is the command handler for the MPX OS.
@@ -47,8 +63,6 @@ char *aliases[] = {" ", " ", " ", " ",
void comhan() {
static char *args[7]; //one more than expected number of arguments
- int argc;
- int cmd_num;
static char buffer[BUF_SIZE];
int do_stop = 0;
@@ -57,19 +71,26 @@ void comhan() {
length = BUF_SIZE; /* Reset length of buffer. */
sys_req(CON,READ,buffer,&length); /* Request CON input */
- argc = set_args(buffer, args);
+ set_args(buffer, args);
- switch (cmd_num = get_cmd(args[0])) {
+ switch (get_cmd(args[0])) {
case VERSION: cmd_version(); break;
- case DATE: cmd_date(args); break;
- case DIRECTORY: cmd_directory(); break;
- case STOP: do_stop = cmd_stop(); break;
- case HELP: cmd_help(args); break;
- case PROMPT: cmd_prompt(args); break;
- case ALIAS: cmd_alias(args); break;
- case SHOW: cmd_show(args); break;
- case ALLOCATE: cmd_allocate(args); break;
- case CMD_FREE: cmd_free(args); break;
+ case DATE: cmd_date(args); break;
+ case DIRECTORY: cmd_directory(); break;
+ case STOP: do_stop = cmd_stop(); break;
+ case HELP: cmd_help(args); break;
+ case PROMPT: cmd_prompt(args); break;
+ case ALIAS: cmd_alias(args); break;
+ case SHOW: cmd_show(args); break;
+ case ALLOCATE: cmd_allocate(args); break;
+ case CMD_FREE: cmd_free(args); break;
+ case CMD_LOAD: cmd_load(args); break;
+ case CMD_RESUME: cmd_resume(args); break;
+ case CMD_RUN: cmd_run(args); break;
+ case CMD_SUSPEND: cmd_suspend(args); break;
+ case CMD_TERMINATE: cmd_terminate(args); break;
+ case CMD_SETPRI: cmd_setpri(args); break;
+ case CMD_DISPATCH: cmd_dispatch(); break;
default:
printf("Can't recognize.\n");
break;
@@ -136,7 +157,6 @@ void cmd_date(char *args[]){
if (m > 0 && m < 13 && d > 0 && d < 32) {
sprintf(date, "%d/%d/%d", m, d, y);
- printf("Date set to %s \n", date);
} else {
printf("Invalid date. \n");
}
@@ -156,7 +176,7 @@ void cmd_directory(){
if (no_proc > 0) {
printf("Size Name \n");
- printf("===================================== \n");
+ printf("========= =========================== \n");
}
for (i = 0; i < no_proc; i++) {
@@ -170,12 +190,20 @@ void cmd_directory(){
int cmd_stop(){
char buffer[2];
int length = 2;
+ pcb *p = pcb_list;
printf("Are you sure you want to exit? [y/n]: ");
sys_req(CON,READ,buffer,&length);
if (strcmp(buffer, "y") == 0 || strcmp(buffer, "Y") == 0) {
- printf("**COMHAN execution complete **\n");
+ do {
+ if(p->type != FREE) {
+ freemem(p->loadaddr);
+ free_pcb(pcb_list, p);
+ }
+ p = p->chain;
+ } while(p != NULL);
+ printf("** COMHAN execution complete **\n");
return 1;
} else {
return 0;
@@ -187,44 +215,41 @@ int cmd_stop(){
* Will print all commands or just information specific to the
* argument if given.
*/
-void cmd_help(char *args[]){
- char ver[] = "version Display version number \n";
- char hlp[] = "help Provide information about commands \n";
- char dir[] = "directory List .mpx files \n";
- char dat[] = "date [mm/dd/yyyy] Display or set the system date \n";
- char stp[] = "stop Terminate execution of COMHAN \n";
- char prmpt[] = "prompt string Change the prompt for commands \n";
- char als[] = "alias command=string Create an alias for a command \n";
- char shw[] = "show Prints PCB information \n";
- char alloc[] = "allocate Builds PCB with specified options \n";
- char free[] = "free name Frees the PCB called name \n";
-
- switch(get_cmd(args[1])){
- case VERSION: printf(ver); break;
- case DATE: printf(dat); break;
- case DIRECTORY: printf(dir); break;
- case STOP: printf(stp); break;
- case HELP: printf(hlp); break;
- case PROMPT: printf(prmpt); break;
- case ALIAS: printf(als); break;
- case SHOW: printf(shw); break;
- case ALLOCATE: printf(alloc); break;
- case CMD_FREE: printf(free); break;
- default:
- printf("**\tCommand Summary\t**\n");
- printf("Name Use\n");
- printf("======================================\n");
- printf(ver);
- printf(dat);
- printf(dir);
- printf(stp);
- printf(hlp);
- printf(prmpt);
- printf(als);
- printf(shw);
- printf(alloc);
- printf(free);
- }
+void cmd_help(char *args[]) {
+ int i;
+ char *help[NUM_CMDS];
+
+ help[VERSION] = "version Display version number";
+ help[HELP] = "help Provide information about commands";
+ help[DIRECTORY] = "directory List .mpx files";
+ help[DATE] = "date [mm/dd/yyyy] Display or set the system date";
+ help[STOP] = "stop Terminate execution of COMHAN";
+ help[PROMPT] = "prompt string Change the prompt for commands";
+ help[ALIAS] = "alias command=string Create an alias for a command";
+ help[SHOW] = "show Prints PCB information";
+ help[ALLOCATE] = "allocate Builds PCB with specified options";
+ help[CMD_FREE] = "free name Frees the PCB called name";
+ help[CMD_LOAD] = "load name[=ppp] Creates a process called name with priority ppp";
+ help[CMD_RESUME] = "resume name Resumes the process called name";
+ help[CMD_RUN] = "run name[=ppp] Runs a process called name with priority ppp";
+ help[CMD_SUSPEND] = "suspend name Suspends the process called name";
+ help[CMD_TERMINATE] = "terminate name Terminates the process called name";
+ help[CMD_SETPRI] = "setpriority name=ppp Sets the priority of process name";
+ help[CMD_DISPATCH] = "dispatch Runs each process once";
+
+ // print header
+ printf( " Name Use \n");
+ printf( " ==================== ================================================= \n");
+
+ if (args[1] != NULL) {
+ // print help for specific command
+ printf(" %s \n", help[ get_cmd(args[1]) ] );
+ } else {
+ // list all help
+ for (i = 0; i < NUM_CMDS; i++) {
+ printf(" %s \n", help[i]);
+ }
+ }
}
/**
@@ -336,16 +361,14 @@ void cmd_allocate(char *args[]) {
pcb * exists;
if (!args[1] || !args[2] || !args[3] || !args[4] || !args[5]) {
- printf("***Error*** \n");
- printf("Please use the correct number of arguments. \n");
+ printf("Error: Please use the correct number of arguments. \n");
return;
}
if (strcmp(args[2], "f") != 0 &&
strcmp(args[2], "a") != 0 &&
strcmp(args[2], "s") != 0) {
- printf("***Error*** \n");
- printf("PCB type must be f(ree), a(pplication) or s(ystem). \n");
+ printf("Error: PCB type must be f(ree), a(pplication) or s(ystem). \n");
printf("You said: %s \n", args[2]);
return;
}
@@ -353,16 +376,14 @@ void cmd_allocate(char *args[]) {
if (strcmp(args[3], "r") != 0 &&
strcmp(args[3], "o") != 0 &&
strcmp(args[3], "b") != 0) {
- printf("***Error*** \n");
- printf("PCB state must be r(eady), o(running), or b(locked). \n");
+ printf("Error: PCB state must be r(eady), o(running), or b(locked). \n");
printf("You said: %s \n", args[3]);
return;
}
if (strcmp(args[4], "y") != 0 &&
strcmp(args[4], "n") != 0) {
- printf("***Error*** \n");
- printf("PCB suspended flag must be y(es) or n(o). \n");
+ printf("Error: PCB suspended flag must be y(es) or n(o). \n");
printf("You said: %s \n", args[4]);
return;
}
@@ -372,8 +393,7 @@ void cmd_allocate(char *args[]) {
exists = search_pcb(pcb_list, args[1]);
if(exists != NULL){
- printf("***Error*** \n");
- printf("A pcb with that name already esists. \n");
+ printf("Error: A pcb with that name already esists. \n");
return;
}
@@ -399,15 +419,13 @@ void cmd_allocate(char *args[]) {
}
if (type == APP_PROCESS && (priority < -126 || priority > 126)) {
- printf("***Error*** \n");
- printf("The priority for an application process must be \n");
+ printf("Error: The priority for an application process must be \n");
printf("between -126 and 126, inclusive. \n");
return;
}
if (type == SYS_PROCESS && (priority < -128 || priority > 127)) {
- printf("***Error*** \n");
- printf("The priority for a system process must be \n");
+ printf("Error: The priority for a system process must be \n");
printf("between -128 and 127, inclusive. \n");
return;
}
@@ -418,20 +436,16 @@ void cmd_allocate(char *args[]) {
switch (result) {
case 1: break;
- case -1: printf("***Error*** \n");
- printf("There was no space for another pcb. \n");
+ case -1: printf("Error: There was no space for another pcb. \n");
break;
- case -2: printf("***Error*** \n");
- printf("Invalid type \n");
+ case -2: printf("Error: Invalid type \n");
break;
- case -3: printf("***Error*** \n");
- printf("Invalid state \n");
+ case -3: printf("Error: Invalid state \n");
break;
- case -4: printf("***Error*** \n");
- printf("Invalid suspend \n");
+ case -4: printf("Error: Invalid suspend \n");
break;
}
@@ -457,8 +471,230 @@ void cmd_free(char *args[]) {
result = free_pcb(pcb_list, to_free);
switch (result) {
- case 1: printf("PCB freed\n"); break;
- case -1: printf("Couldn't find PCB\n"); break;
- case -2: printf("PCB already free\n"); break;
+ case -1: printf("Error: Couldn't find PCB\n"); break;
+ case -2: printf("Error: PCB already free\n"); break;
+ }
+}
+
+/**
+ * Load
+ */
+void cmd_load(char *args[]) {
+ int i, ret, priority = 0;
+ unsigned segp;
+ pcb *p;
+ int paragraphs;
+ char* name = args[1];
+ // figure out how many directory entries
+ int num = directory(direct, DIR_SIZE);
+
+ // search in the directory for the specified program
+ i = 0;
+ while (stricmp(direct[i].dirnam, name) != 0) {
+ i++;
+ if (i == num) {
+ // no program found
+ printf("Error: No program found with that name. \n");
+ return;
+ }
+ }
+
+ // figure out how much memory we need
+ paragraphs = (unsigned) ceil(direct[i].dirsiz / 16);
+
+ // try to allocate the needed memory
+ if (allocmem(paragraphs, &segp) != -1) {
+ // insufficient memory
+ printf("Error: Insufficient memory. \n");
+ return;
}
-} \ No newline at end of file
+
+ // read the file into memory
+ if (load((unsigned *)segp, direct[i].dirnam) != 0) {
+ // load error
+ printf("Error: Could not load program into memory. \n");
+ return;
+ }
+
+ // if a valid priority was specified, replace the default
+ if (args[2] != NULL) {
+ if (atoi(args[2]) >= -126 && atoi(args[2]) <= 126) {
+ priority = atoi(args[2]);
+ } else {
+ printf("Warning: invalid priority specified, using default. \n");
+ }
+ }
+
+ // now we can put the proc into a PCB
+ p = get_pcb(pcb_list);
+
+ if (p == NULL) {
+ printf("Error: No free PCBs. \n");
+ return;
+ }
+
+ if (build_pcb(p, args[1], APP_PROCESS, READY, SUSPENDED,
+ priority, segp, 0 /* ip */, 0 /* ds */, 0x200) != 1) {
+ printf("Error: Unable to build PCB. \n");
+ return;
+ }
+
+ insert_pcb(&ready_queue, p, 0);
+ return;
+}
+
+/**
+ * Resume
+ */
+void cmd_resume(char *args[]) {
+
+ pcb *p = pcb_list;
+
+ if (args[1] != NULL) {
+ if (strcmp(args[1], "*") == 0) {
+ // resume all processes
+ // set suspended to NOT_SUSPENDED for all application PCBs
+ do {
+ if (p->type == APP_PROCESS) {
+ p->suspend = NOT_SUSPENDED;
+ }
+ p = p->chain;
+ } while (p != NULL);
+ } else {
+ // search for the correct PCB and set suspended to NOT_SUSPENDED
+ p = search_pcb(pcb_list, args[1]);
+ if (p != NULL) {
+ p->suspend = NOT_SUSPENDED;
+ } else {
+ printf("No process named %s. \n", args[1]);
+ }
+ }
+ } else {
+ printf("No process specified. Please run resume proc \n");
+ printf("for process proc. To resume all processes, \n");
+ printf("type resume * \n");
+ }
+}
+
+/**
+ * Run
+ */
+void cmd_run(char *args[]) {
+ pcb *p;
+ // load the process ...
+ cmd_load(args);
+
+ // ... then set it to be not suspended
+ p = search_pcb(pcb_list, args[1]);
+ if (p != NULL){
+ p->suspend = NOT_SUSPENDED;
+ } else {
+ printf("Error: process did not load correctly. \n");
+ }
+}
+
+/**
+ * Suspend
+ */
+void cmd_suspend(char *args[]) {
+ pcb *p;
+
+ // Get the pcb...
+ p = search_pcb(pcb_list, args[1]);
+
+ if (p != NULL) {
+ // ... and suspend it
+ p->suspend = SUSPENDED;
+ } else {
+ printf("No process with the specified name. \n");
+ }
+}
+
+/**
+ * Terminate
+ */
+void cmd_terminate(char *args[]) {
+ pcb *p;
+
+ // the "terminate *" case
+ if (strcmp(args[1], "*") == 0) {
+ p = pcb_list;
+ do {
+ if (p->type == APP_PROCESS) {
+ // remove from queue as needed
+ if (p->state == READY) {
+ remove_pcb(&ready_queue, p);
+ } else if (p->state == BLOCKED) {
+ remove_pcb(&io_init_queue, p);
+ }
+
+ // free it
+ freemem(p->loadaddr);
+ free_pcb(pcb_list, p);
+ }
+ p = p -> chain;
+ } while (p != NULL);
+ } else {
+ // the "terminate proc" case
+ p = search_pcb(pcb_list, args[1]);
+
+ if (p != NULL && p->type == APP_PROCESS) {
+
+ // remove from queue as needed
+ if (p->state == READY) {
+ remove_pcb(&ready_queue, p);
+ } else if (p->state == BLOCKED) {
+ remove_pcb(&io_init_queue, p);
+ }
+
+ // free it
+ freemem(p->loadaddr);
+ free_pcb(pcb_list, p);
+ } else {
+ printf("No process with the specified name. \n");
+ }
+ }
+ return;
+}
+
+/**
+ * Set Priority
+ */
+void cmd_setpri(char *args[]) {
+ pcb *p;
+ int new_priority;
+
+ // Get the pcb
+ p = search_pcb(pcb_list, args[1]);
+ new_priority = atoi(args[2]);
+
+ if (p != NULL) {
+ // Check the priority is valid
+ if (p->type == APP_PROCESS && new_priority >= -128 && new_priority <= 127) {
+ remove_pcb(&ready_queue, p); // Take pcb out of ready queue
+ p->priority = new_priority; // Change priority
+ insert_pcb(&ready_queue, p, 0); // Re-insert pcb in ready queue
+ } else {
+ printf("Error: invalid priority. \n");
+ }
+ } else {
+ printf("Error: invalid process name. \n");
+ }
+}
+
+/**
+ * Dispatch
+ */
+void cmd_dispatch() {
+ // set up a pointer to the ready queue
+ pcb dummy;
+ cop = &dummy;
+ cop -> next = ready_queue;
+
+ // save the stack pointer so we can return here
+ sp_save = _SP - 24;
+
+ // call sys_sppt's dispatch
+ dispatch();
+ return;
+}
diff --git a/load.c b/load.c
new file mode 100644
index 0000000..dc39115
--- /dev/null
+++ b/load.c
@@ -0,0 +1,93 @@
+/***********************************************************************
+*
+* Module Name: load
+*
+* Purpose: To provide support for loading files.
+*
+* Functions in Module:
+* load
+
+************************************************************************/
+
+#include <dos.h> /* Borland header file */
+#include <fcntl.h> /* Borland header file */
+#include <dir.h> /* Borland header file */
+
+#include "mpx.h"
+
+#define intnum 33 /* int86 number for load only */
+#define success 0 /* return code for successful process load */
+#define error -1 /* return code for failure on process load */
+
+
+/**************************************************************************
+ *
+ * Function: load
+ * Abstract: Dynamically loads a file from disk
+ * Algorithm:
+ * This procedure dynamically loads a process with a
+ * file extension of .MPX. The memory address provided
+ * is the segment address at which to load the process.
+ * The process with the name in the string pname is
+ * loaded into memory at the segment address found in
+ * load_addr. If load is successful, load returns a 0
+ * return code, otherwise it returns a -1 return code
+ *
+ **************************************************************************/
+
+int load(unsigned *load_addr,char pname[])
+{
+ int i,flags,carry;
+ char fname[30];
+
+ struct PRMBLK
+ {
+ int segaddr;
+ int reloctn;
+ };
+
+ struct PRMBLK prmbk;
+ union REGS *inregs; /* input registers pointer */
+ union REGS *outregs; /* output registers pointer */
+ struct SREGS *segregs; /* segment registers pointer */
+
+ union REGS inr; /* input register structure */
+ union REGS outr; /* output register structure */
+ struct SREGS segr; /* segment register structure */
+
+ disable();
+
+ /* SEGMENT REGISTER VALUE CALL */
+
+ segregs = &segr;
+ segread(segregs); /* returns current segme disablter values */
+
+ strcpy(fname, pname);
+ strcat(fname, ".MPX");
+
+ inregs = &inr;
+ outregs = &outr;
+ inregs->h.ah = 75;
+ inregs->x.dx = &fname[0];
+ prmbk.segaddr = load_addr;
+ prmbk.reloctn = load_addr;
+ segr.es = segr.ds; /* assigning the ES to the data segment */
+ inregs->x.bx = &prmbk;
+ inregs->h.al = 3; /* load only */
+
+ flags = int86x(intnum,inregs,outregs,segregs);
+ carry = flags; /* Could be omitted */
+ carry = outregs->x.cflag;
+ if(carry)
+ {
+ printf("\nerror code:%3d",outregs->x.ax);
+ enable();
+ return(error);
+ }
+
+ /* load successful */
+ enable();
+ return(success);
+ }
+
+/***********************************************************************/
diff --git a/main.c b/main.c
index 0aa8505..a5346b1 100644
--- a/main.c
+++ b/main.c
@@ -66,6 +66,7 @@ int main(void) {
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);
@@ -91,15 +92,18 @@ int main(void) {
(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
+ sys_init();
comhan(); /* Execute the command handler */
+ sys_exit();
return 0;
}
diff --git a/mpx.h b/mpx.h
index d9af678..70e70a1 100644
--- a/mpx.h
+++ b/mpx.h
@@ -12,7 +12,8 @@
#define EXIT_CODE 0 /* Process requesting termination. code. */
#define CON 1 /* The console device - keyboard & monitor. */
#define PRT 2 /* The printer device - LPT1. */
-#define COM 3 /* The serial port - COM1. */
+#define COM 3 /* The serial port - COM1.
+#define */
/* MPX System request types. */
@@ -80,6 +81,15 @@ void cmd_alias(char *[]);
void cmd_show(char *[]);
void cmd_allocate(char *[]);
void cmd_free(char *[]);
+
+void cmd_load(char *[]);
+void cmd_resume(char *[]);
+void cmd_run(char *[]);
+void cmd_suspend(char *[]);
+void cmd_terminate(char *[]);
+void cmd_setpri(char *[]);
+void cmd_dispatch();
+
void sys_req(int,int,char *,int *); /* MPX system request function. */
int directory(dir *, int); /* Support function to load the */
/* directory array. */
@@ -113,6 +123,11 @@ void sys_exit(void);
void interrupt dispatch(void);
void interrupt sys_call(void);
+/**
+ * Load.c
+ */
+int load(unsigned *,char []);
+
/*
* Global variable EXTERN directives.
*
@@ -129,4 +144,5 @@ 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
+extern unsigned sys_stack[];
+extern unsigned sp_save; /* So that mod 4 can return to cmd_dispatch */ \ No newline at end of file
diff --git a/pcb.c b/pcb.c
index c383a37..9cbaf76 100644
--- a/pcb.c
+++ b/pcb.c
@@ -16,7 +16,7 @@ pcb * search_pcb(pcb * list, char name[]) {
// step through the chain
do {
- if (strcmp(current->name, name) == 0) {
+ if (stricmp(current->name, name) == 0) {
return current;
}
current = current->chain;
@@ -113,6 +113,7 @@ int build_pcb(pcb * addr, char name[], int type, int state,
addr->stack[STK_DS] = ds;
addr->stack_ptr =(unsigned) &(addr->stack[INIT_STACK]);
+ addr->loadaddr = cs;
return 1;
}
@@ -196,7 +197,9 @@ int remove_pcb(pcb **queue, pcb * addr) {
do {
if (current->next == addr) {
current->next = addr->next;
- (current->next)->prev = current;
+ if (current->next != NULL) {
+ (current->next)->prev = current;
+ }
addr->next = NULL;
addr->prev = NULL;
return 0;
diff --git a/proc1.asm b/proc1.asm
new file mode 100644
index 0000000..06aa1d4
--- /dev/null
+++ b/proc1.asm
@@ -0,0 +1,62 @@
+;*************************************************************************
+;
+; MPX-PC Test Process
+; Name: PROC1
+; Description: Test process
+; Module: 4
+;
+;************************************************************************
+
+
+ CON EQU 01H
+ PRT EQU 02H
+ WRITE EQU 01H
+
+ CR EQU 0DH
+ LF EQU 0AH
+
+ STACK SEGMENT STACK
+ DB 32 DUP ('STACK ') ; 256 BYTES
+ STACK ENDS
+
+ DATA SEGMENT
+ MSG1 DB 'Proc1 dispatched. ',CR,LF,'$'
+ LEN DW 20
+ DATA ENDS
+
+ CODE SEGMENT
+ ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
+
+ MAIN PROC FAR
+ START: MOV AX,DATA ; SET UP DATA SEGMENT
+ MOV DS,AX
+ MOV ES,AX ; SET UP EXTRA SEGMENT
+
+ ; Set up stack for dummy sys_call
+
+ MOV DX,OFFSET LEN
+ PUSH DX ; LOAD LENGTH PARM
+ MOV DX,OFFSET MSG1
+ PUSH DX ; LOAD MESSAGE ADDRESS
+ MOV DX,WRITE
+ PUSH DX ; LOAD OPERATION TYPE
+ MOV DX,PRT
+ PUSH DX ; LOAD OPERATION NUMBER
+ MOV DX,0AAH
+ PUSH DX ; PUSH EXTRA BYTE TO MAINTAIN
+ MOV DX,0ABH ; COMPATIBILITY WITH C ROUTINES
+ PUSH DX
+
+ LOOP: MOV DX,OFFSET MSG1
+ MOV AH,09H ; PRINT STRING
+ INT 21H
+
+ MOV CX,0 ; RUN ONLY ONCE
+ INT 60H ; INT TO DISP
+ JMP LOOP
+
+ MAIN ENDP
+ CODE ENDS
+ END START
+
+
diff --git a/proc2.asm b/proc2.asm
new file mode 100644
index 0000000..1419a2a
--- /dev/null
+++ b/proc2.asm
@@ -0,0 +1,63 @@
+;*************************************************************************
+;
+; MPX-PC Test Process
+; Name: PROC2
+; Description: Test process
+; Module: 4
+;
+;************************************************************************
+
+
+ CON EQU 01H
+ PRT EQU 02H
+ WRITE EQU 01H
+
+ CR EQU 0DH
+ LF EQU 0AH
+
+ STACK SEGMENT STACK
+ DB 32 DUP ('STACK ') ; 256 BYTES
+ STACK ENDS
+
+ DATA SEGMENT
+ MSG1 DB 'Proc2 dispatched. ',CR,LF,'$'
+ BUF DB 124 dup(?)
+ LEN DW 20
+ DATA ENDS
+
+ CODE SEGMENT
+ ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
+
+ MAIN PROC FAR
+ START: MOV AX,DATA ; SET UP DATA SEGMENT
+ MOV DS,AX
+ MOV ES,AX ; SET UP EXTRA SEGMENT
+
+ ; Set up stack for dummy sys_call
+
+ MOV DX,OFFSET LEN
+ PUSH DX ; LOAD LENGTH PARM
+ MOV DX,OFFSET MSG1
+ PUSH DX ; LOAD MESSAGE ADDRESS
+ MOV DX,WRITE
+ PUSH DX ; LOAD OPERATION TYPE
+ MOV DX,PRT
+ PUSH DX ; LOAD OPERATION NUMBER
+ MOV DX,0AAH
+ PUSH DX ; PUSH EXTRA BYTE TO MAINTAIN
+ MOV DX,0ABH ; COMPATIBILITY WITH C ROUTINES
+ PUSH DX
+
+ LOOP: MOV DX,OFFSET MSG1
+ MOV AH,09H ; PRINT STRING
+ INT 21H
+
+ MOV CX,0 ; RUN ONLY ONCE
+ INT 60H ; INT TO DISP
+ JMP LOOP
+
+ MAIN ENDP
+ CODE ENDS
+ END START
+
+
diff --git a/proc3.asm b/proc3.asm
new file mode 100644
index 0000000..e47a4bd
--- /dev/null
+++ b/proc3.asm
@@ -0,0 +1,63 @@
+;*************************************************************************
+;
+; MPX-PC Test Process
+; Name: PROC3
+; Description: Test process
+; Module: 4
+;
+;************************************************************************
+
+
+ CON EQU 01H
+ PRT EQU 02H
+ WRITE EQU 01H
+
+ CR EQU 0DH
+ LF EQU 0AH
+
+ STACK SEGMENT STACK
+ DB 32 DUP ('STACK ') ; 256 BYTES
+ STACK ENDS
+
+ DATA SEGMENT
+ MSG1 DB 'Proc3 dispatched. ',CR,LF,'$'
+ BUF DB 70 dup(?)
+ LEN DW 20
+ DATA ENDS
+
+ CODE SEGMENT
+ ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
+
+ MAIN PROC FAR
+ START: MOV AX,DATA ; SET UP DATA SEGMENT
+ MOV DS,AX
+ MOV ES,AX ; SET UP EXTRA SEGMENT
+
+ ; Set up stack for dummy sys_call
+
+ MOV DX,OFFSET LEN
+ PUSH DX ; LOAD LENGTH PARM
+ MOV DX,OFFSET MSG1
+ PUSH DX ; LOAD MESSAGE ADDRESS
+ MOV DX,WRITE
+ PUSH DX ; LOAD OPERATION TYPE
+ MOV DX,PRT
+ PUSH DX ; LOAD OPERATION NUMBER
+ MOV DX,0AAH
+ PUSH DX ; PUSH EXTRA BYTE TO MAINTAIN
+ MOV DX,0ABH ; COMPATIBILITY WITH C ROUTINES
+ PUSH DX
+
+ LOOP: MOV DX,OFFSET MSG1
+ MOV AH,09H ; PRINT STRING
+ INT 21H
+
+ MOV CX,0 ; RUN ONLY ONCE
+ INT 60H ; INT TO DISP
+ JMP LOOP
+
+ MAIN ENDP
+ CODE ENDS
+ END START
+
+
diff --git a/proc4.asm b/proc4.asm
new file mode 100644
index 0000000..1043ff9
--- /dev/null
+++ b/proc4.asm
@@ -0,0 +1,63 @@
+;*************************************************************************
+;
+; MPX-PC Test Process
+; Name: PROC4
+; Description: Test process
+; Module: 4
+;
+;************************************************************************
+
+
+ CON EQU 01H
+ PRT EQU 02H
+ WRITE EQU 01H
+
+ CR EQU 0DH
+ LF EQU 0AH
+
+ STACK SEGMENT STACK
+ DB 32 DUP ('STACK ') ; 256 BYTES
+ STACK ENDS
+
+ DATA SEGMENT
+ MSG1 DB 'Proc4 dispatched. ',CR,LF,'$'
+ BUF DB 243 dup(?)
+ LEN DW 20
+ DATA ENDS
+
+ CODE SEGMENT
+ ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
+
+ MAIN PROC FAR
+ START: MOV AX,DATA ; SET UP DATA SEGMENT
+ MOV DS,AX
+ MOV ES,AX ; SET UP EXTRA SEGMENT
+
+ ; Set up stack for dummy sys_call
+
+ MOV DX,OFFSET LEN
+ PUSH DX ; LOAD LENGTH PARM
+ MOV DX,OFFSET MSG1
+ PUSH DX ; LOAD MESSAGE ADDRESS
+ MOV DX,WRITE
+ PUSH DX ; LOAD OPERATION TYPE
+ MOV DX,PRT
+ PUSH DX ; LOAD OPERATION NUMBER
+ MOV DX,0AAH
+ PUSH DX ; PUSH EXTRA BYTE TO MAINTAIN
+ MOV DX,0ABH ; COMPATIBILITY WITH C ROUTINES
+ PUSH DX
+
+ LOOP: MOV DX,OFFSET MSG1
+ MOV AH,09H ; PRINT STRING
+ INT 21H
+
+ MOV CX,0 ; RUN ONLY ONCE
+ INT 60H ; INT TO DISP
+ JMP LOOP
+
+ MAIN ENDP
+ CODE ENDS
+ END START
+
+
diff --git a/proc5.asm b/proc5.asm
new file mode 100644
index 0000000..e1b09f1
--- /dev/null
+++ b/proc5.asm
@@ -0,0 +1,62 @@
+;*************************************************************************
+;
+; MPX-PC Test Process
+; Name: PROC5
+; Description: Test process
+; Module: 4
+;
+;************************************************************************
+
+
+ CON EQU 01H
+ PRT EQU 02H
+ WRITE EQU 01H
+
+ CR EQU 0DH
+ LF EQU 0AH
+
+ STACK SEGMENT STACK
+ DB 32 DUP ('STACK ') ; 256 BYTES
+ STACK ENDS
+
+ DATA SEGMENT
+ MSG1 DB 'Proc5 dispatched. ',CR,LF,'$'
+ LEN DW 20
+ DATA ENDS
+
+ CODE SEGMENT
+ ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
+
+ MAIN PROC FAR
+ START: MOV AX,DATA ; SET UP DATA SEGMENT
+ MOV DS,AX
+ MOV ES,AX ; SET UP EXTRA SEGMENT
+
+ ; Set up stack for dummy sys_call
+
+ MOV DX,OFFSET LEN
+ PUSH DX ; LOAD LENGTH PARM
+ MOV DX,OFFSET MSG1
+ PUSH DX ; LOAD MESSAGE ADDRESS
+ MOV DX,WRITE
+ PUSH DX ; LOAD OPERATION TYPE
+ MOV DX,PRT
+ PUSH DX ; LOAD OPERATION NUMBER
+ MOV DX,0AAH
+ PUSH DX ; PUSH EXTRA BYTE TO MAINTAIN
+ MOV DX,0ABH ; COMPATIBILITY WITH C ROUTINES
+ PUSH DX
+
+ LOOP: MOV DX,OFFSET MSG1
+ MOV AH,09H ; PRINT STRING
+ INT 21H
+
+ MOV CX,0 ; RUN ONLY ONCE
+ INT 60H ; INT TO DISP
+ JMP LOOP
+
+ MAIN ENDP
+ CODE ENDS
+ END START
+
+
diff --git a/sys_sppt.c b/sys_sppt.c
index be03d7d..80ae62d 100644
--- a/sys_sppt.c
+++ b/sys_sppt.c
@@ -24,7 +24,7 @@ void interrupt (*vect60)(); /* Storage for DOS int 60h */
void sys_init()
{
- /* set up interrupt vector for MPX sys_calls */
+ /* set up interrupt vector for MPX sys_calls */
vect60 = getvect(0x60);
setvect(0x60,&sys_call);
@@ -42,13 +42,15 @@ void sys_exit()
void interrupt dispatch()
{
- /* your dispatcher code */
- if (ready_queue == NULL) {
- sys_exit();
+ /* MOD 4 dispatch */
+ do {
+ cop = cop -> next;
+ } while (cop != NULL && cop->suspend == SUSPENDED);
+
+ if (cop == NULL) {
+ _SP = sp_save;
} else {
- cop = ready_queue; // make the front of the queue the running process
- remove_pcb(&ready_queue, cop);
- _SP = cop->stack_ptr;
+ _SP = cop -> stack_ptr;
}
}
@@ -75,8 +77,8 @@ void interrupt sys_call()
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);
+ if (parm_add->op_number == EXIT_CODE) {
+ cop->suspend = SUSPENDED;
}
dispatch();