1 |
|
/* |
2 |
|
* C64_x.h - Put the pieces together, X specific stuff |
3 |
|
* |
4 |
< |
* Frodo (C) 1994-1997,2002-2003 Christian Bauer |
4 |
> |
* Frodo Copyright (C) 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 |
95 |
|
} |
96 |
|
#endif |
97 |
|
|
98 |
+ |
#ifdef __linux__ |
99 |
+ |
// select() timing is much more accurate under Linux |
100 |
+ |
static void Delay_usec(unsigned long usec) |
101 |
+ |
{ |
102 |
+ |
int was_error; |
103 |
+ |
struct timeval tv; |
104 |
+ |
|
105 |
+ |
tv.tv_sec = 0; |
106 |
+ |
tv.tv_usec = usec; |
107 |
+ |
do { |
108 |
+ |
errno = 0; |
109 |
+ |
was_error = select(0, NULL, NULL, NULL, &tv); |
110 |
+ |
} while (was_error && (errno == EINTR)); |
111 |
+ |
} |
112 |
+ |
#else |
113 |
+ |
static void Delay_usec(unsigned long usec) |
114 |
+ |
{ |
115 |
+ |
usleep(usec); |
116 |
+ |
} |
117 |
+ |
#endif |
118 |
+ |
|
119 |
|
|
120 |
|
/* |
121 |
|
* Constructor, system-dependent things |
124 |
|
void C64::c64_ctor1(void) |
125 |
|
{ |
126 |
|
// Initialize joystick variables |
127 |
< |
joyfd[0] = joyfd[1] = -1; |
128 |
< |
joy_minx = joy_miny = 32767; |
129 |
< |
joy_maxx = joy_maxy = -32768; |
130 |
< |
|
110 |
< |
// we need to create a potential GUI subprocess here, because we don't want |
111 |
< |
// it to inherit file-descriptors (such as for the audio-device and alike..) |
112 |
< |
#if defined(__svgalib__) |
113 |
< |
gui = 0; |
114 |
< |
#else |
115 |
< |
// try to start up Tk gui. |
116 |
< |
gui = new CmdPipe("wish", BINDIR "Frodo_GUI.tcl"); |
117 |
< |
if (gui) { |
118 |
< |
if (gui->fail) { |
119 |
< |
delete gui; gui = 0; |
120 |
< |
} |
121 |
< |
} |
122 |
< |
// wait until the GUI process responds (if it does...) |
123 |
< |
if (gui) { |
124 |
< |
if (5 != gui->ewrite("ping\n",5)) { |
125 |
< |
delete gui; gui = 0; |
126 |
< |
} else { |
127 |
< |
char c; |
128 |
< |
fd_set set; |
129 |
< |
FD_ZERO(&set); |
130 |
< |
FD_SET(gui->get_read_fd(), &set); |
131 |
< |
struct timeval tv; |
132 |
< |
tv.tv_usec = 0; |
133 |
< |
tv.tv_sec = 5; |
134 |
< |
// Use the following commented line for HP-UX < 10.20 |
135 |
< |
// if (select(FD_SETSIZE, (int *)&set, (int *)NULL, (int *)NULL, &tv) <= 0) { |
136 |
< |
if (select(FD_SETSIZE, &set, NULL, NULL, &tv) <= 0) { |
137 |
< |
delete gui; gui = 0; |
138 |
< |
} else { |
139 |
< |
if (1 != gui->eread(&c, 1)) { |
140 |
< |
delete gui; gui = 0; |
141 |
< |
} else { |
142 |
< |
if (c != 'o') { |
143 |
< |
delete gui; gui = 0; |
144 |
< |
} |
145 |
< |
} |
146 |
< |
} |
147 |
< |
} |
148 |
< |
} |
149 |
< |
#endif // __svgalib__ |
127 |
> |
joy_minx[0] = joy_miny[0] = 32767; |
128 |
> |
joy_maxx[0] = joy_maxy[0] = -32768; |
129 |
> |
joy_minx[1] = joy_miny[1] = 32767; |
130 |
> |
joy_maxx[1] = joy_maxy[1] = -32768; |
131 |
|
} |
132 |
|
|
133 |
|
void C64::c64_ctor2(void) |
134 |
|
{ |
135 |
< |
#ifndef __svgalib__ |
136 |
< |
if (!gui) { |
137 |
< |
fprintf(stderr,"Alas, master, no preferences window will be available.\n" |
138 |
< |
"If you wish to see one, make sure the 'wish' interpreter\n" |
158 |
< |
"(Tk version >= 4.1) is installed in your path.\n" |
159 |
< |
"You can still use Frodo, though. Use F10 to quit, \n" |
160 |
< |
"F11 to cause an NMI and F12 to reset the C64.\n" |
161 |
< |
"You can change the preferences by editing ~/.frodorc\n"); |
162 |
< |
} |
163 |
< |
#endif // SVGAlib |
135 |
> |
printf("Use F9 to enter the SAM machine language monitor,\n" |
136 |
> |
"F10 to edit preferences or quit,\n" |
137 |
> |
"F11 to cause an NMI (RESTORE key) and\n" |
138 |
> |
"F12 to reset the C64.\n\n"); |
139 |
|
|
140 |
|
gettimeofday(&tv_start, NULL); |
141 |
|
} |
221 |
|
|
222 |
|
// Limit speed to 100% if desired |
223 |
|
if ((speed_index > 100) && ThePrefs.LimitSpeed) { |
224 |
< |
usleep((unsigned long)(ThePrefs.SkipFrames * 20000 - elapsed_time)); |
224 |
> |
Delay_usec((unsigned long)(ThePrefs.SkipFrames * 20000 - elapsed_time)); |
225 |
|
speed_index = 100; |
226 |
|
} |
227 |
|
|
233 |
|
|
234 |
|
|
235 |
|
/* |
261 |
– |
* Open/close joystick drivers given old and new state of |
262 |
– |
* joystick preferences |
263 |
– |
*/ |
264 |
– |
|
265 |
– |
void C64::open_close_joysticks(int oldjoy1, int oldjoy2, int newjoy1, int newjoy2) |
266 |
– |
{ |
267 |
– |
#ifdef HAVE_LINUX_JOYSTICK_H |
268 |
– |
if (oldjoy1 != newjoy1) { |
269 |
– |
joy_minx = joy_miny = 32767; // Reset calibration |
270 |
– |
joy_maxx = joy_maxy = -32768; |
271 |
– |
if (newjoy1) { |
272 |
– |
joyfd[0] = open("/dev/js0", O_RDONLY); |
273 |
– |
if (joyfd[0] < 0) |
274 |
– |
fprintf(stderr, "Couldn't open joystick 1\n"); |
275 |
– |
} else { |
276 |
– |
close(joyfd[0]); |
277 |
– |
joyfd[0] = -1; |
278 |
– |
} |
279 |
– |
} |
280 |
– |
|
281 |
– |
if (oldjoy2 != newjoy2) { |
282 |
– |
joy_minx = joy_miny = 32767; // Reset calibration |
283 |
– |
joy_maxx = joy_maxy = -32768; |
284 |
– |
if (newjoy2) { |
285 |
– |
joyfd[1] = open("/dev/js1", O_RDONLY); |
286 |
– |
if (joyfd[1] < 0) |
287 |
– |
fprintf(stderr, "Couldn't open joystick 2\n"); |
288 |
– |
} else { |
289 |
– |
close(joyfd[1]); |
290 |
– |
joyfd[1] = -1; |
291 |
– |
} |
292 |
– |
} |
293 |
– |
#endif |
294 |
– |
} |
295 |
– |
|
296 |
– |
|
297 |
– |
/* |
298 |
– |
* Poll joystick port, return CIA mask |
299 |
– |
*/ |
300 |
– |
|
301 |
– |
uint8 C64::poll_joystick(int port) |
302 |
– |
{ |
303 |
– |
#ifdef HAVE_LINUX_JOYSTICK_H |
304 |
– |
JS_DATA_TYPE js; |
305 |
– |
uint8 j = 0xff; |
306 |
– |
|
307 |
– |
if (joyfd[port] >= 0) { |
308 |
– |
if (read(joyfd[port], &js, JS_RETURN) == JS_RETURN) { |
309 |
– |
if (js.x > joy_maxx) |
310 |
– |
joy_maxx = js.x; |
311 |
– |
if (js.x < joy_minx) |
312 |
– |
joy_minx = js.x; |
313 |
– |
if (js.y > joy_maxy) |
314 |
– |
joy_maxy = js.y; |
315 |
– |
if (js.y < joy_miny) |
316 |
– |
joy_miny = js.y; |
317 |
– |
|
318 |
– |
if (joy_maxx-joy_minx < 100 || joy_maxy-joy_miny < 100) |
319 |
– |
return 0xff; |
320 |
– |
|
321 |
– |
if (js.x < (joy_minx + (joy_maxx-joy_minx)/3)) |
322 |
– |
j &= 0xfb; // Left |
323 |
– |
else if (js.x > (joy_minx + 2*(joy_maxx-joy_minx)/3)) |
324 |
– |
j &= 0xf7; // Right |
325 |
– |
|
326 |
– |
if (js.y < (joy_miny + (joy_maxy-joy_miny)/3)) |
327 |
– |
j &= 0xfe; // Up |
328 |
– |
else if (js.y > (joy_miny + 2*(joy_maxy-joy_miny)/3)) |
329 |
– |
j &= 0xfd; // Down |
330 |
– |
|
331 |
– |
if (js.buttons & 1) |
332 |
– |
j &= 0xef; // Button |
333 |
– |
} |
334 |
– |
} |
335 |
– |
return j; |
336 |
– |
#else |
337 |
– |
return 0xff; |
338 |
– |
#endif |
339 |
– |
} |
340 |
– |
|
341 |
– |
|
342 |
– |
/* |
236 |
|
* The emulation's main loop |
237 |
|
*/ |
238 |
|
|
239 |
|
void C64::thread_func(void) |
240 |
|
{ |
348 |
– |
int linecnt = 0; |
349 |
– |
|
241 |
|
#ifdef FRODO_SC |
242 |
|
while (!quit_thyself) { |
243 |
|
|
286 |
|
// 1541 processor disabled, only emulate 6510 |
287 |
|
TheCPU->EmulateLine(cycles); |
288 |
|
#endif |
398 |
– |
linecnt++; |
399 |
– |
#if !defined(__svgalib__) |
400 |
– |
if ((linecnt & 0xfff) == 0 && gui) { |
401 |
– |
|
402 |
– |
// check for command from GUI process |
403 |
– |
// fprintf(stderr,":"); |
404 |
– |
while (gui->probe()) { |
405 |
– |
char c; |
406 |
– |
if (gui->eread(&c, 1) != 1) { |
407 |
– |
delete gui; |
408 |
– |
gui = 0; |
409 |
– |
fprintf(stderr,"Oops, GUI process died...\n"); |
410 |
– |
} else { |
411 |
– |
// fprintf(stderr,"%c",c); |
412 |
– |
switch (c) { |
413 |
– |
case 'q': |
414 |
– |
quit_thyself = true; |
415 |
– |
break; |
416 |
– |
case 'r': |
417 |
– |
Reset(); |
418 |
– |
break; |
419 |
– |
case 'p':{ |
420 |
– |
Prefs *np = Frodo::reload_prefs(); |
421 |
– |
NewPrefs(np); |
422 |
– |
ThePrefs = *np; |
423 |
– |
break; |
424 |
– |
} |
425 |
– |
default: |
426 |
– |
break; |
427 |
– |
} |
428 |
– |
} |
429 |
– |
} |
430 |
– |
} |
431 |
– |
#endif |
432 |
– |
} |
433 |
– |
#if !defined(__svgalib__) |
434 |
– |
if (gui) { |
435 |
– |
gui->ewrite("quit\n",5); |
289 |
|
} |
290 |
< |
#endif |
290 |
> |
} |
291 |
> |
|
292 |
> |
|
293 |
> |
/* |
294 |
> |
* Pause main emulation thread |
295 |
> |
*/ |
296 |
> |
|
297 |
> |
void C64::Pause(void) |
298 |
> |
{ |
299 |
> |
TheSID->PauseSound(); |
300 |
> |
} |
301 |
> |
|
302 |
> |
|
303 |
> |
/* |
304 |
> |
* Resume main emulation thread |
305 |
> |
*/ |
306 |
> |
|
307 |
> |
void C64::Resume(void) |
308 |
> |
{ |
309 |
> |
TheSID->ResumeSound(); |
310 |
|
} |