@@ -70,7 +70,7 @@ static int s_crash_count = 0;
7070static unsigned long s_respawn_timer = 0 ;
7171static unsigned long s_tty_deadline = 0 ;
7272static unsigned long s_native_status_timer = 0 ;
73- static unsigned long s_native_fb_mode_timer = 0 ;
73+ static unsigned long s_native_crt_finish_timer = 0 ;
7474static bool s_gave_up = false ;
7575static bool s_init_pending = false ;
7676static bool s_native_crt = false ;
@@ -82,6 +82,8 @@ static const char s_tty_path[] = "/dev/tty2";
8282static const char s_fb_mode_path[] = " /sys/module/MiSTer_fb/parameters/mode" ;
8383static const char s_crt_state_file[] = " zaparoo_launcher_crt.bin" ;
8484static const char s_offsets_file[] = " zaparoo_video_offsets.bin" ;
85+ static char s_saved_fb_mode[64 ];
86+ static bool s_saved_fb_mode_valid = false ;
8587
8688static int8_t s_h_offset = 0 ;
8789static int8_t s_v_offset = 0 ;
@@ -135,9 +137,48 @@ static void set_launcher_fb_mode(int fmt, int rb, int width, int height, int str
135137 printf (" alt_launcher: fb mode set to %dx%d fmt=%d stride=%d\n " , width, height, fmt, stride);
136138}
137139
138- static void set_native_crt_fb_mode ( bool log = true )
140+ static void save_current_fb_mode ( void )
139141{
140- set_launcher_fb_mode (8888 , 1 , 320 , 240 , 1280 , log);
142+ if (s_saved_fb_mode_valid)
143+ return ;
144+
145+ FILE *fp = fopen (s_fb_mode_path, " rt" );
146+ if (!fp)
147+ {
148+ printf (" alt_launcher: unable to read fb mode: %s\n " , strerror (errno));
149+ return ;
150+ }
151+
152+ if (fgets (s_saved_fb_mode, sizeof (s_saved_fb_mode), fp))
153+ {
154+ size_t len = strlen (s_saved_fb_mode);
155+ while (len && (s_saved_fb_mode[len - 1 ] == ' \n ' || s_saved_fb_mode[len - 1 ] == ' \r ' ))
156+ s_saved_fb_mode[--len] = 0 ;
157+ s_saved_fb_mode_valid = len != 0 ;
158+ if (s_saved_fb_mode_valid)
159+ printf (" alt_launcher: saved fb mode '%s'\n " , s_saved_fb_mode);
160+ }
161+ fclose (fp);
162+ }
163+
164+ static void restore_saved_fb_mode (void )
165+ {
166+ if (!s_saved_fb_mode_valid)
167+ {
168+ set_launcher_fb_mode (8888 , 1 , 960 , 720 , 3840 );
169+ return ;
170+ }
171+
172+ FILE *fp = fopen (s_fb_mode_path, " wt" );
173+ if (!fp)
174+ {
175+ printf (" alt_launcher: unable to restore fb mode: %s\n " , strerror (errno));
176+ return ;
177+ }
178+
179+ fprintf (fp, " %s\n " , s_saved_fb_mode);
180+ fclose (fp);
181+ printf (" alt_launcher: restored fb mode '%s'\n " , s_saved_fb_mode);
141182}
142183
143184static void blank_native_crt_fb (void )
@@ -228,31 +269,33 @@ static void disable_native_crt_path(void)
228269 user_io_status_set (" [9]" , 0 );
229270 video_fb_enable (0 );
230271 set_vga_fb (0 );
231- set_launcher_fb_mode (8888 , 1 , 960 , 720 , 3840 );
272+ restore_saved_fb_mode ();
273+ s_tty_deadline = 0 ;
232274 s_native_status_timer = 0 ;
233- s_native_fb_mode_timer = 0 ;
275+ s_native_crt_finish_timer = 0 ;
234276}
235277
236- static void enable_native_crt_path (void )
278+ static void prepare_native_crt_path (void )
237279{
238280 set_vga_fb (0 );
239281 video_fb_enable (0 );
282+ save_current_fb_mode ();
283+ s_native_crt_finish_timer = GetTimer (1 );
284+ if (!s_native_crt_finish_timer) s_native_crt_finish_timer = 1 ;
285+ }
240286
241- // Double-write with a settle window so the kernel module's 320x240 layout
242- // is live before status[9] flips. Without this, the frontend renders for
243- // up to a second under stale dims (the post-fork retry timer used to be
244- // what eventually fixed the picture).
245- set_native_crt_fb_mode (false );
246- usleep (100000 );
247- set_native_crt_fb_mode ();
287+ static void finish_native_crt_path (void )
288+ {
289+ // Main_MiSTer does not program the launcher framebuffer mode. The
290+ // frontend owns its linuxfb `vmode`; this side only blanks the native DDR
291+ // scan-out buffer before status[9] routes the FPGA to it.
292+ s_native_crt_finish_timer = 0 ;
248293
249294 blank_native_crt_fb ();
250295
251296 user_io_status_set (" [9]" , 1 );
252297 s_native_status_timer = GetTimer (500 );
253298 if (!s_native_status_timer) s_native_status_timer = 1 ;
254- s_native_fb_mode_timer = GetTimer (1000 );
255- if (!s_native_fb_mode_timer) s_native_fb_mode_timer = 1 ;
256299}
257300
258301static void return_to_normal_mode (void )
@@ -274,6 +317,8 @@ static void reset_launcher_state(void)
274317 s_pid = 0 ;
275318 s_respawn_timer = 0 ;
276319 s_tty_deadline = 0 ;
320+ s_native_status_timer = 0 ;
321+ s_native_crt_finish_timer = 0 ;
277322 s_crash_count = 0 ;
278323 s_gave_up = false ;
279324 s_init_pending = false ;
@@ -392,8 +437,8 @@ static void spawn(void)
392437 printf (" alt_launcher: native_crt=%d\n " , s_native_crt);
393438 if (s_native_crt)
394439 {
395- enable_native_crt_path ();
396- printf (" alt_launcher: native CRT path enabled \n " );
440+ prepare_native_crt_path ();
441+ printf (" alt_launcher: native CRT path prepared \n " );
397442 }
398443 else
399444 {
@@ -427,7 +472,7 @@ bool alt_launcher_active(void)
427472
428473bool alt_launcher_scheduler_sleep_enabled (void )
429474{
430- return s_pid || s_init_pending || s_respawn_timer || s_tty_deadline;
475+ return s_pid || s_init_pending || s_respawn_timer || s_tty_deadline || s_native_crt_finish_timer ;
431476}
432477
433478bool alt_launcher_native_crt (void )
@@ -529,19 +574,19 @@ void alt_launcher_poll(void)
529574{
530575 if (s_pid)
531576 {
577+ if (s_native_crt && s_native_crt_finish_timer && CheckTimer (s_native_crt_finish_timer))
578+ {
579+ finish_native_crt_path ();
580+ printf (" alt_launcher: native CRT path enabled\n " );
581+ }
582+
532583 if (s_native_crt && s_native_status_timer && CheckTimer (s_native_status_timer))
533584 {
534585 user_io_status_set (" [9]" , 1 );
535586 s_native_status_timer = GetTimer (500 );
536587 if (!s_native_status_timer) s_native_status_timer = 1 ;
537588 }
538589
539- if (s_native_crt && s_native_fb_mode_timer && CheckTimer (s_native_fb_mode_timer))
540- {
541- set_native_crt_fb_mode ();
542- s_native_fb_mode_timer = 0 ;
543- }
544-
545590 int status;
546591 if (waitpid (s_pid, &status, WNOHANG ) == s_pid)
547592 {
@@ -584,7 +629,7 @@ void alt_launcher_poll(void)
584629 return ;
585630 }
586631
587- if (s_tty_deadline && (launcher_tty_ready (s_pid) || CheckTimer (s_tty_deadline)))
632+ if (s_tty_deadline && !s_native_crt_finish_timer && (launcher_tty_ready (s_pid) || CheckTimer (s_tty_deadline)))
588633 finalize_spawn ();
589634 return ;
590635 }
0 commit comments