📄 pause.c
字号:
/*
* Pause.c
*
* Program handles process scheduling
*
* Each process must be registered via ADD_PROCESS, and processes must
* specifically relinquish control by issuing the PAUSE routine at
* appropriate intervals
*
* The constant "MaxPauses" defines the number of processes which can
* be cascaded with these routines
*
* This program assumes a 16 bit memory model in which pointers are considered
* FAR, and also the presence of the "standard stack frame" optimization
*
* BORLAND C (16 bit) version
*
* Code by David Lindauer, CIMple technologies
*
*/
#include "menus.h"
#include "logic.h"
#include <malloc.h>
//#pragma inline
/* Define the following to see debug info on the screen
// #define DEBUG
/*
* A structure to map the assembly-level registers into
* a pointer usable by C routines
*/
typedef union {
struct {
int sp,ss; // Assembly level stack pointer
} h;
struct {
void *stack; // C-usable pointer
} x;
} SDATA ;
static SDATA stacklist[MaxPauses]; // List of all process stacks
static SDATA stackbot[MaxPauses]; // Bottoms of stacks
static FUNC funclist[MaxPauses]; // List of all process init addresses
static int num_Pauses = 1; // Number of processes in use,
// this definitions Leaves space for main process
// (first caller of PAUSE)
static int cur_Pause = 0; // Where we are in the process list
#ifdef DEBUG
/* Routine to print the stack */
void PStack( int num)
{
int i;
printf("%x:",num);
for (i=0; i<12; i++)
printf(" %x", *(((char *) stacklist[num].x.stack)+i));
printf("\n");
}
#endif // DEBUG
static void IniStack(int item)
{
int *temp;
SDATA temP1;
/* Initial SP */
stacklist[item].x.stack = stackbot[item].x.stack;
stacklist[item].h.sp += STACKSIZE-12;
/* Get stack pointer and load the process address up so we can get CS:IP */
temp = (int *) stacklist[item].x.stack;
temP1.x.stack = (void *) funclist[item];
/* Initial value of stack */
*(temp+4) = temP1.h.ss; // CS
*(temp+3) = temP1.h.sp; // IP
*(temp+2) = 0; // BP
*(temp+1) = 0; // DI
*temp = 0; // SI
}
/*
* This routine allocates a stack and adds the function to the
* process list.
*
* Whenever a task is Paused the following items will be added to the stack:
*
* CS
* IP
* BP
* DI
* SI <- SP
*
* SP:SS is stored in stacklist
*/
BOOL AddProcess( FUNC newprocess)
{
if (num_Pauses == MaxPauses)
return(FALSE);
/* Allocate stack */
stackbot[num_Pauses].x.stack = (char *) malloc(STACKSIZE);
if (( stackbot[num_Pauses].x.stack) == NULL) {
printf("Error allocating process stack\n");
return(FALSE);
}
// Initial function
funclist[num_Pauses] = newprocess;
IniStack(num_Pauses);
#ifdef DEBUG
PStack(num_Pauses);
#endif
/* Update number of processes we have */
num_Pauses++;
return(TRUE);
}
void ReinitProcesses(void)
{
int i;
for (i=0; i<num_Pauses; i++)
IniStack(i);
}
/*
* This function sleeps the current process and opens a new one
*/
void Pause(void)
{
/* The following too wasted statements force the BC compiler to
* save DI and SI
* Note that we are relying on the compiler to automatically save
* CS, IP, and BP, so, don't use compiler options which disable this !
*/
asm mov ax,di
asm mov ax,si
/* Save stack pointer for later */
stacklist[cur_Pause].h.ss = _SS;
stacklist[cur_Pause].h.sp = _SP;
/* Go to next routine */
cur_Pause++;
if (cur_Pause >= num_Pauses)
cur_Pause = 0;
#ifdef DEBUG
PStack(cur_Pause);
#endif
/* Load new stack pointer */
asm cli
_SS = stacklist[cur_Pause].h.ss;
_SP = stacklist[cur_Pause].h.sp;
asm sti
/* Compiler will restore all five registers */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -