| 5479 | } |
| 5480 | |
| 5481 | static void run_cpu_thread(int (*f)(void *)) |
| 5482 | { |
| 5483 | int vp = 0; |
| 5484 | int intlev_prev = 0; |
| 5485 | int cck_cnt = 0; |
| 5486 | |
| 5487 | cpu_thread_active = 0; |
| 5488 | cpu_thread_tid = 0; |
| 5489 | cpu_thread_indirect_mode = 0xff; |
| 5490 | atomic_set(&cpu_thread_reset, 0); |
| 5491 | |
| 5492 | uae_sem_init(&cpu_in_sema, 0, 0); |
| 5493 | uae_sem_init(&cpu_out_sema, 0, 0); |
| 5494 | uae_sem_init(&cpu_wakeup_sema, 0, 0); |
| 5495 | |
| 5496 | if (!uae_start_thread(_T("cpu"), f, nullptr, &cpu_thread)) |
| 5497 | return; |
| 5498 | cpu_thread_tid = uae_thread_get_id(cpu_thread); |
| 5499 | while (!cpu_thread_active) { |
| 5500 | sleep_millis(1); |
| 5501 | } |
| 5502 | |
| 5503 | while (!(regs.spcflags & SPCFLAG_MODE_CHANGE)) { |
| 5504 | if (regs.spcflags & SPCFLAG_CALLBACK) { |
| 5505 | unset_special(SPCFLAG_CALLBACK); |
| 5506 | device_call_main_thread_callbacks(); |
| 5507 | } |
| 5508 | |
| 5509 | // Service any pending indirect memory request (lockless fast path) |
| 5510 | service_cpu_indirect_request(); |
| 5511 | |
| 5512 | // Flush any batched register operations from the CPU thread |
| 5513 | cpu_thread_flush_register_batch(); |
| 5514 | |
| 5515 | // Check for CPU reset request |
| 5516 | uae_u32 reset_val = __atomic_load_n(&cpu_thread_reset, __ATOMIC_ACQUIRE); |
| 5517 | if (reset_val & 1) { |
| 5518 | bool hardreset = reset_val & 2; |
| 5519 | bool keyboardreset = reset_val & 4; |
| 5520 | custom_reset(hardreset, keyboardreset); |
| 5521 | __atomic_store_n(&cpu_thread_reset, 0, __ATOMIC_RELEASE); |
| 5522 | uae_sem_post(&cpu_in_sema); |
| 5523 | } |
| 5524 | |
| 5525 | // Advance time - determine how many CCKs to run before re-checking IO |
| 5526 | // When idle (no pending request), run more cycles per iteration. |
| 5527 | // When a request just completed, re-check immediately after 1 cycle. |
| 5528 | int cycles_to_do; |
| 5529 | if (__atomic_load_n(&cpu_thread_indirect_mode, __ATOMIC_RELAXED) > 2) { |
| 5530 | cycles_to_do = currprefs.m68k_speed < 0 ? 256 : 128; |
| 5531 | } else { |
| 5532 | cycles_to_do = 1; |
| 5533 | } |
| 5534 | |
| 5535 | for (int i = 0; i < cycles_to_do; i++) { |
| 5536 | // Check for incoming IO request EVERY cycle for minimal latency |
| 5537 | if (i > 0 && service_cpu_indirect_request()) { |
| 5538 | // Serviced a request - flush register batch too while we're at it |
no test coverage detected