⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcasm5b.c

📁 这是8位微处理器的Verilog源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
void find_mnemonic(FILE *fp_opcode,              \
			 unsigned char *line_buffer,   \
			 unsigned int length,          \
			 unsigned int mnemonic_lines,  \
			 unsigned int *result_buffer,
			 FILE *list_fp)
{
  int      i,j,k,t,p, reg, mnem_char, theword_len, qq;
  int      status;
  char     mnemonic[BL], mode, theword[BL];
  unsigned char *ptr, c, label_found;
  unsigned int opcode,match, immed;
  unsigned char immed_result[3];

  rewind(fp_opcode); // rewind opcode.dat file pointer to top
  status=0;

  // get next word from current line
  ptr=0;
  theword_len=find_word(line_buffer,&ptr,length,theword);

  // if current sourece code line contains 'end', we've reached end of source
  // code file, so exit out
  if((theword[0]=='E'&&theword[1]=='N'&&theword[2]=='D') || \
     (theword[0]=='e'&&theword[1]=='n'&&theword[2]=='d')   )
    return;

  // does this word cotain ':' ?, if so, we're looking at a
  // label and we want to skip over to next word
  for(i=0,label_found=0;i<theword_len;i++)
    if((c=theword[i])==':')
	 label_found=1;

  if (label_found==1)         // if label found, skip to next word
    theword_len=find_word(line_buffer,&ptr,length,theword);

  if(theword_len==0)          // if this new word is empty, no opcode here, exit
  { result_buffer[0]=1 | (label_found<<7);
    return;
  }

  for(j=0;j<mnemonic_lines;j++)
    {
	// clear mnemonic buffer
	for(k=0;k<BL;k++) mnemonic[k]=NULL;

	// load next mnemonic i.e. next line from opcode.dat
	fscanf(fp_opcode,"%s %d %x %c",mnemonic,&mnem_char,&opcode,&mode);

	// if mnemonic I read from opcode.dat is 'END' then entire table
	// has been search, so exit
	if ( (mnemonic[0]=="E")&&(mnemonic[1]=="N")&(mnemonic[2]=="D") )
	 return;

	// scan through the line_buffer looking for matches
	for(i=0,t=0,match=0;i<BL;i++)
	{ if((theword[t]==mnemonic[i]) || ((theword[t]-0x20)==mnemonic[i]))
	    t++;
	  else t=0;
	}

	// *** Matching opcode found ***
	if (t!=0)
	{ match=1;
	  break; // break out of the for loop
	}
    }

    if(match==1)
    {
	/*
	** UNARY OPCODE
	*/
	if( (match==1) && (mode=='U') )
	{
	  result_buffer[0]   = 0 | (label_found<<7); // opcode found and no error
	  result_buffer[1]   = 1;
	  result_buffer[2]   = opcode;
	  fprintf(list_fp,"** unary opcode found\n");
	  //rintf(list_fp,"\t %x\n",result_buffer[2]);
	  return;
	}

	/*
	** REGISTER DIRECT OPCODE, search for valid register
	*/
	if( (match==1) && (mode=='R') )
	{
	  fprintf(list_fp,"** register direct opcode found ");

	  // scan through the rest of line looking for valid reg name
	  // get next word.. hopeflly it is a valid reg name
	  theword_len=find_word(line_buffer,&ptr,length,theword);
	  reg=find_reg(fp_opcode,mnemonic_lines,theword);
	  #ifdef debug
		if (reg==-1) fprintf(list_fp,"** error reg not found\n");
		else fprintf(list_fp,"** reg found\n");
	  #endif

	  if(reg==-1) // valid opcode found, but there was error
		result_buffer[0]  = 2 | (label_found<<7);
	  else
	  {   result_buffer[0]      = 0 | (label_found<<7);
		result_buffer[1]      = 1;
		result_buffer[2]      = (opcode & 0xf8) | (reg & 0x07);
		i = (unsigned int) *(result_buffer+1);     // debug purpose
	  }
	  //fprintf(list_fp,"\t %x\n",result_buffer[2]);
	  return;
	}

	/*
	** (acc) IMMEDIATE OPCODE, search for valid data
	*/
	if( (match==1) && (mode=='I') )
	{
	  fprintf(list_fp,"** (acc) immediate opcode found ");

	  // scan through the line seraching for valid immediate value
	  // get next word.. hopeflly it is a valid immediate
	  theword_len=find_word(line_buffer,&ptr,length,theword);
	  find_immed(theword,theword_len,MODE_BYTE,immed_result);
	  if(immed_result[0]==0)
	  {
	    fprintf(list_fp," immed found \n");
	    result_buffer[0]    =0 | (label_found<<7);
	    result_buffer[1]    =2;
	    result_buffer[2]    =opcode;
	    result_buffer[3]    =immed_result[1];

	    //fprintf(list_fp,"\t %x %x\n",result_buffer[2],result_buffer[3]);
	    return;

	  }
	  else
	  {
	    fprintf(list_fp," err with immed \n");
	    result_buffer[0]    =2|(label_found<<7);
	    return;
	  }
	}

	/*
	** (reg) IMMEDIATE OPCODE, search for valid reg
	**                         search for valid data
	**/
	if( (match==1) && (mode=='A') )
	{
	  fprintf(list_fp,"** (reg) immediate opcode found ");

	  // scan through the rest of the line to find valid reg
	  theword_len=find_word(line_buffer,&ptr,length,theword);
	  reg=find_reg(fp_opcode,mnemonic_lines,theword);
	  #ifdef debug
		if (reg==-1) fprintf(list_fp,"** error reg not found\n");
		else fprintf(list_fp,"** reg found ");
	  #endif
	  if(reg==-1)
	  { result_buffer[0] = 2 | (label_found<<7); //opcode has invalid register
	    return;
	  }

	  // scan through the line seraching for valid immediate value
	  theword_len=find_word(line_buffer,&ptr,length,theword);
	  find_immed(theword,theword_len,MODE_BYTE,immed_result);
	  if(immed_result[0]==0)
	  {
	    fprintf(list_fp," immed found \n");
	    result_buffer[0]    =0 | (label_found<<7);
	    result_buffer[1]    =2;
	    result_buffer[2]    =(opcode & 0xc7) | ( (reg & 0x07) <<3 );
	    result_buffer[3]    =immed_result[1];

	    //fprintf(list_fp,"\t %x %x\n",result_buffer[2],result_buffer[3]);
	    return;
	  }
	  else
	  {
	    fprintf(list_fp," err with immed \n");
	    result_buffer[0]    =2 | (label_found<<7);  // error with immediate value
	    return;
	  }

	}


	/*
	** (memory) DIRECT OPCODES, serach for valid reg
	**                        , search for valid addx
	**
	*/
	if( (match==1) && (mode=='D') )
	{
	  fprintf(list_fp,"** (mem) direct opcode found ");

	  // scan through the rest of the line to find valid reg
	  theword_len=find_word(line_buffer,&ptr,length,theword);
	  reg=find_reg(fp_opcode,mnemonic_lines,theword);
	  #ifdef debug
		if (reg==-1) fprintf(list_fp,"** error reg not found\n");
		else fprintf(list_fp,"** reg found ");
	  #endif
	  if(reg==-1)
	  { result_buffer[0] = 2 | (label_found<<7); //opcode has invalid register
	    return;
	  }

	  // scan through the line seraching for valid addx
	  theword_len=find_word(line_buffer,&ptr,length,theword);
	  find_immed(theword,theword_len,MODE_ADDX,immed_result);
	  if(immed_result[0]==0)
	  {
	    fprintf(list_fp," addx found \n");
	    result_buffer[0]    =0 | (label_found<<7);
	    result_buffer[1]    =3;
	    result_buffer[2]    =(opcode & 0xF8) | (reg & 0x07);
	    result_buffer[3]    =immed_result[1];
	    result_buffer[4]    =immed_result[2];

	    //fprintf(list_fp,"\t %x %x %x\n",result_buffer[2],result_buffer[3], \
			result_buffer[4]);
	    return;
	  }
	  else
	  {
	    fprintf(list_fp," err with addx \n");
	    result_buffer[0]    =2|(label_found<<7);  // error with addx value
	    return;
	  }

	}

	/*
	** BRANCHING OPCODE, search for valid address
	**
	*/
	if( (match==1) && (mode=='B') )
	{
	 fprintf(list_fp,"** branching opcode found ");

	 // get next word
	 theword_len=find_word(line_buffer,&ptr,length,theword);

	 // if this word does not contain '#' then, it is considered
	 // as a label
	 for(i=0,qq=0;i<theword_len;i++)
	  if((c=theword[i])=='#')
	    qq=1;

	 if(qq==0)
	 {
	   fprintf(list_fp,"label found \n");
	   result_buffer[0]    =3|(label_found<<7);   //branching opcode w/ label found
	   result_buffer[1]    =3;
	   result_buffer[2]    =opcode;
	   result_buffer[3]    =0;
	   result_buffer[4]    =0;

	   result_buffer[5]    =theword_len;   // lenght of label
	   for(i=0;i<theword_len;i++)          // on the rest of result_buffer
	   {  result_buffer[i+6] = theword[i];  // copy the label
		c=(unsigned char)result_buffer[i+6];  // debug
	   }
	 }
	 else
	 {
	  find_immed(theword,theword_len,MODE_ADDX,immed_result);
	  if(immed_result[0]==0)
	  {
	    fprintf(list_fp," addx found \n");
	    result_buffer[0]    =0|(label_found<<7);
	    result_buffer[1]    =3;
	    result_buffer[2]    =opcode;
	    result_buffer[3]    =immed_result[1];
	    result_buffer[4]    =immed_result[2];
	  }
	 }

	 //fprintf(list_fp,"\t %x %x %x\n",result_buffer[2],result_buffer[3], \
		    result_buffer[4]);
	 return;
     }


//	 fprintf(list_fp,"\n");
   }
   else
   {
     fprintf(list_fp,"no match\n");
     result_buffer[0]=1|(label_found<<7);  // no opcode found, but no error
   }

   // clear mnemonic buffer
   for(k=0;k<7;k++)
   mnemonic[k]=NULL;



}


/*
** int find_reg( )
**
** search through the "line_buffer" looking for a
** valid register.
**
** input:
**          FILE          *fp_opcode      file pointer to opcode.dat
**          unsiigned int mnemonic_line   line count from opcode.dat
**          unsigned char *theword        pointer to word buffer
**
** output:
**          -1    : no match found
**          0     : found 'ACC'  or 'acc'
**          1     : found 'AX'   or 'ax'
**          2     : found 'BX'   or 'bx'
**          4     : found 'FLAG' or 'flag'
**          5     : found 'PORT' or 'port'
**
**
**
*/
int find_reg(FILE *fp_opcode,             \
		 unsigned int mnemonic_line,  \
		 unsigned char *theword        )

{
 FILE *fp_opcode_save;
 int t,i,j,k,match,opcode,mnem_char;
 unsigned char mnemonic[BL],mode;


 rewind(fp_opcode);

 for(i=0,match=0;i<mnemonic_line;i++)
 {
    // clear mnemonic buffer
    for(k=0;k<BL;k++) mnemonic[k]=NULL;

    // load next mnemonic i.e. next line from opcode.dat
    fscanf(fp_opcode,"%s %d %x %c",mnemonic,&mnem_char,&opcode,&mode);

    // if mnemonic I read from opcode.dat is 'END' then entire table
    // has been search, so break out of loop
    if ( (mnemonic[0]=='E')&&(mnemonic[1]=='N')&&(mnemonic[2]=='D') )
     break;

    // scan through the line_buffer looking for matches
    for(i=0,t=0,match=0;i<BL;i++)
    { if((theword[t]==mnemonic[i]) || ((theword[t]-0x20)==mnemonic[i]))
	  t++;
	  else t=0;
    }

    // if match found, immediately break out of the for loop
    if(t!=0)
	break;

 }

 if(t!=0) return(opcode);
 else return(-1);


}


/*
** void find_immed
**
** see if the literal characters in 'theword' buffer is a valid
** number representation, if so convert it to binary and
** exit
**
** inputs:  unsigned char *theword        buffer containing literal chars
**          unsigned int  theword_len     length of the literal chars
**          unsigned int  mode            mode=0
**                                              expecting 8 bit data
**                                              expecting 12 bit addx
**          unsigned char immed_result    pointer to result array
**
**
** output:  int *immed_result              result array
**
**          immed_result[0]               status
**                      0     succesful
**                      1     out of range
**                      2     not valid number,
**                                  missing # or
**                                  missing radix or
**                                  has non-numerical chars
**          immed_Result[1-2] data: lsb, msb
**
*/
void find_immed(unsigned char *theword,    \
		    unsigned int  theword_len, \
		    unsigned int  mode,        \
		    unsigned char *immed_result            )
{
	int               i,j,k,found_radix,found_num;
	unsigned char     c;
	unsigned int      temp,x,y;

  // See if the literal number is correct
	// see if the number sign and radix are present
	if( theword[0]!='#'|| \
	    (theword[theword_len-1]!='h' && theword[theword_len-1]!='H') )
	{ immed_result[0] = 2;
	  return;
	}

     // see if there are bogus characters != (0-9, a-f)
     for(i=1;i<(theword_len-1);i++)
     { c=theword[i];
	 if( (c<'0') || ((c>'9')&&(c<'A')) || ((c>'F')&&(c<'a')) || \
	     (c>'f') )
	 { immed_result[0]=2;
	   return;
	 }
     }

     // convert the ASCII to numbers
     for(i=1;i<(theword_len-1);i++)
     { c=theword[i];
	 if( (c>='0')&&(c<='9') )
	  theword[i]=(unsigned int)theword[i]-0x30;
	 else if( (c>='A')&&(c<='F') )
	  theword[i]=theword[i]-0x37;
	 else if( (c>='a')&&(c<='f') )
	  theword[i]=theword[i]-0x57;
	 x=theword[i];
     }

     // check for overrange
     temp=0;
     for(i=1;i<(theword_len-1);i++)
     {//  temp += theword[i] * pow(16,(theword_len-2-i)) ;
	x=theword[i];
	y=theword_len;
	y=y-2;
	y=y-i;
	y=pow(16,y);
	x=x * y;
	temp=temp+x;
     }
     if( ((mode==0)&&(temp>(pow(2,8)-1)))||((mode==1)&&(temp>(pow(2,12)-1))) )
     { immed_result[0] = 1;
	 return;
     }


  // if no more errors let's do some work
     if(mode==0)
     { immed_result[0] = 0;
	 immed_result[1] = temp;
	 return;
     }

     if(mode==1)
     { immed_result[0] = 0;
	 immed_result[1] = temp%256;
	 immed_result[2] = temp/256;
	 x=immed_result[1];
	 y=immed_result[2];
	 return;
     }
}


/*
** void find_word( )
**
** given a buffer, extract a "word" surrounded by delimeters
** delimeters can be commas, space, tabs or newline
** 'theword' buffer is converted to all caps.
**
** input:   unsigned char  *buffer   pointer to the buffer, must be
**                                   null terminated
**          unsigned int   *buff_ptr starting location in the buffer
**          unsigned int   buffer_len length of the buffer
**          unsigned char  *word     pointer to the word buffer where
**                                   the found word will be dumped
**
** output:  o *buff_ptr will be updated to where it last found the word
**             delimiter
**          o buffer 'word' will have the NULL terminated word
**            the 'word' buffer will be empty if there was no delimeter
**            in the buffer given to scan or if the given buffer has
**            length of zero
**
**
*/
int find_word( unsigned char *buffer,    \
		   unsigned int  *buff_ptr,  \
		   unsigned int  buffer_len, \
		   unsigned char *theword )
{
  int i,t,ena;
  unsigned char c,c2;

  // clear 'theword' buffer
  for(i=0;i<BL;i++)
    *(theword+i)=NULL;


  // advance the buffer pointer until no delimiter is found
  i=0; c=buffer[*buff_ptr+i];
  while((c==' ')||(c=='\t')||(c==CR)||(c==','))
  {  i++;
     c=buffer[*buff_ptr+i];
  }
  *buff_ptr=*buff_ptr+i;

  // go through the line_buffer and extract a word
  // rules: start when beginning of buffer or blank or tab is found
  //        end   when end of buffer or blank or tab is found
  i=0;
  while((c!=NULL)&&(c!=' ')&&(c!='\t')&&(c!=NL)&&(c!=',')&&((*buff_ptr+i)!=buffer_len))
  {  c=buffer[*buff_ptr+i];
     theword[i]=c;
     i++;
  }

  if((*buff_ptr+i)==buffer_len)
  { *buff_ptr=*buff_ptr+i;
    theword[i]=NULL;
    return(i);
  }
  else
  { *buff_ptr=*buff_ptr+i-1;
    theword[i-1]=NULL;
    return(i-1);
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -