#include <io.h>
#include <system.h>
#include <stdio.h>
#include <alt_types.h>
#include <sys/alt_irq.h>

 #define IOWR_VGA_DATA(base, offset, data) \
  IOWR_16DIRECT(base, (offset) * 2, data)  

 #define IORD_VGA_DATA(base, offset) \
  IORD_16DIRECT(base, (offset) * 2)  
  
unsigned char code;

int main()
{ 
  int count, i;
  int frog_x = 0;
  int frog_y = 0;
  int frog_alive=0;
  int pause = 0;
  int stopflag = 1;
  int frog_action = 0;
  int frog_direction=1;
  const int max=70000;
//  int frog_last_x;
  int frog_last_y = 416;
  int score = 0;
  int frog_life = 5;
  int dummy_life = 5;
  int offset;
  int clear = 1 ;
  
  // audio
  int VolRd = 0, VolWr = 0;
  int volume = 0;
  int initial = 0;
  int a, audioi;

while(1) {
    
   frog_alive = IORD_VGA_DATA(VGA_RASTER_BASE, 24);
 if (IORD_8DIRECT(PS2_BASE, 0) == 1){
//   while (!IORD_8DIRECT(PS2_BASE, 0)) ; /* Poll the status */
   code = IORD_8DIRECT(PS2_BASE, 4);
   printf("%x\n", code);
//   if (code == 0xf0){
//    initial = 0;}
   if (code == 0x1d || code == 0x1b || code == 0x1c || code == 0x23 || code == 0x29 || code == 0x55 || code == 0x4e){
    if (stopflag == 1)
        stopflag = 0;
    else
        stopflag = 1;
   }
   
   //pause function
   if (code == 0x29 && stopflag == 0){
    pause = IORD_VGA_DATA(VGA_RASTER_BASE, 25);
    pause = (pause + 1)%2;
    IOWR_VGA_DATA(VGA_RASTER_BASE, 25, pause);
   } 
   
   // audio volume
   if (code == 0x4e && stopflag == 0){
     VolRd = IORD_16DIRECT(AUDIO_BASE, 2*2);
     IOWR_16DIRECT(AUDIO_BASE, 1*2, 0x0002);
     if (VolRd < 3) VolWr = VolRd + 1;
     IOWR_16DIRECT(AUDIO_BASE, 2*2, VolWr);
   } 
   else if (code == 0x55 && stopflag == 0){
     VolRd = IORD_16DIRECT(AUDIO_BASE, 2*2);
     IOWR_16DIRECT(AUDIO_BASE, 1*2, 0x0002);
     if (VolRd > 0) VolWr = VolRd - 1;
     IOWR_16DIRECT(AUDIO_BASE, 2*2, VolWr);
   }
   
   // audio collision
   if (frog_alive == 1) {
     IOWR_16DIRECT(AUDIO_BASE, 1*2, 0x0001);
     IOWR_16DIRECT(AUDIO_BASE, 3*2, 0x0001);
        audioi = 0; 
        while (1) {
            audioi++;    
            a = IORD_16DIRECT(AUDIO_BASE, audioi*2);
            //printf("a = %x\n", a);
            if (audioi == 4) {
                break;
            } 
        }     
   }
   
   if (frog_alive == 1) {
     IOWR_16DIRECT(AUDIO_BASE, 1*2, 0x0001);
     IOWR_16DIRECT(AUDIO_BASE, 3*2, 0x0000);
        audioi = 0; 
        while (1) {
            audioi++;    
            a = IORD_16DIRECT(AUDIO_BASE, audioi*2);
            //printf("a = %x\n", a);
            if (audioi == 4) {
                break;
            } 
        }     
   }
   
   //send frog x and y to C
   if (frog_alive == 0 && pause == 0 ) {
   frog_x = IORD_VGA_DATA(VGA_RASTER_BASE, 20);
   frog_y = IORD_VGA_DATA(VGA_RASTER_BASE, 21);

   if (code == 0x1d && stopflag == 0)   //up
      { 
        printf("frog_last_y : %d\n", frog_last_y);
        printf("frog_y: %d\n", frog_y);
        printf("frog_life : %d\n", frog_life);
        frog_direction=1;
        IOWR_VGA_DATA(VGA_RASTER_BASE, 22, frog_direction);
        // AUDIO
        IOWR_16DIRECT(AUDIO_BASE, 1*2, 0x0000);
        
    ////////////see whether we should add score or not/////////////              
        if (frog_y == frog_last_y){
           score = score + 10;
           frog_last_y = frog_y - 32;
           IOWR_VGA_DATA(VGA_RASTER_BASE, 26, score);               
        } 
                                             
        frog_y -= 16;

        frog_action = 1;
        IOWR_VGA_DATA(VGA_RASTER_BASE, 23, frog_action);
        IOWR_VGA_DATA(VGA_RASTER_BASE, 21, frog_y);
        IOWR_VGA_DATA(VGA_RASTER_BASE, 20, frog_x);
        // audio
        IOWR_16DIRECT(AUDIO_BASE, 3*2, 0x0001);
        audioi = 0; 
        while (1) {
            audioi++;    
            a = IORD_16DIRECT(AUDIO_BASE, audioi*2);
            //printf("a = %x\n", a);
            if (audioi == 4) {
                break;
            } 
        }
        for (count=0;count<max;count++){
        }
        if (frog_y  > 0) frog_y -= 16;
        
        //check whether arrive at destination
        if (frog_y == 32 ){     
            IOWR_VGA_DATA(VGA_RASTER_BASE, 21, frog_y);      
            IOWR_VGA_DATA(VGA_RASTER_BASE, 28, frog_x);
            printf("HIHIHIHIHIHI\n");
            frog_last_y = 416;
        }
        else{
        frog_action = 0;
        IOWR_VGA_DATA(VGA_RASTER_BASE, 21, frog_y);
        IOWR_VGA_DATA(VGA_RASTER_BASE, 20, frog_x);
        IOWR_VGA_DATA(VGA_RASTER_BASE, 23, frog_action);
        }
        // audio
        IOWR_16DIRECT(AUDIO_BASE, 3*2, 0x0000);
      } 
   else if (code == 0x1b && stopflag == 0)  //down
      {
        frog_direction=3; 
        IOWR_VGA_DATA(VGA_RASTER_BASE, 22, frog_direction); 
        // AUDIO

        IOWR_16DIRECT(AUDIO_BASE, 1*2, 0x0000);   

        if (frog_y < 416) frog_y += 16; 
        frog_action = 1;
        IOWR_VGA_DATA(VGA_RASTER_BASE, 23, frog_action);
        IOWR_VGA_DATA(VGA_RASTER_BASE, 21, frog_y);
        IOWR_VGA_DATA(VGA_RASTER_BASE, 20, frog_x);
        // audio
        IOWR_16DIRECT(AUDIO_BASE, 3*2, 0x0001);
        audioi = 0; 
        while (1) {
            audioi++;    
            a = IORD_16DIRECT(AUDIO_BASE, audioi*2);
            //printf("a = %x\n", a);
            if (audioi == 4) {
                break;
            } 
        }
        for (count=0;count<max;count++){
        }
        if (frog_y < 416) frog_y += 16;
        frog_action = 0;
        IOWR_VGA_DATA(VGA_RASTER_BASE, 21, frog_y);
        IOWR_VGA_DATA(VGA_RASTER_BASE, 20, frog_x);
        IOWR_VGA_DATA(VGA_RASTER_BASE, 23, frog_action);
        // audio
        IOWR_16DIRECT(AUDIO_BASE, 3*2, 0x0000);
      }
      
      
      
   else if (code == 0x1c && stopflag == 0)  //left
      { 
       frog_direction=2;
       IOWR_VGA_DATA(VGA_RASTER_BASE, 22, frog_direction); 
       // AUDIO
       IOWR_16DIRECT(AUDIO_BASE, 1*2, 0x0000);         
       if (frog_x >= 16) frog_x -= 16;
       else if (frog_x >= 0) frog_x = 0;
       frog_action = 1;
       IOWR_VGA_DATA(VGA_RASTER_BASE, 23, frog_action);
       IOWR_VGA_DATA(VGA_RASTER_BASE, 21, frog_y);
       IOWR_VGA_DATA(VGA_RASTER_BASE, 20, frog_x);
       // audio
       IOWR_16DIRECT(AUDIO_BASE, 3*2, 0x0001);
       audioi = 0; 
        while (1) {
            audioi++;    
            a = IORD_16DIRECT(AUDIO_BASE, audioi*2);
            printf("a = %x\n", a);
            if (audioi == 4) {
                break;
            } 
        }
       for (count=0;count<max;count++){
       }
       if (frog_x >= 16) frog_x -= 16;
       else if (frog_x >= 0) frog_x = 0;
       frog_action = 0;
       IOWR_VGA_DATA(VGA_RASTER_BASE, 21, frog_y);
       IOWR_VGA_DATA(VGA_RASTER_BASE, 20, frog_x);
       IOWR_VGA_DATA(VGA_RASTER_BASE, 23, frog_action);
       // audio
       IOWR_16DIRECT(AUDIO_BASE, 3*2, 0x0000);
      }
      
      
   else if (code == 0x23 && stopflag == 0)  //right
      { 
        frog_direction=4;
        IOWR_VGA_DATA(VGA_RASTER_BASE, 22, frog_direction);
        // AUDIO
        IOWR_16DIRECT(AUDIO_BASE, 1*2, 0x0000);
        if (frog_x <= 464) frog_x += 16;
        else if (frog_x <= 480) frog_x = 480;
        frog_action = 1;
        IOWR_VGA_DATA(VGA_RASTER_BASE, 23, frog_action);
        IOWR_VGA_DATA(VGA_RASTER_BASE, 21, frog_y);
        IOWR_VGA_DATA(VGA_RASTER_BASE, 20, frog_x);
        // audio
        IOWR_16DIRECT(AUDIO_BASE, 3*2, 0x0001);
        audioi = 0; 
        while (1) {
            audioi++;    
            a = IORD_16DIRECT(AUDIO_BASE, audioi*2);
            //printf("a = %x\n", a);
            if (audioi == 4) {
                break;
            } 
        }
        for (count=0;count<max;count++){
        }
        if (frog_x <= 464) frog_x += 16;
        else if (frog_x <= 480) frog_x = 480;
        frog_action = 0;
        
        IOWR_VGA_DATA(VGA_RASTER_BASE, 21, frog_y);
        IOWR_VGA_DATA(VGA_RASTER_BASE, 20, frog_x);
        IOWR_VGA_DATA(VGA_RASTER_BASE, 23, frog_action);
        // audio
        IOWR_16DIRECT(AUDIO_BASE, 3*2, 0x0000);

      }
   }
   audioi = 0; 
        while (1) {
            audioi++;    
            a = IORD_16DIRECT(AUDIO_BASE, audioi*2);
            //printf("a = %x\n", a);
            if (audioi == 4) {
                break;
            } 
        }
 }
   else 
   {
    IOWR_VGA_DATA(VGA_RASTER_BASE, 26, score); //keep writing score
    dummy_life = frog_life;
    frog_life = IORD_VGA_DATA(VGA_RASTER_BASE, 27); //keep reading frog life
  //  printf("original frog_life : %d  ", frog_life);
    if (dummy_life > frog_life){
        frog_last_y = 416;
    }
    if (frog_life == 0 && frog_alive  == 1){
        frog_life = 5;
        score = 0;
        IOWR_VGA_DATA(VGA_RASTER_BASE, 29, clear);
    }
   }
}
  printf("Goodbye!\n");
    
  return 0;
}
//20  write read forg_x
//21  write read frog_y
//22  write frog_direction
//23  write frog_action
//24  read frog_alive 
//25  write read pause
//26  write score
//27  read frog_life
//28  write frog_x
//29  write clear


