1 /************************************************************************/
2 /*									*/
3 /* ���ߥ�⡼��								*/
4 /*									*/
5 /************************************************************************/
6 
7 #include <stdio.h>
8 
9 #include "quasi88.h"
10 #include "initval.h"
11 #include "emu.h"
12 
13 #include "pc88cpu.h"
14 
15 #include "screen.h"
16 #include "keyboard.h"
17 #include "intr.h"
18 #include "event.h"
19 #include "menu.h"
20 #include "monitor.h"
21 #include "pause.h"
22 #include "wait.h"
23 #include "suspend.h"
24 #include "status.h"
25 #include "graph.h"
26 #include "snddrv.h"
27 
28 
29 
30 
31 break_t		break_point[2][NR_BP];	/* �֥졼���ݥ����		*/
32 break_drive_t	break_point_fdc[NR_BP];	/* FDC �֥졼���ݥ����		*/
33 
34 
35 int	cpu_timing	= DEFAULT_CPU;		/* SUB-CPU ��ư����	*/
36 
37 int	select_main_cpu = TRUE;			/* -cpu 0 �¹Ԥ���CPU	*/
38 						/* ���ʤ� MAIN CPU��¹�*/
39 
40 int	dual_cpu_count	= 0;			/* -cpu 1 Ʊ������STEP��*/
41 int	CPU_1_COUNT	= 4000;			/* ���Ρ������		*/
42 
43 int	cpu_slice_us    = 5;			/* -cpu 2 ������ʬ��(us)*/
44 						/* 10>��SILPHEED��ư����*/
45 
46 int	trace_counter	= 1;			/* TRACE ���Υ�����	*/
47 
48 
49 
50 static	int	main_state   = 0;
51 static	int	sub_state    = 0;
52 #define	JACKUP	(256)
53 
54 
55 static	int	emu_mode_execute= GO;
56 static	int	emu_rest_step;
57 
set_emu_exec_mode(int mode)58 void	set_emu_exec_mode( int mode )
59 {
60   emu_mode_execute = mode;
61 }
62 
63 /***********************************************************************
64  * ���ߥ�졼�Ƚ����ν������Ϣ
65  ************************************************************************/
66 
emu_reset(void)67 void	emu_reset( void )
68 {
69   select_main_cpu = TRUE;
70   dual_cpu_count  = 0;
71 
72   main_state   = 0;
73   sub_state    = 0;
74 }
75 
76 
emu_breakpoint_init(void)77 void	emu_breakpoint_init( void )
78 {
79   int	i, j;
80 	/* �֥졼���ݥ���ȤΥ������� (��˥����⡼����) */
81   for( j=0; j<2; j++ )
82     for( i=0; i<NR_BP; i++ )
83       break_point[j][i].type = BP_NONE;
84 
85   for( i=0; i<NR_BP; i++ )
86     break_point_fdc[i].type = BP_NONE;
87 }
88 
89 
90 
91 
92 /***********************************************************************
93  * CPU�¹Խ��� (EXEC) ������
94  *	-cpu <n> �˱����ơ�ư����Ѥ��롣
95  *
96  *	STEP  ���ϡ�1step �����¹Ԥ��롣
97  *	TRACE ���ϡ�������ʬ��1step �¹Ԥ��롣
98  *
99  *	�֥졼���ݥ���Ȼ�����ϡ�1step�¹Ԥ��٤� PC ���֥졼���ݥ���Ȥ�
100  *	ã�������ɤ������ǧ���롣
101  *
102  ************************************************************************/
103 
104 #define	INFINITY	(0)
105 #define	ONLY_1STEP	(1)
106 
107 /*------------------------------------------------------------------------*/
108 
109 /*
110  * �֥졼���ݥ���� (������ PC) ��̵ͭ������å�����
111  */
112 
check_break_point_PC(void)113 static	int	check_break_point_PC( void )
114 {
115   int	i, j;
116 
117   for( i=0; i<NR_BP; i++ ) if( break_point[BP_MAIN][i].type == BP_PC ) break;
118   for( j=0; j<NR_BP; j++ ) if( break_point[BP_SUB][j].type  == BP_PC ) break;
119 
120   if( i==NR_BP && j==NR_BP ) return FALSE;
121   else                       return TRUE;
122 }
123 
124 /*------------------------------------------------------------------------*/
125 
126 /*
127  * CPU �� 1step �¹Ԥ��ơ�PC���֥졼���ݥ���Ȥ�ã�����������å�����
128  *	�֥졼���ݥ����(������PC)̤����ʤ餳�δؿ��ϻȤ鷺��z80_emu()��Ȥ�
129  */
130 
z80_emu_with_breakpoint(z80arch * z80,int unused)131 static	int	z80_emu_with_breakpoint( z80arch *z80, int unused )
132 {
133   int i, cpu, states;
134 
135   states = z80_emu( z80, 1 );		/* 1step �����¹� */
136 
137   if( z80==&z80main_cpu ) cpu = BP_MAIN;
138   else                    cpu = BP_SUB;
139 
140   for( i=0; i<NR_BP; i++ ){
141     if( break_point[cpu][i].type == BP_PC     &&
142 	break_point[cpu][i].addr == z80->PC.W ){
143 
144       if( i==BP_NUM_FOR_SYSTEM ){
145 	break_point[cpu][i].type = BP_NONE;
146       }
147 
148       printf( "*** Break at %04x *** ( %s[#%d] : PC )\n",
149 	      z80->PC.W, (cpu==BP_MAIN)?"MAIN":"SUB", i+1 );
150 
151       quasi88_debug();
152     }
153   }
154 
155   return states;
156 }
157 
158 /*---------------------------------------------------------------------------*/
159 
160 static	int	passed_step;		/* �¹Ԥ��� step�� */
161 static	int	target_step;		/* ���� step����ã����ޤǼ¹Ԥ��� */
162 
163 static	int	infinity, only_1step;
164 static	int	(*z80_exec)( z80arch *, int );
165 
166 
emu_init(void)167 void	emu_init(void)
168 {
169 /*xmame_sound_update();*/
170   xmame_update_video_and_audio();
171   event_update();
172 /*keyboard_update();*/
173 
174 
175 
176 /*screen_set_dirty_all();*/
177 /*screen_set_dirty_palette();*/
178 
179   /* ���ơ����������ꥢ */
180   status_message_default(0, NULL);
181   status_message_default(1, NULL);
182   status_message_default(2, NULL);
183 
184 
185 
186 	/* �֥졼���ݥ���������̵ͭ�ǡ��ƤӽФ��ؿ����Ѥ��� */
187   if( check_break_point_PC() ) z80_exec = z80_emu_with_breakpoint;
188   else                         z80_exec = z80_emu;
189 
190 
191 	/* GO/TRACE/STEP/CHANGE �˱����ƽ����η����֤��������� */
192 
193   passed_step = 0;
194 
195   switch( emu_mode_execute ){
196   default:
197   case GO:
198     target_step = 0;			/* ̵�¤˼¹� */
199     infinity    = INFINITY;
200     only_1step  = ONLY_1STEP;
201     break;
202 
203   case TRACE:
204     target_step = trace_counter;	/* ���ꥹ�ƥå׿��¹� */
205     infinity    = ONLY_1STEP;
206     only_1step  = ONLY_1STEP;
207     break;
208 
209   case STEP:
210     target_step = 1;			/* 1���ƥå׼¹� */
211     infinity    = ONLY_1STEP;
212     only_1step  = ONLY_1STEP;
213     break;
214 
215   case TRACE_CHANGE:
216     target_step = 0;			/* ̵�¤˼¹� */
217     infinity    = ONLY_1STEP;
218     only_1step  = ONLY_1STEP;
219     break;
220   }
221 
222 
223   /* �¹Ԥ���Ĥꥹ�ƥå׿���
224 	TRACE / STEP �λ��ϡ����ꤵ�줿���ƥå׿���
225 	GO / TRACE_CHANGE �ʤ� ̵�¤ʤΤǡ� 0��
226 		�ʤ�������ǥ�˥塼�����ܤ�����硢����Ū�� 1 �����åȤ���롣
227 		����ˤ��̵�¤˽���������Ǥ⡢�롼�פ�ȴ����褦�ˤʤ롣 */
228   emu_rest_step = target_step;
229 }
230 
231 
emu_main(void)232 void	emu_main(void)
233 {
234   int	wk;
235 
236   profiler_lapse( PROF_LAPSE_CPU );
237 
238   switch( emu_mode_execute ){
239 
240   /*------------------------------------------------------------------------*/
241   case GO:				/* �Ҥ�����¹Ԥ���           */
242   case TRACE:				/* ���ꤷ�����ƥåס��¹Ԥ��� */
243   case STEP:				/* 1���ƥåפ������¹Ԥ���    */
244 
245     for(;;){
246 
247       switch( cpu_timing ){
248 
249       case 0:		/* select_main_cpu �ǻ��ꤵ�줿�ۤ���CPU��̵�¼¹� */
250 	if( select_main_cpu ) (z80_exec)( &z80main_cpu, infinity );
251 	else                  (z80_exec)( &z80sub_cpu,  infinity );
252 	break;
253 
254       case 1:		/* dual_cpu_count==0 �ʤ�ᥤ��CPU��̵�¼¹ԡ�*/
255 			/*               !=0 �ʤ�ᥤ���֤��߼¹� */
256 	if( dual_cpu_count==0 ) (z80_exec)( &z80main_cpu, infinity   );
257 	else{
258 	  (z80_exec)( &z80main_cpu, only_1step );
259 	  (z80_exec)( &z80sub_cpu,  only_1step );
260 	  dual_cpu_count --;
261 	}
262 	break;
263 
264       case 2:		/* �ᥤ��CPU������CPU���ߤ� 5us ���ļ¹� */
265 	if( main_state < 1*JACKUP  &&  sub_state < 1*JACKUP ){
266 	  main_state += (int) ((cpu_clock_mhz * cpu_slice_us) * JACKUP);
267 	  sub_state  += (int) ((3.9936        * cpu_slice_us) * JACKUP);
268 	}
269 	if( main_state >= 1*JACKUP ){
270 	  wk = (infinity==INFINITY) ? main_state/JACKUP : ONLY_1STEP;
271 	  main_state -= (z80_exec( &z80main_cpu, wk ) ) * JACKUP;
272 	}
273 	if( sub_state >= 1*JACKUP ){
274 	  wk = (infinity==INFINITY) ? sub_state/JACKUP : ONLY_1STEP;
275 	  sub_state  -= (z80_exec( &z80sub_cpu, wk ) ) * JACKUP;
276 	}
277 	break;
278       }
279 
280       /* TRACE/STEP�¹Ի������ꥹ�ƥå׼¹Դ�λ�����顢��˥��������ܤ��� */
281       if( emu_rest_step ){
282 	passed_step ++;
283 	if( -- emu_rest_step <= 0 ) {
284 	  quasi88_debug();
285 	}
286       }
287 
288       /* ������ɽ��ϥ����ߥ��Ǥ���С����� */
289       if (quasi88_event_flags & EVENT_AUDIO_UPDATE) {
290 	quasi88_event_flags &= ~EVENT_AUDIO_UPDATE;
291 
292 	profiler_lapse( PROF_LAPSE_SND );
293 
294 	xmame_sound_update();			/* ������ɽ��� */
295 
296 	profiler_lapse( PROF_LAPSE_AUDIO );
297 
298 	xmame_update_video_and_audio();		/* ������ɽ��� ����2 */
299 
300 	profiler_lapse( PROF_LAPSE_INPUT );
301 
302 	event_update();				/* ���٥�Ƚ���		*/
303 	keyboard_update();
304 
305 	profiler_lapse( PROF_LAPSE_CPU2 );
306       }
307 
308       /* �ӥǥ����ϥ����ߥ��Ǥ���С�CPU�����ϰ�ö��ߡ���̤�ȴ���� */
309       if (quasi88_event_flags & EVENT_FRAME_UPDATE) {
310 	return;
311       }
312 
313       /* ��˥������ܻ��佪λ���ϡ� CPU�����ϰ�ö��ߡ���̤�ȴ���� */
314       if (quasi88_event_flags & (EVENT_DEBUG | EVENT_QUIT)) {
315 	return;
316       }
317 
318       /* �⡼�����ؤ�ȯ�����Ƥ⡢��̤ˤ�ȴ���ʤ����ӥǥ����Ϥޤ��Ԥ� */
319       /* (ȴ����ȡ� ���ߥ� �� ���� �� �������� ��ή�줬�����Τǡ�) */
320     }
321     break;
322 
323   /*------------------------------------------------------------------------*/
324 
325 	/* ���ä��Υ֥졼�������Ϥ��ޤ�ư���ʤ����⡦���� (̤����) */
326 
327   case TRACE_CHANGE:			/* CPU���ڤ��ؤ��ޤǽ������� */
328     if( cpu_timing >= 1 ){
329       printf( "command 'trace change' can use when -cpu 0\n");
330       quasi88_monitor();
331       break;
332     }
333 
334     wk = select_main_cpu;
335     while( wk==select_main_cpu ){
336       if( select_main_cpu ) (z80_exec)( &z80main_cpu, infinity );
337       else                  (z80_exec)( &z80sub_cpu,  infinity );
338       if( emu_rest_step ){
339 	passed_step ++;
340 	if( -- emu_rest_step <= 0 ) {
341 	  quasi88_debug();
342 	}
343       }
344 
345       if (quasi88_event_flags & EVENT_AUDIO_UPDATE) {
346 	quasi88_event_flags &= ~EVENT_AUDIO_UPDATE;
347 	profiler_lapse( PROF_LAPSE_SND );
348 	xmame_sound_update();			/* ������ɽ��� */
349 	profiler_lapse( PROF_LAPSE_AUDIO );
350 	xmame_update_video_and_audio();		/* ������ɽ��� ����2 */
351 	profiler_lapse( PROF_LAPSE_INPUT );
352 	event_update();				/* ���٥�Ƚ���		*/
353 	keyboard_update();
354       }
355 
356       if (quasi88_event_flags & EVENT_FRAME_UPDATE) {
357 	return;
358       }
359       if (quasi88_event_flags & (EVENT_DEBUG | EVENT_QUIT)) {
360 	return;
361       }
362     }
363     quasi88_debug();
364     break;
365   }
366   return;
367 }
368 
369 
370 
371 
372 
373 
374 
375 
376 
377 
378 
379 
380 
381 
382 
383 
384 /***********************************************************************
385  * ���ơ��ȥ��ɡ����ơ��ȥ�����
386  ************************************************************************/
387 
388 #define	SID	"EMU "
389 
390 static	T_SUSPEND_W	suspend_emu_work[] =
391 {
392   { TYPE_INT,	&cpu_timing,		},
393   { TYPE_INT,	&select_main_cpu,	},
394   { TYPE_INT,	&dual_cpu_count,	},
395   { TYPE_INT,	&CPU_1_COUNT,		},
396   { TYPE_INT,	&cpu_slice_us,		},
397   { TYPE_INT,	&main_state,		},
398   { TYPE_INT,	&sub_state,		},
399 
400   { TYPE_END,	0			},
401 };
402 
403 
statesave_emu(void)404 int	statesave_emu( void )
405 {
406   if( statesave_table( SID, suspend_emu_work ) == STATE_OK ) return TRUE;
407   else                                                       return FALSE;
408 }
409 
stateload_emu(void)410 int	stateload_emu( void )
411 {
412   if( stateload_table( SID, suspend_emu_work ) == STATE_OK ) return TRUE;
413   else                                                       return FALSE;
414 }
415