From: anon Date: Fri, 13 Jun 2008 00:31:47 +0000 (+0800) Subject: nagra: improved map register framework X-Git-Tag: 0.9.1~69 X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=752dcca6359528c875780a3cfa9e1b4150dcb435;p=sasc-ng.git nagra: improved map register framework --- diff --git a/systems/nagra/nagra2-0101.c b/systems/nagra/nagra2-0101.c index bffd3be..b94f2df 100644 --- a/systems/nagra/nagra2-0101.c +++ b/systems/nagra/nagra2-0101.c @@ -171,18 +171,14 @@ void cMap0101::DoMap(int f, unsigned char *data, int l) PRINTF(L_SYS_MAP,"0101: calling function %02X",f); l=GetOpSize(l); cycles=0; interrupted=false; -#ifdef MR_DEBUG -fprintf(stderr,"map %x l=%d\n",f,l); -#endif switch(f) { case 0x21: MAP_IRQ_BEGIN(); AddMapCycles(288); - D.Save(); C.Save(); WS_START(1); MakeJ0(J,D); AddMapCycles(282); - WClear(C); + BN_clear(C); WS_END(); AddMapCycles(898-282-288); MAP_IRQ_END(); @@ -348,11 +344,10 @@ fprintf(stderr,"map %x l=%d\n",f,l); memcpy(&data[l],&tmp[l-4],4); } Py.PutLE(&data[0x20],l); - D.Restore(); - WS_END(); BN_zero(A); BN_zero(B); BN_zero(C); + WS_END(); break; } default: @@ -360,7 +355,6 @@ fprintf(stderr,"map %x l=%d\n",f,l); PRINTF(L_SYS_MAP,"0101: unsupported call %02x",f); break; } - Finalise(); } // -- cN2Prov0101 -------------------------------------------------------------- diff --git a/systems/nagra/nagra2.c b/systems/nagra/nagra2.c index 7030978..5cb5f40 100644 --- a/systems/nagra/nagra2.c +++ b/systems/nagra/nagra2.c @@ -260,74 +260,114 @@ bool cN2Emu::Init(int id, int romv) // -- cMapReg ------------------------------------------------------------------ -cMapReg::cMapReg(const int *Ws, const char *Name) +cMapReg::cMapReg(int *_defwordsize, int _maxwordsize) { - ws=Ws; name=Name; + SetDefWordSize(_defwordsize); + SetMaxWordSize(_maxwordsize); + wordsize=DEF_WORDSIZE; } -void cMapReg::Save(int size) +BIGNUM *cMapReg::Value(int wsize, bool mask) { - if(!touched && ws) { - if(size<=0) size=*ws; - BN_copy(save,reg); - BN_mask_bits(reg,size<<6); - touched=true; -#ifdef MR_DEBUG -fprintf(stderr,"saved %s size=%d\n",name,size); -fprintf(stderr,"reg : "); BN_print_fp(stderr,reg); fprintf(stderr,"\n"); -fprintf(stderr,"save: "); BN_print_fp(stderr,save); fprintf(stderr,"\n"); -#endif + wsize=OpWordSize(wsize); + if(wordsize!=wsize) { + Commit(); + Reload(); } + else if(mask) + BN_mask_bits(reg,wsize*64); + return reg; } -void cMapReg::Restore(int size) +void cMapReg::ClearReg(int wsize) { - if(touched && ws) { - if(size<=0) size=*ws; -#ifdef MR_DEBUG -fprintf(stderr,"restore %s size=%d\n",name,size); -fprintf(stderr,"reg : "); BN_print_fp(stderr,reg); fprintf(stderr,"\n"); -fprintf(stderr,"save: "); BN_print_fp(stderr,save); fprintf(stderr,"\n"); -#endif - if(reg->neg) { - BN_zero(tmp); - BN_set_bit(tmp,size<<6); - BN_add(reg,tmp,reg); - } - BN_rshift(tmp,save,size<<6); - BN_lshift(tmp,tmp,size<<6); - BN_mask_bits(reg,size<<6); - BN_add(reg,reg,tmp); - touched=false; -#ifdef MR_DEBUG -fprintf(stderr,"reg : "); BN_print_fp(stderr,reg); fprintf(stderr,"\n"); -#endif + BN_rshift(reg,reg,wsize*64); + BN_lshift(reg,reg,wsize*64); +} + +void cMapReg::ClearFullReg(int wsize) +{ + BN_rshift(fullreg,fullreg,wsize*64); + BN_lshift(fullreg,fullreg,wsize*64); +} + +void cMapReg::PrepTmp(BIGNUM *val, int wsize) +{ + if(val->neg) { + BN_clear(tmp); + BN_set_bit(tmp,wsize*64); + BN_add(tmp,tmp,val); } + else + BN_copy(tmp,val); + BN_mask_bits(tmp,wsize*64); } -// -- cMapMath ----------------------------------------------------------------- +void cMapReg::Commit(int wsize, int resync) +{ + if(resync<0 && wsize<0) resync=1; + wsize=OpWordSize(wsize>=0?wsize:wordsize); + ClearFullReg(wsize); + PrepTmp(reg,wsize); + BN_add(fullreg,fullreg,tmp); + if(resync) { + if(wordsize==wsize) BN_mask_bits(reg,wsize*64); + else wordsize=wsize; + } +} -const int cMapMath::ws1=1; +void cMapReg::Reload(int wsize) +{ + wsize=OpWordSize(wsize>=0?wsize:wordsize); + wordsize=wsize; + BN_copy(reg,fullreg); + BN_mask_bits(reg,64*wsize); +} -cMapMath::cMapMath(void) -:A(&wordsize,"A"),B(&wordsize,"B"),C(&wordsize,"C"),D(&wordsize,"D"),J(&ws1,"J"),I(0,"I") +void cMapReg::GetLE(const unsigned char *in, int n) { - wordsize=DEF_WORDSIZE; + int wsize=OpWordSize(n<=0?n:(n+7)/8); + if(wordsize>wsize) Commit(); + reg.GetLE(in,wsize*8); + Commit(wsize); } -void cMapMath::Finalise(void) +void cMapReg::PutLE(unsigned char *out, int n) { -#ifdef MR_DEBUG -fprintf(stderr,"finalise\n"); -#endif - A.Restore(); B.Restore(); C.Restore(); D.Restore(); + int wsize=OpWordSize(n<=0?n:(n+7)/8); + Commit(); + fullreg.PutLE(out,wsize*8); } -void cMapMath::WClear(BIGNUM *r, int w) +void cMapReg::Set(BIGNUM *val, int wsize) { - if(!w) w=wordsize; - BN_rshift(r,r,w<<6); - BN_lshift(r,r,w<<6); + wsize=OpWordSize(wsize); + if(wordsize!=wsize) Commit(); + ClearReg(wsize); + PrepTmp(val,wsize); + if(wordsize!=wsize) { + ClearFullReg(wsize); + BN_add(fullreg,fullreg,tmp); + } + BN_add(reg,reg,tmp); +} + +void cMapReg::Clear(int wsize) +{ + wsize=OpWordSize(wsize); + if(wordsize!=wsize) { + Commit(); + ClearFullReg(wsize); + } + ClearReg(wsize); +} + +// -- cMapMath ----------------------------------------------------------------- + +cMapMath::cMapMath(void) +:A(&wordsize),B(&wordsize),C(&wordsize),D(&wordsize),J(0,1),I(&wordsize) +{ + wordsize=DEF_WORDSIZE; } bool cMapMath::ModAdd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *d) @@ -621,7 +661,6 @@ bool cMapCore::DoMap(int f, unsigned char *data, int l) cycles=890-6; last=0; regs[0]->GetLE(data,8); - regs[0]->Restore(1); break; case IMPORT_A: case IMPORT_B: @@ -632,14 +671,12 @@ bool cMapCore::DoMap(int f, unsigned char *data, int l) cycles+=771+160*l-6; last=f-IMPORT_J; regs[last]->GetLE(data,l<<3); - regs[last]->Restore(l); break; case IMPORT_LAST: if(l>16) { l=1; cycles+=5; } else if(l<=0) l=1; cycles=656+160*l-6; regs[last]->GetLE(data,(last==0?1:l)<<3); - regs[last]->Restore((last==0?1:l)); break; case EXPORT_J: @@ -672,7 +709,7 @@ bool cMapCore::DoMap(int f, unsigned char *data, int l) last=f-SWAP_A+1; e.GetLE(data,dl); regs[last]->PutLE(data,dl); - BN_copy(*regs[last],e); + regs[last]->Set(e,l1); break; case CLEAR_A: @@ -680,21 +717,22 @@ bool cMapCore::DoMap(int f, unsigned char *data, int l) case CLEAR_C: case CLEAR_D: cycles=462+(8*l1+3)/5*5-6; - last=f-CLEAR_A+1; BN_zero(*regs[last]); + last=f-CLEAR_A+1; + regs[last]->Clear(l1); break; case COPY_A_B: - last=2; BN_copy(B,A); cycles=462+(8*l1+3)/5*5-6; break; + last=2; B.Set(A,l1); cycles=462+(8*l1+3)/5*5-6; break; case COPY_B_A: - last=1; BN_copy(A,B); cycles=462+(8*l1+3)/5*5-6; break; + last=1; A.Set(B,l1); cycles=462+(8*l1+3)/5*5-6; break; case COPY_A_C: - last=3; BN_copy(C,A); cycles=462+(8*l1+3)/5*5-6; break; + last=3; C.Set(A,l1); cycles=462+(8*l1+3)/5*5-6; break; case COPY_C_A: - last=1; BN_copy(A,C); cycles=462+(8*l1+3)/5*5-6; break; + last=1; A.Set(C,l1); cycles=462+(8*l1+3)/5*5-6; break; case COPY_C_D: - last=4; BN_copy(D,C); cycles=462+(8*l1+3)/5*5-6; break; + last=4; D.Set(C,l1); cycles=462+(8*l1+3)/5*5-6; break; case COPY_D_C: - last=3; BN_copy(C,D); cycles=462+(8*l1+3)/5*5-6; break; + last=3; C.Set(D,l1); cycles=462+(8*l1+3)/5*5-6; break; case 0x39: case 0x3a: @@ -726,7 +764,6 @@ bool cMapCore::DoMap(int f, unsigned char *data, int l) default: return false; } - Finalise(); return true; } diff --git a/systems/nagra/nagra2.h b/systems/nagra/nagra2.h index e846cbe..84fc002 100644 --- a/systems/nagra/nagra2.h +++ b/systems/nagra/nagra2.h @@ -50,30 +50,38 @@ extern char auxPassword[250]; // ---------------------------------------------------------------- -//#define MR_DEBUG +#define DEF_WORDSIZE 4 +#define DEF_MAXWORDSIZE 17 class cMapReg { private: - cBN reg, save, tmp; - const int *ws; - const char *name; - bool touched; + cBN fullreg, reg, tmp; + int wordsize, maxwordsize, *defwordsize; + // + int DefWordSize() const { return defwordsize ? *defwordsize:DEF_WORDSIZE; } + int OpWordSize(int wsize) const { int sz=wsize>0 ? wsize:DefWordSize(); return sz>maxwordsize ? maxwordsize:sz; } +// int OpWordSize() const { return wordsize; } + void ClearReg(int wsize); + void ClearFullReg(int wsize); + void PrepTmp(BIGNUM *val, int wsize); +protected: + void SetMaxWordSize(int max) { maxwordsize=max; } + void SetDefWordSize(int *_defwordsize) { defwordsize=_defwordsize; } public: - cMapReg(const int *Ws, const char *Name); - operator BIGNUM* () { Save(); return reg.BN(); } - BIGNUM *operator->() { Save(); return reg.BN(); } - bool Get(const unsigned char *in, int n) { Save(); return reg.Get(in,n); } - bool GetLE(const unsigned char *in, int n) { Save(); return reg.GetLE(in,n); } - int Put(unsigned char *out, int n) const { return reg.Put(out,n); } - int PutLE(unsigned char *out, int n) const { return reg.PutLE(out,n); } - void Save(int size=0); - void Restore(int size=0); + cMapReg(int *_defwordsize=0, int _maxwordsize=DEF_MAXWORDSIZE); + operator BIGNUM* () { return Value(); } + BIGNUM *operator->() { return Value(); } + BIGNUM *Value(int wsize=0, bool mask=false); + void Commit(int wsize=-1, int resync=-1); + void Reload(int wsize=0); + void GetLE(const unsigned char *in, int n=0); + void PutLE(unsigned char *out, int n=0); + void Set(BIGNUM *val, int wsize); + void Clear(int wsize); }; // ---------------------------------------------------------------- -#define DEF_WORDSIZE 4 - #define WS_START(x) { int __oldws=wordsize; wordsize=(x); #define WS_END() wordsize=__oldws; } @@ -81,7 +89,6 @@ class cMapMath { private: cBN x, y, s; int words; - static const int ws1; protected: int wordsize; cMapReg A, B, C, D, J, I; @@ -94,11 +101,9 @@ protected: void MonMul(BIGNUM *o, BIGNUM *a, BIGNUM *b, BIGNUM *c, BIGNUM *d, BIGNUM *j, int w); void MonStart(int w); void MonLoop(BIGNUM *o, BIGNUM *a, BIGNUM *b, BIGNUM *c, BIGNUM *d, BIGNUM *j); - void WClear(BIGNUM *r, int w=0); // statefull void MonMul(BIGNUM *o, BIGNUM *a, BIGNUM *b); void MonMul(BIGNUM *o, BIGNUM *a, BIGNUM *b, int w); - void Finalise(void); public: cMapMath(void); };