Beispiel #1
0
// Timer interrupt function.
word far *schedule( word far *p )
{
    process   *current_process;
    process   *next_process;
    priority_t priority_level;
    bool       found;

    // When the scheduler is called for the first time a non-Phoenix thread will be running.
    // Thus there is no "current process." To work around this just run the idle process for one
    // timer tick. Some other thread will take over at the next interrupt. Using the idle
    // process here is a bit of a hack but it's the only process we know we have.
    //
    if( first_time ) {
        processID idle_process;
        idle_process.pid = IDLE_PID;
        current_process = get_process( idle_process );
        set_current( current_process );
        first_time = false;
        return current_process->stack;
    }

    // Normal operation...
    // Get the current Phoenix process and search for a new one to schedule.
    //
    current_process = get_current( );
    current_process->stack = p;

    // Search for next runnable process.
    found = false;
    for( priority_level = HIGH_PRIORITY; priority_level >= 0; --priority_level ) {
        next_process = get_next( current_process );
        while( !found ) {
            if( next_process->runnable && next_process->priority == priority_level ) {
                found = true;
                break;
            }
            if( next_process == current_process ) break;
            next_process = get_next( next_process );
        }

        if( found ) break;
    }

    // We should find a runnable process because the idle process is always runnable and the
    // loop above will stumble into it eventually. Note that the idle process should be the
    // only process at the IDLE_PRIORITY level. 

    set_current( next_process );
    return next_process->stack;
}
Beispiel #2
0
static void __init start_of_day(void)
{
    init_IRQ();

    scheduler_init();

    /* create idle domain */
    idle_domain = domain_create(IDLE_DOMAIN_ID, 0, 0);
    if ((idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL))
        BUG();
    set_current(idle_domain->vcpu[0]);
    idle_vcpu[0] = current;

    initialize_keytable();
    /* Register another key that will allow for the the Harware Probe
     * to be contacted, this works with RiscWatch probes and should
     * work with Chronos and FSPs */
    register_keyhandler('^', key_hw_probe_attn, "Trap to Hardware Probe");

    /* allow the dumping of the devtree */
    register_keyhandler('D', key_ofdump , "Dump OF Devtree");

    timer_init();
    rcu_init();
    serial_init_postirq();
    do_initcalls();
}
Beispiel #3
0
void callback_set_current(const std_msgs::Float64::ConstPtr& msg) {
  if(command_mode!=globe_epas::globe_epas_cmd::CURRENT_CONTROL) {
    ROS_INFO("Ignoring Globe EPAS command due to incorrect command mode");
    return;
  }
  set_current(msg->data);
}  
Beispiel #4
0
/*!
 * The following logic is used to select the next process:
 *
 * 1. Increment the score of each runnable process. The greater a process's
 *    priority, the greater the increment.
 * 2. Select the process with the highest score. If multiple processes have the
 *    same score, select the first process after the "current" process, where
 *    the "current" process is the process pointed to by the ringbuffer index.
 * 3. Make the selected process the "current" process, set it's score to zero
 *    and run it.
 *
 * Note that only runnable processes are given points. If non-runnable processs
 * are given points, they will attain insane scores. This could be problematic
 * if numerous non-runnable processes all became runnable at the same time
 *
 * This function is inefficient: the score of *every* process is bumped whenever
 * the function is called. As MAX_THREADS grows, the problem will only get
 * worse. Better solutions should be considered. One possible solution is to
 * examine only a limited number of processes each time this interrupt occurs,
 * rather than examining all processes.
 */
word far *Schedule( word far *p )
{
    process * const current = get_current( );
    process * candidate = get_current( ); // Candidate for next runnable process
    process * choice; // Choice for next runnable process
    processID idle; // Used to find the idle thread

    if( NULL == current ) {
        print_at( count++, col, "thread pointing to NULL", 0x04 );
        print_at( count++, col, "(has add_process() been called?)", 0x04 );
        return p;
    }
    // What does this do? It is necessary for test program 1 to function.
    current->stack = p;

    // Make a default choice...
    idle.pid = IDLE;
    choice = get_process( idle );
    // ... then see if any other suitable candidates exist.
    do {
        candidate = get_next( candidate->pid );
        if( true == candidate->runnable ) {
            // Bump score before considering a process. This ensures that
            // `candidate` will always out-score the idle thread.
            candidate->score += candidate->priority;
            if( candidate->score > choice->score ) {
                choice = candidate;
            }
        }
    } while( candidate->pid.pid != current->pid.pid );

    choice->score = 0;
    set_current( choice->pid ); // update ringbuffer index
    return choice->stack;
}
Beispiel #5
0
void calibrate_opamp_offset_trim(settings_t *newsettings, int microamps, progress_callback_t progress_callback) {
    state.calibrating = 1;
	int high_value = microamps / DEFAULT_DAC_HIGH_GAIN;
	int low_value = 100000 / DEFAULT_DAC_HIGH_GAIN; // Approx 100mA
    int high_current, low_current;
    IDAC_Low_SetValue(0);

	// Find the best setting for the opamp trim
    int min_offset = INT_MIN;
    int min_offset_idx = 0;
    
	for(int i = 0; i < MAX_OA_OFFSET_STEPS; i++) {
        progress_callback(i+1,MAX_OA_OFFSET_STEPS);
		CY_SET_REG32(Opamp_cy_psoc4_abuf__OA_OFFSET_TRIM, i);
		
        IDAC_High_SetValue(high_value);
        vTaskDelay(configTICK_RATE_HZ);
        high_current = get_raw_current_usage() - newsettings->calibration_settings.adc_current_offset;

        IDAC_High_SetValue(low_value);
        vTaskDelay(configTICK_RATE_HZ);
        low_current = get_raw_current_usage() - newsettings->calibration_settings.adc_current_offset;

        int offset = (high_value * low_current - low_value * high_current) / (high_value - low_value);
		if(offset <= 0 && offset > min_offset) {
            min_offset = offset;
            min_offset_idx = i;
		}
	}
    set_opamp_offset_trim(newsettings, min_offset_idx);

	set_current(0);
    state.calibrating = 0;
}
 virtual void set_options(const FilterValueVector* new_options)
 {
     assert(new_options != nullptr);
     assert(new_options->empty() == false);
     options = new_options;
     set_current(0);
 }
Beispiel #7
0
void calibrate_dacs(settings_t *newsettings, int microamps) {
    state.calibrating = 1;
	int high_value = microamps / DEFAULT_DAC_HIGH_GAIN;
	int low_value = 100000 / DEFAULT_DAC_HIGH_GAIN; // Approx 100mA
    int high_current, low_current;

    IDAC_Low_SetValue(0);

	// Calculate offset and gain for IDAC_High 
    IDAC_High_SetValue(high_value);
	vTaskDelay(configTICK_RATE_HZ * 2);
	high_current = (get_raw_current_usage() - newsettings->calibration_settings.adc_current_offset) * settings->calibration_settings.adc_current_gain;

	IDAC_High_SetValue(low_value);
	vTaskDelay(configTICK_RATE_HZ * 2);
	low_current = (get_raw_current_usage() - newsettings->calibration_settings.adc_current_offset) * settings->calibration_settings.adc_current_gain;
	
	newsettings->calibration_settings.dac_high_gain = (high_current - low_current) / (high_value - low_value);
	newsettings->calibration_settings.dac_offset = high_current - high_value * newsettings->calibration_settings.dac_high_gain;
	
	// Calculate gain for IDAC_Low
	IDAC_Low_SetValue(127);
	vTaskDelay(configTICK_RATE_HZ * 4);
	newsettings->calibration_settings.dac_low_gain = ((get_raw_current_usage() - newsettings->calibration_settings.adc_current_offset) * settings->calibration_settings.adc_current_gain - low_current) / 127;
	
	// Reset for 0 output
	set_current(0);
    state.calibrating = 0;
}
Beispiel #8
0
Context::Context(std::function<void()>&& code, actor::ActorImpl* actor) : code_(std::move(code)), actor_(actor)
{
  /* If no function was provided, this is the context for maestro
   * and we should set it as the current context */
  if (not has_code())
    set_current(this);
}
Beispiel #9
0
void DeltaProcess::transfer_and_continue() {
  {
    ThreadCritical tc;

    assert(!is_scheduler(), "active must be other than scheduler");
    assert(!in_vm_operation(), "must not be in VM operation");
    assert(this == active(), "receiver must be the active process");


    // save state
    _last_Delta_fp = ::last_Delta_fp;	// *don't* use accessors! (check their implementation to see why)
    _last_Delta_sp = ::last_Delta_sp;
    set_state(in_async_dll);


    // restore state
    ::last_Delta_fp = scheduler()->_last_Delta_fp;	// *don't* use accessors! 
    ::last_Delta_sp = scheduler()->_last_Delta_sp;
    set_current(scheduler());
    set_active(scheduler());

    if (TraceProcessEvents) {
      std->print("Async call: "); print();
      std->print("        to: "); scheduler()->print();
      std->cr();
    }
  }
  os::transfer_and_continue(_thread, _event, scheduler()->_thread, scheduler()->_event);
}
Beispiel #10
0
void DeltaProcess::transfer(ProcessState reason, DeltaProcess* target) {
  // change time_stamp for target
  target->inc_time_stamp();

  {
    ThreadCritical tc;

    assert(this == active(), "receiver must be the active process");

    // save state
    _last_Delta_fp = ::last_Delta_fp;	// *don't* use accessors! (check their implementation to see why)
    _last_Delta_sp = ::last_Delta_sp;
    set_state(reason);

    // restore state
    ::last_Delta_fp = target->_last_Delta_fp;	// *don't* use accessors!
    ::last_Delta_sp = target->_last_Delta_sp;
    set_current(target);
    set_active(target);
    resetStepping();
  }

  // transfer
  basic_transfer(target);
}
Beispiel #11
0
void setup() {
	state.current_setpoint = -1;
	state.current_range = -1;
    state.lower_voltage_limit = -1;

	set_current(0);
	
	CY_SET_REG32(Opamp_cy_psoc4_abuf__OA_OFFSET_TRIM, settings->opamp_offset_trim);
}
// ---------------------------------------------------------------------------
// 
// ------------
int bMacMapLayerAccessContext::load(){
_bTrace_("bMacMapLayerAccessContext::load",true);

long                    margin=0;
bGenericXMLBaseElement	*root,*elt;
	if(map_doc->readTree(&root,0,"drawsearch")){
_tm_("found drawsearch.xml");
char	val[_values_length_max_];
		elt=clssmgr->NthElement(root,1,"int");
		if(elt){
			elt->getvalue(val);
			margin=atoi(val);
_tm_("margin="+(int)margin);
		}
		else{
_tw_("no margin");		
		}
		clssmgr->ReleaseXMLInstance(root);
		if(margin<0){
			margin=0;
		}
	}
	
	_curview=viewmgr->get_root();
    if(!_curview){
_te_("no _curview == NULL");
		return(-1);
    }
	_curview->init(this);
bStyle*	style;
	for(int i=1;i<=_elts->count();i++){
		if(!_elts->get(i,&style)){
_te_("_elts->get("+i+",&style)");
			return(-1);
		}
		if(	(style->gettype()==NULL)	&&
			(!style->is_virtual())		){
_te_("type not found for style "+i);
			remove(i);
			i--;
			continue;
		}
_tm_("* parsing "+i);
		if(!parse(i)){
		}
		style->setmargin(margin);
	}
	
	if(count()>0){
		set_current(1);
	}
	
	return(noErr);
}
// ---------------------------------------------------------------------------
// 
// -----------
bool bScaleMgr::rmv(int idx){	
	if(count()==1){
		return(false);
	}	
	if(bStdUnitMgr::rmv(idx)){
		if((idx==count()+1)&&(idx==get_current())){
			set_current(idx-1);
		}
	}
	return(false);
}
Beispiel #14
0
void tile_picker::handle_inside_event(event &ev, image *screen, InputManager *inm)
{
  if (ev.type==EV_MOUSE_BUTTON)
  {
    int sel=((ev.mouse_move.y-y)/pich()*wid)+(ev.mouse_move.x-x)/picw()+last_sel;
    if (sel<t && sel>=0 && sel!=get_current())
    {
      set_current(sel);
      scroll_event(last_sel, screen);
    }
  }
}
Beispiel #15
0
 const_result_iterator &begin(void)
 {
     for (unsigned loop=0; loop<outer_->num_partitions_; ++loop)
     {
         kvlist_[loop] = std::make_pair(boost::shared_ptr<std::ifstream>(new std::ifstream), keyvalue_t());
         kvlist_[loop].first->open(outer_->intermediate_files_.find(loop)->second.first.c_str());
         BOOST_ASSERT(kvlist_[loop].first->is_open());
         read_record(*kvlist_[loop].first, kvlist_[loop].second.first, kvlist_[loop].second.second);
     }
     set_current();
     return *this;
 }
Beispiel #16
0
static int completeLine(struct current *current) {
    linenoiseCompletions lc = { 0, NULL };
    int c = 0;

    completionCallback(current->buf,&lc,completionUserdata);
    if (lc.len == 0) {
        beep();
    } else {
        size_t stop = 0, i = 0;

        while(!stop) {
            /* Show completion or original buffer */
            if (i < lc.len) {
                struct current tmp = *current;
                tmp.buf = lc.cvec[i];
                tmp.pos = tmp.len = strlen(tmp.buf);
                tmp.chars = utf8_strlen(tmp.buf, tmp.len);
                refreshLine(current->prompt, &tmp);
            } else {
                refreshLine(current->prompt, current);
            }

            c = fd_read(current);
            if (c == -1) {
                break;
            }

            switch(c) {
                case '\t': /* tab */
                    i = (i+1) % (lc.len+1);
                    if (i == lc.len) beep();
                    break;
                case 27: /* escape */
                    /* Re-show original buffer */
                    if (i < lc.len) {
                        refreshLine(current->prompt, current);
                    }
                    stop = 1;
                    break;
                default:
                    /* Update buffer and return */
                    if (i < lc.len) {
                        set_current(current,lc.cvec[i]);
                    }
                    stop = 1;
                    break;
            }
        }
    }

    freeCompletions(&lc);
    return c; /* Return last read character */
}
Beispiel #17
0
//filter an incoming data point and return the filtered value
int Moving_average::filter(int new_data) {
		int result = data.sum() + new_data;
		result = result / len;
		
		//add the new data point to the history			
		data.add(new_data);
		
		//update the current average
		set_current(result);
		
		return result;		
}
Beispiel #18
0
void DeltaProcess::transfer_to_vm() {
  {
    ThreadCritical tc;

    assert(this == active(), "receiver must be the active process");

    // save state
    _last_Delta_fp = ::last_Delta_fp;	// *don't* use accessors! (check their implementation to see why)
    _last_Delta_sp = ::last_Delta_sp;
    set_current(VMProcess::vm_process());
  }
  basic_transfer(VMProcess::vm_process());
}
Beispiel #19
0
void PaletteEditor::rgb_changed()
{
    if (ignore_rgb)
        return;
    RGBColor & pal = get_palette_color();
    pal.r = r_edit->value();
    pal.g = g_edit->value();
    pal.b = b_edit->value();
    ignore_rgb = true;
    set_current();
    ignore_rgb = false;
    window->model_changed();
}
void
MenuManager::pop_current()
{
  previous = current_;

  if (last_menus.size() >= 1) {
    current_ = last_menus.back();
    current_->effect_start_time = real_time;
    current_->effect_progress   = 0.0f;
    last_menus.pop_back();
  } else {
    set_current(NULL);
  }
}
Beispiel #21
0
/* Boot the current CPU */
void __cpuinit start_secondary(unsigned long boot_phys_offset,
                               unsigned long fdt_paddr,
                               unsigned long hwid)
{
    unsigned int cpuid = init_data.cpuid;

    memset(get_cpu_info(), 0, sizeof (struct cpu_info));

    set_processor_id(cpuid);

    current_cpu_data = boot_cpu_data;
    identify_cpu(&current_cpu_data);

    init_traps();

    setup_virt_paging();

    mmu_init_secondary_cpu();

    gic_init_secondary_cpu();

    init_secondary_IRQ();

    gic_route_ppis();

    init_maintenance_interrupt();
    init_timer_interrupt();

    set_current(idle_vcpu[cpuid]);

    setup_cpu_sibling_map(cpuid);

    /* Run local notifiers */
    notify_cpu_starting(cpuid);
    wmb();

    /* Now report this CPU is up */
    smp_up_cpu = MPIDR_INVALID;
    cpumask_set_cpu(cpuid, &cpu_online_map);
    wmb();

    local_irq_enable();
    local_abort_enable();

    printk(XENLOG_DEBUG "CPU %u booted.\n", smp_processor_id());

    startup_cpu_idle_loop();
}
Beispiel #22
0
/**
 * Based on understanding gained from online resources as detailed in the 
 * bibliography of my writeup
 * 
 * recurses through the binary tree until it finds the correct location to 
 * insert the new node. As specified inserts so that smaller values are
 * stored in left sub tree and equal or larger values in the right sub tree
 * 
 * @param root a pointer to the Competitor * root in main, allows the value of 
 * root to be modified where required
 * @param node_to_add
 * @return the appropriate flags for any errors that occur
 */
int add_to_tree(competitor ** root, competitor * node_to_add){
    competitor * current = (*root);
    int error_descriptor = 0;
    if(current == NULL){
        error_descriptor = set_current(node_to_add, &current);
        if(error_descriptor != 0) return error_descriptor;
        (*root) = current;
         return 0;
    }else{
        if(TOTAL_NODE_TO_ADD_LENGTH < TOTAL_CURRENT_LENGTH){
            add_to_tree(&(current->left), node_to_add);
        }else{
            add_to_tree(&(current->right), node_to_add);
        }
    }
}
Beispiel #23
0
/* Boot the current CPU */
void __cpuinit start_secondary(unsigned long boot_phys_offset,
                               unsigned long fdt_paddr,
                               unsigned long cpuid)
{
    struct cpuinfo_arm *c = cpu_data + cpuid;

    memset(get_cpu_info(), 0, sizeof (struct cpu_info));

    /* TODO: handle boards where CPUIDs are not contiguous */
    set_processor_id(cpuid);

    *c = boot_cpu_data;
    identify_cpu(c);

    /* Setup Hyp vector base */
    WRITE_SYSREG((vaddr_t)hyp_traps_vector, VBAR_EL2);

    mmu_init_secondary_cpu();
    enable_vfp();

    gic_init_secondary_cpu();

    init_secondary_IRQ();

    gic_route_ppis();

    init_maintenance_interrupt();
    init_timer_interrupt();

    set_current(idle_vcpu[cpuid]);

    setup_cpu_sibling_map(cpuid);

    /* Run local notifiers */
    notify_cpu_starting(cpuid);
    wmb();

    /* Now report this CPU is up */
    cpumask_set_cpu(cpuid, &cpu_online_map);
    wmb();

    local_irq_enable();

    dprintk(XENLOG_DEBUG, "CPU %u booted.\n", smp_processor_id());

    startup_cpu_idle_loop();
}
Beispiel #24
0
/* Boot the current CPU */
void start_secondary(unsigned long boot_phys_offset,
                     unsigned long fdt_paddr,
                     unsigned long hwid)
{
    unsigned int cpuid = init_data.cpuid;

    memset(get_cpu_info(), 0, sizeof (struct cpu_info));

    set_processor_id(cpuid);

    identify_cpu(&current_cpu_data);

    init_traps();

    mmu_init_secondary_cpu();

    gic_init_secondary_cpu();

    init_secondary_IRQ();

    init_maintenance_interrupt();
    init_timer_interrupt();

    set_current(idle_vcpu[cpuid]);

    setup_cpu_sibling_map(cpuid);

    /* Run local notifiers */
    notify_cpu_starting(cpuid);
    /*
     * Ensure that previous writes are visible before marking the cpu as
     * online.
     */
    smp_wmb();

    /* Now report this CPU is up */
    cpumask_set_cpu(cpuid, &cpu_online_map);

    local_irq_enable();
    local_abort_enable();

    check_local_cpu_errata();

    printk(XENLOG_DEBUG "CPU %u booted.\n", smp_processor_id());

    startup_cpu_idle_loop();
}
Beispiel #25
0
void context_switch(struct vcpu *prev, struct vcpu *next)
{
    ASSERT(local_irq_is_enabled());
    ASSERT(prev != next);
    ASSERT(cpumask_empty(next->vcpu_dirty_cpumask));

    if ( prev != next )
        update_runstate_area(prev);

    local_irq_disable();

    set_current(next);

    prev = __context_switch(prev, next);

    schedule_tail(prev);
}
Beispiel #26
0
bool update(const char * field, std::vector<uint8_t> data) {
    if (!strcmp(field, "dlpkt")) {
        return delete_packet(data);
    } else if (!strcmp(field, "dlcha")) {
        return delete_channel(data);
    } else if (!strcmp(field, "pnum")) {
        return set_pnumber(data);
    } else if (!strcmp(field, "chan")) {
        return set_channel(data);
    } else if (!strcmp(field, "pol")) {
        set_poll(data);
    } else if (!strcmp(field, "dir")) {
        const char * dirStr = byteVec2cstr(data);
        if (!strcmp(dirStr, "pos"))
            set_direction(DIR_POS);
        else if (!strcmp(dirStr, "neg"))
            set_direction(DIR_NEG);
        else return false;
    } else if (!strcmp(field, "data")) {
        return set_current(data);
    } else if (!strcmp(field, "wait")) {
        set_delay(data);
    } else if (!strcmp(field, "send")) {
        flag_return = true;
        send_packets();
    } else if (!strcmp(field, "reset")) {
        send_global_reset();
    } else if (!strcmp(field, "glob")) {
        set_global();
    } else if (!strcmp(field, "conn")) {
        flag_return = true;
        return connect_serial();
    } else if (!strcmp(field, "exit")) {
        return exit();
    } else if (!strcmp(field, "clrpks")) {
        clear_packets();
    } else if (!strcmp(field, "prev")) {
        if (debug_) preview_packets();
        preview_packet_bytes();
        flag_return = true;
    } else { return false; }
    return true;
}
Beispiel #27
0
/* This is the first C code that secondary processors invoke.  */
void secondary_cpu_init(int cpuid, unsigned long r4)
{
    struct vcpu *vcpu;

    cpu_initialize(cpuid);
    smp_generic_take_timebase();

    /* If we are online, we must be able to ACK IPIs.  */
    mpic_setup_this_cpu();
    cpu_set(cpuid, cpu_online_map);

    vcpu = alloc_vcpu(idle_domain, cpuid, cpuid);
    BUG_ON(vcpu == NULL);

    set_current(idle_domain->vcpu[cpuid]);
    idle_vcpu[cpuid] = current;
    startup_cpu_idle_loop();

    panic("should never get here\n");
}
Beispiel #28
0
void main()
{
    CyGlobalIntEnable;

#if USE_WATCHDOG
    // Enable watchdog timer for every 2 seconds
    CySysWdtWriteMode(0, CY_SYS_WDT_MODE_RESET);
    CySysWdtWriteMatch(0, 0xFFFF);
    CySysWdtEnable(CY_SYS_WDT_COUNTER0_MASK);
#endif

    if(settings->settings_version < default_settings.settings_version)
        factory_reset();
    Backlight_Write(1);	
	disp_reset_Write(0);
	CyDelayUs(10);
	disp_reset_Write(1);
	CyDelayUs(10);
	Display_Start();
    Display_SetContrast(settings->lcd_contrast);
	
	#ifdef USE_SPLASHSCREEN
	load_splashscreen();
	#endif	

	IDAC_High_Start();
	IDAC_Low_Start();
    state.calibrating = 0;
    set_current(0);
	set_output_mode(OUTPUT_MODE_FEEDBACK);		
	start_adc();
	setup();
	//Create the two tasks
	xTaskCreate(vTaskUI, (signed portCHAR *) "UI", 178, NULL, tskIDLE_PRIORITY + 2, &ui_task);
	xTaskCreate(vTaskComms, (signed portCHAR *) "UART", 180, NULL, tskIDLE_PRIORITY + 2, &comms_task);
	
	prvHardwareSetup();
	vTaskStartScheduler();
}
Beispiel #29
0
void *switch_to_skas(void *prev, void *next)
{
	struct task_struct *from, *to;

	from = prev;
	to = next;

	/* XXX need to check runqueues[cpu].idle */
	if(current->pid == 0)
		switch_timers(0);

	to->thread.prev_sched = from;
	set_current(to);

	switch_threads(&from->thread.mode.skas.switch_buf, 
		       to->thread.mode.skas.switch_buf);

	if(current->pid == 0)
		switch_timers(1);

	return(current->thread.prev_sched);
}
bool RenderWindow::create(int width, int height, const wchar_t* title) {
  bool rez = false;
  if(_wimpl == 0) {
    Window::create(width, height, title);
    HDC dc = ::GetDC(reinterpret_cast<HWND>(_wimpl));
    if(dc != 0) {
      _dc = reinterpret_cast<void*>(dc);
	    // описание формата пикселей
      PIXELFORMATDESCRIPTOR pfd;
	    memset(&pfd, 0, sizeof(pfd));
	    pfd.nSize      = sizeof(pfd);
	    pfd.nVersion   = 1;
	    pfd.dwFlags    = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
	    pfd.iPixelType = PFD_TYPE_RGBA;
	    pfd.cColorBits = 32;
	    pfd.cDepthBits = 24;

	    // запросим формат пикселей, ближайший к описанному выше
	    int format = ChoosePixelFormat(dc, &pfd);
      if (format && SetPixelFormat(dc, format, &pfd)) {
        _device = reinterpret_cast<RenderContextImpl*>(wglCreateContext(dc));
        if(_device != 0) {
          rez = set_current();
          glDisable ( GL_DEPTH_TEST );
          glMatrixMode(GL_PROJECTION);
          glPushMatrix();
          glLoadIdentity();
          glScalef(1.0f, -1.0f, 1.0f);
          gluOrtho2D(0, width, 0, height);
          glMatrixMode(GL_MODELVIEW);
          glPushMatrix();
          glLoadIdentity();
        }
      }
    }
  }
  return rez;
}