1 /************************************************************************/
2 /* QUASI88 --- PC-8801 emulator */
3 /* Copyright (c) 1998-2012 Showzoh Fukunaga */
4 /* All rights reserved. */
5 /* */
6 /* ���Υ��եȤϡ�UNIX + X Window System �δĶ���ư��롢 */
7 /* PC-8801 �Υ��ߥ�졼���Ǥ��� */
8 /* */
9 /* ���Υ��եȤκ����ˤ����ꡢMarat Fayzullin���� fMSX�� */
10 /* Nicola Salmoria�� (MAME/XMAME project) ��� MAME/XMAME�� */
11 /* ��ߤ������ PC6001V �Υ������ͤˤ����Ƥ�餤�ޤ����� */
12 /* */
13 /* ����ա� */
14 /* ������ɥɥ饤�Фϡ�MAME/XMAME �Υ�������ή�Ѥ��Ƥ��ޤ��� */
15 /* ������ʬ�Υ�����������ϡ�MAME/XMAME �����ढ�뤤�ϥ������� */
16 /* ���ܤ��Ƥ�������Ԥˤ���ޤ��� */
17 /* FM���������ͥ졼���ϡ�fmgen �Υ�������ή�Ѥ��Ƥ��ޤ��� */
18 /* ������ʬ�Υ�����������ϡ� cisc�� �ˤ���ޤ��� */
19 /* */
20 /************************************************************************/
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26
27 #include "quasi88.h"
28 #include "initval.h"
29
30 #include "pc88main.h"
31 #include "pc88sub.h"
32 #include "graph.h"
33 #include "memory.h"
34 #include "file-op.h"
35
36 #include "emu.h"
37 #include "drive.h"
38 #include "event.h"
39 #include "keyboard.h"
40 #include "monitor.h"
41 #include "snddrv.h"
42 #include "wait.h"
43 #include "status.h"
44 #include "suspend.h"
45 #include "snapshot.h"
46 #include "soundbd.h"
47 #include "screen.h"
48 #include "menu.h"
49 #include "pause.h"
50 #include "z80.h"
51 #include "intr.h"
52
53
54 int verbose_level = DEFAULT_VERBOSE; /* ��Ĺ��٥� */
55 int verbose_proc = FALSE; /* �����οʹԾ�����ɽ�� */
56 int verbose_z80 = FALSE; /* Z80�������顼��ɽ�� */
57 int verbose_io = FALSE; /* ̤����I/O��������ɽ��*/
58 int verbose_pio = FALSE; /* PIO ���������Ѥ�ɽ�� */
59 int verbose_fdc = FALSE; /* FD������۾����� */
60 int verbose_wait = FALSE; /* �������Ȼ��ΰ۾����� */
61 int verbose_suspend = FALSE; /* �����ڥ�ɻ��ΰ۾����� */
62 int verbose_snd = FALSE; /* ������ɤΥ�å����� */
63
64 static void imagefile_all_open(int stateload);
65 static void imagefile_all_close(void);
66 static void status_override(void);
67
68 /***********************************************************************
69 *
70 * QUASI88 �ᥤ��ؿ�
71 *
72 ************************************************************************/
quasi88(void)73 void quasi88(void)
74 {
75 quasi88_start();
76 quasi88_main();
77 quasi88_stop(TRUE);
78 }
79
80 /* =========================== �ᥤ������ν���� ========================== */
81
82 #define SET_PROC(n) proc = n; if (verbose_proc) printf("\n"); fflush(NULL);
83 static int proc = 0;
84
quasi88_start(void)85 void quasi88_start(void)
86 {
87 stateload_init(); /* ���ơ��ȥ��ɴ�Ϣ����� */
88 drive_init(); /* �ǥ���������Υ������� */
89 /* �� �����ϡ����ơ��ȥ��ɳ��ϤޤǤ˽�������Ƥ������� */
90
91 SET_PROC(1);
92
93 /* ���ߥ�졼���ѥ���γ��� */
94 if (memory_allocate() == FALSE) { quasi88_exit(-1); }
95
96 if (resume_flag) { /* ���ơ��ȥ��� */
97 SET_PROC(2);
98 if (stateload() == FALSE) {
99 fprintf(stderr, "stateload: Failed ! (filename = %s)\n",
100 filename_get_state());
101 quasi88_exit(-1);
102 }
103 if (verbose_proc) printf("Stateload...OK\n"); fflush(NULL);
104 }
105 SET_PROC(3);
106
107 /* ����ե��å������ƥ����� */
108 if (screen_init() == FALSE) { quasi88_exit(-1); }
109 SET_PROC(4);
110
111 /* �����ƥ।�٥�Ƚ���� */
112 event_init(); /* (screen_init �θ�ǡ�) */
113
114 /* ������ɥɥ饤�н���� */
115 if (xmame_sound_start() == FALSE) { quasi88_exit(-1); }
116 SET_PROC(5);
117
118 /* ���������ѥ����ޡ������ */
119 if (wait_vsync_init() == FALSE) { quasi88_exit(-1); }
120 SET_PROC(6);
121
122
123 set_signal(); /* INT�����ʥ�ν��������� */
124
125 imagefile_all_open(resume_flag); /* ������ե���������Ƴ��� */
126
127 /* ���ߥ��ѥ����缡����� */
128 pc88main_init((resume_flag) ? INIT_STATELOAD : INIT_POWERON);
129 pc88sub_init ((resume_flag) ? INIT_STATELOAD : INIT_POWERON);
130
131 key_record_playback_init(); /* �������ϵ�Ͽ/���� ����� */
132
133 screen_snapshot_init(); /* ���ʥåץ���åȴ�Ϣ����� */
134
135
136 debuglog_init();
137 profiler_init();
138
139 emu_breakpoint_init();
140
141 if (verbose_proc) printf("Running QUASI88...\n");
142 }
143
144 /* ======================== �ᥤ������Υᥤ��롼�� ======================= */
145
quasi88_main(void)146 void quasi88_main(void)
147 {
148 for (;;) {
149
150 /* ��λ�α���������ޤǡ������֤��Ƥ�³���� */
151
152 if (quasi88_loop() == QUASI88_LOOP_EXIT) {
153 break;
154 }
155
156 }
157
158 /* quasi88_loop() �ϡ� 1�ե졼�� (VSYNC 1����ʬ��1/60��) �����ˡ�
159 QUASI88_LOOP_ONE ���֤��Ƥ��롣
160 ��������ͤ�Ƚ�Ǥ��ơ��ʤ�餫�ν�����ä��Ƥ�褤��
161
162 �ޤ������������λ���� QUASI88_LOOP_BUSY ���֤��Ƥ��뤳�Ȥ⤢�뤬��
163 ���ξ��ϵ��ˤ����ˡ������֤��ƤӽФ���³�Ԥ��뤳�� */
164
165 }
166
167 /* ========================== �ᥤ������θ����դ� ========================= */
168
quasi88_stop(int normal_exit)169 void quasi88_stop(int normal_exit)
170 {
171 if (normal_exit) {
172 if (verbose_proc) printf("Shutting down.....\n");
173 }
174
175 /* ���������ξ�硢verbose �ˤ��ܺ�ɽ�����ʤ���С����顼ɽ������ */
176 #define ERR_DISP(n) ((proc == (n)) && (verbose_proc == 0))
177
178 switch (proc) {
179 case 6: /* ����� ����˽���äƤ��� */
180 profiler_exit();
181 debuglog_exit();
182 screen_snapshot_exit();
183 key_record_playback_exit();
184 pc88main_term();
185 pc88sub_term();
186 imagefile_all_close();
187 wait_vsync_exit();
188 /* FALLTHROUGH */
189
190 case 5: /* �����ޡ��ν������NG */
191 if (ERR_DISP(5)) printf("timer initialize failed!\n");
192 xmame_sound_stop();
193 /* FALLTHROUGH */
194
195 case 4: /* ������ɤν������NG */
196 if (ERR_DISP(4)) printf("sound system initialize failed!\n");
197 event_exit();
198 screen_exit();
199 /* FALLTHROUGH */
200
201 case 3: /* ����ե��å��ν������NG */
202 if (ERR_DISP(3)) printf("graphic system initialize failed!\n");
203 /* FALLTHROUGH */
204
205 case 2: /* ���ơ��ȥ��ɤ�NG */
206 /* FALLTHROUGH */
207
208 case 1: /* ���������NG */
209 if (ERR_DISP(2)) printf("memory allocate failed!\n");
210 memory_free();
211 /* FALLTHROUGH */
212
213 case 0: /* ��λ���� ���Ǥ˴�λ */
214 break;
215 }
216
217 proc = 0; /* ���δؿ���³���ƸƤ�Ǥ�����̵���褦�ˡ����ꥢ���Ƥ��� */
218 }
219
220
221 /***********************************************************************
222 * QUASI88 ���潪λ�����ؿ�
223 * exit() ������˸Ƥܤ���
224 ************************************************************************/
225
226 #define MAX_ATEXIT (32)
227 static void (*exit_function[MAX_ATEXIT])(void);
228
229 /*
230 * �ؿ������ MAX_ATEXIT �ġ���Ͽ�Ǥ��롣��������Ͽ�����ؿ��ϡ�
231 * quasi88_exit() ��ƤӽФ������ˡ���Ͽ������ȵս�ǡ��ƤӽФ���롣
232 */
quasi88_atexit(void (* function)(void))233 void quasi88_atexit(void (*function)(void))
234 {
235 int i;
236 for (i=0; i<MAX_ATEXIT; i++) {
237 if (exit_function[i] == NULL) {
238 exit_function[i] = function;
239 return;
240 }
241 }
242 printf("quasi88_atexit: out of array\n");
243 quasi88_exit(-1);
244 }
245
246 /*
247 * quasi88 ������λ���롣
248 * quasi88_atexit() ����Ͽ�����ؿ���ƤӽФ�����ˡ� exit() ����
249 */
quasi88_exit(int status)250 void quasi88_exit(int status)
251 {
252 int i;
253
254 quasi88_stop(FALSE);
255
256 for (i=MAX_ATEXIT-1; i>=0; i--) {
257 if (exit_function[i]) {
258 (*exit_function[i])();
259 exit_function[i] = NULL;
260 }
261 }
262
263 exit(status);
264 }
265
266
267
268
269
270 /***********************************************************************
271 * QUASI88�ᥤ��롼������
272 * QUASI88_LOOP_EXIT ���֤�ޤǡ�̵�¤˸ƤӽФ����ȡ�
273 * �����
274 * QUASI88_LOOP_EXIT �� ���
275 * QUASI88_LOOP_ONE �� 1�ե졼��в�� (�������Ȥ����Τʤ����1/60�ü���)
276 * QUASI88_LOOP_BUSY �� �嵭�ʳ��Ρ��ʤ�餫�Υ����ߥ�
277 ************************************************************************/
278 int quasi88_event_flags = EVENT_MODE_CHANGED;
279 static int mode = EXEC; /* ���ߤΥ⡼�� */
280 static int next_mode = EXEC; /* �⡼����������Ρ����⡼�� */
281
quasi88_loop(void)282 int quasi88_loop(void)
283 {
284 static enum {
285 INIT,
286 MAIN,
287 WAIT,
288 } step = INIT, step_after_wait = INIT;
289
290 int stat;
291
292 switch (step) {
293
294 /* ======================== ���˥������� ======================== */
295 case INIT:
296 profiler_lapse( PROF_LAPSE_RESET );
297
298 /* �⡼���ѹ����ϡ�ɬ����������롣�⡼���ѹ��ե饰�ꥢ */
299 quasi88_event_flags &= ~EVENT_MODE_CHANGED;
300 mode = next_mode;
301
302 /* �㳰Ū�ʥ⡼���ѹ����ν��� */
303 switch (mode) {
304 #ifndef USE_MONITOR
305 case MONITOR: /* ���ꤨ�ʤ����ɡ�ǰ�Τ��� */
306 mode = PAUSE;
307 break;
308 #endif
309 case QUIT: /* QUIT �ʤ顢�ᥤ��롼��λ */
310 return FALSE;
311 }
312
313 /* �⡼���̥��˥������� */
314 if (mode == EXEC) { xmame_sound_resume(); }
315 else { xmame_sound_suspend();}
316
317 screen_switch();
318 event_switch();
319 keyboard_switch();
320
321 switch (mode) {
322 case EXEC: emu_init(); break;
323
324 case MENU: menu_init(); break;
325 #ifdef USE_MONITOR
326 case MONITOR: monitor_init(); break;
327 #endif
328 case PAUSE: pause_init(); break;
329 }
330
331 status_override();
332
333 wait_vsync_switch();
334
335
336 /* ���˥�����������λ�����顢MAIN ������ */
337 step = MAIN;
338
339 /* ���ܤ��뤿�ᡢ��ö�ؿ���ȴ���� (FALLTHROUGH�Ǥ⤤������) */
340 return QUASI88_LOOP_BUSY;
341
342
343 /* ======================== �ᥤ����� ======================== */
344 case MAIN:
345 switch (mode) {
346
347 case EXEC: profiler_lapse( PROF_LAPSE_RESET );
348 emu_main(); break;
349 #ifdef USE_MONITOR
350 case MONITOR: monitor_main(); break;
351 #endif
352 case MENU: menu_main(); break;
353
354 case PAUSE: pause_main(); break;
355 }
356
357 /* �⡼���ѹ���ȯ�����Ƥ����顢(WAIT���) INIT �����ܤ��� */
358 /* �����Ǥʤ���С� (WAIT���) MAIN �����ܤ��� */
359 if (quasi88_event_flags & EVENT_MODE_CHANGED) {
360 step_after_wait = INIT;
361 } else {
362 step_after_wait = MAIN;
363 }
364
365 /* ���西���ߥʤ�Ф��������衣���θ� WAIT �� */
366 /* �����Ǥʤ���С� WAIT ���������� */
367 if (quasi88_event_flags & EVENT_FRAME_UPDATE) {
368 quasi88_event_flags &= ~EVENT_FRAME_UPDATE;
369 screen_update();
370 step = WAIT;
371 } else {
372 step = step_after_wait;
373 }
374
375 /* ��˥������ܻ��佪λ���ϡ� WAIT ������¨���� INIT �� */
376 if (quasi88_event_flags & (EVENT_DEBUG | EVENT_QUIT)) {
377 step = INIT;
378 }
379
380 /* ���ܤ��뤿�ᡢ��ö�ؿ���ȴ���� (WAIT����FALLTHROUGH�Ǥ⤤������) */
381 return QUASI88_LOOP_BUSY;
382
383
384 /* ======================== �������Ƚ��� ======================== */
385 case WAIT:
386 stat = WAIT_JUST;
387
388 switch (mode) {
389 case EXEC:
390 profiler_lapse( PROF_LAPSE_IDLE );
391 if (! no_wait) { stat = wait_vsync_update(); }
392 break;
393
394 case MENU:
395 case PAUSE:
396 /* Esound �ξ�硢 MENU/PAUSE �Ǥ� stream ��ή���Ƥ����ʤ���
397 ʣ����ư���ˡ� MENU/PAUSE ���Ƥʤ��ۤ��������Ǥʤ��ʤ롣
398 �������Τޤޤ��ȡ����ߤβ���ή��äѤʤ��ˤʤ�Τǡ�
399 ̵����ή���褦�ˤ��ʤ��ȡ� */
400 xmame_sound_update(); /* ������ɽ��� */
401 xmame_update_video_and_audio(); /* ������ɽ��� ����2 */
402 stat = wait_vsync_update();
403 break;
404 }
405
406 if (stat == WAIT_YET) { return QUASI88_LOOP_BUSY; }
407
408
409 /* �������Ȼ��֤ˡ��ե졼�ॹ���åפ�̵ͭ����� */
410 if (mode == EXEC) {
411 frameskip_check((stat == WAIT_JUST) ? TRUE : FALSE);
412 }
413
414 /* �������Ƚ�������λ�����顢�� (INIT �� MAIN) ������ */
415 step = step_after_wait;
416 return QUASI88_LOOP_ONE;
417 }
418
419 /* �����ˤ���ʤ� ! */
420 return QUASI88_LOOP_EXIT;
421 }
422
423
424
425 /*======================================================================
426 * QUASI88 �Υ⡼������
427 * �⡼�ɤȤ� QUASI88 �ξ��֤Τ��Ȥǡ� EXEC (�¹�)��PAUSE (������)��
428 * MENU (��˥塼����)�� MONITOR (���÷��ǥХå�)�� QUIT(��λ) �����롣
429 *======================================================================*/
430 /* QUASI88�Υ⡼�ɤ����ꤹ�� */
set_mode(int newmode)431 static void set_mode(int newmode)
432 {
433 if (mode != newmode) {
434
435 if (mode == MENU) { /* ��˥塼����¾�⡼�ɤ����ؤ� */
436 q8tk_event_quit(); /* Q8TK �ν�λ��ɬ�� */
437 }
438
439 next_mode = newmode;
440 quasi88_event_flags |= EVENT_MODE_CHANGED;
441 CPU_BREAKOFF();
442 }
443 }
444
445 /* QUASI88�Υ⡼�ɤ��ڤ��ؤ��� */
quasi88_exec(void)446 void quasi88_exec(void)
447 {
448 set_mode(EXEC);
449 set_emu_exec_mode(GO);
450 }
451
quasi88_exec_step(void)452 void quasi88_exec_step(void)
453 {
454 set_mode(EXEC);
455 set_emu_exec_mode(STEP);
456 }
457
quasi88_exec_trace(void)458 void quasi88_exec_trace(void)
459 {
460 set_mode(EXEC);
461 set_emu_exec_mode(TRACE);
462 }
463
quasi88_exec_trace_change(void)464 void quasi88_exec_trace_change(void)
465 {
466 set_mode(EXEC);
467 set_emu_exec_mode(TRACE_CHANGE);
468 }
469
quasi88_menu(void)470 void quasi88_menu(void)
471 {
472 set_mode(MENU);
473 }
474
quasi88_pause(void)475 void quasi88_pause(void)
476 {
477 set_mode(PAUSE);
478 }
479
quasi88_monitor(void)480 void quasi88_monitor(void)
481 {
482 #ifdef USE_MONITOR
483 set_mode(MONITOR);
484 #else
485 set_mode(PAUSE);
486 #endif
487 }
488
quasi88_debug(void)489 void quasi88_debug(void)
490 {
491 #ifdef USE_MONITOR
492 set_mode(MONITOR);
493 quasi88_event_flags |= EVENT_DEBUG;
494 #else
495 set_mode(PAUSE);
496 #endif
497 }
498
quasi88_quit(void)499 void quasi88_quit(void)
500 {
501 set_mode(QUIT);
502 quasi88_event_flags |= EVENT_QUIT;
503 }
504
505 /* QUASI88�Υ⡼�ɤ�������� */
quasi88_is_exec(void)506 int quasi88_is_exec(void)
507 {
508 return (mode == EXEC) ? TRUE : FALSE;
509 }
quasi88_is_menu(void)510 int quasi88_is_menu(void)
511 {
512 return (mode == MENU) ? TRUE : FALSE;
513 }
quasi88_is_pause(void)514 int quasi88_is_pause(void)
515 {
516 return (mode == PAUSE) ? TRUE : FALSE;
517 }
quasi88_is_monitor(void)518 int quasi88_is_monitor(void)
519 {
520 return (mode == MONITOR) ? TRUE : FALSE;
521 }
522
523
524
525
526
527 /***********************************************************************
528 * Ŭ�ڤʰ��֤˰�ư����
529 ************************************************************************/
wait_vsync_switch(void)530 void wait_vsync_switch(void)
531 {
532 long dt;
533
534 /* dt < 1000000us (1sec) �Ǥʤ��ȥ��� */
535 if (quasi88_is_exec()) {
536 dt = (long)((1000000.0 / (CONST_VSYNC_FREQ * wait_rate/100)));
537 wait_vsync_setup(dt, wait_by_sleep);
538 } else {
539 dt = (long)(1000000.0 / CONST_VSYNC_FREQ);
540 wait_vsync_setup(dt, TRUE);
541 }
542 }
543
544
status_override(void)545 static void status_override(void)
546 {
547 static int first_fime = TRUE;
548
549 if (first_fime) {
550
551 /* EMU�⡼�ɤǵ�ư�������Τߡ����ơ�������ɽ�����Ѥ��� */
552 if (mode == EXEC) {
553
554 status_message(0, STATUS_INFO_TIME, Q_TITLE " " Q_VERSION);
555
556 if (resume_flag == 0) {
557 if (status_imagename == FALSE) {
558 status_message_default(1, "<F12> key to MENU");
559 }
560 } else {
561 status_message(1, STATUS_INFO_TIME, "State-Load Successful");
562 }
563 }
564 first_fime = FALSE;
565 }
566 }
567
568
569
570 /***********************************************************************
571 * �ǥХå���
572 ************************************************************************/
573 #include "debug.c"
574
575
576
577 /***********************************************************************
578 * ��¿�ʴؿ�
579 ************************************************************************/
580 #include "utility.c"
581
582
583
584 /***********************************************************************
585 * �ե�����̾���桿����
586 ************************************************************************/
587 #include "fname.c"
588
589
590
591
592 /***********************************************************************
593 * �Ƽ�ư��ѥ������ѹ�
594 * �����δؿ��ϡ����硼�ȥ��åȥ��������䡢�����¸���Υ��٥��
595 * �����ʤɤ���ƤӽФ���뤳�Ȥ� *���* ���ꤷ�Ƥ��롣
596 *
597 * ��˥塼���̤�ɽ����˸ƤӽФ��ȡ���˥塼ɽ���ȿ����㤤��������
598 * �Τǡ���˥塼��ϸƤӽФ��ʤ��褦�ˡ����ߥ�¹���˸ƤӽФ��Τ�
599 * ���ְ������������ޤ�����
600 *
601 * if( mode == EXEC ){
602 * quasi88_disk_insert_and_reset( file, FALSE );
603 * }
604 *
605 ************************************************************************/
606
607 /***********************************************************************
608 * QUASI88 ��ư��Υꥻ�åȽ����ؿ�
609 ************************************************************************/
quasi88_get_reset_cfg(T_RESET_CFG * cfg)610 void quasi88_get_reset_cfg(T_RESET_CFG *cfg)
611 {
612 cfg->boot_basic = boot_basic;
613 cfg->boot_dipsw = boot_dipsw;
614 cfg->boot_from_rom = boot_from_rom;
615 cfg->boot_clock_4mhz= boot_clock_4mhz;
616 cfg->set_version = set_version;
617 cfg->baudrate_sw = baudrate_sw;
618 cfg->use_extram = use_extram;
619 cfg->use_jisho_rom = use_jisho_rom;
620 cfg->sound_board = sound_board;
621 }
622
quasi88_reset(const T_RESET_CFG * cfg)623 void quasi88_reset(const T_RESET_CFG *cfg)
624 {
625 int sb_changed = FALSE;
626 int empty[2];
627
628 if (verbose_proc) printf("Reset QUASI88...start\n");
629
630 pc88main_term();
631 pc88sub_term();
632
633 if (cfg) {
634 if (sound_board != cfg->sound_board) {
635 sb_changed = TRUE;
636 }
637
638 boot_basic = cfg->boot_basic;
639 boot_dipsw = cfg->boot_dipsw;
640 boot_from_rom = cfg->boot_from_rom;
641 boot_clock_4mhz = cfg->boot_clock_4mhz;
642 set_version = cfg->set_version;
643 baudrate_sw = cfg->baudrate_sw;
644 use_extram = cfg->use_extram;
645 use_jisho_rom = cfg->use_jisho_rom;
646 sound_board = cfg->sound_board;
647 }
648
649 /* ����κƳ��ݤ�ɬ�פʤ顢�������� */
650 if (memory_allocate_additional() == FALSE) {
651 quasi88_exit(-1); /* ���ԡ� */
652 }
653
654 /* ������ɽ��ϤΥꥻ�å� */
655 if (sb_changed == FALSE) {
656 xmame_sound_reset();
657 } else {
658 menu_sound_restart(FALSE); /* ������ɥɥ饤�Фκƽ���� */
659 }
660
661 /* ������� */
662 pc88main_init(INIT_RESET);
663 pc88sub_init(INIT_RESET);
664
665 /* FDC���� */
666 empty[0] = drive_check_empty(0);
667 empty[1] = drive_check_empty(1);
668 drive_reset();
669 if (empty[0]) drive_set_empty(0);
670 if (empty[1]) drive_set_empty(1);
671
672 /*if (xmame_has_sound()) xmame_sound_reset();*/
673
674 emu_reset();
675
676 if (verbose_proc) printf("Reset QUASI88...done\n");
677 }
678
679
680
681 /***********************************************************************
682 * QUASI88 ��ư��Υ��ơ��ȥ��ɽ����ؿ�
683 * TODO �����ǡ��ե�����̾���ꡩ
684 ************************************************************************/
quasi88_stateload(int serial)685 int quasi88_stateload(int serial)
686 {
687 int now_board, success;
688
689 if (serial >= 0) { /* Ϣ�ֻ��ꤢ�� (>=0) �ʤ� */
690 filename_set_state_serial(serial); /* Ϣ�֤����ꤹ�� */
691 }
692
693 if (verbose_proc) printf("Stateload...start (%s)\n",filename_get_state());
694
695 if (stateload_check_file_exist() == FALSE) { /* �ե�����ʤ� */
696 if (quasi88_is_exec()) {
697 status_message(1, STATUS_INFO_TIME, "State-Load file not found !");
698 } /* ��˥塼�Ǥϥ�������ɽ������Τǡ����ơ�����ɽ����̵���ˤ��� */
699
700 if (verbose_proc) printf("State-file not found\n");
701 return FALSE;
702 }
703
704
705 pc88main_term(); /* ǰ�Τ��ᡢ�����λ���֤� */
706 pc88sub_term();
707 imagefile_all_close(); /* ������ե�����������Ĥ��� */
708
709 /*xmame_sound_reset();*/ /* ǰ�Τ��ᡢ������ɥꥻ�å� */
710 /*quasi88_reset();*/ /* ǰ�Τ��ᡢ������ꥻ�å� */
711
712
713 now_board = sound_board;
714
715 success = stateload(); /* ���ơ��ȥ��ɼ¹� */
716
717 if (now_board != sound_board) { /* ������ɥܡ��ɤ��Ѥ�ä��� */
718 menu_sound_restart(FALSE); /* ������ɥɥ饤�Фκƽ���� */
719 }
720
721 if (verbose_proc) {
722 if (success) printf("Stateload...done\n");
723 else printf("Stateload...Failed, Reset start\n");
724 }
725
726
727 if (success) { /* ���ơ��ȥ������������顦���� */
728
729 imagefile_all_open(TRUE); /* ������ե���������Ƴ���*/
730
731 pc88main_init(INIT_STATELOAD);
732 pc88sub_init(INIT_STATELOAD);
733
734 } else { /* ���ơ��ȥ��ɼ��Ԥ����顦���� */
735
736 quasi88_reset(NULL); /* �Ȥꤢ�����ꥻ�å� */
737 }
738
739
740 if (quasi88_is_exec()) {
741 if (success) {
742 status_message(1, STATUS_INFO_TIME, "State-Load Successful");
743 } else {
744 status_message(1, STATUS_INFO_TIME, "State-Load Failed ! Reset done ...");
745 }
746
747 /* quasi88_loop ���������֤� INIT �ˤ��뤿�ᡢ�⡼���ѹ������Ȥ��� */
748 quasi88_event_flags |= EVENT_MODE_CHANGED;
749 }
750 /* ��˥塼�Ǥϥ�������ɽ������Τǡ����ơ�����ɽ����̵���ˤ��� */
751
752 return success;
753 }
754
755
756
757 /***********************************************************************
758 * QUASI88 ��ư��Υ��ơ��ȥ����ֽ����ؿ�
759 * TODO �����ǡ��ե�����̾���ꡩ
760 ************************************************************************/
quasi88_statesave(int serial)761 int quasi88_statesave(int serial)
762 {
763 int success;
764
765 if (serial >= 0) { /* Ϣ�ֻ��ꤢ�� (>=0) �ʤ� */
766 filename_set_state_serial(serial); /* Ϣ�֤����ꤹ�� */
767 }
768
769 if (verbose_proc) printf("Statesave...start (%s)\n",filename_get_state());
770
771 success = statesave(); /* ���ơ��ȥ����ּ¹� */
772
773 if (verbose_proc) {
774 if (success) printf("Statesave...done\n");
775 else printf("Statesave...Failed, Reset done\n");
776 }
777
778
779 if (quasi88_is_exec()) {
780 if (success) {
781 status_message(1, STATUS_INFO_TIME, "State-Save Successful");
782 } else {
783 status_message(1, STATUS_INFO_TIME, "State-Save Failed !");
784 }
785 } /* ��˥塼�Ǥϥ�������ɽ������Τǡ����ơ�����ɽ����̵���ˤ��� */
786
787 return success;
788 }
789
790
791
792 /***********************************************************************
793 * ���̥��ʥåץ���å���¸
794 * TODO �����ǡ��ե�����̾���ꡩ
795 ************************************************************************/
quasi88_screen_snapshot(void)796 int quasi88_screen_snapshot(void)
797 {
798 int success;
799
800 success = screen_snapshot_save();
801
802
803 if (success) {
804 status_message(1, STATUS_INFO_TIME, "Screen Capture Saved");
805 } else {
806 status_message(1, STATUS_INFO_TIME, "Screen Capture Failed !");
807 }
808
809 return success;
810 }
811
812
813
814 /***********************************************************************
815 * ������ɥǡ����Υե��������
816 * TODO �����ǡ��ե�����̾���ꡩ
817 ************************************************************************/
quasi88_waveout(int start)818 int quasi88_waveout(int start)
819 {
820 int success;
821
822 if (start) {
823 success = waveout_save_start();
824
825 if (success) {
826 status_message(1, STATUS_INFO_TIME, "Sound Record Start ...");
827 } else {
828 status_message(1, STATUS_INFO_TIME, "Sound Record Failed !");
829 }
830
831 } else {
832
833 success = TRUE;
834
835 waveout_save_stop();
836 status_message(1, STATUS_INFO_TIME, "Sound Record Stopped");
837 }
838
839 return success;
840 }
841
842
843
844 /***********************************************************************
845 * �ɥ�å�����ɥɥ�å�
846 * TODO ����ͤ�⤦�칩��
847 ************************************************************************/
quasi88_drag_and_drop(const char * filename)848 int quasi88_drag_and_drop(const char *filename)
849 {
850 if (quasi88_is_exec() ||
851 quasi88_is_pause()) {
852
853 if (quasi88_disk_insert_all(filename, FALSE)) {
854
855 status_message(1, STATUS_INFO_TIME, "Disk Image Set and Reset");
856 quasi88_reset(NULL);
857
858 if (quasi88_is_pause()) {
859 quasi88_exec();
860 }
861
862 } else {
863
864 status_message(1, STATUS_WARN_TIME, "D&D Failed ! Disk Unloaded ...");
865 }
866
867 return TRUE;
868 }
869
870 return FALSE;
871 }
872
873
874
875 /***********************************************************************
876 * �������Ȥ���Ψ����
877 * �������Ȥ�̵ͭ����
878 ************************************************************************/
quasi88_cfg_now_wait_rate(void)879 int quasi88_cfg_now_wait_rate(void)
880 {
881 return wait_rate;
882 }
quasi88_cfg_set_wait_rate(int rate)883 void quasi88_cfg_set_wait_rate(int rate)
884 {
885 int time = STATUS_INFO_TIME;
886 char str[32];
887 long dt;
888
889 if (rate < 5) rate = 5;
890 if (rate > 5000) rate = 5000;
891
892 if (wait_rate != rate) {
893 wait_rate = rate;
894
895 if (quasi88_is_exec()) {
896
897 sprintf(str, "WAIT %4d[%%]", wait_rate);
898
899 status_message(1, time, str);
900 /* �� ���������ѹ������Τǡ�ɽ�����֤ϥ��������ܤˤʤ� */
901
902 dt = (long)((1000000.0 / (CONST_VSYNC_FREQ * wait_rate / 100)));
903 wait_vsync_setup(dt, wait_by_sleep);
904 }
905 }
906 }
quasi88_cfg_now_no_wait(void)907 int quasi88_cfg_now_no_wait(void)
908 {
909 return no_wait;
910 }
quasi88_cfg_set_no_wait(int enable)911 void quasi88_cfg_set_no_wait(int enable)
912 {
913 int time = STATUS_INFO_TIME;
914 char str[32];
915 long dt;
916
917 if (no_wait != enable) {
918 no_wait = enable;
919
920 if (quasi88_is_exec()) {
921
922 if (no_wait) { sprintf(str, "WAIT OFF"); time *= 10; }
923 else sprintf(str, "WAIT ON");
924
925 status_message(1, time, str);
926 /* �� �������Ȥʤ��ʤΤǡ�ɽ�����֤ϼºݤΤȤ������� */
927
928 dt = (long)((1000000.0 / (CONST_VSYNC_FREQ * wait_rate / 100)));
929 wait_vsync_setup(dt, wait_by_sleep);
930 }
931 }
932 }
933
934
935
936 /***********************************************************************
937 * �ǥ�����������ե���������
938 * ��ξ�ɥ饤�֤�����
939 * ������ɥ饤�֤�����
940 * ��ȿ�Хɥ饤�֤Υ�����ե����������
941 * ��ξ�ɥ饤�ּ��Ф�
942 * ������ɥ饤�ּ��Ф�
943 ************************************************************************/
quasi88_disk_insert_all(const char * filename,int ro)944 int quasi88_disk_insert_all(const char *filename, int ro)
945 {
946 int success;
947
948 quasi88_disk_eject_all();
949
950 success = quasi88_disk_insert(DRIVE_1, filename, 0, ro);
951
952 if (success) {
953
954 if (disk_image_num(DRIVE_1) > 1) {
955 quasi88_disk_insert_A_to_B(DRIVE_1, DRIVE_2, 1);
956 }
957 }
958
959 if (quasi88_is_exec()) {
960 status_message_default(1, NULL);
961 }
962 return success;
963 }
quasi88_disk_insert(int drv,const char * filename,int image,int ro)964 int quasi88_disk_insert(int drv, const char *filename, int image, int ro)
965 {
966 int success = FALSE;
967
968 quasi88_disk_eject(drv);
969
970 if (strlen(filename) < QUASI88_MAX_FILENAME) {
971
972 if (disk_insert(drv, filename, image, ro) == 0) success = TRUE;
973 else success = FALSE;
974
975 if (success) {
976
977 if (drv == DRIVE_1) boot_from_rom = FALSE;
978
979 strcpy(file_disk[ drv ], filename);
980 readonly_disk[ drv ] = ro;
981
982 if (filename_synchronize) {
983 filename_init_state(TRUE);
984 filename_init_snap(TRUE);
985 filename_init_wav(TRUE);
986 }
987 }
988 }
989
990 if (quasi88_is_exec()) {
991 status_message_default(1, NULL);
992 }
993 return success;
994 }
quasi88_disk_insert_A_to_B(int src,int dst,int img)995 int quasi88_disk_insert_A_to_B(int src, int dst, int img)
996 {
997 int success;
998
999 quasi88_disk_eject(dst);
1000
1001 if (disk_insert_A_to_B(src, dst, img) == 0) success = TRUE;
1002 else success = FALSE;
1003
1004 if (success) {
1005 strcpy(file_disk[ dst ], file_disk[ src ]);
1006 readonly_disk[ dst ] = readonly_disk[ src ];
1007
1008 if (filename_synchronize) {
1009 filename_init_state(TRUE);
1010 filename_init_snap(TRUE);
1011 filename_init_wav(TRUE);
1012 }
1013 }
1014
1015 if (quasi88_is_exec()) {
1016 status_message_default(1, NULL);
1017 }
1018 return success;
1019 }
quasi88_disk_eject_all(void)1020 void quasi88_disk_eject_all(void)
1021 {
1022 int drv;
1023
1024 for (drv = 0; drv<2; drv++) {
1025 quasi88_disk_eject(drv);
1026 }
1027
1028 boot_from_rom = TRUE;
1029
1030 if (quasi88_is_exec()) {
1031 status_message_default(1, NULL);
1032 }
1033 }
quasi88_disk_eject(int drv)1034 void quasi88_disk_eject(int drv)
1035 {
1036 if (disk_image_exist(drv)) {
1037 disk_eject(drv);
1038 memset(file_disk[ drv ], 0, QUASI88_MAX_FILENAME);
1039
1040 if (filename_synchronize) {
1041 filename_init_state(TRUE);
1042 filename_init_snap(TRUE);
1043 filename_init_wav(TRUE);
1044 }
1045 }
1046
1047 if (quasi88_is_exec()) {
1048 status_message_default(1, NULL);
1049 }
1050 }
1051
1052 /***********************************************************************
1053 * �ǥ�����������ե���������
1054 * ���ɥ饤�֤���Ū�˶��ξ��֤ˤ���
1055 * ���ɥ饤�֤Υ�������ѹ�����
1056 * ���ɥ饤�֤Υ���������Υ�������ѹ�����
1057 * ���ɥ饤�֤Υ�����Υ�������ѹ�����
1058 ************************************************************************/
1059 enum { TYPE_SELECT, TYPE_EMPTY, TYPE_NEXT, TYPE_PREV };
1060
disk_image_sub(int drv,int type,int img)1061 static void disk_image_sub(int drv, int type, int img)
1062 {
1063 int d;
1064 char str[48];
1065
1066 if (disk_image_exist(drv)) {
1067 switch (type) {
1068
1069 case TYPE_EMPTY:
1070 drive_set_empty(drv);
1071 sprintf(str, "DRIVE %d: <<<< Eject >>>> ", drv + 1);
1072 break;
1073
1074 case TYPE_NEXT:
1075 case TYPE_PREV:
1076 if (type == TYPE_NEXT) d = +1;
1077 else d = -1;
1078
1079 img = disk_image_selected(drv) + d;
1080 /* FALLTHROUGH */
1081
1082 default:
1083 if (img < 0) img = disk_image_num(drv)-1;
1084 if (img >= disk_image_num(drv)) img = 0;
1085
1086 drive_unset_empty(drv);
1087 disk_change_image(drv, img);
1088
1089 sprintf(str, "DRIVE %d: %-16s %s ",
1090 drv + 1,
1091 drive[drv].image[ disk_image_selected(drv) ].name,
1092 (drive[drv].image[ disk_image_selected(drv) ].protect)
1093 ? "(p)" : " ");
1094 break;
1095 }
1096 } else {
1097 sprintf(str, "DRIVE %d: -- No Disk -- ", drv + 1);
1098 }
1099
1100 if (quasi88_is_exec()) {
1101 status_message_default(1, NULL);
1102 }
1103 status_message(1, STATUS_INFO_TIME, str);
1104 }
quasi88_disk_image_select(int drv,int img)1105 void quasi88_disk_image_select(int drv, int img)
1106 {
1107 disk_image_sub(drv, TYPE_SELECT, img);
1108 }
quasi88_disk_image_empty(int drv)1109 void quasi88_disk_image_empty(int drv)
1110 {
1111 disk_image_sub(drv, TYPE_EMPTY, 0);
1112 }
quasi88_disk_image_next(int drv)1113 void quasi88_disk_image_next(int drv)
1114 {
1115 disk_image_sub(drv, TYPE_NEXT, 0);
1116 }
quasi88_disk_image_prev(int drv)1117 void quasi88_disk_image_prev(int drv)
1118 {
1119 disk_image_sub(drv, TYPE_PREV, 0);
1120 }
1121
1122
1123
1124
1125
1126
1127 /*======================================================================
1128 * �ơ��ץ�����ե���������
1129 * �������ѥơ��ץ�����ե����륻�å�
1130 * �������ѥơ��ץ�����ե����봬���ᤷ
1131 * �������ѥơ��ץ�����ե������곰��
1132 * ���������ѥơ��ץ�����ե����륻�å�
1133 * ���������ѥơ��ץ�����ե������곰��
1134 *======================================================================*/
quasi88_load_tape_insert(const char * filename)1135 int quasi88_load_tape_insert(const char *filename)
1136 {
1137 quasi88_load_tape_eject();
1138
1139 if (strlen(filename) < QUASI88_MAX_FILENAME &&
1140 sio_open_tapeload(filename)) {
1141
1142 strcpy(file_tape[ CLOAD ], filename);
1143 return TRUE;
1144
1145 }
1146 return FALSE;
1147 }
quasi88_load_tape_rewind(void)1148 int quasi88_load_tape_rewind(void)
1149 {
1150 if (sio_tape_rewind()) {
1151
1152 return TRUE;
1153
1154 }
1155 quasi88_load_tape_eject();
1156 return FALSE;
1157 }
quasi88_load_tape_eject(void)1158 void quasi88_load_tape_eject(void)
1159 {
1160 sio_close_tapeload();
1161 memset(file_tape[ CLOAD ], 0, QUASI88_MAX_FILENAME);
1162 }
1163
quasi88_save_tape_insert(const char * filename)1164 int quasi88_save_tape_insert(const char *filename)
1165 {
1166 quasi88_save_tape_eject();
1167
1168 if (strlen(filename) < QUASI88_MAX_FILENAME &&
1169 sio_open_tapesave(filename)) {
1170
1171 strcpy(file_tape[ CSAVE ], filename);
1172 return TRUE;
1173
1174 }
1175 return FALSE;
1176 }
quasi88_save_tape_eject(void)1177 void quasi88_save_tape_eject(void)
1178 {
1179 sio_close_tapesave();
1180 memset(file_tape[ CSAVE ], 0, QUASI88_MAX_FILENAME);
1181 }
1182
1183 /*======================================================================
1184 * ���ꥢ�롦�ѥ��륤����ե���������
1185 * �����ꥢ�������ѥե����륻�å�
1186 * �����ꥢ�������ѥե������곰��
1187 * �����ꥢ������ѥե����륻�å�
1188 * �����ꥢ������ѥե������곰��
1189 * ���ץ�����ѥե����륻�å�
1190 * ���ץ�������ѥե����륻�å�
1191 *======================================================================*/
quasi88_serial_in_connect(const char * filename)1192 int quasi88_serial_in_connect( const char *filename )
1193 {
1194 quasi88_serial_in_remove();
1195
1196 if( strlen( filename ) < QUASI88_MAX_FILENAME &&
1197 sio_open_serialin( filename ) ){
1198
1199 strcpy( file_sin, filename );
1200 return TRUE;
1201
1202 }
1203 return FALSE;
1204 }
quasi88_serial_in_remove(void)1205 void quasi88_serial_in_remove( void )
1206 {
1207 sio_close_serialin();
1208 memset( file_sin, 0, QUASI88_MAX_FILENAME );
1209 }
quasi88_serial_out_connect(const char * filename)1210 int quasi88_serial_out_connect( const char *filename )
1211 {
1212 quasi88_serial_out_remove();
1213
1214 if( strlen( filename ) < QUASI88_MAX_FILENAME &&
1215 sio_open_serialout( filename ) ){
1216
1217 strcpy( file_sout, filename );
1218 return TRUE;
1219
1220 }
1221 return FALSE;
1222 }
quasi88_serial_out_remove(void)1223 void quasi88_serial_out_remove( void )
1224 {
1225 sio_close_serialout();
1226 memset( file_sout, 0, QUASI88_MAX_FILENAME );
1227 }
quasi88_printer_connect(const char * filename)1228 int quasi88_printer_connect( const char *filename )
1229 {
1230 quasi88_printer_remove();
1231
1232 if( strlen( filename ) < QUASI88_MAX_FILENAME &&
1233 printer_open( filename ) ){
1234
1235 strcpy( file_prn, filename );
1236 return TRUE;
1237
1238 }
1239 return FALSE;
1240 }
quasi88_printer_remove(void)1241 void quasi88_printer_remove( void )
1242 {
1243 printer_close();
1244 memset( file_prn, 0, QUASI88_MAX_FILENAME );
1245 }
1246