Beispiel #1
0
void move_point(struct net* pnet, int x, int y) {
    double ax = 0;
    double ay = 0;
    struct vector_t vt;
    int i;
    int l = pnet->layer;
    int dxy[8][2] = {
        { 1, 0},
        { 0, 1},
        {-1, 0},
        { 0,-1},
    };
    struct point_t *op = &(pnet->pt[l][y][x]);

    pnet->pt[l^1][y][x] = *op;
    for (i=0; i<2; ++i) {
        struct point_t *p = &pnet->pt[l][y+dxy[i][1]][x+dxy[i][0]];
        vt = get_power( op, p->x - dxy[i][0]*pnet->dtw, p->y - dxy[i][1]*pnet->dth);
        //vt = get_power( op, p->x, p->y, pnet->dtw, pnet->dth);
        p->vt[i] = vt;
        ax += vt.dx;
        ay += vt.dy;
    }
    ax -= op->vt[0].dx;
    ay -= op->vt[0].dy;
    ax -= op->vt[1].dx;
    ay -= op->vt[1].dy;

    op = &(pnet->pt[l^1][y][x]);
    op->ax = ax;
    op->ay = ay;

    op->vx += op->ax;
    op->vy += op->ay;

    op->x += op->vx;
    op->y += op->vy;

    op->vx *= 1 - g_d_friction;
    op->vy *= 1 - g_d_friction;
    //op->vx = s_minus(op->vx, g_d_friction);
    //op->vy = s_minus(op->vy, g_d_friction);
}
/* takes an integer in parameter and prints it */
void print_number(int n)
{
  if (n < 0)
    {
      n = n * -1;
      print_char('-');
    }
  
  digits = get_digits(n);
  digitRetainer = digits;
  power = get_power();    

if (n == 0)
    {
      print_char('0');
    }
  else
    {
      print_digits(n);
    }
}
Beispiel #3
0
static int bt_power_read_proc(char *buffer, char **start, off_t offset, int size, int *eof, void *data)
{
  char *str;
  int r;
  int len;
  
  r = get_power();
  
  if(r)
    {str = "1 (Bluetooth power is ON)\n";}
  else
    {str = "0 (Bluetooth power is OFF)\n";}
  
  len = strlen(str);
  if (size < len) {return -EINVAL;}
  if (offset != 0){return 0;}
  
  strcpy(buffer, str);
  
  *eof = 1;
  return len;
}
// Poll power until available, then start up
void ActuatorOutputSubmarine::mission_startup_sequence()
{
  bool power_available = false;

  while (!power_available) {
    // Wait for 2 seconds to see if power stays on
    special_cmd(SUB_POWER_ON);
    char c = CharacterStreamSingleton::get_instance().wait_key(5000);
    if (c == 'q') {
      CharacterStreamSingleton::get_instance().write_char(c);
      return;
    }

    // Flush terminal so it can detect if power failed
    get_depth();

    if (get_power()) {
      power_available = true;
    }
  }

  special_cmd(SUB_STARTUP_SEQUENCE);
}
Beispiel #5
0
void cmd_get(int argc,char **argv)
{
  int psec;

  if (argc < 3) 
    usage();

  if (!strcmp(argv[2],"power")) {
    Dprintf("power\n");
    if (argc  < 4 ) {
      psec =10;
    } else {
      psec = atoi(argv[3]);
    }
    get_power(psec);

    
  } else if (!strcmp(argv[2],"state")){
    Dprintf("state");
    if (argc < 4)
      usage();

    if (!strcmp(argv[3],"all")) {
      get_status(1);
      get_status(2);
      get_status(3);

    }else if (!(!strcmp(argv[3],"1") | !strcmp(argv[3],"2") | !strcmp(argv[3],"3" ))){
      usage();
    }else {
      get_status(atoi(argv[3]));
    }
  }else{
    usage();
  }
}
Beispiel #6
0
// ------------------------------------------------------------------------------------------------
// Option parser 
static error_t parse_opt (int key, char *arg, struct argp_state *state)
// ------------------------------------------------------------------------------------------------
{
    arguments_t *arguments = state->input;
    char        *end;  // Used to indicate if ASCII to int was successful
    uint8_t     i8;
    uint32_t    i32;

    switch (key){
        // Verbosity 
        case 'v':
            arguments->verbose_level = strtol(arg, &end, 10);
            if (*end)
                argp_usage(state);
            else
                verbose_level = arguments->verbose_level;
            break; 
        // Print long help and exit
        case 'H':
            arguments->print_long_help = 1;
            break;
        // Activate FEC
        case 'F':
            arguments->fec = 1;
            break;
        // Activate whitening
        case 'W':
            arguments->whitening = 1;
            break;
        // Reception test
        case 'r':
            arguments->test_rx = 1;
            break;
        // Modulation scheme 
        case 'M':
            i8 = strtol(arg, &end, 10); 
            if (*end)
                argp_usage(state);
            else
                arguments->modulation = get_modulation_scheme(i8);
            break;
        // TNC mode 
        case 't':
            i8 = strtol(arg, &end, 10); 
            if (*end)
                argp_usage(state);
            else
                arguments->tnc_mode = get_tnc_mode(i8);
            break;
        // Radio data rate 
        case 'R':
            i8 = strtol(arg, &end, 10); 
            if (*end)
                argp_usage(state);
            else
                arguments->rate = get_rate(i8);
            break;
        // Output power
        case 'd':
            i8 = strtol(arg, &end, 10); 
            if (*end)
                argp_usage(state);
            else
                arguments->power_index = get_power(i8);
            break;
        // Radio link frequency
        case 'f':
            arguments->freq_hz = strtol(arg, &end, 10);
            if (*end)
                argp_usage(state);
            break; 
        // Radio link intermediate frequency
        case 'I':
            arguments->if_freq_hz = strtol(arg, &end, 10);
            if (*end)
                argp_usage(state);
            break; 
        // Packet length
        case 'p':
            arguments->packet_length = strtol(arg, &end, 10) % 254;
            if (*end)
                argp_usage(state);
            break; 
        // Large packet length
        case 'P':
            arguments->large_packet_length = strtol(arg, &end, 10) % (1<<16);
            if (*end)
                argp_usage(state);
            break; 
        // Packet delay
        case 'l':
            arguments->block_delay = strtol(arg, &end, 10);
            if (*end)
                argp_usage(state);
            break; 
        // Variable length packet
        case 'V':
            if (ALLOW_VAR_BLOCKS)
            {
                arguments->variable_length = 1;
            }
            else
            {
                fprintf(stderr, "Variable length blocks are not allowed (yet?)\n");
            }
            break;
        // Real time scheduling
        case 'T':
            if (ALLOW_REAL_TIME)
            {
                arguments->real_time = 1;
            }
            else
            {
                fprintf(stderr, "Real time scheduling is not allowed\n");
            }
            break;
        // Repetition factor
        case 'n':
            arguments->repetition = strtol(arg, &end, 10);
            if (*end)
                argp_usage(state);
            break; 
        // USB device
        case 'U':
            arguments->usbacm_device = strdup(arg);
            break;
        // Serial device
        case 'D':
            arguments->serial_device = strdup(arg);
            break;
        // Serial speed  
        case 'B':
            i32 = strtol(arg, &end, 10); 
            if (*end)
                argp_usage(state);
            else
                arguments->serial_speed = get_serial_speed(i32, &(arguments->serial_speed_n));
            break;
        // Transmission test phrase
        case 'y':
            arguments->test_phrase = strdup(arg);
            break;
        // Print radio status and exit
        case 's':
            arguments->print_radio_status = 1;
            break;
        // Modulation index
        case 'm':
            arguments->modulation_index = atof(arg);
            break;
        // Frequency offset in ppb from nominal
        case 'o':
            arguments->freq_offset_ppm = atof(arg);
            break;
        // Rate skew multiplier
        case 'w':
            arguments->rate_skew = atof(arg);
            break;
        // TNC serial link window
        case 300:
            arguments->tnc_serial_window = strtol(arg, &end, 10);
            if (*end)
                argp_usage(state);
            break; 
        // TNC radio link window
        case 301:
            arguments->tnc_radio_window = strtol(arg, &end, 10);
            if (*end)
                argp_usage(state);
            break; 
        // TNC keyup delay
        case 302:
            arguments->tnc_keyup_delay = strtol(arg, &end, 10);
            if (*end)
                argp_usage(state);
            break; 
        // TNC keydown delay
        case 303:
            arguments->tnc_keydown_delay = strtol(arg, &end, 10);
            if (*end)
                argp_usage(state);
            break; 
        // TNC switchover delay 
        case 304:
            arguments->tnc_switchover_delay = strtol(arg, &end, 10);
            if (*end)
                argp_usage(state);
            break; 
        // Bkulk filename
        case 310:
            arguments->bulk_filename = strdup(arg);
            break;
        default:
            return ARGP_ERR_UNKNOWN;
    }

    return 0;
}
Beispiel #7
0
/** @brief Function for main application entry.
 */
int main(void)
{ 
    radio_tests_t test     = RADIO_TEST_NOP;
    radio_tests_t cur_test = RADIO_TEST_NOP;

    init();
    uart_config(TX_PIN_NUMBER, RX_PIN_NUMBER);
    uart_putstring((const uint8_t *)"RF Test\r\n");
    
    NVIC_EnableIRQ(TIMER0_IRQn);
    __enable_irq();
    
    while (true)
    {
        __WFI();
        switch (uart_get())
        {
            case 'a':
                while (true)
                {
                    uart_putstring((const uint8_t *)"Enter start channel \
                                   (two decimal digits, 00 to 80):");
                    channel_start_ = get_dec2();
                    if (channel_start_ <= 80)
                    break;
                    uart_putstring((const uint8_t *)"Channel must be between 0 and 80\r\n");
                }
                test = cur_test;
                break;

            case 'b':
                while (true)
                {
                    uart_putstring((const uint8_t *)"Enter end channel \
                                   (two decimal digits, 00 to 80):");
                    channel_end_ = get_dec2();
                    if (channel_end_ <= 80)
                    {
                        break;
                    }
                uart_putstring((const uint8_t *)"Channel must be between 0 and 80\r\n");
                }
                test = cur_test;
                break;

            case 'c':
                test = RADIO_TEST_TXCC;
                break;

            case 'd':
                while (true)
                {
                    uart_putstring((const uint8_t *)"Enter delay in ms \
                                   (two decimal digits, 01 to 99):");
                    delayms_ = get_dec2();
                    if ((delayms_ > 0) && (delayms_ < 100))   
                    {
                        break;
                    }
                    uart_putstring((const uint8_t *)"Delay must be between 1 and 99\r\n");
                }
                test = cur_test;
                break;

            case 'e':
                radio_sweep_end();
                cur_test = RADIO_TEST_NOP;
                break;

            case 'm':
                get_datarate();
                test = cur_test;
                break;

            case 'o':
                test = RADIO_TEST_TXMC;
                uart_putstring((const uint8_t *)"TX modulated carrier\r\n");
                break;

            case 'p':
                get_power();
                test = cur_test;
                break;

            case 'r':
                test = RADIO_TEST_RXSWEEP;
                uart_putstring((const uint8_t *)"RX Sweep\r\n");
                break;

            case 's':
                print_parameters();
                break;

            case 't':
                test = RADIO_TEST_TXSWEEP;
                uart_putstring((const uint8_t *)"TX Sweep\r\n");
                break;

            case 'x':
                test = RADIO_TEST_RXC;
                uart_putstring((const uint8_t *)"RX constant carrier\r\n");
                break;

            case 'h':
                // Fall through.
        
            default:
                help();
                break;
        }
    
        switch (test)
        {
            case RADIO_TEST_TXCC:
                if (sweep)
                {
                    radio_sweep_end();
                    sweep = false;
                }
                radio_tx_carrier(txpower_, mode_, channel_start_);
                cur_test = test;
                test     = RADIO_TEST_NOP;
                break;

            case RADIO_TEST_TXMC:
                if (sweep)
                {
                    radio_sweep_end();
                    sweep = false;
                }
                radio_modulated_tx_carrier(txpower_, mode_, channel_start_);
                cur_test = test;
                test     = RADIO_TEST_NOP;
                break;

            case RADIO_TEST_TXSWEEP:
                radio_tx_sweep_start(txpower_, mode_, channel_start_, channel_end_, delayms_);
                sweep    = true;
                cur_test = test;
                test     = RADIO_TEST_NOP;
                break;

            case RADIO_TEST_RXC:
                if (sweep)
                {
                    radio_sweep_end();
                    sweep = false;
                }
                radio_rx_carrier(mode_, channel_start_);
                cur_test = test;
                test     = RADIO_TEST_NOP;
                break;  

            case RADIO_TEST_RXSWEEP:
                radio_rx_sweep_start(mode_, channel_start_, channel_end_, delayms_);
                sweep    = true;
                cur_test = test;
                test     = RADIO_TEST_NOP;
                break;

            case RADIO_TEST_NOP:
                // Fall through.
            default:
                // No implementation needed.
                break;
        }
    }
}
Beispiel #8
0
void
do_organic_farm (int x, int y)
{
  /* 
     // int_1 is the tech level of the farm when built
     // int_2 is a flag so we don't create a farm with nearly ripe crops.
     // int_3 is the food sold count so far this year.
     // int_4 is the food made last year.
     // int_5 is the random crop rotation key.
     // int_6 is the random month stagger, so they don't all flash at once
     // int_7 is the tech-level dependent output of a powered farm with a full
     // workforce.
  */
  int i;
  if (MP_INFO(x,y).int_5 == 0)	/* this should be done when we create */

    {				/* the area! */

      MP_INFO(x,y).int_5 = (rand () % 4) + 1;
      MP_INFO(x,y).int_6 = rand () % 300;
    }
  MP_INFO(x,y).flags &= (0xffffffff - FLAG_POWERED);
  if (get_jobs (x, y, 1) == 0)
    put_food (x, y, 30);
  else if (get_jobs (x, y, FARM_JOBS_USED) != 0)
    {
      if (get_power (x, y, ORG_FARM_POWER_REC, 0) != 0)
	{
	  if (put_food (x, y, (ORGANIC_FARM_FOOD_OUTPUT
			       + MP_INFO(x,y).int_7)) == 0)
	    put_jobs (x, y, FARM_JOBS_USED);
	  else
	    MP_INFO(x,y).int_3++;
	  MP_INFO(x,y).flags |= FLAG_POWERED;
	}
      else
	{
	  if (put_food (x, y, (ORGANIC_FARM_FOOD_OUTPUT / 4)) == 0)
	    put_jobs (x, y, FARM_JOBS_USED);
	  else
	    MP_INFO(x,y).int_3++;
	}
    }
  else if (get_jobs (x, y, FARM_JOBS_USED / 4) != 0)
    {
      if (get_power (x, y, ORG_FARM_POWER_REC, 0) != 0)
	{
	  if (put_food (x, y, (ORGANIC_FARM_FOOD_OUTPUT
			       + (MP_INFO(x,y).int_7 / 4))) == 0)
	    put_jobs (x, y, FARM_JOBS_USED / 4);
	  else
	    MP_INFO(x,y).int_3++;
	  MP_INFO(x,y).flags |= FLAG_POWERED;
	}
      else
	{
	  if (put_food (x, y, (ORGANIC_FARM_FOOD_OUTPUT / (4 * 4))) == 0)
	    put_jobs (x, y, FARM_JOBS_USED / 4);
	  else
	    MP_INFO(x,y).int_3++;
	}
    }
  else
    {
      if (get_power (x, y, ORG_FARM_POWER_REC, 0) != 0)
	{
	  if (put_food (x, y, (ORGANIC_FARM_FOOD_OUTPUT
			       + (MP_INFO(x,y).int_7 / 8))) != 0)
	    MP_INFO(x,y).int_3++;
	  MP_INFO(x,y).flags |= FLAG_POWERED;
	}
      else if (put_food (x, y, 30
			 + (ORGANIC_FARM_FOOD_OUTPUT / (4 * 8))) != 0)
	MP_INFO(x,y).int_3++;
    }
  if ((total_time & 0x7f) == 0)
    if ((MP_INFO(x,y).flags & FLAG_POWERED) != 0)
      get_waste (x, y, 0x80 * ORG_FARM_WASTE_GET);
  if ((total_time % 1200) == 0)
    {
      MP_INFO(x,y).int_4 = MP_INFO(x,y).int_3;
      MP_INFO(x,y).int_3 = 0;
    }
  i = ((total_time + (MP_INFO(x,y).int_5 * 1200)
	+ MP_INFO(x,y).int_6) % 4800);
  if (i % 300 == 0)
    {
      i /= 300;
      if ( /* MP_INFO(x,y).int_2!=0 &&  */ MP_INFO(x,y).int_4
	  > MIN_FOOD_SOLD_FOR_ANIM)
	{
	  if (i % 4 == 0)
	    {
	      MP_INFO(x,y).int_6 = rand () % 100;
	    }
	  switch (i)
	    {
	    case (0):
	      MP_TYPE(x,y) = CST_FARM_O3;
	      break;
	    case (1):
	      MP_TYPE(x,y) = CST_FARM_O3;
	      break;
	    case (2):
	      MP_TYPE(x,y) = CST_FARM_O3;
	      break;
	    case (3):
	      MP_TYPE(x,y) = CST_FARM_O3;
	      break;
	    case (4):
	      MP_TYPE(x,y) = CST_FARM_O7;
	      break;
	    case (5):
	      MP_TYPE(x,y) = CST_FARM_O7;
	      break;
	    case (6):
	      MP_TYPE(x,y) = CST_FARM_O7;
	      break;
	    case (7):
	      MP_TYPE(x,y) = CST_FARM_O7;
	      break;
	    case (8):
	      MP_TYPE(x,y) = CST_FARM_O11;
	      break;
	    case (9):
	      MP_TYPE(x,y) = CST_FARM_O11;
	      break;
	    case (10):
	      MP_TYPE(x,y) = CST_FARM_O11;
	      break;
	    case (11):
	      MP_TYPE(x,y) = CST_FARM_O11;
	      break;
	    case (12):
	      MP_TYPE(x,y) = CST_FARM_O15;
	      break;
	    case (13):
	      MP_TYPE(x,y) = CST_FARM_O15;
	      break;
	    case (14):
	      MP_TYPE(x,y) = CST_FARM_O15;
	      break;
	    case (15):
	      MP_TYPE(x,y) = CST_FARM_O15;
	      break;

	    }
	}
      else
	{
	  MP_TYPE(x,y) = CST_FARM_O0;
	}
    }
}
Beispiel #9
0
int
main (int argc, char *argv[])
{
  struct stats s, s0;
  int print = 0;

  FILE *fp = fopen(STATS_FILE, "rb");
  if (fp != NULL)
    {
      fread(&s0, sizeof(struct stats), 1, fp);
      fclose(fp);
      print = 1;
    }

  get_times(&s);
  get_temp(&s);
  get_mail(&s);
  get_cputime(&s);
  get_power(&s);
  get_mem(&s);
  get_txrx(&s);

  if (print)
    {
      int i;
      double temp = 1e-3*s.temp;
      double charge = 100*s.charge_now/s.charge_full;
      double tx = (s.tx-s0.tx)/(s.t-s0.t);
      double rx = (s.rx-s0.rx)/(s.t-s0.t);
      double mem = s.mem*9.5367431640625e-07;
      double cpu_pct[MAX_CPUS];
      for (i=0; i < s.n_cpus; i++)
        {
          double idle = s.cpu_idle[i] - s0.cpu_idle[i];
          double total = s.cpu_total[i] - s0.cpu_total[i];
          cpu_pct[i] = 1-idle/total;
        }

      fputs(" [", stdout);
      begin_color(color_bar);
      fputs(th_spc, stdout);
      for (i=0; i < s.n_cpus; i++)
        {
          print_bar(cpu_pct[i]);
          fputs(th_spc, stdout);
        }
      end_color();
      fputc(']', stdout);

      begin_color (color_div);
      fputs(spc, stdout);
      fputs(divider, stdout);
      end_color();

      begin_color_coded (temp, LO_TEMP, HI_TEMP);
      num_print (temp, 3, degc);
      end_color();

      begin_color (color_div);
      fputs(spc, stdout);
      fputs(divider, stdout);
      fputs(spc, stdout);
      end_color();

      begin_color_coded (mem, LO_MEM, HI_MEM);
      num_print (mem, 4, "MB");
      end_color();

      begin_color (color_div);
      fputs(spc, stdout);
      fputs(divider, stdout);
      fputs(spc, stdout);
      end_color();

      begin_color (s.ac_connected ? "cyan" : "red");
      fputs(s.ac_connected ? acon : acoff, stdout);
      fputc(' ', stdout);
      end_color();
      begin_color_coded (100-charge, LO_CHARGE, HI_CHARGE);
      num_print (charge, 3, "%");
      end_color();

      begin_color (color_div);
      fputs(spc, stdout);
      fputs(divider, stdout);
      end_color();

      begin_color_coded (tx, LO_RATE, HI_RATE);
      num_print (tx, 0, "B/s  ");
      end_color();
      begin_color (color_up);
      fputs(up, stdout);
      end_color();
      begin_color_coded (rx, LO_RATE, HI_RATE);
      fputs(spc, stdout);
      num_print (rx, 0, "B/s  ");
      end_color();
      begin_color (color_down);
      fputs(down, stdout);
      end_color();

      fputs(spc, stdout);
      begin_color (color_div);
      fputs(divider, stdout);
      fputs(spc, stdout);
      end_color();

      if (s.gmail)
        {
          begin_color (color_mail);
          printf ("%2d/g", s.gmail);
          end_color();
        }
          
      if (s.uiucmail)
        {
          begin_color (color_mail);
          printf ("%2d/u", s.uiucmail);
          end_color();
        }

      if (s.uiucmail || s.gmail)
        {
          fputs(spc, stdout);
          begin_color (color_div);
          fputs(divider, stdout);
          fputs(spc, stdout);
          end_color();
        }
      
      begin_color (color_date);
      fputs(s.date, stdout);
      end_color();

      fputs(spc, stdout);
      begin_color (color_div);
      fputs(divider, stdout);
      end_color();
    }

  fp = fopen(STATS_FILE, "wb");
  fwrite(&s, sizeof(struct stats), 1, fp);
  fclose(fp);

  return 0;
}
int main(int argc, char *argv[])
{
    int sockfd, port;
    struct sockaddr_in my_addr;
    struct sockaddr_in abt_addr;
    socklen_t addrlen;
    struct pollfd abt_pfd;

    char send_buf[SEND_BUF_LEN];
    char recv_buf[RECV_BUF_LEN];
    int quit = 0;
    int abt_alive = 0;
    int n, ret;
    float history_power,total_power,power_cap;
	
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <port>\n", argv[0]);
        exit(1);
    }
    port = atoi(argv[1]);
    power_cap = 100;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) handle_error("ERROR: socket");

    bzero((char *)&my_addr, sizeof(my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_addr.s_addr = INADDR_ANY;
    my_addr.sin_port = htons(port);
    ret = bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));
    if (ret < 0) handle_error("ERROR: bind");

    while (!quit) {
        int core_num;
        printf("Waiting for connection...\n");
        
        listen(sockfd, 5);
        addrlen = sizeof(abt_addr);
        abt_pfd.fd = accept(sockfd, (struct sockaddr *)&abt_addr, &addrlen);
        if (abt_pfd.fd < 0) handle_error("ERROR: accept");
        abt_pfd.events = POLLIN | POLLRDHUP;
        abt_alive = 1;

        printf("Client connected...\n\n");

        while (abt_alive) {
            float current_power;
            current_power = get_power();
            history_power= current_power;
            /* judging for convergence */
            while ((((power_cap >current_power)&&(power_cap>history_power))||((power_cap < current_power)&&(power_cap < history_power)))&&abt_alive){
                if (current_power > power_cap){
                    bzero(send_buf, SEND_BUF_LEN);
                    send_buf[0] = 'd';
                }
                else{
                    bzero(send_buf, SEND_BUF_LEN);
                    send_buf[0] = 'i';
                }
                n = write(abt_pfd.fd, send_buf, strlen(send_buf));
                assert(n == strlen(send_buf));
                bzero(recv_buf, RECV_BUF_LEN);
                while (1) {
                    ret = poll(&abt_pfd, 1, 10);
                    if (ret == -1) {
                        handle_error("ERROR: poll");
                    } else if (ret != 0) {
                        if (abt_pfd.revents & POLLIN) {
                            n = read(abt_pfd.fd, recv_buf, RECV_BUF_LEN);
                            if (n < 0) handle_error("ERROR: read");
                            printf("Response: %s\n\n", recv_buf);
                            sscanf(recv_buf, "done (%d)", &core_num);
                            
                        }
                        if (abt_pfd.revents & POLLRDHUP) {
                            abt_alive = 0;
                            printf("Client disconnected...\n");
                            break;
                        }
                    abt_pfd.revents = 0;
                    break;
                    }
                }
                history_power = current_power;
                current_power = get_power();
                /* check boundry condition*/
                if ((core_num == 40)||(core_num == 1)){
                    break;
                
                }
            }
            abt_alive=0;
            if (current_power > history_power){
                bzero(send_buf, SEND_BUF_LEN);
                send_buf[0] = 'd';
                n = write(abt_pfd.fd, send_buf, strlen(send_buf));
                assert(n == strlen(send_buf));
                while (1) {
                    ret = poll(&abt_pfd, 1, 10);
                    if (ret == -1) {
                        handle_error("ERROR: poll");
                    } else if (ret != 0) {
                            if (abt_pfd.revents & POLLIN) {
                            n = read(abt_pfd.fd, recv_buf, RECV_BUF_LEN);
                            if (n < 0) handle_error("ERROR: read");

                            printf("Response: %s\n\n", recv_buf);
                            printf("core number adjustment finished\n");

                        }
                        if (abt_pfd.revents & POLLRDHUP) {
                            abt_alive = 0;
                            printf("Client disconnected...\n");
                            break;
                        }
                    abt_pfd.revents = 0;
                    break;
                    }
                }

            }
            current_power = get_power();
            printf("currnet power = %f\n",current_power);
        }
    quit = 1;
    close(abt_pfd.fd);
    }

    close(sockfd);

    return EXIT_SUCCESS;
}
void Meter::update_average()
{
  // update running average
  average_power.add(get_power());
}
void main(void) {
  volatile packet_t *p;
#ifdef CARRIER_SENSE
  volatile uint32_t i;
#endif
  uint16_t r=30; /* start reception 100us before ack should arrive */
  uint16_t end=180; /* 750 us receive window*/

  /* trim the reference osc. to 24MHz */
  trim_xtal();
  uart_init(INC, MOD, SAMP);
  vreg_init();
  maca_init();

  ///* Setup the timer */
  *TMR_ENBL = 0;                     /* tmrs reset to enabled */
  *TMR0_SCTRL = 0;
  *TMR0_LOAD = 0;                    /* reload to zero */
  *TMR0_COMP_UP = 18750;             /* trigger a reload at the end */
  *TMR0_CMPLD1 = 18750;              /* compare 1 triggered reload level, 10HZ maybe? */
  *TMR0_CNTR = 0;                    /* reset count register */
  *TMR0_CTRL = (COUNT_MODE<<13) | (PRIME_SRC<<9) | (SEC_SRC<<7) | (ONCE<<6) | (LEN<<5) | (DIR<<4) | (CO_INIT<<3) | (OUT_MODE);
  *TMR_ENBL = 0xf;                   /* enable all the timers --- why not? */

  set_channel(CHANNEL); /* channel 11 */
  set_power(0x12); /* 0x12 is the highest, not documented */

  /* sets up tx_on, should be a board specific item */
  GPIO->FUNC_SEL_44 = 1;	 
  GPIO->PAD_DIR_SET_44 = 1;	 
  GPIO->FUNC_SEL_45 = 2;	 
  GPIO->PAD_DIR_SET_45 = 1;	 
  *MACA_RXACKDELAY = r;
  *MACA_RXEND = end;

  set_prm_mode(AUTOACK);

  while(1) {		

    if((*TMR0_SCTRL >> 15) != 0) 
      tick();

    /* call check_maca() periodically --- this works around */
    /* a few lockup conditions */
    check_maca();

    while((p = rx_packet())) {
      if(p) free_packet(p);
    }

    p = get_free_packet();
    if(p) {
      fill_packet(p);

#ifdef CARRIER_SENSE
      for(i=0; i<POWER_DELAY; i++) {continue;}
      while(get_power()>74) {}
#endif

#ifdef BLOCKING_TX
      blocking_tx_packet(p);
#else
      tx_packet(p);
#endif

      current_pkts++;

#if defined(RANDOM_WAIT_TIME) || defined(FIXED_WAIT)
      random_wait();
#endif
    }
  }
}
Beispiel #13
0
void
do_mill (int x, int y)
{
  /*
     // int_1 contains the goods at the mill
     // int_2 contains the food store
     // int_3 contains the coal store
     // int_4 contains the animation trigger time
     // int_5 is the % count so far this month
     // int_6 is the % capacity last month
   */
  /* get food */
  int block_anim = 0;
  if (MP_INFO(x,y).int_2 < MAX_FOOD_AT_MILL)
    if (get_food (x, y, MILL_GET_FOOD) != 0)
      MP_INFO(x,y).int_2 += MILL_GET_FOOD;
  /* get coal */
  if (MP_INFO(x,y).int_3 < MAX_COAL_AT_MILL)
    {
      if (get_coal (x, y, MILL_GET_COAL) != 0)
	MP_INFO(x,y).int_3 += MILL_GET_COAL;
      else if (get_power (x, y, MILL_GET_COAL
			  * MILL_POWER_PER_COAL, 0) != 0)
	MP_INFO(x,y).int_3 += MILL_GET_COAL;
    }
  if (MP_INFO(x,y).int_1 < MAX_GOODS_AT_MILL)
    {
      if (MP_INFO(x,y).int_2 > FOOD_USED_BY_MILL
	  && MP_INFO(x,y).int_3 > COAL_USED_BY_MILL)
	{
	  if (get_jobs (x, y, MILL_JOBS) != 0)
	    {
	      MP_INFO(x,y).int_2 -= FOOD_USED_BY_MILL;
	      MP_INFO(x,y).int_3 -= COAL_USED_BY_MILL;
	      MP_INFO(x,y).int_1 += GOODS_MADE_BY_MILL;
	      MP_INFO(x,y).int_5++;
	    }
	  else
	    {
	      MP_TYPE(x,y) = CST_MILL_0;
	      block_anim = 1;
	    }
	}
      else
	block_anim = 1;
    }

  if (MP_INFO(x,y).int_1 > 0)
    if (put_goods (x, y, MP_INFO(x,y).int_1) != 0)
      MP_INFO(x,y).int_1 = 0;

  if (total_time % 100 == 0)
    {
      MP_INFO(x,y).int_6 = MP_INFO(x,y).int_5;
      MP_INFO(x,y).int_5 = 0;
    }
  if (real_time >= MP_INFO(x,y).int_4 && block_anim == 0)
    {
      MP_INFO(x,y).int_4 = real_time + MILL_ANIM_SPEED;
      switch (MP_TYPE(x,y))
	{
	case (CST_MILL_0):
	  MP_TYPE(x,y) = CST_MILL_1;
	  break;
	case (CST_MILL_1):
	  MP_TYPE(x,y) = CST_MILL_2;
	  break;
	case (CST_MILL_2):
	  MP_TYPE(x,y) = CST_MILL_3;
	  break;
	case (CST_MILL_3):
	  MP_TYPE(x,y) = CST_MILL_4;
	  break;
	case (CST_MILL_4):
	  MP_TYPE(x,y) = CST_MILL_5;
	  break;
	case (CST_MILL_5):
	  MP_TYPE(x,y) = CST_MILL_6;
	  break;
	case (CST_MILL_6):
	  MP_TYPE(x,y) = CST_MILL_1;
	  MP_POL(x,y)++;
	  break;
	}
    }
}
Beispiel #14
0
int main(void)
{
  printf("%d\n", get_power(8, 2));

  return (0);
}
int main(int argc, char *argv[])
{
  double mean = atof(argv[1]);
  double sigma = atof(argv[2]);
  //for cell 1
  double g_Na1 = atof(argv[3]); //uS/nF 
  double g_CaT1 = atof(argv[4]);
  double g_CaS1 = atof(argv[5]);
  double g_A1 = atof(argv[6]);
  double g_KCa1 = atof(argv[7]);
  double g_K1 = atof(argv[8]);
  double g_H1 = atof(argv[9]);
  double g_L1 = atof(argv[10]); //uS/nF
  double g_syn1 =  atof(argv[11]);
  //for cell 2
  double g_Na2 = atof(argv[12]);
  double g_CaT2 = atof(argv[13]);
  double g_CaS2 = atof(argv[14]); 
  double g_A2 = atof(argv[15]);
  double g_KCa2 = atof(argv[16]);
  double g_K2 = atof(argv[17]);
  double g_H2 = atof(argv[18]);
  double g_L2 = atof(argv[19]); //uS/nF  
  double g_syn2 =  atof(argv[20]);
  //
  double corr_coef = atof(argv[21]); //correlation coefficient of the input
  double tau_c = atof(argv[22]); //correlation time const
  int num_run = atof(argv[23]);
  //NOTE: if num_run=0; then use model with regular synapses ./m.out
  //if num_run=1; then Grashow synapse model ./m2.out

  //don't use, use voltage derivative
  double V_th = -15; //mV, threshold for detecting spikes

  /*open files where spikes will be recorded*/
  /*
  char sp_file1 [999];
  sprintf (sp_file1, "spikes1_mean_%g_sig_%g_gNa_%g_gCaT_%g_gCaS_%g_gA_%g_gKCa_%g_gK_%g_gH_%g_gL_%g_gsyn_%g_%g_corr_%g_tc_%g_dt_%g_num_%d.dat", mean, sigma, g_Na1, g_CaT1, g_CaS1, g_A1, g_KCa1, g_K1, g_H1, g_L1, g_syn1, g_syn2, corr_coef,tau_c, dt, num_run);
  FILE *spfile1;
  spfile1 = fopen(sp_file1,"w");
  //
  char sp_file2 [999];
  sprintf (sp_file2, "spikes2_mean_%g_sig_%g_gNa_%g_gCaT_%g_gCaS_%g_gA_%g_gKCa_%g_gK_%g_gH_%g_gL_%g_gsyn_%g_%g_corr_%g_tc_%g_dt_%g_num_%d.dat", mean, sigma, g_Na2, g_CaT2, g_CaS2, g_A2, g_KCa2, g_K2, g_H2, g_L2, g_syn1, g_syn2, corr_coef,tau_c, dt, num_run);
  FILE *spfile2;
  spfile2 = fopen(sp_file2,"w");
  */
  
  char V_file1 [999];
  sprintf (V_file1, "V1_mean_%g_sig_%g_gNa_%g_gCaT_%g_gCaS_%g_gA_%g_gKCa_%g_gK_%g_gH_%g_gL_%g_gsyn_%g_%g_corr_%g_tc_%g_dt_%g_num_%d.dat", mean, sigma, g_Na1, g_CaT1, g_CaS1, g_A1, g_KCa1, g_K1, g_H1, g_L1, g_syn1, g_syn2, corr_coef,tau_c, dt, num_run);
  FILE *Vfile1;
  Vfile1 = fopen(V_file1,"w");
  //
  char V_file2 [999];
  sprintf (V_file2, "V2_mean_%g_sig_%g_gNa_%g_gCaT_%g_gCaS_%g_gA_%g_gKCa_%g_gK_%g_gH_%g_gL_%g_gsyn_%g_%g_corr_%g_tc_%g_dt_%g_num_%d.dat", mean, sigma, g_Na2, g_CaT2, g_CaS2, g_A2, g_KCa2, g_K2, g_H2, g_L2, g_syn1, g_syn2, corr_coef,tau_c, dt, num_run);
  FILE *Vfile2;
  Vfile2 = fopen(V_file2,"w");

   /*For random number generation:*/
  gsl_rng * r;
  r = gsl_rng_alloc (gsl_rng_default);
  gsl_rng_set(r, time(NULL));
  /*done*/

  int ii, jj, nn;

  /* Defining the model
     gate = [ m h ][4]   gating variables for the four conductances
     g = [ g_Na g_CaT g_CaS g_A g_KCa g_K g_H g_leak ]    maximal conductances
     E = [ E_Na E_CaT E_CaS E_A E_KCa E_K E_H E_leak ]    Nernst (reversal) potentials 
     gmh = [ conductances as a function of time ]
  */
  
 //reversal potentials
  double E_Na = 50; //mV or 30?
  double E_A = -80; //mV
  double E_K = -80; //mV
  double E_H = -20; //mV
  double E_Ca[2]; E_Ca[0] = 120; E_Ca[1] = 120; //mV default, but will vary
  double E_L = -50; //mV
  double C = 1; //nF 
  double tau_Ca = 20; //ms
  double I_Ca[2]; I_Ca[0] = 0; I_Ca[1] = 0;
  //synaptic
  double E_syn = -80; //mV
  double tau_syn = 100; //ms
  //Grashow V_half=-45; V_slope = 5;
  //otherwise I used:  V_half = 40; V_slope = -2.0;
  double V_half = -45.0;  //mV
  double V_slope = 5.0;  //mV

  /*Initial conditions*/
  double V[2];
  V[0] = -46.8; //mV
  V[1] = -50;
  double Ca[2]; Ca[0] = 0.2; Ca[1] = 0.2;
  double Ca_inf[2]; Ca_inf[0] = Ca[0]; Ca_inf[1] = Ca[1];
  double g[7][2];
  double gate[2][7][2];
  double tau[2][7][2];
  double gate_inf[2][7][2];
  double E[7][2];
  int p[7];
  double gnmh[7][2];

  for (nn=0;nn<2;nn++)
    {
      gate_inf[0][0][nn] = Xinf(V[nn],25.5,-5.29); //m, Na
      gate_inf[1][0][nn] = Xinf(V[nn],48.9,5.18); //h, Na
      gate_inf[0][1][nn] = Xinf(V[nn],27.1,-7.2); //m, CaT
      gate_inf[1][1][nn] = Xinf(V[nn],32.1,5.5); //h, CaT
      gate_inf[0][2][nn] = Xinf(V[nn],33.0,-8.1); //m, CaS
      gate_inf[1][2][nn] = Xinf(V[nn],60.0,6.2); //h, CaT
      gate_inf[0][3][nn] = Xinf(V[nn],27.2,-8.7); //m, A
      gate_inf[1][3][nn] = Xinf(V[nn],56.9,4.9); //h, A
      gate_inf[0][4][nn] = m_KCainf(V[nn],Ca[nn]); //m, kCa 
      gate_inf[1][4][nn] = 0.0; //h, kCa
      gate_inf[0][5][nn] = Xinf(V[nn],12.3,-11.8); //m, Kd
      gate_inf[1][5][nn] = 0.0; //h, Kd	
      gate_inf[0][6][nn] = Xinf(V[nn],70.0,6.0); //m, H
      gate_inf[1][6][nn] = 0.0; //h, H
      for (ii=0;ii<7;ii++)
	{
	  gate[0][ii][nn] =  gate_inf[0][ii][nn];
	  gate[1][ii][nn] =  gate_inf[1][ii][nn];
	  gnmh[ii][nn] = 0.0;
	} 
    }
  

  E[0][0] = E_Na; E[0][1] = E_Na;
  E[1][0] = E_Ca[0]; E[1][1] = E_Ca[1]; 
  E[2][0] = E_Ca[0]; E[2][1] = E_Ca[1];
  E[3][0] = E_A;  E[3][1] = E_A;
  E[4][0] = E_K;  E[4][1] = E_K; 
  E[5][0] = E_K;  E[5][1] = E_K;
  E[6][0] = E_H;  E[6][1] = E_H;
  //
  p[0] = p_Na;
  p[1] = p_CaT;
  p[2] = p_CaS;
  p[3] = p_A;
  p[4] = p_KCa;
  p[5] = p_K;
  p[6] = p_H; 
  
  g[0][0] = g_Na1;   g[0][1] = g_Na2;
  g[1][0] = g_CaT1;  g[1][1] = g_CaT2;
  g[2][0] = g_CaS1;  g[2][1] = g_CaS2;
  g[3][0] = g_A1;    g[3][1] = g_A2;
  g[4][0] = g_KCa1;  g[4][1] = g_KCa2;
  g[5][0] = g_K1;    g[5][1] = g_K2;
  g[6][0] = g_H1;    g[6][1] = g_H2;

  double g_L[2]; g_L[0] = g_L1; g_L[1] = g_L2;
  double current_time = 0.0;
  double s_c = mean;
  double s_1 = mean;
  double s_2 = mean;
  double s[2]; 
  double Svar[2];
  Svar[1] = Xinf(V[0],45.0,-2.0);
  Svar[0] = Xinf(V[1],45.0,-2.0); 
  double S_inf[2];
  S_inf[0] = Svar[0]; 
  S_inf[1] = Svar[1];
  double g_syn[2]; g_syn[0] = g_syn1; g_syn[1] = g_syn2;
  int counter = 0;

  int voltage_high1 = 0;
  double spike1 = 0.0; //to impose an absolute refractory period when reading spikes
  int voltage_high2 = 0;
  double spike2 = 0.0; //to impose an absolute refractory period when reading spikes
  double rand_g1 = 0.0;
  double rand_g2 = 0.0;
  double rand_g3 = 0.0;

  double ds = 0.0;
 
  double sum_g[2], sum_Eg[2], tau_V[2], V_inf[2];
  while (current_time < total_time)
   {       
     current_time += dt;
     counter ++;
     //printf("%f \n",current_time);
     //s = mean + sigma/sqrt(dt)*rand_g; //if white noise

     //common input
     rand_g1 = gsl_ran_gaussian (r,1.0);
     //if correlated noise with correlation time constant tau_c
     ds = (mean-s_c)*(1-exp(-dt/tau_c)) + sigma*sqrt(1-exp(-2*dt/tau_c))*rand_g1; 
     s_c += ds;
     //independent input cell 1
     rand_g2 = gsl_ran_gaussian (r,1.0);
     ds = (mean-s_1)*(1-exp(-dt/tau_c)) + sigma*sqrt(1-exp(-2*dt/tau_c))*rand_g2; 
     s_1 += ds;
     //independent input cell 2
     rand_g3 = gsl_ran_gaussian (r,1.0);
     ds = (mean-s_2)*(1-exp(-dt/tau_c)) + sigma*sqrt(1-exp(-2*dt/tau_c))*rand_g3; 
     s_2 += ds;

     s[0] = s_1*(1-corr_coef) + s_c*corr_coef; //input to cell 1
     s[1] = s_2*(1-corr_coef) + s_c*corr_coef; //input to cell 2

     /*
       Model equations:
       C dv/dt = s - I_ion
       I_ion = sum( gate.*(V-E) )
       d gate/dt = -1/tau(v).*(gate-gate_0(v))
     */

      for (nn=0;nn<2;nn++)
       {
	 //next line: variable reversal potential for Ca
	 E_Ca[nn] = 500.0*R_F*(T + 273.15)*log(3000.0/Ca[nn]);
	 E[1][nn] = E_Ca[nn];
	 E[2][nn] = E_Ca[nn];
 	 
	 Ca_inf[nn] = 0.05 - 0.94*I_Ca[nn];  
	 // integrate Ca dynamics 
	 Ca[nn] = Ca[nn] + (1-exp(-dt/tau_Ca))*(Ca_inf[nn] - Ca[nn]);

	 tau[0][0][nn] = tauX(V[nn],1.32,1.26,120.0,-25); //m, Na
	 tau[1][0][nn] = tauhNa(V[nn]); //h, Na
	 tau[0][1][nn] = tauX(V[nn],21.7,21.3,68.1,-20.5); //m, CaT
	 tau[1][1][nn] = tauX(V[nn],105.0,89.8,55.0,-16.9); //h, CaT
	 tau[0][2][nn] = taumCaS(V[nn]); //m, CaS
	 tau[1][2][nn] = tauhCaS(V[nn]); //h, CaS
	 tau[0][3][nn] = tauX(V[nn],11.6,10.4,32.9,-15.2); //m, A
	 tau[1][3][nn] = tauX(V[nn],38.6,29.2,38.9,-26.5); //h, A
	 tau[0][4][nn] = tauX(V[nn],90.3,75.1,46.0,-22.7); //m, KCa
	 tau[1][4][nn] = 0.0; //h, kCa
	 tau[0][5][nn] = tauX(V[nn],7.2,6.4,28.3,-19.2); //m, Kd
	 tau[1][5][nn] = 0.0; //h, Kd	
	 tau[0][6][nn] = tauX(V[nn],272.0,-1499.0,42.2,-8.73); //m, H
	 tau[1][6][nn] = 0.0; //h, H

	 gate_inf[0][0][nn] = Xinf(V[nn],25.5,-5.29); //m, Na
	 gate_inf[1][0][nn] = Xinf(V[nn],48.9,5.18); //h, Na
	 gate_inf[0][1][nn] = Xinf(V[nn],27.1,-7.2); //m, CaT
	 gate_inf[1][1][nn] = Xinf(V[nn],32.1,5.5); //h, CaT
	 gate_inf[0][2][nn] = Xinf(V[nn],33.0,-8.1); //m, CaS
	 gate_inf[1][2][nn] = Xinf(V[nn],60.0,6.2); //h, CaT
	 gate_inf[0][3][nn] = Xinf(V[nn],27.2,-8.7); //m, A
	 gate_inf[1][3][nn] = Xinf(V[nn],56.9,4.9); //h, A
	 gate_inf[0][4][nn] = m_KCainf(V[nn],Ca[nn]); //m, kCa 
	 gate_inf[1][4][nn] = 0.0; //h, kCa
	 gate_inf[0][5][nn] = Xinf(V[nn],12.3,-11.8); //m, Kd
	 gate_inf[1][5][nn] = 0.0; //h, Kd	
	 gate_inf[0][6][nn] = Xinf(V[nn],70.0,6.0); //m, H
	 gate_inf[1][6][nn] = 0.0; //h, H
       }
      //graded synapses
      /*
      S_inf[1] = Xinf(V[0],V_half,V_slope);
      S_inf[0] = Xinf(V[1],V_half,V_slope);
      */
      
      //old synapses, non-differentiable
      if (V[0]>V_half)
       {
	 S_inf[1] = tanh((V[0]-V_half)/V_slope);
       }
     else
       {
	 S_inf[1] = 0;
       }
     //V_pre = V[1]
     if (V[1]>V_half)
       {
	 S_inf[0] = tanh((V[1]-V_half)/V_slope);
       }
     else
       {
	 S_inf[0] = 0;
       }		

    for (nn=0;nn<2;nn++)
       {       
	 //evolve Svar
	 //Svar[nn] = Svar[nn] + (1-exp(-dt/tau_syn))*(S_inf[nn] - Svar[nn]);
	 //old from Grashow papers: "weird" function
	 Svar[nn] = Svar[nn] + (1-exp(-dt/(tau_syn*(1-S_inf[nn]))))*(S_inf[nn] - Svar[nn]);

	 //evolve the conductances, first order Euler
	 for (ii=0;ii<7;ii++)
	   {
	     gate[0][ii][nn] = gate[0][ii][nn] + (1-exp(-dt/tau[0][ii][nn]))*(gate_inf[0][ii][nn] - gate[0][ii][nn]);
	     gate[1][ii][nn] = gate[1][ii][nn] + (1-exp(-dt/tau[1][ii][nn]))*(gate_inf[1][ii][nn] - gate[1][ii][nn]);
	   }
	 //reset
	 gate[1][4][nn] = 1.0; //h, KCa
	 gate[1][5][nn] = 1.0; //h, Kd
	 gate[1][6][nn] = 1.0; //h, H
     
	 sum_g[nn] = g_L[nn] + g_syn[nn]*Svar[nn];
	 sum_Eg[nn] = g_L[nn]*E_L + g_syn[nn]*Svar[nn]*E_syn;
	 for (ii=0;ii<7;ii++)
	   {
	     gnmh[ii][nn] = g[ii][nn]*get_power(gate[0][ii][nn],p[ii])*gate[1][ii][nn];
	     sum_g[nn] += gnmh[ii][nn];
	     sum_Eg[nn] += gnmh[ii][nn]*E[ii][nn];
	   }
	 I_Ca[nn] = (gnmh[1][nn] + gnmh[2][nn])*(V[nn]-E_Ca[nn]);
	 
	 tau_V[nn]  = C/sum_g[nn];  //Membrane time constant.
	 
	 // V_inf is steady-state voltage.
	 V_inf[nn] = (sum_Eg[nn] + s[nn])/sum_g[nn];
	 
	 //evolve the voltage using exponential Euler
	 V[nn] = V_inf[nn] + (V[nn]-V_inf[nn])*exp(-dt/tau_V[nn]);
       }
     
     
       if (current_time > 20000 && fmod(current_time,0.1)<dt)
       {
	 fprintf(Vfile1,"%f \n", V[0]);
	 fprintf(Vfile2,"%f \n", V[1]);
       }
     
   }
     
  //fclose(spfile1);
  //fclose(spfile2);
  fclose(Vfile1);
  fclose(Vfile2);
 
 return 0;
}
Beispiel #16
0
    void main() {
        R = SqrRoot(m);
        int cnt = 0;
        for (long i = 1; m / i > R; ++i)
            basis[++cnt] = m / i;
        for (int i = R; i; --i)
            basis[++cnt] = i;
        // for (int i = 1; i <= cnt; ++i) {
        //     if (get_index(basis[i]) != i)
        //         print("!!! {} {}\n", get_index(basis[i]), i);
        // }

        for (int i = 1; i <= cnt; ++i) {
            num_primes[i] = basis[i] - 1;
        }
        // for (int i = 1; i < cnt; ++i) {
        //     for (int v = basis[i + 1] + 1; v <= basis[i]; ++v)
        //         if (v > R && ProbPrime(v))
        //             f[basis[i]] += 2;
        // }
        // f[1] = 1;
        // for (int i = cnt - 1; i; --i) {
        //     f[basis[i]] += f[basis[i + 1]];
        //     // print("init {} = {}\n", basis[i], f[basis[i]]);
        // }

        // long ans = 0;
        // for (int i = 1; i <= m; ++i) {
        //     ans += m / i;
        // }
        // print("bf = {}\n", ans);
        for (long x = 2; x <= R; ++x) {
            if (ProbPrime(x)) {
                print("current = {}\n", x);
                for (int i = 1; i <= cnt; ++i) {
                    long y = basis[i];
                    if (x * x > y)
                        break;
                    auto a = num_primes[get_index(y / x)];
                    auto b = num_primes[get_index(x - 1)];
                    num_primes[i] -= a - b;
                }
            }
        }
        for (int i = 1; i <= cnt; ++i) {
            num_primes[i] %= MOD;
            // print("{} {}\n", basis[i], num_primes[i]);
        }
        for (int i = 1; i <= cnt; ++i) {
            f[i] = 1;
            // if (basis[i] >= R) {
            //     f[i] += 2 * (num_primes[get_index(basis[i])] - num_primes[R]);
            // }
            // print("init {} {}\n", basis[i], f[i]);
        }

        for (long p = R; p; --p) {
            if (ProbPrime(p)) {
                print("current = {}\n", p);

                int t = p > n ? 0 : get_power(p, n);
                for (int e = 0; e <= 60; ++e)
                    g[e] = (e + 1) * (t + 1) + t * (t + 1) / 2;

                for (int i = 1; i <= cnt; ++i) {
                    long y = basis[i];
                    if (t == 0 && p * p > y)
                        break;
                    long v = 0; // 2 * (num_primes[get_index(y)] - num_primes[p]);
                    for (int e = 0; y; ++e) {
                        v += real_f(y, p) * g[e] % MOD;
                        y /= p;
                    }
                    if (basis[i] >= p)
                        v -= 2 * (num_primes[i] - num_primes[get_index(p)] + 1) % MOD;
                    f[i] = (v + MOD) % MOD;
                    // print("update {} = {}\n", basis[i], v);
                }
            }
        }
        print("ans = {}\n", real_f(m, 1));
    }
int main(int argc, char *argv[])
{
  double mean = atof(argv[1]);
  double sigma = atof(argv[2]);
  //for cell 1
  double g_Na1 = atof(argv[3]); //uS/nF 
  double g_CaT1 = atof(argv[4])-0.5;
  double g_CaS1 = atof(argv[5])-0.5; 
  double g_A1 = atof(argv[6]);
  double g_KCa1 = atof(argv[7])+1000.0;
  double g_K1 = atof(argv[8]);
  double g_H1 = atof(argv[9]);
  double g_L1 = atof(argv[10]);; //uS/nF  
  //for cell 2
  double g_Na2 = atof(argv[11]); //uS/nF 
  double g_CaT2 = atof(argv[12])-0.5;
  double g_CaS2 = atof(argv[13])-0.5; 
  double g_A2 = atof(argv[14]);
  double g_KCa2 = atof(argv[15])+1000.0;
  double g_K2 = atof(argv[16]);
  double g_H2 = atof(argv[17]);
  double g_L2 = atof(argv[18]);; //uS/nF  
  //synaptic
  double g_syn1 =  atof(argv[19]);
  double g_syn2 =  atof(argv[20]);
  //
  double corr_coef = atof(argv[21]); //correlation coefficient of the input
  double tau_c = atof(argv[22]); //correlation time const
  int num_run = atof(argv[23]);

  //don't use, use voltage derivative
  double V_th = -15; //mV, threshold for detecting spikes

  /*open files where spikes will be recorded*/
  char sp_file1 [999];
  sprintf (sp_file1, "spikes1_mean_%g_sig_%g_gNa_%g_gCaT_%g_gCaS_%g_gA_%g_gKCa_%g_gK_%g_gH_%g_gL_%g_gsyn_%g_%g_corr_%g_tc_%g_dt_%g_num_%d.dat", mean, sigma, g_Na1, g_CaT1, g_CaS1, g_A1, g_KCa1, g_K1, g_H1, g_L1, g_syn1, g_syn2, corr_coef,tau_c, dt, num_run);
  FILE *spfile1;
  spfile1 = fopen(sp_file1,"w");
  //
  char sp_file2 [999];
  sprintf (sp_file2, "spikes2_mean_%g_sig_%g_gNa_%g_gCaT_%g_gCaS_%g_gA_%g_gKCa_%g_gK_%g_gH_%g_gL_%g_gsyn_%g_%g_corr_%g_tc_%g_dt_%g_num_%d.dat", mean, sigma, g_Na2, g_CaT2, g_CaS2, g_A2, g_KCa2, g_K2, g_H2, g_L2, g_syn1, g_syn2, corr_coef,tau_c, dt, num_run);
  FILE *spfile2;
  spfile2 = fopen(sp_file2,"w");

  /*
  char V_file1 [999];
  sprintf (V_file1, "V1_mean_%g_sig_%g_gNa_%g_gCaT_%g_gCaS_%g_gA_%g_gKCa_%g_gK_%g_gH_%g_gL_%g_gsyn_%g_%g_corr_%g_tc_%g_dt_%g_num_%d.dat", mean, sigma, g_Na1, g_CaT1, g_CaS1, g_A1, g_KCa1, g_K1, g_H1, g_L1, g_syn1, g_syn2, corr_coef,tau_c, dt, num_run);
  FILE *Vfile1;
  Vfile1 = fopen(V_file1,"w");
  //
  char V_file2 [999];
  sprintf (V_file2, "V2_mean_%g_sig_%g_gNa_%g_gCaT_%g_gCaS_%g_gA_%g_gKCa_%g_gK_%g_gH_%g_gL_%g_gsyn_%g_%g_corr_%g_tc_%g_dt_%g_num_%d.dat", mean, sigma, g_Na2, g_CaT2, g_CaS2, g_A2, g_KCa2, g_K2, g_H2, g_L2, g_syn1, g_syn2, corr_coef,tau_c, dt, num_run);
  FILE *Vfile2;
  Vfile2 = fopen(V_file2,"w");
  */
  
   /*For random number generation:*/
  gsl_rng * r;
  r = gsl_rng_alloc (gsl_rng_default);
  gsl_rng_set(r, time(NULL));
  /*done*/

  int ii, jj, nn;

  /* Defining the model
     gate = [ m h ][4]   gating variables for the four conductances
     g = [ g_Na g_CaT g_CaS g_A g_KCa g_K g_H g_leak ]    maximal conductances
     E = [ E_Na E_CaT E_CaS E_A E_KCa E_K E_H E_leak ]    Nernst (reversal) potentials 
     gmh = [ conductances as a function of time ]
  */
  
  //reversal potentials
  double E_Na = 50; //mV or 30?
  double E_A = -80; //mV
  double E_K = -80; //mV
  double E_H = -20; //mV
  double E_Ca[2]; E_Ca[0] = 120; E_Ca[1] = 120; //mV default, but will vary
  double E_L = -50; //mV
  double C = 1; //nF 
  double tau_Ca = 20; //ms
  double I_Ca[2]; I_Ca[0] = 0; I_Ca[1] = 0;
  //synaptic
  double E_syn = -80; //mV
  double tau_syn = 100; //ms
  double V_half = -45; //mV
  double V_slope = 5; //mV

  /*Initial conditions*/
  double V[2];
  V[0] = -46.8; //mV
  V[1] = -50;
  double Ca[2]; Ca[0] = 0.2; Ca[1] = 0.2;
  double Ca_inf[2]; Ca_inf[0] = 0.2; Ca_inf[1] = 0.2;
  double g[7][2];
  double gate[2][7][2];
  double tau[2][7][2];
  double gate_inf[2][7][2];
  double E[7][2];
  int p[7];
  double gnmh[7][2];
  for (nn=0;nn<2;nn++)
    {
      for (ii=0;ii<7;ii++)
	{
	  gate[0][ii][nn] = 0.02; //m
	  gate[1][ii][nn] = 0.7; //h
	  gnmh[ii][nn] = 0.0;
	} 
    }
  E[0][0] = E_Na; E[0][1] = E_Na;
  E[1][0] = E_Ca[0]; E[1][1] = E_Ca[1]; 
  E[2][0] = E_Ca[0]; E[2][1] = E_Ca[1];
  E[3][0] = E_A;  E[3][1] = E_A;
  E[4][0] = E_K;  E[4][1] = E_K; 
  E[5][0] = E_K;  E[5][1] = E_K;
  E[6][0] = E_H;  E[6][1] = E_H;
  //
  p[0] = p_Na;
  p[1] = p_CaT;
  p[2] = p_CaS;
  p[3] = p_A;
  p[4] = p_KCa;
  p[5] = p_K;
  p[6] = p_H; 
  
  g[0][0] = g_Na1;   g[0][1] = g_Na2;
  g[1][0] = g_CaT1;  g[1][1] = g_CaT2;
  g[2][0] = g_CaS1;  g[2][1] = g_CaS2;
  g[3][0] = g_A1;    g[3][1] = g_A2;
  g[4][0] = g_KCa1;  g[4][1] = g_KCa2;
  g[5][0] = g_K1;    g[5][1] = g_K2;
  g[6][0] = g_H1;    g[6][1] = g_H2;

  double g_L[2]; g_L[0] = g_L1; g_L[1] = g_L2;
  double current_time = 0.0;
  double s_c = mean;
  double s_1 = mean;
  double s_2 = mean;
  double s[2]; 
  double Svar[2]; Svar[0] = 0; Svar[1] = 0;
  double S_inf[2]; S_inf[0] = 0; S_inf[1] = 0;
  double g_syn[2]; g_syn[0] = g_syn1; g_syn[1] = g_syn2;
  int counter = 0;

  int voltage_high1 = 0;
  double spike1 = 0.0; //to impose an absolute refractory period when reading spikes
  int voltage_high2 = 0;
  double spike2 = 0.0; //to impose an absolute refractory period when reading spikes
  double rand_g1 = 0.0;
  double rand_g2 = 0.0;
  double rand_g3 = 0.0;

  double ds = 0.0;
  //  double I_ion[2];   I_ion[0] = 0.0;     I_ion[1] = 0.0;
 
  double sum_g[2], sum_Eg[2], tau_V[2], V_inf[2];
  while (current_time < total_time)
   {       
     current_time += dt;
     counter ++;

     //s = mean + sigma/sqrt(dt)*rand_g; //if white noise

     //common input
     rand_g1 = gsl_ran_gaussian (r,1.0);
     //if correlated noise with correlation time constant tau_c
     ds = (mean-s_c)*(1-exp(-dt/tau_c)) + sigma*sqrt(1-exp(-2*dt/tau_c))*rand_g1; 
     s_c += ds;
     //independent input cell 1
     rand_g2 = gsl_ran_gaussian (r,1.0);
     ds = (mean-s_1)*(1-exp(-dt/tau_c)) + sigma*sqrt(1-exp(-2*dt/tau_c))*rand_g2; 
     s_1 += ds;
     //independent input cell 2
     rand_g3 = gsl_ran_gaussian (r,1.0);
     ds = (mean-s_2)*(1-exp(-dt/tau_c)) + sigma*sqrt(1-exp(-2*dt/tau_c))*rand_g3; 
     s_2 += ds;

     s[0] = s_1*(1-corr_coef) + s_c*corr_coef; //input to cell 1
     s[1] = s_2*(1-corr_coef) + s_c*corr_coef; //input to cell 2

     /*
       Model equations:
       C dv/dt = s - I_ion
       I_ion = sum( gate.*(V-E) )
       d gate/dt = -1/tau(v).*(gate-gate_0(v))
     */

     for (nn=0;nn<2;nn++)
       {
	 E_Ca[nn] = 500.0*R_F*(T + 273.15)*log(3000.0/Ca[nn]);
	 E[1][nn] = E_Ca[nn];
	 E[2][nn] = E_Ca[nn];
	 
	 Ca_inf[nn] = 0.05 + 0.94*I_Ca[nn];    
	 // integrate Ca dynamics 
	 Ca[nn] = Ca[nn] + (1-exp(-dt/tau_Ca))*(Ca_inf[nn] - Ca[nn]);
	 
	 tau[0][0][nn] = 1.32 - 1.26/(1.0+exp((V[nn]+120.0)/(-25.0))); //m, Na
	 tau[1][0][nn] = 0.67/(1+exp((V[nn]+62.9)/(-10.0)))*(1.5+1.0/(1.0+exp((V[nn]+34.9)/3.6))); //h, Na
	 tau[0][1][nn] = 21.7 - 21.3/(1.0 + exp((V[nn]+68.1)/(-20.5))); //m, CaT
	 tau[1][1][nn] = 105.0 - 89.8/(1.0 + exp((V[nn]+55.0)/(-16.9))); //h, CaT
	 tau[0][2][nn] = 1.4 + 7.0/(exp((V[nn]+27.0)/10.0) + exp((V[nn]+70.0)/(-13.0))); //m, CaS
	 tau[1][2][nn] = 60.0 + 150.0/(exp((V[nn]+55.0)/9.0) + exp((V[nn]+65.0)/(-16.0))); //h, CaS
	 tau[0][3][nn] = 11.6 - 10.4/(1.0+exp((V[nn]+32.9)/(-15.2))); //m, A
	 tau[1][3][nn] = 38.6 - 29.2/(1.0+exp((V[nn]+38.9)/(-26.5))); //h, A
	 tau[0][4][nn] = 90.3 - 75.1/(1.0+exp((V[nn]+46.0)/(-22.7))); //m, KCa
	 tau[1][4][nn] = 0.0; //h, kCa
	 tau[0][5][nn] = 7.2 - 6.4/(1+exp((V[nn]+28.3)/(-19.2))); //m, Kd
	 tau[1][5][nn] = 0.0; //h, Kd	
	 tau[0][6][nn] = 272.0 + 1499.0/(1.0+exp((V[nn]+42.2)/(-8.73))); //m, H
	 tau[1][6][nn] = 0.0; //h, H

	 gate_inf[0][0][nn] = 1.0/(1.0+exp((V[nn]+25.5)/(-5.29))); //m, Na
	 gate_inf[1][0][nn] = 1.0/(1.0+exp((V[nn]+48.9)/5.18)); //h, Na
	 gate_inf[0][1][nn] = 1.0/(1.0 + exp((V[nn]+27.1)/(-7.2))); //m, CaT
	 gate_inf[1][1][nn] = 1.0/(1.0 + exp((V[nn]+32.1)/5.5)); //h, CaT
	 gate_inf[0][2][nn] = 1.0/(1.0+exp((V[nn]+33.0)/-8.1)); //m, CaS
	 gate_inf[1][2][nn] = 1.0/(1.0+exp((V[nn]+60.0)/6.2)); //h, CaT
	 gate_inf[0][3][nn] = 1.0/(1.0+exp((V[nn]+27.2)/(-8.7))); //m, A
	 gate_inf[1][3][nn] = 1.0/(1.0+exp((V[nn]+56.9)/4.9)); //h, A
	 gate_inf[0][4][nn] = (Ca[nn]/(Ca[nn]+3.0))/(1.0+exp((V[nn]+28.3)/-12.6)); //m, kCa
	 gate_inf[1][4][nn] = 0.0; //h, kCa
	 gate_inf[0][5][nn] = 1.0/(1.0+exp((V[nn]+12.3)/(-11.8))); //m, Kd
	 gate_inf[1][5][nn] = 0.0; //h, Kd	
	 gate_inf[0][6][nn] = 1.0/(1.0+exp((V[nn]+70.0)/6.0)); //m, H
	 gate_inf[1][6][nn] = 0.0; //h, H
       }
     //V_pre = V[0]
     if (V[0]>V_half)
       {
	 S_inf[1] = tanh((V[0]-V_half)/V_slope);
       }
     else
       {
	 S_inf[1] = 0;
       }
     //V_pre = V[1]
     if (V[1]>V_half)
       {
	 S_inf[0] = tanh((V[1]-V_half)/V_slope);
       }
     else
       {
	 S_inf[0] = 0;
       }			

     for (nn=0;nn<2;nn++)
       {       
	 //evolve Svar
	 Svar[nn] = Svar[nn] + (1-exp(-dt/(tau_syn*(1-S_inf[nn]))))*(S_inf[nn] - Svar[nn]);

	 //evolve the conductances, first order Euler
	 for (ii=0;ii<7;ii++)
	   {
	     gate[0][ii][nn] = gate[0][ii][nn] + (1-exp(-dt/tau[0][ii][nn]))*(gate_inf[0][ii][nn] - gate[0][ii][nn]);
	     gate[1][ii][nn] = gate[1][ii][nn] + (1-exp(-dt/tau[1][ii][nn]))*(gate_inf[1][ii][nn] - gate[1][ii][nn]);
	   }
	 //reset
	 gate[1][4][nn] = 1.0; //h, KCa
	 gate[1][5][nn] = 1.0; //h, Kd
	 gate[1][6][nn] = 1.0; //h, H
     
	 sum_g[nn] = g_L[nn] + g_syn[nn]*Svar[nn];
	 sum_Eg[nn] = g_L[nn]*E_L + g_syn[nn]*Svar[nn]*E_syn;
	 for (ii=0;ii<7;ii++)
	   {
	     gnmh[ii][nn] = g[ii][nn]*get_power(gate[0][ii][nn],p[ii])*gate[1][ii][nn];
	     sum_g[nn] += gnmh[ii][nn];
	     sum_Eg[nn] += gnmh[ii][nn]*E[ii][nn];
	   }
	 I_Ca[nn] = (gnmh[1][nn] + gnmh[2][nn])*(E_Ca[nn]-V[nn]);

	 /*
	 I_ion[nn] = g_L*(V[nn]-E_L); //sum of all ionic currents
	 for (ii=0;ii<4; ii++)
	   {
	     I_ion[nn] += gnmh[ii][nn]*(V[nn]-E[ii]);
	   }
	 */
	 tau_V[nn]  = C/sum_g[nn];  //Membrane time constant.
	 
	 // V_inf is steady-state voltage.
	 V_inf[nn] = (sum_Eg[nn] + s[nn])*tau_V[nn];
	 
	 //evolve the voltage using exponential Euler
	 V[nn] = V_inf[nn] + (V[nn]-V_inf[nn])*exp(-dt/tau_V[nn]);
       }
     
     /*
       if (fmod(current_time,0.1)<dt)
       {
	 //printf("%g \n",current_time);
	 fprintf(Vfile1,"%f \n", V[0]);
	 fprintf(Vfile2,"%f \n", V[1]);
       }
     */
     
     //find out if there's a spike and record it
     if (V[0] > V_th  & current_time>5000)
       {
	 //if a high threshold was detected, record the spike
	 if (voltage_high1 == 0 && current_time-spike1>5) //5 is tau_abs
	   {
	     fprintf(spfile1,"%f \n", current_time);
	     spike1 = current_time;
	   }
	 
	 //if the high threshold was continuous (after spike has occured)
	 //then wait for it to cross the threshold again before recording
	 voltage_high1 ++;
       }
     else
       {
	 if (voltage_high1 > 0)
	   {
	     voltage_high1 = 0; //reset
	   }
       }

     //same for cell 2
     if (V[1] > V_th  & current_time>5000)
       {
	 //if a high threshold was detected, record the spike
	 if (voltage_high2 == 0 && current_time-spike2>5) //5 is tau_abs
	   {
	     fprintf(spfile2,"%f \n", current_time);
	     spike2 = current_time;
	   }
	 
	 //if the high threshold was continuous (after spike has occured)
	 //then wait for it to cross the threshold again before recording
	 voltage_high2 ++;
       }
     else
       {
	 if (voltage_high2 > 0)
	   {
	     voltage_high2 = 0; //reset
	   }
       }
    
   }
     
  fclose(spfile1);
  fclose(spfile2);
  //fclose(Vfile1);
  //fclose(Vfile2);
 
 return 0;
}
void
do_residence (int x, int y)
{
    /*
      // int_1 is a job swingometer to choose +/- JOB_SWING% of normal
      // int_2 is the date of the last starve
      // int 3 is the real time for the next icon update
      // int_4 is the birth rate modifier.
      // int_5 is the death rate modifier.
      */
    int p;                           /* population */
    int bad = 35, good = 30;         /* (un)desirability of living here */
    int r, po, swing;
    int hc = 0;                      /* have health cover ? */
    int brm = 0, drm = 0;            /* birth/death rate modifier */
    int cc = 0;

    p = MP_INFO(x,y).population;
    if ((MP_INFO(x,y).flags & FLAG_HEALTH_COVER) != 0)
    {
	brm += RESIDENCE_BRM_HEALTH;
	good += 15;
	hc = 1;
    }
    if ((MP_INFO(x,y).flags & FLAG_FIRE_COVER) == 0)
	bad += 5;
    else
	good += 15;
    if ((MP_INFO(x,y).flags & FLAG_CRICKET_COVER) != 0)
    {
	good += 20;
	cc = CRICKET_JOB_SWING;
    }
    /* normal deaths + pollution deaths */
    po = ((MP_POL(x,y) / 50) + 1);
    if ((RESIDENCE_BASE_DR - MP_INFO(x,y).int_5 - po) > 1)
	r = rand () % (RESIDENCE_BASE_DR - MP_INFO(x,y).int_5 - po);
    else
	r = 2;
    if (p > 0 && (r < po))
    {
	if (r == 0 || hc == 0)
	    p--;
	else if (hc != 0 && po > 10 && rand () % 4 == 0)
	{
	    p--;
	    unnat_deaths++;
	    total_pollution_deaths++;
	    pollution_deaths_history += 1.0;
	    bad += 100;
	}
	if (r > 0 && hc == 0)
	{
	    unnat_deaths++;
	    total_pollution_deaths++;
	    pollution_deaths_history += 1.0;
	    bad += 100;
	}
    }
    /* normal births - must have food and jobs... and people */
    if ((MP_INFO(x,y).flags & (FLAG_FED + FLAG_EMPLOYED))
	== (FLAG_FED + FLAG_EMPLOYED)
	&& (rand () % (RESIDENCE_BASE_BR + MP_INFO(x,y).int_4) == 1) 
	&& p > 0)
    {
	p++;
	total_births++;
	good += 50;
    }
    /* are people starving. */
    if ((MP_INFO(x,y).flags & FLAG_FED) == 0 && p > 0)
    {
	if (rand () % DAYS_PER_STARVE == 1)
	{
	    p--;
	    unnat_deaths++;
	    total_starve_deaths++;
	    starve_deaths_history += 1.0;
	}
	starving_population += p;
	bad += 250;
	drm += 100;
	MP_INFO(x,y).int_2 = total_time;	/* for the starve screen */
    }
    /* kick one out if overpopulated */
    if (MP_TYPE(x,y) == CST_RESIDENCE_LL)
    {
	brm += RESIDENCE1_BRM;
	drm += p * 8;
	if (p > 50)
	{
	    p--;
	    people_pool++;
	    brm += 20;
	}
    }
    else if (MP_TYPE(x,y) == CST_RESIDENCE_ML)
    {
	brm += RESIDENCE2_BRM;
	drm += p * 3;
	if (p > 100)
	{
	    p--;
	    people_pool++;
	    brm += 10;
	}
    }
    else if (MP_TYPE(x,y) == CST_RESIDENCE_HL)
    {
	brm += RESIDENCE3_BRM;
	drm += p;
	good += 40;
	if (p > 200)
	{
	    p--;
	    people_pool++;
	    brm += 10;
	}
    }
    else if (MP_TYPE(x,y) == CST_RESIDENCE_LH)
    {
	brm += RESIDENCE4_BRM;
	drm += p * 5;
	if (p > 100)
	{
	    p--;
	    people_pool++;
	    brm += 20;
	}
    }
    else if (MP_TYPE(x,y) == CST_RESIDENCE_MH)
    {
	brm += RESIDENCE5_BRM;
	drm += p / 2;
	if (p > 200)
	{
	    p--;
	    people_pool++;
	    brm += 10;
	}
    }
    else if (MP_TYPE(x,y) == CST_RESIDENCE_HH)
    {
	good += 100;
	brm += RESIDENCE6_BRM;
	drm += p;
	if (p > 400)
	{
	    p--;
	    people_pool++;
	    brm += 10;
	}
    }

    population += p;

    /* now get power */
    if (get_power (x, y, POWER_RES_OVERHEAD
		   + (POWER_USE_PER_PERSON * p), 0) != 0)
    {
	MP_INFO(x,y).flags |= FLAG_POWERED;
	MP_INFO(x,y).flags |= FLAG_HAD_POWER;
	good += 10;
    }
    else
    {
	MP_INFO(x,y).flags &= (0xffffffff - FLAG_POWERED);
	bad += 15;
	if ((MP_INFO(x,y).flags & FLAG_HAD_POWER) != 0)
	    bad += 50;
    }
    /* now get fed */
    if (get_food (x, y, p) != 0)
    {
	MP_INFO(x,y).flags |= FLAG_FED;
	good += 10;
    }
    else
	MP_INFO(x,y).flags &= (0xffffffff - FLAG_FED);
    /* now supply jobs and buy goods if employed */
    if (MP_INFO(x,y).int_1 > 0)
	swing = JOB_SWING + (hc * HC_JOB_SWING) + cc;
    else
	swing = -(JOB_SWING + (hc * HC_JOB_SWING) + cc);
    if (put_jobs (x, y, ((p * (WORKING_POP_PERCENT + swing)) / 100)) != 0)
    {
	MP_INFO(x,y).flags |= FLAG_EMPLOYED;
	MP_INFO(x,y).int_1++;
	if (MP_INFO(x,y).int_1 > 10)
	    MP_INFO(x,y).int_1 = 10;
	good += 20;
	if (get_goods (x, y, p / 4) != 0)
	{
	    good += 10;
	    if (get_power (x, y, p / 2, 0) != 0)	/* goods use power */

	    {
		good += 5;
		brm += 10;
		/*     buy more goods if got power for them */
		if (get_goods (x, y, p / 4) != 0)
		    good += 5;
	    }
	    else
		bad += 5;
	}
    }
    else if (MP_INFO(x,y).int_1 < 10)
    {
	MP_INFO(x,y).flags &= (0xffffffff - FLAG_EMPLOYED);
	MP_INFO(x,y).int_1 -= 11;
	if (MP_INFO(x,y).int_1 < -300)
	    MP_INFO(x,y).int_1 = -300;
	unemployed_population += p;
	total_unemployed_days += p;
	if (total_unemployed_days >= NUMOF_DAYS_IN_YEAR)
	{
	    total_unemployed_years++;
	    /* think we're ok doing this, max of about 120 added each time. */
	    total_unemployed_days -= NUMOF_DAYS_IN_YEAR;
	    unemployed_history += 1.0;
	}
	unemployment_cost += p;	/* hmmm */

	bad += 70;
    }
    else
    {
	MP_INFO(x,y).int_1 -= 20;
	bad += 50;
    }
    drm += p / 4;
    /* people_pool stuff */
    bad += p / 2;
    bad += MP_POL(x,y) / 20;
    good += people_pool / 27;
    r = rand () % ((good + bad) * RESIDENCE_PPM);
    if (r < bad)
    {
	if (p > MIN_RES_POPULATION)
	{
	    p--;
	    people_pool++;
	}
    }
    else if (people_pool > 0 && r > ((good + bad) * (RESIDENCE_PPM - 1) + bad))
    {
	p++;
	people_pool--;
    }
    MP_INFO(x,y).population = p;
    MP_INFO(x,y).int_4 = brm;
    MP_INFO(x,y).int_5 = drm;
}
void
do_recycle (int x, int y)
{
  int i;
  /*
     // int_1 is the ore made and waiting to go out
     // int_2 is the used goods in store
     // int_3 is the used steel in store       NOT USED at this time
     // int_4 is the tech level when built
     // int_5 is the recycling done so far this month
     // int_6 is the percent of max recycling last month
     // int_7 is the waste in store
     // cost
   */
  recycle_cost += RECYCLE_RUNNING_COST;

  /*
     // let these go through, even if we're full of waste. It's a waste of time
     // checking.
   */
  if (x > 0 && (MP_INFO(x - 1,y).flags & FLAG_IS_TRANSPORT) != 0)
    {
      i = MP_INFO(x - 1,y).int_7;
      if (i > MAX_WASTE_AT_RECYCLE - MP_INFO(x,y).int_2)
	i = MAX_WASTE_AT_RECYCLE - MP_INFO(x,y).int_2;
      MP_INFO(x,y).int_2 += i;
      MP_INFO(x - 1,y).int_7 -= i;
    }
  if (y > 0 && (MP_INFO(x,y - 1).flags & FLAG_IS_TRANSPORT) != 0)
    {
      i = MP_INFO(x,y - 1).int_7;
      if (i > MAX_WASTE_AT_RECYCLE - MP_INFO(x,y).int_2)
	i = MAX_WASTE_AT_RECYCLE - MP_INFO(x,y).int_2;
      MP_INFO(x,y).int_2 += i;
      MP_INFO(x,y - 1).int_7 -= i;
    }

  /* get some startup power if not powered yet */
  if ((MP_INFO(x,y).flags & FLAG_POWERED) == 0)
    if (get_power (x, y, GOODS_RECYCLED, 1) != 0)
      MP_INFO(x,y).flags |= FLAG_POWERED;

  /* no steel recycling yet - no point, it's only used to make goods.
     // recycle to ore.
   */
  if (MP_INFO(x,y).int_1 < MAX_ORE_AT_RECYCLE
      && MP_INFO(x,y).int_2 > GOODS_RECYCLED
      && (MP_INFO(x,y).flags & FLAG_POWERED) != 0)
    if (get_jobs (x, y, RECYCLE_GOODS_JOBS) != 0)
      {
	if (get_power (x, y, GOODS_RECYCLED / 2, 1) == 0)
	  MP_INFO(x,y).flags
	    &= (0xffffffff - FLAG_POWERED);
	else
	  MP_INFO(x,y).flags |= FLAG_POWERED;
	MP_INFO(x,y).int_2 -= GOODS_RECYCLED;
	i = (GOODS_RECYCLED * (10 + ((50 * MP_INFO(x,y).int_4)
				     / MAX_TECH_LEVEL))) / 100;
	if (i > (GOODS_RECYCLED * 8) / 10)
	  i = (GOODS_RECYCLED * 8) / 10;
	MP_INFO(x,y).int_1 += i;
	ore_made += i;
	MP_INFO(x,y).int_5++;
      }
  if (total_time % 100 == 0)
    {
      MP_INFO(x,y).int_6 = MP_INFO(x,y).int_5;
      MP_INFO(x,y).int_5 = 0;
    }
  /* now bung the ore out */
  /* put it on the railway */
  if (x > 0 && MP_GROUP(x-1,y) == GROUP_RAIL
      && MP_INFO(x - 1,y).int_5 < MAX_ORE_ON_RAIL
      && MP_INFO(x,y).int_1 >= (MAX_ORE_ON_RAIL
				  - MP_INFO(x - 1,y).int_5))
    {
      if (get_jobs (x, y, JOBS_LOAD_ORE) != 0)
	{
	  MP_INFO(x,y).int_1
	    -= (MAX_ORE_ON_RAIL - MP_INFO(x - 1,y).int_5);
	  MP_INFO(x - 1,y).int_5 = MAX_ORE_ON_RAIL;
	}
    }
  if (y > 0 && MP_GROUP(x,y-1) == GROUP_RAIL
      && MP_INFO(x,y - 1).int_5 < MAX_ORE_ON_RAIL
      && MP_INFO(x,y).int_1 >= (MAX_ORE_ON_RAIL
				  - MP_INFO(x,y - 1).int_5))
    {
      if (get_jobs (x, y, JOBS_LOAD_ORE) != 0)
	{
	  MP_INFO(x,y).int_1
	    -= (MAX_ORE_ON_RAIL - MP_INFO(x,y - 1).int_5);
	  MP_INFO(x,y - 1).int_5 = MAX_ORE_ON_RAIL;
	}
    }
  /* put it on the road */
  if (x > 0 && MP_GROUP(x-1,y) == GROUP_ROAD
      && MP_INFO(x - 1,y).int_5 < MAX_ORE_ON_ROAD
      && MP_INFO(x,y).int_1 >= (MAX_ORE_ON_ROAD
				  - MP_INFO(x - 1,y).int_5))
    {
      if (get_jobs (x, y, JOBS_LOAD_ORE) != 0)
	{
	  MP_INFO(x,y).int_1
	    -= (MAX_ORE_ON_ROAD - MP_INFO(x - 1,y).int_5);
	  MP_INFO(x - 1,y).int_5 = MAX_ORE_ON_ROAD;
	}
    }
  if (y > 0 && MP_GROUP(x,y-1) == GROUP_ROAD
      && MP_INFO(x,y - 1).int_5 < MAX_ORE_ON_ROAD
      && MP_INFO(x,y).int_1 >= (MAX_ORE_ON_ROAD
				  - MP_INFO(x,y - 1).int_5))
    {
      if (get_jobs (x, y, JOBS_LOAD_ORE) != 0)
	{
	  MP_INFO(x,y).int_1
	    -= (MAX_ORE_ON_ROAD - MP_INFO(x,y - 1).int_5);
	  MP_INFO(x,y - 1).int_5 = MAX_ORE_ON_ROAD;
	}
    }
  /* put it on the tracks */
  if (x > 0 && MP_GROUP(x-1,y) == GROUP_TRACK
      && MP_INFO(x - 1,y).int_5 < MAX_ORE_ON_TRACK
      && MP_INFO(x,y).int_1 >= (MAX_ORE_ON_TRACK
				  - MP_INFO(x - 1,y).int_5))
    {
      if (get_jobs (x, y, JOBS_LOAD_ORE) != 0)
	{
	  MP_INFO(x,y).int_1
	    -= (MAX_ORE_ON_TRACK - MP_INFO(x - 1,y).int_5);
	  MP_INFO(x - 1,y).int_5 = MAX_ORE_ON_TRACK;
	}
    }
  if (y > 0 && MP_GROUP(x,y-1) == GROUP_TRACK
      && MP_INFO(x,y - 1).int_5 < MAX_ORE_ON_TRACK
      && MP_INFO(x,y).int_1 >= (MAX_ORE_ON_TRACK
				  - MP_INFO(x,y - 1).int_5))
    {
      if (get_jobs (x, y, JOBS_LOAD_ORE) != 0)
	{
	  MP_INFO(x,y).int_1
	    -= (MAX_ORE_ON_TRACK - MP_INFO(x,y - 1).int_5);
	  MP_INFO(x,y - 1).int_5 = MAX_ORE_ON_TRACK;
	}
    }
  /* if we've still got >90% ore and waste in stock, burn some waste cleanly. 
   */
  if (MP_INFO(x,y).int_1 > (MAX_ORE_AT_RECYCLE * 9 / 10)
      && MP_INFO(x,y).int_2 > (MAX_WASTE_AT_RECYCLE * 9 / 10))
    MP_INFO(x,y).int_2 -= BURN_WASTE_AT_RECYCLE;
}
void do_organic_farm(int x, int y)
{
    /* // MP_INFO(x,y)
       // int_1 unused
       // int_2 unused
       // int_3 is the food sold count so far this year.
       // int_4 is the food made last year.
       // int_5 is the random crop rotation key.
       // int_6 is the random month stagger, so they don't all flash at once
       // int_7 is the jobs stored at the farm 
       * 
       * MP_INFO(x+1,y) stores additional info
       *    int_1 reserved (=x)
       *    int_2 reserved (=y)
       *    int_3 max possible production (assuming 100% water and power)
       *    int_4 number of 1x1 tiles with underground water inside the farm
       *    int_5 current production
       *
       // MP_TECH is the tech level of the farm when built
       // MP_ANIM  FIXME, this is unused
     */
    int i;
    int has_power = false;
    int used_jobs = 0;
    int tech_bonus = (int)(((double)MP_TECH(x, y) * ORGANIC_FARM_FOOD_OUTPUT) / MAX_TECH_LEVEL);
    MP_INFO(x + 1, y).int_3 = ORGANIC_FARM_FOOD_OUTPUT + tech_bonus;

    /* Animation */
    if (MP_INFO(x, y).int_5 == 0) {
        /* this should be done when we create the area! */
        MP_INFO(x, y).int_5 = (rand() % 4) + 1;
        MP_INFO(x, y).int_6 = rand() % 300;     /* AL1 will be sooner or later redefined as %100. see below */
    }

    /* check jobs */
    if (MP_INFO(x, y).int_7 < FARM_JOBS_USED) {
        if (get_jobs(x, y, FARM_JOBS_USED) != 0)
            MP_INFO(x, y).int_7 += FARM_JOBS_USED;
        /* adding if (get_jobs ... /2) would allow to have some jobs stored at farm,
         * so would smooth the behavior and make farms more resistant to job penury.
         * Currently keep previous behavior.
         */
        else if (get_jobs(x, y, FARM_JOBS_USED / 4) != 0)
            MP_INFO(x, y).int_7 += FARM_JOBS_USED / 4;
        else if (get_jobs(x, y, 1) != 0)
            MP_INFO(x, y).int_7 += 1;
    }

    /* check power */
    MP_INFO(x, y).flags &= (0xffffffff - FLAG_POWERED);
    if (MP_INFO(x, y).int_7 >= 1) {
        /* There are jobs to do some production, so check for power */
        if (get_power(x, y, ORG_FARM_POWER_REC, 0) != 0) {
            MP_INFO(x, y).flags |= FLAG_POWERED;
            has_power = true;
        }
    }

    /* Produce some food */
    int prod = 0;
    if (MP_INFO(x, y).int_7 >= FARM_JOBS_USED) {
        used_jobs = FARM_JOBS_USED;
        if (has_power) {
            prod = ORGANIC_FARM_FOOD_OUTPUT + tech_bonus;
        } else {
            prod = ORGANIC_FARM_FOOD_OUTPUT / 4;
        }
    } else if (MP_INFO(x, y).int_7 >= FARM_JOBS_USED / 4) {
        used_jobs = FARM_JOBS_USED / 4;
        if (has_power) {
            prod = ORGANIC_FARM_FOOD_OUTPUT + tech_bonus / 4;
        } else {
            prod = ORGANIC_FARM_FOOD_OUTPUT / (4 * 4);
        }
    } else if (MP_INFO(x, y).int_7 >= 1) {
        /* got 1 job */
        used_jobs = 1;
        if (has_power) {
            prod = ORGANIC_FARM_FOOD_OUTPUT + tech_bonus / 8;
        } else {
            /* AL1 "small ouch":
             * without power output with 1 job is bigger than output with 3 !
             * 3 = FARMS_JOBS_USED / 4 
             * ORGANIC_FARM_FOOD_OUTPUT = 550 currently (ng_1.1)
             */
            prod = 30 + ORGANIC_FARM_FOOD_OUTPUT / (4 * 8);
        }
    } else {
        /* AL1 : the farm gives very small amount of food without job. 
         *  ? Probably needed for start ?
         *  ? Useful to prevent starvation when no jobs ? 
         *  The various buildings are "done" in random order,
         *  so it should be ok without this.
         */
        put_food(x, y, 30);
        /* note that this does not generate revenu int_3) */
    }
    /* Check underground water, and reduce production accordingly */
    if (use_waterwell) {
        // TODO No need to count each time. Should be done at build time, and stored 
        int w = 0;
        int n = 0;
        for (int i = 0; i < MP_SIZE(x, y); i++) {
            for (int j = 0; j < MP_SIZE(x, y); j++) {
                n++;
                if (HAS_UGWATER(x + i, y + j))
                    w++;
            }
        }
        prod = (prod * w) / n;
        MP_INFO(x + 1, y).int_4 = w;
    }
    MP_INFO(x + 1, y).int_5 = prod;

    if (prod != 0) {
        if (put_food(x, y, prod) != 0) {
            MP_INFO(x, y).int_3++;
            MP_INFO(x, y).int_7 -= used_jobs;
        }
    }

    if ((total_time & 0x7f) == 0)
        if ((MP_INFO(x, y).flags & FLAG_POWERED) != 0)
            get_waste(x, y, 0x80 * ORG_FARM_WASTE_GET);

    if ((total_time % 1200) == 0) {
        MP_INFO(x, y).int_4 = MP_INFO(x, y).int_3;
        MP_INFO(x, y).int_3 = 0;
    }

    i = (total_time + MP_INFO(x, y).int_5 * 1200 + MP_INFO(x, y).int_6) % 4800;

    if (i % 300 == 0) {
        i /= 300;
        if ( MP_INFO(x, y).int_4 > MIN_FOOD_SOLD_FOR_ANIM) {
            if (i % 4 == 0) {
                MP_INFO(x, y).int_6 = rand() % 100;     /* AL1: initially defined as %300 */
            }
            switch (i) {
            case (0):
                MP_TYPE(x, y) = CST_FARM_O3;
                break;
            case (1):
                MP_TYPE(x, y) = CST_FARM_O3;
                break;
            case (2):
                MP_TYPE(x, y) = CST_FARM_O3;
                break;
            case (3):
                MP_TYPE(x, y) = CST_FARM_O3;
                break;
            case (4):
                MP_TYPE(x, y) = CST_FARM_O7;
                break;
            case (5):
                MP_TYPE(x, y) = CST_FARM_O7;
                break;
            case (6):
                MP_TYPE(x, y) = CST_FARM_O7;
                break;
            case (7):
                MP_TYPE(x, y) = CST_FARM_O7;
                break;
            case (8):
                MP_TYPE(x, y) = CST_FARM_O11;
                break;
            case (9):
                MP_TYPE(x, y) = CST_FARM_O11;
                break;
            case (10):
                MP_TYPE(x, y) = CST_FARM_O11;
                break;
            case (11):
                MP_TYPE(x, y) = CST_FARM_O11;
                break;
            case (12):
                MP_TYPE(x, y) = CST_FARM_O15;
                break;
            case (13):
                MP_TYPE(x, y) = CST_FARM_O15;
                break;
            case (14):
                MP_TYPE(x, y) = CST_FARM_O15;
                break;
            case (15):
                MP_TYPE(x, y) = CST_FARM_O15;
                break;

            }
        } else {
            MP_TYPE(x, y) = CST_FARM_O0;
        }
    }
}