#define MEM0_ADDR  (0x07000000)
#define MEM1_ADDR  (0x08000000)
#define BMP0_ADDR  (0x09000000) //ビットマップディスプレイのアドレス
#define DMA0_ADDR  (0x0a000000)
#define DMA1_ADDR  (0x0b000000)
#define DMA2_ADDR  (0x0d000000)
#define PROC1_ADDR (0x0c000000) //RLUのアドレス
#define DISPLAY_WIDTH 256 //300

#define NOP_1 asm("#param\n" "nop\n")
#define NOP_5 asm("#param\n" "nop\nnop\nnop\nnop\nnop\n")
#define NOP_10 asm("#param\n" "nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n")


struct DMAControlRegister{
  unsigned int source;
  unsigned int destination;
  unsigned int length;
  unsigned int command;
};


int main()
{
  unsigned short *addr_mem0;
  unsigned int *addr_proc1,*addr_context;
  struct DMAControlRegister *controlRegister0 = (struct DMAControlRegister*)DMA0_ADDR;
  struct DMAControlRegister *controlRegister1 = (struct DMAControlRegister*)DMA1_ADDR;;
  struct DMAControlRegister *controlRegister2 = (struct DMAControlRegister*)DMA2_ADDR;;
  volatile int i;

  //MEM1の画像データをBMP0へ転送
  controlRegister2->source = (unsigned int)54;
  controlRegister2->destination = (unsigned int)0;
  controlRegister2->length = (unsigned int)196608;
  controlRegister2->command = (unsigned int)1;//srcはインクリメントする,destはインクリメントする


  //一つ目のコンテキストを使うRLUへの固定の入力
  addr_mem0 = (unsigned short*)MEM0_ADDR;
  *addr_mem0 = (unsigned short)77;//Rの重み
  addr_mem0 += 2;
  *addr_mem0 = (unsigned short)29;//Bの重み
  addr_mem0 += 3;
  *addr_mem0 = (unsigned short)65535;//FFFF
  addr_mem0 += 1;
  *addr_mem0 = (unsigned short)255;//00FF
  addr_mem0 += 1;
  *addr_mem0 = (unsigned short)65280;//FF00

  //最初の画像を全部表示させたいので，転送が終わるまで待つ
  for(i = 0;i < 3200;i++);

  //BMP0の画像データをRLUへ転送するためにDMA0にいろいろ設定
  controlRegister0->source = (unsigned int)0;
  controlRegister0->destination = (unsigned int)7;
  controlRegister0->length = (unsigned int)196608;


  //RLUで処理されたデータをBMP0へ転送するためにDMA1にいろいろ設定
  controlRegister1->source = (unsigned int)47;
  controlRegister1->destination = (unsigned int)0;
  controlRegister1->length = (unsigned int)196608;


  //DMA0の転送開始
  controlRegister0->command = (unsigned int)5;//srcはインクリメントする,destはインクリメントしない

  NOP_10;
  NOP_1;
  NOP_1;
  NOP_1;
  NOP_1;

  //DMA1の転送開始
  controlRegister1->command = (unsigned int)9;//srcはインクリメントしない,destはインクリメントする

  //RLUを使い終わるのを待つ
  for(i = 0;i < 3300;i++);

  addr_proc1 = (unsigned int*)PROC1_ADDR;//RLUのコンテキスト情報を書き込む場所
  addr_context = (unsigned int*)(MEM1_ADDR + 200000);//メモリ上のコンテキストの場所のアドレス
  //コンテキスト書き換え
  for(i = 0;i < 64;i++)
    {
      *addr_proc1 = *addr_context;
      addr_proc1++;
      addr_context++;
    }

  //二つ目のコンテキストを使うRLUへの固定の入力
  addr_mem0 = (unsigned short*)MEM0_ADDR;
  *addr_mem0 = (unsigned short)150;//Gの重み


  //BMP0の画像データをRLUへ転送するためにDMA0にいろいろ設定
  controlRegister0->source = (unsigned int)0;
  controlRegister0->destination = (unsigned int)3;
  controlRegister0->length = (unsigned int)196608;

  //RLUで処理されたデータをBMP0へ転送するためにDMA1にいろいろ設定
  controlRegister1->source = (unsigned int)34;
  controlRegister1->destination = (unsigned int)0;
  controlRegister1->length = (unsigned int)196608;

  //DMA0の転送開始
  controlRegister0->command = (unsigned int)5;//srcはインクリメントする,destはインクリメントしない

  NOP_10;
  NOP_10;
  NOP_5;
  NOP_1;
  NOP_1;

  //DMA1の転送開始
  controlRegister1->command = (unsigned int)9;//srcはインクリメントしない,destはインクリメントする
}
