1 /*****************************************************************************
2 
3 	h6280ops.h - Addressing modes and opcode macros for the Hu6820 cpu
4 
5 	Copyright (c) 1999 Bryan McPhail, mish@tendril.co.uk
6 
7 	This source code is based (with permission!) on the 6502 emulator by
8 	Juergen Buchmueller.  It is released as part of the Mame emulator project.
9 	Let me know if you intend to use this code in any other project.
10 
11 ******************************************************************************/
12 
13 /* 6280 flags */
14 #define _fC 0x01
15 #define _fZ 0x02
16 #define _fI 0x04
17 #define _fD 0x08
18 #define _fB 0x10
19 #define _fT 0x20
20 #define _fV 0x40
21 #define _fN 0x80
22 
23 /* some shortcuts for improved readability */
24 #define A	h6280.a
25 #define X	h6280.x
26 #define Y	h6280.y
27 #define P	h6280.p
28 #define S	h6280.sp.b.l
29 
30 #if LAZY_FLAGS
31 
32 #define NZ	h6280.NZ
33 #define SET_NZ(n)				\
34 	P &= ~_fT;					\
35     NZ = ((n & _fN) << 8) | n
36 
37 #else
38 
39 #define SET_NZ(n)				\
40 	P = (P & ~(_fN|_fT|_fZ)) |	\
41 		(n & _fN) | 			\
42 		((n == 0) ? _fZ : 0)
43 
44 #endif
45 
46 #define EAL h6280.ea.b.l
47 #define EAH h6280.ea.b.h
48 #define EAW h6280.ea.w.l
49 #define EAD h6280.ea.d
50 
51 #define ZPL h6280.zp.b.l
52 #define ZPH h6280.zp.b.h
53 #define ZPW h6280.zp.w.l
54 #define ZPD h6280.zp.d
55 
56 #define PCL h6280.pc.b.l
57 #define PCH h6280.pc.b.h
58 #define PCW h6280.pc.w.l
59 #define PCD h6280.pc.d
60 
61 #define DO_INTERRUPT(vector)									\
62 {																\
63 	h6280.extra_cycles += 7;	/* 7 cycles for an int */		\
64 	PUSH(PCH);													\
65 	PUSH(PCL);													\
66 	COMPOSE_P(0,_fB);											\
67 	PUSH(P);													\
68 	P = (P & ~_fD) | _fI;	/* knock out D and set I flag */	\
69 	PCL = RDMEM(vector);										\
70 	PCH = RDMEM((vector+1));									\
71 }
72 
73 #define CHECK_IRQ_LINES 										\
74 	if( !(P & _fI) )											\
75 	{															\
76 		if ( h6280.irq_state[0] != CLEAR_LINE &&				\
77 			 !(h6280.irq_mask & 0x2) )							\
78 		{														\
79 			DO_INTERRUPT(H6280_IRQ1_VEC);						\
80 			(*h6280.irq_callback)(0);							\
81 		}														\
82 		else													\
83 		if ( h6280.irq_state[1] != CLEAR_LINE &&				\
84 			 !(h6280.irq_mask & 0x1) )							\
85 		{														\
86 			DO_INTERRUPT(H6280_IRQ2_VEC);						\
87 			(*h6280.irq_callback)(1);							\
88         }                                                       \
89 		else													\
90         if ( h6280.irq_state[2] != CLEAR_LINE &&                \
91 			 !(h6280.irq_mask & 0x4) )							\
92 		{														\
93 			h6280.irq_state[2] = CLEAR_LINE;					\
94  			DO_INTERRUPT(H6280_TIMER_VEC);						\
95        }                                                       	\
96     }
97 
98 /***************************************************************
99  *  RDMEM   read memory
100  ***************************************************************/
101 #define RDMEM(addr) 											\
102 	cpu_readmem21( (h6280.mmr[(addr)>>13] << 13) | ((addr)&0x1fff))
103 
104 /***************************************************************
105  *  WRMEM   write memory
106  ***************************************************************/
107 #define WRMEM(addr,data)										\
108 	cpu_writemem21( (h6280.mmr[(addr)>>13] << 13) | ((addr)&0x1fff),data);
109 
110 /***************************************************************
111  *  RDMEMZ   read memory - zero page
112  ***************************************************************/
113 #define RDMEMZ(addr) 											\
114 	cpu_readmem21( (h6280.mmr[1] << 13) | ((addr)&0x1fff));
115 
116 /***************************************************************
117  *  WRMEMZ   write memory - zero page
118  ***************************************************************/
119 #define WRMEMZ(addr,data) 										\
120 	cpu_writemem21( (h6280.mmr[1] << 13) | ((addr)&0x1fff),data);
121 
122 /***************************************************************
123  *  RDMEMW   read word from memory
124  ***************************************************************/
125 #define RDMEMW(addr)											\
126 	cpu_readmem21( (h6280.mmr[(addr)  >>13] << 13) | ((addr  )&0x1fff)) \
127 | ( cpu_readmem21( (h6280.mmr[(addr+1)>>13] << 13) | ((addr+1)&0x1fff)) << 8 )
128 
129 /***************************************************************
130  *  RDZPWORD    read a word from a zero page address
131  ***************************************************************/
132 #define RDZPWORD(addr)											\
133 	((addr&0xff)==0xff) ?										\
134 		cpu_readmem21( (h6280.mmr[1] << 13) | ((addr)&0x1fff))				\
135 		+(cpu_readmem21( (h6280.mmr[1] << 13) | ((addr-0xff)&0x1fff))<<8) : \
136 		cpu_readmem21( (h6280.mmr[1] << 13) | ((addr)&0x1fff))				\
137 		+(cpu_readmem21( (h6280.mmr[1] << 13) | ((addr+1)&0x1fff))<<8)
138 
139 
140 /***************************************************************
141  * push a register onto the stack
142  ***************************************************************/
143 #define PUSH(Rg) cpu_writemem21( (h6280.mmr[1] << 13) | h6280.sp.d,Rg); S--
144 
145 /***************************************************************
146  * pull a register from the stack
147  ***************************************************************/
148 #define PULL(Rg) S++; Rg = cpu_readmem21( (h6280.mmr[1] << 13) | h6280.sp.d)
149 
150 /***************************************************************
151  *  RDOP    read an opcode
152  ***************************************************************/
153 #define RDOP()													\
154 	cpu_readop((h6280.mmr[PCW>>13] << 13) | (PCW&0x1fff))
155 
156 /***************************************************************
157  *  RDOPARG read an opcode argument
158  ***************************************************************/
159 #define RDOPARG()												\
160 	cpu_readop_arg((h6280.mmr[PCW>>13] << 13) | (PCW&0x1fff))
161 
162 /***************************************************************
163  *	BRA  branch relative
164  ***************************************************************/
165 #define BRA(cond)												\
166 	if (cond)													\
167 	{															\
168 		h6280_ICount -= 4;										\
169 		tmp = RDOPARG();										\
170 		PCW++;													\
171 		EAW = PCW + (signed char)tmp;							\
172 		PCD = EAD;												\
173 	}															\
174 	else														\
175 	{															\
176 		PCW++;													\
177 		h6280_ICount -= 2;										\
178 	}
179 
180 /***************************************************************
181  *
182  * Helper macros to build the effective address
183  *
184  ***************************************************************/
185 
186 /***************************************************************
187  *  EA = zero page address
188  ***************************************************************/
189 #define EA_ZPG													\
190 	ZPL = RDOPARG();											\
191 	PCW++;														\
192 	EAD = ZPD
193 
194 /***************************************************************
195  *  EA = zero page address + X
196  ***************************************************************/
197 #define EA_ZPX													\
198 	ZPL = RDOPARG() + X;										\
199 	PCW++;														\
200 	EAD = ZPD
201 
202 /***************************************************************
203  *  EA = zero page address + Y
204  ***************************************************************/
205 #define EA_ZPY													\
206 	ZPL = RDOPARG() + Y;										\
207 	PCW++;														\
208 	EAD = ZPD
209 
210 /***************************************************************
211  *  EA = absolute address
212  ***************************************************************/
213 #define EA_ABS													\
214 	EAL = RDOPARG();											\
215 	PCW++;														\
216 	EAH = RDOPARG();											\
217 	PCW++
218 
219 /***************************************************************
220  *  EA = absolute address + X
221  ***************************************************************/
222 #define EA_ABX                                                  \
223 	EA_ABS; 													\
224 	EAW += X
225 
226 /***************************************************************
227  *	EA = absolute address + Y
228  ***************************************************************/
229 #define EA_ABY													\
230 	EA_ABS; 													\
231 	EAW += Y
232 
233 /***************************************************************
234  *	EA = zero page indirect (65c02 pre indexed w/o X)
235  ***************************************************************/
236 #define EA_ZPI													\
237 	ZPL = RDOPARG();											\
238 	PCW++;														\
239 	EAD = RDZPWORD(ZPD)
240 
241 /***************************************************************
242  *  EA = zero page + X indirect (pre indexed)
243  ***************************************************************/
244 #define EA_IDX													\
245 	ZPL = RDOPARG() + X;										\
246 	PCW++;														\
247 	EAD = RDZPWORD(ZPD);
248 
249 /***************************************************************
250  *  EA = zero page indirect + Y (post indexed)
251  ***************************************************************/
252 #define EA_IDY													\
253 	ZPL = RDOPARG();											\
254 	PCW++;														\
255 	EAD = RDZPWORD(ZPD);										\
256 	EAW += Y
257 
258 /***************************************************************
259  *	EA = indirect (only used by JMP)
260  ***************************************************************/
261 #define EA_IND													\
262 	EA_ABS; 													\
263 	tmp = RDMEM(EAD);											\
264 	EAD++; 														\
265 	EAH = RDMEM(EAD);											\
266 	EAL = tmp
267 
268 /***************************************************************
269  *	EA = indirect plus x (only used by JMP)
270  ***************************************************************/
271 #define EA_IAX                                                  \
272 	EA_ABS;														\
273 	EAD+=X;														\
274 	tmp = RDMEM(EAD);											\
275 	EAD++; 	 													\
276 	EAH = RDMEM(EAD);											\
277 	EAL = tmp
278 
279 /* read a value into tmp */
280 #define RD_IMM	tmp = RDOPARG(); PCW++
281 #define RD_IMM2	tmp2 = RDOPARG(); PCW++
282 #define RD_ACC	tmp = A
283 #define RD_ZPG	EA_ZPG; tmp = RDMEMZ(EAD)
284 #define RD_ZPX	EA_ZPX; tmp = RDMEMZ(EAD)
285 #define RD_ZPY	EA_ZPY; tmp = RDMEMZ(EAD)
286 #define RD_ABS	EA_ABS; tmp = RDMEM(EAD)
287 #define RD_ABX	EA_ABX; tmp = RDMEM(EAD)
288 #define RD_ABY	EA_ABY; tmp = RDMEM(EAD)
289 #define RD_ZPI	EA_ZPI; tmp = RDMEM(EAD)
290 #define RD_IDX	EA_IDX; tmp = RDMEM(EAD)
291 #define RD_IDY	EA_IDY; tmp = RDMEM(EAD)
292 
293 /* write a value from tmp */
294 #define WR_ZPG	EA_ZPG; WRMEMZ(EAD, tmp)
295 #define WR_ZPX	EA_ZPX; WRMEMZ(EAD, tmp)
296 #define WR_ZPY	EA_ZPY; WRMEMZ(EAD, tmp)
297 #define WR_ABS	EA_ABS; WRMEM(EAD, tmp)
298 #define WR_ABX	EA_ABX; WRMEM(EAD, tmp)
299 #define WR_ABY	EA_ABY; WRMEM(EAD, tmp)
300 #define WR_ZPI	EA_ZPI; WRMEM(EAD, tmp)
301 #define WR_IDX	EA_IDX; WRMEM(EAD, tmp)
302 #define WR_IDY	EA_IDY; WRMEM(EAD, tmp)
303 
304 /* write back a value from tmp to the last EA */
305 #define WB_ACC	A = (UINT8)tmp;
306 #define WB_EA	WRMEM(EAD, tmp)
307 #define WB_EAZ	WRMEMZ(EAD, tmp)
308 
309 /***************************************************************
310  *
311  * Macros to emulate the 6280 opcodes
312  *
313  ***************************************************************/
314 
315 /***************************************************************
316  * compose the real flag register by
317  * including N and Z and set any
318  * SET and clear any CLR bits also
319  ***************************************************************/
320 #if LAZY_FLAGS
321 
322 #define COMPOSE_P(SET,CLR)										\
323 	P = (P & ~(_fN | _fZ | CLR)) |								\
324 		(NZ >> 8) | 											\
325 		((NZ & 0xff) ? 0 : _fZ) |								\
326 		SET
327 
328 #else
329 
330 #define COMPOSE_P(SET,CLR)										\
331 	P = (P & ~CLR) | SET
332 
333 #endif
334 
335 /* 6280 ********************************************************
336  *	ADC Add with carry
337  ***************************************************************/
338 #define ADC 													\
339 	if (P & _fD)												\
340 	{															\
341 	int c = (P & _fC);											\
342 	int lo = (A & 0x0f) + (tmp & 0x0f) + c; 					\
343 	int hi = (A & 0xf0) + (tmp & 0xf0); 						\
344 		P &= ~(_fV | _fC);										\
345 		if (lo > 0x09)											\
346 		{														\
347 			hi += 0x10; 										\
348 			lo += 0x06; 										\
349 		}														\
350 		if (~(A^tmp) & (A^hi) & _fN)							\
351 			P |= _fV;											\
352 		if (hi > 0x90)											\
353 			hi += 0x60; 										\
354 		if (hi & 0xff00)										\
355 			P |= _fC;											\
356 		A = (lo & 0x0f) + (hi & 0xf0);							\
357 	}															\
358 	else														\
359 	{															\
360 	int c = (P & _fC);											\
361 	int sum = A + tmp + c;										\
362 		P &= ~(_fV | _fC);										\
363 		if (~(A^tmp) & (A^sum) & _fN)							\
364 			P |= _fV;											\
365 		if (sum & 0xff00)										\
366 			P |= _fC;											\
367 		A = (UINT8) sum;										\
368 	}															\
369 	SET_NZ(A)
370 
371 /* 6280 ********************************************************
372  *	AND Logical and
373  ***************************************************************/
374 #define AND 													\
375 	A = (UINT8)(A & tmp);										\
376 	SET_NZ(A)
377 
378 /* 6280 ********************************************************
379  *	ASL Arithmetic shift left
380  ***************************************************************/
381 #define ASL 													\
382 	P = (P & ~_fC) | ((tmp >> 7) & _fC);						\
383 	tmp = (UINT8)(tmp << 1);									\
384 	SET_NZ(tmp)
385 
386 /* 6280 ********************************************************
387  *  BBR Branch if bit is reset
388  ***************************************************************/
389 #define BBR(bit)                                                \
390     BRA(!(tmp & (1<<bit)))
391 
392 /* 6280 ********************************************************
393  *  BBS Branch if bit is set
394  ***************************************************************/
395 #define BBS(bit)                                                \
396     BRA(tmp & (1<<bit))
397 
398 /* 6280 ********************************************************
399  *	BCC Branch if carry clear
400  ***************************************************************/
401 #define BCC BRA(!(P & _fC))
402 
403 /* 6280 ********************************************************
404  *	BCS Branch if carry set
405  ***************************************************************/
406 #define BCS BRA(P & _fC)
407 
408 /* 6280 ********************************************************
409  *	BEQ Branch if equal
410  ***************************************************************/
411 #if LAZY_FLAGS
412 #define BEQ BRA(!(NZ & 0xff))
413 #else
414 #define BEQ BRA(P & _fZ)
415 #endif
416 
417 /* 6280 ********************************************************
418  *	BIT Bit test
419  ***************************************************************/
420 #undef BIT
421 #define BIT														\
422 	P = (P & ~(_fN|_fV|_fT|_fZ))								\
423 		| ((tmp&0x80) ? _fN:0)									\
424 		| ((tmp&0x40) ? _fV:0)									\
425 		| ((tmp&A)  ? 0:_fZ)
426 
427 /* 6280 ********************************************************
428  *	BMI Branch if minus
429  ***************************************************************/
430 #if LAZY_FLAGS
431 #define BMI BRA(NZ & 0x8000)
432 #else
433 #define BMI BRA(P & _fN)
434 #endif
435 
436 /* 6280 ********************************************************
437  *	BNE Branch if not equal
438  ***************************************************************/
439 #if LAZY_FLAGS
440 #define BNE BRA(NZ & 0xff)
441 #else
442 #define BNE BRA(!(P & _fZ))
443 #endif
444 
445 /* 6280 ********************************************************
446  *	BPL Branch if plus
447  ***************************************************************/
448 #if LAZY_FLAGS
449 #define BPL BRA(!(NZ & 0x8000))
450 #else
451 #define BPL BRA(!(P & _fN))
452 #endif
453 
454 /* 6280 ********************************************************
455  *	BRK Break
456  *	increment PC, push PC hi, PC lo, flags (with B bit set),
457  *	set I flag, reset D flag and jump via IRQ vector
458  ***************************************************************/
459 #define BRK 													\
460 	logerror("BRK %04x\n",activecpu_get_pc());	\
461 	PCW++;														\
462 	PUSH(PCH);													\
463 	PUSH(PCL);													\
464 	PUSH(P | _fB);												\
465 	P = (P & ~_fD) | _fI;										\
466 	PCL = RDMEM(H6280_IRQ2_VEC); 								\
467 	PCH = RDMEM(H6280_IRQ2_VEC+1)
468 
469 /* 6280 ********************************************************
470  *	BSR Branch to subroutine
471  ***************************************************************/
472 #define BSR 													\
473 	PUSH(PCH);													\
474 	PUSH(PCL);													\
475 	h6280_ICount -= 4; /* 4 cycles here, 4 in BRA */			\
476 	BRA(1)
477 
478 /* 6280 ********************************************************
479  *	BVC Branch if overflow clear
480  ***************************************************************/
481 #define BVC BRA(!(P & _fV))
482 
483 /* 6280 ********************************************************
484  *	BVS Branch if overflow set
485  ***************************************************************/
486 #define BVS BRA(P & _fV)
487 
488 /* 6280 ********************************************************
489  *  CLA Clear accumulator
490  ***************************************************************/
491 #define CLA                                                     \
492     A = 0
493 
494 /* 6280 ********************************************************
495  *	CLC Clear carry flag
496  ***************************************************************/
497 #define CLC 													\
498 	P &= ~_fC
499 
500 /* 6280 ********************************************************
501  *	CLD Clear decimal flag
502  ***************************************************************/
503 #define CLD 													\
504 	P &= ~_fD
505 
506 /* 6280 ********************************************************
507  *	CLI Clear interrupt flag
508  ***************************************************************/
509 #define CLI 													\
510 	if( P & _fI )												\
511 	{															\
512 		P &= ~_fI;												\
513 		CHECK_IRQ_LINES;										\
514 	}
515 
516 
517 /* 6280 ********************************************************
518  *	CLV Clear overflow flag
519  ***************************************************************/
520 #define CLV 													\
521 	P &= ~_fV
522 
523 /* 6280 ********************************************************
524  *  CLX Clear index X
525  ***************************************************************/
526 #define CLX                                                     \
527     X = 0
528 
529 /* 6280 ********************************************************
530  *  CLY Clear index Y
531  ***************************************************************/
532 #define CLY                                                     \
533     Y = 0
534 
535 /* 6280 ********************************************************
536  *	CMP Compare accumulator
537  ***************************************************************/
538 #define CMP 													\
539 	P &= ~_fC;													\
540 	if (A >= tmp)												\
541 		P |= _fC;												\
542 	SET_NZ((UINT8)(A - tmp))
543 
544 /* 6280 ********************************************************
545  *	CPX Compare index X
546  ***************************************************************/
547 #define CPX 													\
548 	P &= ~_fC;													\
549 	if (X >= tmp)												\
550 		P |= _fC;												\
551 	SET_NZ((UINT8)(X - tmp))
552 
553 /* 6280 ********************************************************
554  *	CPY Compare index Y
555  ***************************************************************/
556 #define CPY 													\
557 	P &= ~_fC;													\
558 	if (Y >= tmp)												\
559 		P |= _fC;												\
560 	SET_NZ((UINT8)(Y - tmp))
561 
562 /* 6280 ********************************************************
563  *  DEA Decrement accumulator
564  ***************************************************************/
565 #define DEA                                                     \
566 	A = (UINT8)--A; 											\
567     SET_NZ(A)
568 
569 /* 6280 ********************************************************
570  *	DEC Decrement memory
571  ***************************************************************/
572 #define DEC 													\
573 	tmp = (UINT8)(tmp-1); 										\
574 	SET_NZ(tmp)
575 
576 /* 6280 ********************************************************
577  *	DEX Decrement index X
578  ***************************************************************/
579 #define DEX 													\
580 	X = (UINT8)--X; 											\
581 	SET_NZ(X)
582 
583 /* 6280 ********************************************************
584  *	DEY Decrement index Y
585  ***************************************************************/
586 #define DEY 													\
587 	Y = (UINT8)--Y; 											\
588 	SET_NZ(Y)
589 
590 /* 6280 ********************************************************
591  *	EOR Logical exclusive or
592  ***************************************************************/
593 #define EOR 													\
594 	A = (UINT8)(A ^ tmp);										\
595 	SET_NZ(A)
596 
597 /* 6280 ********************************************************
598  *	ILL Illegal opcode
599  ***************************************************************/
600 #define ILL 													\
601 	h6280_ICount -= 2; /* (assumed) */							\
602 	logerror("%04x: WARNING - h6280 illegal opcode\n",activecpu_get_pc())
603 
604 /* 6280 ********************************************************
605  *  INA Increment accumulator
606  ***************************************************************/
607 #define INA                                                     \
608 	A = (UINT8)++A; 											\
609     SET_NZ(A)
610 
611 /* 6280 ********************************************************
612  *	INC Increment memory
613  ***************************************************************/
614 #define INC 													\
615 	tmp = (UINT8)(tmp+1); 										\
616 	SET_NZ(tmp)
617 
618 /* 6280 ********************************************************
619  *	INX Increment index X
620  ***************************************************************/
621 #define INX 													\
622 	X = (UINT8)++X; 											\
623 	SET_NZ(X)
624 
625 /* 6280 ********************************************************
626  *	INY Increment index Y
627  ***************************************************************/
628 #define INY 													\
629 	Y = (UINT8)++Y; 											\
630 	SET_NZ(Y)
631 
632 /* 6280 ********************************************************
633  *	JMP Jump to address
634  *	set PC to the effective address
635  ***************************************************************/
636 #define JMP 													\
637 	PCD = EAD
638 
639 /* 6280 ********************************************************
640  *	JSR Jump to subroutine
641  *	decrement PC (sic!) push PC hi, push PC lo and set
642  *	PC to the effective address
643  ***************************************************************/
644 #define JSR 													\
645 	PCW--;														\
646 	PUSH(PCH);													\
647 	PUSH(PCL);													\
648 	PCD = EAD
649 
650 /* 6280 ********************************************************
651  *	LDA Load accumulator
652  ***************************************************************/
653 #define LDA 													\
654 	A = (UINT8)tmp; 											\
655 	SET_NZ(A)
656 
657 /* 6280 ********************************************************
658  *	LDX Load index X
659  ***************************************************************/
660 #define LDX 													\
661 	X = (UINT8)tmp; 											\
662 	SET_NZ(X)
663 
664 /* 6280 ********************************************************
665  *	LDY Load index Y
666  ***************************************************************/
667 #define LDY 													\
668 	Y = (UINT8)tmp; 											\
669 	SET_NZ(Y)
670 
671 /* 6280 ********************************************************
672  *	LSR Logic shift right
673  *	0 -> [7][6][5][4][3][2][1][0] -> C
674  ***************************************************************/
675 #define LSR 													\
676 	P = (P & ~_fC) | (tmp & _fC);								\
677 	tmp = (UINT8)tmp >> 1;										\
678 	SET_NZ(tmp)
679 
680 /* 6280 ********************************************************
681  *	NOP No operation
682  ***************************************************************/
683 #define NOP
684 
685 /* 6280 ********************************************************
686  *	ORA Logical inclusive or
687  ***************************************************************/
688 #define ORA 													\
689 	A = (UINT8)(A | tmp);										\
690 	SET_NZ(A)
691 
692 /* 6280 ********************************************************
693  *	PHA Push accumulator
694  ***************************************************************/
695 #define PHA 													\
696 	PUSH(A)
697 
698 /* 6280 ********************************************************
699  *	PHP Push processor status (flags)
700  ***************************************************************/
701 #define PHP 													\
702 	COMPOSE_P(0,0); 											\
703 	PUSH(P)
704 
705 /* 6280 ********************************************************
706  *  PHX Push index X
707  ***************************************************************/
708 #define PHX                                                     \
709     PUSH(X)
710 
711 /* 6280 ********************************************************
712  *  PHY Push index Y
713  ***************************************************************/
714 #define PHY                                                     \
715     PUSH(Y)
716 
717 /* 6280 ********************************************************
718  *	PLA Pull accumulator
719  ***************************************************************/
720 #define PLA 													\
721 	PULL(A);													\
722 	SET_NZ(A)
723 
724 /* 6280 ********************************************************
725  *	PLP Pull processor status (flags)
726  ***************************************************************/
727 #if LAZY_FLAGS
728 
729 #define PLP 													\
730 	PULL(P);													\
731 	NZ = ((P & _fN) << 8) | 									\
732 		 ((P & _fZ) ^ _fZ); 									\
733 	CHECK_IRQ_LINES
734 
735 #else
736 
737 #define PLP 													\
738 	PULL(P); 													\
739 	CHECK_IRQ_LINES
740 #endif
741 
742 /* 6280 ********************************************************
743  *  PLX Pull index X
744  ***************************************************************/
745 #define PLX                                                     \
746     PULL(X)
747 
748 /* 6280 ********************************************************
749  *  PLY Pull index Y
750  ***************************************************************/
751 #define PLY                                                     \
752     PULL(Y)
753 
754 /* 6280 ********************************************************
755  *  RMB Reset memory bit
756  ***************************************************************/
757 #define RMB(bit)                                                \
758     tmp &= ~(1<<bit)
759 
760 /* 6280 ********************************************************
761  *	ROL Rotate left
762  *	new C <- [7][6][5][4][3][2][1][0] <- C
763  ***************************************************************/
764 #define ROL 													\
765 	tmp = (tmp << 1) | (P & _fC);								\
766 	P = (P & ~_fC) | ((tmp >> 8) & _fC);						\
767 	tmp = (UINT8)tmp;											\
768 	SET_NZ(tmp)
769 
770 /* 6280 ********************************************************
771  *	ROR Rotate right
772  *	C -> [7][6][5][4][3][2][1][0] -> new C
773  ***************************************************************/
774 #define ROR 													\
775 	tmp |= (P & _fC) << 8;										\
776 	P = (P & ~_fC) | (tmp & _fC);								\
777 	tmp = (UINT8)(tmp >> 1);									\
778 	SET_NZ(tmp)
779 
780 /* 6280 ********************************************************
781  *	RTI Return from interrupt
782  *	pull flags, pull PC lo, pull PC hi and increment PC
783  ***************************************************************/
784 #if LAZY_FLAGS
785 
786 #define RTI 													\
787 	PULL(P);													\
788 	NZ = ((P & _fN) << 8) | 									\
789 		 ((P & _fZ) ^ _fZ); 									\
790 	PULL(PCL);													\
791 	PULL(PCH);													\
792 	CHECK_IRQ_LINES
793 #else
794 
795 #define RTI 													\
796 	PULL(P);													\
797 	PULL(PCL);													\
798 	PULL(PCH);													\
799 	CHECK_IRQ_LINES
800 #endif
801 
802 /* 6280 ********************************************************
803  *	RTS Return from subroutine
804  *	pull PC lo, PC hi and increment PC
805  ***************************************************************/
806 #define RTS 													\
807 	PULL(PCL);													\
808 	PULL(PCH);													\
809 	PCW++;														\
810 
811 /* 6280 ********************************************************
812  *  SAX Swap accumulator and index X
813  ***************************************************************/
814 #define SAX                                                     \
815     tmp = X;                                                    \
816     X = A;                                                      \
817     A = tmp
818 
819 /* 6280 ********************************************************
820  *  SAY Swap accumulator and index Y
821  ***************************************************************/
822 #define SAY                                                     \
823     tmp = Y;                                                    \
824     Y = A;                                                      \
825     A = tmp
826 
827 /* 6280 ********************************************************
828  *	SBC Subtract with carry
829  ***************************************************************/
830 #define SBC 													\
831 	if (P & _fD)												\
832 	{															\
833 	int c = (P & _fC) ^ _fC;									\
834 	int sum = A - tmp - c;										\
835 	int lo = (A & 0x0f) - (tmp & 0x0f) - c; 					\
836 	int hi = (A & 0xf0) - (tmp & 0xf0); 						\
837 		P &= ~(_fV | _fC);										\
838 		if ((A^tmp) & (A^sum) & _fN)							\
839 			P |= _fV;											\
840 		if (lo & 0xf0)											\
841 			lo -= 6;											\
842 		if (lo & 0x80)											\
843 			hi -= 0x10; 										\
844 		if (hi & 0x0f00)										\
845 			hi -= 0x60; 										\
846 		if ((sum & 0xff00) == 0)								\
847 			P |= _fC;											\
848 		A = (lo & 0x0f) + (hi & 0xf0);							\
849 	}															\
850 	else														\
851 	{															\
852 	int c = (P & _fC) ^ _fC;									\
853 	int sum = A - tmp - c;										\
854 		P &= ~(_fV | _fC);										\
855 		if ((A^tmp) & (A^sum) & _fN)							\
856 			P |= _fV;											\
857 		if ((sum & 0xff00) == 0)								\
858 			P |= _fC;											\
859 		A = (UINT8) sum;										\
860 	}															\
861 	SET_NZ(A)
862 
863 /* 6280 ********************************************************
864  *	SEC Set carry flag
865  ***************************************************************/
866 #define SEC 													\
867 	P |= _fC
868 
869 /* 6280 ********************************************************
870  *	SED Set decimal flag
871  ***************************************************************/
872 #define SED 													\
873 	P |= _fD
874 
875 /* 6280 ********************************************************
876  *	SEI Set interrupt flag
877  ***************************************************************/
878 #define SEI 													\
879 	P |= _fI
880 
881 /* 6280 ********************************************************
882  *	SET Set t flag
883  ***************************************************************/
884 #define SET 													\
885 	P |= _fT;													\
886 	logerror("%04x: WARNING H6280 SET\n",activecpu_get_pc())
887 
888 /* 6280 ********************************************************
889  *  SMB Set memory bit
890  ***************************************************************/
891 #define SMB(bit)                                                \
892     tmp |= (1<<bit)
893 
894 /* 6280 ********************************************************
895  *  ST0 Store at hardware address 0
896  ***************************************************************/
897 #define ST0                                                     \
898     cpu_writeport16(0x0000,tmp)
899 
900 /* 6280 ********************************************************
901  *  ST1 Store at hardware address 2
902  ***************************************************************/
903 #define ST1                                                     \
904     cpu_writeport16(0x0002,tmp)
905 
906 /* 6280 ********************************************************
907  *  ST2 Store at hardware address 3
908  ***************************************************************/
909 #define ST2                                                     \
910     cpu_writeport16(0x0003,tmp)
911 
912 /* 6280 ********************************************************
913  *	STA Store accumulator
914  ***************************************************************/
915 #define STA 													\
916 	tmp = A
917 
918 /* 6280 ********************************************************
919  *	STX Store index X
920  ***************************************************************/
921 #define STX 													\
922 	tmp = X
923 
924 /* 6280 ********************************************************
925  *	STY Store index Y
926  ***************************************************************/
927 #define STY 													\
928 	tmp = Y
929 
930 /* 6280 ********************************************************
931  * STZ  Store zero
932  ***************************************************************/
933 #define STZ                                                     \
934     tmp = 0
935 
936 /* H6280 *******************************************************
937  *  SXY Swap index X and index Y
938  ***************************************************************/
939 #define SXY                                                    \
940     tmp = X;                                                   \
941     X = Y;                                                     \
942     Y = tmp
943 
944 /* H6280 *******************************************************
945  *  TAI
946  ***************************************************************/
947 #define TAI 													\
948 	from=RDMEMW(PCW);											\
949 	to  =RDMEMW(PCW+2);											\
950 	length=RDMEMW(PCW+4);										\
951 	PCW+=6; 													\
952 	alternate=0; 												\
953 	while ((length--) != 0) { 									\
954 		WRMEM(to,RDMEM(from+alternate)); 						\
955 		to++; 													\
956 		alternate ^= 1; 										\
957 	}		 													\
958 	h6280_ICount-=(6 * length) + 17;
959 
960 /* H6280 *******************************************************
961  *  TAM Transfer accumulator to memory mapper register(s)
962  ***************************************************************/
963 #define TAM                                                     \
964     if (tmp&0x01) h6280.mmr[0] = A;                             \
965     if (tmp&0x02) h6280.mmr[1] = A;                             \
966     if (tmp&0x04) h6280.mmr[2] = A;                             \
967     if (tmp&0x08) h6280.mmr[3] = A;                             \
968     if (tmp&0x10) h6280.mmr[4] = A;                             \
969     if (tmp&0x20) h6280.mmr[5] = A;                             \
970     if (tmp&0x40) h6280.mmr[6] = A;                             \
971     if (tmp&0x80) h6280.mmr[7] = A
972 
973 /* 6280 ********************************************************
974  *	TAX Transfer accumulator to index X
975  ***************************************************************/
976 #define TAX 													\
977 	X = A;														\
978 	SET_NZ(X)
979 
980 /* 6280 ********************************************************
981  *	TAY Transfer accumulator to index Y
982  ***************************************************************/
983 #define TAY 													\
984 	Y = A;														\
985 	SET_NZ(Y)
986 
987 /* 6280 ********************************************************
988  *  TDD
989  ***************************************************************/
990 #define TDD 													\
991 	from=RDMEMW(PCW);											\
992 	to  =RDMEMW(PCW+2);											\
993 	length=RDMEMW(PCW+4);										\
994 	PCW+=6; 													\
995 	while ((length--) != 0) { 									\
996 		WRMEM(to,RDMEM(from)); 									\
997 		to--; 													\
998 		from--;													\
999 	}		 													\
1000 	h6280_ICount-=(6 * length) + 17;
1001 
1002 /* 6280 ********************************************************
1003  *  TIA
1004  ***************************************************************/
1005 #define TIA 													\
1006 	from=RDMEMW(PCW);											\
1007 	to  =RDMEMW(PCW+2);											\
1008 	length=RDMEMW(PCW+4);										\
1009 	PCW+=6; 													\
1010 	alternate=0; 												\
1011 	while ((length--) != 0) { 									\
1012 		WRMEM(to+alternate,RDMEM(from));						\
1013 		from++; 												\
1014 		alternate ^= 1; 										\
1015 	}		 													\
1016 	h6280_ICount-=(6 * length) + 17;
1017 
1018 /* 6280 ********************************************************
1019  *  TII
1020  ***************************************************************/
1021 #define TII 													\
1022 	from=RDMEMW(PCW);											\
1023 	to  =RDMEMW(PCW+2);											\
1024 	length=RDMEMW(PCW+4);										\
1025 	PCW+=6; 													\
1026 	while ((length--) != 0) { 									\
1027 		WRMEM(to,RDMEM(from)); 									\
1028 		to++; 													\
1029 		from++;													\
1030 	}		 													\
1031 	h6280_ICount-=(6 * length) + 17;
1032 
1033 /* 6280 ********************************************************
1034  *  TIN Transfer block, source increments every loop
1035  ***************************************************************/
1036 #define TIN 													\
1037 	from=RDMEMW(PCW);											\
1038 	to  =RDMEMW(PCW+2);											\
1039 	length=RDMEMW(PCW+4);										\
1040 	PCW+=6; 													\
1041 	while ((length--) != 0) { 									\
1042 		WRMEM(to,RDMEM(from)); 									\
1043 		from++;													\
1044 	}		 													\
1045 	h6280_ICount-=(6 * length) + 17;
1046 
1047 /* 6280 ********************************************************
1048  *  TMA Transfer memory mapper register(s) to accumulator
1049  *  the highest bit set in tmp is the one that counts
1050  ***************************************************************/
1051 #define TMA                                                     \
1052     if (tmp&0x01) A = h6280.mmr[0];                             \
1053     if (tmp&0x02) A = h6280.mmr[1];                             \
1054     if (tmp&0x04) A = h6280.mmr[2];                             \
1055     if (tmp&0x08) A = h6280.mmr[3];                             \
1056     if (tmp&0x10) A = h6280.mmr[4];                             \
1057     if (tmp&0x20) A = h6280.mmr[5];                             \
1058     if (tmp&0x40) A = h6280.mmr[6];                             \
1059     if (tmp&0x80) A = h6280.mmr[7]
1060 
1061 /* 6280 ********************************************************
1062  * TRB  Test and reset bits
1063  ***************************************************************/
1064 #define TRB                                                   	\
1065 	P = (P & ~(_fN|_fV|_fT|_fZ))								\
1066 		| ((tmp&0x80) ? _fN:0)									\
1067 		| ((tmp&0x40) ? _fV:0)									\
1068 		| ((tmp&A)  ? 0:_fZ);									\
1069     tmp &= ~A
1070 
1071 /* 6280 ********************************************************
1072  * TSB  Test and set bits
1073  ***************************************************************/
1074 #define TSB                                                     \
1075 	P = (P & ~(_fN|_fV|_fT|_fZ))								\
1076 		| ((tmp&0x80) ? _fN:0)									\
1077 		| ((tmp&0x40) ? _fV:0)									\
1078 		| ((tmp&A)  ? 0:_fZ);									\
1079     tmp |= A
1080 
1081 /* 6280 ********************************************************
1082  *	TSX Transfer stack LSB to index X
1083  ***************************************************************/
1084 #define TSX 													\
1085 	X = S;														\
1086 	SET_NZ(X)
1087 
1088 /* 6280 ********************************************************
1089  *	TST
1090  ***************************************************************/
1091 #define TST														\
1092 	P = (P & ~(_fN|_fV|_fT|_fZ))								\
1093 		| ((tmp2&0x80) ? _fN:0)									\
1094 		| ((tmp2&0x40) ? _fV:0)									\
1095 		| ((tmp2&tmp)  ? 0:_fZ)
1096 
1097 /* 6280 ********************************************************
1098  *	TXA Transfer index X to accumulator
1099  ***************************************************************/
1100 #define TXA 													\
1101 	A = X;														\
1102 	SET_NZ(A)
1103 
1104 /* 6280 ********************************************************
1105  *	TXS Transfer index X to stack LSB
1106  *	no flags changed (sic!)
1107  ***************************************************************/
1108 #define TXS 													\
1109 	S = X
1110 
1111 /* 6280 ********************************************************
1112  *	TYA Transfer index Y to accumulator
1113  ***************************************************************/
1114 #define TYA 													\
1115 	A = Y;														\
1116 	SET_NZ(A)
1117