1 |
|
/* |
2 |
|
* main_unix.cpp - Startup code for Unix |
3 |
|
* |
4 |
< |
* Basilisk II (C) 1997-2000 Christian Bauer |
4 |
> |
* Basilisk II (C) 1997-2001 Christian Bauer |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
195 |
|
* Main program |
196 |
|
*/ |
197 |
|
|
198 |
+ |
static void usage(const char *prg_name) |
199 |
+ |
{ |
200 |
+ |
printf("Usage: %s [OPTION...]\n", prg_name); |
201 |
+ |
printf("\nUnix options:\n"); |
202 |
+ |
printf(" --display STRING\n X display to use\n"); |
203 |
+ |
printf(" --break ADDRESS\n set ROM breakpoint\n"); |
204 |
+ |
printf(" --rominfo\n dump ROM information\n"); |
205 |
+ |
PrefsPrintUsage(); |
206 |
+ |
exit(0); |
207 |
+ |
} |
208 |
+ |
|
209 |
|
int main(int argc, char **argv) |
210 |
|
{ |
211 |
|
char str[256]; |
227 |
|
x_display_name = gdk_get_display(); // gtk_init() handles and removes the "--display" argument |
228 |
|
#endif |
229 |
|
|
230 |
< |
// Parse and remove arguments |
230 |
> |
// Read preferences |
231 |
> |
PrefsInit(argc, argv); |
232 |
> |
|
233 |
> |
// Parse command line arguments |
234 |
|
for (int i=1; i<argc; i++) { |
235 |
< |
if (strcmp(argv[i], "--display") == 0) { |
236 |
< |
argv[i] = NULL; |
237 |
< |
if ((i + 1) < argc && argv[i + 1]) { |
238 |
< |
argv[i++] = NULL; |
235 |
> |
if (strcmp(argv[i], "--help") == 0) { |
236 |
> |
usage(argv[0]); |
237 |
> |
} else if (strcmp(argv[i], "--display") == 0) { |
238 |
> |
i++; |
239 |
> |
if (i < argc) |
240 |
|
x_display_name = strdup(argv[i]); |
226 |
– |
} |
241 |
|
} else if (strcmp(argv[i], "--break") == 0) { |
242 |
< |
argv[i] = NULL; |
243 |
< |
if ((i + 1) < argc && argv[i + 1]) { |
230 |
< |
argv[i++] = NULL; |
242 |
> |
i++; |
243 |
> |
if (i < argc) |
244 |
|
ROMBreakpoint = strtol(argv[i], NULL, 0); |
232 |
– |
} |
245 |
|
} else if (strcmp(argv[i], "--rominfo") == 0) { |
234 |
– |
argv[i] = NULL; |
246 |
|
PrintROMInfo = true; |
247 |
< |
} |
248 |
< |
} |
249 |
< |
for (int i=1; i<argc; i++) { |
239 |
< |
int k; |
240 |
< |
for (k=i; k<argc; k++) |
241 |
< |
if (argv[k] != NULL) |
242 |
< |
break; |
243 |
< |
if (k > i) { |
244 |
< |
k -= i; |
245 |
< |
for (int j=i+k; j<argc; j++) |
246 |
< |
argv[j-k] = argv[j]; |
247 |
< |
argc -= k; |
247 |
> |
} else if (argv[i][0] == '-') { |
248 |
> |
fprintf(stderr, "Unrecognized option '%s'\n", argv[i]); |
249 |
> |
usage(argv[0]); |
250 |
|
} |
251 |
|
} |
252 |
|
|
264 |
|
XF86DGAForkApp(DefaultScreen(x_display)); |
265 |
|
#endif |
266 |
|
|
265 |
– |
// Read preferences |
266 |
– |
PrefsInit(argc, argv); |
267 |
– |
|
267 |
|
// Init system routines |
268 |
|
SysInit(); |
269 |
|
|
773 |
|
{ |
774 |
|
while (!xpram_thread_cancel) { |
775 |
|
for (int i=0; i<60 && !xpram_thread_cancel; i++) |
776 |
< |
Delay_usec(999999); |
776 |
> |
Delay_usec(999999); // Only wait 1 second so we quit promptly when xpram_thread_cancel becomes true |
777 |
|
xpram_watchdog(); |
778 |
|
} |
779 |
|
return NULL; |
868 |
|
// Linux select() changes its timeout parameter upon return to contain |
869 |
|
// the remaining time. Most other unixen leave it unchanged or undefined. |
870 |
|
#define SELECT_SETS_REMAINING |
871 |
< |
#elif defined(__FreeBSD__) || defined(__sun__) || defined(sgi) |
871 |
> |
#elif defined(__FreeBSD__) || defined(__sun__) |
872 |
|
#define USE_NANOSLEEP |
873 |
+ |
#elif defined(HAVE_PTHREADS) && defined(sgi) |
874 |
+ |
// SGI pthreads has a bug when using pthreads+signals+nanosleep, |
875 |
+ |
// so instead of using nanosleep, wait on a CV which is never signalled. |
876 |
+ |
#define USE_COND_TIMEDWAIT |
877 |
|
#endif |
878 |
|
|
879 |
|
void Delay_usec(uint32 usec) |
880 |
|
{ |
881 |
|
int was_error; |
882 |
|
|
883 |
< |
#ifdef USE_NANOSLEEP |
883 |
> |
#if defined(USE_NANOSLEEP) |
884 |
|
struct timespec elapsed, tv; |
885 |
+ |
#elif defined(USE_COND_TIMEDWAIT) |
886 |
+ |
// Use a local mutex and cv, so threads remain independent |
887 |
+ |
pthread_cond_t delay_cond = PTHREAD_COND_INITIALIZER; |
888 |
+ |
pthread_mutex_t delay_mutex = PTHREAD_MUTEX_INITIALIZER; |
889 |
+ |
struct timespec elapsed; |
890 |
+ |
uint64 future; |
891 |
|
#else |
892 |
|
struct timeval tv; |
893 |
|
#ifndef SELECT_SETS_REMAINING |
896 |
|
#endif |
897 |
|
|
898 |
|
// Set the timeout interval - Linux only needs to do this once |
899 |
< |
#ifdef SELECT_SETS_REMAINING |
899 |
> |
#if defined(SELECT_SETS_REMAINING) |
900 |
|
tv.tv_sec = 0; |
901 |
|
tv.tv_usec = usec; |
902 |
|
#elif defined(USE_NANOSLEEP) |
903 |
|
elapsed.tv_sec = 0; |
904 |
|
elapsed.tv_nsec = usec * 1000; |
905 |
+ |
#elif defined(USE_COND_TIMEDWAIT) |
906 |
+ |
future = GetTicks_usec() + usec; |
907 |
+ |
elapsed.tv_sec = future / 1000000; |
908 |
+ |
elapsed.tv_nsec = (future % 1000000) * 1000; |
909 |
|
#else |
910 |
|
then = GetTicks_usec(); |
911 |
|
#endif |
912 |
|
|
913 |
|
do { |
914 |
|
errno = 0; |
915 |
< |
#ifdef USE_NANOSLEEP |
915 |
> |
#if defined(USE_NANOSLEEP) |
916 |
|
tv.tv_sec = elapsed.tv_sec; |
917 |
|
tv.tv_nsec = elapsed.tv_nsec; |
918 |
|
was_error = nanosleep(&tv, &elapsed); |
919 |
+ |
#elif defined(USE_COND_TIMEDWAIT) |
920 |
+ |
was_error = pthread_mutex_lock(&delay_mutex); |
921 |
+ |
was_error = pthread_cond_timedwait(&delay_cond, &delay_mutex, &elapsed); |
922 |
+ |
was_error = pthread_mutex_unlock(&delay_mutex); |
923 |
|
#else |
924 |
|
#ifndef SELECT_SETS_REMAINING |
925 |
|
// Calculate the time interval left (in case of interrupt) |