]> www.vanbest.org Git - sasc-ng.git/commitdiff
nagra: improved map register framework
authoranon <unknown>
Fri, 13 Jun 2008 00:31:47 +0000 (08:31 +0800)
committeranon <unknown>
Fri, 13 Jun 2008 00:31:47 +0000 (08:31 +0800)
systems/nagra/nagra2-0101.c
systems/nagra/nagra2.c
systems/nagra/nagra2.h

index bffd3be4adcddbecd6952f9d2a779180df731ea1..b94f2df2371336101b34082d388eecad3bddc1c5 100644 (file)
@@ -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 --------------------------------------------------------------
index 70309785143ef3ed808a6388c2b3ecc8d40a0dbf..5cb5f40f4fa5a234e7931bdc02cbf7d5e9580a5b 100644 (file)
@@ -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;
 }
 
index e846cbe3a7c38f5f21fbdf4cb772e99b9eb23c43..84fc00270dc3ae00e8925c73e8ed6cdd9dbcfe57 100644 (file)
@@ -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);
   };