⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Softcam plugin to VDR (C++) * * This code is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "data.h"#include "cpu.h"#include "log-nagra.h"#define LOGLBPUT(t...)  loglb->Printf(t)#define CCLOGLBPUT(t...)  do { if(doDisAsm) loglb->Printf(t); } while(0)// -- cMapMem ------------------------------------------------------------------cMapMem::cMapMem(unsigned short Offset, int Size){  offset=Offset; size=Size;  if((mem=(unsigned char *)malloc(size)))    memset(mem,0,size);  PRINTF(L_SYS_EMU,"mapmem: new map off=%04x size=%04x",offset,size);}cMapMem::~cMapMem(){  free(mem);}bool cMapMem::IsFine(void){  return (mem!=0);}unsigned char cMapMem::Get(unsigned short ea){  return (ea>=offset && ea<offset+size) ? mem[ea-offset] : 0;}void cMapMem::Set(unsigned short ea, unsigned char val){  if(ea>=offset && ea<offset+size)    mem[ea-offset]=val;}// -- cMapRom ------------------------------------------------------------------cMapRom::cMapRom(unsigned short Offset, const char *Filename, int InFileOffset){  offset=Offset; addr=0;  fm=filemaps.GetFileMap(Filename,FILEMAP_DOMAIN,false);  if(fm && fm->Map()) {    addr=fm->Addr()+InFileOffset;    size=fm->Size()-InFileOffset;    PRINTF(L_SYS_EMU,"maprom: new map off=%04x size=%04x",offset,size);    }}cMapRom::~cMapRom(){  if(fm) fm->Unmap();}bool cMapRom::IsFine(void){  return (addr!=0);}unsigned char cMapRom::Get(unsigned short ea){  return (ea>=offset && ea<offset+size) ? addr[ea-offset] : 0;}void cMapRom::Set(unsigned short ea, unsigned char val){  if(ea>=offset && ea<offset+size) LOGLBPUT("[ROM] ");  // this is a ROM!}// -- cMapEeprom ---------------------------------------------------------------cMapEeprom::cMapEeprom(unsigned short Offset, const char *Filename, int OtpSize, int InFileOffset){  offset=Offset; otpSize=OtpSize; addr=0;  fm=filemaps.GetFileMap(Filename,FILEMAP_DOMAIN,true);  if(fm && fm->Map()) {    addr=fm->Addr()+InFileOffset;    size=fm->Size()-InFileOffset;    PRINTF(L_SYS_EMU,"mapeeprom: new map off=%04x size=%04x otp=%04x",offset,size,otpSize);    }}cMapEeprom::~cMapEeprom(){  if(fm) fm->Unmap();}bool cMapEeprom::IsFine(void){  return (addr!=0);}unsigned char cMapEeprom::Get(unsigned short ea){  return (ea>=offset && ea<offset+size) ? addr[ea-offset] : 0;}void cMapEeprom::Set(unsigned short ea, unsigned char val){  if(ea>=offset && ea<offset+otpSize) {    if(addr[ea-offset]==0) {      addr[ea-offset]=val;      LOGLBPUT("[OTP-SET] ");      }    LOGLBPUT("[OTP] ");    }  if(ea>=offset+otpSize && ea<offset+size) {    addr[ea-offset]=val;    LOGLBPUT("[EEP] ");    }}// -- c6805 --------------------------------------------------------------------#define HILO(ea)      ((Get(ea)<<8)+Get((ea)+1))#define HILOS(s,ea)   ((Get((s),(ea))<<8)+Get((s),(ea)+1))#define PAGEOFF(ea,s) (((ea)&0x8000) ? pageMap[s]:0)c6805::c6805(void) {  cc.c=0; cc.z=0; cc.n=0; cc.i=0; cc.h=0; cc.v=1;  pc=0; a=0; x=0; y=0; cr=dr=0; sp=spHi=0x100; spLow=0xC0;  ClearBreakpoints();  InitMapper();  memset(stats,0,sizeof(stats));  loglb=new cLineBuff(128);}c6805::~c6805(){  if(LOG(L_SYS_CPUSTATS)) {    int i, j, sort[256];    for(i=0; i<256; i++) sort[i]=i;    for(i=0; i<256; i++)      for(j=0; j<255; j++)        if(stats[sort[j]]<stats[sort[j+1]]) {          int x=sort[j]; sort[j]=sort[j+1]; sort[j+1]=x;          }    PRINTF(L_SYS_CPUSTATS,"opcode statistics");    for(i=0; i<256; i++)      if((j=stats[sort[i]])) PRINTF(L_SYS_CPUSTATS,"opcode %02x: %d",sort[i],j);    }  ClearMapper();  delete loglb;}bool c6805::AddMapper(cMap *map, unsigned short start, int size, unsigned char seg){  if(map && map->IsFine()) {    if(nextMapper<MAX_MAPPER) {      map->loglb=loglb;      mapper[nextMapper]=map;      memset(&mapMap[start+PAGEOFF(start,seg)],nextMapper,size);      nextMapper++;      return true;      }    else PRINTF(L_SYS_EMU,"6805: too many mappers");    }  else PRINTF(L_SYS_EMU,"6805: mapper not ready");  delete map;  return false;}void c6805::ResetMapper(void){  ClearMapper(); InitMapper();}void c6805::InitMapper(void){  memset(mapMap,0,sizeof(mapMap));  memset(mapper,0,sizeof(mapper));  mapper[0]=new cMapMem(0,PAGE_SIZE*2);  nextMapper=1;  memset(pageMap,0,sizeof(pageMap));  pageMap[0]=PAGE_SIZE*0;  pageMap[1]=PAGE_SIZE*1;  pageMap[2]=PAGE_SIZE*2;  pageMap[0x80]=PAGE_SIZE*3;}void c6805::ClearMapper(void){  for(int i=0; i<MAX_MAPPER; i++) delete mapper[i];}unsigned char c6805::Get(unsigned short ea) const{  return mapper[mapMap[ea+PAGEOFF(ea,cr)]&0x7f]->Get(ea);}unsigned char c6805::Get(unsigned char seg, unsigned short ea) const{  return mapper[mapMap[ea+PAGEOFF(ea,seg)]&0x7f]->Get(ea);}void c6805::Set(unsigned short ea, unsigned char val){  unsigned char mapId=mapMap[ea+PAGEOFF(ea,cr)];  if(!(mapId&0x80)) mapper[mapId&0x7f]->Set(ea,val);}void c6805::Set(unsigned char seg, unsigned short ea, unsigned char val){  unsigned char mapId=mapMap[ea+PAGEOFF(ea,seg)];  if(!(mapId&0x80)) mapper[mapId&0x7f]->Set(ea,val);}void c6805::ForceSet(unsigned short ea, unsigned char val, bool ro){  mapMap[ea]=0;     		// reset to RAM map  Set(0,ea,val);      		// set value  if(ro) mapMap[ea]|=0x80; 	// protect byte}void c6805::SetMem(unsigned short addr, const unsigned char *data, int len, unsigned char seg){  while(len>0) { Set(seg,addr++,*data++); len--; }}void c6805::GetMem(unsigned short addr, unsigned char *data, int len, unsigned char seg) const{  while(len>0) { *data++=Get(seg,addr++); len--; }}void c6805::SetSp(unsigned short SpHi, unsigned short SpLow){  spHi =sp=SpHi;  spLow   =SpLow;}void c6805::SetPc(unsigned short addr){  pc=addr;}void c6805::PopPc(void){  poppc();}void c6805::PopCr(void){  cr=pop();}void c6805::AddBreakpoint(unsigned short addr){  if(numBp<MAX_BREAKPOINTS) {    bp[numBp++]=addr;    PRINTF(L_SYS_EMU,"6805: setting breakpoint at 0x%04x",addr);    }  else PRINTF(L_SYS_EMU,"6805: too many breakpoints");}void c6805::ClearBreakpoints(void){  numBp=0;  memset(bp,0,sizeof(bp));}static const char * const ops[] = {//         0x00    0x01    0x02    0x03    0x04    0x05    0x06    0x07    0x08    0x09    0x0a    0x0b    0x0c    0x0d    0x0e    0x0f/* 0x00 */ "BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR",/* 0x10 */ "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR",/* 0x20 */ "BRA",  "BRN",  "BHI",  "BLS",  "BCC",  "BCS",  "BNE",  "BEQ",  "BHCC", "BHCS", "BPL",  "BMI",  "BMC",  "BMS",  "BIL",  "BIH",/* 0x30 */ "NEG",  "pre31","pre32","COM",  "LSR",  "op35", "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "op3b", "INC",  "TST",  "SWAP", "CLR",/* 0x40 */ "NEG",  "op41", "MUL",  "COM",  "LSR",  "op45", "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "op4b", "INC",  "TST",  "SWAP", "CLR",/* 0x50 */ "NEG",  "op51", "MUL",  "COM",  "LSR",  "op55", "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "op5b", "INC",  "TST",  "SWAP", "CLR",/* 0x60 */ "NEG",  "op61", "op62", "COM",  "LSR",  "op65", "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "op6b", "INC",  "TST",  "SWAP", "CLR",/* 0x70 */ "NEG",  "LDD",  "LDD",  "COM",  "LSR",  "LDD",  "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "TAD",  "INC",  "TST",  "SWAP", "CLR",/* 0x80 */ "RTI",  "RTS",  "op82", "SWI",  "POPA", "POP%c","POPC", "PRTS", "PUSHA","PUSH%c","PUSHC","TDA", "TCA",  "PJSR", "STOP", "WAIT",/* 0x90 */ "pre90","pre91","pre92","T%2$c%1$c","T%cS","TAS","TS%c","TA%c", "CLC",  "SEC",  "CLI",  "SEI",  "RSP",  "NOP",  "TSA",  "T%cA",/* 0xa0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "opa7", "EOR",  "ADC",  "ORA",  "ADD",  "PUSHD","BSR",  "LD%c", "POPD",/* 0xb0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",/* 0xc0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",/* 0xd0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",/* 0xe0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",/* 0xf0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",  };static const char * const vops[] = {  "BVGT","BVLE","BVGE","BVLT","BVC","BVS"  };// Flags:// 1 - read operant// 2 - write operant// 4 - use dr register// 8 - special address mode in high nibblestatic const char opFlags[] = {//            00    01    02    03    04    05    06    07    08    09    0a    0b    0c    0d    0e    0f/* 0x00 */  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,/* 0x10 */  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,/* 0x20 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,/* 0x30 */  0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,/* 0x40 */  0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,/* 0x50 */  0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,/* 0x60 */  0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,/* 0x70 */  0x03, 0xA9, 0xB9, 0x03, 0x03, 0xC9, 0x03, 0x03, 0x03, 0x03, 0x03, 0x88, 0x03, 0x01, 0x03, 0x02,/* 0x80 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,/* 0x90 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,/* 0xa0 */  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x88, 0x88, 0x01, 0x88,/* 0xb0 */  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02,/* 0xc0 */  0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,/* 0xd0 */  0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,/* 0xe0 */  0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,/* 0xf0 */  0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,  };char * c6805::PADDR(unsigned char s, unsigned short ea){  snprintf(addrBuff,sizeof(addrBuff),((ea&0x8000) && s>0)?"%2$x:%1$04x":"%04x",ea,s);  return addrBuff;}int c6805::Run(int max_count){// returns:// 0 - breakpoint// 1 - stack overflow// 2 - instruction counter exeeded// 3 - unsupported instruction  disAsmLogClass=L_SYS_DISASM;  if(LOG(L_SYS_DISASM)) doDisAsm=true;  else {    doDisAsm=false;    if(LOG(L_SYS_DISASM80)) disAsmLogClass=L_SYS_DISASM80;    }  PRINTF(disAsmLogClass,"cr:-pc- aa xx yy dr -sp- VHINZC -mem@pc- -mem@sp-");  int count=0;  while (1) {    if(sp<spLow) {      PRINTF(L_SYS_EMU,"stack overflow (count=%d)",count);      return 1;      }    if(spHi>spLow && sp>spHi) {      PRINTF(L_SYS_EMU,"stack underflow (count=%d)",count);      return 1;      }    count++;    if(!LOG(L_SYS_DISASM) && LOG(L_SYS_DISASM80)) {      bool flag=(pc>=0x80 && pc<0xE0);      if(doDisAsm && !flag) PRINTF(disAsmLogClass,"[...]");      doDisAsm=flag;      }    CCLOGLBPUT("%02x:%04x %02x %02x %02x %02x %04x %c%c%c%c%c%c %02x%02x%02x%02x %02x%02x%02x%02x ",               cr,pc,a,x,y,dr,sp,               cc.v?'V':'.',cc.h?'H':'.',cc.i?'I':'.',cc.n?'N':'.',cc.z?'Z':'.',cc.c?'C':'.',               Get(pc),Get(pc+1),Get(pc+2),Get(pc+3),Get(sp+1),Get(sp+2),Get(sp+3),Get(sp+4));    Stepper();    unsigned char *ex=&x;    unsigned short idx=*ex;    indirect=false;    bool paged=false, vbra=false;    unsigned char ins=Get(pc++);    char xs='X', xi='X';     // check pre-bytes    switch(ins) {      case 0x31: // use SP indexed or indirect paged mode (ST19)        ins=Get(pc++);        switch(ins) {          case 0x22 ... 0x27: vbra=true; PRINTF(L_SYS_EMU,"WARN: V-flag not yet calculated"); break;          case 0x75:          case 0x8D:          case 0xC0 ... 0xCB:          case 0xCE ... 0xCF:          case 0xD0 ... 0xDB:          case 0xDE ... 0xDF: paged=true; indirect=true; break;          case 0xE0 ... 0xEB:          case 0xEE ... 0xEF: idx=sp; xi='S'; break;          }        break;      case 0x32: // use indirect SP indexed or indirect paged Y indexed mode (ST19)        ins=Get(pc++);        switch(ins) {          case 0x22 ... 0x27: vbra=true; PRINTF(L_SYS_EMU,"WARN: V-flag not yet calculated"); indirect=true; break;          case 0xC3:          case 0xCE ... 0xCF:          case 0xD0 ... 0xDB:          case 0xDE ... 0xDF: paged=true; indirect=true; ex=&y; idx=*ex; xs='Y'; xi='Y'; break;          case 0xE0 ... 0xEB:          case 0xEE ... 0xEF: indirect=true; idx=sp; xi='S'; break;          }        break;      case 0x91: // use Y register with indirect addr mode (ST7)        indirect=true;        // fall through      case 0x90: // use Y register (ST7)        ex=&y; idx=*ex; xs='Y'; xi='Y';        ins=Get(pc++);        break;      case 0x92: // use indirect addr mode (ST7)        indirect=true;        ins=Get(pc++);        break;      }    if(doDisAsm) {      char str[8];      if(!vbra) snprintf(str,sizeof(str),ops[ins],xs,xs^1);      else snprintf(str,sizeof(str),"%s",vops[ins-0x22]);      LOGLBPUT("%-5s ",str);      }    // address decoding    unsigned short ea=0;    unsigned char flags=opFlags[ins];    unsigned char pr=(flags&4) ? dr:cr;    switch(((flags&8) ? flags:ins)>>4) {      case 0x2:			// no or special address mode      case 0x8:      case 0x9:        break;      case 0xA:			// immediate        CCLOGLBPUT("#%02x ",Get(pc));        ea=pc++; break;      case 0x3:			// short      case 0xB:        ea=Get(pc++);        if(!indirect) {		// short direct          }        else {			// short indirect          CCLOGLBPUT("[%02x] -> ",ea);          ea=Get(ea);          }        CCLOGLBPUT("%02x ",ea);        break;      case 0xC:			// long        if(!indirect) {		// long direct          ea=HILO(pc); pc+=2;          }        else {			// long indirect          if(paged) {            ea=HILO(pc); pc+=2;            CCLOGLBPUT("[%s] -> ",PADDR(pr,ea));            unsigned char s=Get(pr,ea);            ea=HILOS(pr,ea+1);            pr=s;            }          else {            ea=Get(pc++);            CCLOGLBPUT("[%02x] -> ",ea);            ea=HILO(ea);            }          }        CCLOGLBPUT("%s ",PADDR(pr,ea));        break;      case 0xD:			// long indexed        if(!indirect) {		// long direct indexed          ea=HILO(pc); pc+=2;          CCLOGLBPUT("(%s",PADDR(cr,ea));          }        else {			// long indirect indexed          if(paged) {            ea=HILO(pc); pc+=2;            CCLOGLBPUT("([%s]",PADDR(pr,ea));            unsigned char s=Get(pr,ea++);            ea=HILOS(pr,ea);            pr=s;            }          else {            ea=Get(pc++);            CCLOGLBPUT("([%02x]",ea);            ea=HILO(ea);            }          CCLOGLBPUT(",%c) -> (%s",xi,PADDR(pr,ea));          }        ea+=idx;        CCLOGLBPUT(",%c) -> %s ",xi,PADDR(pr,ea));        break;      case 0x6:			// short indexed      case 0xE:        ea=Get(pc++);        if(!indirect) {		// short direct indexed          CCLOGLBPUT("(%02x",ea);          }        else {			// short indirect indexed          CCLOGLBPUT("([%02x]",ea);          ea=Get(ea);          CCLOGLBPUT(",%c) -> (%02x",xi,ea);          }        ea+=idx;        CCLOGLBPUT(",%c) -> %s ",xi,PADDR(pr,ea));        break;      case 0x7:			// indexed      case 0xF:        ea=idx;        CCLOGLBPUT("(%c) -> %s ",xi,PADDR(pr,ea));        break;      case 0x4:			// inherent A        CCLOGLBPUT("A ");        break;      case 0x5:			// inherent X/Y        CCLOGLBPUT("%c ",xs);

⌨️ 快捷键说明

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