X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fnew_dynarec%2Fnew_dynarec.c;h=6f7c5673785dd63e1638f30794b4a0b26deb752e;hp=9b8f153c0fbcf82852cb17eb60102fe3ac72ef57;hb=2002a1dbd97bc1b94b12ec3e90702a770b040858;hpb=57871462a0b157066bbc4a763c59b61085436609 diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index 9b8f153c..6f7c5673 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -22,14 +22,7 @@ #include //include for uint64_t #include -#include "../recomp.h" -#include "../recomph.h" //include for function prototypes -#include "../macros.h" -#include "../r4300.h" -#include "../ops.h" -#include "../interupt.h" - -#include "../../memory/memory.h" +#include "emu_if.h" //emulator interface #include @@ -258,8 +251,9 @@ void nullf() {} #define assem_debug nullf #define inv_debug nullf -void tlb_hacks() +static void tlb_hacks() { +#ifndef DISABLE_TLB // Goldeneye hack if (strncmp((char *) ROM_HEADER->nom, "GOLDENEYE",9) == 0) { @@ -301,18 +295,35 @@ void tlb_hacks() } } } +#endif } -// Get address from virtual address -// This is called from the recompiled JR/JALR instructions -void *get_addr(u_int vaddr) +static u_int get_page(u_int vaddr) { u_int page=(vaddr^0x80000000)>>12; - u_int vpage=page; +#ifndef DISABLE_TLB if(page>262143&&tlb_LUT_r[vaddr>>12]) page=(tlb_LUT_r[vaddr>>12]^0x80000000)>>12; +#endif if(page>2048) page=2048+(page&2047); + return page; +} + +static u_int get_vpage(u_int vaddr) +{ + u_int vpage=(vaddr^0x80000000)>>12; +#ifndef DISABLE_TLB if(vpage>262143&&tlb_LUT_r[vaddr>>12]) vpage&=2047; // jump_dirty uses a hash of the virtual address instead +#endif if(vpage>2048) vpage=2048+(vpage&2047); + return vpage; +} + +// Get address from virtual address +// This is called from the recompiled JR/JALR instructions +void *get_addr(u_int vaddr) +{ + u_int page=get_page(vaddr); + u_int vpage=get_vpage(vaddr); struct ll_entry *head; //printf("TRACE: count=%d next=%d (get_addr %x,page %d)\n",Count,next_interupt,vaddr,page); head=jump_in[page]; @@ -339,10 +350,12 @@ void *get_addr(u_int vaddr) invalid_code[vaddr>>12]=0; memory_map[vaddr>>12]|=0x40000000; if(vpage<2048) { +#ifndef DISABLE_TLB if(tlb_LUT_r[vaddr>>12]) { invalid_code[tlb_LUT_r[vaddr>>12]>>12]=0; memory_map[tlb_LUT_r[vaddr>>12]>>12]|=0x40000000; } +#endif restore_candidate[vpage>>3]|=1<<(vpage&7); } else restore_candidate[page>>3]|=1<<(page&7); @@ -390,12 +403,8 @@ void *get_addr_32(u_int vaddr,u_int flags) int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF]; if(ht_bin[0]==vaddr) return (void *)ht_bin[1]; if(ht_bin[2]==vaddr) return (void *)ht_bin[3]; - u_int page=(vaddr^0x80000000)>>12; - u_int vpage=page; - if(page>262143&&tlb_LUT_r[vaddr>>12]) page=(tlb_LUT_r[vaddr>>12]^0x80000000)>>12; - if(page>2048) page=2048+(page&2047); - if(vpage>262143&&tlb_LUT_r[vaddr>>12]) vpage&=2047; // jump_dirty uses a hash of the virtual address instead - if(vpage>2048) vpage=2048+(vpage&2047); + u_int page=get_page(vaddr); + u_int vpage=get_vpage(vaddr); struct ll_entry *head; head=jump_in[page]; while(head!=NULL) { @@ -430,10 +439,12 @@ void *get_addr_32(u_int vaddr,u_int flags) invalid_code[vaddr>>12]=0; memory_map[vaddr>>12]|=0x40000000; if(vpage<2048) { +#ifndef DISABLE_TLB if(tlb_LUT_r[vaddr>>12]) { invalid_code[tlb_LUT_r[vaddr>>12]>>12]=0; memory_map[tlb_LUT_r[vaddr>>12]>>12]|=0x40000000; } +#endif restore_candidate[vpage>>3]|=1<<(vpage&7); } else restore_candidate[page>>3]|=1<<(page&7); @@ -974,9 +985,7 @@ void *check_addr(u_int vaddr) if(((ht_bin[3]-MAX_OUTPUT_BLOCK_SIZE-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) if(isclean(ht_bin[3])) return (void *)ht_bin[3]; } - u_int page=(vaddr^0x80000000)>>12; - if(page>262143&&tlb_LUT_r[vaddr>>12]) page=(tlb_LUT_r[vaddr>>12]^0x80000000)>>12; - if(page>2048) page=2048+(page&2047); + u_int page=get_page(vaddr); struct ll_entry *head; head=jump_in[page]; while(head!=NULL) { @@ -1104,12 +1113,8 @@ int invalidate_page(u_int page) void invalidate_block(u_int block) { int modified; - u_int page,vpage; - page=vpage=block^0x80000; - if(page>262143&&tlb_LUT_r[block]) page=(tlb_LUT_r[block]^0x80000000)>>12; - if(page>2048) page=2048+(page&2047); - if(vpage>262143&&tlb_LUT_r[block]) vpage&=2047; // jump_dirty uses a hash of the virtual address instead - if(vpage>2048) vpage=2048+(vpage&2047); + u_int page=get_page(block<<12); + u_int vpage=get_vpage(block<<12); inv_debug("INVALIDATE: %x (%d)\n",block<<12,page); //inv_debug("invalid_code[block]=%d\n",invalid_code[block]); u_int first,last; @@ -1128,12 +1133,14 @@ void invalidate_block(u_int block) if((((end-1-(u_int)rdram)>>12)&2047)>last) last=((end-1-(u_int)rdram)>>12)&2047; } } +#ifndef DISABLE_TLB if(page<2048&&(signed int)start>=(signed int)0xC0000000&&(signed int)end>=(signed int)0xC0000000) { if(((start+memory_map[start>>12]-(u_int)rdram)>>12)<=page&&((end-1+memory_map[(end-1)>>12]-(u_int)rdram)>>12)>=page) { if((((start+memory_map[start>>12]-(u_int)rdram)>>12)&2047)>12]-(u_int)rdram)>>12)&2047; if((((end-1+memory_map[(end-1)>>12]-(u_int)rdram)>>12)&2047)>last) last=((end-1+memory_map[(end-1)>>12]-(u_int)rdram)>>12)&2047; } } +#endif } head=head->next; } @@ -1152,6 +1159,7 @@ void invalidate_block(u_int block) // Don't trap writes invalid_code[block]=1; +#ifndef DISABLE_TLB // If there is a valid TLB entry for this page, remove write protect if(tlb_LUT_w[block]) { assert(tlb_LUT_r[block]==tlb_LUT_w[block]); @@ -1162,6 +1170,7 @@ void invalidate_block(u_int block) if(real_block>=0x80000&&real_block<0x80800) memory_map[real_block]=((u_int)rdram-0x80000000)>>2; } else if(block>=0x80000&&block<0x80800) memory_map[block]=((u_int)rdram-0x80000000)>>2; +#endif #ifdef __arm__ if(modified) __clear_cache((void *)BASE_ADDR,(void *)BASE_ADDR+(1<>12; - if(page>262143&&tlb_LUT_r[vaddr>>12]) page=(tlb_LUT_r[vaddr>>12]^0x80000000)>>12; - if(page>4095) page=2048+(page&2047); + u_int page=get_page(vaddr); inv_debug("add_link: %x -> %x (%d)\n",(int)src,vaddr,page); ll_add(jump_out+page,vaddr,src); //int ptr=get_pointer(src); @@ -1251,7 +1260,9 @@ void clean_blocks(u_int page) void * clean_addr=(void *)get_clean_addr((int)head->addr); if((((u_int)clean_addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) { u_int ppage=page; +#ifndef DISABLE_TLB if(page<2048&&tlb_LUT_r[head->vaddr>>12]) ppage=(tlb_LUT_r[head->vaddr>>12]^0x80000000)>>12; +#endif inv_debug("INV: Restored %x (%x/%x)\n",head->vaddr, (int)head->addr, (int)clean_addr); //printf("page=%x, addr=%x\n",page,head->vaddr); //assert(head->vaddr>>12==(page|0x80000)); @@ -1919,10 +1930,12 @@ void wb_register(signed char r,signed char regmap[],uint64_t dirty,uint64_t is32 if((dirty>>hr)&1) { if(regmap[hr]<64) { emit_storereg(r,hr); +#ifndef FORCE32 if((is32>>regmap[hr])&1) { emit_sarimm(hr,31,hr); emit_storereg(r|64,hr); } +#endif }else{ emit_storereg(r|64,hr); } @@ -1953,14 +1966,6 @@ int rchecksum() sum^=((u_int *)reg)[i]; return sum; } -int fchecksum() -{ - int i; - int sum=0; - for(i=0;i<64;i++) - sum^=((u_int *)reg_cop1_fgr_64)[i]; - return sum; -} void rlist() { int i; @@ -1968,10 +1973,12 @@ void rlist() for(i=0;i<32;i++) printf("r%d:%8x%8x ",i,((int *)(reg+i))[1],((int *)(reg+i))[0]); printf("\n"); +#ifndef DISABLE_COP1 printf("TRACE: "); for(i=0;i<32;i++) printf("f%d:%8x%8x ",i,((int*)reg_cop1_simple[i])[1],*((int*)reg_cop1_simple[i])); printf("\n"); +#endif } void enabletrace() @@ -2741,8 +2748,13 @@ void load_assemble(int i,struct regstat *i_regs) //gen_tlb_addr_r(tl,map); //emit_movsbl_indexed((int)rdram-0x80000000,tl,tl); int x=0; +#ifdef BIG_ENDIAN_MIPS if(!c) emit_xorimm(addr,3,tl); else x=((constmap[i][s]+offset)^3)-(constmap[i][s]+offset); +#else + if(c) x=(constmap[i][s]+offset)-(constmap[i][s]+offset); + else if (tl!=addr) emit_mov(addr,tl); +#endif emit_movsbl_indexed_tlb(x,tl,map,tl); } if(jaddr) @@ -2760,8 +2772,13 @@ void load_assemble(int i,struct regstat *i_regs) #endif { int x=0; +#ifdef BIG_ENDIAN_MIPS if(!c) emit_xorimm(addr,2,tl); else x=((constmap[i][s]+offset)^2)-(constmap[i][s]+offset); +#else + if(c) x=(constmap[i][s]+offset)-(constmap[i][s]+offset); + else if (tl!=addr) emit_mov(addr,tl); +#endif //#ifdef //emit_movswl_indexed_tlb(x,tl,map,tl); //else @@ -2804,8 +2821,13 @@ void load_assemble(int i,struct regstat *i_regs) //gen_tlb_addr_r(tl,map); //emit_movzbl_indexed((int)rdram-0x80000000,tl,tl); int x=0; +#ifdef BIG_ENDIAN_MIPS if(!c) emit_xorimm(addr,3,tl); else x=((constmap[i][s]+offset)^3)-(constmap[i][s]+offset); +#else + if(c) x=(constmap[i][s]+offset)-(constmap[i][s]+offset); + else if (tl!=addr) emit_mov(addr,tl); +#endif emit_movzbl_indexed_tlb(x,tl,map,tl); } if(jaddr) @@ -2823,8 +2845,13 @@ void load_assemble(int i,struct regstat *i_regs) #endif { int x=0; +#ifdef BIG_ENDIAN_MIPS if(!c) emit_xorimm(addr,2,tl); else x=((constmap[i][s]+offset)^2)-(constmap[i][s]+offset); +#else + if(c) x=(constmap[i][s]+offset)-(constmap[i][s]+offset); + else if (tl!=addr) emit_mov(addr,tl); +#endif //#ifdef //emit_movzwl_indexed_tlb(x,tl,map,tl); //#else @@ -2981,8 +3008,13 @@ void store_assemble(int i,struct regstat *i_regs) if (opcode[i]==0x28) { // SB if(!c||memtarget) { int x=0; +#ifdef BIG_ENDIAN_MIPS if(!c) emit_xorimm(addr,3,temp); else x=((constmap[i][s]+offset)^3)-(constmap[i][s]+offset); +#else + if(c) x=(constmap[i][s]+offset)-(constmap[i][s]+offset); + else if (addr!=temp) emit_mov(addr,temp); +#endif //gen_tlb_addr_w(temp,map); //emit_writebyte_indexed(tl,(int)rdram-0x80000000,temp); emit_writebyte_indexed_tlb(tl,x,temp,map,temp); @@ -2992,8 +3024,13 @@ void store_assemble(int i,struct regstat *i_regs) if (opcode[i]==0x29) { // SH if(!c||memtarget) { int x=0; +#ifdef BIG_ENDIAN_MIPS if(!c) emit_xorimm(addr,2,temp); else x=((constmap[i][s]+offset)^2)-(constmap[i][s]+offset); +#else + if(c) x=(constmap[i][s]+offset)-(constmap[i][s]+offset); + else if (addr!=temp) emit_mov(addr,temp); +#endif //#ifdef //emit_writehword_indexed_tlb(tl,x,temp,map,temp); //#else @@ -3143,6 +3180,9 @@ void storelr_assemble(int i,struct regstat *i_regs) if(!rs2[i]) temp2=th=tl; } +#ifndef BIG_ENDIAN_MIPS + emit_xorimm(temp,3,temp); +#endif emit_testimm(temp,2); case2=(int)out; emit_jne(0); @@ -3307,6 +3347,7 @@ void storelr_assemble(int i,struct regstat *i_regs) void c1ls_assemble(int i,struct regstat *i_regs) { +#ifndef DISABLE_COP1 int s,th,tl; int temp,ar; int map=-1; @@ -3481,6 +3522,9 @@ void c1ls_assemble(int i,struct regstat *i_regs) emit_call((int)memdebug); emit_popa(); }/**/ +#else + cop1_unusable(i, i_regs); +#endif } #ifndef multdiv_assemble @@ -4041,6 +4085,7 @@ void wb_dirtys(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty) if((i_dirty>>hr)&1) { if(i_regmap[hr]<64) { emit_storereg(i_regmap[hr],hr); +#ifndef FORCE32 if( ((i_is32>>i_regmap[hr])&1) ) { #ifdef DESTRUCTIVE_WRITEBACK emit_sarimm(hr,31,hr); @@ -4050,6 +4095,7 @@ void wb_dirtys(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty) emit_storereg(i_regmap[hr]|64,HOST_TEMPREG); #endif } +#endif }else{ if( !((i_is32>>(i_regmap[hr]&63))&1) ) { emit_storereg(i_regmap[hr],hr); @@ -4075,6 +4121,7 @@ void wb_needed_dirtys(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty,in if((i_dirty>>hr)&1) { if(i_regmap[hr]<64) { emit_storereg(i_regmap[hr],hr); +#ifndef FORCE32 if( ((i_is32>>i_regmap[hr])&1) ) { #ifdef DESTRUCTIVE_WRITEBACK emit_sarimm(hr,31,hr); @@ -4084,6 +4131,7 @@ void wb_needed_dirtys(signed char i_regmap[],uint64_t i_is32,uint64_t i_dirty,in emit_storereg(i_regmap[hr]|64,HOST_TEMPREG); #endif } +#endif }else{ if( !((i_is32>>(i_regmap[hr]&63))&1) ) { emit_storereg(i_regmap[hr],hr); @@ -6192,12 +6240,8 @@ static void pagespan_ds() { assem_debug("initial delay slot:\n"); u_int vaddr=start+1; - u_int page=(0x80000000^vaddr)>>12; - u_int vpage=page; - if(page>262143&&tlb_LUT_r[vaddr>>12]) page=(tlb_LUT_r[page^0x80000]^0x80000000)>>12; - if(page>2048) page=2048+(page&2047); - if(vpage>262143&&tlb_LUT_r[vaddr>>12]) vpage&=2047; // jump_dirty uses a hash of the virtual address instead - if(vpage>2048) vpage=2048+(vpage&2047); + u_int page=get_page(vaddr); + u_int vpage=get_vpage(vaddr); ll_add(jump_dirty+vpage,vaddr,(void *)out); do_dirty_stub_ds(); ll_add(jump_in+page,vaddr,(void *)out); @@ -6501,6 +6545,9 @@ void unneeded_registers(int istart,int iend,int r) // Save it unneeded_reg[i]=u; unneeded_reg_upper[i]=uu; +#ifdef FORCE32 + unneeded_reg_upper[i]=-1LL; +#endif /* printf("ur (%d,%d) %x: ",istart,iend,start+i*4); printf("U:"); @@ -7381,10 +7428,12 @@ void new_dynarec_init() PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) <= 0) {printf("mmap() failed\n");} +#ifdef MUPEN64 rdword=&readmem_dword; fake_pc.f.r.rs=&readmem_dword; fake_pc.f.r.rt=&readmem_dword; fake_pc.f.r.rd=&readmem_dword; +#endif int n; for(n=0x80000;n<0x80800;n++) invalid_code[n]=1; @@ -7409,32 +7458,44 @@ void new_dynarec_init() memory_map[n]=((u_int)rdram-0x80000000)>>2; for(n=526336;n<1048576;n++) // 0x80800000 .. 0xFFFFFFFF memory_map[n]=-1; +#ifdef MUPEN64 for(n=0;n<0x8000;n++) { // 0 .. 0x7FFFFFFF writemem[n] = write_nomem_new; writememb[n] = write_nomemb_new; writememh[n] = write_nomemh_new; +#ifndef FORCE32 writememd[n] = write_nomemd_new; +#endif readmem[n] = read_nomem_new; readmemb[n] = read_nomemb_new; readmemh[n] = read_nomemh_new; +#ifndef FORCE32 readmemd[n] = read_nomemd_new; +#endif } for(n=0x8000;n<0x8080;n++) { // 0x80000000 .. 0x807FFFFF writemem[n] = write_rdram_new; writememb[n] = write_rdramb_new; writememh[n] = write_rdramh_new; +#ifndef FORCE32 writememd[n] = write_rdramd_new; +#endif } for(n=0xC000;n<0x10000;n++) { // 0xC0000000 .. 0xFFFFFFFF writemem[n] = write_nomem_new; writememb[n] = write_nomemb_new; writememh[n] = write_nomemh_new; +#ifndef FORCE32 writememd[n] = write_nomemd_new; +#endif readmem[n] = read_nomem_new; readmemb[n] = read_nomemb_new; readmemh[n] = read_nomemh_new; +#ifndef FORCE32 readmemd[n] = read_nomemd_new; +#endif } +#endif tlb_hacks(); arch_init(); } @@ -7474,14 +7535,18 @@ int new_recompile_block(int addr) //rlist(); start = (u_int)addr&~3; //assert(((u_int)addr&1)==0); +#ifdef MUPEN64 if ((int)addr >= 0xa4000000 && (int)addr < 0xa4001000) { source = (u_int *)((u_int)SP_DMEM+start-0xa4000000); pagelimit = 0xa4001000; } - else if ((int)addr >= 0x80000000 && (int)addr < 0x80800000) { + else +#endif + if ((int)addr >= 0x80000000 && (int)addr < 0x80800000) { source = (u_int *)((u_int)rdram+start-0x80000000); pagelimit = 0x80800000; } +#ifndef DISABLE_TLB else if ((signed int)addr >= (signed int)0xC0000000) { //printf("addr=%x mm=%x\n",(u_int)addr,(memory_map[start>>12]<<2)); //if(tlb_LUT_r[start>>12]) @@ -7505,6 +7570,7 @@ int new_recompile_block(int addr) } //printf("source= %x\n",(int)source); } +#endif else { printf("Compile at bogus memory address: %x \n", (int)addr); exit(1); @@ -7792,7 +7858,9 @@ int new_recompile_block(int addr) case 0x3C: strcpy(insn[i],"SCD"); type=NI; break; case 0x3D: strcpy(insn[i],"SDC1"); type=C1LS; break; case 0x3F: strcpy(insn[i],"SD"); type=STORE; break; - default: strcpy(insn[i],"???"); type=NI; break; + default: strcpy(insn[i],"???"); type=NI; + assem_debug("NI %08x @%08x\n", source[i], addr + i*4); + break; } itype[i]=type; opcode2[i]=op2; @@ -8153,6 +8221,11 @@ int new_recompile_block(int addr) current.is32=temp_is32; } } +#ifdef FORCE32 + memset(p32, 0xff, sizeof(p32)); + current.is32=-1LL; +#endif + memcpy(regmap_pre[i],current.regmap,sizeof(current.regmap)); regs[i].wasconst=current.isconst; regs[i].was32=current.is32; @@ -9919,6 +9992,7 @@ int new_recompile_block(int addr) else printf(" r%d",r); } } +#ifndef FORCE32 printf(" UU:"); for(r=1;r<=CCREG;r++) { if(((unneeded_reg_upper[i]&~unneeded_reg[i])>>r)&1) { @@ -9937,6 +10011,7 @@ int new_recompile_block(int addr) else printf(" r%d",r); } } +#endif printf("\n"); #if defined(__i386__) || defined(__x86_64__) printf("pre: eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",regmap_pre[i][0],regmap_pre[i][1],regmap_pre[i][2],regmap_pre[i][3],regmap_pre[i][5],regmap_pre[i][6],regmap_pre[i][7]); @@ -10058,6 +10133,7 @@ int new_recompile_block(int addr) #endif printf("\n"); } +#ifndef FORCE32 printf(" 32:"); for(r=0;r<=CCREG;r++) { if((regs[i].is32>>r)&1) { @@ -10068,6 +10144,7 @@ int new_recompile_block(int addr) } } printf("\n"); +#endif /*printf(" p32:"); for(r=0;r<=CCREG;r++) { if((p32[i]>>r)&1) { @@ -10105,6 +10182,7 @@ int new_recompile_block(int addr) if((branch_regs[i].dirty>>10)&1) printf("r10 "); if((branch_regs[i].dirty>>12)&1) printf("r12 "); #endif +#ifndef FORCE32 printf(" 32:"); for(r=0;r<=CCREG;r++) { if((branch_regs[i].is32>>r)&1) { @@ -10115,6 +10193,7 @@ int new_recompile_block(int addr) } } printf("\n"); +#endif } } @@ -10352,12 +10431,8 @@ int new_recompile_block(int addr) if(instr_addr[i]) // TODO - delay slots (=null) { u_int vaddr=start+i*4; - u_int page=(0x80000000^vaddr)>>12; - u_int vpage=page; - if(page>262143&&tlb_LUT_r[vaddr>>12]) page=(tlb_LUT_r[page^0x80000]^0x80000000)>>12; - if(page>2048) page=2048+(page&2047); - if(vpage>262143&&tlb_LUT_r[vaddr>>12]) vpage&=2047; // jump_dirty uses a hash of the virtual address instead - if(vpage>2048) vpage=2048+(vpage&2047); + u_int page=get_page(vaddr); + u_int vpage=get_vpage(vaddr); literal_pool(256); //if(!(is32[i]&(~unneeded_reg_upper[i])&~(1LL<>12;i<=(start+slen*4)>>12;i++) { invalid_code[i]=0; +#ifndef DISABLE_TLB memory_map[i]|=0x40000000; if((signed int)start>=(signed int)0xC0000000) { assert(using_tlb); @@ -10429,6 +10505,7 @@ int new_recompile_block(int addr) memory_map[j]|=0x40000000; //printf("write protect physical page: %x (virtual %x)\n",j<<12,start); } +#endif } /* Pass 10 - Free memory by expiring oldest blocks */