]> www.vanbest.org Git - sasc-ng.git/commitdiff
nagra: add cpu exception handling
authoranon <unknown>
Mon, 26 May 2008 13:19:00 +0000 (21:19 +0800)
committeranon <unknown>
Mon, 26 May 2008 13:19:00 +0000 (21:19 +0800)
systems/nagra/cpu.c
systems/nagra/cpu.h

index 7c7554e83cb5496270cf964eabf3274452a07840..da46c6d381d46f8d417ad12c6dc984e8f76135a0 100644 (file)
@@ -144,6 +144,8 @@ 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;
   hasReadHandler=hasWriteHandler=false;
+  exptPending=false; timerDisable=0; exptBase=0x4000;
+  for(int i=0; i<EXPT_MAX; i++) expt[i]=false;
   ClearBreakpoints();
   InitMapper();
   ResetCycles();
@@ -297,7 +299,12 @@ void c6805::AddCycles(unsigned int num)
 {
   if(num>0) {
     clockcycles+=num;
-    TimerHandler(num);
+    if(timerDisable>0) {
+      timerDisable-=num;
+      if(timerDisable<0) timerDisable=0;
+      }
+    if(!timerDisable)
+      TimerHandler(num);
     }
 }
 
@@ -306,6 +313,24 @@ void c6805::ResetCycles(void)
   clockcycles=0;
 }
 
+void c6805::RaiseException(int num)
+{
+  if(num<EXPT_MAX) {
+    exptPending=true;
+    expt[num]=true;
+    }
+}
+
+void c6805::DisableTimers(int num)
+{
+  timerDisable=num;
+}
+
+void c6805::SetExptBase(unsigned short base)
+{
+  exptBase=base;
+}
+
 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",
@@ -1033,6 +1058,18 @@ int c6805::Run(int max_count)
       return 2;
       }
     }
+
+    if(exptPending && !cc.i) {
+      exptPending=false;
+      for(int i=0; i<EXPT_MAX; ++i)
+       if(expt[i]) {
+          exptPending=true; // to force check for another interrupt in next Run pass
+          expt[i]=false;
+          pushpc(); push(x); push(a); pushc(); cc.i=1;
+          pc=exptBase+4*i;
+          break;
+          }
+      }
 }
 
 void c6805::branch(bool branch)
index f3185a52c3a4d6ee9f968bad0be4691713f8133a..b2f462e6b6e556a61c4ec555f101aafba07792cb 100644 (file)
@@ -92,6 +92,7 @@ public:
 #define MAX_MAPPER      10
 #define MAX_PAGES       5
 #define PAGE_SIZE       32*1024
+#define EXPT_MAX        16
 
 #define bitset(d,bit) (((d)>>(bit))&1)
 
@@ -100,7 +101,7 @@ public:
 
 class c6805 {
 private:
-  unsigned short pc, sp, spHi, spLow;
+  unsigned short pc, sp, spHi, spLow, exptBase;
   unsigned short bp[MAX_BREAKPOINTS], numBp;
   unsigned char mapMap[(MAX_PAGES+1)*PAGE_SIZE];
   cMap *mapper[MAX_MAPPER];
@@ -108,6 +109,8 @@ private:
   int pageMap[256];
   bool indirect;
   unsigned int clockcycles;
+  bool exptPending, expt[EXPT_MAX];
+  int timerDisable;
   //
   void InitMapper(void);
   void ClearMapper(void);
@@ -149,6 +152,9 @@ protected:
   void ResetCycles(void);
   void AddCycles(unsigned int num);
   unsigned int Cycles(void) { return clockcycles; }
+  void RaiseException(int num);
+  void SetExptBase(unsigned short base);
+  void DisableTimers(int num);
   virtual void Stepper(void)=0;
   virtual void WriteHandler(unsigned char seg, unsigned short ea, unsigned char &op) {}
   virtual void ReadHandler(unsigned char seg, unsigned short ea, unsigned char &op) {}