Exemple #1
0
/*
	exec_init
	A partir d'une chaine de caractere complexe, on decompose les differentes commandes
	On les decoupe par rapport a |, && et ||
	le N | M redirige la sortie du N sur l'entre du M
	le N || M execute M si !N
	le N && M execute M si N

	les sous commandes seront décomposé dans la pseudo classe 'cmd'
*/
Exec* exec_init(Meta* meta,char* exec){

	char* execCpy=(char*)malloc(sizeof(char)*(strlen(exec)+1));
	strcpy(execCpy,exec);

	int i=0;
	int length=strlen(execCpy);
	int nbCmd=1;
	/* On compte le nombre de commande */
	for(i=0;i<length;i++){
		if((execCpy[i]=='|' && execCpy[i+1]!='|' && execCpy[i-1]!='|') || (execCpy[i]=='&' && execCpy[i+1]=='&') || (execCpy[i]=='|' && execCpy[i+1]=='|') ){
			nbCmd++;
		}
	}
	char** tabCmdStr=(char**)leash_malloc(sizeof(char*)*nbCmd);
	int* link=(int*)leash_malloc(sizeof(int)*nbCmd);
	
	int next=0;
	tabCmdStr[0]=execCpy;
	int nb=0;
	for(i=0;i<length;i++){
		if(next){
			next=0;
			tabCmdStr[nb] = &execCpy[i];
		}else if(execCpy[i]=='|' && execCpy[i+1]!='|' && execCpy[i-1]!='|'){
			/* on a un pipe */
			execCpy[i]='\0';
			link[nb]=EXEC_PIPE;
			nb++;
			next=1;
		}else if(execCpy[i]=='&'){
			/* on a un && */
			if(i+1<length && execCpy[i+1]=='&'){
				next=1;
				execCpy[i]='\0';
				execCpy[i+1]='\0';
				link[nb]=EXEC_AND;
				nb++;
				i++;
			}
		}else if(execCpy[i]=='|'){
			/* on a un || */
			if(i+1<length && execCpy[i+1]=='|'){
				next=1;
				execCpy[i]='\0';
				execCpy[i+1]='\0';
				link[nb]=EXEC_OR;
				nb++;
				i++;
			}
		}

	}
	link[nb]=EXEC_NONE;

	Exec* execut=(Exec*)leash_malloc(sizeof(Exec));
	execut->fd_out=-1;
	execut->link=link;
	execut->nbCommands=nbCmd;

	execut->commands=(Cmd**)leash_malloc(sizeof(Cmd*)*nbCmd);
	for(i=0;i<nbCmd;i++){
		execut->commands[i]=NULL;
	}
	for(i=0;i<nbCmd;i++){
		Cmd* cmd = cmd_init(tabCmdStr[i]);
		if(meta_is_allowed(meta,cmd->nom) ||strcmp(cmd->nom,"about") == 0 /*||strcmp(cmd->nom,"cd") == 0*/  ){
			execut->commands[i]=cmd;
		}else{
			cmd_dest(cmd);
			exec_dest(execut);
			free(tabCmdStr);
			free(execCpy);
			return NULL;
		}
	}

	free(tabCmdStr);
	free(execCpy);

	return execut;

}
Exemple #2
0
int main(int argc, char **argv)
{
printf("\33[0;40;33m\n");	
printf("    FemtoForth  Copyright (C) 2014 Victor Yurkovsky\n");
printf("    This program comes with ABSOLUTELY NO WARRANTY'.\n");
printf("    This is free software, and you are welcome to redistribute it\n");
printf("    under certain conditions; type 'license' for details.\n\n");
color(COLOR_RESET);color(FORE_WHITE);
//---------------------------------------------------------------------
// Data segment.  Houses var at the bottom...  
//
        // memmap data segment
        U8* data_base = mmap((void*)0x04000000,
                 CODE_SIZE,
                 PROT_READ+PROT_WRITE+PROT_EXEC,
                 MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED,
                 0,0);
        //var structure is placed into bottom RESERVED (512) bytes of data!
        lay = (sMemLayout*)data_base;           // HOST_RESERVED bytes 
        var = (sVar*)(data_base+HOST_RESERVED); // SYS_RESERVED bytes 
        
        // install system var structure at bottom
        lay->data_bottom = data_base;
        lay->data_top = data_base + CODE_SIZE;
        //
        var->data_ptr = lay->data_bottom + HOST_RESERVED + SYS_RESERVED;

        printf("data at %p->%p ",lay->data_bottom,lay->data_top);

//---------------------------------------------------------------------
// Table - runtime 
//
        lay->table_bottom = mmap((U8**)(CODE_ADDRESS/4),
                 sizeof(TINDEX)*TABLE_SIZE,
                 PROT_READ+PROT_WRITE+PROT_EXEC,
                 MAP_ANONYMOUS|MAP_SHARED|MAP_FIXED,
                 0,0);
        printf("TABLE at %p ",lay->table_bottom);
        lay->table_top = (U8*)lay->table_bottom + sizeof(TINDEX)*TABLE_SIZE;
       // var->table_ptr = (U8**)var->table_bottom;
       // *var->table_ptr++ = 0 ; //first table entry is always 0 !
      
//---------------------------------------------------------------------
// DSP
//
// 
        lay->dsp_bottom = (U8*)malloc(DSP_SIZE);
        lay->dsp_top = lay->dsp_bottom + DSP_SIZE;
 printf("DSP at %p ",lay->dsp_top);
//---------------------------------------------------------------------
// RSP
        lay->rsp_bottom = (U8*)malloc(RSP_SIZE);
        lay->rsp_top = lay->rsp_bottom + RSP_SIZE;
        var->sp_meow = (sRegsMM*)lay->rsp_top;
 printf("RSP at %p ",lay->rsp_top);
//---------------------------------------------------------------------
// HEAD
        lay->head_bottom = (U8*)malloc(HEAD_SIZE);
        lay->head_top = lay->head_bottom + HEAD_SIZE;
        var->head_ptr = lay->head_bottom;
 printf("HEAD at %p \n",lay->head_bottom);
//---------------------------------------------------------------------
// SRC 
        lay->src_bottom =  (char*)malloc(256);
        src_reset(); 
      
        head_build();
     
//  printf("data pointer is now at %p\n",var->data_ptr);
        kernel_load();
//  printf("data pointer is now at %p\n",var->data_ptr);
  
        cmd_init();
        lang_init();

//        int i;
//for(i=0;i<20;i++)

      
// U32 qqq = xxx(0x3456,0x1234);
// printf("bindings returns %x\n",1);
    interpret_init();
// src_error("ass");
//  call_meow();
  
 
   while(1)
      interpret_outer();
 // line();
//        int z = armFunction(99);
//        printf("assembly returnst %d\n",z);       
        exit(0);
}
Exemple #3
0
// Initialize and start PSL thread
//
// The return value is encode int a 16-bit value divided into 4 for each
// possible adapter.  Then the 4 bits in each adapter represent the 4 possible
// AFUs on an adapter.  For example: afu0.0 is 0x8000 and afu3.0 is 0x0008.
uint16_t psl_init(struct psl **head, struct parms *parms, char *id, char *host,
		  int port, pthread_mutex_t * lock, FILE * dbg_fp)
{
	struct psl *psl;
	struct job_event *reset;
	uint16_t location;

	location = 0x8000;
	if ((psl = (struct psl *)calloc(1, sizeof(struct psl))) == NULL) {
		perror("malloc");
		error_msg("Unable to allocation memory for psl");
		goto init_fail;
	}
	psl->timeout = parms->timeout;
	if ((strlen(id) != 6) || strncmp(id, "afu", 3) || (id[4] != '.')) {
		warn_msg("Invalid afu name: %s", id);
		goto init_fail;
	}
	if ((id[3] < '0') || (id[3] > '3')) {
		warn_msg("Invalid afu major: %c", id[3]);
		goto init_fail;
	}
	if ((id[5] < '0') || (id[5] > '3')) {
		warn_msg("Invalid afu minor: %c", id[5]);
		goto init_fail;
	}
	psl->dbg_fp = dbg_fp;
	psl->major = id[3] - '0';
	psl->minor = id[5] - '0';
	psl->dbg_id = psl->major << 4;
	psl->dbg_id |= psl->minor;
	location >>= (4 * psl->major);
	location >>= psl->minor;
	if ((psl->name = (char *)malloc(strlen(id) + 1)) == NULL) {
		perror("malloc");
		error_msg("Unable to allocation memory for psl->name");
		goto init_fail;
	}
	strcpy(psl->name, id);
	if ((psl->host = (char *)malloc(strlen(host) + 1)) == NULL) {
		perror("malloc");
		error_msg("Unable to allocation memory for psl->host");
		goto init_fail;
	}
	strcpy(psl->host, host);
	psl->port = port;
	psl->client = NULL;
	psl->idle_cycles = PSL_IDLE_CYCLES;
	psl->lock = lock;

	// Connect to AFU
	psl->afu_event = (struct AFU_EVENT *)malloc(sizeof(struct AFU_EVENT));
	if (psl->afu_event == NULL) {
		perror("malloc");
		goto init_fail;
	}
	info_msg("Attempting to connect AFU: %s @ %s:%d", psl->name,
		 psl->host, psl->port);
	if (psl_init_afu_event(psl->afu_event, psl->host, psl->port) !=
	    PSL_SUCCESS) {
		warn_msg("Unable to connect AFU: %s @ %s:%d", psl->name,
			 psl->host, psl->port);
		goto init_fail;
	}
	// DEBUG
	debug_afu_connect(psl->dbg_fp, psl->dbg_id);

	// Initialize job handler
	if ((psl->job = job_init(psl->afu_event, &(psl->state), psl->dbg_fp,
				 psl->dbg_id)) == NULL) {
		perror("job_init");
		goto init_fail;
	}
	// Initialize mmio handler
	if ((psl->mmio = mmio_init(psl->afu_event, psl->timeout, psl->dbg_fp,
				   psl->dbg_id)) == NULL) {
		perror("mmio_init");
		goto init_fail;
	}
	// Initialize cmd handler
	if ((psl->cmd = cmd_init(psl->afu_event, parms, psl->mmio,
				 &(psl->state), psl->dbg_fp, psl->dbg_id))
	    == NULL) {
		perror("cmd_init");
		goto init_fail;
	}
	// Set credits for AFU
	if (psl_aux1_change(psl->afu_event, psl->cmd->credits) != PSL_SUCCESS) {
		warn_msg("Unable to set credits");
		goto init_fail;
	}
	// Start psl loop thread
	if (pthread_create(&(psl->thread), NULL, _psl_loop, psl)) {
		perror("pthread_create");
		goto init_fail;
	}
	// Add psl to list
	while ((*head != NULL) && ((*head)->major < psl->major)) {
		head = &((*head)->_next);
	}
	while ((*head != NULL) && ((*head)->major == psl->major) &&
	       ((*head)->minor < psl->minor)) {
		head = &((*head)->_next);
	}
	psl->_next = *head;
	if (psl->_next != NULL)
		psl->_next->_prev = psl;
	*head = psl;

	// Send reset to AFU
	reset = add_job(psl->job, PSL_JOB_RESET, 0L);
	while (psl->job->job == reset) {	/*infinite loop */
		lock_delay(psl->lock);
	}

	// Read AFU descriptor
	psl->state = PSLSE_DESC;
	read_descriptor(psl->mmio, psl->lock);

	// Finish PSL configuration
	psl->state = PSLSE_IDLE;
	if (dedicated_mode_support(psl->mmio)) {
		// AFU supports Dedicated Mode
		psl->max_clients = 1;
	}
	if (directed_mode_support(psl->mmio)) {
		// AFU supports Directed Mode
		psl->max_clients = psl->mmio->desc.num_of_processes;
	}
	if (psl->max_clients == 0) {
		error_msg("AFU programming model is invalid");
		goto init_fail;
	}
	psl->client = (struct client **)calloc(psl->max_clients,
					       sizeof(struct client *));
	psl->cmd->client = psl->client;
	psl->cmd->max_clients = psl->max_clients;

	return location;

 init_fail:
	if (psl) {
		if (psl->afu_event) {
			psl_close_afu_event(psl->afu_event);
			free(psl->afu_event);
		}
		if (psl->host)
			free(psl->host);
		if (psl->name)
			free(psl->name);
		free(psl);
	}
	pthread_mutex_unlock(lock);
	return 0;
}
Exemple #4
0
void main_init(int argc, char *argv[])
{
   bool override_hw = false;
   if (argc > 1)
   {
      if (strcmp(argv[1], "calibrate") == 0)
         calibrate = true;
      else
         override_hw = true;
   }

   /* init data structures: */
   memset(&pos_in, 0, sizeof(pos_in_t));
   vec3_init(&pos_in.acc);

   /* init SCL subsystem: */
   syslog(LOG_INFO, "initializing signaling and communication link (SCL)");
   if (scl_init("pilot") != 0)
   {
      syslog(LOG_CRIT, "could not init scl module");
      die();
   }
   
   /* init params subsystem: */
   syslog(LOG_INFO, "initializing opcd interface");
   opcd_params_init("pilot.", 1);
   
   /* initialize logger: */
   syslog(LOG_INFO, "opening logger");
   if (logger_open() != 0)
   {
      syslog(LOG_CRIT, "could not open logger");
      die();
   }
   syslog(LOG_CRIT, "logger opened");
   
   LOG(LL_INFO, "initializing platform");
   if (arcade_quad_init(&platform, override_hw) < 0)
   {
      LOG(LL_ERROR, "could not initialize platform");
      die();
   }
   acc_mag_cal_init();
   cmc_init();
 
   const size_t array_len = sizeof(float) * platform.n_motors;
   setpoints = malloc(array_len);
   ASSERT_NOT_NULL(setpoints);
   memset(setpoints, 0, array_len);
   rpm_square = malloc(array_len);
   ASSERT_NOT_NULL(rpm_square);
   memset(rpm_square, 0, array_len);

   LOG(LL_INFO, "initializing model/controller");
   pos_init();
   ne_speed_ctrl_init(REALTIME_PERIOD);
   att_ctrl_init();
   yaw_ctrl_init();
   u_ctrl_init();
   u_speed_init();
   navi_init();

   LOG(LL_INFO, "initializing command interface");
   cmd_init();

   motors_state_init();
   blackbox_init();

   /* init flight logic: */
   flight_logic_init();

   /* init calibration data: */
   cal_init(&gyro_cal, 3, 1000);

   cal_ahrs_init();
   flight_state_init(50, 150, 4.0);
   
   piid_init(REALTIME_PERIOD);

   interval_init(&gyro_move_interval);
   gps_data_init(&gps_data);

   mag_decl_init();
   cal_init(&rc_cal, 3, 500);

   tsfloat_t acc_fg;
   opcd_param_t params[] =
   {
      {"acc_fg", &acc_fg},
      OPCD_PARAMS_END
   };
   opcd_params_apply("main.", params);
   filter1_lp_init(&lp_filter, tsfloat_get(&acc_fg), 0.06, 3);

   cm_init();
   mon_init();
   LOG(LL_INFO, "entering main loop");
}
Exemple #5
0
/*
	Parses the incoming argv list.
	Arguments:
		argv, argc,
		cmd description 

	Action:
		performs a match for every p_option string in the CMD description.
		checks the number of arguments left
		calls the user handler with the pointer to the correct arguments

	Implementation:
		- for each option in the table
			- find it in the argv list
			- check the required number of arguments
			- call the handler
*/
RC_TYPE get_cmd_parse_data(char **argv, int argc, CMD_DESCRIPTION_TYPE *p_cmd_descr)
{
	RC_TYPE rc = RC_OK;
	CMD_DATA cmd;
	int curr_arg_nr = 1; /* without the prg name*/
	
	if (argv == NULL || p_cmd_descr == NULL)
	{
		return RC_INVALID_POINTER;
	}
	
	do
	{
		rc = cmd_init(&cmd);
		if (rc != RC_OK)
		{
			break;
		}
		rc = cmd_add_vals_from_argv(&cmd, argv, argc);
		if (rc != RC_OK)
		{
			break;
		}
	 	while(curr_arg_nr < cmd.argc)
		{
			CMD_DESCRIPTION_TYPE *p_curr_opt = opt_search(p_cmd_descr, cmd.argv[curr_arg_nr]);
	
			if (p_curr_opt == NULL)
			{
				rc = RC_CMD_PARSER_INVALID_OPTION;
	            DBG_PRINTF((LOG_WARNING,"W:" MODULE_TAG "Invalid option name at position %d ('%s')\n", 
	                        curr_arg_nr + 1, cmd.argv[curr_arg_nr]));
				break;
			}
	
			++curr_arg_nr;
		
			/*check arg nr required by the current option*/
			if (curr_arg_nr + p_curr_opt->arg_nr > cmd.argc)
			{
				rc = RC_CMD_PARSER_INVALID_OPTION_ARGUMENT;
	            DBG_PRINTF((LOG_WARNING,"W:" MODULE_TAG "Missing option value at position %d ('%s')\n", 
	                        curr_arg_nr + 1, p_curr_opt->p_option));
	            break;
			}
					
			rc = p_curr_opt->p_handler.p_func(&cmd, curr_arg_nr, p_curr_opt->p_handler.p_context);
			if (rc != RC_OK)
			{
	            DBG_PRINTF((LOG_WARNING,"W:" MODULE_TAG "Error parsing option %d ('%s')\n", 
	                        curr_arg_nr, cmd.argv[curr_arg_nr-1]));
				break;
			}
			
			curr_arg_nr += p_curr_opt->arg_nr;
		} 				
	}
	while(0);
	cmd_destruct(&cmd);
	return rc;
}
Exemple #6
0
/* Main startup routine. */
int
main (int argc, char **argv)
{
  char *p;
  char *vty_addr = NULL;
  int vty_port = ZEBRA_VTY_PORT;
  int batch_mode = 0;
  int daemon_mode = 0;
  char *config_file = NULL;
  char *progname;
  struct thread thread;
  void rib_weed_tables ();
  void zebra_vty_init ();

  /* Set umask before anything for security */
  umask (0027);

  /* preserve my name */
  progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);

  zlog_default = openzlog (progname, ZLOG_ZEBRA,
			   LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);

  while (1) 
    {
      int opt;
  
#ifdef HAVE_NETLINK  
      opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:g:vs:", longopts, 0);
#else
      opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:g:v", longopts, 0);
#endif /* HAVE_NETLINK */

      if (opt == EOF)
	break;

      switch (opt) 
	{
	case 0:
	  break;
	case 'b':
	  batch_mode = 1;
	case 'd':
	  daemon_mode = 1;
	  break;
	case 'k':
	  keep_kernel_mode = 1;
	  break;
	case 'l':
	  /* log_mode = 1; */
	  break;
	case 'f':
	  config_file = optarg;
	  break;
	case 'A':
	  vty_addr = optarg;
	  break;
        case 'i':
          pid_file = optarg;
          break;
	case 'P':
	  /* Deal with atoi() returning 0 on failure, and zebra not
	     listening on zebra port... */
	  if (strcmp(optarg, "0") == 0) 
	    {
	      vty_port = 0;
	      break;
	    } 
	  vty_port = atoi (optarg);
	  vty_port = (vty_port ? vty_port : ZEBRA_VTY_PORT);
	  break;
	case 'r':
	  retain_mode = 1;
	  break;
#ifdef HAVE_NETLINK
	case 's':
	  nl_rcvbufsize = atoi (optarg);
	  break;
#endif /* HAVE_NETLINK */
	case 'u':
	  zserv_privs.user = optarg;
	  break;
	case 'g':
	  zserv_privs.group = optarg;
	  break;
	case 'v':
	  print_version (progname);
	  exit (0);
	  break;
	case 'h':
	  usage (progname, 0);
	  break;
	default:
	  usage (progname, 1);
	  break;
	}
    }

  /* Make master thread emulator. */
  zebrad.master = thread_master_create ();

  /* privs initialise */
  zprivs_init (&zserv_privs);

  /* Vty related initialize. */
  signal_init (zebrad.master, Q_SIGC(zebra_signals), zebra_signals);
  cmd_init (1);
  vty_init (zebrad.master);
  memory_init ();

  /* Zebra related initialize. */
  zebra_init ();
  rib_init ();
  zebra_if_init ();
  zebra_debug_init ();
  router_id_init();
  zebra_vty_init ();
  access_list_init ();
  rtadv_init ();
#ifdef HAVE_IRDP
  irdp_init();
#endif

  /* For debug purpose. */
  /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */

  /* Make kernel routing socket. */
  kernel_init ();
  interface_list ();
  route_read ();

  /* Sort VTY commands. */
  sort_node ();

#ifdef HAVE_SNMP
  zebra_snmp_init ();
#endif /* HAVE_SNMP */

  /* Clean up self inserted route. */
  if (! keep_kernel_mode)
    rib_sweep_route ();

  /* Configuration file read*/
  vty_read_config (config_file, config_default);

  /* Clean up rib. */
  rib_weed_tables ();

  /* Exit when zebra is working in batch mode. */
  if (batch_mode)
    exit (0);

  /* Needed for BSD routing socket. */
  old_pid = getpid ();

  /* Daemonize. */
  if (daemon_mode)
    daemon (0, 0);

  /* Output pid of zebra. */
  pid_output (pid_file);

  /* Needed for BSD routing socket. */
  pid = getpid ();

  /* Make vty server socket. */
  vty_serv_sock (vty_addr, vty_port, ZEBRA_VTYSH_PATH);

  /* Print banner. */
  zlog_notice ("Zebra %s starting: vty@%d", QUAGGA_VERSION, vty_port);

  while (thread_fetch (zebrad.master, &thread))
    thread_call (&thread);

  /* Not reached... */
  exit (0);
}
Exemple #7
0
int main(int argc, char *argv[])
{
	int timeout = 0;
	sp_error error;
	int notify_cmdline = 0;
	int notify_events = 0;
	struct timespec ts;
	
	(void)argc;
	(void)argv;

	pthread_mutex_init(&g_notify_mutex, NULL);
	pthread_cond_init(&g_notify_cond, NULL);
	session_init();
	cmd_init(cmd_notify);
	
	do {
		clock_gettime(CLOCK_REALTIME, &ts);
		ts.tv_sec += timeout / 1000;
		ts.tv_nsec += (timeout % 1000) * 1E6;
		if (ts.tv_nsec > 1E9) {
			ts.tv_sec++;
			ts.tv_nsec -= 1E9;
		}

		pthread_mutex_lock(&g_notify_mutex);
		pthread_cond_timedwait(&g_notify_cond, &g_notify_mutex, &ts);
		notify_cmdline = g_notify_cmdline;
		notify_events = g_notify_events;
		g_notify_cmdline = 0;
		g_notify_events = 0;
		pthread_mutex_unlock(&g_notify_mutex);
		if (notify_cmdline) {
			cmd_process();
		}

		if (notify_events) {
			do {
				error = sp_session_process_events(g_session, &timeout);
				if (error != SP_ERROR_OK)
					fprintf(stderr, "error processing events: %s\n",
							sp_error_message(error));
			} while (timeout == 0);
		}

	} while (!is_program_finished());

	session_logout();
	while (session_is_logged_in()) {
       		clock_gettime(CLOCK_REALTIME, &ts);
		ts.tv_sec += 1;

		pthread_mutex_lock(&g_notify_mutex);
		pthread_cond_timedwait(&g_notify_cond, &g_notify_mutex, &ts);
		notify_events = g_notify_events;
		g_notify_events = 0;
		pthread_mutex_unlock(&g_notify_mutex);
		if (notify_events) {
			do {
				error = sp_session_process_events(g_session, &timeout);
				if (error != SP_ERROR_OK)
					fprintf(stderr, "error processing events: %s\n",
							sp_error_message(error));
			} while (timeout == 0);
		}
	}

	session_release();
	cmd_destroy();

	pthread_mutex_destroy(&g_notify_mutex);
	pthread_cond_destroy(&g_notify_cond);

	return 0;

}
Exemple #8
0
void rdp_update(void)
{
    uint32_t** dp_reg = plugin_get_dp_registers();
    uint32_t dp_current_al = (*dp_reg[DP_CURRENT] & ~7) >> 2;
    uint32_t dp_end_al = (*dp_reg[DP_END] & ~7) >> 2;

    // don't do anything if the RDP has crashed or the registers are not set up correctly
    if (rdp_pipeline_crashed || dp_end_al <= dp_current_al) {
        return;
    }

    // while there's data in the command buffer...
    while (dp_end_al - dp_current_al > 0) {
        uint32_t i, toload;
        bool xbus_dma = (*dp_reg[DP_STATUS] & DP_STATUS_XBUS_DMA) != 0;
        uint32_t* dmem = (uint32_t*)plugin_get_dmem();
        uint32_t* cmd_buf = rdp_cmd_buf[rdp_cmd_buf_pos];

        // when reading the first int, extract the command ID and update the buffer length
        if (rdp_cmd_pos == 0) {
            if (xbus_dma) {
                cmd_buf[rdp_cmd_pos++] = dmem[dp_current_al++ & 0x3ff];
            } else {
                cmd_buf[rdp_cmd_pos++] = rdram_read_idx32(dp_current_al++);
            }

            rdp_cmd_id = CMD_ID(cmd_buf);
            rdp_cmd_len = rdp_commands[rdp_cmd_id].length >> 2;
        }

        // copy more data from the N64 to the local command buffer
        toload = MIN(dp_end_al - dp_current_al, rdp_cmd_len - 1);

        if (xbus_dma) {
            for (i = 0; i < toload; i++) {
                cmd_buf[rdp_cmd_pos++] = dmem[dp_current_al++ & 0x3ff];
            }
        } else {
            for (i = 0; i < toload; i++) {
                cmd_buf[rdp_cmd_pos++] = rdram_read_idx32(dp_current_al++);
            }
        }

        // if there's enough data for the current command...
        if (rdp_cmd_pos == rdp_cmd_len) {
            // check if parallel processing is enabled
            if (config.parallel) {
                // special case: sync_full always needs to be run in main thread
                if (rdp_cmd_id == CMD_ID_SYNC_FULL) {
                    // first, run all pending commands
                    cmd_flush();

                    // parameters are unused, so NULL is fine
                    rdp_sync_full(NULL, NULL);
                } else {
                    // increment buffer position
                    rdp_cmd_buf_pos++;

                    // flush buffer when it is full or when the current command requires a sync
                    if (rdp_cmd_buf_pos >= CMD_BUFFER_SIZE || rdp_commands[rdp_cmd_id].sync) {
                        cmd_flush();
                    }
                }
            } else {
                // run command directly
                cmd_run(&rdp_states[0], cmd_buf);
            }

            // reset current command buffer to prepare for the next one
            cmd_init();
        }
    }

    // update DP registers to indicate that all bytes have been read
    *dp_reg[DP_START] = *dp_reg[DP_CURRENT] = *dp_reg[DP_END];
}
Exemple #9
0
int main (int argc, char *argv[])
{
	int       r;
	char      **optarg;
	int       run, nomon;
	unsigned  drive;
	char      *cfg;
	ini_sct_t *sct;

	cfg = NULL;
	run = 0;
	nomon = 0;

	pce_log_init();
	pce_log_add_fp (stderr, 0, MSG_INF);

	par_cfg = ini_sct_new (NULL);

	if (par_cfg == NULL) {
		return (1);
	}

	ini_str_init (&par_ini_str);

	while (1) {
		r = pce_getopt (argc, argv, &optarg, opts);

		if (r == GETOPT_DONE) {
			break;
		}

		if (r < 0) {
			return (1);
		}

		switch (r) {
		case '?':
			print_help();
			return (0);

		case 'V':
			print_version();
			return (0);

		case 'b':
			par_disk_delay_valid |= 1;
			par_disk_delay[0] = (unsigned) strtoul (optarg[0], NULL, 0);
			break;

		case 'B':
			drive = strtoul (optarg[0], NULL, 0);

			if ((drive < 1) || (drive >= SONY_DRIVES)) {
				fprintf (stderr, "%s: bad drive number (%u)\n",
					argv[0], drive
				);
				return (1);
			}

			drive -= 1;

			par_disk_delay_valid |= 1U << drive;
			par_disk_delay[drive] = (unsigned) strtoul (optarg[1], NULL, 0);
			break;

		case 'c':
			cfg = optarg[0];
			break;

		case 'd':
			pce_path_set (optarg[0]);
			break;

		case 'i':
			if (ini_read_str (par_cfg, optarg[0])) {
				fprintf (stderr,
					"%s: error parsing ini string (%s)\n",
					argv[0], optarg[0]
				);
				return (1);
			}
			break;

		case 'I':
			ini_str_add (&par_ini_str, optarg[0], "\n", NULL);
			break;

		case 'l':
			pce_log_add_fname (optarg[0], MSG_DEB);
			break;

		case 'p':
			ini_str_add (&par_ini_str, "cpu.model = \"",
				optarg[0], "\"\n"
			);
			break;

		case 'q':
			pce_log_set_level (stderr, MSG_ERR);
			break;

		case 'r':
			run = 1;
			break;

		case 'R':
			nomon = 1;
			break;

		case 's':
			ini_str_add (&par_ini_str, "cpu.speed = ",
				optarg[0], "\n"
			);
			break;

		case 't':
			par_terminal = optarg[0];
			break;

		case 'v':
			pce_log_set_level (stderr, MSG_DEB);
			break;

		case 0:
			fprintf (stderr, "%s: unknown option (%s)\n",
				argv[0], optarg[0]
			);
			return (1);

		default:
			return (1);
		}
	}

	mac_log_banner();

	if (pce_load_config (par_cfg, cfg)) {
		return (1);
	}

	sct = ini_next_sct (par_cfg, NULL, "macplus");

	if (sct == NULL) {
		sct = par_cfg;
	}

	if (ini_str_eval (&par_ini_str, sct, 1)) {
		return (1);
	}

	atexit (mac_atexit);

#ifdef PCE_ENABLE_SDL
	SDL_Init (0);
#endif

	pce_path_ini (sct);

	signal (SIGINT, &sig_int);
	signal (SIGSEGV, &sig_segv);
	signal (SIGTERM, &sig_term);

	pce_console_init (stdin, stdout);

	par_sim = mac_new (sct);

	mon_init (&par_mon);
	mon_set_cmd_fct (&par_mon, mac_cmd, par_sim);
	mon_set_msg_fct (&par_mon, mac_set_msg, par_sim);
	mon_set_get_mem_fct (&par_mon, par_sim->mem, mem_get_uint8);
	mon_set_set_mem_fct (&par_mon, par_sim->mem, mem_set_uint8);
	mon_set_memory_mode (&par_mon, 0);

	cmd_init (par_sim, cmd_get_sym, cmd_set_sym);
	mac_cmd_init (par_sim, &par_mon);

	mac_reset (par_sim);

	if (nomon) {
		while (par_sim->brk != PCE_BRK_ABORT) {
			mac_run (par_sim);
		}
	}
	else if (run) {
		mac_run (par_sim);
		if (par_sim->brk != PCE_BRK_ABORT) {
			pce_puts ("\n");
		}
	}
	else {
		pce_puts ("type 'h' for help\n");
	}

	if (par_sim->brk != PCE_BRK_ABORT) {
		mon_run (&par_mon);
	}

	mac_del (par_sim);

#ifdef PCE_ENABLE_SDL
	SDL_Quit();
#endif

	mon_free (&par_mon);
	pce_console_done();
	pce_log_done();

	return (0);
}