MCUME/MCUME_teensy41/teensyhandy/c6502mak.h

852 wiersze
14 KiB
C

//
// Copyright (c) 2004 K. Wilkins
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from
// the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
//////////////////////////////////////////////////////////////////////////////
// Handy - An Atari Lynx Emulator //
// Copyright (c) 1996,1997 //
// K. Wilkins //
//////////////////////////////////////////////////////////////////////////////
// 65C02 Macro definitions //
//////////////////////////////////////////////////////////////////////////////
// //
// This file contains all of the required address mode and operand //
// macro definitions for the 65C02 emulation //
// //
// K. Wilkins //
// August 1997 //
// //
//////////////////////////////////////////////////////////////////////////////
// Revision History: //
// ----------------- //
// //
// 01Aug1997 KW Document header added & class documented. //
// //
//////////////////////////////////////////////////////////////////////////////
//
// Addressing mode decoding
//
#define xIMMEDIATE() {mOperand=mPC;mPC++;}
#define xABSOLUTE() {mOperand=CPU_PEEKW(mPC);mPC+=2;}
#define xZEROPAGE() {mOperand=CPU_PEEK_RAM(mPC);mPC++;}
#define xZEROPAGE_X() {mOperand=CPU_PEEK_RAM(mPC)+mX;mPC++;mOperand&=0xff;}
#define xZEROPAGE_Y() {mOperand=CPU_PEEK_RAM(mPC)+mY;mPC++;mOperand&=0xff;}
#define xABSOLUTE_X() {mOperand=CPU_PEEKW(mPC);mPC+=2;mOperand+=mX;mOperand&=0xffff;}
#define xABSOLUTE_Y() {mOperand=CPU_PEEKW(mPC);mPC+=2;mOperand+=mY;mOperand&=0xffff;}
#define xINDIRECT_ABSOLUTE_X() {mOperand=CPU_PEEKW(mPC);mPC+=2;mOperand+=mX;mOperand&=0xffff;mOperand=CPU_PEEKW(mOperand);}
#define xRELATIVE() {mOperand=CPU_PEEK(mPC);mPC++;mOperand=(mPC+mOperand)&0xffff;}
#define xINDIRECT_X() {mOperand=CPU_PEEK(mPC);mPC++;mOperand=mOperand+mX;mOperand&=0x00ff;mOperand=CPU_PEEKW(mOperand);}
#define xINDIRECT_Y() {mOperand=CPU_PEEK(mPC);mPC++;mOperand=CPU_PEEKW(mOperand);mOperand=mOperand+mY;mOperand&=0xffff;}
#define xINDIRECT_ABSOLUTE() {mOperand=CPU_PEEKW(mPC);mPC+=2;mOperand=CPU_PEEKW(mOperand);}
#define xINDIRECT() {mOperand=CPU_PEEK(mPC);mPC++;mOperand=CPU_PEEKW(mOperand);}
//
// Helper Macros
//
//#define SET_Z(m) { mZ=(m)?false:true; }
//#define SET_N(m) { mN=(m&0x80)?true:false; }
//#define SET_NZ(m) SET_Z(m) SET_N(m)
#define SET_Z(m) { mZ=!(m); }
#define SET_N(m) { mN=(m)&0x80; }
#define SET_NZ(m) { mZ=!(m); mN=(m)&0x80; }
#define PULL(m) { mSP++; mSP&=0xff; m=CPU_PEEK_RAM(mSP+0x0100); }
#define PUSH(m) { CPU_POKE_RAM(0x0100+mSP,m); mSP--; mSP&=0xff; }
//
// Opcode execution
//
/*
#define xADC()\
{\
UBYTE value=CPU_PEEK(mOperand);\
UBYTE oldA=mA;\
if(!mD)\
{\
SWORD sum=(SWORD)((SBYTE)mA)+(SWORD)((SBYTE)value)+(mC?1:0);\
mV=((sum > 127) || (sum < -128));\
sum=(SWORD)mA + (SWORD)value + (mC?1:0);\
mA=(UBYTE)sum;\
mC=(sum>0xff);\
SET_NZ(mA);\
}\
else\
{\
SWORD sum=mBCDTable[0][mA]+mBCDTable[0][value]+(mC?1:0);\
mC=(sum > 99);\
mA=mBCDTable[1][sum & 0xff];\
SET_NZ(mA);\
mV=((oldA^mA)&0x80) && ((mA^value)&0x80);\
}\
}
*/
#define xADC()\
{\
int value=CPU_PEEK(mOperand);\
if(mD)\
{\
int c = mC?1:0;\
int lo = (mA & 0x0f) + (value & 0x0f) + c;\
int hi = (mA & 0xf0) + (value & 0xf0);\
mV=0;\
mC=0;\
if (lo > 0x09)\
{\
hi += 0x10;\
lo += 0x06;\
}\
if (~(mA^value) & (mA^hi) & 0x80) mV=1;\
if (hi > 0x90) hi += 0x60;\
if (hi & 0xff00) mC=1;\
mA = (lo & 0x0f) + (hi & 0xf0);\
}\
else\
{\
int c = mC?1:0;\
int sum = mA + value + c;\
mV=0;\
mC=0;\
if (~(mA^value) & (mA^sum) & 0x80) mV=1;\
if (sum & 0xff00) mC=1;\
mA = (UBYTE) sum;\
}\
SET_NZ(mA)\
}
#define xAND()\
{\
mA&=CPU_PEEK(mOperand);\
SET_NZ(mA);\
}
#define xASL()\
{\
int value=CPU_PEEK(mOperand);\
mC=value&0x80;\
value<<=1;\
value&=0xff;\
SET_NZ(value);\
CPU_POKE(mOperand,value);\
}
#define xASLA()\
{\
mC=mA&0x80;\
mA<<=1;\
mA&=0xff;\
SET_NZ(mA);\
}
#define xBCC()\
{\
if(!mC)\
{\
int offset=(signed char)CPU_PEEK(mPC);\
mPC++;\
mPC+=offset;\
mPC&=0xffff;\
}\
else\
{\
mPC++;\
mPC&=0xffff;\
}\
}
#define xBCS()\
{\
if(mC)\
{\
int offset=(signed char)CPU_PEEK(mPC);\
mPC++;\
mPC+=offset;\
mPC&=0xffff;\
}\
else\
{\
mPC++;\
mPC&=0xffff;\
}\
}
#define xBEQ()\
{\
if(mZ)\
{\
int offset=(signed char)CPU_PEEK(mPC);\
mPC++;\
mPC+=offset;\
mPC&=0xffff;\
}\
else\
{\
mPC++;\
mPC&=0xffff;\
}\
}
// This version of bit, not setting N and V status flags in immediate, seems to be correct.
// The same behaviour is reported on the 65C02 used in old Apple computers, at least.
// (From a pragmatic sense, using the normal version of bit for immediate
// mode breaks the title screen of "California Games" in a subtle way.)
#define xBIT()\
{\
int value=CPU_PEEK(mOperand);\
SET_Z(mA&value);\
\
if(mOpcode!=0x89)\
{\
mN=value&0x80;\
mV=value&0x40;\
}\
}
//
// DONT USE THIS VERSION OF BIT, IT BREAKS CALGAMES TITLE SCREEN !!!!
//
/*
#define xBIT()\
{\
int value=CPU_PEEK(mOperand);\
SET_Z(mA&value);\
mN=value&0x80;\
mV=value&0x40;\
}
*/
#define xBMI()\
{\
if(mN)\
{\
int offset=(signed char)CPU_PEEK(mPC);\
mPC++;\
mPC+=offset;\
mPC&=0xffff;\
}\
else\
{\
mPC++;\
mPC&=0xffff;\
}\
}
#define xBNE()\
{\
if(!mZ)\
{\
int offset=(signed char)CPU_PEEK(mPC);\
mPC++;\
mPC+=offset;\
mPC&=0xffff;\
}\
else\
{\
mPC++;\
mPC&=0xffff;\
}\
}
#define xBPL()\
{\
if(!mN)\
{\
int offset=(signed char)CPU_PEEK(mPC);\
mPC++;\
mPC+=offset;\
mPC&=0xffff;\
}\
else\
{\
mPC++;\
mPC&=0xffff;\
}\
}
#define xBRA()\
{\
int offset=(signed char)CPU_PEEK(mPC);\
mPC++;\
mPC+=offset;\
mPC&=0xffff;\
}
/*
#define xBRK()\
{\
mPC++;\
PUSH(mPC>>8);\
PUSH(mPC&0xff);\
PUSH(PS()|0x10);\
mD=FALSE;\
mI=TRUE;\
mPC=CPU_PEEKW(IRQ_VECTOR);\
}
*/
#define xBRK()\
{\
mPC++;\
PUSH(mPC>>8);\
PUSH(mPC&0xff);\
PUSH(PS()|0x10);\
\
mD=FALSE;\
mI=TRUE;\
\
mPC=CPU_PEEKW(IRQ_VECTOR);\
}
// KW 4/11/98 B flag needed to be set IN the stack status word = 0x10.
#define xBVC()\
{\
if(!mV)\
{\
int offset=(signed char)CPU_PEEK(mPC);\
mPC++;\
mPC+=offset;\
mPC&=0xffff;\
}\
else\
{\
mPC++;\
mPC&=0xffff;\
}\
}
#define xBVS()\
{\
if(mV)\
{\
int offset=(signed char)CPU_PEEK(mPC);\
mPC++;\
mPC+=offset;\
mPC&=0xffff;\
}\
else\
{\
mPC++;\
mPC&=0xffff;\
}\
}
#define xCLC()\
{\
mC=FALSE;\
}
#define xCLD()\
{\
mD=FALSE;\
}
#define xCLI()\
{\
mI=FALSE;\
}
#define xCLV()\
{\
mV=FALSE;\
}
//
// Alternate CMP code
//
/*
#define xCMP()\
{\
UBYTE value=CPU_PEEK(mOperand);\
if(mA+0x100-value>0xff) mC=TRUE; else mC=FALSE;\
value=mA+0x100-value;\
mZ=!value;\
mN=value&0x0080;\
}
#define xCPX()\
{\
UBYTE value=CPU_PEEK(mOperand);\
if(mX+0x100-value>0xff) mC=TRUE; else mC=FALSE;\
value=mX+0x100-value;\
mZ=!value;\
mN=value&0x0080;\
}
#define xCPY()\
{\
UBYTE value=CPU_PEEK(mOperand);\
if(mY+0x100-value>0xff) mC=TRUE; else mC=FALSE;\
value=mY+0x100-value;\
mZ=!value;\
mN=value&0x0080;\
}
#define xCMP()\
{\
UWORD value=(UWORD)mA-CPU_PEEK(mOperand);\
SET_NZ(value);\
mC=!(value&0x0100);\
}
#define xCPX()\
{\
UWORD value=(UWORD)mX-CPU_PEEK(mOperand);\
SET_NZ(value);\
mC=!(value&0x0100);\
}
#define xCPY()\
{\
UWORD value=(UWORD)mY-CPU_PEEK(mOperand);\
SET_NZ(value);\
mC=!(value&0x0100);\
}
*/
#define xCMP()\
{\
int value=CPU_PEEK(mOperand);\
mC=0;\
if (mA >= value) mC=1;\
SET_NZ((UBYTE)(mA - value))\
}
#define xCPX()\
{\
int value=CPU_PEEK(mOperand);\
mC=0;\
if (mX >= value) mC=1;\
SET_NZ((UBYTE)(mX - value))\
}
#define xCPY()\
{\
int value=CPU_PEEK(mOperand);\
mC=0;\
if (mY >= value) mC=1;\
SET_NZ((UBYTE)(mY - value))\
}
#define xDEC()\
{\
int value=CPU_PEEK(mOperand)-1;\
value&=0xff;\
CPU_POKE(mOperand,value);\
SET_NZ(value);\
}
#define xDECA()\
{\
mA--;\
mA&=0xff;\
SET_NZ(mA);\
}
#define xDEX()\
{\
mX--;\
mX&=0xff;\
SET_NZ(mX);\
}
#define xDEY()\
{\
mY--;\
mY&=0xff;\
SET_NZ(mY);\
}
#define xEOR()\
{\
mA^=CPU_PEEK(mOperand);\
SET_NZ(mA);\
}
#define xINC()\
{\
int value=CPU_PEEK(mOperand)+1;\
value&=0xff;\
CPU_POKE(mOperand,value);\
SET_NZ(value);\
}
#define xINCA()\
{\
mA++;\
mA&=0xff;\
SET_NZ(mA);\
}
#define xINX()\
{\
mX++;\
mX&=0xff;\
SET_NZ(mX);\
}
#define xINY()\
{\
mY++;\
mY&=0xff;\
SET_NZ(mY);\
}
#define xJMP()\
{\
mPC=mOperand;\
}
#define xJSR()\
{\
PUSH((mPC-1)>>8);\
PUSH((mPC-1)&0xff);\
mPC=mOperand;\
}
#define xLDA()\
{\
mA=CPU_PEEK(mOperand);\
SET_NZ(mA);\
}
#define xLDX()\
{\
mX=CPU_PEEK(mOperand);\
SET_NZ(mX);\
}
#define xLDY()\
{\
mY=CPU_PEEK(mOperand);\
SET_NZ(mY);\
}
#define xLSR()\
{\
int value=CPU_PEEK(mOperand);\
mC=value&0x01;\
value=(value>>1)&0x7f;\
CPU_POKE(mOperand,value);\
SET_NZ(value);\
}
#define xLSRA()\
{\
mC=mA&0x01;\
mA=(mA>>1)&0x7f;\
SET_NZ(mA);\
}
#define xNOP()\
{\
}
#define xORA()\
{\
mA|=CPU_PEEK(mOperand);\
SET_NZ(mA);\
}
#define xPHA()\
{\
PUSH(mA);\
}
#define xPHP()\
{\
PUSH(PS());\
}
#define xPHX()\
{\
PUSH(mX);\
}
#define xPHY()\
{\
PUSH(mY);\
}
#define xPLA()\
{\
PULL(mA);\
SET_NZ(mA);\
}
#define xPLP()\
{\
int P;\
PULL(P);\
PS(P);\
}
#define xPLX()\
{\
PULL(mX);\
SET_NZ(mX);\
}
#define xPLY()\
{\
PULL(mY);\
SET_NZ(mY);\
}
#define xROL()\
{\
int value=CPU_PEEK(mOperand);\
int oldC=mC;\
mC=value&0x80;\
value=(value<<1)|(oldC?1:0);\
value&=0xff;\
CPU_POKE(mOperand,value);\
SET_NZ(value);\
}
#define xROLA()\
{\
int oldC=mC;\
mC=mA&0x80;\
mA=(mA<<1)|(oldC?1:0);\
mA&=0xff;\
SET_NZ(mA);\
}
#define xROR()\
{\
int value=CPU_PEEK(mOperand);\
int oldC=mC;\
mC=value&0x01;\
value=((value>>1)&0x7f)|(oldC?0x80:0x00);\
value&=0xff;\
CPU_POKE(mOperand,value);\
SET_NZ(value);\
}
#define xRORA()\
{\
int oldC=mC;\
mC=mA&0x01;\
mA=((mA>>1)&0x7f)|(oldC?0x80:0x00);\
mA&=0xff;\
SET_NZ(mA);\
}
#define xRTI()\
{\
int tmp;\
PULL(tmp);\
PS(tmp);\
PULL(mPC);\
PULL(tmp);\
mPC|=tmp<<8;\
}
#define xRTS()\
{\
int tmp;\
PULL(mPC);\
PULL(tmp);\
mPC|=tmp<<8;\
mPC++;\
}
/*
#define xSBC()\
{\
UBYTE oldA=mA;\
if(!mD)\
{\
UBYTE value=~(CPU_PEEK(mOperand));\
SWORD difference=(SWORD)((SBYTE)mA)+(SWORD)((SBYTE)value)+(mC?1:0);\
mV=((difference>127)||(difference<-128));\
difference=((SWORD)mA)+((SWORD)value)+ (mC?1:0);\
mA=(UBYTE)difference;\
mC=(difference>0xff);\
SET_NZ(mA);\
}\
else\
{\
UBYTE value=CPU_PEEK(mOperand);\
SWORD difference=mBCDTable[0][mA]-mBCDTable[0][value]-(mC?0:1);\
if(difference<0) difference+=100;\
mA=mBCDTable[1][difference];\
mC=(oldA>=(value+(mC?0:1)));\
mV=((oldA^mA)&0x80)&&((mA^value)&0x80);\
SET_NZ(mA);\
}\
}
*/
#define xSBC()\
{\
int value=CPU_PEEK(mOperand);\
if (mD)\
{\
int c = mC?0:1;\
int sum = mA - value - c;\
int lo = (mA & 0x0f) - (value & 0x0f) - c;\
int hi = (mA & 0xf0) - (value & 0xf0);\
mV=0;\
mC=0;\
if ((mA^value) & (mA^sum) & 0x80) mV=1;\
if (lo & 0xf0) lo -= 6;\
if (lo & 0x80) hi -= 0x10;\
if (hi & 0x0f00) hi -= 0x60;\
if ((sum & 0xff00) == 0) mC=1;\
mA = (lo & 0x0f) + (hi & 0xf0);\
}\
else\
{\
int c = mC?0:1;\
int sum = mA - value - c;\
mV=0;\
mC=0;\
if ((mA^value) & (mA^sum) & 0x80) mV=1;\
if ((sum & 0xff00) == 0) mC=1;\
mA = (UBYTE) sum;\
}\
SET_NZ(mA)\
}
#define xSEC()\
{\
mC=true;\
}
#define xSED()\
{\
mD=true;\
}
#define xSEI()\
{\
mI=true;\
}
#define xSTA()\
{\
CPU_POKE(mOperand,mA);\
}
#define xSTP()\
{\
gSystemCPUSleep=TRUE;\
}
#define xSTX()\
{\
CPU_POKE(mOperand,mX);\
}
#define xSTY()\
{\
CPU_POKE(mOperand,mY);\
}
#define xSTZ()\
{\
CPU_POKE(mOperand,0);\
}
#define xTAX()\
{\
mX=mA;\
SET_NZ(mX);\
}
#define xTAY()\
{\
mY=mA;\
SET_NZ(mY);\
}
#define xTRB()\
{\
int value=CPU_PEEK(mOperand);\
SET_Z(mA&value);\
value=value&(mA^0xff);\
CPU_POKE(mOperand,value);\
}
//
// THE COMMENTED OUT CODE IS DERIVED FROM THE MAME 65C02 MODEL AND
// LOOKS TO BE INCORRECT i.e When plugged into Handy things stop working
//
/*
#define xTRB()\
{\
int value=CPU_PEEK(mOperand);\
value &= ~mA;\
SET_NZ(value);\
CPU_POKE(mOperand,value);\
}
*/
#define xTSB()\
{\
int value=CPU_PEEK(mOperand);\
SET_Z(mA&value);\
value=value|mA;\
CPU_POKE(mOperand,value);\
}
//
// THE COMMENTED OUT CODE IS DERIVED FROM THE MAME 65C02 MODEL AND
// LOOKS TO BE INCORRECT i.e When plugged into Handy things stop working
//
/*
#define xTSB()\
{\
int value=CPU_PEEK(mOperand);\
value |= mA;\
SET_NZ(value);\
CPU_POKE(mOperand,value);\
}
*/
#define xTSX()\
{\
mX=mSP;\
SET_NZ(mX);\
}
#define xTXA()\
{\
mA=mX;\
SET_NZ(mA);\
}
#define xTXS()\
{\
mSP=mX;\
}
#define xTYA()\
{\
mA=mY;\
SET_NZ(mA);\
}
#define xWAI()\
{\
gSystemCPUSleep=TRUE;\
}