分享
 
 
 

DOS 下多任务系统的设计与实现 -- 源码 -- 主程序

王朝other·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

1、TASK.C

/*

TASK.C

Teacher: Wang Xiaoniu

program by Wang Xiaozhi & Zhao Tingzhe

CopyRight Northwest Normal Univeristy Computer Department 1995.4

*/

/*

TCC -mc -1 -f- -d -k- -O -Z task.c

Usage:task [DRIVE:\PATH\]

*/

#include <stdlib.h>

#include <io.h>

#include <fcntl.h>

#include <dos.h>

#include <mem.h>

#include <conio.h>

#include <process.h>

/*

Use BIOS correspondence areas

0:0x4f0 Software flag

0:0x4f4 Menu Return

*/

/*

Change Vector includes 1CH,2AH,9H,5H,7DH,

1CH:Timer;

2AH:DOS critical section;

9H:Keyboard hardware interrupt;

*/

#define SOFTWAREFLAG 0x575a

#define NDEBUG

#ifndef NDEBUG

void _Assert(char *,int);

void DeleteTask(void);

#define Assert(f) if(f) ; else _Assert(__FILE__,__LINE__)

void _Assert(char *s,int line)

{

cprintf("Assert failed :FILE :%s LINE:%d",

s,line);

DeleteTask();

}

#else

#define Assert(f)

#endif

#define INTERRUPT void interrupt

typedef unsigned int WORD;

typedef unsigned char BYTE;

#define STACKSIZE 2048 /* Itself stack */

char sStack[STACKSIZE];

#define MAXUSERS 6 /* Max Task Number */

#define F10_KEY 68 /* This is F10 */ /* Hot Key */

#define CTRL_ALT_KEY 12 /* This is ctrl 0x8 && alt 0x4*/ /* Crtl_ALT Key */

#define SDA_SWAPSIZE 0x7c0

extern WORD _stklen=2048;

int WantPopUp=0; /* Menu pop_up flag */

int Int2ABusy=0; /* Dos Enter flag */

int nExe=0; /* Now Task Id */

int uTask=0;

INTERRUPT (*OldInt9)();

INTERRUPT NewInt9();

/*

INTERRUPT (*OldInt1C)();

INTERRUPT NewInt1C();

*/

INTERRUPT (*OldInt2A)();

INTERRUPT NewInt2A();

void main(int argc,char *argv[]);

void TaskMain(void);

void ChangeVect(void);

void TestInstall(void);

void End(void);

void TaskChange(void);

void Menu(void);

void SaveAllMem(void);

void SaveMem(WORD seg);

void SetMemFree(WORD seg);

void LoadMem(WORD seg);

WORD GetMem(void);

void DeleteTask(void);

void SubDos(void);

int MakeMapName(char *s,int mode);

#define READ 0

#define READ_AND_NOT_DIRECT_PUT 2

#define WRITE 1

void IOFile(char *s,char *buf,WORD size,int ctrl);

typedef struct {

WORD es,ds,di,si,bp,sp,bx,dx,cx,ax,ip,cs,flags;

} INTERRUPT_REGS; /* Interrupt parameters */

typedef struct {

WORD psp;

struct SAVE_REGS {

WORD sp,ss; /* Task RESG */

} save_regs;

char swapsave[SDA_SWAPSIZE]; /* DosSwapArea */

} PCB; /* PCB For Task */

PCB nPCB[2];

BYTE IsTask[MAXUSERS+1]; /* For Task 1 to 6 */

/* 0 noused */

int fp;

#define VECTMAP "vect"

#define SDAMAP "sda"

#define BLOCKSIZE 512

#define MEMORYMAP "mem" /* memory map file */

typedef struct {

char attr;

WORD owner;

WORD size;

} MCB; /* Memory Crtl Block */

MCB mcbdesc={ /* Last,size,nouse */

'Z',0,0

};

char sPath[32]; /* Owner's path and swapdisk */

char sDisk[32];

char sNameBuffer[82];

char temp2[48];

/*_______________________________________________________________________*/

/*

DOSSWAP.C-Functions to manage DOS swap areas

*/

/*

INT21h 5D06

DS:SI -points to DOS swappable data area

DX -size of area to swap when InDOS>0

CX -size of area to always swap

*/

#define GET_DOSSWAP3 0X5D06

/* variables for 3.x swap work*/

char far *pDosSwapArea; /* DosSwapArea Addr */

int DosSwapSize;

/*

Function:InitDosSwap

Initialize pointers and sizes of DOS swap area.

*/

void InitDosSwap(void)

{

WORD save_ds;

WORD tmp_ds,tmp_si,tmp_cx;

save_ds=_DS;

_AX=GET_DOSSWAP3;

geninterrupt(0x21); /* Must save DS */

tmp_cx=_CX;

tmp_ds=_DS;

tmp_si=_SI;

_DS=save_ds;

pDosSwapArea=MK_FP(tmp_ds,tmp_si);

Assert(pDosSwapArea);

DosSwapSize=tmp_cx;

}

/*

Function:SaveDosSwap

This function will save the dos swap area to a local buffer

*/

void SaveDosSwap(void)

{

movedata( FP_SEG(pDosSwapArea),

FP_OFF(pDosSwapArea),

_DS,

FP_OFF(nPCB[nExe].swapsave),

DosSwapSize);

}

/*

Function:RestoreDosSwap

This function will restore a previously swapped dos data area

*/

void RestoreDosSwap(void)

{

movedata( _DS,

FP_OFF(nPCB[nExe].swapsave),

FP_SEG(pDosSwapArea),

FP_OFF(pDosSwapArea),

DosSwapSize);

}

/*_______________________________________________________________________*/

/*

MAIN.C-Main program for Task DOS

*/

void TaskMain(void)

{

TestInstall();

InitDosSwap();

SaveDosSwap();

ChangeVect();

/* Save raw vector table */

IOFile(VECTMAP,(char far *)0l,1024,WRITE);

uTask=1;

IsTask[1]=1;

SubDos();

End();

}

void ChangeVect(void) /* Set owner hook intr */

{

/*

OldInt1C=getvect(0x1c);

*/

OldInt2A=getvect(0x2a);

OldInt9=getvect(0x9);

/*

setvect(0x1c,NewInt1C);

*/

setvect(0x2a,NewInt2A);

setvect(0x9,NewInt9);

}

/*

The function TestInstall first check is also installed!

Then makeup pop_up stack,save task's DTA for use.

*/

void TestInstall(void)

{

if(peek(0,0x4f0)==SOFTWAREFLAG) /* If also exist, exit */

exit(1);

else

poke(0,0x4f0,SOFTWAREFLAG); /* Exist flag */

nPCB[0].save_regs.ss=_DS;

/* We not sure if sp is a odd */

nPCB[0].save_regs.sp=FP_OFF(&sStack[STACKSIZE-2]);

nPCB[0].psp=_psp;

}

void End(void) /* Restore old intr and clear */

{

IOFile(VECTMAP,(char far *)0l,1024,READ_AND_NOT_DIRECT_PUT);

/*

setvect(0x1c,OldInt1C);

*/

setvect(0x2a,OldInt2A);

setvect(0x9,OldInt9);

poke(0,0x4f0,0); /* Clear softflag */

}

INTERRUPT NewInt9() /* CTRL_ALT_F10 to pop up. */

{

static char far *pKey=MK_FP(0,0x417);

static int key;

if(inportb(0x60)==F10_KEY) /* Hot key */

{ /* CTRL and ALT */

if((*pKey&CTRL_ALT_KEY)==CTRL_ALT_KEY)

{

key=inportb(0x61);

outportb(0x61,key);

outportb(0x20,0x20);

/*

if also pop up, or if dos_error,or dos busy,

can not pop up.

*/

if(WantPopUp||*pDosSwapArea||Int2ABusy)

return;

else

{

WantPopUp=1;

disable();

nPCB[1].save_regs.ss=_SS; /* save old stack */

nPCB[1].save_regs.sp=_SP;

_SP=nPCB[0].save_regs.sp; /* set new stack */

_SS=nPCB[0].save_regs.ss;

enable();

TaskChange(); /* enter task */

disable();

_SP=nPCB[1].save_regs.sp; /* restore old stack */

_SS=nPCB[1].save_regs.ss;

enable();

WantPopUp=0;

}

}

else

(*OldInt9)();

}

else

(*OldInt9)();

}

/*

INTERRUPT NewInt1C()

{

static int i=0;

static char str[12],*sptr;

char far *p;

static char h,m,s;

(*OldInt1C)();

if(i++<4)

return;

else

{

i=0;

_AH=2;

geninterrupt(0x1a);

h=_CH;

m=_CL;

s=_DH;

#ifndef NDEBUG

sprintf(str,"%d %d ",*(pDosSwapArea),

*(pDosSwapArea+1));

#else

sprintf(str,"%02d %02x:%02x:%02x",

uTask,h,m,s);

#endif

sptr=str;

p=MK_FP(0xb800,160-22);

while(*sptr)

{

*(p++)=*(sptr++);

*(p++)=RED;

}

}

}

*/

INTERRUPT NewInt2A(INTERRUPT_REGS r) /* Check DOS busy. */

{

switch(r.ax&0xff00)

{

case 0x8000:

Int2ABusy++;

break;

case 0x8001:

case 0x8002:

if(Int2ABusy)

Int2ABusy--;

break;

default:

break;

}

_AX=r.ax;

(*OldInt2A)();

}

void TaskChange(void) /* Task Change Procedure */

{

nExe=1;

SaveDosSwap(); /* save SDA */

nExe=0;

RestoreDosSwap(); /* set new SDA */

IOFile(SDAMAP,(char *)&nPCB[1].psp,sizeof(PCB),WRITE);

Menu(); /* sub route */

IOFile(SDAMAP,(char *)&nPCB[1].psp,sizeof(PCB),READ);

SaveDosSwap();

nExe=1;

RestoreDosSwap(); /* restore old SDA */

}

void cccp(char *temp)

{

sprintf(sNameBuffer,"%s%s",sPath,temp);

spawnl(P_WAIT,sNameBuffer,sNameBuffer,temp2,NULL);

}

/* Define Sub program */

#define MENU "menu"

#define SAVEDISP "savedisp"

#define LOADDISP "loaddisp"

/* Define display filename */

#define DISPMAP "disp"

void Menu(void)

{

int nTmpTask;

/* Save Task's Vector */

IOFile(VECTMAP,(char far *)0l,1024,WRITE);

nTmpTask=uTask;

uTask=0;

/* restore raw vect for another task */

IOFile(VECTMAP,(char far *)0l,1024,READ_AND_NOT_DIRECT_PUT);

uTask=nTmpTask;

SaveAllMem(); /* save and clear memory */

sprintf(temp2," %s%s%d.map",sDisk,DISPMAP,uTask);/* sDisk is SwapDisk */

cccp(SAVEDISP); /* save and load display for menu to do.*/

sprintf(temp2," %s",sDisk);

poke(0,0x4f4,uTask);

cccp(MENU);

if((uTask=(int)peek(0,0x4f4))==-1) /* menu return value in this address.*/

DeleteTask(); /* all task exit memory */

Assert(uTask<=MAXUSERS);

if(IsTask[uTask]==0) /* Build a new task. */

{

IsTask[uTask]=1;

WantPopUp=0;

SubDos();

}

sprintf(temp2," %s%s%d.map",sDisk,DISPMAP,uTask);

cccp(LOADDISP); /* restore display */

LoadMem(GetMem()); /* restore memory */

/* Restore Task Vector */

IOFile(VECTMAP,(char far *)0l,1024,READ_AND_NOT_DIRECT_PUT);

}

/*

Memory MAP

___________

| intr |

| bios |

| dos |

| command |

| t a s k | _______ first swap seg

| |

| . |

| . |

| . |

| . |

| . |

| . |

___________ A000h

*/

void SaveAllMem(void)

{

WORD firstseg;

firstseg=GetMem();

SaveMem(firstseg);

SetMemFree(firstseg);

}

void SaveMem(WORD seg) /* from seg to 0xa000 save to file */

{

char huge *tmpptr;

tmpptr=(char huge *)MK_FP(seg,0);

MakeMapName(MEMORYMAP,1);

Assert(fp!=-1);

while(seg<=0xa000)

{

_write(fp,(char far *)tmpptr,BLOCKSIZE);

tmpptr+=BLOCKSIZE;

seg+=BLOCKSIZE/16;

}

_close(fp);

}

void SetMemFree(WORD seg) /* Let from seg to 0xa000 is */

{

mcbdesc.size=0xa000-seg-1; /* a free MCB */

movedata(_DS,FP_OFF(&(mcbdesc.attr)),

seg,0,16);

}

void LoadMem(WORD seg) /* load memory map from file */

{

char huge *tmpptr;

MakeMapName(MEMORYMAP,0);

tmpptr=(char huge *)MK_FP(seg,0);

Assert(fp!=-1);

while(seg<0xa000)

{

if((0xa000-seg)<32)

_read(fp,(char far *)tmpptr,(0xa000-seg)*16);

else

_read(fp,(char far *)tmpptr,BLOCKSIZE);

tmpptr+=BLOCKSIZE;

seg+=BLOCKSIZE/16;

}

_close(fp);

}

/*

Cation :

The next MCB is

first swap memory seg.

*/

/*

GetMem return's seg is next MCB,

It belone's sub command.com.

*/

WORD GetMem()

{

MCB far *p;

p=MK_FP(nPCB[0].psp-1,0);

return(nPCB[0].psp+p->size);

}

/*

Cation:

DeleteTask free DOS memory,restore raw vector,

but it not close other task's opening files. You

can use it, But remember this.

*/

void DeleteTask(void)

{

uTask=0;

SetMemFree(GetMem());

End();

exit(1);

}

#define WELLCOMEFILE "sptmap" /* PAGE */

#define HELPFILE "help" /* HELP */

void main(int argc,char *argv[])

{

char *s,*t;

Assert(argv[0]);

s=argv[0]; /* get task's path */

t=0;

for(;*s;s++)

{

if(*s=='\\')

t=s;

}

*(t+1)=0;

sprintf(sPath,"%s",argv[0]);

*t=0;

if(argc==2) /* get task's swapdisk */

sprintf(sDisk,"%s",argv[1]);

else

sprintf(sDisk,"%s",sPath);

temp2[0]=0;

cccp(WELLCOMEFILE); /* Page */

TaskMain(); /* MAIN ROUTE */

}

int MakeMapName(char *s,int mode) /* open a task's file */

{

sprintf(sNameBuffer,"%s%s%d.map",sDisk,s,uTask);

if(mode)

fp=_creat(sNameBuffer,FA_ARCH);

else

fp=_open(sNameBuffer,O_RDWR);

}

/* ctrl 0:read,1:write */

void IOFile(char *s,char *buf,WORD size,int ctrl)

{

int i;

long vector;

Assert(size<0x800);

if(ctrl==READ_AND_NOT_DIRECT_PUT)

{

i=1;

ctrl=READ;

}

else

i=0;

MakeMapName(s,ctrl);

Assert(fp!=-1);

if(ctrl==WRITE)

{

_write(fp,buf,size);

}

else

{

if(i) /* Can't direct put to Vectable */

{

for(i=0;i<256;i++)

{

_read(fp,(char far *)(&vector),4);

setvect(i,vector);

}

}

else

_read(fp,buf,size);

}

_close(fp);

}

void SubDos(void)

{

char *p;

p=getenv("COMSPEC");

spawnl(P_WAIT,p,p,"/p",NULL);

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有