OpenCores
URL https://opencores.org/ocsvn/plasma/plasma/trunk

Subversion Repositories plasma

[/] [plasma/] [trunk/] [tools/] [mlite.c] - Diff between revs 104 and 137

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 104 Rev 137
Line 12... Line 12...
--------------------------------------------------------------------*/
--------------------------------------------------------------------*/
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <ctype.h>
#include <ctype.h>
 
#include <assert.h>
 
 
#define MEM_SIZE (1024*1024*2)
#define MEM_SIZE (1024*1024*2)
#define ntohs(A) ( ((A)>>8) | (((A)&0xff)<<8) )
#define ntohs(A) ( ((A)>>8) | (((A)&0xff)<<8) )
#define htons(A) ntohs(A)
#define htons(A) ntohs(A)
#define ntohl(A) ( ((A)>>24) | (((A)&0xff0000)>>8) | (((A)&0xff00)<<8) | ((A)<<24) )
#define ntohl(A) ( ((A)>>24) | (((A)&0xff0000)>>8) | (((A)&0xff00)<<8) | ((A)<<24) )
#define htonl(A) ntohl(A)
#define htonl(A) ntohl(A)
 
 
// int getch(void);
// int getch(void);
 
#ifndef WIN32
#define getch getchar
#define getch getchar
 
void Sleep(unsigned long value)
 
{
 
   volatile unsigned long count = value*1000000;
 
   while(--count > 0) ;
 
}
 
#else
 
extern void __stdcall Sleep(unsigned long value);
 
#endif
 
 
 
#define UART_WRITE        0x20000000
 
#define UART_READ         0x20000000
 
#define IRQ_MASK          0x20000010
 
#define IRQ_STATUS        0x20000020
 
 
 
#define IRQ_UART_READ_AVAILABLE  0x01
 
#define IRQ_UART_WRITE_AVAILABLE 0x02
 
#define IRQ_COUNTER18_NOT        0x04
 
#define IRQ_COUNTER18            0x08
 
 
typedef struct {
typedef struct {
   long r[32];
   long r[32];
   long pc,pc_next;
   long pc,pc_next;
   long hi;
   long hi;
   long lo;
   long lo;
   long skip;
   long skip;
   char *mem;
   unsigned char *mem;
   long wakeup;
   long wakeup;
   long big_endian;
   long big_endian;
} State;
} State;
 
 
static char *opcode_string[]={
static char *opcode_string[]={
Line 62... Line 82...
   "TGEI","TGEIU","TLTI","TLTIU","TEQI","?","TNEI","?",
   "TGEI","TGEIU","TLTI","TLTIU","TEQI","?","TNEI","?",
   "BLTZAL","BEQZAL","BLTZALL","BGEZALL","?","?","?","?",
   "BLTZAL","BEQZAL","BLTZALL","BGEZALL","?","?","?","?",
   "?","?","?","?","?","?","?","?"
   "?","?","?","?","?","?","?","?"
};
};
 
 
static long big_endian=0;
static long big_endian=1;
 
 
 
static unsigned long HWMemory[3];
 
 
 
static unsigned char SRAM[1024*1024];
 
 
 
 
static long mem_read(State *s,long size,unsigned long address)
static long mem_read(State *s,long size,unsigned long address)
{
{
   unsigned long value=0,ptr;
   unsigned long value=0,ptr;
   address%=MEM_SIZE;
 
   ptr=(long)s->mem+address;
   HWMemory[2] |= IRQ_UART_WRITE_AVAILABLE;
   switch(size) {
   switch(address)
      case 4: value=*(long*)ptr;
   {
         if(big_endian) value=ntohl(value);
      case UART_READ:
 
         if(kbhit())
 
            HWMemory[0] = getch();
 
         HWMemory[2] &= ~IRQ_UART_READ_AVAILABLE; //clear bit
 
         return HWMemory[0];
 
      case IRQ_MASK:
 
         return HWMemory[1];
 
      case IRQ_MASK + 4:
 
         Sleep(10);
 
         return 0;
 
      case IRQ_STATUS:
 
         if(kbhit())
 
            HWMemory[2] |= IRQ_UART_READ_AVAILABLE;
 
         return HWMemory[2];
 
   }
 
 
 
   ptr = (unsigned long)s->mem + (address % MEM_SIZE);
 
 
 
   if(0x10000000 <= address && address < 0x10000000 + 1024*1024)
 
      ptr = (unsigned long)SRAM + address - 0x10000000;
 
 
 
   switch(size)
 
   {
 
      case 4:
 
         if(address & 3)
 
            printf("Unaligned access PC=0x%x data=0x%x\n", s->pc, address);
 
         assert((address & 3) == 0);
 
         value = *(long*)ptr;
 
         if(big_endian)
 
            value = ntohl(value);
         break;
         break;
      case 2:
      case 2:
         value=*(unsigned short*)ptr;
         assert((address & 1) == 0);
         if(big_endian) value=ntohs((unsigned short)value);
         value = *(unsigned short*)ptr;
 
         if(big_endian)
 
            value = ntohs((unsigned short)value);
         break;
         break;
      case 1:
      case 1:
         value=*(unsigned char*)ptr;
         value = *(unsigned char*)ptr;
         break;
         break;
      default: printf("ERROR");
      default:
 
         printf("ERROR");
   }
   }
   return(value);
   return(value);
}
}
 
 
static void mem_write(State *s,long size,long unsigned address,unsigned long value)
static void mem_write(State *s,long size,long unsigned address,unsigned long value)
{
{
   static char_count=0;
   static char_count=0;
   unsigned long ptr;
   unsigned long ptr;
   if(address==0xffff) {          //UART write register at 0xffff
 
      value&=0xff;
   switch(address)
      if(isprint(value)) {
   {
         printf("%c",value);
      case UART_WRITE:
         if(++char_count>=72) {
         putch(value);
            printf("\n");
         return;
            char_count=0;
      case IRQ_MASK:
         }
         HWMemory[1] = value;
      } else if(value=='\n') {
         return;
         printf("\n");
      case IRQ_STATUS:
         char_count=0;
         HWMemory[2] = value;
      } else {
         return;
         printf(".");
 
      }
 
   }
   }
   address%=MEM_SIZE;
 
   ptr=(long)s->mem+address;
   ptr = (unsigned long)s->mem + (address % MEM_SIZE);
   switch(size) {
 
      case 4: if(big_endian) value=htonl(value);
   if(0x10000000 <= address && address < 0x10000000 + 1024*1024)
 
      ptr = (unsigned long)SRAM + address - 0x10000000;
 
 
 
   switch(size)
 
   {
 
      case 4:
 
         assert((address & 3) == 0);
 
         if(big_endian)
 
            value = htonl(value);
         *(long*)ptr=value;
         *(long*)ptr=value;
         break;
         break;
      case 2:
      case 2:
         if(big_endian) {
         assert((address & 1) == 0);
 
         if(big_endian)
            value=htons((unsigned short)value);
            value=htons((unsigned short)value);
         }
 
         *(short*)ptr=(unsigned short)value;
         *(short*)ptr=(unsigned short)value;
         break;
         break;
      case 1:
      case 1:
         *(char*)ptr=(unsigned char)value;
         *(char*)ptr=(unsigned char)value;
         break;
         break;
      default: printf("ERROR");
      default:
 
         printf("ERROR");
   }
   }
}
}
 
 
void mult_big(unsigned long a,unsigned long b,
void mult_big(unsigned long a,
              unsigned long *hi,unsigned long *lo)
              unsigned long b,
 
              unsigned long *hi,
 
              unsigned long *lo)
{
{
   unsigned long ahi,alo,bhi,blo;
   unsigned long ahi,alo,bhi,blo;
   unsigned long c0,c1,c2,c3;
   unsigned long c0, c1, c2;
   unsigned long c1_a,c1_b,c2_a,c2_b;
   unsigned long c1_a, c1_b;
 
 
 
   //printf("mult_big(0x%x, 0x%x)\n", a, b);
   ahi=a>>16;
   ahi=a>>16;
   alo=a&0xffff;
   alo=a&0xffff;
   bhi=b>>16;
   bhi=b>>16;
   blo=b&0xffff;
   blo=b&0xffff;
 
 
   c0=alo*blo;
   c0=alo*blo;
   c1_a=ahi*blo;
   c1_a=ahi*blo;
   c1_b=alo*bhi;
   c1_b=alo*bhi;
   c2=ahi*bhi;
   c2=ahi*bhi;
 
 
 
   c2 += (c1_a >> 16) + (c1_b >> 16);
 
   c1 = (c1_a & 0xffff) + (c1_b & 0xffff) + (c0 >> 16);
 
   c2 += (c1 >> 16);
 
   c0 = (c1 << 16) + (c0 & 0xffff);
 
   //printf("answer=0x%x 0x%x\n", c2, c0);
 
   *hi = c2;
 
   *lo = c0;
 
}
 
 
 
void mult_big_signed(long a,
 
                     long b,
 
                     unsigned long *hi,
 
                     unsigned long *lo)
 
{
 
   unsigned long ahi, alo, bhi, blo;
 
   unsigned long c0, c1, c2;
 
   unsigned long c1_a, c1_b;
 
 
 
   //printf("mult_big_signed(0x%x, 0x%x)\n", a, b);
 
   ahi = a >> 16;
 
   alo = a & 0xffff;
 
   bhi = b >> 16;
 
   blo = b & 0xffff;
 
 
 
   c0 = alo * blo;
 
   c1_a = ahi * blo;
 
   c1_b = alo * bhi;
 
   c2 = ahi * bhi;
 
 
   c2+=(c1_a>>16)+(c1_b>>16);
   c2+=(c1_a>>16)+(c1_b>>16);
   c1=(c1_a&0xffff)+(c1_b&0xffff)+(c0>>16);
   c1=(c1_a&0xffff)+(c1_b&0xffff)+(c0>>16);
   c0&=0xffff;
 
   c2+=(c1>>16);
   c2+=(c1>>16);
   c1&=0xffff;
   c0 = (c1 << 16) + (c0 & 0xffff);
 
   //printf("answer=0x%x 0x%x\n", c2, c0);
   *hi=c2;
   *hi=c2;
   *lo=(c1<<16)+c0;
   *lo = c0;
}
}
 
 
//execute one cycle of a Plasma CPU
//execute one cycle of a Plasma CPU
void cycle(State *s,int show_mode)
void cycle(State *s,int show_mode)
{
{
Line 170... Line 266...
   imm=opcode&0xffff;
   imm=opcode&0xffff;
   imm_shift=(((long)(short)imm)<<2)-4;
   imm_shift=(((long)(short)imm)<<2)-4;
   target=(opcode<<6)>>4;
   target=(opcode<<6)>>4;
   ptr=(short)imm+r[rs];
   ptr=(short)imm+r[rs];
   r[0]=0;
   r[0]=0;
   if(show_mode) {
   if(show_mode)
 
   {
      printf("%8.8lx %8.8lx ",s->pc,opcode);
      printf("%8.8lx %8.8lx ",s->pc,opcode);
      if(op==0) printf("%8s ",special_string[func]);
      if(op == 0)
      else if(op==1) printf("%8s ",regimm_string[rt]);
         printf("%8s ", special_string[func]);
      else printf("%8s ",opcode_string[op]);
      else if(op == 1)
 
         printf("%8s ", regimm_string[rt]);
 
      else
 
         printf("%8s ", opcode_string[op]);
      printf("$%2.2ld $%2.2ld $%2.2ld $%2.2ld ",rs,rt,rd,re);
      printf("$%2.2ld $%2.2ld $%2.2ld $%2.2ld ",rs,rt,rd,re);
      printf("%4.4lx\n",imm);
      printf("%4.4lx\n",imm);
   }
   }
   if(show_mode>5) return;
   if(show_mode > 5)
 
      return;
   s->pc=s->pc_next;
   s->pc=s->pc_next;
   s->pc_next=s->pc_next+4;
   s->pc_next=s->pc_next+4;
   if(s->skip) {
   if(s->skip)
 
   {
      s->skip=0;
      s->skip=0;
      return;
      return;
   }
   }
   switch(op) {
   switch(op)
 
   {
      case 0x00:/*SPECIAL*/
      case 0x00:/*SPECIAL*/
         switch(func) {
         switch(func)
 
         {
            case 0x00:/*SLL*/  r[rd]=r[rt]<<re;          break;
            case 0x00:/*SLL*/  r[rd]=r[rt]<<re;          break;
            case 0x02:/*SRL*/  r[rd]=u[rt]>>re;          break;
            case 0x02:/*SRL*/  r[rd]=u[rt]>>re;          break;
            case 0x03:/*SRA*/  r[rd]=r[rt]>>re;          break;
            case 0x03:/*SRA*/  r[rd]=r[rt]>>re;          break;
            case 0x04:/*SLLV*/ r[rd]=r[rt]<<r[rs];       break;
            case 0x04:/*SLLV*/ r[rd]=r[rt]<<r[rs];       break;
            case 0x06:/*SRLV*/ r[rd]=u[rt]>>r[rs];       break;
            case 0x06:/*SRLV*/ r[rd]=u[rt]>>r[rs];       break;
Line 205... Line 309...
            case 0x0f:/*SYNC*/ s->wakeup=1; break;
            case 0x0f:/*SYNC*/ s->wakeup=1; break;
            case 0x10:/*MFHI*/ r[rd]=s->hi;              break;
            case 0x10:/*MFHI*/ r[rd]=s->hi;              break;
            case 0x11:/*FTHI*/ s->hi=r[rs];              break;
            case 0x11:/*FTHI*/ s->hi=r[rs];              break;
            case 0x12:/*MFLO*/ r[rd]=s->lo;              break;
            case 0x12:/*MFLO*/ r[rd]=s->lo;              break;
            case 0x13:/*MTLO*/ s->lo=r[rs];              break;
            case 0x13:/*MTLO*/ s->lo=r[rs];              break;
            case 0x18:/*MULT*/
            case 0x18:/*MULT*/ mult_big_signed(r[rs],r[rt],&s->hi,&s->lo); break;
            case 0x19:/*MULTU*/ //s->lo=r[rs]*r[rt]; s->hi=0; break;
            case 0x19:/*MULTU*/ //s->lo=r[rs]*r[rt]; s->hi=0; break;
                               mult_big(r[rs],r[rt],&s->hi,&s->lo); break;
                               mult_big(r[rs],r[rt],&s->hi,&s->lo); break;
            case 0x1a:/*DIV*/  s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt]; break;
            case 0x1a:/*DIV*/  s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt]; break;
            case 0x1b:/*DIVU*/ s->lo=u[rs]/u[rt]; s->hi=u[rs]%u[rt]; break;
            case 0x1b:/*DIVU*/ s->lo=u[rs]/u[rt]; s->hi=u[rs]%u[rt]; break;
            case 0x20:/*ADD*/  r[rd]=r[rs]+r[rt];        break;
            case 0x20:/*ADD*/  r[rd]=r[rs]+r[rt];        break;
Line 305... Line 409...
}
}
 
 
void show_state(State *s)
void show_state(State *s)
{
{
   long i,j;
   long i,j;
   for(i=0;i<4;++i) {
   for(i = 0; i < 4; ++i)
 
   {
      printf("%2.2ld ",i*8);
      printf("%2.2ld ",i*8);
      for(j=0;j<8;++j) {
      for(j = 0; j < 8; ++j)
 
      {
         printf("%8.8lx ",s->r[i*8+j]);
         printf("%8.8lx ",s->r[i*8+j]);
      }
      }
      printf("\n");
      printf("\n");
   }
   }
   printf("%8.8lx %8.8lx %8.8lx %8.8lx\n",s->pc,s->pc_next,s->hi,s->lo);
   printf("%8.8lx %8.8lx %8.8lx %8.8lx\n",s->pc,s->pc_next,s->hi,s->lo);
   j=s->pc;
   j=s->pc;
   for(i=-4;i<=8;++i) {
   for(i = -4; i <= 8; ++i)
 
   {
      printf("%c",i==0?'*':' ');
      printf("%c",i==0?'*':' ');
      s->pc=j+i*4;
      s->pc=j+i*4;
      cycle(s,10);
      cycle(s,10);
   }
   }
   s->pc=j;
   s->pc=j;
Line 330... Line 437...
   long i,j=0,watch=0,addr;
   long i,j=0,watch=0,addr;
   s->pc_next=s->pc+4;
   s->pc_next=s->pc+4;
   s->skip=0;
   s->skip=0;
   s->wakeup=0;
   s->wakeup=0;
   show_state(s);
   show_state(s);
   for(;;) {
   for(;;)
      if(watch) printf("0x%8.8lx=0x%8.8lx\n",watch,mem_read(s,4,watch));
   {
 
      if(watch)
 
         printf("0x%8.8lx=0x%8.8lx\n", watch, mem_read(s, 4, watch));
      printf("1=Debug 2=Trace 3=Step 4=BreakPt 5=Go 6=Memory ");
      printf("1=Debug 2=Trace 3=Step 4=BreakPt 5=Go 6=Memory ");
      printf("7=Watch 8=Jump 9=Quit> ");
      printf("7=Watch 8=Jump 9=Quit> ");
      ch=getch();
      ch=getch();
      printf("\n");
      printf("\n");
      switch(ch) {
      switch(ch)
      case '1': case 'd': case ' ': cycle(s,0); show_state(s); break;
      {
      case '2': case 't': cycle(s,0); printf("*"); cycle(s,10); break;
      case '1': case 'd': case ' ':
 
         cycle(s,0); show_state(s); break;
 
      case '2': case 't':
 
         cycle(s,0); printf("*"); cycle(s,10); break;
      case '3': case 's':
      case '3': case 's':
         printf("Count> ");
         printf("Count> ");
         scanf("%ld",&j);
         scanf("%ld", &j);
         for(i=0;i<j;++i) cycle(s,0);
         for(i = 0; i < j; ++i)
 
            cycle(s,0);
         show_state(s);
         show_state(s);
         break;
         break;
      case '4': case 'b':
      case '4': case 'b':
         printf("Line> ");
         printf("Line> ");
         scanf("%lx",&j);
         scanf("%lx", &j);
 
         printf("break point=0x%x\n", j);
         break;
         break;
      case '5': case 'g':
      case '5': case 'g':
         s->wakeup=0;
         s->wakeup=0;
         while(s->wakeup==0) {
         cycle(s, 0);
            if(s->pc==j) break;
         while(s->wakeup == 0)
 
         {
 
            //printf("0x%x ", s->pc);
 
            if(s->pc == j)
 
               break;
            cycle(s,0);
            cycle(s,0);
         }
         }
         show_state(s);
         show_state(s);
         break;
         break;
      case '6': case 'm':
      case '6': case 'm':
         printf("Memory> ");
         printf("Memory> ");
         scanf("%lx",&j);
         scanf("%lx", &j);
         for(i=0;i<8;++i) {
         for(i = 0; i < 8; ++i)
 
         {
            printf("%8.8lx ",mem_read(s,4,j+i*4));
            printf("%8.8lx ",mem_read(s,4,j+i*4));
         }
         }
         printf("\n");
         printf("\n");
         break;
         break;
      case '7': case 'w':
      case '7': case 'w':
         printf("Watch> ");
         printf("Watch> ");
         scanf("%lx",&watch);
         scanf("%lx", &watch);
         break;
         break;
      case '8': case 'j':
      case '8': case 'j':
         printf("Jump> ");
         printf("Jump> ");
         scanf("%lx",&addr);
         scanf("%lx", &addr);
         s->pc=addr;
         s->pc=addr;
         s->pc_next=addr+4;
         s->pc_next=addr+4;
         show_state(s);
         show_state(s);
         break;
         break;
      case '9': case 'q': return;
      case '9': case 'q':
 
         return;
      }
      }
   }
   }
}
}
/************************************************************/
/************************************************************/
 
 
int main(int argc,char *argv[])
int main(int argc,char *argv[])
{
{
   State state,*s=&state;
   State state, *s=&state;
   FILE *in;
   FILE *in;
   long bytes,index;
   long bytes,index;
   printf("Plasma emulator\n");
   printf("Plasma emulator\n");
   memset(s,0,sizeof(State));
   memset(s,0,sizeof(State));
   s->big_endian=0;
   s->big_endian = 1;
   s->mem=malloc(MEM_SIZE);
   s->mem = (unsigned char*)malloc(MEM_SIZE);
   if(argc<=1) {
   if(argc <= 1)
 
   {
      printf("   Usage:  mlite file.exe\n");
      printf("   Usage:  mlite file.exe\n");
      printf("           mlite file.exe B   {for big_endian}\n");
      printf("           mlite file.exe B   {for big_endian}\n");
      printf("           mlite file.exe DD  {disassemble}\n");
      printf("           mlite file.exe L   {for little_endian}\n");
      printf("           mlite file.exe BD  {disassemble big_endian}\n");
      printf("           mlite file.exe BD  {disassemble big_endian}\n");
 
      printf("           mlite file.exe LD  {disassemble little_endian}\n");
 
 
      return 0;
      return 0;
   }
   }
   in=fopen(argv[1],"rb");
   in=fopen(argv[1],"rb");
   if(in==NULL) { printf("Can't open file %s!\n",argv[1]); getch(); return(0); }
   if(in == NULL)
 
   {
 
      printf("Can't open file %s!\n",argv[1]);
 
      getch();
 
      return(0);
 
   }
   bytes=fread(s->mem,1,MEM_SIZE,in);
   bytes=fread(s->mem,1,MEM_SIZE,in);
   fclose(in);
   fclose(in);
 
   memcpy(SRAM, s->mem, bytes);
   printf("Read %ld bytes.\n",bytes);
   printf("Read %ld bytes.\n",bytes);
   if(argc==3&&argv[2][0]=='B') {
   if(argc == 3 && argv[2][0] == 'B')
 
   {
      printf("Big Endian\n");
      printf("Big Endian\n");
      s->big_endian=1;
      s->big_endian=1;
      big_endian=1;
      big_endian=1;
   }
   }
   if(argc==3&&argv[2][0]=='S') {   /*make big endian*/
   if(argc == 3 && argv[2][0] == 'L')
 
   {
      printf("Big Endian\n");
      printf("Big Endian\n");
      for(index=0;index<bytes+3;index+=4) {
      s->big_endian = 0;
 
      big_endian = 0;
 
   }
 
   if(argc == 3 && argv[2][0] == 'S')
 
   {  /*make big endian*/
 
      printf("Big Endian\n");
 
      for(index = 0; index < bytes+3; index += 4)
 
      {
         *(unsigned long*)&s->mem[index]=htonl(*(unsigned long*)&s->mem[index]);
         *(unsigned long*)&s->mem[index]=htonl(*(unsigned long*)&s->mem[index]);
      }
      }
      in=fopen("big.exe","wb");
      in=fopen("big.exe","wb");
      fwrite(s->mem,bytes,1,in);
      fwrite(s->mem,bytes,1,in);
      fclose(in);
      fclose(in);
      return(0);
      return(0);
   }
   }
   if(argc==3&&argv[2][1]=='D') {   /*dump image*/
   if(argc == 3 && argv[2][1] == 'D')
 
   {  /*dump image*/
      for(index=0;index<bytes;index+=4) {
      for(index=0;index<bytes;index+=4) {
         s->pc=index;
         s->pc=index;
         cycle(s,10);
         cycle(s,10);
      }
      }
      free(s->mem);
      free(s->mem);
      return(0);
      return(0);
   }
   }
   s->pc=0x0;
   s->pc=0x0;
 
   index = mem_read(s, 4, 0);
 
   if(index == 0x3c1c1000)
 
      s->pc = 0x10000000;
   do_debug(s);
   do_debug(s);
   free(s->mem);
   free(s->mem);
   return(0);
   return(0);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.