Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <badn64.h>
- #include <stdio.h>
- /*
- RAM: rambus dynamic Random-Access Memory
- REG: rdram REGisters
- RCP: Reality CoProcessor
- LEO: LEO registers (64DD)
- IPL: Initial Program Load (64DD)
- STA: STAtic ram
- ROM: ROM (cartridge)
- PIF: Program Information File
- */
- /* enumerated memory segments */
- enum SEGMENT{RAM, REG, RCP, LEO, IPL, STA, ROM, PIF};
- /* lookup table for the purpose of translating n64 memory segments to our segments */
- BYTE LUT[0x20]=
- {/* 0x00 0x03 0x04 0x05 0x06 0x08 */
- RAM, 0, 0, REG, RCP, LEO, IPL, 0, STA, 0, 0, 0, 0, 0, 0, 0,
- /* 0x10 0x1F */
- ROM, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PIF
- };
- WORD loop;
- /* function for sign extension of immediate values */
- WORD extend(HALF imm);
- WORD extend(HALF imm)
- {
- WORD extended;
- if(sign(imm)==0x8000)
- {
- extended=0xffff0000|imm;
- }
- else
- {
- extended=imm;
- }
- return extended;
- }
- /* function for reading 32 bits */
- WORD read32(BYTE *mem[8], WORD ptr);
- WORD read32(BYTE *mem[8], WORD ptr)
- {
- BYTE temp=(ptr>>24)&0x1f;
- switch(LUT[temp])
- {
- case REG:
- ptr&=0x0fffff;
- break;
- case PIF:
- ptr&=0x3fffff;
- break;
- default:
- ptr&=0xffffff;
- break;
- }
- return (WORD)((mem[LUT[temp]][ptr]<<24)|(mem[LUT[temp]][ptr+1]<<16)|(mem[LUT[temp]][ptr+2]<<8)|mem[LUT[temp]][ptr+3]);
- }
- void handle_pi(BYTE *mem[8], WORD ptr);
- void handle_pi(BYTE *mem[8], WORD ptr)
- {
- WORD dram_addr, cart_addr, rd_len, wr_len;
- dram_addr=read32(mem,0xa4600000);
- cart_addr=read32(mem,0xa4600004)&0xffffff;
- rd_len=1+read32(mem,0xa4600008);
- wr_len=1+read32(mem,0xa460000c);
- if(ptr==0x600008)
- {
- }
- else if(ptr==0x60000c)
- {
- for(loop=0;loop<wr_len;loop+=1)
- {
- mem[RAM][dram_addr+loop]=mem[ROM][cart_addr+loop];
- }
- }
- }
- /* function for writing 32 bits */
- void write32(BYTE *mem[8], WORD ptr, WORD val);
- void write32(BYTE *mem[8], WORD ptr, WORD val)
- {
- BYTE handle=9;
- BYTE temp=(ptr>>24)&0x1f;
- switch(LUT[temp])
- {
- case REG:
- ptr&=0x0fffff;
- break;
- case RCP:
- handle=(ptr&0xf00000)>>20;
- ptr&=0xffffff;
- break;
- case PIF:
- ptr&=0x3fffff;
- break;
- default:
- ptr&=0xffffff;
- break;
- }
- mem[LUT[temp]][ptr]=(val>>24)&0xff;
- mem[LUT[temp]][ptr+1]=(val>>16)&0xff;
- mem[LUT[temp]][ptr+2]=(val>>8)&0xff;
- mem[LUT[temp]][ptr+3]=val&0xff;
- switch(handle)
- {
- case 6:
- handle_pi(mem,ptr);
- break;
- }
- }
- int main(int argc, char **argv)
- {
- const char names[32][3]=
- {
- "r0", "at", "v0", "v1",
- "a0", "a1", "a2", "a3",
- "t0", "t1", "t2", "t3",
- "t4", "t5", "t6", "t7",
- "s0", "s1", "s2", "s3",
- "s4", "s5", "s6", "s7",
- "t8", "t9", "k0", "k1",
- "gp", "sp", "fp", "ra"
- };
- BYTE *mem[8], delay=0, depth=0;
- WORD CPU[32]={0},CP0[32]={0},pc=0xa4000040,tick=0,ticks,inst;
- unsigned long long sixtyfour;
- WORD hi, lo;
- FILE *cart=fopen(argv[1],"rb");
- fseek(cart,0,SEEK_END);
- loop=ftell(cart);
- WORD sizes[8]=
- {
- 0x800000, /* RAM */
- 0x100000, /* REG */
- 0x80001c, /* RCP */
- 0x0005c0, /* LEO */
- 0x400000, /* IPL */
- 0x008000, /* STA */
- loop, /* ROM */
- 0x000800 /* PIF */
- };
- for(loop=0;loop<8;loop+=1)
- {
- mem[loop]=(BYTE*)calloc(sizes[loop],1); /* allocate our memory segments and init to zero */
- }
- fseek(cart,0,SEEK_SET);
- fread(mem[ROM],1,sizes[ROM],cart);
- fclose(cart);
- for(loop=0;loop<0xfc0;loop+=1)
- {
- mem[RCP][0x40+loop]=mem[ROM][0x40+loop];
- }
- write32(mem,0xa4001000,0x3c0dbfc0); /* SP IMEM +0 */
- write32(mem,0xa4001004,0x8da807fc); /* SP IMEM +4 */
- write32(mem,0xa4001008,0x25ad07c0); /* SP IMEM +8 */
- write32(mem,0xa400100c,0x31080080); /* SP IMEM +0xC */
- write32(mem,0xa4001010,0x5500fffc); /* SP IMEM +0x10*/
- write32(mem,0xa4001014,0x3c0dbfc0); /* SP IMEM +0x14*/
- write32(mem,0xa4001018,0x8da80024); /* SP IMEM +0x18*/
- write32(mem,0xa400101c,0x3c0bb000); /* SP IMEM +0x1C*/
- write32(mem,0xa4040010,1); /* SP status */
- write32(mem,0xa4300004,0x02020102); /* MI version*/
- write32(mem,0xa4600014,0x40); /* PI dom1 latency */
- write32(mem,0xa4600018,0x12); /* PI dom1 pulse width */
- write32(mem,0xa460001c,7); /* PI dom1 page size */
- write32(mem,0xa4600020,3); /* PI dom1 dom1 release*/
- CPU[S4]=1; /* tv type */
- CPU[S6]=0x3f; /* seed */
- CPU[T3]=pc;
- CPU[SP]=0xa4001ff0; /* Stack Pointer */
- CPU[RA]=0xa4001550; /* Return Address*/
- /*printf("How many ticks? ");*/
- /*scanf("%d",&ticks);*/
- while(tick<0xffffffff)
- {
- if(pc==read32(mem,0xb0000008))
- {
- printf("%10d\n",tick);
- break;
- }
- inst=read32(mem,pc);
- switch(op(inst))
- {
- case SPECIAL:
- switch(funct(inst))
- {
- case SLL:
- CPU[rd(inst)]=CPU[rt(inst)]<<sa(inst);
- break;
- case SRL:
- CPU[rd(inst)]=CPU[rt(inst)]>>sa(inst);
- break;
- case SLLV:
- CPU[rd(inst)]=CPU[rt(inst)]<<(CPU[rs(inst)]&0x1f);
- break;
- case SRLV:
- CPU[rd(inst)]=CPU[rt(inst)]>>(CPU[rs(inst)]&0x1f);
- break;
- case JR:
- if(delay==0)
- {
- delay=1;
- }
- else if(delay==3)
- {
- pc=CPU[rs(inst)]-4;
- if(pc==CPU[RA]-4)
- {
- depth-=1;
- printf("%10d %08x: ",tick+1,pc+4);
- for(loop=0;loop<depth;loop+=1)
- {
- printf(" ");
- }
- printf("returned from function\n");
- }
- delay=0;
- }
- break;
- case JALR:
- if(delay==0)
- {
- CPU[rd(inst)]=pc+8;
- delay=1;
- }
- else if(delay==3)
- {
- pc=CPU[rs(inst)]-4;
- delay=0;
- }
- break;
- case MFLO:
- CPU[rd(inst)]=lo;
- break;
- case MULTU:
- sixtyfour=CPU[rs(inst)]*CPU[rt(inst)];
- hi=sixtyfour>>32;
- lo=sixtyfour&0xffffffff;
- break;
- case ADD:
- CPU[rd(inst)]=CPU[rs(inst)]+CPU[rt(inst)];
- break;
- case ADDU:
- CPU[rd(inst)]=CPU[rs(inst)]+CPU[rt(inst)];
- break;
- case SUBU:
- CPU[rd(inst)]=CPU[rs(inst)]-CPU[rt(inst)];
- break;
- case AND:
- CPU[rd(inst)]=CPU[rs(inst)]&CPU[rt(inst)];
- break;
- case OR:
- CPU[rd(inst)]=CPU[rs(inst)]|CPU[rt(inst)];
- break;
- case XOR:
- CPU[rd(inst)]=CPU[rs(inst)]^CPU[rt(inst)];
- break;
- case SLT:
- CPU[rd(inst)]=0;
- if((int)(CPU[rs(inst)])<(int)(CPU[rt(inst)]))
- {
- CPU[rd(inst)]=1;
- }
- break;
- case SLTU:
- CPU[rd(inst)]=0;
- if(CPU[rs(inst)]<CPU[rt(inst)])
- {
- CPU[rd(inst)]=1;
- }
- break;
- }
- break;
- case REGIMM:
- switch(rt(inst))
- {
- case BLTZ:
- if(delay==0)
- {
- delay=1;
- }
- else if(delay==3)
- {
- if(CPU[rs(inst)]<0)
- {
- pc+=extend(imm(inst)<<2)-4;
- }
- pc+=4;
- delay=0;
- }
- break;
- case BGEZ:
- if(delay==0)
- {
- delay=1;
- }
- else if(delay==3)
- {
- if(CPU[rs(inst)]>=0)
- {
- pc+=extend(imm(inst)<<2)-4;
- }
- pc+=4;
- delay=0;
- }
- break;
- case BLTZL:
- if(delay==0)
- {
- if(CPU[rs(inst)]<0)
- {
- delay=1;
- }
- else
- {
- pc+=4;
- }
- }
- else if(delay==3)
- {
- pc+=extend(imm(inst)<<2);
- delay=0;
- }
- break;
- case BGEZL:
- if(delay==0)
- {
- if(CPU[rs(inst)]>=0)
- {
- delay=1;
- }
- else
- {
- pc+=4;
- }
- }
- else if(delay==3)
- {
- pc+=extend(imm(inst)<<2);
- delay=0;
- }
- break;
- case BLTZAL:
- if(delay==0)
- {
- CPU[RA]=pc+8;
- delay=1;
- }
- else if(delay==3)
- {
- if(CPU[rs(inst)]<0)
- {
- pc+=extend(imm(inst)<<2)-4;
- }
- pc+=4;
- delay=0;
- }
- break;
- case BGEZAL:
- if(delay==0)
- {
- CPU[RA]=pc+8;
- delay=1;
- }
- else if(delay==3)
- {
- if(CPU[rs(inst)]>=0)
- {
- pc+=extend(imm(inst)<<2)-4;
- }
- pc+=4;
- delay=0;
- }
- break;
- case BLTZALL:
- if(delay==0)
- {
- CPU[RA]=pc+8;
- if(CPU[rs(inst)]<0)
- {
- delay=1;
- }
- else
- {
- pc+=4;
- }
- }
- else if(delay==3)
- {
- pc+=extend(imm(inst)<<2);
- delay=0;
- }
- break;
- case BGEZALL:
- if(delay==0)
- {
- CPU[RA]=pc+8;
- if(CPU[rs(inst)]>=0)
- {
- delay=1;
- }
- else
- {
- pc+=4;
- }
- }
- else if(delay==3)
- {
- pc+=extend(imm(inst)<<2);
- delay=0;
- }
- break;
- }
- break;
- case J:
- if(delay==0)
- {
- delay=1;
- }
- else if(delay==3)
- {
- pc=((pc&0xf0000000)|target(inst))-4;
- delay=0;
- }
- break;
- case JAL:
- if(delay==0)
- {
- CPU[RA]=pc+8;
- delay=1;
- }
- else if(delay==3)
- {
- printf("%10d %08x: ",tick+1,pc);
- for(loop=0;loop<depth;loop+=1)
- {
- printf(" ");
- }
- pc=((pc&0xf0000000)|target(inst))-4;
- printf("jumped inside function (%08x)\n",pc+4);
- depth+=1;
- delay=0;
- }
- break;
- case BEQ:
- if(delay==0)
- {
- delay=1;
- }
- else if(delay==3)
- {
- if(CPU[rs(inst)]==CPU[rt(inst)])
- {
- pc+=extend(imm(inst)<<2)-4;
- }
- pc+=4;
- delay=0;
- }
- break;
- case BNE:
- if(delay==0)
- {
- delay=1;
- }
- else if(delay==3)
- {
- if(CPU[rs(inst)]!=CPU[rt(inst)])
- {
- pc+=extend(imm(inst)<<2)-4;
- }
- pc+=4;
- delay=0;
- }
- break;
- case BLEZ:
- if(delay==0)
- {
- delay=1;
- }
- else if(delay==3)
- {
- if(CPU[rs(inst)]<=0)
- {
- pc+=extend(imm(inst)<<2)-4;
- }
- pc+=4;
- delay=0;
- }
- break;
- case BGTZ:
- if(delay==0)
- {
- delay=1;
- }
- else if(delay==3)
- {
- if(CPU[rs(inst)]>0)
- {
- pc+=extend(imm(inst)<<2)-4;
- }
- pc+=4;
- delay=0;
- }
- break;
- case ADDI:
- CPU[rt(inst)]=CPU[rs(inst)]+extend(imm(inst));
- break;
- case ADDIU:
- CPU[rt(inst)]=CPU[rs(inst)]+extend(imm(inst));
- break;
- case SLTI:
- CPU[rt(inst)]=0;
- if((int)(CPU[rs(inst)])<(int)(extend(imm(inst))))
- {
- CPU[rt(inst)]=1;
- }
- break;
- case SLTIU:
- CPU[rt(inst)]=0;
- if(CPU[rs(inst)]<extend(imm(inst)))
- {
- CPU[rt(inst)]=1;
- }
- break;
- case ANDI:
- CPU[rt(inst)]=CPU[rs(inst)]&imm(inst);
- break;
- case ORI:
- CPU[rt(inst)]=CPU[rs(inst)]|imm(inst);
- break;
- case XORI:
- CPU[rt(inst)]=CPU[rs(inst)]^imm(inst);
- break;
- case LUI:
- CPU[rt(inst)]=imm(inst)<<16;
- break;
- case COP0:
- switch(rs(inst))
- {
- case MT:
- CP0[rd(inst)]=CPU[rt(inst)];
- break;
- }
- break;
- case BEQL:
- if(delay==0)
- {
- if(CPU[rs(inst)]==CPU[rt(inst)])
- {
- delay=1;
- }
- else
- {
- pc+=4;
- }
- }
- else if(delay==3)
- {
- pc+=extend(imm(inst)<<2);
- delay=0;
- }
- break;
- case BNEL:
- if(delay==0)
- {
- if(CPU[rs(inst)]!=CPU[rt(inst)])
- {
- delay=1;
- }
- else
- {
- pc+=4;
- }
- }
- else if(delay==3)
- {
- pc+=extend(imm(inst)<<2);
- delay=0;
- }
- break;
- case BLEZL:
- if(delay==0)
- {
- if(CPU[rs(inst)]<=0)
- {
- delay=1;
- }
- else
- {
- pc+=4;
- }
- }
- else if(delay==3)
- {
- pc+=extend(imm(inst)<<2);
- delay=0;
- }
- break;
- case BGTZL:
- if(delay==0)
- {
- if(CPU[rs(inst)]>0)
- {
- delay=1;
- }
- else
- {
- pc+=4;
- }
- }
- else if(delay==3)
- {
- pc+=extend(imm(inst)<<2);
- delay=0;
- }
- break;
- case LW:
- loop=CPU[rs(inst)]+extend(imm(inst));
- CPU[rt(inst)]=read32(mem,loop);
- break;
- case LBU:
- loop=CPU[rs(inst)]+extend(imm(inst));
- CPU[rt(inst)]=read32(mem,loop)>>24;
- break;
- case SB:
- loop=CPU[rs(inst)]+extend(imm(inst));
- switch(LUT[(loop>>24)&0x1f])
- {
- case REG:
- mem[REG][loop&0x0fffff]=CPU[rt(inst)]&0xff;
- break;
- case PIF:
- mem[PIF][loop&0x3fffff]=CPU[rt(inst)]&0xff;
- break;
- default:
- mem[LUT[(loop>>24)&0x1f]][loop&0xffffff]=CPU[rt(inst)]&0xff;
- break;
- }
- break;
- case SW:
- loop=CPU[rs(inst)]+extend(imm(inst));
- write32(mem,loop,CPU[rt(inst)]);
- break;
- case CACHE:
- break;
- }
- pc+=4;
- tick+=1;
- if(delay>0)
- {
- delay+=1;
- tick-=1;
- if(delay==3)
- {
- pc-=8;
- tick+=1;
- }
- }
- }
- for(loop=0;loop<32;loop+=1)
- {
- printf("%s: %08x ",names[loop],CPU[loop]);
- if(loop%4==3)
- {
- printf("\n");
- }
- }
- printf("pc: %08x\n",pc);
- system("pause");
- for(loop=0;loop<8;loop+=1)
- {
- free(mem[loop]);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement