1 /****************************************************************************
2  *						Intel 8039 Portable Emulator						*
3  *																			*
4  *					 Copyright (C) 1997 by Mirko Buffoni					*
5  *	Based on the original work (C) 1997 by Dan Boris, an 8048 emulator		*
6  *		You are not allowed to distribute this software commercially		*
7  *		  Please, notify me, if you make any changes to this file			*
8  *																			*
9  *																			*
10  *	**** Change Log ****													*
11  *																			*
12  *	TLP (19-Jun-2001)														*
13  *	 - Changed Ports 1 and 2 to quasi bidirectional output latched ports	*
14  *	 - Added the Port 1 & 2 output latch data to the debugger window		*
15  *	TLP (02-Jan-2002)														*
16  *	 - External IRQs no longer go pending (sampled as a level state)		*
17  *	 - Timer IRQs do not go pending if Timer interrupts are disabled		*
18  *	 - Timer IRQs made pending, were incorrectly being cleared if the		*
19  *		external interrupt was being serviced								*
20  *	 - External interrupts now take precedence when simultaneous			*
21  *		internal and external interrupt requests occur						*
22  *	 - 'DIS TCNTI' now removes pending timer IRQs							*
23  *	 - Nested IRQs of any sort are no longer allowed						*
24  *	 - T_flag was not being set in the right place of execution, which		*
25  *		could have lead to it being incorrectly set after being cleared		*
26  *	 - Counter overflows now also set the T_flag							*
27  *	 - Added the Timer/Counter register to the debugger window				*
28  *	TLP (09-Jan-2002)														*
29  *	 - Changed Interrupt system to instant servicing						*
30  *	 - The Timer and Counter can no longer be 'on' simultaneously			*
31  *	 - Added Save State														*
32  *  TLP (15-Feb-2002)                                                       *
33  *	 - Corrected Positive signal edge sensing (used on the T1 input)		*
34  ****************************************************************************/
35 
36 
37 #include <stdio.h>
38 #include <string.h>
39 #include <stdlib.h>
40 
41 #include "cpuintrf.h"
42 #include "state.h"
43 #include "mamedbg.h"
44 #include "i8039.h"
45 
46 
47 /*** Cycle times for the jump on condition instructions, are unusual.
48 	 Condition is tested during the first cycle, so if condition is not
49 	 met, second address fetch cycle may not really be taken. For now we
50 	 just use the cycle counts as listed in the i8048 user manual.
51 ***/
52 
53 #if 0
54 #define ADJUST_CYCLES { inst_cycles -= 1; }	/* Possible real cycles setting */
55 #else
56 #define ADJUST_CYCLES { }					/* User Manual cycles setting */
57 #endif
58 
59 
60 
61 /* HJB 01/05/99 changed to positive values to use pending_irq as a flag */
62 #define I8039_NO_INT		0	/* No Interrupts pending or executing	*/
63 #define I8039_EXTERNAL_INT	1	/* Execute a normal external interrupt	*/
64 #define I8039_TIMCNT_INT	2	/* Execute a Timer/Counter interrupt	*/
65 
66 
67 /* Layout of the registers in the debugger */
68 static UINT8 i8039_reg_layout[] = {
69 	I8039_PC, I8039_SP, I8039_PSW, I8039_A, I8039_IRQ_STATE,    I8039_TC, I8039_P1, I8039_P2, -1,
70 	I8039_R0, I8039_R1, I8039_R2, I8039_R3, I8039_R4, I8039_R5, I8039_R6, I8039_R7, 0
71 };
72 
73 /* Layout of the debugger windows x,y,w,h */
74 static UINT8 i8039_win_layout[] = {
75 	 0, 0,80, 2,	/* register window (top rows) */
76 	 0, 3,24,19,	/* disassembler window (left colums) */
77 	25, 3,55, 9,	/* memory #1 window (right, upper middle) */
78 	25,13,55, 9,	/* memory #2 window (right, lower middle) */
79 	 0,23,80, 1,	/* command line window (bottom rows) */
80 };
81 
82 
83 static int Ext_IRQ(void);
84 static int Timer_IRQ(void);
85 
86 #define M_RDMEM(A)		I8039_RDMEM(A)
87 #define M_RDOP(A)		I8039_RDOP(A)
88 #define M_RDOP_ARG(A)	I8039_RDOP_ARG(A)
89 #define M_IN(A)			I8039_In(A)
90 #define M_OUT(A,V)		I8039_Out(A,V)
91 
92 #define port_r(A)		I8039_In(I8039_p0 + A)
93 #define port_w(A,V)		I8039_Out(I8039_p0 + A,V)
94 #define test_r(A)		I8039_In(I8039_t0 + A)
95 #define test_w(A,V)		I8039_Out(I8039_t0 + A,V)
96 #define bus_r()			I8039_In(I8039_bus)
97 #define bus_w(V)		I8039_Out(I8039_bus,V)
98 
99 #define C_FLAG			0x80
100 #define A_FLAG			0x40
101 #define F_FLAG			0x20
102 #define B_FLAG			0x10
103 
104 typedef struct
105 {
106 	PAIR	PREVPC;			/* previous program counter */
107 	PAIR	PC;				/* program counter */
108 	UINT8	A, SP, PSW;
109 	UINT8	RAM[128];
110 	UINT8	bus, f1;		/* Bus data, and flag1 */
111 	UINT8	P1, P2;			/* Internal Port 1 and 2 latched outputs */
112 
113 	UINT8	pending_irq, irq_executing, masterClock, regPtr;
114 	UINT8	t_flag, timer, timerON, countON, xirq_en, tirq_en;
115 	UINT16	A11, A11ff;
116 	UINT8	irq_state, irq_extra_cycles;
117 	int		(*irq_callback)(int irqline);
118 } I8039_Regs;
119 
120 static I8039_Regs R;
121 int	   i8039_ICount;
122 int    inst_cycles;
123 static UINT8 Old_T1;
124 
125 /* The opcode table now is a combination of cycle counts and function pointers */
126 typedef struct {
127 	unsigned cycles;
128 	void (*function) (void);
129 }	s_opcode;
130 
131 #define POSITIVE_EDGE_T1  (( (int)(T1-Old_T1) > 0) ? 1 : 0)
132 #define NEGATIVE_EDGE_T1  (( (int)(Old_T1-T1) > 0) ? 1 : 0)
133 
134 #define M_Cy	((R.PSW & C_FLAG) >> 7)
135 #define M_Cn	(!M_Cy)
136 #define M_Ay	((R.PSW & A_FLAG))
137 #define M_An	(!M_Ay)
138 #define M_F0y	((R.PSW & F_FLAG))
139 #define M_F0n	(!M_F0y)
140 #define M_By	((R.PSW & B_FLAG))
141 #define M_Bn	(!M_By)
142 
143 #define intRAM	R.RAM
144 #define regPTR	R.regPtr
145 
146 #define R0	intRAM[regPTR  ]
147 #define R1	intRAM[regPTR+1]
148 #define R2	intRAM[regPTR+2]
149 #define R3	intRAM[regPTR+3]
150 #define R4	intRAM[regPTR+4]
151 #define R5	intRAM[regPTR+5]
152 #define R6	intRAM[regPTR+6]
153 #define R7	intRAM[regPTR+7]
154 
155 
CLR(UINT8 flag)156 static INLINE void CLR (UINT8 flag) { R.PSW &= ~flag; }
SET(UINT8 flag)157 static INLINE void SET (UINT8 flag) { R.PSW |= flag;  }
158 
159 
160 /* Get next opcode argument and increment program counter */
M_RDMEM_OPCODE(void)161 static INLINE unsigned M_RDMEM_OPCODE (void)
162 {
163 	unsigned retval;
164 	retval=M_RDOP_ARG(R.PC.w.l);
165 	R.PC.w.l++;
166 	return retval;
167 }
168 
push(UINT8 d)169 static INLINE void push(UINT8 d)
170 {
171 	intRAM[8+R.SP++] = d;
172 	R.SP  = R.SP & 0x0f;
173 	R.PSW = R.PSW & 0xf8;
174 	R.PSW = R.PSW | (R.SP >> 1);
175 }
176 
pull(void)177 static INLINE UINT8 pull(void) {
178 	R.SP  = (R.SP + 15) & 0x0f;		/*  if (--R.SP < 0) R.SP = 15;  */
179 	R.PSW = R.PSW & 0xf8;
180 	R.PSW = R.PSW | (R.SP >> 1);
181 	/* regPTR = ((M_By) ? 24 : 0);	regPTR should not change */
182 	return intRAM[8+R.SP];
183 }
184 
daa_a(void)185 static INLINE void daa_a(void)
186 {
187 	if ((R.A & 0x0f) > 0x09 || (R.PSW & A_FLAG))
188 		R.A += 0x06;
189 	if ((R.A & 0xf0) > 0x90 || (R.PSW & C_FLAG))
190 	{
191 		R.A += 0x60;
192 		SET(C_FLAG);
193 	} else CLR(C_FLAG);
194 }
195 
M_ADD(UINT8 dat)196 static INLINE void M_ADD(UINT8 dat)
197 {
198 	UINT16 temp;
199 
200 	CLR(C_FLAG | A_FLAG);
201 	if ((R.A & 0xf) + (dat & 0xf) > 0xf) SET(A_FLAG);
202 	temp = R.A + dat;
203 	if (temp > 0xff) SET(C_FLAG);
204 	R.A  = temp & 0xff;
205 }
206 
M_ADDC(UINT8 dat)207 static INLINE void M_ADDC(UINT8 dat)
208 {
209 	UINT16 temp;
210 
211 	CLR(A_FLAG);
212 	if ((R.A & 0xf) + (dat & 0xf) + M_Cy > 0xf) SET(A_FLAG);
213 	temp = R.A + dat + M_Cy;
214 	CLR(C_FLAG);
215 	if (temp > 0xff) SET(C_FLAG);
216 	R.A  = temp & 0xff;
217 }
218 
M_CALL(UINT16 addr)219 static INLINE void M_CALL(UINT16 addr)
220 {
221 	push(R.PC.b.l);
222 	push((R.PC.b.h & 0x0f) | (R.PSW & 0xf0));
223 	R.PC.w.l = addr;
224 	#ifdef MESS
225 		change_pc16(addr);
226 	#endif
227 
228 }
229 
M_XCHD(UINT8 addr)230 static INLINE void M_XCHD(UINT8 addr)
231 {
232 	UINT8 dat = R.A & 0x0f;
233 	R.A &= 0xf0;
234 	R.A |= intRAM[addr] & 0x0f;
235 	intRAM[addr] &= 0xf0;
236 	intRAM[addr] |= dat;
237 }
238 
239 
M_ILLEGAL(void)240 static INLINE void M_ILLEGAL(void)
241 {
242 	logerror("I8039:  PC = %04x,  Illegal opcode = %02x\n", R.PC.w.l-1, M_RDMEM(R.PC.w.l-1));
243 }
244 
M_UNDEFINED(void)245 static INLINE void M_UNDEFINED(void)
246 {
247 	logerror("I8039:  PC = %04x,  Unimplemented opcode = %02x\n", R.PC.w.l-1, M_RDMEM(R.PC.w.l-1));
248 }
249 
illegal(void)250 static void illegal(void)	 { M_ILLEGAL(); }
251 
add_a_n(void)252 static void add_a_n(void)	 { M_ADD(M_RDMEM_OPCODE()); }
add_a_r0(void)253 static void add_a_r0(void)	 { M_ADD(R0); }
add_a_r1(void)254 static void add_a_r1(void)	 { M_ADD(R1); }
add_a_r2(void)255 static void add_a_r2(void)	 { M_ADD(R2); }
add_a_r3(void)256 static void add_a_r3(void)	 { M_ADD(R3); }
add_a_r4(void)257 static void add_a_r4(void)	 { M_ADD(R4); }
add_a_r5(void)258 static void add_a_r5(void)	 { M_ADD(R5); }
add_a_r6(void)259 static void add_a_r6(void)	 { M_ADD(R6); }
add_a_r7(void)260 static void add_a_r7(void)	 { M_ADD(R7); }
add_a_xr0(void)261 static void add_a_xr0(void)	 { M_ADD(intRAM[R0 & 0x7f]); }
add_a_xr1(void)262 static void add_a_xr1(void)	 { M_ADD(intRAM[R1 & 0x7f]); }
adc_a_n(void)263 static void adc_a_n(void)	 { M_ADDC(M_RDMEM_OPCODE()); }
adc_a_r0(void)264 static void adc_a_r0(void)	 { M_ADDC(R0); }
adc_a_r1(void)265 static void adc_a_r1(void)	 { M_ADDC(R1); }
adc_a_r2(void)266 static void adc_a_r2(void)	 { M_ADDC(R2); }
adc_a_r3(void)267 static void adc_a_r3(void)	 { M_ADDC(R3); }
adc_a_r4(void)268 static void adc_a_r4(void)	 { M_ADDC(R4); }
adc_a_r5(void)269 static void adc_a_r5(void)	 { M_ADDC(R5); }
adc_a_r6(void)270 static void adc_a_r6(void)	 { M_ADDC(R6); }
adc_a_r7(void)271 static void adc_a_r7(void)	 { M_ADDC(R7); }
adc_a_xr0(void)272 static void adc_a_xr0(void)	 { M_ADDC(intRAM[R0 & 0x7f]); }
adc_a_xr1(void)273 static void adc_a_xr1(void)	 { M_ADDC(intRAM[R1 & 0x7f]); }
anl_a_n(void)274 static void anl_a_n(void)	 { R.A &= M_RDMEM_OPCODE(); }
anl_a_r0(void)275 static void anl_a_r0(void)	 { R.A &= R0; }
anl_a_r1(void)276 static void anl_a_r1(void)	 { R.A &= R1; }
anl_a_r2(void)277 static void anl_a_r2(void)	 { R.A &= R2; }
anl_a_r3(void)278 static void anl_a_r3(void)	 { R.A &= R3; }
anl_a_r4(void)279 static void anl_a_r4(void)	 { R.A &= R4; }
anl_a_r5(void)280 static void anl_a_r5(void)	 { R.A &= R5; }
anl_a_r6(void)281 static void anl_a_r6(void)	 { R.A &= R6; }
anl_a_r7(void)282 static void anl_a_r7(void)	 { R.A &= R7; }
anl_a_xr0(void)283 static void anl_a_xr0(void)	 { R.A &= intRAM[R0 & 0x7f]; }
anl_a_xr1(void)284 static void anl_a_xr1(void)	 { R.A &= intRAM[R1 & 0x7f]; }
anl_bus_n(void)285 static void anl_bus_n(void)	 { bus_w( bus_r() & M_RDMEM_OPCODE() ); }
anl_p1_n(void)286 static void anl_p1_n(void)	 { R.P1 &= M_RDMEM_OPCODE(); port_w( 1, R.P1 ); }
anl_p2_n(void)287 static void anl_p2_n(void)	 { R.P2 &= M_RDMEM_OPCODE(); port_w( 2, R.P2 ); }
anld_p4_a(void)288 static void anld_p4_a(void)	 { port_w( 4, port_r(4) & M_RDMEM_OPCODE() ); }
anld_p5_a(void)289 static void anld_p5_a(void)	 { port_w( 5, port_r(5) & M_RDMEM_OPCODE() ); }
anld_p6_a(void)290 static void anld_p6_a(void)	 { port_w( 6, port_r(6) & M_RDMEM_OPCODE() ); }
anld_p7_a(void)291 static void anld_p7_a(void)	 { port_w( 7, port_r(7) & M_RDMEM_OPCODE() ); }
call(void)292 static void call(void)		 { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | R.A11); }
call_1(void)293 static void call_1(void)	 { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x100 | R.A11); }
call_2(void)294 static void call_2(void)	 { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x200 | R.A11); }
call_3(void)295 static void call_3(void)	 { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x300 | R.A11); }
call_4(void)296 static void call_4(void)	 { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x400 | R.A11); }
call_5(void)297 static void call_5(void)	 { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x500 | R.A11); }
call_6(void)298 static void call_6(void)	 { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x600 | R.A11); }
call_7(void)299 static void call_7(void)	 { UINT8 i=M_RDMEM_OPCODE(); M_CALL(i | 0x700 | R.A11); }
clr_a(void)300 static void clr_a(void)		 { R.A=0; }
clr_c(void)301 static void clr_c(void)		 { CLR(C_FLAG); }
clr_f0(void)302 static void clr_f0(void)	 { CLR(F_FLAG); }
clr_f1(void)303 static void clr_f1(void)	 { R.f1 = 0; }
cpl_a(void)304 static void cpl_a(void)		 { R.A ^= 0xff; }
cpl_c(void)305 static void cpl_c(void)		 { R.PSW ^= C_FLAG; }
cpl_f0(void)306 static void cpl_f0(void)	 { R.PSW ^= F_FLAG; }
cpl_f1(void)307 static void cpl_f1(void)	 { R.f1 ^= 1; }
dec_a(void)308 static void dec_a(void)		 { R.A--; }
dec_r0(void)309 static void dec_r0(void)	 { R0--; }
dec_r1(void)310 static void dec_r1(void)	 { R1--; }
dec_r2(void)311 static void dec_r2(void)	 { R2--; }
dec_r3(void)312 static void dec_r3(void)	 { R3--; }
dec_r4(void)313 static void dec_r4(void)	 { R4--; }
dec_r5(void)314 static void dec_r5(void)	 { R5--; }
dec_r6(void)315 static void dec_r6(void)	 { R6--; }
dec_r7(void)316 static void dec_r7(void)	 { R7--; }
dis_i(void)317 static void dis_i(void)		 { R.xirq_en = 0; }
dis_tcnti(void)318 static void dis_tcnti(void)	 { R.tirq_en = 0; R.pending_irq &= ~I8039_TIMCNT_INT; }
319 #ifdef MESS
djnz_r0(void)320 	static void djnz_r0(void)	{ UINT8 i=M_RDMEM_OPCODE(); R0--; if (R0 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
djnz_r1(void)321 	static void djnz_r1(void)	{ UINT8 i=M_RDMEM_OPCODE(); R1--; if (R1 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
djnz_r2(void)322 	static void djnz_r2(void)	{ UINT8 i=M_RDMEM_OPCODE(); R2--; if (R2 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
djnz_r3(void)323 	static void djnz_r3(void)	{ UINT8 i=M_RDMEM_OPCODE(); R3--; if (R3 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
djnz_r4(void)324 	static void djnz_r4(void)	{ UINT8 i=M_RDMEM_OPCODE(); R4--; if (R4 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
djnz_r5(void)325 	static void djnz_r5(void)	{ UINT8 i=M_RDMEM_OPCODE(); R5--; if (R5 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
djnz_r6(void)326 	static void djnz_r6(void)	{ UINT8 i=M_RDMEM_OPCODE(); R6--; if (R6 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
djnz_r7(void)327 	static void djnz_r7(void)	{ UINT8 i=M_RDMEM_OPCODE(); R7--; if (R7 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
328 #else
djnz_r0(void)329 	static void djnz_r0(void)	{ UINT8 i=M_RDMEM_OPCODE(); R0--; if (R0 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
djnz_r1(void)330 	static void djnz_r1(void)	{ UINT8 i=M_RDMEM_OPCODE(); R1--; if (R1 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
djnz_r2(void)331 	static void djnz_r2(void)	{ UINT8 i=M_RDMEM_OPCODE(); R2--; if (R2 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
djnz_r3(void)332 	static void djnz_r3(void)	{ UINT8 i=M_RDMEM_OPCODE(); R3--; if (R3 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
djnz_r4(void)333 	static void djnz_r4(void)	{ UINT8 i=M_RDMEM_OPCODE(); R4--; if (R4 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
djnz_r5(void)334 	static void djnz_r5(void)	{ UINT8 i=M_RDMEM_OPCODE(); R5--; if (R5 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
djnz_r6(void)335 	static void djnz_r6(void)	{ UINT8 i=M_RDMEM_OPCODE(); R6--; if (R6 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
djnz_r7(void)336 	static void djnz_r7(void)	{ UINT8 i=M_RDMEM_OPCODE(); R7--; if (R7 != 0) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
337 #endif
en_i(void)338 static void en_i(void)		 { R.xirq_en = 1; if (R.irq_state == I8039_EXTERNAL_INT) { R.irq_extra_cycles += Ext_IRQ(); } }
en_tcnti(void)339 static void en_tcnti(void)	 { R.tirq_en = 1; }
ento_clk(void)340 static void ento_clk(void)	 { M_UNDEFINED(); }
in_a_p1(void)341 static void in_a_p1(void)	 { R.A = port_r(1) & R.P1; }
in_a_p2(void)342 static void in_a_p2(void)	 { R.A = port_r(2) & R.P2; }
ins_a_bus(void)343 static void ins_a_bus(void)	 { R.A = bus_r(); }
inc_a(void)344 static void inc_a(void)		 { R.A++; }
inc_r0(void)345 static void inc_r0(void)	 { R0++; }
inc_r1(void)346 static void inc_r1(void)	 { R1++; }
inc_r2(void)347 static void inc_r2(void)	 { R2++; }
inc_r3(void)348 static void inc_r3(void)	 { R3++; }
inc_r4(void)349 static void inc_r4(void)	 { R4++; }
inc_r5(void)350 static void inc_r5(void)	 { R5++; }
inc_r6(void)351 static void inc_r6(void)	 { R6++; }
inc_r7(void)352 static void inc_r7(void)	 { R7++; }
inc_xr0(void)353 static void inc_xr0(void)	 { intRAM[R0 & 0x7f]++; }
inc_xr1(void)354 static void inc_xr1(void)	 { intRAM[R1 & 0x7f]++; }
355 
356 /* static void jmp(void)	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | R.A11; }
357  */
358 
jmp(void)359 static void jmp(void)
360 {
361 	UINT8 i=M_RDOP(R.PC.w.l);
362 	UINT16 oldpc,newpc;
363 
364 	oldpc = R.PC.w.l-1;
365 	R.PC.w.l = i | R.A11;
366 #ifdef MESS
367 	change_pc16(R.PC.w.l);
368 #endif
369 	newpc = R.PC.w.l;
370 	if (newpc == oldpc) { if (i8039_ICount > 0) i8039_ICount = 0; } /* speed up busy loop */
371 	else if (newpc == oldpc-1 && M_RDOP(newpc) == 0x00)	/* NOP - Gyruss */
372 		{ if (i8039_ICount > 0) i8039_ICount = 0; }
373 }
374 
375 #ifdef MESS
jmp_1(void)376 	static void jmp_1(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x100 | R.A11; change_pc16(R.PC.w.l); }
jmp_2(void)377 	static void jmp_2(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x200 | R.A11; change_pc16(R.PC.w.l); }
jmp_3(void)378 	static void jmp_3(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x300 | R.A11; change_pc16(R.PC.w.l); }
jmp_4(void)379 	static void jmp_4(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x400 | R.A11; change_pc16(R.PC.w.l); }
jmp_5(void)380 	static void jmp_5(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x500 | R.A11; change_pc16(R.PC.w.l); }
jmp_6(void)381 	static void jmp_6(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x600 | R.A11; change_pc16(R.PC.w.l); }
jmp_7(void)382 	static void jmp_7(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x700 | R.A11; change_pc16(R.PC.w.l); }
jmpp_xa(void)383 	static void jmpp_xa(void)	 { UINT16 addr = (R.PC.w.l & 0xf00) | R.A; R.PC.w.l = (R.PC.w.l & 0xf00) | M_RDMEM(addr); change_pc16(R.PC.w.l); }
jb_0(void)384 	static void jb_0(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x01) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jb_1(void)385 	static void jb_1(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x02) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jb_2(void)386 	static void jb_2(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x04) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jb_3(void)387 	static void jb_3(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x08) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jb_4(void)388 	static void jb_4(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x10) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jb_5(void)389 	static void jb_5(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x20) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jb_6(void)390 	static void jb_6(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x40) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jb_7(void)391 	static void jb_7(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x80) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jf0(void)392 	static void jf0(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (M_F0y) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jf1(void)393 	static void jf1(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.f1)	{ R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jnc(void)394 	static void jnc(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (M_Cn)	{ R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jc(void)395 	static void jc(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (M_Cy)	{ R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jni(void)396 	static void jni(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.irq_state == I8039_EXTERNAL_INT) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jnt_0(void)397 	static void jnt_0(void)  	 { UINT8 i=M_RDMEM_OPCODE(); if (!test_r(0)) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jt_0(void)398 	static void jt_0(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (test_r(0))  { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jnt_1(void)399 	static void jnt_1(void)  	 { UINT8 i=M_RDMEM_OPCODE(); if (!test_r(1)) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jt_1(void)400 	static void jt_1(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (test_r(1))  { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jnz(void)401 	static void jnz(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A != 0)	 { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jz(void)402 	static void jz(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A == 0)	 { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); } else ADJUST_CYCLES }
jtf(void)403 	static void jtf(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.t_flag)	 { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; change_pc16(R.PC.w.l); R.t_flag = 0; } else ADJUST_CYCLES }
404 #else
jmp_1(void)405 	static void jmp_1(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x100 | R.A11; }
jmp_2(void)406 	static void jmp_2(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x200 | R.A11; }
jmp_3(void)407 	static void jmp_3(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x300 | R.A11; }
jmp_4(void)408 	static void jmp_4(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x400 | R.A11; }
jmp_5(void)409 	static void jmp_5(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x500 | R.A11; }
jmp_6(void)410 	static void jmp_6(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x600 | R.A11; }
jmp_7(void)411 	static void jmp_7(void)	 	 { UINT8 i=M_RDOP(R.PC.w.l); R.PC.w.l = i | 0x700 | R.A11; }
jmpp_xa(void)412 	static void jmpp_xa(void)	 { UINT16 addr = (R.PC.w.l & 0xf00) | R.A; R.PC.w.l = (R.PC.w.l & 0xf00) | M_RDMEM(addr); }
jb_0(void)413 	static void jb_0(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x01) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jb_1(void)414 	static void jb_1(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x02) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jb_2(void)415 	static void jb_2(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x04) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jb_3(void)416 	static void jb_3(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x08) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jb_4(void)417 	static void jb_4(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x10) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jb_5(void)418 	static void jb_5(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x20) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jb_6(void)419 	static void jb_6(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x40) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jb_7(void)420 	static void jb_7(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A & 0x80) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jf0(void)421 	static void jf0(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (M_F0y) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jf1(void)422 	static void jf1(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.f1)	{ R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jnc(void)423 	static void jnc(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (M_Cn)	{ R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jc(void)424 	static void jc(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (M_Cy)	{ R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jni(void)425 	static void jni(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.irq_state == I8039_EXTERNAL_INT) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jnt_0(void)426 	static void jnt_0(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (!test_r(0)) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jt_0(void)427 	static void jt_0(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (test_r(0))  { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jnt_1(void)428 	static void jnt_1(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (!test_r(1)) { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jt_1(void)429 	static void jt_1(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (test_r(1))  { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jnz(void)430 	static void jnz(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A != 0)	 { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jz(void)431 	static void jz(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.A == 0)	 { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; } else ADJUST_CYCLES }
jtf(void)432 	static void jtf(void)	 	 { UINT8 i=M_RDMEM_OPCODE(); if (R.t_flag)	 { R.PC.w.l = ((R.PC.w.l-1) & 0xf00) | i; R.t_flag = 0; } else ADJUST_CYCLES }
433 #endif
434 
mov_a_n(void)435 static void mov_a_n(void)	 { R.A = M_RDMEM_OPCODE(); }
mov_a_r0(void)436 static void mov_a_r0(void)	 { R.A = R0; }
mov_a_r1(void)437 static void mov_a_r1(void)	 { R.A = R1; }
mov_a_r2(void)438 static void mov_a_r2(void)	 { R.A = R2; }
mov_a_r3(void)439 static void mov_a_r3(void)	 { R.A = R3; }
mov_a_r4(void)440 static void mov_a_r4(void)	 { R.A = R4; }
mov_a_r5(void)441 static void mov_a_r5(void)	 { R.A = R5; }
mov_a_r6(void)442 static void mov_a_r6(void)	 { R.A = R6; }
mov_a_r7(void)443 static void mov_a_r7(void)	 { R.A = R7; }
mov_a_psw(void)444 static void mov_a_psw(void)	 { R.A = R.PSW; }
mov_a_xr0(void)445 static void mov_a_xr0(void)	 { R.A = intRAM[R0 & 0x7f]; }
mov_a_xr1(void)446 static void mov_a_xr1(void)	 { R.A = intRAM[R1 & 0x7f]; }
mov_r0_a(void)447 static void mov_r0_a(void)	 { R0 = R.A; }
mov_r1_a(void)448 static void mov_r1_a(void)	 { R1 = R.A; }
mov_r2_a(void)449 static void mov_r2_a(void)	 { R2 = R.A; }
mov_r3_a(void)450 static void mov_r3_a(void)	 { R3 = R.A; }
mov_r4_a(void)451 static void mov_r4_a(void)	 { R4 = R.A; }
mov_r5_a(void)452 static void mov_r5_a(void)	 { R5 = R.A; }
mov_r6_a(void)453 static void mov_r6_a(void)	 { R6 = R.A; }
mov_r7_a(void)454 static void mov_r7_a(void)	 { R7 = R.A; }
mov_psw_a(void)455 static void mov_psw_a(void)	 { R.PSW = R.A; regPTR = ((M_By) ? 24 : 0); R.SP = (R.PSW & 7) << 1; }
mov_r0_n(void)456 static void mov_r0_n(void)	 { R0 = M_RDMEM_OPCODE(); }
mov_r1_n(void)457 static void mov_r1_n(void)	 { R1 = M_RDMEM_OPCODE(); }
mov_r2_n(void)458 static void mov_r2_n(void)	 { R2 = M_RDMEM_OPCODE(); }
mov_r3_n(void)459 static void mov_r3_n(void)	 { R3 = M_RDMEM_OPCODE(); }
mov_r4_n(void)460 static void mov_r4_n(void)	 { R4 = M_RDMEM_OPCODE(); }
mov_r5_n(void)461 static void mov_r5_n(void)	 { R5 = M_RDMEM_OPCODE(); }
mov_r6_n(void)462 static void mov_r6_n(void)	 { R6 = M_RDMEM_OPCODE(); }
mov_r7_n(void)463 static void mov_r7_n(void)	 { R7 = M_RDMEM_OPCODE(); }
mov_a_t(void)464 static void mov_a_t(void)	 { R.A = R.timer; }
mov_t_a(void)465 static void mov_t_a(void)	 { R.timer = R.A; }
mov_xr0_a(void)466 static void mov_xr0_a(void)	 { intRAM[R0 & 0x7f] = R.A; }
mov_xr1_a(void)467 static void mov_xr1_a(void)	 { intRAM[R1 & 0x7f] = R.A; }
mov_xr0_n(void)468 static void mov_xr0_n(void)	 { intRAM[R0 & 0x7f] = M_RDMEM_OPCODE(); }
mov_xr1_n(void)469 static void mov_xr1_n(void)	 { intRAM[R1 & 0x7f] = M_RDMEM_OPCODE(); }
movd_a_p4(void)470 static void movd_a_p4(void)	 { R.A = port_r(4); }
movd_a_p5(void)471 static void movd_a_p5(void)	 { R.A = port_r(5); }
movd_a_p6(void)472 static void movd_a_p6(void)	 { R.A = port_r(6); }
movd_a_p7(void)473 static void movd_a_p7(void)	 { R.A = port_r(7); }
movd_p4_a(void)474 static void movd_p4_a(void)	 { port_w(4, R.A); }
movd_p5_a(void)475 static void movd_p5_a(void)	 { port_w(5, R.A); }
movd_p6_a(void)476 static void movd_p6_a(void)	 { port_w(6, R.A); }
movd_p7_a(void)477 static void movd_p7_a(void)	 { port_w(7, R.A); }
movp_a_xa(void)478 static void movp_a_xa(void)	 { R.A = M_RDMEM((R.PC.w.l & 0x0f00) | R.A); }
movp3_a_xa(void)479 static void movp3_a_xa(void) { R.A = M_RDMEM(0x300 | R.A); }
movx_a_xr0(void)480 static void movx_a_xr0(void) { R.A = M_IN(R0); }
movx_a_xr1(void)481 static void movx_a_xr1(void) { R.A = M_IN(R1); }
movx_xr0_a(void)482 static void movx_xr0_a(void) { M_OUT(R0, R.A); }
movx_xr1_a(void)483 static void movx_xr1_a(void) { M_OUT(R1, R.A); }
nop(void)484 static void nop(void) { }
orl_a_n(void)485 static void orl_a_n(void)	 { R.A |= M_RDMEM_OPCODE(); }
orl_a_r0(void)486 static void orl_a_r0(void)	 { R.A |= R0; }
orl_a_r1(void)487 static void orl_a_r1(void)	 { R.A |= R1; }
orl_a_r2(void)488 static void orl_a_r2(void)	 { R.A |= R2; }
orl_a_r3(void)489 static void orl_a_r3(void)	 { R.A |= R3; }
orl_a_r4(void)490 static void orl_a_r4(void)	 { R.A |= R4; }
orl_a_r5(void)491 static void orl_a_r5(void)	 { R.A |= R5; }
orl_a_r6(void)492 static void orl_a_r6(void)	 { R.A |= R6; }
orl_a_r7(void)493 static void orl_a_r7(void)	 { R.A |= R7; }
orl_a_xr0(void)494 static void orl_a_xr0(void)	 { R.A |= intRAM[R0 & 0x7f]; }
orl_a_xr1(void)495 static void orl_a_xr1(void)	 { R.A |= intRAM[R1 & 0x7f]; }
orl_bus_n(void)496 static void orl_bus_n(void)	 { bus_w( bus_r() | M_RDMEM_OPCODE() ); }
orl_p1_n(void)497 static void orl_p1_n(void)	 { R.P1 |= M_RDMEM_OPCODE(); port_w(1, R.P1); }
orl_p2_n(void)498 static void orl_p2_n(void)	 { R.P2 |= M_RDMEM_OPCODE(); port_w(2, R.P2); }
orld_p4_a(void)499 static void orld_p4_a(void)	 { port_w(4, port_r(4) | R.A ); }
orld_p5_a(void)500 static void orld_p5_a(void)	 { port_w(5, port_r(5) | R.A ); }
orld_p6_a(void)501 static void orld_p6_a(void)	 { port_w(6, port_r(6) | R.A ); }
orld_p7_a(void)502 static void orld_p7_a(void)	 { port_w(7, port_r(7) | R.A ); }
outl_bus_a(void)503 static void outl_bus_a(void) { bus_w(R.A); }
outl_p1_a(void)504 static void outl_p1_a(void)	 { port_w(1, R.A); R.P1 = R.A; }
outl_p2_a(void)505 static void outl_p2_a(void)	 { port_w(2, R.A); R.P2 = R.A; }
506 #ifdef MESS
ret(void)507 	static void ret(void)	 { R.PC.w.l = ((pull() & 0x0f) << 8); R.PC.w.l |= pull(); change_pc16(R.PC.w.l); }
508 #else
ret(void)509 	static void ret(void)	 { R.PC.w.l = ((pull() & 0x0f) << 8); R.PC.w.l |= pull(); }
510 #endif
511 
retr(void)512 static void retr(void)
513 {
514 	UINT8 i=pull();
515 	R.PC.w.l = ((i & 0x0f) << 8) | pull();
516 	#ifdef MESS
517 		change_pc16(R.PC.w.l);
518 	#endif
519 //	R.A11 = R.A11ff;	/* NS990113 */
520 	R.PSW = (R.PSW & 0x0f) | (i & 0xf0);	/* Stack is already changed by pull */
521 	regPTR = ((M_By) ? 24 : 0);
522 
523 	R.irq_executing = I8039_NO_INT;
524 
525 	/* Take an interrupt if a request is still being made */
526 	if (R.irq_state == I8039_EXTERNAL_INT) {
527 		R.irq_extra_cycles += Ext_IRQ();			/* Service External IRQ */
528 	}
529 	else if (R.pending_irq == I8039_TIMCNT_INT) {
530 		R.irq_extra_cycles += Timer_IRQ();			/* Service pending Timer/Counter IRQ */
531 	}
532 }
rl_a(void)533 static void rl_a(void)		 { UINT8 i=R.A & 0x80; R.A <<= 1; if (i) R.A |= 0x01; else R.A &= 0xfe; }
534 /* NS990113 */
rlc_a(void)535 static void rlc_a(void) 	 { UINT8 i=M_Cy; if (R.A & 0x80) SET(C_FLAG); else CLR(C_FLAG); R.A <<= 1; if (i) R.A |= 0x01; else R.A &= 0xfe; }
rr_a(void)536 static void rr_a(void)		 { UINT8 i=R.A & 1; R.A >>= 1; if (i) R.A |= 0x80; else R.A &= 0x7f; }
537 /* NS990113 */
rrc_a(void)538 static void rrc_a(void)		 { UINT8 i=M_Cy; if (R.A & 1) SET(C_FLAG); else CLR(C_FLAG); R.A >>= 1; if (i) R.A |= 0x80; else R.A &= 0x7f; }
sel_mb0(void)539 static void sel_mb0(void)	{ R.A11 = 0; R.A11ff = 0; }
sel_mb1(void)540 static void sel_mb1(void)	 { R.A11ff = 0x800; if (R.irq_executing == I8039_NO_INT) R.A11 = 0x800; }
sel_rb0(void)541 static void sel_rb0(void)	 { CLR(B_FLAG); regPTR = 0;  }
sel_rb1(void)542 static void sel_rb1(void)	 { SET(B_FLAG); regPTR = 24; }
stop_tcnt(void)543 static void stop_tcnt(void)	 { R.timerON = R.countON = 0; }
strt_cnt(void)544 static void strt_cnt(void)	 { R.countON = 1; R.timerON = 0; Old_T1 = test_r(1); }	/* NS990113 */
strt_t(void)545 static void strt_t(void)	 { R.timerON = 1; R.countON = 0; R.masterClock = 0; }	/* NS990113 */
swap_a(void)546 static void swap_a(void)	 { UINT8 i=R.A >> 4; R.A <<= 4; R.A |= i; }
xch_a_r0(void)547 static void xch_a_r0(void)	 { UINT8 i=R.A; R.A=R0; R0=i; }
xch_a_r1(void)548 static void xch_a_r1(void)	 { UINT8 i=R.A; R.A=R1; R1=i; }
xch_a_r2(void)549 static void xch_a_r2(void)	 { UINT8 i=R.A; R.A=R2; R2=i; }
xch_a_r3(void)550 static void xch_a_r3(void)	 { UINT8 i=R.A; R.A=R3; R3=i; }
xch_a_r4(void)551 static void xch_a_r4(void)	 { UINT8 i=R.A; R.A=R4; R4=i; }
xch_a_r5(void)552 static void xch_a_r5(void)	 { UINT8 i=R.A; R.A=R5; R5=i; }
xch_a_r6(void)553 static void xch_a_r6(void)	 { UINT8 i=R.A; R.A=R6; R6=i; }
xch_a_r7(void)554 static void xch_a_r7(void)	 { UINT8 i=R.A; R.A=R7; R7=i; }
xch_a_xr0(void)555 static void xch_a_xr0(void)	 { UINT8 i=R.A; R.A=intRAM[R0 & 0x7f]; intRAM[R0 & 0x7f]=i; }
xch_a_xr1(void)556 static void xch_a_xr1(void)	 { UINT8 i=R.A; R.A=intRAM[R1 & 0x7f]; intRAM[R1 & 0x7f]=i; }
xchd_a_xr0(void)557 static void xchd_a_xr0(void) { M_XCHD(R0 & 0x7f); }
xchd_a_xr1(void)558 static void xchd_a_xr1(void) { M_XCHD(R1 & 0x7f); }
xrl_a_n(void)559 static void xrl_a_n(void)	 { R.A ^= M_RDMEM_OPCODE(); }
xrl_a_r0(void)560 static void xrl_a_r0(void)	 { R.A ^= R0; }
xrl_a_r1(void)561 static void xrl_a_r1(void)	 { R.A ^= R1; }
xrl_a_r2(void)562 static void xrl_a_r2(void)	 { R.A ^= R2; }
xrl_a_r3(void)563 static void xrl_a_r3(void)	 { R.A ^= R3; }
xrl_a_r4(void)564 static void xrl_a_r4(void)	 { R.A ^= R4; }
xrl_a_r5(void)565 static void xrl_a_r5(void)	 { R.A ^= R5; }
xrl_a_r6(void)566 static void xrl_a_r6(void)	 { R.A ^= R6; }
xrl_a_r7(void)567 static void xrl_a_r7(void)	 { R.A ^= R7; }
xrl_a_xr0(void)568 static void xrl_a_xr0(void)	 { R.A ^= intRAM[R0 & 0x7f]; }
xrl_a_xr1(void)569 static void xrl_a_xr1(void)	 { R.A ^= intRAM[R1 & 0x7f]; }
570 
571 static s_opcode opcode_main[256]=
572 {
573 	{1, nop 	   },{0, illegal	},{2, outl_bus_a },{2, add_a_n	  },{2, jmp 	   },{1, en_i		},{0, illegal	 },{1, dec_a	  },
574 	{2, ins_a_bus  },{2, in_a_p1	},{2, in_a_p2	 },{0, illegal	  },{2, movd_a_p4  },{2, movd_a_p5	},{2, movd_a_p6  },{2, movd_a_p7  },
575 	{1, inc_xr0    },{1, inc_xr1	},{2, jb_0		 },{2, adc_a_n	  },{2, call	   },{1, dis_i		},{2, jtf		 },{1, inc_a	  },
576 	{1, inc_r0	   },{1, inc_r1 	},{1, inc_r2	 },{1, inc_r3	  },{1, inc_r4	   },{1, inc_r5 	},{1, inc_r6	 },{1, inc_r7	  },
577 	{1, xch_a_xr0  },{1, xch_a_xr1	},{0, illegal	 },{2, mov_a_n	  },{2, jmp_1	   },{1, en_tcnti	},{2, jnt_0 	 },{1, clr_a	  },
578 	{1, xch_a_r0   },{1, xch_a_r1	},{1, xch_a_r2	 },{1, xch_a_r3   },{1, xch_a_r4   },{1, xch_a_r5	},{1, xch_a_r6	 },{1, xch_a_r7   },
579 	{1, xchd_a_xr0 },{1, xchd_a_xr1 },{2, jb_1		 },{0, illegal	  },{2, call_1	   },{1, dis_tcnti	},{2, jt_0		 },{1, cpl_a	  },
580 	{0, illegal    },{2, outl_p1_a	},{2, outl_p2_a  },{0, illegal	  },{2, movd_p4_a  },{2, movd_p5_a	},{2, movd_p6_a  },{2, movd_p7_a  },
581 	{1, orl_a_xr0  },{1, orl_a_xr1	},{1, mov_a_t	 },{2, orl_a_n	  },{2, jmp_2	   },{1, strt_cnt	},{2, jnt_1 	 },{1, swap_a	  },
582 	{1, orl_a_r0   },{1, orl_a_r1	},{1, orl_a_r2	 },{1, orl_a_r3   },{1, orl_a_r4   },{1, orl_a_r5	},{1, orl_a_r6	 },{1, orl_a_r7   },
583 	{1, anl_a_xr0  },{1, anl_a_xr1	},{2, jb_2		 },{2, anl_a_n	  },{2, call_2	   },{1, strt_t 	},{2, jt_1		 },{1, daa_a	  },
584 	{1, anl_a_r0   },{1, anl_a_r1	},{1, anl_a_r2	 },{1, anl_a_r3   },{1, anl_a_r4   },{1, anl_a_r5	},{1, anl_a_r6	 },{1, anl_a_r7   },
585 	{1, add_a_xr0  },{1, add_a_xr1	},{1, mov_t_a	 },{0, illegal	  },{2, jmp_3	   },{1, stop_tcnt	},{0, illegal	 },{1, rrc_a	  },
586 	{1, add_a_r0   },{1, add_a_r1	},{1, add_a_r2	 },{1, add_a_r3   },{1, add_a_r4   },{1, add_a_r5	},{1, add_a_r6	 },{1, add_a_r7   },
587 	{1, adc_a_xr0  },{1, adc_a_xr1	},{2, jb_3		 },{0, illegal	  },{2, call_3	   },{1, ento_clk	},{2, jf1		 },{1, rr_a 	  },
588 	{1, adc_a_r0   },{1, adc_a_r1	},{1, adc_a_r2	 },{1, adc_a_r3   },{1, adc_a_r4   },{1, adc_a_r5	},{1, adc_a_r6	 },{1, adc_a_r7   },
589 	{2, movx_a_xr0 },{2, movx_a_xr1 },{0, illegal	 },{2, ret		  },{2, jmp_4	   },{1, clr_f0 	},{2, jni		 },{0, illegal	  },
590 	{2, orl_bus_n  },{2, orl_p1_n	},{2, orl_p2_n	 },{0, illegal	  },{2, orld_p4_a  },{2, orld_p5_a	},{2, orld_p6_a  },{2, orld_p7_a  },
591 	{2, movx_xr0_a },{2, movx_xr1_a },{2, jb_4		 },{2, retr 	  },{2, call_4	   },{1, cpl_f0 	},{2, jnz		 },{1, clr_c	  },
592 	{2, anl_bus_n  },{2, anl_p1_n	},{2, anl_p2_n	 },{0, illegal	  },{2, anld_p4_a  },{2, anld_p5_a	},{2, anld_p6_a  },{2, anld_p7_a  },
593 	{1, mov_xr0_a  },{1, mov_xr1_a	},{0, illegal	 },{2, movp_a_xa  },{2, jmp_5	   },{1, clr_f1 	},{0, illegal	 },{1, cpl_c	  },
594 	{1, mov_r0_a   },{1, mov_r1_a	},{1, mov_r2_a	 },{1, mov_r3_a   },{1, mov_r4_a   },{1, mov_r5_a	},{1, mov_r6_a	 },{1, mov_r7_a   },
595 	{2, mov_xr0_n  },{2, mov_xr1_n	},{2, jb_5		 },{2, jmpp_xa	  },{2, call_5	   },{1, cpl_f1 	},{2, jf0		 },{0, illegal	  },
596 	{2, mov_r0_n   },{2, mov_r1_n	},{2, mov_r2_n	 },{2, mov_r3_n   },{2, mov_r4_n   },{2, mov_r5_n	},{2, mov_r6_n	 },{2, mov_r7_n   },
597 	{0, illegal    },{0, illegal	},{0, illegal	 },{0, illegal	  },{2, jmp_6	   },{1, sel_rb0	},{2, jz		 },{1, mov_a_psw  },
598 	{1, dec_r0	   },{1, dec_r1 	},{1, dec_r2	 },{1, dec_r3	  },{1, dec_r4	   },{1, dec_r5 	},{1, dec_r6	 },{1, dec_r7	  },
599 	{1, xrl_a_xr0  },{1, xrl_a_xr1	},{2, jb_6		 },{2, xrl_a_n	  },{2, call_6	   },{1, sel_rb1	},{0, illegal	 },{1, mov_psw_a  },
600 	{1, xrl_a_r0   },{1, xrl_a_r1	},{1, xrl_a_r2	 },{1, xrl_a_r3   },{1, xrl_a_r4   },{1, xrl_a_r5	},{1, xrl_a_r6	 },{1, xrl_a_r7   },
601 	{0, illegal    },{0, illegal	},{0, illegal	 },{2, movp3_a_xa },{2, jmp_7	   },{1, sel_mb0	},{2, jnc		 },{1, rl_a 	  },
602 	{2, djnz_r0    },{2, djnz_r1	},{2, djnz_r2	 },{2, djnz_r3	  },{2, djnz_r4    },{2, djnz_r5	},{2, djnz_r6	 },{2, djnz_r7	  },
603 	{1, mov_a_xr0  },{1, mov_a_xr1	},{2, jb_7		 },{0, illegal	  },{2, call_7	   },{1, sel_mb1	},{2, jc		 },{1, rlc_a	  },
604 	{1, mov_a_r0   },{1, mov_a_r1	},{1, mov_a_r2	 },{1, mov_a_r3   },{1, mov_a_r4   },{1, mov_a_r5	},{1, mov_a_r6	 },{1, mov_a_r7   }
605 };
606 
607 
608 
609 
610 /****************************************************************************
611  * Initialize emulation
612  ****************************************************************************/
i8039_init(void)613 void i8039_init (void)
614 {
615 	int cpu = cpu_getactivecpu();
616 
617 	state_save_register_UINT16("i8039", cpu, "PC", &R.PC.w.l, 1);
618 	state_save_register_UINT16("i8039", cpu, "PREVPC", &R.PREVPC.w.l, 1);
619 	state_save_register_UINT8("i8039", cpu, "A", &R.A, 1);
620 	state_save_register_UINT8("i8039", cpu, "SP", &R.SP, 1);
621 	state_save_register_UINT8("i8039", cpu, "PSW", &R.PSW, 1);
622 	state_save_register_UINT8("i8039", cpu, "RAM", intRAM, 128);
623 	state_save_register_UINT8("i8039", cpu, "Bus", &R.bus, 1);
624 	state_save_register_UINT8("i8039", cpu, "F1", &R.f1, 1);
625 	state_save_register_UINT8("i8039", cpu, "P1", &R.P1, 1);
626 	state_save_register_UINT8("i8039", cpu, "P2", &R.P2, 1);
627 	state_save_register_UINT8("i8039", cpu, "Pending IRQ", &R.pending_irq, 1);
628 	state_save_register_UINT8("i8039", cpu, "Executing IRQ", &R.irq_executing, 1);
629 	state_save_register_UINT8("i8039", cpu, "Master Clock", &R.masterClock, 1);
630 	state_save_register_UINT8("i8039", cpu, "Register Pointer", &R.regPtr, 1);
631 	state_save_register_UINT8("i8039", cpu, "T flag", &R.t_flag, 1);
632 	state_save_register_UINT8("i8039", cpu, "Timer", &R.timer, 1);
633 	state_save_register_UINT8("i8039", cpu, "Timer ON", &R.timerON, 1);
634 	state_save_register_UINT8("i8039", cpu, "Clock ON", &R.countON, 1);
635 	state_save_register_UINT8("i8039", cpu, "External IRQ Enable", &R.xirq_en, 1);
636 	state_save_register_UINT8("i8039", cpu, "Timer/Counter IRQ Enable", &R.tirq_en, 1);
637 	state_save_register_UINT16("i8039", cpu, "A11", &R.A11, 1);
638 	state_save_register_UINT16("i8039", cpu, "A11 FF", &R.A11ff, 1);
639 	state_save_register_UINT8("i8039", cpu, "IRQ State", &R.irq_state, 1);
640 	state_save_register_UINT8("i8039", cpu, "IRQ extra cycles", &R.irq_extra_cycles, 1);
641 }
642 
643 /****************************************************************************
644  * Reset registers to their initial values
645  ****************************************************************************/
i8039_reset(void * param)646 void i8039_reset (void *param)
647 {
648 	R.PC.w.l = 0;
649 	R.SP  = 0;
650 	R.A   = 0;
651 	R.PSW = 0x08;		/* Start with Carry SET, Bit 4 is always SET */
652 	memset(R.RAM, 0x0, 128);
653 	R.P1  = 0xff;
654 	R.P2  = 0xff;
655 	R.bus = 0;
656 	R.irq_executing = I8039_NO_INT;
657 	R.pending_irq	= I8039_NO_INT;
658 
659 	R.A11ff   = R.A11     = 0;
660 	R.tirq_en = R.xirq_en = 0;
661 	R.timerON = R.countON = 0;
662 	R.timerON = 1;  /* Mario Bros. doesn't work without this */
663 	R.irq_extra_cycles = 0;
664 	R.masterClock = 0;
665 }
666 
667 
668 /****************************************************************************
669  * Shut down CPU emulation
670  ****************************************************************************/
i8039_exit(void)671 void i8039_exit (void)
672 {
673 	/* nothing to do ? */
674 }
675 
676 /****************************************************************************
677  * Issue an interrupt if necessary
678  ****************************************************************************/
Ext_IRQ(void)679 static int Ext_IRQ(void)
680 {
681 	int extra_cycles = 0;
682 
683 	if (R.xirq_en) {
684 		if (R.irq_executing == I8039_NO_INT) {
685 //			logerror("I8039:  EXT INTERRUPT being serviced\n");
686 			R.irq_executing = I8039_EXTERNAL_INT;
687 			push(R.PC.b.l);
688 			push((R.PC.b.h & 0x0f) | (R.PSW & 0xf0));
689 			R.PC.w.l = 0x03;
690 			R.A11ff = R.A11;
691 			R.A11   = 0;
692 
693 			extra_cycles = 2;		/* 2 clock cycles used */
694 
695 			if (R.timerON)	/* NS990113 */
696 				R.masterClock += extra_cycles;
697 			if (R.irq_callback) (*R.irq_callback)(0);
698 		}
699 	}
700 
701 	return extra_cycles;
702 }
703 
Timer_IRQ(void)704 static int Timer_IRQ(void)
705 {
706 	int extra_cycles = 0;
707 
708 	if (R.tirq_en) {
709 		if (R.irq_executing == I8039_NO_INT) {
710 //			logerror("I8039:  TIMER/COUNTER INTERRUPT\n");
711 			R.irq_executing = I8039_TIMCNT_INT;
712 			R.pending_irq &= ~I8039_TIMCNT_INT;
713 			push(R.PC.b.l);
714 			push((R.PC.b.h & 0x0f) | (R.PSW & 0xf0));
715 			R.PC.w.l = 0x07;
716 			#ifdef MESS
717 				change_pc16(0x07);
718 			#endif
719 			R.A11ff = R.A11;
720 			R.A11	= 0;
721 
722 			extra_cycles = 2;		/* 2 clock cycles used */
723 
724 			if (R.timerON)	/* NS990113 */
725 				R.masterClock += extra_cycles;
726 		}
727 		else {
728 			if (R.irq_executing == I8039_EXTERNAL_INT) {
729 				R.pending_irq |= I8039_TIMCNT_INT;
730 			}
731 		}
732 	}
733 
734 	R.t_flag = 1;
735 
736 	return extra_cycles;
737 }
738 
739 
740 /****************************************************************************
741  * Execute cycles CPU cycles. Return number of cycles really executed
742  ****************************************************************************/
i8039_execute(int cycles)743 int i8039_execute(int cycles)
744 {
745 	unsigned opcode, T1;
746 	int count;
747 
748 	i8039_ICount = (cycles - R.irq_extra_cycles);
749 	R.irq_extra_cycles = 0;
750 
751 	do
752 	{
753 		R.PREVPC = R.PC;
754 
755 		CALL_MAME_DEBUG;
756 
757 		opcode=M_RDOP(R.PC.w.l);
758 
759 /*		logerror("I8039:  PC = %04x,  opcode = %02x\n", R.PC.w.l, opcode); */
760 
761 		R.PC.w.l++;
762 		inst_cycles = opcode_main[opcode].cycles;
763 		(*(opcode_main[opcode].function))();
764 		i8039_ICount -= inst_cycles; ///
765 
766 		if (R.countON)	/* NS990113 */
767 		{
768 			for ( ; inst_cycles > 0; inst_cycles-- )
769 			{
770 				T1 = test_r(1);
771 				if (POSITIVE_EDGE_T1)
772 				{
773 					R.timer++;
774 					if (R.timer == 0) {
775 						count = Timer_IRQ();	/* Handle Counter IRQ */
776 						i8039_ICount -= count;
777 					}
778 				}
779 				Old_T1 = T1;
780 			}
781 		}
782 
783 		if (R.timerON) {
784 			R.masterClock += opcode_main[opcode].cycles;
785 			if (R.masterClock >= 32) {	/* NS990113 */
786 				R.masterClock -= 32;
787 				R.timer++;
788 				if (R.timer == 0) {
789 					count = Timer_IRQ();	/* Handle Timer IRQ */
790 					i8039_ICount -= count;
791 				}
792 			}
793 		}
794 	} while (i8039_ICount>0);
795 
796 	i8039_ICount -= R.irq_extra_cycles;
797 	R.irq_extra_cycles = 0;
798 
799 	return cycles - i8039_ICount;
800 }
801 
802 /****************************************************************************
803  * Get all registers in given buffer
804  ****************************************************************************/
i8039_get_context(void * dst)805 unsigned i8039_get_context (void *dst)
806 {
807 	if( dst )
808 		*(I8039_Regs*)dst = R;
809 	return sizeof(I8039_Regs);
810 }
811 
812 
813 /****************************************************************************
814  * Set all registers to given values
815  ****************************************************************************/
i8039_set_context(void * src)816 void i8039_set_context (void *src)
817 {
818 	if( src )
819 	{
820 		R = *(I8039_Regs*)src;
821 		regPTR = ((M_By) ? 24 : 0);
822 		R.SP = (R.PSW << 1) & 0x0f;
823 		#ifdef MESS
824 			change_pc16(R.PC.w.l);
825 		#endif
826 	}
827 	/* Handle forced Interrupts throught the Debugger */
828 	if (R.irq_state != I8039_NO_INT) {
829 		R.irq_extra_cycles += Ext_IRQ();		/* Handle External IRQ */
830 	}
831 	if (R.timer == 0) {
832 		R.irq_extra_cycles += Timer_IRQ();		/* Handle Timer IRQ */
833 	}
834 }
835 
836 
837 /****************************************************************************
838  * Get a specific register
839  ****************************************************************************/
i8039_get_reg(int regnum)840 unsigned i8039_get_reg (int regnum)
841 {
842 	switch( regnum )
843 	{
844 		case REG_PC:
845 		case I8039_PC: return R.PC.w.l;
846 		case REG_SP:
847 		case I8039_SP: return R.SP;
848 		case I8039_PSW: return R.PSW;
849 		case I8039_A: return R.A;
850 		case I8039_IRQ_STATE: return R.irq_state;
851 		case I8039_TC: return R.timer;
852 		case I8039_P1: return R.P1;
853 		case I8039_P2: return R.P2;
854 		case I8039_R0: return R0;
855 		case I8039_R1: return R1;
856 		case I8039_R2: return R2;
857 		case I8039_R3: return R3;
858 		case I8039_R4: return R4;
859 		case I8039_R5: return R5;
860 		case I8039_R6: return R6;
861 		case I8039_R7: return R7;
862 		case REG_PREVIOUSPC: return R.PREVPC.w.l;
863 		default:
864 			if( regnum <= REG_SP_CONTENTS )
865 			{
866 				unsigned offset = 8 + 2 * ((R.SP + REG_SP_CONTENTS - regnum) & 7);
867 				return R.RAM[offset] + 256 * R.RAM[offset+1];
868 			}
869 	}
870 	return 0;
871 }
872 
873 
874 /****************************************************************************
875  * Set a specific register
876  ****************************************************************************/
i8039_set_reg(int regnum,unsigned val)877 void i8039_set_reg (int regnum, unsigned val)
878 {
879 	switch( regnum )
880 	{
881 		case REG_PC:
882 		case I8039_PC: R.PC.w.l = val; break;
883 		case REG_SP:
884 		case I8039_SP: R.SP = val; break;
885 		case I8039_PSW: R.PSW = val; break;
886 		case I8039_A: R.A = val; break;
887 		case I8039_IRQ_STATE: i8039_set_irq_line( 0, val ); break;
888 		case I8039_TC: R.timer = val; break;
889 		case I8039_P1: R.P1 = val; break;
890 		case I8039_P2: R.P2 = val; break;
891 		case I8039_R0: R0 = val; break;
892 		case I8039_R1: R1 = val; break;
893 		case I8039_R2: R2 = val; break;
894 		case I8039_R3: R3 = val; break;
895 		case I8039_R4: R4 = val; break;
896 		case I8039_R5: R5 = val; break;
897 		case I8039_R6: R6 = val; break;
898 		case I8039_R7: R7 = val; break;
899 		default:
900 			if( regnum <= REG_SP_CONTENTS )
901 			{
902 				unsigned offset = 8 + 2 * ((R.SP + REG_SP_CONTENTS - regnum) & 7);
903 				R.RAM[offset] = val & 0xff;
904 				R.RAM[offset+1] = val >> 8;
905 			}
906 	}
907 }
908 
909 
910 /****************************************************************************
911  * Set IRQ line state
912  ****************************************************************************/
i8039_set_irq_line(int irqline,int state)913 void i8039_set_irq_line(int irqline, int state)
914 {
915 	if (state != CLEAR_LINE) {
916 		R.irq_state = I8039_EXTERNAL_INT;
917 		R.irq_extra_cycles += Ext_IRQ();		/* Handle External IRQ */
918 	}
919 	else {
920 		R.irq_state = I8039_NO_INT;
921 	}
922 }
923 
924 /****************************************************************************
925  * Set IRQ callback (interrupt acknowledge)
926  ****************************************************************************/
i8039_set_irq_callback(int (* callback)(int irqline))927 void i8039_set_irq_callback(int (*callback)(int irqline))
928 {
929 	R.irq_callback = callback;
930 }
931 
932 /****************************************************************************
933  * Return a formatted string for a register
934  ****************************************************************************/
i8039_info(void * context,int regnum)935 const char *i8039_info(void *context, int regnum)
936 {
937 	static char buffer[8][47+1];
938 	static int which = 0;
939 	I8039_Regs *r = context;
940 
941 	which = (which+1) % 8;
942 	buffer[which][0] = '\0';
943 	if( !context )
944 		r = &R;
945 
946 	switch( regnum )
947 	{
948 		case CPU_INFO_REG+I8039_PC: sprintf(buffer[which], "PC:%04X", r->PC.w.l); break;
949 		case CPU_INFO_REG+I8039_SP: sprintf(buffer[which], "SP:%02X", r->SP); break;
950 		case CPU_INFO_REG+I8039_PSW: sprintf(buffer[which], "PSW:%02X", r->PSW); break;
951 		case CPU_INFO_REG+I8039_A: sprintf(buffer[which], "A:%02X", r->A); break;
952 		case CPU_INFO_REG+I8039_IRQ_STATE: sprintf(buffer[which], "IRQ:%X", r->irq_state); break;
953 		case CPU_INFO_REG+I8039_TC: sprintf(buffer[which], "TC:%02X", r->timer); break;
954 		case CPU_INFO_REG+I8039_P1: sprintf(buffer[which], "P1:%02X", r->P1); break;
955 		case CPU_INFO_REG+I8039_P2: sprintf(buffer[which], "P2:%02X", r->P2); break;
956 		case CPU_INFO_REG+I8039_R0: sprintf(buffer[which], "R0:%02X", r->RAM[r->regPtr+0]); break;
957 		case CPU_INFO_REG+I8039_R1: sprintf(buffer[which], "R1:%02X", r->RAM[r->regPtr+1]); break;
958 		case CPU_INFO_REG+I8039_R2: sprintf(buffer[which], "R2:%02X", r->RAM[r->regPtr+2]); break;
959 		case CPU_INFO_REG+I8039_R3: sprintf(buffer[which], "R3:%02X", r->RAM[r->regPtr+3]); break;
960 		case CPU_INFO_REG+I8039_R4: sprintf(buffer[which], "R4:%02X", r->RAM[r->regPtr+4]); break;
961 		case CPU_INFO_REG+I8039_R5: sprintf(buffer[which], "R5:%02X", r->RAM[r->regPtr+5]); break;
962 		case CPU_INFO_REG+I8039_R6: sprintf(buffer[which], "R6:%02X", r->RAM[r->regPtr+6]); break;
963 		case CPU_INFO_REG+I8039_R7: sprintf(buffer[which], "R7:%02X", r->RAM[r->regPtr+7]); break;
964 		case CPU_INFO_FLAGS:
965 			sprintf(buffer[which], "%c%c%c%c%c%c%c%c",
966 				r->PSW & 0x80 ? 'C':'.',
967 				r->PSW & 0x40 ? 'A':'.',
968 				r->PSW & 0x20 ? 'F':'.',
969 				r->PSW & 0x10 ? 'B':'.',
970 				r->PSW & 0x08 ? '?':'.',
971 				r->PSW & 0x04 ? '4':'.',
972 				r->PSW & 0x02 ? '2':'.',
973 				r->PSW & 0x01 ? '1':'.');
974 			break;
975 		case CPU_INFO_NAME: return "I8039";
976 		case CPU_INFO_FAMILY: return "Intel 8039";
977 		case CPU_INFO_VERSION: return "1.2";
978 		case CPU_INFO_FILE: return __FILE__;
979 		case CPU_INFO_CREDITS: return "Copyright (C) 1997 by Mirko Buffoni\nBased on the original work (C) 1997 by Dan Boris";
980 		case CPU_INFO_REG_LAYOUT: return (const char*)i8039_reg_layout;
981 		case CPU_INFO_WIN_LAYOUT: return (const char*)i8039_win_layout;
982 	}
983 	return buffer[which];
984 }
985 
i8039_dasm(char * buffer,unsigned pc)986 unsigned i8039_dasm(char *buffer, unsigned pc)
987 {
988 #ifdef	MAME_DEBUG
989 	return Dasm8039(buffer,pc);
990 #else
991 	sprintf( buffer, "$%02X", cpu_readop(pc) );
992 	return 1;
993 #endif
994 }
995 
996 /**************************************************************************
997  * I8035 section
998  **************************************************************************/
999 #if (HAS_I8035)
1000 /* Layout of the registers in the debugger */
1001 static UINT8 i8035_reg_layout[] = {
1002 	I8035_PC, I8035_SP, I8035_PSW, I8035_A, I8035_IRQ_STATE,    I8035_TC, I8035_P1, I8035_P2, -1,
1003 	I8035_R0, I8035_R1, I8035_R2, I8035_R3, I8035_R4, I8035_R5, I8035_R6, I8035_R7, 0
1004 };
1005 
1006 /* Layout of the debugger windows x,y,w,h */
1007 static UINT8 i8035_win_layout[] = {
1008 	 0, 0,80, 2,	/* register window (top rows) */
1009 	 0, 3,24,19,	/* disassembler window (left colums) */
1010 	25, 3,55, 9,	/* memory #1 window (right, upper middle) */
1011 	25,13,55, 9,	/* memory #2 window (right, lower middle) */
1012 	 0,23,80, 1,	/* command line window (bottom rows) */
1013 };
1014 
i8035_init(void)1015 void i8035_init(void) { }
i8035_reset(void * param)1016 void i8035_reset(void *param) { i8039_reset(param); }
i8035_exit(void)1017 void i8035_exit(void) { i8039_exit(); }
i8035_execute(int cycles)1018 int i8035_execute(int cycles) { return i8039_execute(cycles); }
i8035_get_context(void * dst)1019 unsigned i8035_get_context(void *dst) { return i8039_get_context(dst); }
i8035_set_context(void * src)1020 void i8035_set_context(void *src)  { i8039_set_context(src); }
i8035_get_reg(int regnum)1021 unsigned i8035_get_reg(int regnum) { return i8039_get_reg(regnum); }
i8035_set_reg(int regnum,unsigned val)1022 void i8035_set_reg(int regnum, unsigned val) { i8039_set_reg(regnum,val); }
i8035_set_irq_line(int irqline,int state)1023 void i8035_set_irq_line(int irqline, int state) { i8039_set_irq_line(irqline,state); }
i8035_set_irq_callback(int (* callback)(int irqline))1024 void i8035_set_irq_callback(int (*callback)(int irqline)) { i8039_set_irq_callback(callback); }
i8035_info(void * context,int regnum)1025 const char *i8035_info(void *context, int regnum)
1026 {
1027 	switch( regnum )
1028 	{
1029 		case CPU_INFO_NAME: return "I8035";
1030 		case CPU_INFO_VERSION: return "1.2";
1031 		case CPU_INFO_REG_LAYOUT: return (const char*)i8035_reg_layout;
1032 		case CPU_INFO_WIN_LAYOUT: return (const char*)i8035_win_layout;
1033 	}
1034 	return i8039_info(context,regnum);
1035 }
1036 
i8035_dasm(char * buffer,unsigned pc)1037 unsigned i8035_dasm(char *buffer, unsigned pc)
1038 {
1039 #ifdef MAME_DEBUG
1040 	return Dasm8039(buffer,pc);
1041 #else
1042 	sprintf( buffer, "$%02X", cpu_readop(pc) );
1043 	return 1;
1044 #endif
1045 }
1046 
1047 #endif
1048 
1049 /**************************************************************************
1050  * I8048 section
1051  **************************************************************************/
1052 #if (HAS_I8048)
1053 /* Layout of the registers in the debugger */
1054 static UINT8 i8048_reg_layout[] = {
1055 	I8048_PC, I8048_SP, I8048_PSW, I8048_A, I8048_IRQ_STATE,    I8048_TC, I8048_P1, I8048_P2, -1,
1056 	I8048_R0, I8048_R1, I8048_R2, I8048_R3, I8048_R4, I8048_R5, I8048_R6, I8048_R7, 0
1057 };
1058 
1059 /* Layout of the debugger windows x,y,w,h */
1060 static UINT8 i8048_win_layout[] = {
1061 	 0, 0,80, 2,	/* register window (top rows) */
1062 	 0, 3,24,19,	/* disassembler window (left colums) */
1063 	25, 3,55, 9,	/* memory #1 window (right, upper middle) */
1064 	25,13,55, 9,	/* memory #2 window (right, lower middle) */
1065 	 0,23,80, 1,	/* command line window (bottom rows) */
1066 };
1067 
i8048_init(void)1068 void i8048_init(void) { }
i8048_reset(void * param)1069 void i8048_reset(void *param) { i8039_reset(param); }
i8048_exit(void)1070 void i8048_exit(void) { i8039_exit(); }
i8048_execute(int cycles)1071 int i8048_execute(int cycles) { return i8039_execute(cycles); }
i8048_get_context(void * dst)1072 unsigned i8048_get_context(void *dst) { return i8039_get_context(dst); }
i8048_set_context(void * src)1073 void i8048_set_context(void *src)  { i8039_set_context(src); }
i8048_get_reg(int regnum)1074 unsigned i8048_get_reg(int regnum) { return i8039_get_reg(regnum); }
i8048_set_reg(int regnum,unsigned val)1075 void i8048_set_reg(int regnum, unsigned val) { i8039_set_reg(regnum,val); }
i8048_set_irq_line(int irqline,int state)1076 void i8048_set_irq_line(int irqline, int state) { i8039_set_irq_line(irqline,state); }
i8048_set_irq_callback(int (* callback)(int irqline))1077 void i8048_set_irq_callback(int (*callback)(int irqline)) { i8039_set_irq_callback(callback); }
i8048_info(void * context,int regnum)1078 const char *i8048_info(void *context, int regnum)
1079 {
1080 	switch( regnum )
1081 	{
1082 		case CPU_INFO_NAME: return "I8048";
1083 		case CPU_INFO_VERSION: return "1.2";
1084 		case CPU_INFO_REG_LAYOUT: return (const char*)i8048_reg_layout;
1085 		case CPU_INFO_WIN_LAYOUT: return (const char*)i8048_win_layout;
1086 	}
1087 	return i8039_info(context,regnum);
1088 }
1089 
i8048_dasm(char * buffer,unsigned pc)1090 unsigned i8048_dasm(char *buffer, unsigned pc)
1091 {
1092 #ifdef MAME_DEBUG
1093 	return Dasm8039(buffer,pc);
1094 #else
1095 	sprintf( buffer, "$%02X", cpu_readop(pc) );
1096 	return 1;
1097 #endif
1098 }
1099 #endif
1100 /**************************************************************************
1101  * N7751 section
1102  **************************************************************************/
1103 #if (HAS_N7751)
1104 /* Layout of the registers in the debugger */
1105 static UINT8 n7751_reg_layout[] = {
1106 	N7751_PC, N7751_SP, N7751_PSW, N7751_A, N7751_IRQ_STATE,    N7751_TC, N7751_P1, N7751_P2, -1,
1107 	N7751_R0, N7751_R1, N7751_R2, N7751_R3, N7751_R4, N7751_R5, N7751_R6, N7751_R7, 0
1108 };
1109 
1110 /* Layout of the debugger windows x,y,w,h */
1111 static UINT8 n7751_win_layout[] = {
1112 	 0, 0,80, 2,	/* register window (top rows) */
1113 	 0, 3,24,19,	/* disassembler window (left colums) */
1114 	25, 3,55, 9,	/* memory #1 window (right, upper middle) */
1115 	25,13,55, 9,	/* memory #2 window (right, lower middle) */
1116 	 0,23,80, 1,	/* command line window (bottom rows) */
1117 };
1118 
n7751_init(void)1119 void n7751_init(void) { }
n7751_reset(void * param)1120 void n7751_reset(void *param) { i8039_reset(param); }
n7751_exit(void)1121 void n7751_exit(void) { i8039_exit(); }
n7751_execute(int cycles)1122 int n7751_execute(int cycles) { return i8039_execute(cycles); }
n7751_get_context(void * dst)1123 unsigned n7751_get_context(void *dst) { return i8039_get_context(dst); }
n7751_set_context(void * src)1124 void n7751_set_context(void *src)  { i8039_set_context(src); }
n7751_get_reg(int regnum)1125 unsigned n7751_get_reg(int regnum) { return i8039_get_reg(regnum); }
n7751_set_reg(int regnum,unsigned val)1126 void n7751_set_reg(int regnum, unsigned val) { i8039_set_reg(regnum,val); }
n7751_set_irq_line(int irqline,int state)1127 void n7751_set_irq_line(int irqline, int state) { i8039_set_irq_line(irqline,state); }
n7751_set_irq_callback(int (* callback)(int irqline))1128 void n7751_set_irq_callback(int (*callback)(int irqline)) { i8039_set_irq_callback(callback); }
n7751_info(void * context,int regnum)1129 const char *n7751_info(void *context, int regnum)
1130 {
1131 	switch( regnum )
1132 	{
1133 		case CPU_INFO_NAME: return "N7751";
1134 		case CPU_INFO_VERSION: return "1.2";
1135 		case CPU_INFO_REG_LAYOUT: return (const char*)n7751_reg_layout;
1136 		case CPU_INFO_WIN_LAYOUT: return (const char*)n7751_win_layout;
1137 	}
1138 	return i8039_info(context,regnum);
1139 }
1140 
n7751_dasm(char * buffer,unsigned pc)1141 unsigned n7751_dasm(char *buffer, unsigned pc)
1142 {
1143 #ifdef	MAME_DEBUG
1144 	return Dasm8039(buffer,pc);
1145 #else
1146 	sprintf( buffer, "$%02X", cpu_readop(pc) );
1147 	return 1;
1148 #endif
1149 }
1150 #endif
1151 
1152