nagra2-0101.c

来自「VDR softcam plugin 0.9.1」· C语言 代码 · 共 969 行 · 第 1/2 页

C
969
字号
  memcpy(data,mecmCode,sizeof(data));  RotateBytes(data,sizeof(data));  SHA1(data,sizeof(data)-8,data);  RotateBytes(data,20);  if(memcmp(data,mecmCode,8)) {     PRINTF(L_SYS_ECM,"%04X: MECM %02x decrypt signature failed",id,keyNr);     return false;    }  memcpy(hw,hd,seedSize);  ExpandInput(hw);  SetSp(0x0FFF,0x0EF8);  ClearBreakpoints();  SetMem(0x0100,mecmCode+8,0x100-8);  SetMem(0xa00,hd,seedSize);  SetMem(0x0ba2,hw,0x80);  AddBreakpoint(0x0000);  AddRomCallbacks();  SetPc(0x0100);  while(!Run(100000)) {    if(GetPc()==0x0000) {      GetMem(0x0ba2,hw,0x80);      return true;      }    else if(!RomCallbacks()) return false;    }/*  if(algo==0x40) {    const int hwCount=2;    memcpy(hw,hd,hwCount+1);    ExpandInput(hw);    hw[0x18]|=1; hw[0x40]|=1;    DoMap(SETSIZE,0,2);    DoMap(IMPORT_A,hw,3);    DoMap(IMPORT_D,hw+24);    DoMap(0x3b);    DoMap(EXPORT_C,hw);    DoMap(IMPORT_A,hw+40,3);    DoMap(IMPORT_D,hw+64);    DoMap(0x3b);    DoMap(EXPORT_C,hw+40);    DoMap(0x43);    DoMap(0x44,hw);    DoMap(0x44,hw+64);    memcpy(&hw[0],&hw[64+4],hwCount);    memset(&hw[hwCount],0,128-hwCount);    return true;    }  else if(algo==0x60) { // map 4D/4E/57    hw[127]|=0x80; hw[0]|=0x01;    DoMap(SETSIZE,0,16);    DoMap(IMPORT_A,hw);    DoMap(0x4d);    DoMap(0x4e);    DoMap(EXPORT_A,hw);    RotateBytes(hw,16);    DoMap(IMPORT_A,hw);    DoMap(0x4e);    DoMap(EXPORT_A,hw);    DoMap(0x57,hw);    return true;    }  PRINTF(L_SYS_ECM,"%04X: unknown MECM algo %02x",id,algo);*/  return false;}bool cN2Prov0101::PostProcAU(int id, unsigned char *data){  if(data[1]&0x5f) return false;  return true;}bool cN2Prov0101::RomInit(void){  if(!AddMapper(hwMapper=new cMapMemHW(),HW_OFFSET,HW_REGS,0x00)) return false;  SetPc(0x4000);  SetSp(0x0FFF,0x0FE0);  ClearBreakpoints();  AddBreakpoint(0x537d);  AddBreakpoint(0x8992);  AddBreakpoint(0xA822);  while(!Run(7000)) {    switch(GetPc()) {      case 0x537d:        PRINTF(L_SYS_EMU,"%04x: ROM init successfull",id);        return true;      default:        PRINTF(L_SYS_EMU,"%04x: ROM init failed: unexpected breakpoint",id);        break;      }    }  return false;}bool cN2Prov0101::ProcessMap(int f){  unsigned short addr;  unsigned char tmp[512];  int l=GetOpSize(Get(0x48));  int dl=l<<3;  switch(f) {    case SETSIZE:      DoMap(f,0,Get(0x48));      break;    case IMPORT_J:      l=8; dl=8<<3;      // fall throught    case IMPORT_A:    case IMPORT_B:    case IMPORT_C:    case IMPORT_D:    case IMPORT_LAST:      addr=HILO(0x44);      GetMem(addr,tmp,dl,0); DoMap(f,tmp,l);      break;    case EXPORT_J:      l=8; dl=8<<3;      // fall throught    case EXPORT_A:    case EXPORT_B:    case EXPORT_C:    case EXPORT_D:    case EXPORT_LAST:      addr=HILO(0x44);      DoMap(f,tmp,l); SetMem(addr,tmp,dl,0);      break;    case SWAP_A:    case SWAP_B:    case SWAP_C:    case SWAP_D:      addr=HILO(0x44);      GetMem(addr,tmp,dl,0); DoMap(f,tmp,l); SetMem(addr,tmp,dl,0);      break;    case CLEAR_A:    case CLEAR_B:    case CLEAR_C:    case CLEAR_D:    case COPY_A_B:    case COPY_B_A:    case COPY_A_C:    case COPY_C_A:    case COPY_C_D:    case COPY_D_C:      DoMap(f);      break;    case 0x22:      DoMap(f,tmp,(Get(0x48)<<16)|(Get(0x4a)<<8)|Get(0x49));      break;    case 0x29:    case 0x2a:      DoMap(f,tmp);      Set(0x4b,tmp[0]);      break;    case 0x3c:    case 0x3e:      GetMem(HILO(0x44),tmp,dl,0);      DoMap(f,tmp,Get(0x48));      break;    case 0x32:    case 0x39:    case 0x3b:      GetMem(HILO(0x44),tmp,dl,0);      DoMap(f,tmp,l);      break;    case 0x21:    case 0x23:    case 0x25:    case 0x30:    case 0x31:    case 0x36:    case 0x38:    case 0x3a:    case 0x43:      DoMap(f);      break;    case 0x44:    case 0x45:      GetMem(0x400,tmp,64,0);      DoMap(f,tmp,l);      SetMem(0x440,tmp,20,0);      break;     case 0x4d:      DoMap(f,tmp,-((Get(0x48)<<16)|(Get(0x49)<<8)|Get(0x4a)));      SetMem(0x400,tmp,53,0);      break;    case 0x4e:      GetMem(0x400,tmp,53,0);      DoMap(f,tmp);      SetMem(0x400,tmp,53,0);      break;    case 0x57:      addr=HILO(0x46);      l=wordsize; if(l<2 || l>4) l=4;      dl=l<<3;      for(int i=0; i<6; i++) GetMem(HILO(addr+i*2),tmp+i*dl,dl,0);      DoMap(f,tmp);      SetMem(0x400,tmp,0x40,0);      memset(tmp,0,11*32);      SetMem(0x440,tmp,11*32,0);      break;    default:      PRINTF(L_SYS_EMU,"%04x: map call %02x not emulated",id,f);      return false;    }  c6805::a=0; c6805::x=0; c6805::y=0;   return true;}bool cN2Prov0101::ProcessDESMap(int f){  unsigned char data[16];  switch(f) {    case 0x05:  // 3DES encrypt      DES_ecb2_encrypt(DES_CAST(desblock),DES_CAST(desblock),&desks1,&desks2,DES_ENCRYPT);      break;    case 0x06:  // 3DES decrypt      DES_ecb2_encrypt(DES_CAST(desblock),DES_CAST(desblock),&desks1,&desks2,DES_DECRYPT);      break;    case 0x07:      Set(0x2d,0x02); //XXX quick-hack or the real thing??      break;    case 0x0b:  // load DES data block from memory      GetMem(HILO(0x25),desblock,8,Get(0x24));      break;    case 0x0c:  // store DES data block to memory      SetMem(HILO(0x2b),desblock,8,Get(0x2a));      break;    case 0x0e:  // get DES key1 and key2      GetMem(HILO(0x25),data,8,Get(0x24));      DES_key_sched((DES_cblock *)data,&desks1);      GetMem(HILO(0x28),data,8,Get(0x27));      DES_key_sched((DES_cblock *)data,&desks2);      break;    case 0x0f:  // set DES size      desSize=Get(0x2d);      if(desSize!=0x10 && desSize!=0x18) {        PRINTF(L_SYS_EMU,"%04x: invalid DES key size %02x",id,desSize);        return false;        }      break;    default:      PRINTF(L_SYS_EMU,"%04x: DES map call %02x not emulated",id,f);      return false;  }  return true;}bool cN2Prov0101::RomCallbacks(void){  bool dopop=true;  unsigned int ea=GetPc();  if(ea&0x8000) ea|=(cr<<16);  switch(ea) {    case 0x3840: //MAP Handler    case 0x00A822:      if(!ProcessMap(a)) return false;      if(Interrupted()) dopop=false;      break;    case 0x3844: //DES Handler    case 0x008992:      if(!ProcessDESMap(a)) return false;      break;    case 0x5F23: //Erase_RAM_and_Hang    case 0x5F27: //Erase_RAM_and_Hang_Lp    case 0x5F5E: //BrainDead      PRINTF(L_SYS_EMU,"%04x: emu hung at %04x",id,ea);      return false;    case 0x70A6: //Write_Row_EEP_RC2_Len_A_To_RC1      {      unsigned short rc1=HILO(0x47);      unsigned short rc2=HILO(0x4a);      for(int i=0; i<a; i++) Set(0x80,rc1++,Get(dr,rc2++));      Set(0x4a,rc2>>8);      Set(0x4b,rc2&0xff);      break;      }    case 0x7BFE: //Write_Row_EEPROM_A_from_X_to_RC1      {      unsigned short rc1=HILO(0x47);      unsigned short rc2=c6805::x;      for(int i=0; i<a; i++) Set(0x80,rc1++,Get(rc2++));      break;      }    case 0x7CFF: //UPDATE_USW_03DD_03DE      Set(0x30E8,Get(0x03DD));      Set(0x30E9,Get(0x03DE));      break;    case 0x00A23C: //IDEA_Generate_Expanded_Key      {      unsigned char key[16];      GetMem(0x0a20,key,16);      idea.SetEncKey(key,&ks);      break;      }    case 0x00A2E9: //IDEA_Cypher      {      unsigned char data[8];      GetMem(0x070,data,8);      idea.Encrypt(data,8,data,&ks,0);      SetMem(0x070,data,8);      break;      }    default:      PRINTF(L_SYS_EMU,"%04X: unknown ROM breakpoint %04x",id,ea);      return false;    }  if(dopop) {    if(ea>=0x8000) PopCr();    PopPc();    }  return true;}void cN2Prov0101::AddRomCallbacks(void){  AddBreakpoint(0xA822); // map handler  AddBreakpoint(0x3840);  AddBreakpoint(0x3844);  AddBreakpoint(0xA23C); //IDEA   AddBreakpoint(0xA2E9);  AddBreakpoint(0x70A6);  AddBreakpoint(0x7BFE);  AddBreakpoint(0x7CFF);  AddBreakpoint(0x5F23);  AddBreakpoint(0x5F27);  AddBreakpoint(0x5F5E);}int cN2Prov0101::ProcessBx(unsigned char *data, int len, int pos){  if(Init(id,102)) {    SetMem(0x92,data+pos-1,len-pos+1);    SetPc(0x93);    SetSp(0x0FFF,0x0EF8);    ClearBreakpoints();    AddBreakpoint(0x9569);    AddBreakpoint(0x0000);    AddRomCallbacks();    while(!Run(1000)) {      if(GetPc()==0x9569) {        GetMem(0x80,data,len);        return a;        }      else if(GetPc()==0x0000) break;      else if(!RomCallbacks()) break;      }    }  return -1;}int cN2Prov0101::ProcessEx(unsigned char *data, int len, int pos){  if(Init(id,102)) {    SetMem(0x80,data,len);    SetPc(0x9591);    SetSp(0x0FFF,0x0EF8);    Push(0x99); //push the bug-table return onto the stack    Push(0x95);    Push(0x00);    Set(0x00,0x62,0x26);    Set(0x00,0x63,0x02);    Set(0x00,0x03d3,len-0x12);    ClearBreakpoints();    AddBreakpoint(0x9569);    AddBreakpoint(0x9599);    AddRomCallbacks();    while(!Run(10000)) {      if(GetPc()==0x9569) {        GetMem(0x80,data,len);        return max((int)a,6);        }      else if(GetPc()==0x9599) break;      else if(!RomCallbacks()) break;      }    }  return -1;}int cN2Prov0101::RunEmu(unsigned char *data, int len, unsigned short load, unsigned short run, unsigned short stop, unsigned short fetch, int fetch_len){  if(Init(id,102)) {    SetSp(0x0FFF,0x0EF8);    SetMem(load,data,len);    SetPc(run);    ClearBreakpoints();    AddBreakpoint(stop);    if(stop!=0x0000) AddBreakpoint(0x0000);    AddRomCallbacks();    while(!Run(100000)) {      if(GetPc()==0x0000 || GetPc()==stop) {        GetMem(fetch,data,fetch_len);        return 1;        }      else if(!RomCallbacks()) break;      }    }  return -1;}void cN2Prov0101::ReadHandler(unsigned char seg, unsigned short ea, unsigned char &op){   if(ea==0x2f70) op=random()&0xFF;   else if(ea==0x2f71) {     unsigned int n=random()&0xFF;     unsigned int cy=Cycles();     if(cy>rndtime && cy<=rndtime+4) {       unsigned int o=sn8(rnd);       n=(n&0xE3) | (o&4) | ((o>>1)&16) | ((o^(o>>1))&8);       }     op=rnd=n; rndtime=cy;     }}void cN2Prov0101::TimerHandler(unsigned int num){  if(hwMapper) {    int mask=hwMapper->AddCycles(num);    for(int t=0; mask; mask>>=1,t++)      if(mask&1) {        DisableTimers(11);        if(t==2) {          PRINTF(L_SYS_EMU,"0101: Timer interrupt %u @ %04x",t,GetPc());          RaiseException(9);          if(Interruptible()) throw(t);          }        }    }}void cN2Prov0101::Stepper(void){  unsigned short pc=GetPc();  if(pc>=0x93 && pc<=0xE0) { 	// pc in EMM data    unsigned char op=Get(pc);    if((op&0xF0)==0x00) { 	// current opcode BRCLR/BRSET      int fake=0; 		// 1=branch -1=non-branch      if(Get(pc+3)==0x81) 	// next opcode == RTS        fake=1;			// fake branch      else {        unsigned char off=Get(pc+2);        unsigned short target=pc+3+off;        if(off&0x80) target-=0x100;        if(Get(target)==0x81) 	// branch target == RTS          fake=-1;		// fake non-branch        }      if(fake) {        unsigned short ea=Get(pc+1);        unsigned char val=Get(dr,ea);        int bit=1<<((op&0xF)>>1);        // set/clr bit according to fake-mode and opcode        if((fake>0 && (op&0x01)) || (fake<0 && !(op&0x01)))  {          if(val&bit) loglb->Printf("*");          val&=~bit;          }        else {          if(!(val&bit)) loglb->Printf("*");          val|=bit;          }        Set(dr,ea,val);        }      }    }}// -- cN2Prov0901 --------------------------------------------------------------class cN2Prov0901 : public cN2Prov0101 {public:  cN2Prov0901(int Id, int Flags);  };static cN2ProvLinkReg<cN2Prov0901,0x0901,(N2FLAG_MECM|N2FLAG_POSTAU|N2FLAG_Bx|N2FLAG_Ex)> staticPL0901;cN2Prov0901::cN2Prov0901(int Id, int Flags):cN2Prov0101(Id,Flags){  mecmAddr[0]=0x91f5; mecmAddr[1]=0x92f5; mecmKeyId=0x907;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?