/*********************************************/

/*           MIRX68K for PEP VSBC-1          */

/*********************************************/

#include "iodef.h"

#include "task.h"



int  inzdsp(),eichi;

void timdsp(),nrmdsp(),intdsp();

interrupt void reig1(),reig2(),reig3(),reig4(),reig5(),reig6(),reig7(),reig8();

interrupt void reig9(),reig10(),reig11(),reig12(),reig13(),reig14(),reig15();

interrupt void reig16(),l1(),l2(),l3(),l4(),l5(),RTCint(),l7(),unsi();

void fin(),e_fin(int e2,int e1);

void sys0(),sys2(),sys3(),sys4(),sys5(),sys8();

int  sys1(),sys9(),sys10(),sys11();



void (*pinz)(),(*pnrm)(),(*ptim)(),(*pint)(),(*(*vp))();



unsigned que[7][MAXTSK],lastq[7];

int      ncom[7][MAXTSK], tcom[MAXTSK], icom[MAXTSK];

int      nscom[7][MAXTSK],tscom[MAXTSK],iscom[MAXTSK];

int      code[2];



unsigned long Sysclk=0;

int vmemask=0;

extern int inportb();
extern int outportb();
extern int outportl();

int absl(a)              /*aを絶対値表示*/

{

   int ans;

   if(a<0) ans = 0 - a;

   else ans = a;

   return(ans);

}



/***********************/

/*MIRX68K main program*/

/***********************/



void main()

{

   int usetsk,i,rtc_base;

   eichi = 30;



   /* Real Time Clock initialize*/



   outportb(MSR,0x40); 

   outportb(PFIC,0x10);

   outportb(TSIC,0x00);

   outportb(MSR,0x00);   



	/* written by N.Hayashi */ /*リアルタイムクロックの初期化*/

	outportb(MSR,0x0c);

        inportb(0xfdfe07); 

	outportb(MSR,0x4c);

	outportb(RTMR,0x08);

	outportb(PFIC,0x10);

	outportb(MSR,0x0c);  

	/********************************************************* */

   usetsk=inzdsp();

   eichi = 70;

   asm("   MOVE.W  #$2000,SR   ");   /* Interrupt enable */ 

   while( usetsk != 0)

   {

      timdsp();

      nrmdsp();

   }

}



int inzdsp()

{

   int ut,tn,py;

   ut=0;



   for (tn=0;tn 0x80) ut++;/*フラグの7と6、3、2ビット目のいずれかが*/

   }                                        /*1なら帰り値が1*/

   return(ut);

}



void timdsp() /*タスクタイマ処理(タイマー割込み処理)timt00〜timt05を実効*/

{

   int tn;



   for (tn=0;tn= table[tn].timset))

      {

	 ptim=table[tn].timtsk;

	 table[tn].flg |= 0x20;         /*   set busyflag */

	 (*ptim)(tcom[tn],tscom[tn]);

	 table[tn].flg &= 0xdf;         /* reset busyflag */

	 table[tn].timer=0;

      }

}



void nrmdsp()/*ノーマルタスク処理 nrmt00〜nrmt05を実効*/

{

   int nb,tn,py,savesrn;



   nb=tn=py=0;

   for (py=0;py<7;py++) 

      if (lastq[py] != 0)

      {

	 tn=que[py][0];

	 if ((table[tn].flg & 0xe0) == 0xc0)

	 {

	    pnrm=table[tn].nrmtsk;

	    table[tn].flg |= 0x20;      /*   set busyflag  */

	    (*pnrm)(ncom[py][0],nscom[py][0]);

	    table[tn].flg &= 0xdf;      /* reset busyflag  */

	 }

	 asm("   MOVE.W  SR,`savesrn` ");  /*Save SR*/

	 asm("   MOVE.W  #$2700,SR   ");  /*Interrupt disable*/ 

	 lastq[py]--;

	 for (nb=0;nb= 0x80)

		e_fin(2,7);

	else

		e_fin(2,8);

}



void sys0(tskn,flag)                /* system call 0:task initialize 初期化 */

int tskn,flag;                      /* 制御フラグの初期化 */

{

   int fg7,fg6,fg3,fg2;



   fg7=fg6=fg3=fg2=1;

   if ((flag&0x1000) == 0) fg7=0;      /*タスクの有無*/

   if ((flag&0x100) == 0) fg6=0;       /*ノーマルタスクの有無*/

   if ((flag&0x10) == 0) fg2=0;        /*タイマタスクの有無*/

   if ((flag&0x1) == 0) fg3=0;         /*割込みタスクの有無*/

   fg7<<=7; fg6<<=6; fg3<<=3; fg2<<=2; /*fgn<<=m  fgnの値をm回左へビットシフト*/

   table[tskn].flg=fg7+fg6+fg3+fg2;

   /*4ビットの[flag]を1バイトの制御フラグに変換する*/

}



int sys1(tn,py,cm,scm)              /* system call 1:set normal task    */

int tn,py,cm,scm;

{

   int n,i,savesr;



   asm("   MOVE.W  SR,`savesr` ");  /*Save SR*/

   asm("   MOVE.W  #$2700,SR   ");  /*Interrupt disable*/ 

   n=lastq[py]++;

   if (n>=MAXTSK) fin();

   que[py][n] =tn;

   ncom[py][n] =cm;

   nscom[py][n]=scm;

   if(eichi != 30)

   {

   asm("   MOVE.W  `savesr`,SR   ");  /*Restore SR*/

   }

   return(0);

}



void sys2(tn,st,cm,scm)             /* system call 2:set timer task   */

int tn,st,cm,scm;                   /*タイマータスクの設定*/

{

   table[tn].timset = st;

   tcom[tn]=cm;

   tscom[tn]=scm;

   sys3(tn,0);

}



void sys3(tskn,reset)               /* system call 3:count start       */

int tskn,reset;                     /*タイマータスクのカウントスタート*/

{

   table[tskn].flg |= 0x01;

   if (reset!=0) table[tskn].timer=0;

}



void sys4(tskn)                     /* system call 4:count stop       */

int tskn;                           /*タイマータスクのカウントストップ*/

{

   table[tskn].flg &= 0xfe;

}



void sys5(tskn,aflg,lv,cm,scm)          /* system call 5:set interrupt task   */

int tskn,aflg,lv,cm,scm;                /*vpにintt00〜intt05迄をセット*/

{

   if(aflg == 1) {

	       table[tskn].flg &= 0xef;

	       icom[tskn]=cm;

	       iscom[tskn]=scm;

	       vp=(void *)(0x60+4*lv);

	       *vp=table[tskn].inttsk; 

   }

   if(aflg == 0) {

       table[tskn].flg &= 0xef;

       icom[tskn]=cm;

       iscom[tskn]=scm;

	vp = (void *)(lv * 4); 

	*vp=table[tskn].inttsk;                 

   }

}





void sys8(tskn,bbn,dat)             /* system call 8:BB write           */

int tskn,bbn,dat;

{

   switch (bbn)

   {

      case 1:table[tskn].BB1 = dat;break;

      case 2:table[tskn].BB2 = dat;break;

      case 3:table[tskn].BB3 = dat;break;

      case 4:table[tskn].BB4 = dat;break;

      case 5:table[tskn].BB5 = dat;break;

      case 6:table[tskn].BB6 = dat;break;

   }

}



int  sys9(tskn,bbn)                 /* system call 9:BB read           */

int tskn,bbn;

{

   switch (bbn)

   {

      case 1:return(table[tskn].BB1);

      case 2:return(table[tskn].BB2);

      case 3:return(table[tskn].BB3);

      case 4:return(table[tskn].BB4);

      case 5:return(table[tskn].BB5);

      case 6:return(table[tskn].BB6);

   }

   return(0);

}



int sys10(irqn)    /* VME IRQx mask */

int irqn;

{

  int i;

  i=(1<