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