/***********************************************************************/
/*                                                                     */
/*  FILE        :3dLED.c                                               */
/*  DATE        :Sat, Aug 21, 2004                                     */
/*  DESCRIPTION :Main Program                                          */
/*  CPU TYPE    :H8/3694F                                              */
/*                                                                     */
/*  This file is generated by Renesas Project Generator (Ver.3.0).     */
/*                                                                     */
/***********************************************************************/
                  
//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
//
//　HEW 4.0 のコンパイラを使用しました。
//　割り込み等の足りないファイルは適当に推測してください。
//                                                    　なる研
//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

#include <machine.h>
#include "iodefine.h"


#ifdef __cplusplus
extern "C" {
#endif
void abort(void);
#ifdef __cplusplus
}
#endif

//▼▼▼関数のプロトタイプ宣言
void PWM(unsigned char balance);
void outMatrix(void);
void timerAOVF(void);
void SCI3_R(void);
int GetOut(unsigned char,unsigned char);
void shiftBullet(void);
//▼▼▼グローバル変数宣言

volatile static unsigned int vram[8][16]={	//vram[z][y]
{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,},
{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,},
{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,},
{0x0,0x0,0x0,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x0,0x0,0x0,0x0,},
{0x0,0x0,0x0,0x15,0x0,0x15,0x0,0x15,0x0,0x15,0x0,0x15,0x0,0x0,0x0,0x0,},
{0x0,0x0,0x0,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x0,0x0,0x0,0x0,},
{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,},
{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,},
};	//↑←y→
	//z
	//↓

volatile static unsigned int vramB[8][16];	//vramB[z][y]
volatile static signed char ofsXB;		//vramBのオフセット
volatile static signed char ofsYB;		//
volatile static signed char ofsZB;		//
volatile static unsigned int vramC[8][16];	//vramC[z][y]
volatile static unsigned char y = 0;
volatile static unsigned char z = 0;
volatile unsigned char tmp = 0;
volatile unsigned long tacount = 0;
volatile unsigned int taovfcnt = 0;

//▼▼▼ビット操作用
unsigned char bit[8]={
  0x01,0x02,0x04,0x08,
  0x10,0x20,0x40,0x80};
unsigned int bitF[16]={
  0x0001,0x0002,0x0004,0x0008,
  0x0010,0x0020,0x0040,0x0080,
  0x0100,0x0200,0x0400,0x0800,
  0x1000,0x2000,0x4000,0x8000};

//■■■■■■■■■■■■■■
//▼▼▼mainと言うか初期化
void main(void){
  volatile unsigned int i;
  volatile unsigned char j;
  //▼▼▼IO初期化
  IO.PCR1	= 0xff;
  IO.PDR1.BYTE	= 0x00;
  IO.PCR5	= 0xff;
  IO.PDR5.BYTE	= 0x00;
  IO.PCR7	= 0xff;
  IO.PDR7.BYTE	= 0x00;
  IO.PCR8	= 0xff;
  IO.PDR8.BYTE	= 0x00;
  //▼▼▼PWM初期化
  TV.TCRV0.BYTE	= 0x0b;
  TV.TCSRV.BIT.OS	= 0x06;
  TV.TCRV1.BYTE	= 0xE3;
  TV.TCORA	= 0xff;
  TV.TCORB	= 0x00;
  //▼▼▼SCI3受信割り込み初期化
  SCI3.BRR=32;
  SCI3.SMR.BIT.CKS=0;		//19200bps
  SCI3.SCR3.BIT.RIE=1;		//受信割り込み
  SCI3.SCR3.BIT.RE=1;		//受信許可
  
  //▼▼▼タイマW関係初期化
  TW.TCRW.BIT.CCLR= 1;		//
  TW.TCRW.BIT.CKS = 3;		//20M/8
				//20M/8/1583
  TW.GRA = (unsigned int)1100;	//■スキャン周期
  TW.TIERW.BIT.IMIEA = 1;	//コンペアマッチA割り込み
  TW.TMRW.BIT.CTS = 1;	//カウントスタート
  //▼▼▼タイマA関係初期化
  TA.TMA.BIT.CKSI = 0x05;	//20M/128/256=610Hz
  IENR1.BIT.IENTA = 1;		//タイマA割り込み有効
  set_imask_ccr(0);		//割り込み許可
  //▼▼▼ADC関係初期化
  AD.ADCSR.BYTE   = 0x30;
  //▼▼▼VRAM内容初期化
  vramB[3][7]=0x0100;		//自機の像
  while(1){
  }
}


void SCI3_R(void){
  unsigned char i,j;
  switch(SCI3.RDR){
  case 'X': if(ofsXB <=  7) ofsXB+=1;break;
  case 'x': if(ofsXB >= -7) ofsXB-=1;break;
  case 'C': if(ofsYB <=  7) ofsYB+=1;break;
  case 'c': if(ofsYB >= -7) ofsYB-=1;break;
  case 'Z': if(ofsZB <=  7) ofsZB+=1;break;
  case 'z': if(ofsZB >= -7) ofsZB-=1;break;
  case 'w':
    for(j=0;j<8;j++){
    for(i=0;i<16;i++){
      vram[j][i] |= GetOut(j,i);
    }
    }
  break;
  case 's':
    vramC[ofsZB+3][ofsYB+7] |= bitF[ofsXB+7];
  break;
  }
}

void abort(void){}

//▼▼▼モータ制御	0<=balance<=2
void PWM(unsigned char balance){
	TV.TCORB = TV.TCORB + balance - 1;
}

void outMatrix(void){
	//▼▼▼y設定
	unsigned char tmpA;
	unsigned int out;
	tmpA=IO.PDR1.BYTE;	//バックアップ
	IO.PDR7.BIT.B5=1;	//INHIBIT=H 点灯禁止
	IO.PDR7.BIT.B4=1;	//STROBE=H (y変更許可)
	IO.PDR1.BYTE = (((15-y)<<4) | 0x08);
	IO.PDR7.BIT.B4=0;	//STROBE=L (y固定)
	IO.PDR1.BYTE=tmpA;	//復帰
	//▼▼▼x設定
	out=GetOut(z,y) | vramC[z][y];
	IO.PDR5.BYTE = (unsigned char)(out & 0x00ff);
	IO.PDR8.BYTE = (unsigned char)(out>>8);
//	IO.PDR5.BYTE = 0xff;	//■■マトリクス点灯テスト用
//	IO.PDR8.BYTE = 0xff;	//■■マトリクス点灯テスト用
	IO.PDR7.BIT.B5=0;	//INHIBIT=L 点灯許可
}

int GetOut(unsigned char gz,unsigned char gy){
  unsigned int out = vram[gz][gy];
  if( 0<=gz-ofsZB && gz-ofsZB<16 && 0<=gy-ofsYB && gy-ofsYB<16){
    if(ofsXB<0){
      out |= (vramB[gz-ofsZB][gy-ofsYB]>>-ofsXB);
    }else{
      out |= (vramB[gz-ofsZB][gy-ofsYB]<<ofsXB);
    }
  }
  return out;
}

//▼▼▼▼▼タイマーAオーバーフロー
void timerAOVF(void){
}
//▼▼▼▼▼タイマーWコンペアマッチA
void timerWCMA(void){
  unsigned char photoc = 0;
  IO.PDR1.BYTE=0xff;
  if( 0x9999 < AD.ADDRA){	//闘値3V=0x9999
    photoc = 1;
    if(taovfcnt == 0xffff){
      IO.PDR5.BYTE = 0x00;	//表示なし
      IO.PDR8.BYTE = 0x00;	//表示なし
    }else{			//photoが立ち上がったとき
      if(taovfcnt<259) PWM(0);
      if(taovfcnt>259) PWM(2);
      taovfcnt = 0xffff;
      shiftBullet();
    }
  }else{
    if(taovfcnt>270 && taovfcnt!=0xffff){   //スタート時加速
      PWM(3);
      taovfcnt=0xffff;
    }
    if(taovfcnt < 0xff00)   taovfcnt++;
    if(taovfcnt==0xffff){	//photoが立ち下がったとき
      taovfcnt=0;
      y=0;
      z=0;
      outMatrix();
    }else if(1<=taovfcnt && taovfcnt<=128){	//z軸正方向に移動中
      y++;
      if (y==16){
        y=0;
        z++;
        if(z==8)z=0;
      }
      outMatrix();
    }else if(131<=taovfcnt && taovfcnt<=259){	//z軸負方向に移動中
      y--;
      if (y==255){
        y=15;
        z--;
        if(z==255)z=7;
      }
      outMatrix();
    }else{
      IO.PDR5.BYTE = 0x00;//表示なし
      IO.PDR8.BYTE = 0x00;//表示なし
    }
  }
  IO.PDR1.BYTE=0x00;
}


void shiftBullet(){
  unsigned char i,j;
  unsigned int tmp;
  for(j=0;j<8;j++){
  for(i=0;i<16;i++){
    vramC[j][i] = vramC[j][i] >> 1;
    tmp= 0xffff - (vram[j][i] & vramC[j][i]);
    vram[j][i] &= tmp;
    vramC[j][i] &= tmp;
	//  A C | A C  真理値表
	//  0 0 | 0 0  
	//  0 1 | 0 1  C=C & !(A&C)
	//  1 0 | 1 0  A=A & !(A&C)
	//  1 1 | 0 0  

  }
  }
}
