geek gets pounded by angry lawyers^^THIS (Whoever posted that leak is going to get f*cked 23 times in the a**.)
geek gets pounded by angry lawyers^^THIS (Whoever posted that leak is going to get f*cked 23 times in the a**.)
Yo I made that page!
I've always been interested in learning how to decompile projects, so this is quite cool! If any of you are in the thread, where/ how did you learn to decompile programs?
Excuse me. I've been looking at the code on and off since I posted this thread. I have a different vision for porting it than total accuracy.when it's very clear you know absolutely nothing about the code
If it's publicly available, it's public domain. That's what I live by.Nobody is going to spend quality time with a leaked project simply out of respect for the developers.
Others already went but that will depend upon what you mean by that.So does this mean it's graphics can be drastically upgraded now?
I am a programmer. I'm making my own Nintendo 64 emulator.I'm willing to bet that if I pointed to a line of code and asked you explain exactly what it did, you would have no idea. It's for this reason programmers are paid so much, it's hard work! It's even rarer for passion projects like this to come to fruition, because you are essentially working for free. So please, treat the devs with respect.
I can infer this because of how excited you are for the project, and how angsty you got when you realized that nobody was researching the code alongside you.
#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;
}
lol good luck with graphicsI'm making my own Nintendo 64 emulator.
The source code is available for many graphics plugins, including an OpenGL one. I will reference them.lol good luck with graphics
No assembly is left except that of a few audio functions whose C have not been made to match 1-1 with the assembly; for hacks and ports, this obviously doesn't matterany MIPS code (if any still exists - I haven't looked at the code out of respect until it's finished)
Compiling SM64 with optimizations and using F3DEX/F3DEX2 microcode has been done and does allow for huge performance improvements. These have been implemented in the SM64 RandomizerThe microcode could be updated, but even more simply, you could just compile the game with newer tools and with actual optimisation flags this time (Thanks, Nintendo!) to see some gains.
No assembly is left except that of a few audio functions whose C have not been made to match 1-1 with the assembly; for hacks and ports, this obviously doesn't matter
Compiling SM64 with optimizations and using F3DEX/F3DEX2 microcode has been done and does allow for huge performance improvements. These have been implemented in the SM64 Randomizer