www.pudn.com > Mos.rar > VCS.cpp


// VCS.cpp: implementation of the CVCS class. 
// Wrote by Wang Hao&Wu Yong. Released April,2002. 
// Copyright (C) 2002 by Wang Hao&Wu Yong. 
// All rights reserved. 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "Mos.h" 
#include "VCS.h" 
#include "PCB.h" 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
CVCS m_cpu; 
extern PCB m_pcb; 
CVCS::CVCS() 
{ 
 
} 
 
CVCS::~CVCS() 
{ 
 
} 
 
BOOL CVCS::Test() 
{ 
	if(PI+SI+TI+IOI>0) 
		return TRUE; 
	else  
		return FALSE; 
} 
 
void CVCS::VCS() 
{ 
	int ipc = 0; 
	int addr1 = 0,addr2 = 0; 
	for(;;) 
	{ 
		m_pcb.curr_pcb->cputime++; 
		m_cpu.usertime++; 
		addr1 = ipc = (PC[1]-0x30)*10 + (PC[0]-0x30); 
		ipc++; 
		PC[1] =	char(ipc/10)+0x30;//high 
		PC[0] = ipc%10+0x30;//low 
		mapy(addr1); 
		addr2 = (memory[addr1].op3-0x30)*10 + (memory[addr1].op4 -0x30); 
		//op3: x1,op4: x2 
		switch(memory[addr1].op1) 
		{ 
			case 'L':LR(addr2);break; 
			case 'C':CR(addr2);break; 
			case 'A':AD(addr2);break; 
			case 'R':SI=1;break; 
			case 'W':SI=2;break; 
			case 'G':SI=3;break; 
			case 'H':SI=4;break; 
			case 'S':switch(memory[addr1].op2) 
					 { 
						case 'R':SR(addr2);break; 
						case 'U':SU(addr2);break; 
						default:PI=2;break; 
					 } 
					break; 
			case 'B':switch(memory[addr1].op2) 
					{ 
						case 'T':BT(addr2);break; 
						case 'N':BN(addr2);break; 
						case 'U':BU(addr2);break; 
						default:PI=2;break; 
					} 
					break; 
			default:PI=2;break; 
		} 
		clock(); 
		if(Test()){ 
			MODE = KERNELMODE; 
			return;//有中断 
		} 
	}//end of for(;;) 
} 
 
bool CVCS::mapy(int &adr)//adr: pc寄存器内容 or 指令中 x1x2 
/* 
regptr:|op4|op3|op2|op1| 
        [3] [2] [1] [0] 
*/ 
{ 
	char a1 = PTR.op2;//op2 l-1 
	char a2 = PTR.op3;//op3 x1 
	char a3 = PTR.op4;//op4 x2 
	int m = (a2-'0')*10+(a3-'0');  //取得页表基址 
	int x1 = (int)(adr/10);//取得逻辑页号 
	int x2 = adr%10; //取得页内位移 
	if(x1 > (a1-'0')) 
	{ 
		PI = 1; 
		return false; //映射不成功 
	} 
	else 
	{ 
		char bi1 = memory[m*10+x1].op1;//0 0 
		char bi2 = memory[m*10+x1].op2;//1 2 
		int n = (bi1-'0')*10+(bi2-'0');//取得实际物理页号 
		n*=10;//得相应物理页起始下标 
		adr = n+x2;//加页内位移,得指令、数据的物理下标 
		return true; 
	} 
} 
 
void CVCS::clock() 
{ 
	CString str; 
	rtime++; 
	time--; 
	if(time == 0) 
		TI = 1; 
	if(CHST[0]+CHST[1]+CHST[2]>0) 
	{//通道计时 
		for(int i = 0;i<=2;i++) 
			if(CHST[i]==BUSY){ 
				CHCOUNT[i]--; 
				str.Format("%d",CHCOUNT[i]); 
				m_UI.DealWithUI(str,IDC_STATIC_IOKB-i); 
			} 
 
		if(CHCOUNT[0]==0&&CHST[0]==BUSY) 
		{ 
			IOI = 1; 
			CHST[0] = FREE; 
			if(CHCOUNT[1]==0&&CHST[1]==BUSY) 
			{ 
				IOI = 4; 
				CHST[1] = FREE; 
				if(CHCOUNT[2]==0&&CHST[2]==BUSY) 
				{ 
					IOI = 7; 
					CHST[2] = FREE; 
				} 
			} 
			else if(CHCOUNT[2]==0&&CHST[2]==BUSY) 
			{ 
				IOI = 5; 
				CHST[2] = FREE; 
			} 
		}//end of if(CHCOUNT[0]==0) 
		else if(CHCOUNT[1] == 0&&CHST[1]==BUSY) 
		{ 
			IOI = 2; 
			CHST[1] = FREE; 
			if(CHCOUNT[2]==0&&CHST[2]==BUSY) 
			{ 
				IOI = 6; 
				CHST[2] = FREE; 
			} 
		} 
		else if(CHCOUNT[2]==0&&CHST[2]==BUSY) 
		{ 
			IOI = 3; 
			CHST[2] = FREE; 
		} 
		for(i=0;i<=2;i++){ 
			if(CHST[i]==FREE) m_UI.DealWithUI("FREE",IDC_STATIC_KBS+i); 
			else if(CHST[i]==BUSY) m_UI.DealWithUI("BUSY",IDC_STATIC_KBS+i); 
		} 
	}//end of if 
} 
 
void CVCS::LR(int &addr) 
/*     ___ ___ ___ ___ 
R:高->|op1|op2|op3|op4|->低 
       R[3]R[2]R[1]R[0] 下同   
*/ 
{ 
	mapy(addr); 
	R[3] = memory[addr].op1; 
	R[2] = memory[addr].op2; 
	R[1] = memory[addr].op3; 
	R[0] = memory[addr].op4; 
} 
 
void CVCS::SR(int &addr) 
{ 
	char oldch[8],newch[8]; 
	for(int i=0;i<=6;i++) 
		oldch[i] = newch[i] = ' '; 
	newch[7] = oldch[7] = '\0'; 
	mapy(addr); 
	oldch[0] = memory[addr].op1; 
	oldch[2] = memory[addr].op2; 
	oldch[4] = memory[addr].op3; 
	oldch[6] = memory[addr].op4; 
	newch[0] = memory[addr].op1 = R[3]; 
	newch[2] = memory[addr].op2 = R[2]; 
	newch[4] = memory[addr].op3 = R[1]; 
	newch[6] = memory[addr].op4 = R[0]; 
	m_UI.UpdateList(IDC_LIST1,oldch,addr,newch); 
} 
 
void CVCS::CR(int &addr) 
{ 
	mapy(addr); 
	if(memory[addr].op1==R[3]&&memory[addr].op2 == R[2]&& 
	   memory[addr].op3==R[1]&&memory[addr].op4 == R[0]) 
	   C = 'T'; 
	else C = 'F'; 
} 
 
void CVCS::BT(int &addr) 
/* 
PC:high|x1|x2|low 
		1  0 
*/ 
{ 
	if(C == 'T')  
		addr = (PC[1]-0x30)*10+(PC[0]-0x30); 
} 
 
void CVCS::AD(int &addr) 
{ 
	mapy(addr); 
	int a,b; 
	b=(R[2]-0x30)*100+(R[1]-0x30)*10+(R[0]-0x30); 
	if(R[3]=='-') b=-b; 
	else b+=(R[3]-0x30)*1000; 
	 
	a=(memory[addr].op2-0x30)*100+(memory[addr].op3-0x30)*10+(memory[addr].op4-0x30); 
	if(memory[addr].op1=='-') a=-a; 
	else a+=(memory[addr].op1-0x30)*1000; 
 
	b += a; 
	if(b<0){ 
		R[3] = '-'-0x30; 
		b = -b; 
		R[2] = b/100; 
	} 
	else{ 
			R[3] = b/1000; 
			R[2] = (b-R[3]*1000)/100; 
	} 
	R[0] = b%10; 
	R[1] = (b-R[0])%100/10; 
	for(a=0;a<=3;a++) 
		R[a] += 0x30; 
} 
 
void CVCS::SU(int &addr) 
{ 
	mapy(addr); 
	int a,b; 
	b=(R[2]-0x30)*100+(R[1]-0x30)*10+(R[0]-0x30); 
	if(R[3]=='-') b=-b; 
	else b+=(R[3]-0x30)*1000; 
	a=(memory[addr].op2-0x30)*100+(memory[addr].op3-0x30)*10+(memory[addr].op4-0x30); 
	if(memory[addr].op1=='-') a=-a; 
	else a+=(memory[addr].op1-0x30)*1000; 
 
	b -= a; 
	if(b<0){ 
		R[3] = '-'-0x30; 
		b = -b; 
		R[2] = b/100; 
	} 
	else{ 
			R[3] = b/1000; 
			R[2] = (b-R[3]*1000)/100; 
	} 
	R[0] = b%10; 
	R[1] = (b-R[0])%100/10; 
	for(a=0;a<=3;a++) 
		R[a] += 0x30; 
} 
 
void CVCS::BN(int &addr) 
{ 
	if(R[3] == '-'){ 
		PC[0] = addr%10 + 0x30; 
		PC[1] = addr/10 + 0x30; 
	} 
} 
 
void CVCS::BU(int &addr) 
{ 
	PC[0] = addr%10 + 0x30; 
	PC[1] = addr/10 + 0x30; 
} 
 
void CVCS::GT() 
{	 
	R[3] = rtime/1000; 
	R[2] = (rtime-R[3]*1000)/100; 
	R[0] = rtime%10; 
	R[1] = (rtime-R[0])%100/10; 
	for(int i=0;i<=3;i++) 
		R[i] +=  0x30; 
}