1 /*****************************************************************************/
2 /* Z80���ߥ�졼�� */
3 /* */
4 /*****************************************************************************/
5
6 /******************************************************************************
7 *
8 * �����ͤˤ������
9 * fMSX ������ http://www.komkon.org/fms/
10 * MAME ������ http://www.mame.net/
11 * Z80 CPU User Manual http://www.zilog.com/
12 * The Undocumented Z80 Documented http://www.msxnet.org/tech/
13 *
14 * ����������
15 *
16 * total_state = 0; ���δؿ�����ޤǤ˽����������ơ��ȿ��߷�
17 * z80_state_goal = �¹Ԥ������ơ��ȿ���0��̵��
18 * (����ͤϰ�����Ϳ�����뤬�������ѿ���
19 * �����Х��ѿ��ʤΤǡ����������ͤ��ѹ�����ǽ)
20 * for(;;){ -----------------------------------------------------
21 * z80_state_intchk = �ʲ��Υ롼�פˤƽ������륹�ơ��ȿ�
22 * (������ȯ���ޤǤΥ��ơ��ȿ� z80->icount ����
23 * z80_state_goal �ˤ��Ĥꥹ�ơ��ȿ�)
24 *
25 * do{ - - - - - - - - - - - - - - - - - - - - - - -
26 *
27 * z80->state0 += ̿����Υ��ơ��ȿ�;
28 * ̿�����(); �����ˤ�ꡢ�롼�פ�ȴ����
29 * [z80_state_intchk = 0 �ǡ��롼�פ�ȴ����]
30 * �������߾�郎�ѹ����줿��
31 * ��EI ��������̿�� (FD/DD��³�����) (��1)
32 * ��PIO���������ˤ�ꡢCPU���ڤ��ؤ����(��2)
33 * ����˥塼�⡼�ɤʤɤ����ܤ����� (��2)
34 * ��1 �ξ�硢�롼�פ�ȴ����ľ��ϳ����ߤ�̵��
35 * [z80->skip_intr_chk = TRUE �å�]
36 * ��2 �ξ��ϡ����δؿ������ȴ���롣
37 * [z80_state_goal = 1 �ǡ��ؿ���ȴ����]
38 *
39 * } while( z80->state0 < z80_state_intchk ) - - - - - - - - - - - -
40 *
41 * (z80->intr_update)(); ������ȯ����Ƚ��
42 * (���δؿ�������ƽС�����ƽФޤǤδ֤˽���
43 * �������ơ��ȿ��� z80->state0 �Ȥʤ롣)
44 * ���ȯ���� z80->INT_active = TRUE �åȡ�
45 * ������ȯ���ޤǤΥ��ơ��ȿ� (z80->icount)
46 * ���碌�ƹ������Ƥ�����
47 * ��˥塼�⡼�ɤʤɤ����ܤǡ����δؿ�����
48 * ȴ������ϡ� z80_state_goal = 1 �åȡ�
49 *
50 * total_state += z80->state0; �¹Ԥ������ơ��ȿ����߷���
51 * z80->state0 = 0; �¹Ԥ������ơ��ȿ����ꥢ
52 *
53 * if( z80->skip_intr_chk ){ EI̿���ľ��ʤɤϡ�
54 * z80->skip_intr_chk = 0; ����Ͻ����롼�פ�1���ȴ����
55 * z80->icount = 0; ������ȯ����Ƚ��˿ʤࡣ
56 * }else{
57 * if( z80->IFF==INT_ENABLE && �����ߥ����å���Ԥ�
58 * z80->INT_active ){
59 * level = (z80->intr_ack)(); ���δؿ��dz����٥�����
60 * if( level >= 0 ){
61 * ���ʬ������();
62 * z80->state0 += ����Υ��ơ��ȿ�;
63 * }
64 * }
65 * }
66 *
67 * if( z80_state_goal ){ ���ꤷ�����ơ��ȿ��¹Ԥ����齪���
68 * if( z80_state_goal <= total_state ) break;
69 * ������ z80_state_goal = 1 �åȤ����顢ɬ������뤳�Ȥˤʤ�
70 * }
71 * } ------------------------------------------------------
72 *
73 * ������
74 * �������߱����ϡ�PC-8801 ���ò�
75 * ���⡼��0�����ߤΥ����ɽ����Ϸ�ᤦ��
76 * ���Υ�ޥ����֥�����ߤ�̤���ݡ���
77 * ��IN / OUT ̿��ϡ�256��ʬ�Υݡ��ȤΤߥ��ݡ���
78 *
79 *****************************************************************************/
80
81 #include <stdio.h>
82
83 #include "quasi88.h"
84 #include "z80.h"
85
86
87 #define S_FLAG (0x80)
88 #define Z_FLAG (0x40)
89 #define H_FLAG (0x10)
90 #define P_FLAG (0x04)
91 #define V_FLAG (0x04)
92 #define N_FLAG (0x02)
93 #define C_FLAG (0x01)
94
95 #define ACC AF.B.h
96 #define FLAG AF.B.l
97
98 #define M_C() (z80->FLAG & C_FLAG)
99 #define M_NC() (!M_C())
100 #define M_Z() (z80->FLAG & Z_FLAG)
101 #define M_NZ() (!M_Z())
102 #define M_M() (z80->FLAG & S_FLAG)
103 #define M_P() (!M_M())
104 #define M_PE() (z80->FLAG & V_FLAG)
105 #define M_PO() (!M_PE())
106
107
108 #define M_FETCH(addr) (z80->fetch)(addr)
109 #define M_RDMEM(addr) (z80->mem_read)(addr)
110 #define M_WRMEM(addr,data) (z80->mem_write)(addr,data)
111 #define M_RDIO(addr) (z80->io_read)(addr)
112 #define M_WRIO(addr,data) (z80->io_write)(addr,data)
113
114
115
116
117
118 /****************************************************************************
119 * void z80_reset( z80arch *z80 )
120 *
121 * Z80 ���ߥ�졼���� ��¤��(z80arch)������(�ꥻ�å�)���롣
122 * PC��I��R �쥸������ 0
123 * ����¾������ 0xffff
124 * ����ػߡ�����⡼�� 0
125 *
126 * �ʲ��ι�¤�Υ��Фϡ��ƽ�¦�ˤƽ����
127 * z80->log
128 * z80->break_if_halt
129 * �Ƽ�ؿ��ݥ���
130 *****************************************************************************/
z80_reset(z80arch * z80)131 void z80_reset( z80arch *z80 )
132 {
133 z80->AF.W = z80->BC.W = z80->DE.W = z80->HL.W =0xffff;
134 z80->AF1.W = z80->BC1.W = z80->DE1.W = z80->HL1.W =0xffff;
135 z80->IX.W = z80->IY.W = 0xffff;
136
137 z80->PC.W = 0x0000; z80->SP.W = 0xffff;
138 z80->I = 0x00;
139 z80->R = 0x00; z80->R_saved = z80->R;
140
141 z80->IFF = INT_DISABLE; z80->IFF2 = INT_DISABLE;
142 z80->IM = 0;
143
144 z80->state0 = 0;
145 z80->icount = 0;
146
147 z80->HALT = FALSE;
148 z80->INT_active = FALSE;
149
150 z80->skip_intr_chk = FALSE;
151
152 z80->PC_prev.W = 0x0000;
153 }
154
155
156 /*---------------------------------------------------------------------------*/
157
158
159 /*------------------------------------------------------*/
160 /* ���ơ��ȡ����ե�̿��Υޥ��� */
161 /* �ե饰�Ѳ� : S Z H PV N C */
162 /* �� �� 0 �� 0 �� */
163 /* (�� �� �� �ơ��֥뻲��) */
164 /*------------------------------------------------------*/
165 #define M_RLC(reg) do{ \
166 z80->FLAG = reg>>7; \
167 reg = (reg<<1)|z80->FLAG; \
168 z80->FLAG |= SZP_table[reg]; \
169 }while(0)
170 #define M_RL(reg) do{ \
171 if( reg&0x80 ){ \
172 reg = (reg<<1)|(z80->FLAG&C_FLAG); \
173 z80->FLAG = SZP_table[reg]|C_FLAG; \
174 }else{ \
175 reg = (reg<<1)|(z80->FLAG&C_FLAG); \
176 z80->FLAG = SZP_table[reg]; \
177 } \
178 }while(0)
179 #define M_RRC(reg) do{ \
180 z80->FLAG = reg&0x01; \
181 reg = (reg>>1)|(z80->FLAG<<7); \
182 z80->FLAG |= SZP_table[reg]; \
183 }while(0)
184 #define M_RR(reg) do{ \
185 if( reg&0x01 ){ \
186 reg = (reg>>1)|(z80->FLAG<<7); \
187 z80->FLAG = SZP_table[reg]|C_FLAG; \
188 }else{ \
189 reg = (reg>>1)|(z80->FLAG<<7); \
190 z80->FLAG = SZP_table[reg]; \
191 } \
192 }while(0)
193 #define M_SLA(reg) do{ \
194 z80->FLAG = reg>>7; \
195 reg <<= 1; \
196 z80->FLAG |= SZP_table[reg]; \
197 }while(0)
198 #define M_SRA(reg) do{ \
199 z80->FLAG = reg&C_FLAG; \
200 reg = (reg>>1)|(reg&0x80); \
201 z80->FLAG |= SZP_table[reg]; \
202 }while(0)
203 #define M_SLL(reg) do{ \
204 z80->FLAG = reg>>7; \
205 reg = (reg<<1)|0x01; \
206 z80->FLAG |= SZP_table[reg]; \
207 }while(0)
208 #define M_SRL(reg) do{ \
209 z80->FLAG = reg&0x01; \
210 reg >>= 1; \
211 z80->FLAG |= SZP_table[reg]; \
212 }while(0)
213
214 /*------------------------------------------------------*/
215 /* �ӥåȱ黻�Υޥ��� */
216 /* �ե饰�Ѳ� : S Z H PV N C */
217 /* (BIT) �� �� 1 �� 0 �� */
218 /* �ե饰�Ѳ� : S Z H PV N C */
219 /* (SET/RES) �� �� �� �� �� �� */
220 /* */
221 /* BIT 7,reg �Ǥϡ�������ե饰���Ѳ����롣 */
222 /*------------------------------------------------------*/
223 #define M_BIT(bit,reg) do{ \
224 z80->FLAG = (z80->FLAG&~(Z_FLAG|N_FLAG|S_FLAG)) | \
225 H_FLAG | \
226 ((reg&(1<<bit))?((bit==7)?S_FLAG:0) \
227 :Z_FLAG); \
228 }while(0)
229
230 #define M_SET(bit,reg) do{ reg |= 1<<bit; }while(0)
231 #define M_RES(bit,reg) do{ reg &= ~(1<<bit); }while(0)
232
233 /*------------------------------------------------------*/
234 /* PUSH/POP/ʬ��̿��Υޥ��� */
235 /* �ե饰�Ѳ� : S Z H PV N C */
236 /* �� �� �� �� �� �� */
237 /*------------------------------------------------------*/
238 #define M_POP(reg) do{ \
239 z80->reg.B.l = M_RDMEM( z80->SP.W++ ); \
240 z80->reg.B.h = M_RDMEM( z80->SP.W++ ); \
241 }while(0)
242 #define M_PUSH(reg) do{ \
243 M_WRMEM( --z80->SP.W, z80->reg.B.h ); \
244 M_WRMEM( --z80->SP.W, z80->reg.B.l ); \
245 }while(0)
246 #define M_CALL() do{ \
247 J.B.l = M_RDMEM( z80->PC.W++ ); \
248 J.B.h = M_RDMEM( z80->PC.W++ ); \
249 M_WRMEM( --z80->SP.W, z80->PC.B.h ); \
250 M_WRMEM( --z80->SP.W, z80->PC.B.l ); \
251 z80->PC.W = J.W; \
252 z80->state0 += 7; \
253 }while(0)
254 #define M_JP() do{ \
255 J.B.l = M_RDMEM( z80->PC.W++ ); \
256 J.B.h = M_RDMEM( z80->PC.W ); \
257 z80->PC.W = J.W; \
258 }while(0)
259 #define M_JR() do{ \
260 z80->PC.W += (offset)M_RDMEM(z80->PC.W)+1; \
261 z80->state0 += 5; \
262 }while(0)
263 #define M_RET() do{ \
264 z80->PC.B.l = M_RDMEM( z80->SP.W++ ); \
265 z80->PC.B.h = M_RDMEM( z80->SP.W++ ); \
266 z80->state0 += 6; \
267 }while(0)
268 #define M_RST(addr) do{ \
269 M_WRMEM( --z80->SP.W, z80->PC.B.h ); \
270 M_WRMEM( --z80->SP.W, z80->PC.B.l ); \
271 z80->PC.W = addr; \
272 }while(0)
273
274
275 #define M_CALL_SKIP() do{ z80->PC.W += 2; }while(0)
276 #define M_JP_SKIP() do{ z80->PC.W += 2; }while(0)
277 #define M_JR_SKIP() do{ z80->PC.W ++; }while(0)
278 #define M_RET_SKIP() do{ }while(0)
279
280 /*------------------------------------------------------*/
281 /* 16�ӥåȥ���̿��Υޥ��� */
282 /* �ե饰�Ѳ� : S Z H PV N C */
283 /* �� �� �� �� �� �� */
284 /*------------------------------------------------------*/
285 #define M_LDWORD(reg) do{ \
286 z80->reg.B.l = M_RDMEM( z80->PC.W++ ); \
287 z80->reg.B.h = M_RDMEM( z80->PC.W++ ); \
288 }while(0)
289
290 /*------------------------------------------------------*/
291 /* 8�ӥåȻ��ѱ黻̿��Υޥ��� */
292 /* �ե饰�Ѳ� : S Z H PV N C */
293 /* �� �� �� �� �� �� */
294 /* (�� �� �ơ��֥뻲��) */
295 /*------------------------------------------------------*/
296 #define M_ADD_A(reg) do{ \
297 J.W = z80->ACC+reg; \
298 z80->FLAG = \
299 SZ_table[J.B.l] | ((z80->ACC^reg^J.B.l)&H_FLAG) | \
300 (~(z80->ACC^reg)&(reg^J.B.l)&0x80? V_FLAG:0) | \
301 J.B.h; \
302 z80->ACC = J.B.l; \
303 }while(0)
304 #define M_ADC_A(reg) do{ \
305 J.W = z80->ACC +reg +(z80->FLAG&C_FLAG); \
306 z80->FLAG = \
307 SZ_table[J.B.l] | ((z80->ACC^reg^J.B.l)&H_FLAG) | \
308 (~(z80->ACC^reg)&(reg^J.B.l)&0x80? V_FLAG:0) | \
309 J.B.h; \
310 z80->ACC = J.B.l; \
311 }while(0)
312 #define M_SUB(reg) do{ \
313 J.W = z80->ACC-reg; \
314 z80->FLAG = \
315 SZ_table[J.B.l] | ((z80->ACC^reg^J.B.l)&H_FLAG) | \
316 ((z80->ACC^reg)&(z80->ACC^J.B.l)&0x80? V_FLAG:0)| \
317 N_FLAG | -J.B.h; \
318 z80->ACC = J.B.l; \
319 }while(0)
320 #define M_SBC_A(reg) do{ \
321 J.W = z80->ACC-reg-(z80->FLAG&C_FLAG); \
322 z80->FLAG = \
323 SZ_table[J.B.l] | ((z80->ACC^reg^J.B.l)&H_FLAG) | \
324 ((z80->ACC^reg)&(z80->ACC^J.B.l)&0x80? V_FLAG:0)| \
325 N_FLAG | -J.B.h; \
326 z80->ACC = J.B.l; \
327 }while(0)
328 #define M_CP(reg) do{ \
329 J.W = z80->ACC-reg; \
330 z80->FLAG = \
331 SZ_table[J.B.l] | ((z80->ACC^reg^J.B.l)&H_FLAG) | \
332 ((z80->ACC^reg)&(z80->ACC^J.B.l)&0x80? V_FLAG:0)| \
333 N_FLAG | -J.B.h; \
334 }while(0)
335 #define M_INC(reg) do{ \
336 reg++; \
337 z80->FLAG = \
338 SZ_table[reg] | (reg&0x0f? 0:H_FLAG) | \
339 (reg==0x80? V_FLAG:0) | (z80->FLAG&C_FLAG); \
340 }while(0)
341 #define M_DEC(reg) do{ \
342 reg--; \
343 z80->FLAG = \
344 SZ_table[reg] | ((reg&0x0f)==0x0f? H_FLAG:0) | \
345 (reg==0x7f? V_FLAG:0)| N_FLAG |(z80->FLAG&C_FLAG);\
346 }while(0)
347
348 /*------------------------------------------------------*/
349 /* 8�ӥå�����̿��Υޥ��� */
350 /* �ե饰�Ѳ� : S Z H PV N C */
351 /* (AND) �� �� 1 �� 0 0 */
352 /* (�� �� �� �ơ��֥뻲��) */
353 /* �ե饰�Ѳ� : S Z H PV N C */
354 /* (OR/XOR) �� �� 0 �� 0 0 */
355 /* (�� �� �� �ơ��֥뻲��) */
356 /*------------------------------------------------------*/
357 #define M_AND(reg) do{ \
358 z80->ACC &= reg; \
359 z80->FLAG = SZP_table[z80->ACC]|H_FLAG; \
360 }while(0)
361 #define M_OR(reg) do{ \
362 z80->ACC |= reg; \
363 z80->FLAG = SZP_table[z80->ACC]; \
364 }while(0)
365 #define M_XOR(reg) do{ \
366 z80->ACC ^= reg; \
367 z80->FLAG = SZP_table[z80->ACC]; \
368 }while(0)
369
370 /*------------------------------------------------------*/
371 /* ������̿��Υޥ��� */
372 /* �ե饰�Ѳ� : S Z H PV N C */
373 /* (IN) �� �� 0 �� 0 �� */
374 /* (�� �� �� �ơ��֥뻲��) */
375 /* �ե饰�Ѳ� : S Z H PV N C */
376 /* (OUT) �� �� �� �� �� �� */
377 /*------------------------------------------------------*/
378 #define M_IN_C(reg) do{ \
379 I = M_RDIO( z80->BC.B.l ); \
380 reg = I; \
381 z80->FLAG = SZP_table[reg]|(z80->FLAG&C_FLAG);\
382 }while(0)
383
384 #define M_OUT_C(reg) do{ \
385 M_WRIO( z80->BC.B.l, reg ); \
386 }while(0)
387
388
389 /*------------------------------------------------------*/
390 /* 16�ӥåȻ��ѱ黻̿��Υޥ��� */
391 /* �ե饰�Ѳ� : S Z H PV N C */
392 /* (ADD) �� �� �� �� 0 �� */
393 /* �ե饰�Ѳ� : S Z H PV N C */
394 /* (ADC/SBC) �� �� �� �� �� �� */
395 /*------------------------------------------------------*/
396 #define M_ADDW(reg1,reg2) do{ \
397 J.W = (reg1+reg2)&0xffff; \
398 z80->FLAG = \
399 (z80->FLAG&~(H_FLAG|N_FLAG|C_FLAG))| \
400 ((reg1^reg2^J.W)&0x1000? H_FLAG:0) | \
401 (((long)reg1+(long)reg2)&0x10000?C_FLAG:0);\
402 reg1 = J.W; \
403 }while(0)
404 #define M_ADCW(reg) do{ \
405 I = z80->FLAG&C_FLAG; \
406 J.W = (z80->HL.W+reg+I)&0xffff; \
407 z80->FLAG = \
408 (J.B.h&S_FLAG) | (J.W? 0:Z_FLAG) | \
409 ((z80->HL.W^reg^J.W)&0x1000? H_FLAG:0) | \
410 (~(z80->HL.W^reg)&(reg^J.W)&0x8000? V_FLAG:0) | \
411 (((long)z80->HL.W+(long)reg+(long)I)&0x10000?C_FLAG:0);\
412 z80->HL.W = J.W; \
413 }while(0)
414 #define M_SBCW(reg) do{ \
415 I = z80->FLAG&C_FLAG; \
416 J.W = (z80->HL.W-reg-I)&0xffff; \
417 z80->FLAG = \
418 (J.B.h&S_FLAG) | (J.W? 0:Z_FLAG) | \
419 ((z80->HL.W^reg^J.W)&0x1000? H_FLAG:0) |\
420 ((z80->HL.W^reg)&(z80->HL.W^J.W)&0x8000? V_FLAG:0)|\
421 N_FLAG | \
422 (((long)z80->HL.W-(long)reg-(long)I)&0x10000?C_FLAG:0);\
423 z80->HL.W = J.W; \
424 }while(0)
425
426
427
428 /*---------------------------------------------------------------------------*/
429
430 enum Codes
431 {
432 NOP, LD_BC_16, LD_xBC_A, INC_BC, INC_B, DEC_B, LD_B_8, RLCA,
433 EX_AF_AF,ADD_HL_BC,LD_A_xBC, DEC_BC, INC_C, DEC_C, LD_C_8, RRCA,
434 DJNZ, LD_DE_16, LD_xDE_A, INC_DE, INC_D, DEC_D, LD_D_8, RLA,
435 JR, ADD_HL_DE,LD_A_xDE, DEC_DE, INC_E, DEC_E, LD_E_8, RRA,
436 JR_NZ, LD_HL_16, LD_x16_HL,INC_HL, INC_H, DEC_H, LD_H_8, DAA,
437 JR_Z, ADD_HL_HL,LD_HL_x16,DEC_HL, INC_L, DEC_L, LD_L_8, CPL,
438 JR_NC, LD_SP_16, LD_x16_A, INC_SP, INC_xHL, DEC_xHL, LD_xHL_8, SCF,
439 JR_C, ADD_HL_SP,LD_A_x16, DEC_SP, INC_A, DEC_A, LD_A_8, CCF,
440 LD_B_B, LD_B_C, LD_B_D, LD_B_E, LD_B_H, LD_B_L, LD_B_xHL, LD_B_A,
441 LD_C_B, LD_C_C, LD_C_D, LD_C_E, LD_C_H, LD_C_L, LD_C_xHL, LD_C_A,
442 LD_D_B, LD_D_C, LD_D_D, LD_D_E, LD_D_H, LD_D_L, LD_D_xHL, LD_D_A,
443 LD_E_B, LD_E_C, LD_E_D, LD_E_E, LD_E_H, LD_E_L, LD_E_xHL, LD_E_A,
444 LD_H_B, LD_H_C, LD_H_D, LD_H_E, LD_H_H, LD_H_L, LD_H_xHL, LD_H_A,
445 LD_L_B, LD_L_C, LD_L_D, LD_L_E, LD_L_H, LD_L_L, LD_L_xHL, LD_L_A,
446 LD_xHL_B,LD_xHL_C, LD_xHL_D, LD_xHL_E, LD_xHL_H,LD_xHL_L,HALT, LD_xHL_A,
447 LD_A_B, LD_A_C, LD_A_D, LD_A_E, LD_A_H, LD_A_L, LD_A_xHL, LD_A_A,
448 ADD_A_B, ADD_A_C, ADD_A_D, ADD_A_E, ADD_A_H, ADD_A_L, ADD_A_xHL,ADD_A_A,
449 ADC_A_B, ADC_A_C, ADC_A_D, ADC_A_E, ADC_A_H, ADC_A_L, ADC_A_xHL,ADC_A_A,
450 SUB_B, SUB_C, SUB_D, SUB_E, SUB_H, SUB_L, SUB_xHL, SUB_A,
451 SBC_A_B, SBC_A_C, SBC_A_D, SBC_A_E, SBC_A_H, SBC_A_L, SBC_A_xHL,SBC_A_A,
452 AND_B, AND_C, AND_D, AND_E, AND_H, AND_L, AND_xHL, AND_A,
453 XOR_B, XOR_C, XOR_D, XOR_E, XOR_H, XOR_L, XOR_xHL, XOR_A,
454 OR_B, OR_C, OR_D, OR_E, OR_H, OR_L, OR_xHL, OR_A,
455 CP_B, CP_C, CP_D, CP_E, CP_H, CP_L, CP_xHL, CP_A,
456 RET_NZ, POP_BC, JP_NZ, JP, CALL_NZ, PUSH_BC, ADD_A_8, RST00,
457 RET_Z, RET, JP_Z, PFX_CB, CALL_Z, CALL, ADC_A_8, RST08,
458 RET_NC, POP_DE, JP_NC, OUT_x8_A, CALL_NC, PUSH_DE, SUB_8, RST10,
459 RET_C, EXX, JP_C, IN_A_x8, CALL_C, PFX_DD, SBC_A_8, RST18,
460 RET_PO, POP_HL, JP_PO, EX_xSP_HL,CALL_PO, PUSH_HL, AND_8, RST20,
461 RET_PE, JP_xHL, JP_PE, EX_DE_HL, CALL_PE, PFX_ED, XOR_8, RST28,
462 RET_P, POP_AF, JP_P, DI, CALL_P, PUSH_AF, OR_8, RST30,
463 RET_M, LD_SP_HL, JP_M, EI, CALL_M, PFX_FD, CP_8, RST38,
464 EndofCodes
465 };
466
467 enum CodesCB
468 {
469 RLC_B, RLC_C, RLC_D, RLC_E, RLC_H, RLC_L, RLC_xHL, RLC_A,
470 RRC_B, RRC_C, RRC_D, RRC_E, RRC_H, RRC_L, RRC_xHL, RRC_A,
471 RL_B, RL_C, RL_D, RL_E, RL_H, RL_L, RL_xHL, RL_A,
472 RR_B, RR_C, RR_D, RR_E, RR_H, RR_L, RR_xHL, RR_A,
473 SLA_B, SLA_C, SLA_D, SLA_E, SLA_H, SLA_L, SLA_xHL, SLA_A,
474 SRA_B, SRA_C, SRA_D, SRA_E, SRA_H, SRA_L, SRA_xHL, SRA_A,
475 SLL_B, SLL_C, SLL_D, SLL_E, SLL_H, SLL_L, SLL_xHL, SLL_A,
476 SRL_B, SRL_C, SRL_D, SRL_E, SRL_H, SRL_L, SRL_xHL, SRL_A,
477 BIT_0_B, BIT_0_C, BIT_0_D, BIT_0_E, BIT_0_H, BIT_0_L, BIT_0_xHL, BIT_0_A,
478 BIT_1_B, BIT_1_C, BIT_1_D, BIT_1_E, BIT_1_H, BIT_1_L, BIT_1_xHL, BIT_1_A,
479 BIT_2_B, BIT_2_C, BIT_2_D, BIT_2_E, BIT_2_H, BIT_2_L, BIT_2_xHL, BIT_2_A,
480 BIT_3_B, BIT_3_C, BIT_3_D, BIT_3_E, BIT_3_H, BIT_3_L, BIT_3_xHL, BIT_3_A,
481 BIT_4_B, BIT_4_C, BIT_4_D, BIT_4_E, BIT_4_H, BIT_4_L, BIT_4_xHL, BIT_4_A,
482 BIT_5_B, BIT_5_C, BIT_5_D, BIT_5_E, BIT_5_H, BIT_5_L, BIT_5_xHL, BIT_5_A,
483 BIT_6_B, BIT_6_C, BIT_6_D, BIT_6_E, BIT_6_H, BIT_6_L, BIT_6_xHL, BIT_6_A,
484 BIT_7_B, BIT_7_C, BIT_7_D, BIT_7_E, BIT_7_H, BIT_7_L, BIT_7_xHL, BIT_7_A,
485 RES_0_B, RES_0_C, RES_0_D, RES_0_E, RES_0_H, RES_0_L, RES_0_xHL, RES_0_A,
486 RES_1_B, RES_1_C, RES_1_D, RES_1_E, RES_1_H, RES_1_L, RES_1_xHL, RES_1_A,
487 RES_2_B, RES_2_C, RES_2_D, RES_2_E, RES_2_H, RES_2_L, RES_2_xHL, RES_2_A,
488 RES_3_B, RES_3_C, RES_3_D, RES_3_E, RES_3_H, RES_3_L, RES_3_xHL, RES_3_A,
489 RES_4_B, RES_4_C, RES_4_D, RES_4_E, RES_4_H, RES_4_L, RES_4_xHL, RES_4_A,
490 RES_5_B, RES_5_C, RES_5_D, RES_5_E, RES_5_H, RES_5_L, RES_5_xHL, RES_5_A,
491 RES_6_B, RES_6_C, RES_6_D, RES_6_E, RES_6_H, RES_6_L, RES_6_xHL, RES_6_A,
492 RES_7_B, RES_7_C, RES_7_D, RES_7_E, RES_7_H, RES_7_L, RES_7_xHL, RES_7_A,
493 SET_0_B, SET_0_C, SET_0_D, SET_0_E, SET_0_H, SET_0_L, SET_0_xHL, SET_0_A,
494 SET_1_B, SET_1_C, SET_1_D, SET_1_E, SET_1_H, SET_1_L, SET_1_xHL, SET_1_A,
495 SET_2_B, SET_2_C, SET_2_D, SET_2_E, SET_2_H, SET_2_L, SET_2_xHL, SET_2_A,
496 SET_3_B, SET_3_C, SET_3_D, SET_3_E, SET_3_H, SET_3_L, SET_3_xHL, SET_3_A,
497 SET_4_B, SET_4_C, SET_4_D, SET_4_E, SET_4_H, SET_4_L, SET_4_xHL, SET_4_A,
498 SET_5_B, SET_5_C, SET_5_D, SET_5_E, SET_5_H, SET_5_L, SET_5_xHL, SET_5_A,
499 SET_6_B, SET_6_C, SET_6_D, SET_6_E, SET_6_H, SET_6_L, SET_6_xHL, SET_6_A,
500 SET_7_B, SET_7_C, SET_7_D, SET_7_E, SET_7_H, SET_7_L, SET_7_xHL, SET_7_A,
501 EndofCodesCB
502 };
503
504 enum CodesED
505 {
506 ED_00, ED_01, ED_02, ED_03, ED_04, ED_05, ED_06, ED_07,
507 ED_08, ED_09, ED_0A, ED_0B, ED_0C, ED_0D, ED_0E, ED_0F,
508 ED_10, ED_11, ED_12, ED_13, ED_14, ED_15, ED_16, ED_17,
509 ED_18, ED_19, ED_1A, ED_1B, ED_1C, ED_1D, ED_1E, ED_1F,
510 ED_20, ED_21, ED_22, ED_23, ED_24, ED_25, ED_26, ED_27,
511 ED_28, ED_29, ED_2A, ED_2B, ED_2C, ED_2D, ED_2E, ED_2F,
512 ED_30, ED_31, ED_32, ED_33, ED_34, ED_35, ED_36, ED_37,
513 ED_38, ED_39, ED_3A, ED_3B, ED_3C, ED_3D, ED_3E, ED_3F,
514 IN_B_xC, OUT_xC_B, SBC_HL_BC, LD_x16x_BC, NEG, RETN, IM_0, LD_I_A,
515 IN_C_xC, OUT_xC_C, ADC_HL_BC, LD_BC_x16x, NEG_4C, RETI, IM_0_4E, LD_R_A,
516 IN_D_xC, OUT_xC_D, SBC_HL_DE, LD_x16x_DE, NEG_54, RETN_55, IM_1, LD_A_I,
517 IN_E_xC, OUT_xC_E, ADC_HL_DE, LD_DE_x16x, NEG_5C, RETN_5D, IM_2, LD_A_R,
518 IN_H_xC, OUT_xC_H, SBC_HL_HL, LD_x16x_HL, NEG_64, RETN_65, IM_0_66, RRD,
519 IN_L_xC, OUT_xC_L, ADC_HL_HL, LD_HL_x16x, NEG_6C, RETN_6D, IM_0_6E, RLD,
520 IN_F_xC, OUT_xC_F, SBC_HL_SP, LD_x16x_SP, NEG_74, RETN_75, IM_1_76, ED_77,
521 IN_A_xC, OUT_xC_A, ADC_HL_SP, LD_SP_x16x, NEG_7C, RETN_7D, IM_2_7E, ED_7F,
522 ED_80, ED_81, ED_82, ED_83, ED_84, ED_85, ED_86, ED_87,
523 ED_88, ED_89, ED_8A, ED_8B, ED_8C, ED_8D, ED_8E, ED_8F,
524 ED_90, ED_91, ED_92, ED_93, ED_94, ED_95, ED_96, ED_97,
525 ED_98, ED_99, ED_9A, ED_9B, ED_9C, ED_9D, ED_9E, ED_9F,
526 LDI, CPI, INI, OUTI, ED_A4, ED_A5, ED_A6, ED_A7,
527 LDD, CPD, IND, OUTD, ED_AC, ED_AD, ED_AE, ED_AF,
528 LDIR, CPIR, INIR, OTIR, ED_B4, ED_B5, ED_B6, ED_B7,
529 LDDR, CPDR, INDR, OTDR, ED_BC, ED_BD, ED_BE, ED_BF,
530 ED_C0, ED_C1, ED_C2, ED_C3, ED_C4, ED_C5, ED_C6, ED_C7,
531 ED_C8, ED_C9, ED_CA, ED_CB, ED_CC, ED_CD, ED_CE, ED_CF,
532 ED_D0, ED_D1, ED_D2, ED_D3, ED_D4, ED_D5, ED_D6, ED_D7,
533 ED_D8, ED_D9, ED_DA, ED_DB, ED_DC, ED_DD, ED_DE, ED_DF,
534 ED_E0, ED_E1, ED_E2, ED_E3, ED_E4, ED_E5, ED_E6, ED_E7,
535 ED_E8, ED_E9, ED_EA, ED_EB, ED_EC, ED_ED, ED_EE, ED_EF,
536 ED_F0, ED_F1, ED_F2, ED_F3, ED_F4, ED_F5, ED_F6, ED_F7,
537 ED_F8, ED_F9, ED_FA, ED_FB, ED_FC, ED_FD, ED_FE, ED_FF,
538 EndofCodesED
539 };
540
541
542 /*---------------------------------------------------------------------------*/
543
544
545 #include "z80-table.h"
546
547
548 /*---------------------------------------------------------------------------*/
549
z80_code_CB(z80arch * z80)550 INLINE void z80_code_CB( z80arch *z80 )
551 {
552 int opcode;
553 byte I;
554
555 opcode = M_FETCH( z80->PC.W++ );
556 z80->R ++;
557 z80->state0 += state_CB_table[ opcode ];
558
559 switch( opcode ){
560 #include "z80-codeCB.h" /* CB XX */
561 default: /* CB ?? */
562 printf("!! Internal Error in Z80-Emulator !!\n");
563 printf(" PC = %04X : code = CB %02X\n", z80->PC.W-2, opcode );
564 }
565 }
566
567
z80_code_ED(z80arch * z80)568 INLINE void z80_code_ED( z80arch *z80 )
569 {
570 int opcode;
571 byte I;
572 pair J;
573
574 opcode = M_FETCH( z80->PC.W++ );
575 z80->R ++;
576 z80->state0 += state_ED_table[ opcode ];
577
578 switch( opcode ){
579 #include "z80-codeED.h" /* ED XX */
580 default: /* ED ?? */
581 if( verbose_z80 )
582 printf( "Unrecognized instruction: ED %02X at PC=%04X\n",
583 M_RDMEM(z80->PC.W-1), z80->PC.W-2 );
584 z80->state0 += 8; /* ED ?? == NOP NOP */
585 }
586 }
587
588
z80_code_DD(z80arch * z80)589 INLINE void z80_code_DD( z80arch *z80 )
590 {
591 int opcode;
592 byte I;
593 pair J;
594
595 opcode = M_FETCH( z80->PC.W++ );
596 z80->R ++;
597 z80->state0 += state_XX_table[ opcode ];
598
599 #define XX IX
600
601 switch( opcode ){
602 #include "z80-codeXX.h" /* DD XX */
603 case PFX_CB: /* DD CB �� */
604 J.W = z80->XX.W +(offset)M_RDMEM( z80->PC.W++ );
605 opcode = M_FETCH( z80->PC.W++ );
606 z80->state0 += state_XXCB_table[ opcode ];
607 switch( opcode ){
608 #include "z80-codeXXCB.h" /* DD CB XX XX */
609 default: /* DD CB ?? ?? */
610 printf("!! Internal Error in Z80-Emulator !!\n");
611 printf(" PC = %04x : code = DD CB %02X %02X\n", z80->PC.W-4,
612 M_RDMEM(z80->PC.W-2), M_RDMEM(z80->PC.W-1) );
613 }
614 break;
615 default: /* DD ?? */
616 if( verbose_z80 )
617 printf( "Unrecognized instruction: DD %02X at PC=%04X\n",
618 M_RDMEM(z80->PC.W-1), z80->PC.W-2 );
619 z80->PC.W --;
620 z80->R --; /* ?? �ΰ��֤�PC���᤹ */
621 z80->state0 += 4; /* DD == NOP */
622 z80->skip_intr_chk = TRUE; /* ������Ƚ��ʤ� */
623 z80_state_intchk = 0;
624 break;
625 }
626 #undef XX
627 }
628
629
z80_code_FD(z80arch * z80)630 INLINE void z80_code_FD( z80arch *z80 )
631 {
632 int opcode;
633 byte I;
634 pair J;
635
636 opcode = M_FETCH( z80->PC.W++ );
637 z80->R ++;
638 z80->state0 += state_XX_table[ opcode ];
639
640 #define XX IY
641
642 switch( opcode ){
643 #include "z80-codeXX.h" /* FD XX */
644 case PFX_CB: /* FD CB �� */
645 J.W = z80->XX.W +(offset)M_RDMEM( z80->PC.W++ );
646 opcode = M_FETCH( z80->PC.W++ );
647 z80->state0 += state_XXCB_table[ opcode ];
648 switch( opcode ){
649 #include "z80-codeXXCB.h" /* FD CB XX XX */
650 default: /* FD CB ?? ?? */
651 printf("!! Internal Error in Z80-Emulator !!\n");
652 printf(" PC = %04x : code = FD CB %02X %02X\n", z80->PC.W-4,
653 M_RDMEM(z80->PC.W-2), M_RDMEM(z80->PC.W-1) );
654 }
655 break;
656 default: /* FD ?? */
657 if( verbose_z80 )
658 printf( "Unrecognized instruction: FD %02X at PC=%04X\n",
659 M_RDMEM(z80->PC.W-1), z80->PC.W-2 );
660 z80->PC.W --;
661 z80->R --; /* ?? �ΰ��֤�PC���᤹ */
662 z80->state0 += 4; /* FD == NOP */
663 z80->skip_intr_chk = TRUE; /* ������Ƚ��ʤ� */
664 z80_state_intchk = 0;
665 break;
666 }
667 #undef XX
668 }
669
670
671
672
z80_im0_interrupt(z80arch * z80,int level)673 static int z80_im0_interrupt( z80arch *z80, int level )
674 {
675 int state;
676 pair J;
677
678 state = state_table[ level ];
679
680 switch( level ){
681 case 0: /* NOP */
682 break;
683 case 1: /* LD (BC),A */
684 M_WRMEM(z80->BC.W,z80->ACC);
685 break;
686 case 2: /* INC B */
687 M_INC(z80->BC.B.h);
688 break;
689 case 3: /* LD B,n */
690 z80->BC.B.h=M_RDMEM(z80->PC.W++);
691 break;
692 case 4: /* EX AF,AF' */
693 J.W=z80->AF.W; z80->AF.W=z80->AF1.W; z80->AF1.W=J.W;
694 break;
695 case 5: /* LD A,(BC) */
696 z80->ACC=M_RDMEM(z80->BC.W);
697 break;
698 case 6: /* INC C */
699 M_INC(z80->BC.B.l);
700 break;
701 case 7: /* LD C,n */
702 z80->BC.B.l=M_RDMEM(z80->PC.W++);
703 break;
704 default:
705 if( verbose_z80 )
706 printf("Unexpected interrupt signal %X\n",level );
707 break;
708 }
709
710 return state;
711 }
712
713
z80_interrupt(z80arch * z80)714 INLINE void z80_interrupt( z80arch *z80 )
715 {
716 int level;
717
718 level = (z80->intr_ack)();
719 if( level >= 0 ){
720 z80->IFF = INT_DISABLE; /* �����߶ػ� */
721 z80->R ++; /* �����߱����������� */
722 z80->state0 += 2;
723
724 if( z80->HALT ){ /* HALT ���ֲ�� */
725 z80->HALT = FALSE;
726 z80->PC.W ++;
727 }
728
729 switch( z80->IM ){ /* ������ʬ������ */
730 case 0: /* IM 0 �λ� */
731 z80->state0 += z80_im0_interrupt( z80, level );
732 break;
733 case 1: /* IM 1 �λ� */
734 z80->state0 += state_table[ RST38 ];
735 M_RST(0x0038);
736 break;
737 case 2: /* IM 2 �λ� */
738 M_PUSH(PC);
739 level = ((word)z80->I << 8) | (level << 1);
740 z80->PC.B.l = M_RDMEM( level++ );
741 z80->PC.B.h = M_RDMEM( level );
742 z80->state0 += 17;
743 break;
744 }
745 }
746 }
747
748
749
750 /****************************************************************************
751 * int z80_emu( z80arch *z80, int state_of_exec )
752 *
753 * ���� *z80 �� z80arch ����Υݥ���
754 * state_of_exec �� �������٤����ơ��ȿ�
755 * ==0 �λ��ϡ�̵�¤˽�����Ԥʤ���
756 * > 0 �λ��ϡ����Υ��ơ��ȿ�ʬ������Ԥʤ���
757 * state_of_exec==0 �ξ��Ǥ⡢CPU_BREAKOFF() ���ƤӽФ��줿��
758 * ���λ����ǽ�����λ���롣
759 *
760 * ���� �� �ºݤ˽����������ơ��ȿ�
761 *
762 *****************************************************************************/
763
764 /* �ʲ��Υ���ϡ����������ѹ������Τǥ����Х��ѿ��Ȥ��Ƥ��롣 */
765 /* ����������ѹ��ϡ�(¿ʬ) ���߽������ CPU���Ф��ƤΤߤʤ����ϥ� */
766 /* �ʤΤǡ�z80arch ��¤�Τˤϴޤ�ʤ����Ȥˤ��롣 */
767
768 int z80_state_goal; /* ����state��ʬ���������֤�(0��̵��) */
769 int z80_state_intchk; /* ����state���¹Ը塢���Ƚ�ꤹ�� */
770
771
z80_emu(z80arch * z80,int state_of_exec)772 int z80_emu( z80arch *z80, int state_of_exec )
773 {
774 int opcode, istate = 0;
775 byte I;
776 pair J;
777 int total_state = 0; /* �ؿ���λ���ޤǤˡ������������ơ��ȿ� */
778
779
780 z80_state_goal = state_of_exec;
781
782 for( ;; ){
783
784 /* ==== CPU�¹�state������� (�̾�ϼ����ȯ�������ߥ�) ==== */
785
786 if( z80_state_goal ){ /* state������� */
787 z80_state_intchk = MIN( z80->icount, z80_state_goal - total_state );
788 }
789 else{ /* ̵�»���� */
790 z80_state_intchk = z80->icount;
791 }
792
793
794 /* ============ ��ۤɷ� state��ʬ���¹Ԥ��� ============ */
795
796 do{
797
798 #ifdef DEBUGLOG
799 if( z80->log ) z80_logging( z80 ); /* ����Ͽ */
800 #endif
801
802 #ifdef USE_MONITOR
803 z80->PC_prev = z80->PC; /* ľ���Τ�Τ� */
804 #endif
805
806 opcode = M_FETCH(z80->PC.W++); /* ̿��ե��å� */
807 z80->R ++;
808 z80->state0 += state_table[ opcode ];
809
810 switch( opcode ){ /* ̿��ǥ����� */
811
812 #include "z80-code.h" /* �̾�̿��ξ�� */
813
814 case PFX_CB: z80_code_CB( z80 ); break; /* CB ̿��ξ�� */
815
816 case PFX_ED: z80_code_ED( z80 ); break; /* ED ̿��ξ�� */
817
818 case PFX_DD: z80_code_DD( z80 ); break; /* DD ̿��ξ�� */
819
820 case PFX_FD: z80_code_FD( z80 ); break; /* FD ̿��ξ�� */
821
822 default: /* �������ʤ��ϥ� */
823 printf("!! Internal Error in Z80-Emulator !!\n");
824 printf(" PC = %04X : code = %02X\n", z80->PC.W-1, opcode );
825 }
826
827 } while( z80->state0 < z80_state_intchk );
828
829 /* ===================== ��������� ====================== */
830
831 /* ������ȯ����Ƚ�ꤹ��ؿ���ƤӽФ��� */
832 /* */
833 /* �ƤӽФ����ؿ�¦��������� */
834 /* z80->state0 �� CPU�������������֤ʤΤǤ����Ƚ�ꤹ�롣 */
835 /* (z80->icount�ϲ�����Ƥ��뤫�⤷��ʤ��Τǡ����Ƥˤ��ʤ�) */
836 /* ���ȯ�����ϡ� z80->INT_active = TRUE �åȤ��롣 */
837 /* z80->icount �ι����⤳�δؿ��ˤƹԤ��� */
838 /* ��˥塼���ؤ����ܻ��ϡ� CPU_BREAKOFF() �ǽ������롣 */
839
840 (z80->intr_update)();
841
842 total_state += z80->state0; /* �������� state �����߷� */
843 z80->state0 = 0;
844
845 /* ======== ���ȯ�������å�����ȯ�����Ƥ������������ ======== */
846
847 if( z80->skip_intr_chk ){ /* ����������ʤ���� (EI,DD/FD����̿��ľ��)*/
848 z80->skip_intr_chk = FALSE;
849
850 if( z80->IFF==INT_ENABLE && /* �����Ȥꤳ�ܤ��Ƥ��� */
851 z80->INT_active ){ /* ľ��˳���������뤿�ᡢ*/
852 z80->icount = 0; /* ����� 1step�����¹� */
853 }
854 }
855 else{ /* �̾�ϡ������������Τǡ����ä� */
856
857 if( z80->IFF==INT_ENABLE && /* ������Ĥ��ij��ȯ������ */
858 z80->INT_active ){
859
860 z80_interrupt( z80 );
861
862 /* �����ߤ�����դ���ȡ����ν���ʬ z80->state0 �����ä��뤬��
863 ����Ϥޤ� total_state �ˤ�ȿ�Ǥ���Ƥ��ʤ��Τǡ���ա� */
864 }
865 }
866
867 /* ========================== ��λȽ�� ======================= */
868
869 if( z80_state_goal ){ /* �¹�state��������ϡ������ǽ�λȽ�� */
870 if( (unsigned int)z80_state_goal <= (unsigned int)total_state ) break;
871
872 /* ��ա� ����state���¹Ԥ���ľ��˳����߱���������硢���α���
873 ���פ��� state ���� z80->state0 �ˤ�ȿ�Ǥ���Ƥ��뤬��
874 total_state �ˤ�ȿ�Ǥ���Ƥ��ʤ�����äơ������Ǥ�����ͤ�
875 z80->state0 �������ʤ��ͤˤʤ롣�����ͤϡ����� z80_emu ��
876 �ƤӽФ��줿���˲û�����Ƥ���Τǡ��ޤ��褷�Ȥ��褦��*/
877 }
878 }
879
880 return total_state;
881 }
882