c6502mak.h
  1  //
  2  // Copyright (c) 2004 K. Wilkins
  3  //
  4  // This software is provided 'as-is', without any express or implied warranty.
  5  // In no event will the authors be held liable for any damages arising from
  6  // the use of this software.
  7  //
  8  // Permission is granted to anyone to use this software for any purpose,
  9  // including commercial applications, and to alter it and redistribute it
 10  // freely, subject to the following restrictions:
 11  //
 12  // 1. The origin of this software must not be misrepresented; you must not
 13  //    claim that you wrote the original software. If you use this software
 14  //    in a product, an acknowledgment in the product documentation would be
 15  //    appreciated but is not required.
 16  //
 17  // 2. Altered source versions must be plainly marked as such, and must not
 18  //    be misrepresented as being the original software.
 19  //
 20  // 3. This notice may not be removed or altered from any source distribution.
 21  //
 22  
 23  //////////////////////////////////////////////////////////////////////////////
 24  //                       Handy - An Atari Lynx Emulator                     //
 25  //                          Copyright (c) 1996,1997                         //
 26  //                                 K. Wilkins                               //
 27  //////////////////////////////////////////////////////////////////////////////
 28  // 65C02 Macro definitions                                                  //
 29  //////////////////////////////////////////////////////////////////////////////
 30  //                                                                          //
 31  // This file contains all of the required address mode and operand          //
 32  // macro definitions for the 65C02 emulation                                //
 33  //                                                                          //
 34  //    K. Wilkins                                                            //
 35  // August 1997                                                              //
 36  //                                                                          //
 37  //////////////////////////////////////////////////////////////////////////////
 38  // Revision History:                                                        //
 39  // -----------------                                                        //
 40  //                                                                          //
 41  // 01Aug1997 KW Document header added & class documented.                   //
 42  //                                                                          //
 43  //////////////////////////////////////////////////////////////////////////////
 44  
 45  //
 46  // Addressing mode decoding
 47  //
 48  
 49  #define	xIMMEDIATE()			{mOperand=mPC;mPC++;}
 50  #define	xABSOLUTE()				{mOperand=CPU_PEEKW(mPC);mPC+=2;}
 51  #define xZEROPAGE()				{mOperand=CPU_PEEK_RAM(mPC);mPC++;}
 52  #define xZEROPAGE_X()			{mOperand=CPU_PEEK_RAM(mPC)+mX;mPC++;mOperand&=0xff;}
 53  #define xZEROPAGE_Y()			{mOperand=CPU_PEEK_RAM(mPC)+mY;mPC++;mOperand&=0xff;}
 54  #define xABSOLUTE_X()			{mOperand=CPU_PEEKW(mPC);mPC+=2;mOperand+=mX;mOperand&=0xffff;}
 55  #define	xABSOLUTE_Y()			{mOperand=CPU_PEEKW(mPC);mPC+=2;mOperand+=mY;mOperand&=0xffff;}
 56  #define xINDIRECT_ABSOLUTE_X()	{mOperand=CPU_PEEKW(mPC);mPC+=2;mOperand+=mX;mOperand&=0xffff;mOperand=CPU_PEEKW(mOperand);}
 57  #define xRELATIVE()				{mOperand=CPU_PEEK(mPC);mPC++;mOperand=(mPC+mOperand)&0xffff;}
 58  #define xINDIRECT_X()			{mOperand=CPU_PEEK(mPC);mPC++;mOperand=mOperand+mX;mOperand&=0x00ff;mOperand=CPU_PEEKW(mOperand);}
 59  #define xINDIRECT_Y()			{mOperand=CPU_PEEK(mPC);mPC++;mOperand=CPU_PEEKW(mOperand);mOperand=mOperand+mY;mOperand&=0xffff;}
 60  #define xINDIRECT_ABSOLUTE()	{mOperand=CPU_PEEKW(mPC);mPC+=2;mOperand=CPU_PEEKW(mOperand);}
 61  #define xINDIRECT()				{mOperand=CPU_PEEK(mPC);mPC++;mOperand=CPU_PEEKW(mOperand);}
 62  
 63  //
 64  // Helper Macros
 65  //
 66  //#define SET_Z(m)				{ mZ=(m)?false:true; }
 67  //#define SET_N(m)				{ mN=(m&0x80)?true:false; }
 68  //#define SET_NZ(m)				SET_Z(m) SET_N(m)
 69  #define SET_Z(m)				{ mZ=!(m); }
 70  #define SET_N(m)				{ mN=(m)&0x80; }
 71  #define SET_NZ(m)				{ mZ=!(m); mN=(m)&0x80; }
 72  #define PULL(m)					{ mSP++; mSP&=0xff; m=CPU_PEEK_RAM(mSP+0x0100); }
 73  #define PUSH(m)					{ CPU_POKE_RAM(0x0100+mSP,m); mSP--; mSP&=0xff; }
 74  //
 75  // Opcode execution
 76  //
 77  
 78  /*
 79  #define	xADC()\
 80  {\
 81  	UBYTE	value=CPU_PEEK(mOperand);\
 82  	UBYTE	oldA=mA;\
 83  	if(!mD)\
 84  	{\
 85  		SWORD sum=(SWORD)((SBYTE)mA)+(SWORD)((SBYTE)value)+(mC?1:0);\
 86  		mV=((sum > 127) || (sum < -128));\
 87  		sum=(SWORD)mA + (SWORD)value + (mC?1:0);\
 88  		mA=(UBYTE)sum;\
 89  		mC=(sum>0xff);\
 90  		SET_NZ(mA);\
 91  	}\
 92  	else\
 93  	{\
 94  		SWORD sum=mBCDTable[0][mA]+mBCDTable[0][value]+(mC?1:0);\
 95  		mC=(sum > 99);\
 96  		mA=mBCDTable[1][sum & 0xff];\
 97  		SET_NZ(mA);\
 98  		mV=((oldA^mA)&0x80) && ((mA^value)&0x80);\
 99  	}\
100  }
101  */
102  
103  #define xADC()\
104  {\
105  	int value=CPU_PEEK(mOperand);\
106  	if(mD)\
107  	{\
108  		int c = mC?1:0;\
109  		int lo = (mA & 0x0f) + (value & 0x0f) + c;\
110  		int hi = (mA & 0xf0) + (value & 0xf0);\
111  		mV=0;\
112  		mC=0;\
113  		if (lo > 0x09)\
114  	    {\
115  		    hi += 0x10;\
116  			lo += 0x06;\
117  	    }\
118  		if (~(mA^value) & (mA^hi) & 0x80) mV=1;\
119  	    if (hi > 0x90) hi += 0x60;\
120  		if (hi & 0xff00) mC=1;\
121  		mA = (lo & 0x0f) + (hi & 0xf0);\
122  	}\
123  	else\
124  	{\
125  		int c = mC?1:0;\
126  		int sum = mA + value + c;\
127  	    mV=0;\
128  		mC=0;\
129  	    if (~(mA^value) & (mA^sum) & 0x80) mV=1;\
130  		if (sum & 0xff00) mC=1;\
131  	    mA = (UBYTE) sum;\
132  	}\
133  	SET_NZ(mA)\
134  }
135  
136  #define xAND()\
137  {\
138  	mA&=CPU_PEEK(mOperand);\
139  	SET_NZ(mA);\
140  }
141  
142  #define xASL()\
143  {\
144  	int value=CPU_PEEK(mOperand);\
145  	mC=value&0x80;\
146  	value<<=1;\
147  	value&=0xff;\
148  	SET_NZ(value);\
149  	CPU_POKE(mOperand,value);\
150  }
151  
152  #define xASLA()\
153  {\
154  	mC=mA&0x80;\
155  	mA<<=1;\
156  	mA&=0xff;\
157  	SET_NZ(mA);\
158  }
159  
160  #define xBCC()\
161  {\
162  	if(!mC)\
163  	{\
164  		int offset=(signed char)CPU_PEEK(mPC);\
165  		mPC++;\
166  		mPC+=offset;\
167  		mPC&=0xffff;\
168  	}\
169  	else\
170  	{\
171  		mPC++;\
172  		mPC&=0xffff;\
173  	}\
174  }
175  
176  #define	xBCS()\
177  {\
178  	if(mC)\
179  	{\
180  		int offset=(signed char)CPU_PEEK(mPC);\
181  		mPC++;\
182  		mPC+=offset;\
183  		mPC&=0xffff;\
184  	}\
185  	else\
186  	{\
187  		mPC++;\
188  		mPC&=0xffff;\
189  	}\
190  }
191  
192  #define	xBEQ()\
193  {\
194  	if(mZ)\
195  	{\
196  		int offset=(signed char)CPU_PEEK(mPC);\
197  		mPC++;\
198  		mPC+=offset;\
199  		mPC&=0xffff;\
200  	}\
201  	else\
202  	{\
203  		mPC++;\
204  		mPC&=0xffff;\
205  	}\
206  }
207  
208  // This version of bit, not setting N and V status flags in immediate, seems to be correct.
209  // The same behaviour is reported on the 65C02 used in old Apple computers, at least.
210  // (From a pragmatic sense, using the normal version of bit for immediate
211  // mode breaks the title screen of "California Games" in a subtle way.)
212  #define	xBIT()\
213  {\
214  	int value=CPU_PEEK(mOperand);\
215  	SET_Z(mA&value);\
216  \
217  	if(mOpcode!=0x89)\
218  	{\
219  		mN=value&0x80;\
220  		mV=value&0x40;\
221  	}\
222  }
223  
224  //
225  // DONT USE THIS VERSION OF BIT, IT BREAKS CALGAMES TITLE SCREEN !!!!
226  //
227  /*
228  #define	xBIT()\
229  {\
230  	int value=CPU_PEEK(mOperand);\
231  	SET_Z(mA&value);\
232  	mN=value&0x80;\
233  	mV=value&0x40;\
234  }
235  */
236  
237  #define	xBMI()\
238  {\
239  	if(mN)\
240  	{\
241  		int offset=(signed char)CPU_PEEK(mPC);\
242  		mPC++;\
243  		mPC+=offset;\
244  		mPC&=0xffff;\
245  	}\
246  	else\
247  	{\
248  		mPC++;\
249  		mPC&=0xffff;\
250  	}\
251  }
252  
253  #define	xBNE()\
254  {\
255  	if(!mZ)\
256  	{\
257  		int offset=(signed char)CPU_PEEK(mPC);\
258  		mPC++;\
259  		mPC+=offset;\
260  		mPC&=0xffff;\
261  	}\
262  	else\
263  	{\
264  		mPC++;\
265  		mPC&=0xffff;\
266  	}\
267  }
268  
269  #define	xBPL()\
270  {\
271  	if(!mN)\
272  	{\
273  		int offset=(signed char)CPU_PEEK(mPC);\
274  		mPC++;\
275  		mPC+=offset;\
276  		mPC&=0xffff;\
277  	}\
278  	else\
279  	{\
280  		mPC++;\
281  		mPC&=0xffff;\
282  	}\
283  }
284  
285  #define	xBRA()\
286  {\
287  	int offset=(signed char)CPU_PEEK(mPC);\
288  	mPC++;\
289  	mPC+=offset;\
290  	mPC&=0xffff;\
291  }
292  
293  /*
294  #define	xBRK()\
295  {\
296  	mPC++;\
297      PUSH(mPC>>8);\
298  	PUSH(mPC&0xff);\
299  	PUSH(PS()|0x10);\
300  	mD=FALSE;\
301  	mI=TRUE;\
302  	mPC=CPU_PEEKW(IRQ_VECTOR);\
303  }
304  */
305  
306  #define	xBRK()\
307  {\
308  	mPC++;\
309      PUSH(mPC>>8);\
310  	PUSH(mPC&0xff);\
311  	PUSH(PS()|0x10);\
312  \
313  	mD=FALSE;\
314  	mI=TRUE;\
315  \
316  	mPC=CPU_PEEKW(IRQ_VECTOR);\
317  }
318  // KW 4/11/98 B flag needed to be set IN the stack status word = 0x10.
319  
320  #define	xBVC()\
321  {\
322  	if(!mV)\
323  	{\
324  		int offset=(signed char)CPU_PEEK(mPC);\
325  		mPC++;\
326  		mPC+=offset;\
327  		mPC&=0xffff;\
328  	}\
329  	else\
330  	{\
331  		mPC++;\
332  		mPC&=0xffff;\
333  	}\
334  }
335  
336  #define	xBVS()\
337  {\
338  	if(mV)\
339  	{\
340  		int offset=(signed char)CPU_PEEK(mPC);\
341  		mPC++;\
342  		mPC+=offset;\
343  		mPC&=0xffff;\
344  	}\
345  	else\
346  	{\
347  		mPC++;\
348  		mPC&=0xffff;\
349  	}\
350  }
351  
352  #define	xCLC()\
353  {\
354  	mC=FALSE;\
355  }
356  
357  #define	xCLD()\
358  {\
359  	mD=FALSE;\
360  }
361  
362  #define	xCLI()\
363  {\
364  	mI=FALSE;\
365  }
366  
367  #define	xCLV()\
368  {\
369  	mV=FALSE;\
370  }
371  
372  //
373  // Alternate CMP code
374  //
375  /*
376  #define	xCMP()\
377  {\
378  	UBYTE value=CPU_PEEK(mOperand);\
379  	if(mA+0x100-value>0xff) mC=TRUE; else mC=FALSE;\
380  	value=mA+0x100-value;\
381  	mZ=!value;\
382  	mN=value&0x0080;\
383  }
384  
385  #define	xCPX()\
386  {\
387  	UBYTE value=CPU_PEEK(mOperand);\
388  	if(mX+0x100-value>0xff) mC=TRUE; else mC=FALSE;\
389  	value=mX+0x100-value;\
390  	mZ=!value;\
391  	mN=value&0x0080;\
392  }
393  
394  #define	xCPY()\
395  {\
396  	UBYTE value=CPU_PEEK(mOperand);\
397  	if(mY+0x100-value>0xff) mC=TRUE; else mC=FALSE;\
398  	value=mY+0x100-value;\
399  	mZ=!value;\
400  	mN=value&0x0080;\
401  }
402  
403  #define	xCMP()\
404  {\
405  	UWORD value=(UWORD)mA-CPU_PEEK(mOperand);\
406  	SET_NZ(value);\
407  	mC=!(value&0x0100);\
408  }
409  
410  #define	xCPX()\
411  {\
412  	UWORD value=(UWORD)mX-CPU_PEEK(mOperand);\
413  	SET_NZ(value);\
414  	mC=!(value&0x0100);\
415  }
416  
417  #define	xCPY()\
418  {\
419  	UWORD value=(UWORD)mY-CPU_PEEK(mOperand);\
420  	SET_NZ(value);\
421  	mC=!(value&0x0100);\
422  }
423  */
424  
425  #define	xCMP()\
426  {\
427  	int value=CPU_PEEK(mOperand);\
428  	mC=0;\
429  	if (mA >= value) mC=1;\
430  	SET_NZ((UBYTE)(mA - value))\
431  }
432  
433  #define	xCPX()\
434  {\
435  	int value=CPU_PEEK(mOperand);\
436  	mC=0;\
437  	if (mX >= value) mC=1;\
438  	SET_NZ((UBYTE)(mX - value))\
439  }
440  
441  #define	xCPY()\
442  {\
443  	int value=CPU_PEEK(mOperand);\
444  	mC=0;\
445  	if (mY >= value) mC=1;\
446  	SET_NZ((UBYTE)(mY - value))\
447  }
448  
449  #define	xDEC()\
450  {\
451  	int value=CPU_PEEK(mOperand)-1;\
452  	value&=0xff;\
453  	CPU_POKE(mOperand,value);\
454  	SET_NZ(value);\
455  }
456  
457  #define	xDECA()\
458  {\
459  	mA--;\
460  	mA&=0xff;\
461  	SET_NZ(mA);\
462  }
463  
464  #define	xDEX()\
465  {\
466  	mX--;\
467  	mX&=0xff;\
468  	SET_NZ(mX);\
469  }
470  
471  #define	xDEY()\
472  {\
473  	mY--;\
474  	mY&=0xff;\
475  	SET_NZ(mY);\
476  }
477  
478  #define	xEOR()\
479  {\
480  	mA^=CPU_PEEK(mOperand);\
481  	SET_NZ(mA);\
482  }
483  
484  #define	xINC()\
485  {\
486  	int value=CPU_PEEK(mOperand)+1;\
487  	value&=0xff;\
488  	CPU_POKE(mOperand,value);\
489  	SET_NZ(value);\
490  }
491  
492  #define	xINCA()\
493  {\
494  	mA++;\
495  	mA&=0xff;\
496  	SET_NZ(mA);\
497  }
498  
499  #define	xINX()\
500  {\
501  	mX++;\
502  	mX&=0xff;\
503  	SET_NZ(mX);\
504  }
505  
506  #define	xINY()\
507  {\
508  	mY++;\
509  	mY&=0xff;\
510  	SET_NZ(mY);\
511  }
512  
513  #define	xJMP()\
514  {\
515  	mPC=mOperand;\
516  }
517  
518  #define	xJSR()\
519  {\
520  	PUSH((mPC-1)>>8);\
521  	PUSH((mPC-1)&0xff);\
522  	mPC=mOperand;\
523  }
524  
525  #define	xLDA()\
526  {\
527  	mA=CPU_PEEK(mOperand);\
528  	SET_NZ(mA);\
529  }
530  
531  #define	xLDX()\
532  {\
533  	mX=CPU_PEEK(mOperand);\
534  	SET_NZ(mX);\
535  }
536  
537  #define	xLDY()\
538  {\
539  	mY=CPU_PEEK(mOperand);\
540  	SET_NZ(mY);\
541  }
542  
543  #define	xLSR()\
544  {\
545  	int value=CPU_PEEK(mOperand);\
546  	mC=value&0x01;\
547  	value=(value>>1)&0x7f;\
548  	CPU_POKE(mOperand,value);\
549  	SET_NZ(value);\
550  }
551  
552  #define	xLSRA()\
553  {\
554  	mC=mA&0x01;\
555  	mA=(mA>>1)&0x7f;\
556  	SET_NZ(mA);\
557  }
558  
559  #define	xNOP()\
560  {\
561  }
562  
563  #define	xORA()\
564  {\
565  	mA|=CPU_PEEK(mOperand);\
566  	SET_NZ(mA);\
567  }
568  
569  #define	xPHA()\
570  {\
571  	PUSH(mA);\
572  }
573  
574  #define	xPHP()\
575  {\
576  	PUSH(PS());\
577  }
578  
579  #define	xPHX()\
580  {\
581  	PUSH(mX);\
582  }
583  
584  #define	xPHY()\
585  {\
586  	PUSH(mY);\
587  }
588  
589  #define	xPLA()\
590  {\
591  	PULL(mA);\
592  	SET_NZ(mA);\
593  }
594  
595  #define	xPLP()\
596  {\
597  	int P;\
598  	PULL(P);\
599  	PS(P);\
600  }
601  
602  #define	xPLX()\
603  {\
604  	PULL(mX);\
605  	SET_NZ(mX);\
606  }
607  
608  #define	xPLY()\
609  {\
610  	PULL(mY);\
611  	SET_NZ(mY);\
612  }
613  
614  #define	xROL()\
615  {\
616  	int value=CPU_PEEK(mOperand);\
617  	int oldC=mC;\
618  	mC=value&0x80;\
619  	value=(value<<1)|(oldC?1:0);\
620  	value&=0xff;\
621  	CPU_POKE(mOperand,value);\
622  	SET_NZ(value);\
623  }
624  
625  #define	xROLA()\
626  {\
627  	int oldC=mC;\
628  	mC=mA&0x80;\
629  	mA=(mA<<1)|(oldC?1:0);\
630  	mA&=0xff;\
631  	SET_NZ(mA);\
632  }
633  
634  #define	xROR()\
635  {\
636  	int value=CPU_PEEK(mOperand);\
637  	int oldC=mC;\
638  	mC=value&0x01;\
639  	value=((value>>1)&0x7f)|(oldC?0x80:0x00);\
640  	value&=0xff;\
641  	CPU_POKE(mOperand,value);\
642  	SET_NZ(value);\
643  }
644  
645  #define	xRORA()\
646  {\
647  	int oldC=mC;\
648  	mC=mA&0x01;\
649  	mA=((mA>>1)&0x7f)|(oldC?0x80:0x00);\
650  	mA&=0xff;\
651  	SET_NZ(mA);\
652  }
653  
654  #define	xRTI()\
655  {\
656  	int tmp;\
657  	PULL(tmp);\
658  	PS(tmp);\
659  	PULL(mPC);\
660  	PULL(tmp);\
661  	mPC|=tmp<<8;\
662  }
663  
664  #define	xRTS()\
665  {\
666  	int tmp;\
667  	PULL(mPC);\
668  	PULL(tmp);\
669  	mPC|=tmp<<8;\
670  	mPC++;\
671  }
672  
673  /*
674  #define	xSBC()\
675  {\
676  	UBYTE oldA=mA;\
677  	if(!mD)\
678  	{\
679  		UBYTE value=~(CPU_PEEK(mOperand));\
680  		SWORD difference=(SWORD)((SBYTE)mA)+(SWORD)((SBYTE)value)+(mC?1:0);\
681  		mV=((difference>127)||(difference<-128));\
682  		difference=((SWORD)mA)+((SWORD)value)+ (mC?1:0);\
683  		mA=(UBYTE)difference;\
684  		mC=(difference>0xff);\
685  		SET_NZ(mA);\
686  	}\
687  	else\
688  	{\
689  		UBYTE value=CPU_PEEK(mOperand);\
690  		SWORD difference=mBCDTable[0][mA]-mBCDTable[0][value]-(mC?0:1);\
691  		if(difference<0) difference+=100;\
692  		mA=mBCDTable[1][difference];\
693  		mC=(oldA>=(value+(mC?0:1)));\
694  		mV=((oldA^mA)&0x80)&&((mA^value)&0x80);\
695  		SET_NZ(mA);\
696  	}\
697  }
698  */
699  
700  #define	xSBC()\
701  {\
702  	int value=CPU_PEEK(mOperand);\
703  	if (mD)\
704  	{\
705  		int c = mC?0:1;\
706  		int sum = mA - value - c;\
707  		int lo = (mA & 0x0f) - (value & 0x0f) - c;\
708  		int hi = (mA & 0xf0) - (value & 0xf0);\
709  	    mV=0;\
710  		mC=0;\
711  	    if ((mA^value) & (mA^sum) & 0x80) mV=1;\
712  	    if (lo & 0xf0) lo -= 6;\
713  	    if (lo & 0x80) hi -= 0x10;\
714  	    if (hi & 0x0f00) hi -= 0x60;\
715  	    if ((sum & 0xff00) == 0) mC=1;\
716  	    mA = (lo & 0x0f) + (hi & 0xf0);\
717  	}\
718  	else\
719  	{\
720  		int c = mC?0:1;\
721  		int sum = mA - value - c;\
722  	    mV=0;\
723  		mC=0;\
724  	    if ((mA^value) & (mA^sum) & 0x80) mV=1;\
725  	    if ((sum & 0xff00) == 0) mC=1;\
726  	    mA = (UBYTE) sum;\
727  	}\
728  	SET_NZ(mA)\
729  }
730  
731  #define	xSEC()\
732  {\
733  	mC=true;\
734  }
735  
736  #define	xSED()\
737  {\
738  	mD=true;\
739  }
740  
741  #define	xSEI()\
742  {\
743  	mI=true;\
744  }
745  
746  #define	xSTA()\
747  {\
748  	CPU_POKE(mOperand,mA);\
749  }
750  
751  #define	xSTP()\
752  {\
753  	gSystemCPUSleep=TRUE;\
754  }
755  
756  #define	xSTX()\
757  {\
758  	CPU_POKE(mOperand,mX);\
759  }
760  
761  #define	xSTY()\
762  {\
763  	CPU_POKE(mOperand,mY);\
764  }
765  
766  #define	xSTZ()\
767  {\
768  	CPU_POKE(mOperand,0);\
769  }
770  
771  #define	xTAX()\
772  {\
773  	mX=mA;\
774  	SET_NZ(mX);\
775  }
776  
777  #define	xTAY()\
778  {\
779  	mY=mA;\
780  	SET_NZ(mY);\
781  }
782  
783  #define	xTRB()\
784  {\
785  	int value=CPU_PEEK(mOperand);\
786  	SET_Z(mA&value);\
787  	value=value&(mA^0xff);\
788  	CPU_POKE(mOperand,value);\
789  }
790  //
791  // THE COMMENTED OUT CODE IS DERIVED FROM THE MAME 65C02 MODEL AND
792  // LOOKS TO BE INCORRECT i.e When plugged into Handy things stop working
793  //
794  /*
795  #define	xTRB()\
796  {\
797  	int value=CPU_PEEK(mOperand);\
798  	value &= ~mA;\
799  	SET_NZ(value);\
800  	CPU_POKE(mOperand,value);\
801  }
802  */
803  #define	xTSB()\
804  {\
805  	int value=CPU_PEEK(mOperand);\
806  	SET_Z(mA&value);\
807  	value=value|mA;\
808  	CPU_POKE(mOperand,value);\
809  }
810  //
811  // THE COMMENTED OUT CODE IS DERIVED FROM THE MAME 65C02 MODEL AND
812  // LOOKS TO BE INCORRECT i.e When plugged into Handy things stop working
813  //
814  /*
815  #define	xTSB()\
816  {\
817  	int value=CPU_PEEK(mOperand);\
818  	value |= mA;\
819  	SET_NZ(value);\
820  	CPU_POKE(mOperand,value);\
821  }
822  */
823  
824  #define	xTSX()\
825  {\
826  	mX=mSP;\
827  	SET_NZ(mX);\
828  }
829  
830  #define	xTXA()\
831  {\
832  	mA=mX;\
833  	SET_NZ(mA);\
834  }
835  
836  #define	xTXS()\
837  {\
838  	mSP=mX;\
839  }
840  
841  #define	xTYA()\
842  {\
843  	mA=mY;\
844  	SET_NZ(mA);\
845  }
846  
847  #define	xWAI()\
848  {\
849  	gSystemCPUSleep=TRUE;\
850  }
851