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


// Mos_input.cpp: implementation of the CMos_input class. 
// Wrote by Wang Hao. Released April,2002. 
// Copyright (C) 2002 by Wang Hao. 
// All rights reserved. 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "Mos.h" 
#include "Mos_input.h" 
#include "Mos_io.h" 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
extern JCB m_jcb; 
extern CMos_io m_io; 
extern CVCS m_cpu; 
extern PCB m_pcb; 
extern CMos_stor m_stor; 
CMos_input::CMos_input() 
{ 
	Bufflen = 40; 
	Data[40] = '\0'; 
} 
 
CMos_input::~CMos_input() 
{ 
 
} 
 
void CMos_input::FillJcb(jcbtype* &pJ) 
{ 
	pJ->name[0]=Buffer[7]; 
	pJ->name[1]=Buffer[8]; 
	pJ->name[2]=Buffer[9]; 
	pJ->name[3]=Buffer[10]; 
	pJ->error=0; 
	pJ->time=(Buffer[12]-0x30)*1000+(Buffer[13]-0x30)*100+(Buffer[14]-0x30)*10+(Buffer[15]-0x30); 
	pJ->line=(Buffer[17]-0x30)*1000+(Buffer[18]-0x30)*100+(Buffer[19]-0x30)*10+(Buffer[20]-0x30); 
	pJ->rpadd=-1; 
	pJ->rdadd=-1; 
	pJ->wdadd=-1; 
	pJ->wdlen=pJ->line*10; 
	pJ->rdlen=0; 
	pJ->rplen=0; 
	pJ->jcputime=0; 
	pJ->jio=0; 
} 
 
jcbtype* CMos_input::jcb_allocation() 
{ 
	jcbtype* pJ; 
	if(m_jcb.jcbfree_head==NULL) return NULL;//失败 
	pJ = m_jcb.jcbfree_head; 
	m_jcb.jcbfree_head = m_jcb.jcbfree_head->jnext; 
	pJ->jnext = NULL; 
	if(m_jcb.jcbfree_head==NULL) 
		m_jcb.jcbfree_tail = NULL; 
	m_jcb.free_jcb_count--; 
	CString str; 
	str.Format("%d",JCBMAX-m_jcb.free_jcb_count); 
	m_UI.DealWithUI(str,IDC_STATIC_JN); 
	return pJ; 
} 
 
void CMos_input::getins() 
{ 
	int k=0; 
	while(Buffer[k]==' ') k++; 
	Data[Ptr]=Buffer[k]; 
	Data[Ptr+1]=Buffer[k+1]; 
	Data[Ptr+2]=Buffer[k+2]; 
	Data[Ptr+3]=Buffer[k+3]; 
	if(Data[Ptr+1]=='\n')//例如H 
		Data[Ptr+1]=Data[Ptr+2]=Data[Ptr+3]=' '; 
	else if(Data[Ptr+2]=='\n')//例如GT 
		Data[Ptr+2]=Data[Ptr+3]=' '; 
    else if(Data[Ptr+3]=='\n') 
		Data[Ptr+3]=' '; 
} 
 
int CMos_input::getdata() 
{ 
	while(Bptr<=Bufflen-1) 
	{ 
		if(Buffer[Bptr]=='*')  return 1;//读到'*' 
		if(Buffer[Bptr]!=' ') 
		{ 
			if(Buffer[Bptr]=='+') 
				Data[Ptr]='0'; 
			else Data[Ptr]=Buffer[Bptr]; 
			Bptr++; 
			Ptr++; 
			if(Ptr==40) 
				return 2;//Data[]满,但还没读到'*' 
		} 
		else Bptr++;//跳过空格 
	} 
   return 3;//Data[]未读完,未遇到'*' 
} 
////////////////////////////////////////////////////////////////// 
//P1 pre_input() 
////////////////////////////////////////////////////////////////// 
 
void CMos_input::pre_input() 
{ 
	static jcbtype* curr_jcb; //当前JCB指针 
	static maptype* dskptr;//磁盘分配指针 
	static int pcode;//指令指针 
	static int pdata;//数据指针 
	int i; 
	m_cpu.kerneltime++; 
	switch(m_pcb.curr_pcb->step) 
	{ 
	case 0:m_pcb.curr_pcb->step=1; 
		   m_io.rkbln(Buffer);//从KB读一行到输入缓冲区 
		   return; 
//1/////////////////////////////////////////////////////////////////////////// 
	case 1:if(Buffer[0]=='$'&&Buffer[1]=='J'&&Buffer[2]=='O'&&Buffer[3]=='B') 
			{//Is $JOB? 
				m_pcb.curr_pcb->step=2; 
				m_io.rkbln(Buffer); 
				return; 
			} 
			else{ 
					m_proc.sleep(KBEND);//miss $JOB 
					AfxMessageBox("Job Miss '$JOB'!"); 
					m_cpu.FatalError = true; 
					return; 
			} 
//2/////////////////////////////////////////////////////////////////////////// 
step2:case 2:if(Buffer[0]=='$'&&Buffer[1]=='B'&&Buffer[2]=='E'&&Buffer[3]=='G'&&Buffer[4]=='I'&&Buffer[5]=='N') 
				m_pcb.curr_pcb->step=3;//Is $BEGIN? 
			else{ 
					m_proc.sleep(KBEND);//miss $BEGIN 
					AfxMessageBox("Job Miss '$BEGIN'!"); 
					m_cpu.FatalError = true; 
					return; 
			} 
//3////////////////////////////////////////////////////////////////////////// 
	case 3:if((curr_jcb=jcb_allocation())!=NULL) 
			{ 
				FillJcb(curr_jcb); //填JCB表 
				Ptr=0; 
				m_pcb.curr_pcb->step=4; 
				m_io.rkbln(Buffer); 
				return; 
			} 
			else{ 
					if(m_pcb.jcbnull_head!=NULL) 
						m_proc.wakeup(JCBNULL);//唤醒P2; 
					m_proc.sleep(JCBFULL); 
					return; 
			} 
//4/////////////////////////////////////////////////////////////////////////// 
	case 4:if(Buffer[0]=='$'&&Buffer[1]=='P'&&Buffer[2]=='O'&&Buffer[3]=='B') 
			{//Is $POB? 
				m_pcb.curr_pcb->step=5; 
				m_io.rkbln(Buffer); 
				return; 
			} 
			else{ 
					m_proc.sleep(KBEND); 
					AfxMessageBox("Job Miss '$POB'!"); 
					m_cpu.FatalError = true; 
					return; 
			} 
//5////////////////////////////////////////////////////////////////////////// 
	case 5:if(Buffer[0]=='$'&&Buffer[1]=='P'&&Buffer[2]=='O'&&Buffer[3]=='E') 
			{//Is $POE? 
				m_pcb.curr_pcb->step=8; 
				goto step8; 
			} 
			else{ 
					if(Buffer[0]=='$') 
					{ 
						m_proc.sleep(KBEND);//miss $POE 
						AfxMessageBox("Job Miss '$POE'!"); 
						m_cpu.FatalError = true; 
						return; 
					} 
					getins();//从Buffer[]取指令送Data[] 
					Ptr+=4; 
					if(Ptr==40) 
					{ 
						m_pcb.curr_pcb->step=6; 
						Ptr=0; 
					} 
					else{ 
							m_pcb.curr_pcb->step=5; 
							m_io.rkbln(Buffer); 
							return; 
					} 
			} 
//6/////////////////////////////////////////////////////////////////////////// 
	case 6:if(m_stor.dsk_allocation(1,dskptr)) 
			{ 
				if(curr_jcb->rpadd==-1)//是第一块 
				{ 
					pcode=dskptr->index; 
					curr_jcb->rpadd=dskptr->index; 
				}//磁盘分配地址保存到JCB表 
				curr_jcb->rplen+=10; 
				if(curr_jcb->rplen>100)//指令超过100条 
				{ 
					m_proc.sleep(KBEND); 
					AfxMessageBox("指令超过100条!"); 
					m_cpu.FatalError = true; 
					return; 
				} 
				m_pcb.curr_pcb->step=7; 
			} 
			else{//分配不成功 
					m_proc.sleep(DSKFULL); 
					return; 
			} 
//7/////////////////////////////////////////////////////////////////////////// 
	case 7: m_pcb.curr_pcb->step=16; 
			m_stor.DSKMTB[pcode].forwp=dskptr;//链下一块 
			pcode=dskptr->index; 
			m_io.wdsk(10,Data,dskptr->index);//从Data[]写到磁盘 
			for(i=0;i<40;i++) 
				Data[i]='\0';//清空Data[] 
			Ptr=0; 
			return; 
//8/////////////////////////////////////////////////////////////////////////// 
step8:case 8: if(m_stor.dsk_allocation(1,dskptr)) 
			{ 
				if(curr_jcb->rpadd==-1) 
				{//是分配的第一块 
					pcode=dskptr->index; 
					curr_jcb->rpadd=dskptr->index; 
				} 
				else{//链下一块 
						m_stor.DSKMTB[pcode].forwp=dskptr; 
						pcode=dskptr->index; 
				} 
				m_pcb.curr_pcb->step=9; 
				curr_jcb->rplen+=10; 
				if(curr_jcb->rplen>100) 
				{ 
					m_proc.sleep(KBEND);//多于100条指令 
					AfxMessageBox("指令超过100条!"); 
					m_cpu.FatalError = true; 
					return; 
				} 
				m_io.wdsk(10,Data,dskptr->index); 
				for(int i=0;i<40;i++) 
					Data[i]='\0';//清空 
				Ptr=0; 
				return; 
			} 
			else{//不成功 
					m_proc.sleep(DSKFULL); 
					return; 
			} 
//9/////////////////////////////////////////////////////////////////////////// 
	case 9: m_pcb.curr_pcb->step=10; 
			m_io.rkbln(Buffer); 
			return; 
//10/////////////////////////////////////////////////////////////////////////// 
	case 10:if(Buffer[0]=='$'&&Buffer[1]=='D'&&Buffer[2]=='A'&&Buffer[3]=='T'&&Buffer[4]=='A') 
			{//is $DATA? 
				Bptr=Ptr=0; 
				m_pcb.curr_pcb->step=11; 
				m_io.rkbln(Buffer); 
				return; 
			} 
			else{//将该JCB链到后备队列并唤醒P2 
					if(m_jcb.jcb_head==NULL) 
					{ 
						m_jcb.jcb_head=m_jcb.jcb_tail=curr_jcb; 
						m_jcb.jcb_tail->jnext=NULL; 
					} 
					else{ 
							m_jcb.jcb_tail->jnext=curr_jcb; 
							m_jcb.jcb_tail=curr_jcb; 
							m_jcb.jcb_tail->jnext=NULL; 
						} 
					if((curr_jcb->rdlen-curr_jcb->rdlen/10*10)>0) 
						curr_jcb->rdlen=(curr_jcb->rdlen/10+1)*10; 
					if(m_pcb.jcbnull_head!=NULL) 
						m_proc.wakeup(JCBNULL); 
					m_pcb.curr_pcb->step=15; 
					goto step15; 
			} 
//11/////////////////////////////////////////////////////////////////////////// 
	case 11:if(Buffer[0]=='$'&&Buffer[1]=='D'&&Buffer[2]=='O'&&Buffer[3]=='E')//is $DOE? 
			{//将该JCB链到后备队列 
				if(m_jcb.jcb_head==NULL) 
				{ 
					m_jcb.jcb_head=m_jcb.jcb_tail=curr_jcb; 
					m_jcb.jcb_tail->jnext=NULL; 
				} 
				else{ 
						m_jcb.jcb_tail->jnext=curr_jcb; 
						m_jcb.jcb_tail=curr_jcb; 
						m_jcb.jcb_tail->jnext=NULL; 
				} 
				if((curr_jcb->rdlen-curr_jcb->rdlen/10*10)>0) 
					curr_jcb->rdlen=(curr_jcb->rdlen/10+1)*10; 
				if(m_pcb.jcbnull_head!=NULL) 
					m_proc.wakeup(JCBNULL); 
				m_pcb.curr_pcb->step=15; 
				m_io.rkbln(Buffer); 
				return; 
			} 
			else m_pcb.curr_pcb->step=12; 
//12//////////////////////////////////////////////////////////////////////////// 
step12:case 12:if(Buffer[0]=='$') 
			{ 
				m_proc.sleep(KBEND);//miss $DOE 
				AfxMessageBox("Job Miss '$DOE'!"); 
				m_cpu.FatalError = true; 
				return; 
			} 
			//读数据到Data[] 
			if(getdata()==3) 
			{//继续读 
				m_pcb.curr_pcb->step=11; 
				m_io.rkbln(Buffer); 
				return; 
			} 
			else{ 
					curr_jcb->rdlen+=Ptr/4; 
					m_pcb.curr_pcb->step=13; 
			} 
//13/////////////////////////////////////////////////////////////////////////// 
	case 13:if(m_stor.dsk_allocation(1,dskptr)) 
			{//分配成功,建立磁盘链并把Data[]写到磁盘 
				m_pcb.curr_pcb->step=14; 
				if(curr_jcb->rdadd==-1) 
				{ 
					pdata=dskptr->index; 
					curr_jcb->rdadd=dskptr->index; 
				} 
				else{ 
						m_stor.DSKMTB[pdata].forwp=dskptr; 
						pdata=dskptr->index; 
					} 
				m_io.wdsk(10,Data,dskptr->index); 
				return; 
			} 
			else{ 
					m_proc.sleep(DSKFULL); 
					return; 
			} 
//14/////////////////////////////////////////////////////////////////////////// 
	case 14:Ptr=0; 
			if(Bptrstep=12; 
				goto step12; 
			} 
			else{ 
					Bptr=0; 
					m_pcb.curr_pcb->step=11; 
					m_io.rkbln(Buffer); 
					return; 
			} 
//15/////////////////////////////////////////////////////////////////////////// 
step15:case 15:if(Buffer[0]=='$'&&Buffer[1]=='J'&&Buffer[2]=='O'&&Buffer[3]=='E') 
			{//is $JOE? 
				m_pcb.curr_pcb->step=0; 
				m_proc.sleep(KBEND);//处理完,正常睡眠 
				return; 
			} 
			else{ 
					m_pcb.curr_pcb->step=2; 
					goto step2; 
			} 
//16/////////////////////////////////////////////////////////////////////////// 
	case 16:m_pcb.curr_pcb->step=5; 
			m_io.rkbln(Buffer); 
			return; 
	}//end of switch 
}