int main(int argc, char **argv) { /* 模块初始化 */ exc_init(); /* 中断初始化 */ sys_timer_init(); /* 系统时钟初始化 */ light_init(); /* LED灯初始化 */ switch_init(); /* 开关初始化 */ speaker_init(); /* 蜂鸣器初始化 */ motor_init(); /* 电机初始化 */ steer_init(); /* 舵机初始化 */ decoder_init(); /* 编码器初始化 */ serial_initialize((intptr_t)(NULL)); /* 初始化串口 */ //sd_init(&Fatfs); /* 初始化SD卡,并创建文件 */ //sd_create_file(&test_data, test_data_name); /* 命令注册 */ help_cmd_initialize((intptr_t)(NULL)); light_cmd_initialize((intptr_t)(NULL)); switch_cmd_initialize((intptr_t)(NULL)); speaker_cmd_initialize((intptr_t)(NULL)); motor_cmd_initialize((intptr_t)(NULL)); decoder_cmd_initialize((intptr_t)(NULL)); control_cmd_initialize((intptr_t)(NULL)); //sd_cmd_initialize((intptr_t)(NULL)); printf("\n Welcome to k60 software platform!"); printf("\n Press 'help' to get the help! \n"); //light_open(LIGHT4); /* ntshell测试 */ task_ntshell((intptr_t)(NULL)); }
void set_volume(void) { uint8_t mode = SHOW_MENU; uint8_t volume; timeoutcounter = INACTIVITYTIMEOUT;; volume = eeprom_read_byte((uint8_t *)EE_VOLUME); while (1) { if (just_pressed || pressed) { timeoutcounter = INACTIVITYTIMEOUT;; // timeout w/no buttons pressed after 3 seconds? } else if (!timeoutcounter) { //timed out! displaymode = SHOW_TIME; return; } if (just_pressed & 0x1) { // mode change return; } if (just_pressed & 0x2) { just_pressed = 0; if (mode == SHOW_MENU) { // start! mode = SET_VOL; // display volume if (volume) { display_str("vol high"); display[5] |= 0x1; } else { display_str("vol low"); } display[6] |= 0x1; display[7] |= 0x1; display[8] |= 0x1; } else { displaymode = SHOW_TIME; return; } } if (just_pressed & 0x4) { just_pressed = 0; if (mode == SET_VOL) { volume = !volume; if (volume) { display_str("vol high"); display[5] |= 0x1; } else { display_str("vol low"); } display[6] |= 0x1; display[7] |= 0x1; display[8] |= 0x1; eeprom_write_byte((uint8_t *)EE_VOLUME, volume); speaker_init(); beep(4000, 1); } } } }
int main () { speaker_waiter_init(); speaker_cooker_init(); speaker_init(); speaker_waiter_run(); }
void power_up() { sleep_disable(); led_set(9,1); power_flag = 1; ADCSRA |= (1<<ADPS2)|(1<<ADPS1); ADCSRA |= (1<<ADATE); TCCR0A |= (1 << WGM01); TCCR0B |= (1 << CS00) | (1 << CS02); TIMSK0 |= (1 << OCIE0A); OCR0A = 255; led_init(); button_init(); vib_init(); speaker_init(); EIMSK &= ~(1 << INT1); //disable INT1 PCICR |= (1 << PCIE2) | (1 << PCIE0); // enable PCINT rfm12_power_up(); VOL = eeprom_read_byte((uint8_t*)0); id_tab[0][0] = eeprom_read_byte((uint8_t*)8); id_tab[0][1] = eeprom_read_byte((uint8_t*)16); id_tab[0][2] = eeprom_read_byte((uint8_t*)24); id_tab[1][0] = eeprom_read_byte((uint8_t*)32); id_tab[1][1] = eeprom_read_byte((uint8_t*)40); id_tab[1][2] = eeprom_read_byte((uint8_t*)48); id_tab[2][0] = eeprom_read_byte((uint8_t*)56); id_tab[2][1] = eeprom_read_byte((uint8_t*)64); id_tab[2][2] = eeprom_read_byte((uint8_t*)72); id_tab[3][0] = eeprom_read_byte((uint8_t*)80); id_tab[3][1] = eeprom_read_byte((uint8_t*)88); id_tab[3][2] = eeprom_read_byte((uint8_t*)96); sei(); main_mode = 0; func_mode = 0; function = 2; }
void wakeup(void) { if (!sleepmode) return; CLKPR = _BV(CLKPCE); CLKPR = 0; DEBUGP("waketime"); sleepmode = 0; // plugged in // wait to verify _delay_ms(20); if (ACSR & _BV(ACO)) return; // turn on pullups initbuttons(); dimmer_init(); // turn on boost brightness_level = eeprom_read_byte((uint8_t *)EE_BRIGHT); boost_init(brightness_level); // turn on vfd control vfd_init(); // turn on display VFDSWITCH_PORT &= ~_BV(VFDSWITCH); VFDBLANK_PORT &= ~_BV(VFDBLANK); volume = eeprom_read_byte((uint8_t *)EE_VOLUME); // reset speaker_init(); kickthedog(); setalarmstate(); // wake up sound beep(880, 1); beep(1760, 1); beep(3520, 1); kickthedog(); }
void resetpchard() { if (!modelchanged) device_close_all(); else modelchanged = 0; device_init(); midi_close(); midi_init(); timer_reset(); sound_reset(); mem_resize(); if (pcfirsttime) { fdc_init(); pcfirsttime = 0; } else fdc_hard_reset(); model_init(); video_init(); speaker_init(); // #ifdef USE_NETWORKING vlan_reset(); //NETWORK network_card_init(network_card_current); // #endif sound_card_init(sound_card_current); if (GUS) device_add(&gus_device); if (GAMEBLASTER) device_add(&cms_device); if (SSI2001) device_add(&ssi2001_device); if (voodoo_enabled) device_add(&voodoo_device); pc_reset(); resetide(); loadnvr(); // cpuspeed2 = (AT)?2:1; // atfullspeed = 0; // setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); shadowbios = 0; ali1429_reset(); keyboard_at_reset(); // output=3; #if __unix if (cdrom_drive == -1) cdrom_null_reset(); else #endif ioctl_reset(); }
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) { static const u16 spd_addr[] = { DIMM0, 0, 0, 0, DIMM1, 0, 0, 0, }; int needs_reset = 0; u32 bsp_apicid = 0; msr_t msr; struct cpuid_result cpuid1; struct sys_info *sysinfo = &sysinfo_car; if (!cpu_init_detectedx && boot_cpu()) { /* Nothing special needs to be done to find bus 0 */ /* Allow the HT devices to be found */ enumerate_ht_chain(); /* sb600_lpc_port80(); */ sb600_pci_port80(); } technexion_post_code_init(); technexion_post_code(LED_MESSAGE_START); if (bist == 0) bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo); enable_rs690_dev8(); sb600_lpc_init(); ite_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); ite_kill_watchdog(GPIO_DEV); console_init(); /* Halt if there was a built in self test failure */ report_bist_failure(bist); printk(BIOS_DEBUG, "bsp_apicid=0x%x\n", bsp_apicid); setup_tim5690_resource_map(); setup_coherent_ht_domain(); #if CONFIG_LOGICAL_CPUS /* It is said that we should start core1 after all core0 launched */ wait_all_core0_started(); start_other_cores(); #endif wait_all_aps_started(bsp_apicid); ht_setup_chains_x(sysinfo); /* run _early_setup before soft-reset. */ rs690_early_setup(); sb600_early_setup(); /* Check to see if processor is capable of changing FIDVID */ /* otherwise it will throw a GP# when reading FIDVID_STATUS */ cpuid1 = cpuid(0x80000007); if ((cpuid1.edx & 0x6) == 0x6) { /* Read FIDVID_STATUS */ msr=rdmsr(0xc0010042); printk(BIOS_DEBUG, "begin msr fid, vid: hi=0x%x, lo=0x%x\n", msr.hi, msr.lo); enable_fid_change(); enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn); init_fidvid_bsp(bsp_apicid); /* show final fid and vid */ msr=rdmsr(0xc0010042); printk(BIOS_DEBUG, "end msr fid, vid: hi=0x%x, lo=0x%x\n", msr.hi, msr.lo); } else { printk(BIOS_DEBUG, "Changing FIDVID not supported\n"); } needs_reset = optimize_link_coherent_ht(); needs_reset |= optimize_link_incoherent_ht(sysinfo); rs690_htinit(); printk(BIOS_DEBUG, "needs_reset=0x%x\n", needs_reset); if (needs_reset) { printk(BIOS_INFO, "ht reset -\n"); soft_reset(); } speaker_init(255); speaker_on_nodelay(); allow_all_aps_stop(bsp_apicid); /* It's the time to set ctrl now; */ printk(BIOS_DEBUG, "sysinfo->nodes: %2x sysinfo->ctrl: %p spd_addr: %p\n", sysinfo->nodes, sysinfo->ctrl, spd_addr); fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr); technexion_post_code(LED_MESSAGE_RAM); sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo); speaker_off_nodelay(); rs690_before_pci_init(); sb600_before_pci_init(); post_cache_as_ram(); }
int main(void) { // uint8_t i; uint8_t mcustate; // turn boost off TCCR0B = 0; BOOST_DDR |= _BV(BOOST); BOOST_PORT &= ~_BV(BOOST); // pull boost fet low // check if we were reset mcustate = MCUSR; MCUSR = 0; wdt_disable(); // now turn it back on... 2 second time out //WDTCSR |= _BV(WDP0) | _BV(WDP1) | _BV(WDP2); //WDTCSR = _BV(WDE); wdt_enable(WDTO_2S); kickthedog(); // we lost power at some point so lets alert the user // that the time may be wrong (the clock still works) timeunknown = 1; // have we read the time & date from eeprom? restored = 0; // setup uart uart_init(BRRL_192); //DEBUGP("VFD Clock"); DEBUGP("!"); //DEBUGP("turning on anacomp"); // set up analog comparator ACSR = _BV(ACBG) | _BV(ACIE); // use bandgap, intr. on toggle! // settle! if (ACSR & _BV(ACO)) { // hmm we should not interrupt here ACSR |= _BV(ACI); // even in low power mode, we run the clock DEBUGP("clock init"); clock_init(); } else { // we aren't in low power mode so init stuff // init io's initbuttons(); VFDSWITCH_PORT &= ~_BV(VFDSWITCH); DEBUGP("turning on buttons"); // set up button interrupts DEBUGP("turning on alarmsw"); // set off an interrupt if alarm is set or unset EICRA = _BV(ISC00); EIMSK = _BV(INT0); displaymode = SHOW_TIME; DEBUGP("vfd init"); vfd_init(); dimmer_init(); DEBUGP("boost init"); brightness_level = eeprom_read_byte((uint8_t *)EE_BRIGHT); boost_init(brightness_level); sei(); region = eeprom_read_byte((uint8_t *)EE_REGION); DEBUGP("speaker init"); speaker_init(); beep(4000, 1); DEBUGP("clock init"); clock_init(); DEBUGP("alarm init"); setalarmstate(); } DEBUGP("done"); while (1) { //_delay_ms(100); kickthedog(); //uart_putc_hex(ACSR); if (ACSR & _BV(ACO)) { // DEBUGP("SLEEPYTIME"); gotosleep(); continue; } //DEBUGP("."); if (just_pressed & 0x1) { just_pressed = 0; switch(displaymode) { case (SHOW_TIME): displaymode = SET_ALARM; display_str("set alarm"); set_alarm(); break; case (SET_ALARM): displaymode = SET_TIME; display_str("set time"); set_time(); timeunknown = 0; break; case (SET_TIME): displaymode = SET_DATE; display_str("set date"); set_date(); break; case (SET_DATE): displaymode = SET_BRIGHTNESS; display_str("set brit"); set_brightness(); break; case (SET_BRIGHTNESS): displaymode = SET_DIMMER; display_str("set dimr"); set_dimmer(); break; case (SET_DIMMER): displaymode = SET_VOLUME; display_str("set vol "); set_volume(); break; case (SET_VOLUME): displaymode = SET_REGION; display_str("set regn"); set_region(); break; /* case (SET_REGION): displaymode = SET_SNOOZE; display_str("set snoz"); set_snooze(); break; */ default: displaymode = SHOW_TIME; } } else if ((just_pressed & 0x2) || (just_pressed & 0x4)) { just_pressed = 0; displaymode = NONE; display_date(DAY); kickthedog(); delayms(1500); kickthedog(); displaymode = SHOW_TIME; } } }
int main(int argc, char **argv) { uint8_t speaker_no = 0; uint8_t speaker_total_no = 2; uint8_t get_char = 0; uint8_t n = 0; ER speaker_msg = 0; /* 模块初始化 */ // exc_init(); /* 中断初始化 */ //sys_timer_init(); /* 系统时钟初始化 */ speaker_init(); /* 蜂鸣器初始化 */ light_init(); //serial_initialize((intptr_t)(NULL)); /* 初始化串口 */ // printf("\n Welcome to k60 software platform! \n"); while(1) { speaker_msg = speaker_close(SPEAKER0); light_open(LIGHT0); } //printf(" *** This is a test for speaker module! *** \n"); // printf(" \n>>>> The speaker will be ringing! \n"); // for(speaker_no = 0; speaker_no < speaker_total_no; speaker_no++) // { // delay(200); // switch (speaker_no) // { // case 0: // speaker_msg = speaker_open(SPEAKER0); // break; // case 1: // speaker_msg = speaker_open(SPEAKER1); // break; // default: // //printf("The speaker number is error!\n"); // break; // // } // if (speaker_msg == E_ID) // { // //printf(" The ID of speaker%d is error!\n", speaker_no); // } // else if (speaker_msg == E_ILUSE) // { // // printf(" The port of speaker%d is not open!\n", speaker_no); // } // else // { // // printf(" The speaker%d is ringing now!\n", speaker_no); // } // } // // //printf(" \n>>>> The speaker will be not ringing! \n"); // for (speaker_no = 0; speaker_no < speaker_total_no; speaker_no++) // { // delay(200); // switch (speaker_no) // { // case 0: // speaker_msg = speaker_close(SPEAKER0); // break; // case 1: // speaker_msg = speaker_close(SPEAKER1); // break; // default: // //printf("The speaker number is error!"); // break; // // } // if (speaker_msg == E_ID) // { // // printf(" The ID of speaker%d is error !\n", speaker_no); // } // else if (speaker_msg == E_ILUSE) // { // //printf(" The port of speaker%d is not open!\n", speaker_no); // } // else // { // //printf(" The speaker%d is not ringing now!\n", speaker_no); // } // } // // //printf(" \n>>>> The speaker will change frequence! \n"); // // for(n=0;n<10;n++) // { // delay(10); // if(speaker_read(SPEAKER0)) // { // speaker_close(SPEAKER0); // } // else // { // speaker_open(SPEAKER0); // } // } // for(n=0;n<10;n++) // { // delay(5); // if(speaker_read(SPEAKER0)) // { // speaker_close(SPEAKER0); // } // else // { // speaker_open(SPEAKER0); // } // } // for(n=0;n<20;n++) // { // delay(1); // if(speaker_read(SPEAKER0)) // { // speaker_close(SPEAKER0); // } // else // { // speaker_open(SPEAKER0); // } // } // for(n=0;n<10;n++) // { // delay(10); // if(speaker_read(SPEAKER0)) // { // speaker_close(SPEAKER0); // } // else // { // speaker_open(SPEAKER0); // } // } // for(n=0;n<10;n++) // { // delay(20); // if(speaker_read(SPEAKER0)) // { // speaker_close(SPEAKER0); // } // else // { // speaker_open(SPEAKER0); // } // } // // speaker_close(SPEAKER0); // // printf(" \n>>>> A test for speaker module is over!\n"); // while (1) // { // // printf(" \n>>>> Press 'n' to test once more.\n"); // serial_rea_dat(NTSHELL_PORTID, &get_char, 1); // // if (get_char == 'n') // { // // printf("Once more \n"); // delay(200); // break; // } // } // } }
static void *cpu_thread(void *dummyptr) { #ifndef NDEBUG // Spamsung Galaxy Y running Gingerbread triggers this, wTf?! ASSERT_ON_CPU_THREAD(); #endif LOG("cpu_thread : initialized..."); struct timespec deltat = { 0 }; struct timespec disk_motor_time = { 0 }; struct timespec t0 = { 0 }; // the target timer struct timespec ti = { 0 }; // actual before time sample struct timespec tj = { 0 }; // actual after time sample bool negative = false; long drift_adj_nsecs = 0; // generic drift adjustment between target and actual int debugging_cycles = 0; unsigned long dbg_ticks = 0; #if DEBUG_TIMING int speaker_neg_feedback = 0; int speaker_pos_feedback = 0; unsigned long dbg_cycles_executed = 0; #endif audio_init(); speaker_init(); MB_Initialize(); run_args.emul_reinitialize = 1; cpu_runloop: do { LOG("CPUTHREAD %lu LOCKING FOR MAYBE INITIALIZING AUDIO ...", (unsigned long)cpu_thread_id); pthread_mutex_lock(&interface_mutex); if (emul_reinitialize_audio) { emul_reinitialize_audio = false; speaker_destroy(); extern void MB_SoftDestroy(void); MB_SoftDestroy(); audio_shutdown(); audio_init(); speaker_init(); extern void MB_SoftInitialize(void); MB_SoftInitialize(); } pthread_mutex_unlock(&interface_mutex); LOG("UNLOCKING FOR MAYBE INITIALIZING AUDIO ..."); if (run_args.emul_reinitialize) { reinitialize(); } LOG("cpu_thread : begin main loop ..."); clock_gettime(CLOCK_MONOTONIC, &t0); do { ////SCOPE_TRACE_CPU("CPU mainloop"); // -LOCK----------------------------------------------------------------------------------------- SAMPLE ti if (UNLIKELY(emul_pause_audio)) { emul_pause_audio = false; audio_pause(); } pthread_mutex_lock(&interface_mutex); if (UNLIKELY(emul_resume_audio)) { emul_resume_audio = false; audio_resume(); } if (UNLIKELY(emul_video_dirty)) { emul_video_dirty = false; video_setDirty(A2_DIRTY_FLAG); } clock_gettime(CLOCK_MONOTONIC, &ti); deltat = timespec_diff(t0, ti, &negative); if (deltat.tv_sec) { if (!is_fullspeed) { TIMING_LOG("NOTE : serious divergence from target time ..."); } t0 = ti; deltat = timespec_diff(t0, ti, &negative); } t0 = timespec_add(t0, EXECUTION_PERIOD_NSECS); // expected interval drift_adj_nsecs = negative ? ~deltat.tv_nsec : deltat.tv_nsec; // set up increment & decrement counters run_args.cpu65_cycles_to_execute = (cycles_persec_target / 1000); // cycles_persec_target * EXECUTION_PERIOD_NSECS / NANOSECONDS_PER_SECOND if (!is_fullspeed) { run_args.cpu65_cycles_to_execute += cycles_speaker_feedback; } if (run_args.cpu65_cycles_to_execute < 0) { run_args.cpu65_cycles_to_execute = 0; } MB_StartOfCpuExecute(); if (is_debugging) { debugging_cycles = run_args.cpu65_cycles_to_execute; } do { if (is_debugging) { run_args.cpu65_cycles_to_execute = 1; } run_args.cpu65_cycle_count = 0; cycles_checkpoint_count = 0; cpu65_run(&run_args); // run emulation for cpu65_cycles_to_execute cycles ... #if DEBUG_TIMING dbg_cycles_executed += run_args.cpu65_cycle_count; #endif if (is_debugging) { debugging_cycles -= run_args.cpu65_cycle_count; timing_checkpointCycles(); if (c_debugger_should_break() || (debugging_cycles <= 0)) { int err = 0; if ((err = pthread_cond_signal(&dbg_thread_cond))) { LOG("pthread_cond_signal : %d", err); } if ((err = pthread_cond_wait(&cpu_thread_cond, &interface_mutex))) { LOG("pthread_cond_wait : %d", err); } if (debugging_cycles <= 0) { break; } } if (run_args.emul_reinitialize) { pthread_mutex_unlock(&interface_mutex); goto cpu_runloop; } } } while (is_debugging); MB_UpdateCycles(); // TODO : modularize MB and other peripheral card cycles/interrupts ... speaker_flush(); // play audio TRACE_CPU_BEGIN("advance scanner"); video_scannerUpdate(); TRACE_CPU_END(); clock_gettime(CLOCK_MONOTONIC, &tj); pthread_mutex_unlock(&interface_mutex); // -UNLOCK--------------------------------------------------------------------------------------- SAMPLE tj if (timing_shouldAutoAdjustSpeed() && !is_fullspeed) { disk_motor_time = timespec_diff(disk6.motor_time, tj, &negative); if (UNLIKELY(negative)) { LOG("WHOA... time went backwards #1! Did you just cross a timezone?"); disk_motor_time.tv_sec = 1; } if (!speaker_isActive() && !video_isDirty(A2_DIRTY_FLAG) && (disk6.disk[disk6.drive].file_name != NULL) && !disk6.motor_off && (disk_motor_time.tv_sec || disk_motor_time.tv_nsec > DISK_MOTOR_QUIET_NSECS) ) { TIMING_LOG("auto switching to full speed"); _timing_initialize(CPU_SCALE_FASTEST); } } if (!is_fullspeed) { deltat = timespec_diff(ti, tj, &negative); if (UNLIKELY(negative)) { LOG("WHOA... time went backwards #2! Did you just cross a timezone?"); deltat.tv_sec = 1; } long sleepfor = 0; if (LIKELY(!deltat.tv_sec)) { sleepfor = EXECUTION_PERIOD_NSECS - drift_adj_nsecs - deltat.tv_nsec; } if (sleepfor <= 0) { // lagging ... static time_t throttle_warning = 0; if (t0.tv_sec - throttle_warning > 0) { TIMING_LOG("not sleeping to catch up ... %ld . %ld", deltat.tv_sec, deltat.tv_nsec); throttle_warning = t0.tv_sec; } } else { deltat.tv_sec = 0; deltat.tv_nsec = sleepfor; ////TRACE_CPU_BEGIN("sleep"); nanosleep(&deltat, NULL); ////TRACE_CPU_END(); } #if DEBUG_TIMING // collect timing statistics if (speaker_neg_feedback > cycles_speaker_feedback) { speaker_neg_feedback = cycles_speaker_feedback; } if (speaker_pos_feedback < cycles_speaker_feedback) { speaker_pos_feedback = cycles_speaker_feedback; } if ((dbg_ticks % NANOSECONDS_PER_SECOND) == 0) { TIMING_LOG("tick:(%ld.%ld) real:(%ld.%ld) cycles exe: %d ... speaker feedback: %d/%d", t0.tv_sec, t0.tv_nsec, ti.tv_sec, ti.tv_nsec, dbg_cycles_executed, speaker_neg_feedback, speaker_pos_feedback); dbg_cycles_executed = 0; speaker_neg_feedback = 0; speaker_pos_feedback = 0; } #endif if ((dbg_ticks % NANOSECONDS_PER_SECOND) == 0) { dbg_ticks = 0; } } if (timing_shouldAutoAdjustSpeed() && is_fullspeed) { disk_motor_time = timespec_diff(disk6.motor_time, tj, &negative); if (UNLIKELY(negative)) { LOG("WHOA... time went backwards #3! Did you just cross a timezone?"); disk_motor_time.tv_sec = 1; } if (speaker_isActive() || video_isDirty(A2_DIRTY_FLAG) || (disk6.motor_off && (disk_motor_time.tv_sec || disk_motor_time.tv_nsec > DISK_MOTOR_QUIET_NSECS)) ) { double speed = alt_speed_enabled ? cpu_altscale_factor : cpu_scale_factor; if (speed <= CPU_SCALE_FASTEST_PIVOT) { TIMING_LOG("auto switching to configured speed"); _timing_initialize(speed); } } } if (UNLIKELY(run_args.emul_reinitialize)) { break; } if (UNLIKELY(emul_reinitialize_audio)) { break; } if (UNLIKELY(cpu_shutting_down)) { break; } } while (1); if (UNLIKELY(cpu_shutting_down)) { break; } } while (1); speaker_destroy(); MB_Destroy(); audio_shutdown(); cpu_thread_id = 0; cpu_pause(); disk6_eject(0); disk6_eject(1); return NULL; }
static void *cpu_thread(void *dummyptr) { assert(pthread_self() == cpu_thread_id); LOG("cpu_thread : initialized..."); struct timespec deltat; #if !MOBILE_DEVICE struct timespec disk_motor_time; #endif struct timespec t0; // the target timer struct timespec ti, tj; // actual time samples bool negative = false; long drift_adj_nsecs = 0; // generic drift adjustment between target and actual int debugging_cycles0 = 0; int debugging_cycles = 0; #if DEBUG_TIMING unsigned long dbg_ticks = 0; int speaker_neg_feedback = 0; int speaker_pos_feedback = 0; unsigned int dbg_cycles_executed = 0; #endif do { #ifdef AUDIO_ENABLED LOG("CPUTHREAD %lu LOCKING FOR MAYBE INITIALIZING AUDIO ...", cpu_thread_id); pthread_mutex_lock(&interface_mutex); if (emul_reinitialize_audio) { emul_reinitialize_audio = false; speaker_destroy(); MB_Destroy(); audio_shutdown(); audio_init(); speaker_init(); MB_Initialize(); } pthread_mutex_unlock(&interface_mutex); LOG("UNLOCKING FOR MAYBE INITIALIZING AUDIO ..."); #endif if (emul_reinitialize) { reinitialize(); } LOG("cpu_thread : begin main loop ..."); clock_gettime(CLOCK_MONOTONIC, &t0); do { SCOPE_TRACE_CPU("CPU mainloop"); // -LOCK----------------------------------------------------------------------------------------- SAMPLE ti #ifdef AUDIO_ENABLED if (UNLIKELY(emul_pause_audio)) { emul_pause_audio = false; audio_pause(); } #endif pthread_mutex_lock(&interface_mutex); #ifdef AUDIO_ENABLED if (UNLIKELY(emul_resume_audio)) { emul_resume_audio = false; audio_resume(); } #endif clock_gettime(CLOCK_MONOTONIC, &ti); deltat = timespec_diff(t0, ti, &negative); if (deltat.tv_sec) { if (!is_fullspeed) { TIMING_LOG("NOTE : serious divergence from target time ..."); } t0 = ti; deltat = timespec_diff(t0, ti, &negative); } t0 = timespec_add(t0, EXECUTION_PERIOD_NSECS); // expected interval drift_adj_nsecs = negative ? ~deltat.tv_nsec : deltat.tv_nsec; // set up increment & decrement counters cpu65_cycles_to_execute = (cycles_persec_target / 1000); // cycles_persec_target * EXECUTION_PERIOD_NSECS / NANOSECONDS_PER_SECOND if (!is_fullspeed) { cpu65_cycles_to_execute += cycles_speaker_feedback; } if (cpu65_cycles_to_execute < 0) { cpu65_cycles_to_execute = 0; } #ifdef AUDIO_ENABLED MB_StartOfCpuExecute(); #endif if (is_debugging) { debugging_cycles0 = cpu65_cycles_to_execute; debugging_cycles = cpu65_cycles_to_execute; } do { if (is_debugging) { cpu65_cycles_to_execute = 1; } cpu65_cycle_count = 0; cycles_checkpoint_count = 0; cpu65_run(); // run emulation for cpu65_cycles_to_execute cycles ... if (is_debugging) { debugging_cycles -= cpu65_cycle_count; if (c_debugger_should_break() || (debugging_cycles <= 0)) { int err = 0; if ((err = pthread_cond_signal(&dbg_thread_cond))) { ERRLOG("pthread_cond_signal : %d", err); } if ((err = pthread_cond_wait(&cpu_thread_cond, &interface_mutex))) { ERRLOG("pthread_cond_wait : %d", err); } if (debugging_cycles <= 0) { cpu65_cycle_count = debugging_cycles0 - debugging_cycles/*<=0*/; break; } } } if (emul_reinitialize) { reinitialize(); } } while (is_debugging); #if DEBUG_TIMING dbg_cycles_executed += cpu65_cycle_count; #endif g_dwCyclesThisFrame += cpu65_cycle_count; #ifdef AUDIO_ENABLED MB_UpdateCycles(); // update 6522s (NOTE: do this before updating cycles_count_total) #endif timing_checkpoint_cycles(); #if CPU_TRACING cpu65_trace_checkpoint(); #endif #ifdef AUDIO_ENABLED speaker_flush(); // play audio #endif if (g_dwCyclesThisFrame >= dwClksPerFrame) { g_dwCyclesThisFrame -= dwClksPerFrame; #ifdef AUDIO_ENABLED MB_EndOfVideoFrame(); #endif } clock_gettime(CLOCK_MONOTONIC, &tj); pthread_mutex_unlock(&interface_mutex); // -UNLOCK--------------------------------------------------------------------------------------- SAMPLE tj #if !MOBILE_DEVICE if (timing_shouldAutoAdjustSpeed()) { disk_motor_time = timespec_diff(disk6.motor_time, tj, &negative); assert(!negative); if (!is_fullspeed && #ifdef AUDIO_ENABLED !speaker_isActive() && #endif !video_isDirty() && (!disk6.motor_off && (disk_motor_time.tv_sec || disk_motor_time.tv_nsec > DISK_MOTOR_QUIET_NSECS)) ) { TIMING_LOG("auto switching to full speed"); _timing_initialize(CPU_SCALE_FASTEST); } } #endif if (!is_fullspeed) { deltat = timespec_diff(ti, tj, &negative); assert(!negative); long sleepfor = 0; if (!deltat.tv_sec) { sleepfor = EXECUTION_PERIOD_NSECS - drift_adj_nsecs - deltat.tv_nsec; } if (sleepfor <= 0) { // lagging ... static time_t throttle_warning = 0; if (t0.tv_sec - throttle_warning > 0) { TIMING_LOG("not sleeping to catch up ... %ld . %ld", deltat.tv_sec, deltat.tv_nsec); throttle_warning = t0.tv_sec; } } else { deltat.tv_sec = 0; deltat.tv_nsec = sleepfor; TRACE_CPU_BEGIN("sleep"); nanosleep(&deltat, NULL); TRACE_CPU_END(); } #if DEBUG_TIMING // collect timing statistics if (speaker_neg_feedback > cycles_speaker_feedback) { speaker_neg_feedback = cycles_speaker_feedback; } if (speaker_pos_feedback < cycles_speaker_feedback) { speaker_pos_feedback = cycles_speaker_feedback; } dbg_ticks += EXECUTION_PERIOD_NSECS; if ((dbg_ticks % NANOSECONDS_PER_SECOND) == 0) { TIMING_LOG("tick:(%ld.%ld) real:(%ld.%ld) cycles exe: %d ... speaker feedback: %d/%d", t0.tv_sec, t0.tv_nsec, ti.tv_sec, ti.tv_nsec, dbg_cycles_executed, speaker_neg_feedback, speaker_pos_feedback); dbg_cycles_executed = 0; dbg_ticks = 0; speaker_neg_feedback = 0; speaker_pos_feedback = 0; } #endif } #if !MOBILE_DEVICE if (timing_shouldAutoAdjustSpeed()) { if (is_fullspeed && ( #ifdef AUDIO_ENABLED speaker_isActive() || #endif video_isDirty() || (disk6.motor_off && (disk_motor_time.tv_sec || disk_motor_time.tv_nsec > DISK_MOTOR_QUIET_NSECS))) ) { double speed = alt_speed_enabled ? cpu_altscale_factor : cpu_scale_factor; if (speed < CPU_SCALE_FASTEST) { TIMING_LOG("auto switching to configured speed"); _timing_initialize(speed); } } } #endif if (UNLIKELY(emul_reinitialize)) { break; } #ifdef AUDIO_ENABLED if (UNLIKELY(emul_reinitialize_audio)) { break; } #endif if (UNLIKELY(cpu_shutting_down)) { break; } } while (1); if (UNLIKELY(cpu_shutting_down)) { break; } } while (1); #ifdef AUDIO_ENABLED speaker_destroy(); MB_Destroy(); audio_shutdown(); #endif return NULL; }