char *sym_find(int addr) { static char buf[256]; Sym *s; int offset; addr&=ADDRMASK; // find s=sym+findsym(addr); offset=addr-s->addr; if(offset<0 || offset>99999) { int a; a=mem_read32(addr); if(OP_OP(a)==19) { sprintf(buf,"?<patch:%i>",OP_IMM(a)); return(buf); } else return("?"); } if(offset==0) strcpy(buf,s->text); else sprintf(buf,"?%i+%s",offset,s->text); return(buf); }
static void op_rwmemrl( dword opcode, int write, int right ) { dword x, y, a, s, m; a = op_memaddr(opcode); s = a & 3; a &= ~3; if( write ) { x = mem_read32(a); y = st.g[OP_RT(opcode)].d; if( right ) { m = 0x00ffffff >> (s * 8); y <<= (3 - s) * 8; x &= m; x |= y; } else { m = 0xffffff00 << ((3 - s) * 8); y >>= s * 8; x &= m; x |= y; } mem_write32( a, x ); }
static void op_readmem(dword opcode,int bytes) { int a,x,*d; a=op_memaddr(opcode); if(bytes>0x10) { // fpu d =&st.f[OP_RT(opcode)].d; bytes-=0x10; } else { d =&st.g[OP_RT(opcode)].d; } cpu_notify_readmem(a,bytes); switch(bytes) { case -1: x=mem_read8(a); d[0]=SIGNEXT8(x); break; case 1: x=mem_read8(a); d[0]=x; break; case -2: x=mem_read16(a); d[0]=SIGNEXT16(x); break; case 2: x=mem_read16(a); d[0]=x; break; case -4: case 4: x=mem_read32(a); d[0]=x; break; case 8: case -8: d[1]=mem_read32(a); d[0]=mem_read32(a+4); break; } }
void hw_si_pads(int write) { dword base=WSI[0]; int i; logh("hw-si: dma %08X (write=%i)\n",base,write); if(!cart.first_pad) { print("note: first pad access\n"); cart.first_pad=1; } if(write) { for(i=0;i<16;i++) { RPIF[0x1f0+i]=mem_read32(base+i*4); } } else { // 2 dwords for each controller: // 000000ss bbbbxxyy // ss=status? !&00C0 or error // bbbb=buttons // xx=stick-x // yy=stick-y // construct reply memset(RPIF+0x1f0,0,16*4); RPIF[0x1f0+1+2*selectpad]=pad_getdata(0); // copy it for(i=0;i<16;i++) { mem_write32(base+i*4,RPIF[0x1f0+i]); } } /* for(i=0;i<16;i++) { print("%08X ",RPIF[0x1f0+i]); if((i&3)==3) print("\n"); } */ WSI[1]=NULLFILL; WSI[4]=NULLFILL; RSI[0]=WSI[0]; RSI[6]=0; // not busy os_event(OS_EVENT_SI); }
void readshort(int *q,dword addr,int bytes) { int x,i; bytes>>=1; for(i=0;i<bytes;i+=2) { x=mem_read32(addr+i*2); q[i+0]=(short)(x>>16); q[i+1]=(short)(x&65535); } }
void readdata(void *dst,dword addr,int bytes) { dword *d=(dword *)dst; int i,x; bytes>>=2; for(i=0;i<bytes;i++) { x=mem_read32(addr+i*4); d[i]=x; } }
int pif_plugin_hoptime_statistics(EXTRACTED_HEADERS_T *headers, MATCH_DATA_T *match_data) { PIF_PLUGIN_hoptime_T *hoptime = pif_plugin_hdr_get_hoptime(headers); __xread struct hoptime_data in_xfer; __gpr struct hoptime_data out_reg; __xwrite struct hoptime_data out_xfer; uint64_t ctime, ptime; uint64_t latency; unsigned port; /* Get the time at parsing from the intrinsic metadata timestamp * Note that we do this in two parts __0 being the 32 lsbs and __1 the 16 * msbs */ ctime = pif_plugin_meta_get__intrinsic_metadata__ingress_global_tstamp__0(headers); ctime |= ((uint64_t)pif_plugin_meta_get__intrinsic_metadata__ingress_global_tstamp__1(headers)) << 32; /* Retrieve ingress port from P4 metadata */ port = pif_plugin_meta_get__standard_metadata__ingress_port(headers); /* we don't error out here, we just use use a reserved bucket */ if (port >= PORTMAX) port = PORTMAX; /* Retrieve the previous hop time from the hoptime header field */ ptime = ((uint64_t)PIF_HEADER_GET_hoptime___time___1(hoptime)) << 32; ptime |= PIF_HEADER_GET_hoptime___time___0(hoptime); latency = ctime - ptime; mem_read32(&in_xfer, &hoptime_data[port], sizeof(in_xfer)); out_reg = in_xfer; if (latency > out_reg.max_latency) out_reg.max_latency = latency; if (latency < out_reg.min_latency || out_reg.min_latency == 0) out_reg.min_latency = latency; out_reg.count += 1; out_reg.total_latency += latency; out_xfer = out_reg; mem_write32(&out_xfer, &hoptime_data[port], sizeof(out_xfer)); return PIF_PLUGIN_RETURN_FORWARD; }
int main(void){ printf("Initializing\n"); mem_init(); printf("Allocating 1MB\n"); uint32_t loc = mem_dynamic_alloc(1<<20,0); printf("Got address 0x%X\n",loc); printf("Writing 192342\n"); mem_write32(loc,192343); printf("Reading...\n"); uint32_t result = mem_read32(loc); printf("Read %d\n",result); printf("Freeing\n"); mem_free(loc); printf("Cleaning up\n"); mem_cleanup(); return 0; }
static int ReadStateChunks(MEMFILE *st) { int t; uint32 size; int ret=1; for(;;) { t=mem_fgetc(st); if(t==EOF) break; if(!mem_read32(&size,st)) break; // printf("ReadStateChunks: chunk %i\n", t); switch(t) { case 1:if(!ReadStateChunk(st,SFCPU,size)) ret=0; #ifdef ASM_6502 asmcpu_unpack(); #endif break; case 2:if(!ReadStateChunk(st,SFCPUC,size)) ret=0; else { X.mooPI=X.P; // Quick and dirty hack. } break; case 3:if(!ReadStateChunk(st,FCEUPPU_STATEINFO,size)) ret=0;break; case 4:if(!ReadStateChunk(st,FCEUCTRL_STATEINFO,size)) ret=0;break; case 5:if(!ReadStateChunk(st,SFSND,size)) ret=0;break; case 0x10:if(!ReadStateChunk(st,SFMDATA,size)) ret=0;break; default:printf("ReadStateChunks: unknown chunk: %i\n", t); if(mem_fseek(st,size,SEEK_CUR)<0) goto endo;break; } } endo: return ret; }
void routinecrc2(dword addr,int barrier,dword *xcrc1,dword *xcrc2) { dword crc,crc1=0,crc2=0; dword x1,x2; int i,in,errorsaid=0; int dump=0; // if(addr>=0x002004b0 && addr<=0x002004ff) dump=1; if(!barrier) crc1=*xcrc1; in=16; x1=mem_read32(addr); if(!(x1&0xffffff)) { *xcrc1=-1; *xcrc2=-1; return; } for(i=0; i<in; i++) { x1=mem_read32(addr+i*4); if(x1==0x03e00008) { // JR ret in=i+2; if(in>16) in=16; } } for(i=0; i<in; i++) { x1=mem_read32(addr+i*4); crc=i; if(OP_OP(x1)==3 || OP_OP(x1)==2) { // JAL or J crc+=OP_OP(x1); } else if(OP_OP(x1)==15) { // LUI if(OP_IMM(x1)>=0xa400 && OP_IMM(x1)<=0xafff) crc2+=x1; // must be right else crc+=OP_OP(x1); } else if(OP_OP(x1)==16) { // COP0 crc2^=x1; // these must be totally correct crc=0; } else if(OP_OP(x1)==17) { // COP1 crc2^=x1; // these must be totally correct crc=0; } else { // default instr, just check upper 16 bits if(barrier) { // generating x2=mem_read32(addr+i*4+barrier); if(OP_OP(x1)>=4 && OP_OP(x1)<=15) { // immediates crc1|=(1<<i); crc^=x1>>16; } else if(x1!=x2) { if((x1^x2)>>16) { if(!errorsaid) { //print("32-bit routine difference at %08X\n",addr+i*4); errorsaid=1; crc1|=-1; } } crc1|=(1<<i); crc^=x1>>16; } else { crc^=x1; } }
u32int process_opcode(farcpu *cpu) { u8int op = cpu->regs.IR; u8int mem_add = 1; //amount to add to memory to get to next OpCode u32int PC = cpu->regs.PC + 1; //just skip the opcode, to make things easier char *memory = cpu->memory; if(op == EXOP) return process_extended_opcode(cpu); switch(op) { case NOP: asm("nop"); break; //might just remove the asm statement sometime, just fo-sho right now /* * Aritmatic functions * TODO: OVERFLOW, EXCEPTION Handeling */ case INC: set_register(cpu, mem_get8(memory, PC), get_register(cpu, mem_get8(memory, PC)) + 1); mem_add++; break; case DEC: set_register(cpu, mem_get8(memory, PC), get_register(cpu, mem_get8(memory, PC)) - 1); mem_add++; break; case ADD: set_register(cpu, AL, process_in_loc(cpu, memory, PC, &mem_add) + process_in_loc(cpu, memory, PC + mem_add-1 , &mem_add)); break; case SUB: set_register(cpu, AL, process_in_loc(cpu, memory, PC, &mem_add) - process_in_loc(cpu, memory, PC + mem_add-1, &mem_add)); break; case MUL: //TODO:OPTIMIZE set_register(cpu, AL, process_in_loc(cpu, memory, PC, &mem_add) * process_in_loc(cpu, memory, PC + mem_add-1, &mem_add)); break; case DIV: //TODO:OPTIMIZE, DIV BY 0 set_register(cpu, AL, (u32int)(process_in_loc(cpu, memory, PC, &mem_add) / process_in_loc(cpu, memory, PC + mem_add-1, &mem_add))); break; //Moving data around: TODO:ADD CONTENT!!! case MOVNM: switch(mem_read8(cpu->memory, PC)){ case 0: mem_write8(cpu->memory, mem_read32(cpu->memory, PC + 2),mem_read8(cpu->memory, PC + 1)); mem_add+=6; break; case 1: mem_write16(cpu->memory, mem_read32(cpu->memory, PC + 3), mem_read16(cpu->memory, PC + 1)); mem_add+=7; break; case 2: mem_write32(cpu->memory, mem_read32(cpu->memory, PC + 6), mem_read32(cpu->memory, PC + 1)); mem_add+=9; break; } mem_add++; break; case MOVRM: switch(reg_sizes[mem_read8(cpu->memory, PC)]){ case 1: mem_write8(cpu->memory, mem_read32(cpu->memory, PC + 1), get_register(cpu, mem_read8(cpu->memory, PC))); break; case 2: mem_write16(cpu->memory, mem_read32(cpu->memory, PC + 1), get_register(cpu, mem_read8(cpu->memory, PC))); break; case 4: mem_write32(cpu->memory, mem_read32(cpu->memory, PC + 1), get_register(cpu, mem_read8(cpu->memory, PC))); break; } mem_add += 5; break; case MOVIM: mem_write8(cpu->memory, mem_read32(cpu->memory, PC), cpu->IO); mem_add += 4; break; case MOVMM: break; case MOVMR: break; case MOVNR: switch(mem_read8(cpu->memory, PC)) { case 0: set_register(cpu, mem_read8(cpu->memory, PC+2), mem_read8(cpu->memory, PC+1)); mem_add += 3; break; //byte case 1: set_register(cpu, mem_read8(cpu->memory, PC+3), mem_read16(cpu->memory, PC+1)); mem_add += 4; break; //short case 2: set_register(cpu, mem_read8(cpu->memory, PC+5), mem_read32(cpu->memory, PC+1)); mem_add += 6; break; //long } break; case MOVIR: set_register(cpu, mem_read8(cpu->memory, PC), cpu->IO); mem_add += 1; break; case MOVRR: set_register(cpu, mem_read8(cpu->memory, PC + 1), get_register(cpu, mem_read8(cpu->memory, PC))); mem_add += 2; break; //bit-minipulating: case SHL: break; case SHR: break; case AND: break; case OR: break; case XOR: break; case NOT: break; //Low-Level: case HWU: switch(mem_read16(cpu->memory, PC)) { case 0x08: gfx_upd(cpu); } mem_add += 2; break; //branching: case JMP: cpu->regs.PC = mem_read32(cpu->memory, PC); return 1; case SJP: cpu->regs.JP = mem_read32(cpu->memory, PC); mem_add += 4; break; case JZ: if(cpu->regs.AL == 0){ cpu->regs.PC = cpu->regs.JP; return 1; }break; case JNZ: if(cpu->regs.AL != 0){ cpu->regs.PC = cpu->regs.JP; return 1; }break; case JFE: if(cpu->regs.AL == cpu->regs.BL){ cpu->regs.PC = cpu->regs.JP; return 1; }break; case JNE: if(cpu->regs.AL != cpu->regs.BL){ cpu->regs.PC = cpu->regs.JP; return 1; }break; case JGT: if(cpu->regs.AL > cpu->regs.BL){ cpu->regs.PC = cpu->regs.JP; return 1; }break; break; case JNG: if(!(cpu->regs.AL > cpu->regs.BL)){ cpu->regs.PC = cpu->regs.JP; return 1; }break; case JGE: if(cpu->regs.AL >= cpu->regs.BL){ cpu->regs.PC = cpu->regs.JP; return 1; }break; case JNGE: if(!(cpu->regs.AL >= cpu->regs.BL)){ cpu->regs.PC = cpu->regs.JP; return 1; }break; case JLT: if(cpu->regs.AL < cpu->regs.BL){ cpu->regs.PC = cpu->regs.JP; return 1; }break; case JNL: if(!(cpu->regs.AL < cpu->regs.BL)){ cpu->regs.PC = cpu->regs.JP; return 1; }break; break; case JLE: if(cpu->regs.AL <= cpu->regs.BL){ cpu->regs.PC = cpu->regs.JP; return 1; }break; break; case JNLE: if(!(cpu->regs.AL <= cpu->regs.BL)){ cpu->regs.PC = cpu->regs.JP; return 1; }break; break; case MOVNRM: switch(mem_read8(cpu->memory, PC)) { case 0: set_register(cpu, get_register(cpu, mem_get8(cpu->memory, PC + 2)), mem_read8(cpu->memory, PC+1)); mem_add += 4; break; //byte case 1: set_register(cpu, get_register(cpu, mem_get8(cpu->memory, PC + 3)), mem_read16(cpu->memory, PC+1)); mem_add += 5; break; //short case 2: set_register(cpu, get_register(cpu, mem_get8(cpu->memory, PC + 5)), mem_read32(cpu->memory, PC+1)); mem_add += 7; break; //long } break; case MOVRRM: switch(reg_sizes[mem_read8(cpu->memory, PC)]){ case 1: mem_write8(cpu->memory, get_register(cpu, mem_get8(cpu->memory, PC + 1)), get_register(cpu, mem_read8(cpu->memory, PC))); break; case 2: mem_write16(cpu->memory, get_register(cpu, mem_get8(cpu->memory, PC + 1)), get_register(cpu, mem_read8(cpu->memory, PC))); break; case 4: mem_write32(cpu->memory, get_register(cpu, mem_get8(cpu->memory, PC + 1)), get_register(cpu, mem_read8(cpu->memory, PC))); break; } mem_add += 2; break; case MOVIRM: break; case MOVMRM: break; case OUTN: D("G"); cpu->IO = mem_read8(cpu->memory, PC); D("Y"); mem_add += 1; D("H"); break; case OUTR: cpu->IO = get_register(cpu, mem_read8(cpu->memory, PC)); mem_add += 1; break; case OUTM: cpu->IO = mem_read8(cpu->memory, mem_read32(cpu->memory, PC)); mem_add += 4; break; case RET: break; } cpu->regs.PC += mem_add + 0; return 0; }
void boot_boot(void) { int a; // memory init (Must do before cpuinit!) mem_init(RDRAMSIZE); // cpu/compiler init cpu_init(); // os emulator structures os_init(); // map cart into memory (read only) for(a=0;a<cart.size;a+=4096) { mem_mapexternal(0x10000000+a,MAP_R,cart.data+a); mem_mapexternal(0x90000000+a,MAP_R,cart.data+a); mem_mapexternal(0xb0000000+a,MAP_R,cart.data+a); } // copy pif rom #ifdef PIFROM memcpy(RPIF,pifRomImage,0x7c0); memcpy(WPIF,pifRomImage,0x7c0); #endif cart.codebase=mem_read32(0x10000008); cart.codesize=0x100000; // guess, always same? if(cart.codesize>4096*1024) { print("error: codeblock too large"); return; } if(mem_read32(0x10000540)!=0) cart.bootloader=1; if(cart.bootloader==1) { print("Alternate boot loader. "); cart.codebase&=~0x300000; // fzero } if(0) { // RealBoot mem_writerangeraw(0xa4000000,4096,cart.data); cpu_goto(0xa4000000); } else { // C-Boot mem_writerangeraw(cart.codebase,cart.codesize,cart.data+0x1000); sym_load(cart.symname); cpu_goto(cart.codebase); } st.framesync=cart.framesync; view.codebase=cart.codebase; view_changed(VIEW_CODE); }