Remove the top-level AppleWin folder

This commit is contained in:
tomcw
2014-05-23 22:59:02 +01:00
parent bb56c46f80
commit d591dd006b
361 changed files with 0 additions and 207 deletions
+335
View File
@@ -0,0 +1,335 @@
/*
AppleWin : An Apple //e emulator for Windows
Copyright (C) 1994-1996, Michael O'Brien
Copyright (C) 1999-2001, Oliver Schmidt
Copyright (C) 2002-2005, Tom Charlesworth
Copyright (C) 2006-2011, Tom Charlesworth, Michael Pohoreski
AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AppleWin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AppleWin; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//===========================================================================
static DWORD Cpu6502 (DWORD uTotalCycles)
{
WORD addr;
BOOL flagc; // must always be 0 or 1, no other values allowed
BOOL flagn; // must always be 0 or 0x80.
BOOL flagv; // any value allowed
BOOL flagz; // any value allowed
WORD temp;
WORD temp2;
WORD val;
AF_TO_EF
ULONG uExecutedCycles = 0;
BOOL bSlowerOnPagecross = 0; // Set if opcode writes to memory (eg. ASL, STA)
WORD base;
g_bDebugBreakpointHit = 0;
do
{
UINT uExtraCycles = 0;
BYTE iOpcode;
if (g_ActiveCPU == CPU_Z80)
{
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
}
else
{
if (!Fetch(iOpcode, uExecutedCycles))
break;
#define $ INV // INV = Invalid -> Debugger Break
switch (iOpcode)
{
case 0x00: BRK CYC(7) break;
case 0x01: idx ORA CYC(6) break;
case 0x02: $ HLT CYC(2) break;
case 0x03: $ idx ASO CYC(8) break;
case 0x04: $ ZPG NOP CYC(3) break;
case 0x05: ZPG ORA CYC(3) break;
case 0x06: ZPG ASLn CYC(5) break;
case 0x07: $ ZPG ASO CYC(5) break; // invalid
case 0x08: PHP CYC(3) break;
case 0x09: IMM ORA CYC(2) break;
case 0x0A: asl CYC(2) break;
case 0x0B: $ IMM ANC CYC(2) break; // invald
case 0x0C: $ abx NOP CYC(4) break;
case 0x0D: ABS ORA CYC(4) break;
case 0x0E: ABS ASLn CYC(6) break;
case 0x0F: $ ABS ASO CYC(6) break; // invalid
case 0x10: REL BPL CYC(2) break;
case 0x11: idy ORA CYC(5) break;
case 0x12: $ HLT CYC(2) break;
case 0x13: $ idy ASO CYC(8) break; // invalid
case 0x14: $ zpx NOP CYC(4) break;
case 0x15: zpx ORA CYC(4) break;
case 0x16: zpx ASLn CYC(6) break;
case 0x17: $ zpx ASO CYC(6) break; // invalid
case 0x18: CLC CYC(2) break;
case 0x19: aby ORA CYC(4) break;
case 0x1A: $ NOP CYC(2) break;
case 0x1B: $ aby ASO CYC(7) break; // invalid
case 0x1C: $ abx NOP CYC(4) break;
case 0x1D: abx ORA CYC(4) break;
case 0x1E: abx ASLn CYC(6) break;
case 0x1F: $ abx ASO CYC(7) break; // invalid
case 0x20: ABS JSR CYC(6) break;
case 0x21: idx AND CYC(6) break;
case 0x22: $ HLT CYC(2) break;
case 0x23: $ idx RLA CYC(8) break;
case 0x24: ZPG BIT CYC(3) break;
case 0x25: ZPG AND CYC(3) break;
case 0x26: ZPG ROLn CYC(5) break;
case 0x27: $ ZPG RLA CYC(5) break;
case 0x28: PLP CYC(4) break;
case 0x29: IMM AND CYC(2) break;
case 0x2A: rol CYC(2) break;
case 0x2B: $ IMM ANC CYC(2) break; // invalid
case 0x2C: ABS BIT CYC(4) break;
case 0x2D: ABS AND CYC(2) break;
case 0x2E: ABS ROLn CYC(6) break;
case 0x2F: $ ABS RLA CYC(6) break;
case 0x30: REL BMI CYC(2) break;
case 0x31: idy AND CYC(5) break;
case 0x32: $ HLT CYC(2) break;
case 0x33: $ idy RLA CYC(8) break; // invalid
case 0x34: $ zpx NOP CYC(4) break;
case 0x35: zpx AND CYC(4) break;
case 0x36: zpx ROLn CYC(6) break;
case 0x37: $ zpx RLA CYC(6) break;
case 0x38: SEC CYC(2) break;
case 0x39: aby AND CYC(4) break;
case 0x3A: $ NOP CYC(2) break;
case 0x3B: $ aby RLA CYC(7) break; // invalid
case 0x3C: $ abx NOP CYC(4) break;
case 0x3D: abx AND CYC(4) break;
case 0x3E: abx ROLn CYC(6) break;
case 0x3F: $ abx RLA CYC(7) break; // invalid
case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break;
case 0x41: idx EOR CYC(6) break;
case 0x42: $ HLT CYC(2) break;
case 0x43: $ idx LSE CYC(8) break; // invalid
case 0x44: $ ZPG NOP CYC(3) break;
case 0x45: ZPG EOR CYC(3) break;
case 0x46: ZPG LSRn CYC(5) break;
case 0x47: $ ZPG LSE CYC(5) break; // invalid
case 0x48: PHA CYC(3) break;
case 0x49: IMM EOR CYC(2) break;
case 0x4A: lsr CYC(2) break;
case 0x4B: $ IMM ALR CYC(2) break; // invalid
case 0x4C: ABS JMP CYC(3) break;
case 0x4D: ABS EOR CYC(4) break;
case 0x4E: ABS LSRn CYC(6) break;
case 0x4F: $ ABS LSE CYC(6) break;
case 0x50: REL BVC CYC(2) break;
case 0x51: idy EOR CYC(5) break;
case 0x52: $ HLT CYC(2) break;
case 0x53: $ idy LSE CYC(8) break;
case 0x54: $ zpx NOP CYC(4) break;
case 0x55: zpx EOR CYC(4) break;
case 0x56: zpx LSRn CYC(6) break;
case 0x57: $ zpx LSE CYC(6) break; // invalid
case 0x58: CLI CYC(2) break;
case 0x59: aby EOR CYC(4) break;
case 0x5A: $ NOP CYC(2) break;
case 0x5B: $ aby LSE CYC(7) break; // invalid
case 0x5C: $ abx NOP CYC(4) break;
case 0x5D: abx EOR CYC(4) break;
case 0x5E: abx LSRn CYC(6) break;
case 0x5F: $ abx LSE CYC(7) break;
case 0x60: RTS CYC(6) break;
case 0x61: idx ADCn CYC(6) break;
case 0x62: $ HLT CYC(2) break;
case 0x63: $ idx RRA CYC(8) break; // invalid
case 0x64: $ ZPG NOP CYC(3) break;
case 0x65: ZPG ADCn CYC(3) break;
case 0x66: ZPG RORn CYC(5) break;
case 0x67: $ ZPG RRA CYC(5) break;
case 0x68: PLA CYC(4) break;
case 0x69: IMM ADCn CYC(2) break;
case 0x6A: ror CYC(2) break;
case 0x6B: $ IMM ARR CYC(2) break; // invalid
case 0x6C: IABSNMOS JMP CYC(6) break;
case 0x6D: ABS ADCn CYC(4) break;
case 0x6E: ABS RORn CYC(6) break;
case 0x6F: $ ABS RRA CYC(6) break; // invalid
case 0x70: REL BVS CYC(2) break;
case 0x71: idy ADCn CYC(5) break;
case 0x72: $ HLT CYC(2) break;
case 0x73: $ idy RRA CYC(8) break; // invalid
case 0x74: $ zpx NOP CYC(4) break;
case 0x75: zpx ADCn CYC(4) break;
case 0x76: zpx RORn CYC(6) break;
case 0x77: $ zpx RRA CYC(6) break; // invalid
case 0x78: SEI CYC(2) break;
case 0x79: aby ADCn CYC(4) break;
case 0x7A: $ NOP CYC(2) break;
case 0x7B: $ aby RRA CYC(7) break; // invalid
case 0x7C: $ abx NOP CYC(4) break;
case 0x7D: abx ADCn CYC(4) break;
case 0x7E: abx RORn CYC(6) break;
case 0x7F: $ abx RRA CYC(7) break; // invalid
case 0x80: $ IMM NOP CYC(2) break;
case 0x81: idx STA CYC(6) break;
case 0x82: $ IMM NOP CYC(2) break;
case 0x83: $ idx AXS CYC(6) break; // invalid
case 0x84: ZPG STY CYC(3) break;
case 0x85: ZPG STA CYC(3) break;
case 0x86: ZPG STX CYC(3) break;
case 0x87: $ ZPG AXS CYC(3) break; // invalid
case 0x88: DEY CYC(2) break;
case 0x89: $ IMM NOP CYC(2) break;
case 0x8A: TXA CYC(2) break;
case 0x8B: $ IMM XAA CYC(2) break; // invalid
case 0x8C: ABS STY CYC(4) break;
case 0x8D: ABS STA CYC(4) break;
case 0x8E: ABS STX CYC(4) break;
case 0x8F: $ ABS AXS CYC(4) break; // invalid
case 0x90: REL BCC CYC(2) break;
case 0x91: idy STA CYC(6) break;
case 0x92: $ HLT CYC(2) break;
case 0x93: $ idy AXA CYC(6) break; // invalid
case 0x94: zpx STY CYC(4) break;
case 0x95: zpx STA CYC(4) break;
case 0x96: zpy STX CYC(4) break;
case 0x97: $ zpy AXS CYC(4) break; // invalid
case 0x98: TYA CYC(2) break;
case 0x99: aby STA CYC(5) break;
case 0x9A: TXS CYC(2) break;
case 0x9B: $ aby TAS CYC(5) break; // invalid
case 0x9C: $ abx SAY CYC(5) break; // invalid
case 0x9D: abx STA CYC(5) break;
case 0x9E: $ aby XAS CYC(5) break;
case 0x9F: $ aby AXA CYC(5) break;
case 0xA0: IMM LDY CYC(2) break;
case 0xA1: idx LDA CYC(6) break;
case 0xA2: IMM LDX CYC(2) break;
case 0xA3: $ idx LAX CYC(6) break; // invalid
case 0xA4: ZPG LDY CYC(3) break;
case 0xA5: ZPG LDA CYC(3) break;
case 0xA6: ZPG LDX CYC(3) break;
case 0xA7: $ ZPG LAX CYC(3) break; // invalid
case 0xA8: TAY CYC(2) break;
case 0xA9: IMM LDA CYC(2) break;
case 0xAA: TAX CYC(2) break;
case 0xAB: $ IMM OAL CYC(2) break; // invalid
case 0xAC: ABS LDY CYC(4) break;
case 0xAD: ABS LDA CYC(4) break;
case 0xAE: ABS LDX CYC(4) break;
case 0xAF: $ ABS LAX CYC(4) break; // invalid
case 0xB0: REL BCS CYC(2) break;
case 0xB1: idy LDA CYC(5) break;
case 0xB2: $ HLT CYC(2) break;
case 0xB3: $ idy LAX CYC(5) break;
case 0xB4: zpx LDY CYC(4) break;
case 0xB5: zpx LDA CYC(4) break;
case 0xB6: zpy LDX CYC(4) break;
case 0xB7: $ zpy LAX CYC(4) break; // invalid
case 0xB8: CLV CYC(2) break;
case 0xB9: aby LDA CYC(4) break;
case 0xBA: TSX CYC(2) break;
case 0xBB: $ aby LAS CYC(4) break; // invalid
case 0xBC: abx LDY CYC(4) break;
case 0xBD: abx LDA CYC(4) break;
case 0xBE: aby LDX CYC(4) break;
case 0xBF: $ aby LAX CYC(4) break; // invalid
case 0xC0: IMM CPY CYC(2) break;
case 0xC1: idx CMP CYC(6) break;
case 0xC2: $ IMM NOP CYC(2) break;
case 0xC3: $ idx DCM CYC(8) break; // invalid
case 0xC4: ZPG CPY CYC(3) break;
case 0xC5: ZPG CMP CYC(3) break;
case 0xC6: ZPG DECn CYC(5) break;
case 0xC7: $ ZPG DCM CYC(5) break; // invalid
case 0xC8: INY CYC(2) break;
case 0xC9: IMM CMP CYC(2) break;
case 0xCA: DEX CYC(2) break;
case 0xCB: $ IMM SAX CYC(2) break; // invalid
case 0xCC: ABS CPY CYC(4) break;
case 0xCD: ABS CMP CYC(4) break;
case 0xCE: ABS DECn CYC(5) break;
case 0xCF: $ ABS DCM CYC(6) break; // invalid
case 0xD0: REL BNE CYC(2) break;
case 0xD1: idy CMP CYC(5) break;
case 0xD2: $ HLT CYC(2) break;
case 0xD3: $ idy DCM CYC(8) break; // invalid
case 0xD4: $ zpx NOP CYC(4) break;
case 0xD5: zpx CMP CYC(4) break;
case 0xD6: zpx DECn CYC(6) break;
case 0xD7: $ zpx DCM CYC(6) break; // invalid
case 0xD8: CLD CYC(2) break;
case 0xD9: aby CMP CYC(4) break;
case 0xDA: $ NOP CYC(2) break;
case 0xDB: $ aby DCM CYC(7) break; // invalid
case 0xDC: $ abx NOP CYC(4) break;
case 0xDD: abx CMP CYC(4) break;
case 0xDE: abx DECn CYC(6) break;
case 0xDF: $ abx DCM CYC(7) break; // invalid
case 0xE0: IMM CPX CYC(2) break;
case 0xE1: idx SBCn CYC(6) break;
case 0xE2: $ IMM NOP CYC(2) break;
case 0xE3: $ idx INS CYC(8) break; // invalid
case 0xE4: ZPG CPX CYC(3) break;
case 0xE5: ZPG SBCn CYC(3) break;
case 0xE6: ZPG INCn CYC(5) break;
case 0xE7: $ ZPG INS CYC(5) break; // invalid
case 0xE8: INX CYC(2) break;
case 0xE9: IMM SBCn CYC(2) break;
case 0xEA: NOP CYC(2) break;
case 0xEB: $ IMM SBCn CYC(2) break;
case 0xEC: ABS CPX CYC(4) break;
case 0xED: ABS SBCn CYC(4) break;
case 0xEE: ABS INCn CYC(6) break;
case 0xEF: $ ABS INS CYC(6) break; // invalid
case 0xF0: REL BEQ CYC(2) break;
case 0xF1: idy SBCn CYC(5) break;
case 0xF2: $ HLT CYC(2) break;
case 0xF3: $ idy INS CYC(8) break; // invalid
case 0xF4: $ zpx NOP CYC(4) break;
case 0xF5: zpx SBCn CYC(4) break;
case 0xF6: zpx INCn CYC(6) break;
case 0xF7: $ zpx INS CYC(6) break; // invalid
case 0xF8: SED CYC(2) break;
case 0xF9: aby SBCn CYC(4) break;
case 0xFA: $ NOP CYC(2) break;
case 0xFB: $ aby INS CYC(7) break;
case 0xFC: $ abx NOP CYC(4) break;
case 0xFD: abx SBCn CYC(4) break;
case 0xFE: abx INCn CYC(6) break;
case 0xFF: $ abx INS CYC(7) break;
}
}
CheckInterruptSources(uExecutedCycles);
NMI(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
IRQ(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
if ( IsDebugBreakpointHit() )
break;
} while (uExecutedCycles < uTotalCycles);
EF_TO_AF
if( g_bDebugBreakpointHit )
if ((g_nAppMode != MODE_DEBUG) && (g_nAppMode != MODE_STEPPING)) // Running at full speed? (debugger not running)
RequestDebugger();
return uExecutedCycles;
}
//===========================================================================
+340
View File
@@ -0,0 +1,340 @@
/*
AppleWin : An Apple //e emulator for Windows
Copyright (C) 1994-1996, Michael O'Brien
Copyright (C) 1999-2001, Oliver Schmidt
Copyright (C) 2002-2005, Tom Charlesworth
Copyright (C) 2006-2011, Tom Charlesworth, Michael Pohoreski
AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AppleWin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AppleWin; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//===========================================================================
static DWORD Cpu65C02 (DWORD uTotalCycles)
{
// Optimisation:
// . Copy the global /regs/ vars to stack-based local vars
// (Oliver Schmidt says this gives a performance gain, see email - The real deal: "1.10.5")
WORD addr;
BOOL flagc; // must always be 0 or 1, no other values allowed
BOOL flagn; // must always be 0 or 0x80.
BOOL flagv; // any value allowed
BOOL flagz; // any value allowed
WORD temp;
WORD temp2;
WORD val;
AF_TO_EF
ULONG uExecutedCycles = 0;
BOOL bSlowerOnPagecross = 0; // Set if opcode writes to memory (eg. ASL, STA)
WORD base;
g_bDebugBreakpointHit = 0;
do
{
UINT uExtraCycles = 0;
BYTE iOpcode;
if (g_ActiveCPU == CPU_Z80)
{
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
}
else
{
if (!Fetch(iOpcode, uExecutedCycles))
break;
switch (iOpcode)
{
#define $ INV // INV = Invalid -> Debugger Break
case 0x00: BRK CYC(7) break;
case 0x01: idx ORA CYC(6) break;
case 0x02: $ IMM NOP CYC(2) break;
case 0x03: $ NOP CYC(2) break;
case 0x04: ZPG TSB CYC(5) break;
case 0x05: ZPG ORA CYC(3) break;
case 0x06: ZPG ASLc CYC(5) break;
case 0x07: $ NOP CYC(2) break;
case 0x08: PHP CYC(3) break;
case 0x09: IMM ORA CYC(2) break;
case 0x0A: asl CYC(2) break;
case 0x0B: $ NOP CYC(2) break;
case 0x0C: ABS TSB CYC(6) break;
case 0x0D: ABS ORA CYC(4) break;
case 0x0E: ABS ASLc CYC(6) break;
case 0x0F: $ NOP CYC(2) break;
case 0x10: REL BPL CYC(2) break;
case 0x11: idy ORA CYC(5) break;
case 0x12: izp ORA CYC(5) break;
case 0x13: $ NOP CYC(2) break;
case 0x14: ZPG TRB CYC(5) break;
case 0x15: zpx ORA CYC(4) break;
case 0x16: zpx ASLc CYC(6) break;
case 0x17: $ NOP CYC(2) break;
case 0x18: CLC CYC(2) break;
case 0x19: aby ORA CYC(4) break;
case 0x1A: INA CYC(2) break;
case 0x1B: $ NOP CYC(2) break;
case 0x1C: ABS TRB CYC(6) break;
case 0x1D: abx ORA CYC(4) break;
case 0x1E: abx ASLc CYC(6) break;
case 0x1F: $ NOP CYC(2) break;
case 0x20: ABS JSR CYC(6) break;
case 0x21: idx AND CYC(6) break;
case 0x22: $ IMM NOP CYC(2) break;
case 0x23: $ NOP CYC(2) break;
case 0x24: ZPG BIT CYC(3) break;
case 0x25: ZPG AND CYC(3) break;
case 0x26: ZPG ROLc CYC(5) break;
case 0x27: $ NOP CYC(2) break;
case 0x28: PLP CYC(4) break;
case 0x29: IMM AND CYC(2) break;
case 0x2A: rol CYC(2) break;
case 0x2B: $ NOP CYC(2) break;
case 0x2C: ABS BIT CYC(4) break;
case 0x2D: ABS AND CYC(2) break;
case 0x2E: ABS ROLc CYC(6) break;
case 0x2F: $ NOP CYC(2) break;
case 0x30: REL BMI CYC(2) break;
case 0x31: idy AND CYC(5) break;
case 0x32: izp AND CYC(5) break;
case 0x33: $ NOP CYC(2) break;
case 0x34: zpx BIT CYC(4) break;
case 0x35: zpx AND CYC(4) break;
case 0x36: zpx ROLc CYC(6) break;
case 0x37: $ NOP CYC(2) break;
case 0x38: SEC CYC(2) break;
case 0x39: aby AND CYC(4) break;
case 0x3A: DEA CYC(2) break;
case 0x3B: $ NOP CYC(2) break;
case 0x3C: abx BIT CYC(4) break;
case 0x3D: abx AND CYC(4) break;
case 0x3E: abx ROLc CYC(6) break;
case 0x3F: $ NOP CYC(2) break;
case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break;
case 0x41: idx EOR CYC(6) break;
case 0x42: $ IMM NOP CYC(2) break;
case 0x43: $ NOP CYC(2) break;
case 0x44: $ ZPG NOP CYC(3) break;
case 0x45: ZPG EOR CYC(3) break;
case 0x46: ZPG LSRc CYC(5) break;
case 0x47: $ NOP CYC(2) break;
case 0x48: PHA CYC(3) break;
case 0x49: IMM EOR CYC(2) break;
case 0x4A: lsr CYC(2) break;
case 0x4B: $ NOP CYC(2) break;
case 0x4C: ABS JMP CYC(3) break;
case 0x4D: ABS EOR CYC(4) break;
case 0x4E: ABS LSRc CYC(6) break;
case 0x4F: $ NOP CYC(2) break;
case 0x50: REL BVC CYC(2) break;
case 0x51: idy EOR CYC(5) break;
case 0x52: izp EOR CYC(5) break;
case 0x53: $ NOP CYC(2) break;
case 0x54: $ zpx NOP CYC(4) break;
case 0x55: zpx EOR CYC(4) break;
case 0x56: zpx LSRc CYC(6) break;
case 0x57: $ NOP CYC(2) break;
case 0x58: CLI CYC(2) break;
case 0x59: aby EOR CYC(4) break;
case 0x5A: PHY CYC(3) break;
case 0x5B: $ NOP CYC(2) break;
case 0x5C: $ abx NOP CYC(8) break;
case 0x5D: abx EOR CYC(4) break;
case 0x5E: abx LSRc CYC(6) break;
case 0x5F: $ NOP CYC(2) break;
case 0x60: RTS CYC(6) break;
case 0x61: idx ADCc CYC(6) break;
case 0x62: $ IMM NOP CYC(2) break;
case 0x63: $ NOP CYC(2) break;
case 0x64: ZPG STZ CYC(3) break;
case 0x65: ZPG ADCc CYC(3) break;
case 0x66: ZPG RORc CYC(5) break;
case 0x67: $ NOP CYC(2) break;
case 0x68: PLA CYC(4) break;
case 0x69: IMM ADCc CYC(2) break;
case 0x6A: ror CYC(2) break;
case 0x6B: $ NOP CYC(2) break;
case 0x6C: IABSCMOS JMP CYC(6) break;
case 0x6D: ABS ADCc CYC(4) break;
case 0x6E: ABS RORc CYC(6) break;
case 0x6F: $ NOP CYC(2) break;
case 0x70: REL BVS CYC(2) break;
case 0x71: idy ADCc CYC(5) break;
case 0x72: izp ADCc CYC(5) break;
case 0x73: $ NOP CYC(2) break;
case 0x74: zpx STZ CYC(4) break;
case 0x75: zpx ADCc CYC(4) break;
case 0x76: zpx RORc CYC(6) break;
case 0x77: $ NOP CYC(2) break;
case 0x78: SEI CYC(2) break;
case 0x79: aby ADCc CYC(4) break;
case 0x7A: PLY CYC(4) break;
case 0x7B: $ NOP CYC(2) break;
case 0x7C: IABSX JMP CYC(6) break; //
case 0x7D: abx ADCc CYC(4) break;
case 0x7E: abx RORc CYC(6) break;
case 0x7F: $ NOP CYC(2) break;
case 0x80: REL BRA CYC(2) break;
case 0x81: idx STA CYC(6) break;
case 0x82: $ IMM NOP CYC(2) break;
case 0x83: $ NOP CYC(2) break;
case 0x84: ZPG STY CYC(3) break;
case 0x85: ZPG STA CYC(3) break;
case 0x86: ZPG STX CYC(3) break;
case 0x87: $ NOP CYC(2) break;
case 0x88: DEY CYC(2) break;
case 0x89: IMM BITI CYC(2) break;
case 0x8A: TXA CYC(2) break;
case 0x8B: $ NOP CYC(2) break;
case 0x8C: ABS STY CYC(4) break;
case 0x8D: ABS STA CYC(4) break;
case 0x8E: ABS STX CYC(4) break;
case 0x8F: $ NOP CYC(2) break;
case 0x90: REL BCC CYC(2) break;
case 0x91: idy STA CYC(6) break;
case 0x92: izp STA CYC(5) break;
case 0x93: $ NOP CYC(2) break;
case 0x94: zpx STY CYC(4) break;
case 0x95: zpx STA CYC(4) break;
case 0x96: zpy STX CYC(4) break;
case 0x97: $ NOP CYC(2) break;
case 0x98: TYA CYC(2) break;
case 0x99: aby STA CYC(5) break;
case 0x9A: TXS CYC(2) break;
case 0x9B: $ NOP CYC(2) break;
case 0x9C: ABS STZ CYC(4) break;
case 0x9D: abx STA CYC(5) break;
case 0x9E: abx STZ CYC(5) break;
case 0x9F: $ NOP CYC(2) break;
case 0xA0: IMM LDY CYC(2) break;
case 0xA1: idx LDA CYC(6) break;
case 0xA2: IMM LDX CYC(2) break;
case 0xA3: $ NOP CYC(2) break;
case 0xA4: ZPG LDY CYC(3) break;
case 0xA5: ZPG LDA CYC(3) break;
case 0xA6: ZPG LDX CYC(3) break;
case 0xA7: $ NOP CYC(2) break;
case 0xA8: TAY CYC(2) break;
case 0xA9: IMM LDA CYC(2) break;
case 0xAA: TAX CYC(2) break;
case 0xAB: $ NOP CYC(2) break;
case 0xAC: ABS LDY CYC(4) break;
case 0xAD: ABS LDA CYC(4) break;
case 0xAE: ABS LDX CYC(4) break;
case 0xAF: $ NOP CYC(2) break;
case 0xB0: REL BCS CYC(2) break;
case 0xB1: idy LDA CYC(5) break;
case 0xB2: izp LDA CYC(5) break;
case 0xB3: $ NOP CYC(2) break;
case 0xB4: zpx LDY CYC(4) break;
case 0xB5: zpx LDA CYC(4) break;
case 0xB6: zpy LDX CYC(4) break;
case 0xB7: $ NOP CYC(2) break;
case 0xB8: CLV CYC(2) break;
case 0xB9: aby LDA CYC(4) break;
case 0xBA: TSX CYC(2) break;
case 0xBB: $ NOP CYC(2) break;
case 0xBC: abx LDY CYC(4) break;
case 0xBD: abx LDA CYC(4) break;
case 0xBE: aby LDX CYC(4) break;
case 0xBF: $ NOP CYC(2) break;
case 0xC0: IMM CPY CYC(2) break;
case 0xC1: idx CMP CYC(6) break;
case 0xC2: $ IMM NOP CYC(2) break;
case 0xC3: $ NOP CYC(2) break;
case 0xC4: ZPG CPY CYC(3) break;
case 0xC5: ZPG CMP CYC(3) break;
case 0xC6: ZPG DECc CYC(5) break;
case 0xC7: $ NOP CYC(2) break;
case 0xC8: INY CYC(2) break;
case 0xC9: IMM CMP CYC(2) break;
case 0xCA: DEX CYC(2) break;
case 0xCB: $ NOP CYC(2) break;
case 0xCC: ABS CPY CYC(4) break;
case 0xCD: ABS CMP CYC(4) break;
case 0xCE: ABS DECc CYC(5) break;
case 0xCF: $ NOP CYC(2) break;
case 0xD0: REL BNE CYC(2) break;
case 0xD1: idy CMP CYC(5) break;
case 0xD2: izp CMP CYC(5) break;
case 0xD3: $ NOP CYC(2) break;
case 0xD4: $ zpx NOP CYC(4) break;
case 0xD5: zpx CMP CYC(4) break;
case 0xD6: zpx DECc CYC(6) break;
case 0xD7: $ NOP CYC(2) break;
case 0xD8: CLD CYC(2) break;
case 0xD9: aby CMP CYC(4) break;
case 0xDA: PHX CYC(3) break;
case 0xDB: $ NOP CYC(2) break;
case 0xDC: $ abx NOP CYC(4) break;
case 0xDD: abx CMP CYC(4) break;
case 0xDE: abx DECc CYC(6) break;
case 0xDF: $ NOP CYC(2) break;
case 0xE0: IMM CPX CYC(2) break;
case 0xE1: idx SBCc CYC(6) break;
case 0xE2: $ IMM NOP CYC(2) break;
case 0xE3: $ NOP CYC(2) break;
case 0xE4: ZPG CPX CYC(3) break;
case 0xE5: ZPG SBCc CYC(3) break;
case 0xE6: ZPG INCc CYC(5) break;
case 0xE7: $ NOP CYC(2) break;
case 0xE8: INX CYC(2) break;
case 0xE9: IMM SBCc CYC(2) break;
case 0xEA: NOP CYC(2) break;
case 0xEB: $ NOP CYC(2) break;
case 0xEC: ABS CPX CYC(4) break;
case 0xED: ABS SBCc CYC(4) break;
case 0xEE: ABS INCc CYC(6) break;
case 0xEF: $ NOP CYC(2) break;
case 0xF0: REL BEQ CYC(2) break;
case 0xF1: idy SBCc CYC(5) break;
case 0xF2: izp SBCc CYC(5) break;
case 0xF3: $ NOP CYC(2) break;
case 0xF4: $ zpx NOP CYC(4) break;
case 0xF5: zpx SBCc CYC(4) break;
case 0xF6: zpx INCc CYC(6) break;
case 0xF7: $ NOP CYC(2) break;
case 0xF8: SED CYC(2) break;
case 0xF9: aby SBCc CYC(4) break;
case 0xFA: PLX CYC(4) break;
case 0xFB: $ NOP CYC(2) break;
case 0xFC: $ abx NOP CYC(4) break;
case 0xFD: abx SBCc CYC(4) break;
case 0xFE: abx INCc CYC(6) break;
case 0xFF: $ NOP CYC(2) break;
}
#undef $
}
CheckInterruptSources(uExecutedCycles);
NMI(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
IRQ(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
if( IsDebugBreakpointHit() )
break;
} while (uExecutedCycles < uTotalCycles);
EF_TO_AF // Emulator Flags to Apple Flags
if( g_bDebugBreakpointHit )
if ((g_nAppMode != MODE_DEBUG) && (g_nAppMode != MODE_STEPPING)) // Running at full speed? (debugger not running)
RequestDebugger();
return uExecutedCycles;
}
//===========================================================================
+667
View File
@@ -0,0 +1,667 @@
/*
AppleWin : An Apple //e emulator for Windows
Copyright (C) 2010-2011, Tom Charlesworth, Michael Pohoreski
AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AppleWin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AppleWin; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
typedef unsigned char u8;
typedef unsigned short u16;
// return (x < 255) ? (x+1) : 255;
inline u8 IncClamp8( u8 x )
{
u16 c = (~((x + 1) >> 8) & 1);
u8 r = x + c;
return r;
}
// return (x > 0) ? (x-1) : 0;
inline u8 DecClamp8( u8 x )
{
u16 c = (~((x - 1) >> 8) & 1);
u8 r = x - c;
return r;
}
// 0 A n/a
// 1 B Exec
// 2 G Read
// 3 R Write
// RGBA r= write, g = read, b = pc
int g_aMemoryAccess[ 65536 ];
u8 *g_pRead = 0;
u8 *g_pWrite = 0;
u8 *g_pExeec = 0;
#undef READ
#define READ ReadByte( addr, uExecutedCycles )
inline u8 ReadByte( u16 addr, int uExecutedCycles )
{
(u8*) g_pRead = ((u8*)g_aMemoryAccess) + (addr * 4) + 3;
*g_pRead = IncClamp8( *g_pRead );
return
( \
((addr & 0xF000) == 0xC000) \
? IORead[(addr>>4) & 0xFF](regs.pc,addr,0,0,uExecutedCycles) \
: *(mem+addr) \
);
}
#undef WRITE
#define WRITE(a) \
(u8*) g_pWrite = ((u8*)g_aMemoryAccess) + (addr * 4) + 0; \
*g_pWrite = DecClamp8( *g_pWrite ); \
{ \
memdirty[addr >> 8] = 0xFF; \
LPBYTE page = memwrite[addr >> 8]; \
if (page) \
*(page+(addr & 0xFF)) = (BYTE)(a); \
else if ((addr & 0xF000) == 0xC000) \
IOWrite[(addr>>4) & 0xFF](regs.pc,addr,1,(BYTE)(a),uExecutedCycles); \
}
#include "cpu/cpu_instructions.inl"
//===========================================================================
// Michael's Real-Time Debugger/Visualizer CPU
// Based on Modified 65C02
static DWORD Cpu65D02 (DWORD uTotalCycles)
{
// Optimisation:
// . Copy the global /regs/ vars to stack-based local vars
// (Oliver Schmidt says this gives a performance gain, see email - The real deal: "1.10.5")
WORD addr;
BOOL flagc; // must always be 0 or 1, no other values allowed
BOOL flagn; // must always be 0 or 0x80.
BOOL flagv; // any value allowed
BOOL flagz; // any value allowed
WORD temp;
WORD temp2;
WORD val;
AF_TO_EF
ULONG uExecutedCycles = 0;
BOOL bSlowerOnPagecross = 0; // Set if opcode writes to memory (eg. ASL, STA)
WORD base;
g_bDebugBreakpointHit = 0;
do
{
UINT uExtraCycles = 0;
BYTE iOpcode;
if (g_ActiveCPU == CPU_Z80)
{
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
}
else
if (!Fetch(iOpcode, uExecutedCycles))
break;
// INV = Invalid -> Debugger Break
// MSVC C PreProcessor is BROKEN... #define @ INV
//#define # INV
//#define @ Read()
//#define $ Store()
#define $ INV
switch (iOpcode)
{
// TODO Optimization Note: ?? Move CYC(#) to array ??
// Version 1 opcode: INV AM Instruction // Form1: INV=DebugBreak AM=AddressingMode
// INV Instruction // Form2:
//! ! ! ! ! ! // Tab-Stops
/*
case 0x00: BRK CYC(7) break;
case 0x01: idx ORA CYC(6) break;
case 0x02: INV IMM NOP CYC(2) break;
case 0x03: INV NOP CYC(2) break;
case 0x04: ZPG TSB CYC(5) break;
case 0x05: ZPG ORA CYC(3) break;
case 0x06: ZPG ASL_CMOS CYC(5) break;
case 0x07: INV NOP CYC(2) break;
case 0x08: PHP CYC(3) break;
case 0x09: IMM ORA CYC(2) break;
case 0x0A: asl CYC(2) break;
case 0x0B: INV NOP CYC(2) break;
case 0x0C: ABS TSB CYC(6) break;
case 0x0D: ABS ORA CYC(4) break;
case 0x0E: ABS ASL_CMOS CYC(6) break;
case 0x0F: INV NOP CYC(2) break;
case 0x10: REL BPL CYC(2) break;
case 0x11: idy ORA CYC(5) break;
case 0x12: izp ORA CYC(5) break;
case 0x13: INV NOP CYC(2) break;
case 0x14: ZPG TRB CYC(5) break;
case 0x15: zpx ORA CYC(4) break;
case 0x16: zpx ASL_CMOS CYC(6) break;
case 0x17: INV NOP CYC(2) break;
case 0x18: CLC CYC(2) break;
case 0x19: aby ORA CYC(4) break;
case 0x1A: INA CYC(2) break;
case 0x1B: INV NOP CYC(2) break;
case 0x1C: ABS TRB CYC(6) break;
case 0x1D: abx ORA CYC(4) break;
case 0x1E: abx ASL_CMOS CYC(6) break;
case 0x1F: INV NOP CYC(2) break;
case 0x20: ABS JSR CYC(6) break;
case 0x21: idx AND CYC(6) break;
case 0x22: INV IMM NOP CYC(2) break;
case 0x23: INV NOP CYC(2) break;
case 0x24: ZPG BIT CYC(3) break;
case 0x25: ZPG AND CYC(3) break;
case 0x26: ZPG ROL_CMOS CYC(5) break;
case 0x27: INV NOP CYC(2) break;
case 0x28: PLP CYC(4) break;
case 0x29: IMM AND CYC(2) break;
case 0x2A: rol CYC(2) break;
case 0x2B: INV NOP CYC(2) break;
case 0x2C: ABS BIT CYC(4) break;
case 0x2D: ABS AND CYC(2) break;
case 0x2E: ABS ROL_CMOS CYC(6) break;
case 0x2F: INV NOP CYC(2) break;
case 0x30: REL BMI CYC(2) break;
case 0x31: idy AND CYC(5) break;
case 0x32: izp AND CYC(5) break;
case 0x33: INV NOP CYC(2) break;
case 0x34: zpx BIT CYC(4) break;
case 0x35: zpx AND CYC(4) break;
case 0x36: zpx ROL_CMOS CYC(6) break;
case 0x37: INV NOP CYC(2) break;
case 0x38: SEC CYC(2) break;
case 0x39: aby AND CYC(4) break;
case 0x3A: DEA CYC(2) break;
case 0x3B: INV NOP CYC(2) break;
case 0x3C: abx BIT CYC(4) break;
case 0x3D: abx AND CYC(4) break;
case 0x3E: abx ROL_CMOS CYC(6) break;
case 0x3F: INV NOP CYC(2) break;
case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break;
case 0x41: idx EOR CYC(6) break;
case 0x42: INV IMM NOP CYC(2) break;
case 0x43: INV NOP CYC(2) break;
case 0x44: INV ZPG NOP CYC(3) break;
case 0x45: ZPG EOR CYC(3) break;
case 0x46: ZPG LSR_CMOS CYC(5) break;
case 0x47: INV NOP CYC(2) break;
case 0x48: PHA CYC(3) break;
case 0x49: IMM EOR CYC(2) break;
case 0x4A: lsr CYC(2) break;
case 0x4B: INV NOP CYC(2) break;
case 0x4C: ABS JMP CYC(3) break;
case 0x4D: ABS EOR CYC(4) break;
case 0x4E: ABS LSR_CMOS CYC(6) break;
case 0x4F: INV NOP CYC(2) break;
case 0x50: REL BVC CYC(2) break;
case 0x51: idy EOR CYC(5) break;
case 0x52: izp EOR CYC(5) break;
case 0x53: INV NOP CYC(2) break;
case 0x54: INV zpx NOP CYC(4) break;
case 0x55: zpx EOR CYC(4) break;
case 0x56: zpx LSR_CMOS CYC(6) break;
case 0x57: INV NOP CYC(2) break;
case 0x58: CLI CYC(2) break;
case 0x59: aby EOR CYC(4) break;
case 0x5A: PHY CYC(3) break;
case 0x5B: INV NOP CYC(2) break;
case 0x5C: INV abx NOP CYC(8) break;
case 0x5D: abx EOR CYC(4) break;
case 0x5E: abx LSR_CMOS CYC(6) break;
case 0x5F: INV NOP CYC(2) break;
case 0x60: RTS CYC(6) break;
case 0x61: idx ADC_CMOS CYC(6) break;
case 0x62: INV IMM NOP CYC(2) break;
case 0x63: INV NOP CYC(2) break;
case 0x64: ZPG STZ CYC(3) break;
case 0x65: ZPG ADC_CMOS CYC(3) break;
case 0x66: ZPG ROR_CMOS CYC(5) break;
case 0x67: INV NOP CYC(2) break;
case 0x68: PLA CYC(4) break;
case 0x69: IMM ADC_CMOS CYC(2) break;
case 0x6A: ror CYC(2) break;
case 0x6B: INV NOP CYC(2) break;
case 0x6C: IABSCMOS JMP CYC(6) break; // 0x6C // 65c02 IABSCMOS JMP // 6502 IABSNMOS JMP
case 0x6D: ABS ADC_CMOS CYC(4) break;
case 0x6E: ABS ROR_CMOS CYC(6) break;
case 0x6F: INV NOP CYC(2) break;
case 0x70: REL BVS CYC(2) break;
case 0x71: idy ADC_CMOS CYC(5) break;
case 0x72: izp ADC_CMOS CYC(5) break;
case 0x73: INV NOP CYC(2) break;
case 0x74: zpx STZ CYC(4) break;
case 0x75: zpx ADC_CMOS CYC(4) break;
case 0x76: zpx ROR_CMOS CYC(6) break;
case 0x77: INV NOP CYC(2) break;
case 0x78: SEI CYC(2) break;
case 0x79: aby ADC_CMOS CYC(4) break;
case 0x7A: PLY CYC(4) break;
case 0x7B: INV NOP CYC(2) break;
case 0x7C: IABSX JMP CYC(6) break; // 0x7C // 65c02 IABSX JMP // 6502 ABSX NOP
case 0x7D: abx ADC_CMOS CYC(4) break;
case 0x7E: abx ROR_CMOS CYC(6) break;
case 0x7F: INV NOP CYC(2) break;
case 0x80: REL BRA CYC(2) break;
case 0x81: idx STA CYC(6) break;
case 0x82: INV IMM NOP CYC(2) break;
case 0x83: INV NOP CYC(2) break;
case 0x84: ZPG STY CYC(3) break;
case 0x85: ZPG STA CYC(3) break;
case 0x86: ZPG STX CYC(3) break;
case 0x87: INV NOP CYC(2) break;
case 0x88: DEY CYC(2) break;
case 0x89: IMM BITI CYC(2) break;
case 0x8A: TXA CYC(2) break;
case 0x8B: INV NOP CYC(2) break;
case 0x8C: ABS STY CYC(4) break;
case 0x8D: ABS STA CYC(4) break;
case 0x8E: ABS STX CYC(4) break;
case 0x8F: INV NOP CYC(2) break;
case 0x90: REL BCC CYC(2) break;
case 0x91: idy STA CYC(6) break;
case 0x92: izp STA CYC(5) break;
case 0x93: INV NOP CYC(2) break;
case 0x94: zpx STY CYC(4) break;
case 0x95: zpx STA CYC(4) break;
case 0x96: zpy STX CYC(4) break;
case 0x97: INV NOP CYC(2) break;
case 0x98: TYA CYC(2) break;
case 0x99: aby STA CYC(5) break;
case 0x9A: TXS CYC(2) break;
case 0x9B: INV NOP CYC(2) break;
case 0x9C: ABS STZ CYC(4) break;
case 0x9D: abx STA CYC(5) break;
case 0x9E: abx STZ CYC(5) break;
case 0x9F: INV NOP CYC(2) break;
case 0xA0: IMM LDY CYC(2) break;
case 0xA1: idx LDA CYC(6) break;
case 0xA2: IMM LDX CYC(2) break;
case 0xA3: INV NOP CYC(2) break;
case 0xA4: ZPG LDY CYC(3) break;
case 0xA5: ZPG LDA CYC(3) break;
case 0xA6: ZPG LDX CYC(3) break;
case 0xA7: INV NOP CYC(2) break;
case 0xA8: TAY CYC(2) break;
case 0xA9: IMM LDA CYC(2) break;
case 0xAA: TAX CYC(2) break;
case 0xAB: INV NOP CYC(2) break;
case 0xAC: ABS LDY CYC(4) break;
case 0xAD: ABS LDA CYC(4) break;
case 0xAE: ABS LDX CYC(4) break;
case 0xAF: INV NOP CYC(2) break;
case 0xB0: REL BCS CYC(2) break;
case 0xB1: idy LDA CYC(5) break;
case 0xB2: izp LDA CYC(5) break;
case 0xB3: INV NOP CYC(2) break;
case 0xB4: zpx LDY CYC(4) break;
case 0xB5: zpx LDA CYC(4) break;
case 0xB6: zpy LDX CYC(4) break;
case 0xB7: INV NOP CYC(2) break;
case 0xB8: CLV CYC(2) break;
case 0xB9: aby LDA CYC(4) break;
case 0xBA: TSX CYC(2) break;
case 0xBB: INV NOP CYC(2) break;
case 0xBC: abx LDY CYC(4) break;
case 0xBD: abx LDA CYC(4) break;
case 0xBE: aby LDX CYC(4) break;
case 0xBF: INV NOP CYC(2) break;
case 0xC0: IMM CPY CYC(2) break;
case 0xC1: idx CMP CYC(6) break;
case 0xC2: INV IMM NOP CYC(2) break;
case 0xC3: INV NOP CYC(2) break;
case 0xC4: ZPG CPY CYC(3) break;
case 0xC5: ZPG CMP CYC(3) break;
case 0xC6: ZPG DEC_CMOS CYC(5) break;
case 0xC7: INV NOP CYC(2) break;
case 0xC8: INY CYC(2) break;
case 0xC9: IMM CMP CYC(2) break;
case 0xCA: DEX CYC(2) break;
case 0xCB: INV NOP CYC(2) break;
case 0xCC: ABS CPY CYC(4) break;
case 0xCD: ABS CMP CYC(4) break;
case 0xCE: ABS DEC_CMOS CYC(5) break;
case 0xCF: INV NOP CYC(2) break;
case 0xD0: REL BNE CYC(2) break;
case 0xD1: idy CMP CYC(5) break;
case 0xD2: izp CMP CYC(5) break;
case 0xD3: INV NOP CYC(2) break;
case 0xD4: INV zpx NOP CYC(4) break;
case 0xD5: zpx CMP CYC(4) break;
case 0xD6: zpx DEC_CMOS CYC(6) break;
case 0xD7: INV NOP CYC(2) break;
case 0xD8: CLD CYC(2) break;
case 0xD9: aby CMP CYC(4) break;
case 0xDA: PHX CYC(3) break;
case 0xDB: INV NOP CYC(2) break;
case 0xDC: INV abx NOP CYC(4) break;
case 0xDD: abx CMP CYC(4) break;
case 0xDE: abx DEC_CMOS CYC(6) break;
case 0xDF: INV NOP CYC(2) break;
case 0xE0: IMM CPX CYC(2) break;
case 0xE1: idx SBC_CMOS CYC(6) break;
case 0xE2: INV IMM NOP CYC(2) break;
case 0xE3: INV NOP CYC(2) break;
case 0xE4: ZPG CPX CYC(3) break;
case 0xE5: ZPG SBC_CMOS CYC(3) break;
case 0xE6: ZPG INC_CMOS CYC(5) break;
case 0xE7: INV NOP CYC(2) break;
case 0xE8: INX CYC(2) break;
case 0xE9: IMM SBC_CMOS CYC(2) break;
case 0xEA: NOP CYC(2) break;
case 0xEB: INV NOP CYC(2) break;
case 0xEC: ABS CPX CYC(4) break;
case 0xED: ABS SBC_CMOS CYC(4) break;
case 0xEE: ABS INC_CMOS CYC(6) break;
case 0xEF: INV NOP CYC(2) break;
case 0xF0: REL BEQ CYC(2) break;
case 0xF1: idy SBC_CMOS CYC(5) break;
case 0xF2: izp SBC_CMOS CYC(5) break;
case 0xF3: INV NOP CYC(2) break;
case 0xF4: INV zpx NOP CYC(4) break;
case 0xF5: zpx SBC_CMOS CYC(4) break;
case 0xF6: zpx INC_CMOS CYC(6) break;
case 0xF7: INV NOP CYC(2) break;
case 0xF8: SED CYC(2) break;
case 0xF9: aby SBC_CMOS CYC(4) break;
case 0xFA: PLX CYC(4) break;
case 0xFB: INV NOP CYC(2) break;
case 0xFC: INV abx NOP CYC(4) break;
case 0xFD: abx SBC_CMOS CYC(4) break;
case 0xFE: abx INC_CMOS CYC(6) break;
case 0xFF: INV NOP CYC(2) break;
*/
// Version 2 opcode: $ AM Instruction // $=DebugBreak AM=AddressingMode
//! ! ! ! ! ! // Tab-Stops
case 0x00: BRK CYC(7) break;
case 0x01: idx ORA CYC(6) break;
case 0x02: $ IMM NOP CYC(2) break;
case 0x03: $ NOP CYC(2) break;
case 0x04: ZPG TSB CYC(5) break;
case 0x05: ZPG ORA CYC(3) break;
case 0x06: ZPG ASLc CYC(5) break;
case 0x07: $ NOP CYC(2) break;
case 0x08: PHP CYC(3) break;
case 0x09: IMM ORA CYC(2) break;
case 0x0A: asl CYC(2) break;
case 0x0B: $ NOP CYC(2) break;
case 0x0C: ABS TSB CYC(6) break;
case 0x0D: ABS ORA CYC(4) break;
case 0x0E: ABS ASLc CYC(6) break;
case 0x0F: $ NOP CYC(2) break;
case 0x10: REL BPL CYC(2) break;
case 0x11: idy ORA CYC(5) break;
case 0x12: izp ORA CYC(5) break;
case 0x13: $ NOP CYC(2) break;
case 0x14: ZPG TRB CYC(5) break;
case 0x15: zpx ORA CYC(4) break;
case 0x16: zpx ASLc CYC(6) break;
case 0x17: $ NOP CYC(2) break;
case 0x18: CLC CYC(2) break;
case 0x19: aby ORA CYC(4) break;
case 0x1A: INA CYC(2) break;
case 0x1B: $ NOP CYC(2) break;
case 0x1C: ABS TRB CYC(6) break;
case 0x1D: abx ORA CYC(4) break;
case 0x1E: abx ASLc CYC(6) break;
case 0x1F: $ NOP CYC(2) break;
case 0x20: ABS JSR CYC(6) break;
case 0x21: idx AND CYC(6) break;
case 0x22: $ IMM NOP CYC(2) break;
case 0x23: $ NOP CYC(2) break;
case 0x24: ZPG BIT CYC(3) break;
case 0x25: ZPG AND CYC(3) break;
case 0x26: ZPG ROLc CYC(5) break;
case 0x27: $ NOP CYC(2) break;
case 0x28: PLP CYC(4) break;
case 0x29: IMM AND CYC(2) break;
case 0x2A: rol CYC(2) break;
case 0x2B: $ NOP CYC(2) break;
case 0x2C: ABS BIT CYC(4) break;
case 0x2D: ABS AND CYC(2) break;
case 0x2E: ABS ROLc CYC(6) break;
case 0x2F: $ NOP CYC(2) break;
case 0x30: REL BMI CYC(2) break;
case 0x31: idy AND CYC(5) break;
case 0x32: izp AND CYC(5) break;
case 0x33: $ NOP CYC(2) break;
case 0x34: zpx BIT CYC(4) break;
case 0x35: zpx AND CYC(4) break;
case 0x36: zpx ROLc CYC(6) break;
case 0x37: $ NOP CYC(2) break;
case 0x38: SEC CYC(2) break;
case 0x39: aby AND CYC(4) break;
case 0x3A: DEA CYC(2) break;
case 0x3B: $ NOP CYC(2) break;
case 0x3C: abx BIT CYC(4) break;
case 0x3D: abx AND CYC(4) break;
case 0x3E: abx ROLc CYC(6) break;
case 0x3F: $ NOP CYC(2) break;
case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break;
case 0x41: idx EOR CYC(6) break;
case 0x42: $ IMM NOP CYC(2) break;
case 0x43: $ NOP CYC(2) break;
case 0x44: $ ZPG NOP CYC(3) break;
case 0x45: ZPG EOR CYC(3) break;
case 0x46: ZPG LSRc CYC(5) break;
case 0x47: $ NOP CYC(2) break;
case 0x48: PHA CYC(3) break;
case 0x49: IMM EOR CYC(2) break;
case 0x4A: lsr CYC(2) break;
case 0x4B: $ NOP CYC(2) break;
case 0x4C: ABS JMP CYC(3) break;
case 0x4D: ABS EOR CYC(4) break;
case 0x4E: ABS LSRc CYC(6) break;
case 0x4F: $ NOP CYC(2) break;
case 0x50: REL BVC CYC(2) break;
case 0x51: idy EOR CYC(5) break;
case 0x52: izp EOR CYC(5) break;
case 0x53: $ NOP CYC(2) break;
case 0x54: $ zpx NOP CYC(4) break;
case 0x55: zpx EOR CYC(4) break;
case 0x56: zpx LSRc CYC(6) break;
case 0x57: $ NOP CYC(2) break;
case 0x58: CLI CYC(2) break;
case 0x59: aby EOR CYC(4) break;
case 0x5A: PHY CYC(3) break;
case 0x5B: $ NOP CYC(2) break;
case 0x5C: $ abx NOP CYC(8) break;
case 0x5D: abx EOR CYC(4) break;
case 0x5E: abx LSRc CYC(6) break;
case 0x5F: $ NOP CYC(2) break;
case 0x60: RTS CYC(6) break;
case 0x61: idx ADCc CYC(6) break;
case 0x62: $ IMM NOP CYC(2) break;
case 0x63: $ NOP CYC(2) break;
case 0x64: ZPG STZ CYC(3) break;
case 0x65: ZPG ADCc CYC(3) break;
case 0x66: ZPG RORc CYC(5) break;
case 0x67: $ NOP CYC(2) break;
case 0x68: PLA CYC(4) break;
case 0x69: IMM ADCc CYC(2) break;
case 0x6A: ror CYC(2) break;
case 0x6B: $ NOP CYC(2) break;
case 0x6C: IABSCMOS JMP CYC(6) break; // 0x6C // 65c02 IABSCMOS JMP // 6502 IABSNMOS JMP
case 0x6D: ABS ADCc CYC(4) break;
case 0x6E: ABS RORc CYC(6) break;
case 0x6F: $ NOP CYC(2) break;
case 0x70: REL BVS CYC(2) break;
case 0x71: idy ADCc CYC(5) break;
case 0x72: izp ADCc CYC(5) break;
case 0x73: $ NOP CYC(2) break;
case 0x74: zpx STZ CYC(4) break;
case 0x75: zpx ADCc CYC(4) break;
case 0x76: zpx RORc CYC(6) break;
case 0x77: $ NOP CYC(2) break;
case 0x78: SEI CYC(2) break;
case 0x79: aby ADCc CYC(4) break;
case 0x7A: PLY CYC(4) break;
case 0x7B: $ NOP CYC(2) break;
case 0x7C: IABSX JMP CYC(6) break; // 0x7C // 65c02 IABSX JMP // 6502 ABSX NOP
case 0x7D: abx ADCc CYC(4) break;
case 0x7E: abx RORc CYC(6) break;
case 0x7F: $ NOP CYC(2) break;
case 0x80: REL BRA CYC(2) break;
case 0x81: idx STA CYC(6) break;
case 0x82: $ IMM NOP CYC(2) break;
case 0x83: $ NOP CYC(2) break;
case 0x84: ZPG STY CYC(3) break;
case 0x85: ZPG STA CYC(3) break;
case 0x86: ZPG STX CYC(3) break;
case 0x87: $ NOP CYC(2) break;
case 0x88: DEY CYC(2) break;
case 0x89: IMM BITI CYC(2) break;
case 0x8A: TXA CYC(2) break;
case 0x8B: $ NOP CYC(2) break;
case 0x8C: ABS STY CYC(4) break;
case 0x8D: ABS STA CYC(4) break;
case 0x8E: ABS STX CYC(4) break;
case 0x8F: $ NOP CYC(2) break;
case 0x90: REL BCC CYC(2) break;
case 0x91: idy STA CYC(6) break;
case 0x92: izp STA CYC(5) break;
case 0x93: $ NOP CYC(2) break;
case 0x94: zpx STY CYC(4) break;
case 0x95: zpx STA CYC(4) break;
case 0x96: zpy STX CYC(4) break;
case 0x97: $ NOP CYC(2) break;
case 0x98: TYA CYC(2) break;
case 0x99: aby STA CYC(5) break;
case 0x9A: TXS CYC(2) break;
case 0x9B: $ NOP CYC(2) break;
case 0x9C: ABS STZ CYC(4) break;
case 0x9D: abx STA CYC(5) break;
case 0x9E: abx STZ CYC(5) break;
case 0x9F: $ NOP CYC(2) break;
case 0xA0: IMM LDY CYC(2) break;
case 0xA1: idx LDA CYC(6) break;
case 0xA2: IMM LDX CYC(2) break;
case 0xA3: $ NOP CYC(2) break;
case 0xA4: ZPG LDY CYC(3) break;
case 0xA5: ZPG LDA CYC(3) break;
case 0xA6: ZPG LDX CYC(3) break;
case 0xA7: $ NOP CYC(2) break;
case 0xA8: TAY CYC(2) break;
case 0xA9: IMM LDA CYC(2) break;
case 0xAA: TAX CYC(2) break;
case 0xAB: $ NOP CYC(2) break;
case 0xAC: ABS LDY CYC(4) break;
case 0xAD: ABS LDA CYC(4) break;
case 0xAE: ABS LDX CYC(4) break;
case 0xAF: $ NOP CYC(2) break;
case 0xB0: REL BCS CYC(2) break;
case 0xB1: idy LDA CYC(5) break;
case 0xB2: izp LDA CYC(5) break;
case 0xB3: $ NOP CYC(2) break;
case 0xB4: zpx LDY CYC(4) break;
case 0xB5: zpx LDA CYC(4) break;
case 0xB6: zpy LDX CYC(4) break;
case 0xB7: $ NOP CYC(2) break;
case 0xB8: CLV CYC(2) break;
case 0xB9: aby LDA CYC(4) break;
case 0xBA: TSX CYC(2) break;
case 0xBB: $ NOP CYC(2) break;
case 0xBC: abx LDY CYC(4) break;
case 0xBD: abx LDA CYC(4) break;
case 0xBE: aby LDX CYC(4) break;
case 0xBF: $ NOP CYC(2) break;
case 0xC0: IMM CPY CYC(2) break;
case 0xC1: idx CMP CYC(6) break;
case 0xC2: $ IMM NOP CYC(2) break;
case 0xC3: $ NOP CYC(2) break;
case 0xC4: ZPG CPY CYC(3) break;
case 0xC5: ZPG CMP CYC(3) break;
case 0xC6: ZPG DECc CYC(5) break;
case 0xC7: $ NOP CYC(2) break;
case 0xC8: INY CYC(2) break;
case 0xC9: IMM CMP CYC(2) break;
case 0xCA: DEX CYC(2) break;
case 0xCB: $ NOP CYC(2) break;
case 0xCC: ABS CPY CYC(4) break;
case 0xCD: ABS CMP CYC(4) break;
case 0xCE: ABS DECc CYC(5) break;
case 0xCF: $ NOP CYC(2) break;
case 0xD0: REL BNE CYC(2) break;
case 0xD1: idy CMP CYC(5) break;
case 0xD2: izp CMP CYC(5) break;
case 0xD3: $ NOP CYC(2) break;
case 0xD4: $ zpx NOP CYC(4) break;
case 0xD5: zpx CMP CYC(4) break;
case 0xD6: zpx DECc CYC(6) break;
case 0xD7: $ NOP CYC(2) break;
case 0xD8: CLD CYC(2) break;
case 0xD9: aby CMP CYC(4) break;
case 0xDA: PHX CYC(3) break;
case 0xDB: $ NOP CYC(2) break;
case 0xDC: $ abx NOP CYC(4) break;
case 0xDD: abx CMP CYC(4) break;
case 0xDE: abx DECc CYC(6) break;
case 0xDF: $ NOP CYC(2) break;
case 0xE0: IMM CPX CYC(2) break;
case 0xE1: idx SBCc CYC(6) break;
case 0xE2: $ IMM NOP CYC(2) break;
case 0xE3: $ NOP CYC(2) break;
case 0xE4: ZPG CPX CYC(3) break;
case 0xE5: ZPG SBCc CYC(3) break;
case 0xE6: ZPG INCc CYC(5) break;
case 0xE7: $ NOP CYC(2) break;
case 0xE8: INX CYC(2) break;
case 0xE9: IMM SBCc CYC(2) break;
case 0xEA: NOP CYC(2) break;
case 0xEB: $ NOP CYC(2) break;
case 0xEC: ABS CPX CYC(4) break;
case 0xED: ABS SBCc CYC(4) break;
case 0xEE: ABS INCc CYC(6) break;
case 0xEF: $ NOP CYC(2) break;
case 0xF0: REL BEQ CYC(2) break;
case 0xF1: idy SBCc CYC(5) break;
case 0xF2: izp SBCc CYC(5) break;
case 0xF3: $ NOP CYC(2) break;
case 0xF4: $ zpx NOP CYC(4) break;
case 0xF5: zpx SBCc CYC(4) break;
case 0xF6: zpx INCc CYC(6) break;
case 0xF7: $ NOP CYC(2) break;
case 0xF8: SED CYC(2) break;
case 0xF9: aby SBCc CYC(4) break;
case 0xFA: PLX CYC(4) break;
case 0xFB: $ NOP CYC(2) break;
case 0xFC: $ abx NOP CYC(4) break;
case 0xFD: abx SBCc CYC(4) break;
case 0xFE: abx INCc CYC(6) break;
case 0xFF: $ NOP CYC(2) break;
}
#undef $
CheckInterruptSources(uExecutedCycles);
NMI(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
IRQ(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
if( IsDebugBreakpointHit() )
break;
} while (uExecutedCycles < uTotalCycles);
EF_TO_AF // Emulator Flags to Apple Flags
if( g_bDebugBreakpointHit )
if ((g_nAppMode != MODE_DEBUG) && (g_nAppMode != MODE_STEPPING)) // // Running at full speed? (debugger not running)
RequestDebugger();
return uExecutedCycles;
}
+176
View File
@@ -0,0 +1,176 @@
/*
AppleWin : An Apple //e emulator for Windows
Copyright (C) 1994-1996, Michael O'Brien
Copyright (C) 1999-2001, Oliver Schmidt
Copyright (C) 2002-2005, Tom Charlesworth
Copyright (C) 2006-2010, Tom Charlesworth, Michael Pohoreski
AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AppleWin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AppleWin; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Description: 6502/65C02 emulation
*
* Author: Various
*/
/****************************************************************************
*
* GENERAL PURPOSE MACROS
*
***/
#undef AF_TO_EF
#undef EF_TO_AF
#define AF_TO_EF flagc = (regs.ps & AF_CARRY); \
flagn = (regs.ps & AF_SIGN); \
flagv = (regs.ps & AF_OVERFLOW); \
flagz = (regs.ps & AF_ZERO);
#define EF_TO_AF regs.ps = (regs.ps & ~(AF_CARRY | AF_SIGN | \
AF_OVERFLOW | AF_ZERO)) \
| flagc \
| flagn \
| (flagv ? AF_OVERFLOW : 0) \
| (flagz ? AF_ZERO : 0) \
| AF_RESERVED | AF_BREAK;
// CYC(a): This can be optimised, as only certain opcodes will affect uExtraCycles
#define CYC(a) uExecutedCycles += (a)+uExtraCycles; g_nIrqCheckTimeout -= (a)+uExtraCycles;
#define POP (*(mem+((regs.sp >= 0x1FF) ? (regs.sp = 0x100) : ++regs.sp)))
#define PUSH(a) *(mem+regs.sp--) = (a); \
if (regs.sp < 0x100) \
regs.sp = 0x1FF;
#define READ ( \
((addr & 0xF000) == 0xC000) \
? IORead[(addr>>4) & 0xFF](regs.pc,addr,0,0,uExecutedCycles) \
: *(mem+addr) \
)
#define SETNZ(a) { \
flagn = ((a) & 0x80); \
flagz = !((a) & 0xFF); \
}
#define SETZ(a) flagz = !((a) & 0xFF);
#define WRITE(a) { \
memdirty[addr >> 8] = 0xFF; \
LPBYTE page = memwrite[addr >> 8]; \
if (page) \
*(page+(addr & 0xFF)) = (BYTE)(a); \
else if ((addr & 0xF000) == 0xC000) \
IOWrite[(addr>>4) & 0xFF](regs.pc,addr,1,(BYTE)(a),uExecutedCycles); \
}
//
// ExtraCycles:
// +1 if branch taken
// +1 if page boundary crossed
#define BRANCH_TAKEN { \
base = regs.pc; \
regs.pc += addr; \
if ((base ^ regs.pc) & 0xFF00) \
uExtraCycles=2; \
else \
uExtraCycles=1; \
}
//
#define CHECK_PAGE_CHANGE if (bSlowerOnPagecross) { \
if ((base ^ addr) & 0xFF00) \
uExtraCycles=1; \
}
/****************************************************************************
*
* ADDRESSING MODE MACROS
*
***/
#define ABS addr = *(LPWORD)(mem+regs.pc); regs.pc += 2;
#define IABSX addr = *(LPWORD)(mem+(*(LPWORD)(mem+regs.pc))+(WORD)regs.x); regs.pc += 2;
#define ABSX base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; CHECK_PAGE_CHANGE;
#define ABSY base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; CHECK_PAGE_CHANGE;
// TODO Optimization Note: uExtraCycles = ((base & 0xFF) + 1) >> 8;
#define IABSCMOS base = *(LPWORD)(mem+regs.pc); \
addr = *(LPWORD)(mem+base); \
if ((base & 0xFF) == 0xFF) uExtraCycles=1; \
regs.pc += 2;
#define IABSNMOS base = *(LPWORD)(mem+regs.pc); \
if ((base & 0xFF) == 0xFF) \
addr = *(mem+base)+((WORD)*(mem+(base&0xFF00))<<8);\
else \
addr = *(LPWORD)(mem+base); \
regs.pc += 2;
#define IMM addr = regs.pc++;
#define INDX base = ((*(mem+regs.pc++))+regs.x) & 0xFF; \
if (base == 0xFF) \
addr = *(mem+0xFF)+(((WORD)*mem)<<8); \
else \
addr = *(LPWORD)(mem+base);
#define INDY if (*(mem+regs.pc) == 0xFF) \
base = *(mem+0xFF)+(((WORD)*mem)<<8); \
else \
base = *(LPWORD)(mem+*(mem+regs.pc)); \
regs.pc++; \
addr = base+(WORD)regs.y; \
CHECK_PAGE_CHANGE;
#define IZPG base = *(mem+regs.pc++); \
if (base == 0xFF) \
addr = *(mem+0xFF)+(((WORD)*mem)<<8); \
else \
addr = *(LPWORD)(mem+base);
#define REL addr = (signed char)*(mem+regs.pc++);
// TODO Optimization Note:
// . Opcodes that generate zero-page addresses can't be accessing $C000..$CFFF
// so they could be paired with special READZP/WRITEZP macros (instead of READ/WRITE)
#define ZPG addr = *(mem+regs.pc++);
#define ZPGX addr = ((*(mem+regs.pc++))+regs.x) & 0xFF;
#define ZPGY addr = ((*(mem+regs.pc++))+regs.y) & 0xFF;
// Tidy 3 char addressing modes to keep the opcode table visually aligned, clean, and readable.
#undef abx
#undef abx
#undef aby
#undef asl
#undef idx
#undef idy
#undef imm
#undef izp
#undef lsr
#undef rel
#undef rol
#undef ror
#undef zpx
#undef zpy
#define abx ABSX
#define aby ABSY
#define asl ASLA // Arithmetic Shift Left
#define idx INDX
#define idy INDY
#define imm IMM
#define izp IZPG
#define lsr LSRA // Logical Shift Right
#define rel REL
#define rol ROLA // Rotate Left
#define ror RORA // Rotate Right
#define zpx ZPGX
#define zpy ZPGY
// 0x6C // 65c02 IABSCMOS JMP // 6502 IABSNMOS JMP
// 0x7C IABSX
+665
View File
@@ -0,0 +1,665 @@
/*
AppleWin : An Apple //e emulator for Windows
Copyright (C) 1994-1996, Michael O'Brien
Copyright (C) 1999-2001, Oliver Schmidt
Copyright (C) 2002-2005, Tom Charlesworth
Copyright (C) 2006-2010, Tom Charlesworth, Michael Pohoreski
AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AppleWin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AppleWin; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Description: 6502/65C02 emulation
*
* Author: Various
*/
// TO DO:
// . All these CPP macros need to be converted to inline funcs
/****************************************************************************
*
* INSTRUCTION MACROS
*
***/
#undef ADC_NMOS
#undef ADC_CMOS
#undef ALR
#undef AND
#undef ANC
#undef ARR
#undef ASL_NMOS
#undef ASL_CMOS
#undef ASLA
#undef ASO
#undef AXA
#undef AXS
#undef BCC
#undef BCS
#undef BEQ
#undef BIT
#undef BITI
#undef BMI
#undef BNE
#undef BPL
#undef BRA
#undef BRK
#undef BVC
#undef BVS
#undef CLC
#undef CLD
#undef CLI
#undef CLV
#undef CMP
#undef CPX
#undef CPY
#undef DCM
#undef DEA
#undef DEC_NMOS
#undef DEC_CMOS
#undef DEX
#undef DEY
#undef EOR
#undef HLT
#undef INA
#undef INC_NMOS
#undef INC_CMOS
#undef INS
#undef INX
#undef INY
#undef JMP
#undef JSR
#undef LAS
#undef LAX
#undef LDA
#undef LDX
#undef LDY
#undef LSE
#undef LSR_NMOS
#undef LSR_CMOS
#undef LSRA
#undef NOP
#undef OAL
#undef ORA
#undef PHA
#undef PHP
#undef PHX
#undef PHY
#undef PLA
#undef PLP
#undef PLX
#undef PLY
#undef RLA
#undef ROL_NMOS
#undef ROL_CMOS
#undef ROLA
#undef ROR_NMOS
#undef ROR_CMOS
#undef RORA
#undef RRA
#undef RTI
#undef RTS
#undef SAX
#undef SAY
#undef SBC_NMOS
#undef SBC_CMOS
#undef SEC
#undef SED
#undef SEI
#undef STA
#undef STX
#undef STY
#undef STZ
#undef TAS
#undef TAX
#undef TAY
#undef TRB
#undef TSB
#undef TSX
#undef TXA
#undef TXS
#undef TYA
#undef XAA
#undef XAS
// ==========
#undef ADCn
#undef ASLn
#undef DECn
#undef INCn
#undef LSRn
#undef ROLn
#undef RORn
#undef SBCn
#define ADCn ADC_NMOS
#define ASLn ASL_NMOS
#define DECn DEC_NMOS
#define INCn INC_NMOS
#define LSRn LSR_NMOS
#define ROLn ROL_NMOS
#define RORn ROR_NMOS
#define SBCn SBC_NMOS
// ==========
#undef ADCc
#undef ASLc
#undef DECc
#undef INCc
#undef LSRc
#undef ROLc
#undef RORc
#undef SBCc
#define ADCc ADC_CMOS
#define ASLc ASL_CMOS
#define DECc DEC_CMOS
#define INCc INC_CMOS
#define LSRc LSR_CMOS
#define ROLc ROL_CMOS
#define RORc ROR_CMOS
#define SBCc SBC_CMOS
// ==========
#define ADC_NMOS bSlowerOnPagecross = 1; \
temp = READ; \
if (regs.ps & AF_DECIMAL) { \
val = (regs.a & 0x0F) + (temp & 0x0F) + flagc; \
if (val > 0x09) \
val += 0x06; \
if (val <= 0x0F) \
val = (val & 0x0F) + (regs.a & 0xF0) + (temp & 0xF0); \
else \
val = (val & 0x0F) + (regs.a & 0xF0) + (temp & 0xF0) + 0x10;\
flagz = !((regs.a + temp + flagc) & 0xFF); \
flagn = (val & 0x80); \
flagv = ((regs.a ^ val) & 0x80) && !((regs.a ^ temp) & 0x80);\
if ((val & 0x1F0) > 0x90) \
val += 0x60; \
flagc = ((val & 0xFF0) > 0xF0); \
regs.a = val & 0xFF; \
} \
else { \
val = regs.a + temp + flagc; \
flagc = (val > 0xFF); \
flagv = (((regs.a & 0x80) == (temp & 0x80)) && \
((regs.a & 0x80) != (val & 0x80))); \
regs.a = val & 0xFF; \
SETNZ(regs.a); \
}
#define ADC_CMOS bSlowerOnPagecross = 1; \
temp = READ; \
flagv = !((regs.a ^ temp) & 0x80); \
if (regs.ps & AF_DECIMAL) { \
uExtraCycles++; \
val = (regs.a & 0x0f) + (temp & 0x0f) + flagc; \
if (val >= 0x0A) \
val = 0x10 | ((val + 6) & 0x0f); \
val += (regs.a & 0xf0) + (temp & 0xf0); \
if (val >= 0xA0) { \
flagc = 1; \
if (val >= 0x180) \
flagv = 0; \
val += 0x60; \
} \
else { \
flagc = 0; \
if (val < 0x80) \
flagv = 0; \
} \
} \
else { \
val = regs.a + temp + flagc; \
if (val >= 0x100) { \
flagc = 1; \
if (val >= 0x180) flagv = 0; \
} \
else { \
flagc = 0; \
if (val < 0x80) flagv = 0; \
} \
} \
regs.a = val & 0xFF; \
SETNZ(regs.a)
#define ALR regs.a &= READ; \
flagc = (regs.a & 1); \
flagn = 0; \
regs.a >>= 1; \
SETZ(regs.a)
#define AND bSlowerOnPagecross = 1; \
regs.a &= READ; \
SETNZ(regs.a)
#define ANC regs.a &= READ; \
SETNZ(regs.a) \
flagc = !!flagn;
#define ARR temp = regs.a & READ; /* Yes, this is sick */ \
if (regs.ps & AF_DECIMAL) { \
val = temp; \
val |= (flagc ? 0x100 : 0); \
val >>= 1; \
flagn = (flagc ? 0x80 : 0); \
SETZ(val) \
flagv = ((val ^ temp) & 0x40); \
if (((val & 0x0F) + (val & 0x01)) > 0x05) \
val = (val & 0xF0) | ((val + 0x06) & 0x0F); \
if (((val & 0xF0) + (val & 0x10)) > 0x50) { \
val = (val & 0x0F) | ((val + 0x60) & 0xF0); \
flagc = 1; \
} \
else \
flagc = 0; \
regs.a = (val & 0xFF); \
} \
else { \
val = temp | (flagc ? 0x100 : 0); \
val >>= 1; \
SETNZ(val) \
flagc = !!(val & 0x40); \
flagv = ((val & 0x40) ^ ((val & 0x20) << 1)); \
regs.a = (val & 0xFF); \
}
#define ASL_NMOS bSlowerOnPagecross = 0; \
val = READ << 1; \
flagc = (val > 0xFF); \
SETNZ(val) \
WRITE(val)
#define ASL_CMOS bSlowerOnPagecross = 1; \
val = READ << 1; \
flagc = (val > 0xFF); \
SETNZ(val) \
WRITE(val)
#define ASLA val = regs.a << 1; \
flagc = (val > 0xFF); \
SETNZ(val) \
regs.a = (BYTE)val;
#define ASO bSlowerOnPagecross = 0; \
val = READ << 1; \
flagc = (val > 0xFF); \
WRITE(val) \
regs.a |= val; \
SETNZ(regs.a)
#define AXA bSlowerOnPagecross = 0;/*FIXME: $93 case is still unclear*/ \
val = regs.a & regs.x & (((base >> 8) + 1) & 0xFF); \
WRITE(val)
#define AXS bSlowerOnPagecross = 0; \
WRITE(regs.a & regs.x)
#define BCC if (!flagc) BRANCH_TAKEN;
#define BCS if ( flagc) BRANCH_TAKEN;
#define BEQ if ( flagz) BRANCH_TAKEN;
#define BIT bSlowerOnPagecross = 1; \
val = READ; \
flagz = !(regs.a & val); \
flagn = val & 0x80; \
flagv = val & 0x40;
#define BITI flagz = !(regs.a & READ);
#define BMI if ( flagn) BRANCH_TAKEN;
#define BNE if (!flagz) BRANCH_TAKEN;
#define BPL if (!flagn) BRANCH_TAKEN;
#define BRA BRANCH_TAKEN;
#define BRK regs.pc++; \
PUSH(regs.pc >> 8) \
PUSH(regs.pc & 0xFF) \
EF_TO_AF \
PUSH(regs.ps); \
regs.ps |= AF_INTERRUPT; \
regs.pc = *(LPWORD)(mem+0xFFFE);
#define BVC if (!flagv) BRANCH_TAKEN;
#define BVS if ( flagv) BRANCH_TAKEN;
#define CLC flagc = 0;
#define CLD regs.ps &= ~AF_DECIMAL;
#define CLI regs.ps &= ~AF_INTERRUPT;
#define CLV flagv = 0;
#define CMP bSlowerOnPagecross = 1; \
val = READ; \
flagc = (regs.a >= val); \
val = regs.a-val; \
SETNZ(val)
#define CPX val = READ; \
flagc = (regs.x >= val); \
val = regs.x-val; \
SETNZ(val)
#define CPY val = READ; \
flagc = (regs.y >= val); \
val = regs.y-val; \
SETNZ(val)
#define DCM bSlowerOnPagecross = 0; \
val = READ-1; \
WRITE(val) \
flagc = (regs.a >= val); \
val = regs.a-val; \
SETNZ(val)
#define DEA --regs.a; \
SETNZ(regs.a)
#define DEC_NMOS bSlowerOnPagecross = 0; \
val = READ-1; \
SETNZ(val) \
WRITE(val)
#define DEC_CMOS bSlowerOnPagecross = 1; \
val = READ-1; \
SETNZ(val) \
WRITE(val)
#define DEX --regs.x; \
SETNZ(regs.x)
#define DEY --regs.y; \
SETNZ(regs.y)
#define EOR bSlowerOnPagecross = 1; \
regs.a ^= READ; \
SETNZ(regs.a)
#define HLT regs.bJammed = 1; \
--regs.pc;
#define INA ++regs.a; \
SETNZ(regs.a)
#define INC_NMOS bSlowerOnPagecross = 0; \
val = READ+1; \
SETNZ(val) \
WRITE(val)
#define INC_CMOS bSlowerOnPagecross = 1; \
val = READ+1; \
SETNZ(val) \
WRITE(val)
#define INS bSlowerOnPagecross = 0; \
val = READ+1; \
WRITE(val) \
temp = val; \
temp2 = regs.a - temp - !flagc; \
if (regs.ps & AF_DECIMAL) { \
val = (regs.a & 0x0F) - (temp & 0x0F) - !flagc; \
if (val & 0x10) \
val = ((val - 0x06) & 0x0F) | ((regs.a & 0xF0) - (temp & 0xF0) - 0x10);\
else \
val = (val & 0x0F) | ((regs.a & 0xF0) - (temp & 0xF0));\
if (val & 0x100) \
val -= 0x60; \
flagc = (temp2 < 0x100); \
SETNZ(temp2 & 0xFF); \
flagv = ((regs.a ^ temp2) & 0x80) && ((regs.a ^ temp) & 0x80);\
regs.a = val & 0xFF; \
} \
else { \
val = temp2; \
flagc = (val < 0x100); \
flagv = (((regs.a & 0x80) != (temp & 0x80)) && \
((regs.a & 0x80) != (val & 0x80))); \
regs.a = val & 0xFF; \
SETNZ(regs.a); \
}
#define INX ++regs.x; \
SETNZ(regs.x)
#define INY ++regs.y; \
SETNZ(regs.y)
#define JMP regs.pc = addr;
#define JSR --regs.pc; \
PUSH(regs.pc >> 8) \
PUSH(regs.pc & 0xFF) \
regs.pc = addr;
#define LAS bSlowerOnPagecross = 1; \
val = (BYTE)(READ & regs.sp); \
regs.a = regs.x = (BYTE) val; \
regs.sp = val | 0x100; \
SETNZ(val)
#define LAX bSlowerOnPagecross = 1; \
regs.a = regs.x = READ; \
SETNZ(regs.a)
#define LDA bSlowerOnPagecross = 1; \
regs.a = READ; \
SETNZ(regs.a)
#define LDX bSlowerOnPagecross = 1; \
regs.x = READ; \
SETNZ(regs.x)
#define LDY bSlowerOnPagecross = 1; \
regs.y = READ; \
SETNZ(regs.y)
#define LSE bSlowerOnPagecross = 0; \
val = READ; \
flagc = (val & 1); \
val >>= 1; \
WRITE(val) \
regs.a ^= val; \
SETNZ(regs.a)
#define LSR_NMOS bSlowerOnPagecross = 0; \
val = READ; \
flagc = (val & 1); \
flagn = 0; \
val >>= 1; \
SETZ(val) \
WRITE(val)
#define LSR_CMOS bSlowerOnPagecross = 1; \
val = READ; \
flagc = (val & 1); \
flagn = 0; \
val >>= 1; \
SETZ(val) \
WRITE(val)
#define LSRA flagc = (regs.a & 1); \
flagn = 0; \
regs.a >>= 1; \
SETZ(regs.a)
#define NOP bSlowerOnPagecross = 1;
#define OAL regs.a |= 0xEE; \
regs.a &= READ; \
regs.x = regs.a; \
SETNZ(regs.a)
#define ORA bSlowerOnPagecross = 1; \
regs.a |= READ; \
SETNZ(regs.a)
#define PHA PUSH(regs.a)
#define PHP EF_TO_AF \
PUSH(regs.ps)
#define PHX PUSH(regs.x)
#define PHY PUSH(regs.y)
#define PLA regs.a = POP; \
SETNZ(regs.a)
#define PLP regs.ps = POP | AF_RESERVED | AF_BREAK; \
AF_TO_EF
#define PLX regs.x = POP; \
SETNZ(regs.x)
#define PLY regs.y = POP; \
SETNZ(regs.y)
#define RLA bSlowerOnPagecross = 0; \
val = (READ << 1) | flagc; \
flagc = (val > 0xFF); \
WRITE(val) \
regs.a &= val; \
SETNZ(regs.a)
#define ROL_NMOS bSlowerOnPagecross = 0; \
val = (READ << 1) | flagc; \
flagc = (val > 0xFF); \
SETNZ(val) \
WRITE(val)
#define ROL_CMOS bSlowerOnPagecross = 1; \
val = (READ << 1) | flagc; \
flagc = (val > 0xFF); \
SETNZ(val) \
WRITE(val)
#define ROLA val = (((WORD)regs.a) << 1) | flagc; \
flagc = (val > 0xFF); \
regs.a = val & 0xFF; \
SETNZ(regs.a);
#define ROR_NMOS bSlowerOnPagecross = 0; \
temp = READ; \
val = (temp >> 1) | (flagc ? 0x80 : 0); \
flagc = (temp & 1); \
SETNZ(val) \
WRITE(val)
#define ROR_CMOS bSlowerOnPagecross = 1; \
temp = READ; \
val = (temp >> 1) | (flagc ? 0x80 : 0); \
flagc = (temp & 1); \
SETNZ(val) \
WRITE(val)
#define RORA val = (((WORD)regs.a) >> 1) | (flagc ? 0x80 : 0); \
flagc = (regs.a & 1); \
regs.a = val & 0xFF; \
SETNZ(regs.a)
#define RRA bSlowerOnPagecross = 0; \
temp = READ; \
val = (temp >> 1) | (flagc ? 0x80 : 0); \
flagc = (temp & 1); \
WRITE(val) \
temp = val; \
if (regs.ps & AF_DECIMAL) { \
val = (regs.a & 0x0F) + (temp & 0x0F) + flagc; \
if (val > 0x09) \
val += 0x06; \
if (val <= 0x0F) \
val = (val & 0x0F) + (regs.a & 0xF0) + (temp & 0xF0); \
else \
val = (val & 0x0F) + (regs.a & 0xF0) + (temp & 0xF0) + 0x10;\
flagz = !((regs.a + temp + flagc) & 0xFF); \
flagn = (val & 0x80); \
flagv = ((regs.a ^ val) & 0x80) && !((regs.a ^ temp) & 0x80);\
if ((val & 0x1F0) > 0x90) \
val += 0x60; \
flagc = ((val & 0xFF0) > 0xF0); \
regs.a = val & 0xFF; \
} \
else { \
val = regs.a + temp + flagc; \
flagc = (val > 0xFF); \
flagv = (((regs.a & 0x80) == (temp & 0x80)) && \
((regs.a & 0x80) != (val & 0x80))); \
regs.a = val & 0xFF; \
SETNZ(regs.a); \
}
#define RTI regs.ps = POP | AF_RESERVED | AF_BREAK; \
AF_TO_EF \
regs.pc = POP; \
regs.pc |= (((WORD)POP) << 8);
#define RTS regs.pc = POP; \
regs.pc |= (((WORD)POP) << 8); \
++regs.pc;
#define SAX temp = regs.a & regs.x; \
val = READ; \
flagc = (temp >= val); \
regs.x = temp-val; \
SETNZ(regs.x)
#define SAY bSlowerOnPagecross = 0; \
val = regs.y & (((base >> 8) + 1) & 0xFF); \
WRITE(val)
#define SBC_NMOS bSlowerOnPagecross = 1; \
temp = READ; \
temp2 = regs.a - temp - !flagc; \
if (regs.ps & AF_DECIMAL) { \
val = (regs.a & 0x0F) - (temp & 0x0F) - !flagc; \
if (val & 0x10) \
val = ((val - 0x06) & 0x0F) | ((regs.a & 0xF0) - (temp & 0xF0) - 0x10);\
else \
val = (val & 0x0F) | ((regs.a & 0xF0) - (temp & 0xF0));\
if (val & 0x100) \
val -= 0x60; \
flagc = (temp2 < 0x100); \
SETNZ(temp2 & 0xFF); \
flagv = ((regs.a ^ temp2) & 0x80) && ((regs.a ^ temp) & 0x80);\
regs.a = val & 0xFF; \
} \
else { \
val = temp2; \
flagc = (val < 0x100); \
flagv = (((regs.a & 0x80) != (temp & 0x80)) && \
((regs.a & 0x80) != (val & 0x80))); \
regs.a = val & 0xFF; \
SETNZ(regs.a); \
}
#define SBC_CMOS bSlowerOnPagecross = 1; \
temp = READ; \
flagv = ((regs.a ^ temp) & 0x80); \
if (regs.ps & AF_DECIMAL) { \
uExtraCycles++; \
temp2 = 0x0F + (regs.a & 0x0F) - (temp & 0x0F) + flagc; \
if (temp2 < 0x10) { \
val = 0; \
temp2 -= 0x06; \
} \
else { \
val = 0x10; \
temp2 -= 0x10; \
} \
val += 0xF0 + (regs.a & 0xF0) - (temp & 0xF0); \
if (val < 0x100) { \
flagc = 0; \
if (val < 0x80) \
flagv = 0; \
val -= 0x60; \
} \
else { \
flagc = 1; \
if (val >= 0x180) \
flagv = 0; \
} \
val += temp2; \
} \
else { \
val = 0xff + regs.a - temp + flagc; \
if (val < 0x100) { \
flagc = 0; \
if (val < 0x80) \
flagv = 0; \
} \
else { \
flagc = 1; \
if (val >= 0x180) \
flagv = 0; \
} \
} \
regs.a = val & 0xFF; \
SETNZ(regs.a)
#define SEC flagc = 1;
#define SED regs.ps |= AF_DECIMAL;
#define SEI regs.ps |= AF_INTERRUPT;
#define STA bSlowerOnPagecross = 0; \
WRITE(regs.a)
#define STX bSlowerOnPagecross = 0; \
WRITE(regs.x)
#define STY bSlowerOnPagecross = 0; \
WRITE(regs.y)
#define STZ bSlowerOnPagecross = 0; \
WRITE(0)
#define TAS bSlowerOnPagecross = 0; \
val = regs.a & regs.x; \
regs.sp = 0x100 | val; \
val &= (((base >> 8) + 1) & 0xFF); \
WRITE(val)
#define TAX regs.x = regs.a; \
SETNZ(regs.x)
#define TAY regs.y = regs.a; \
SETNZ(regs.y)
#define TRB bSlowerOnPagecross = 0; \
val = READ; \
flagz = !(regs.a & val); \
val &= ~regs.a; \
WRITE(val)
#define TSB bSlowerOnPagecross = 0; \
val = READ; \
flagz = !(regs.a & val); \
val |= regs.a; \
WRITE(val)
#define TSX regs.x = regs.sp & 0xFF; \
SETNZ(regs.x)
#define TXA regs.a = regs.x; \
SETNZ(regs.a)
#define TXS regs.sp = 0x100 | regs.x;
#define TYA regs.a = regs.y; \
SETNZ(regs.a)
#define XAA regs.a = regs.x; \
regs.a &= READ; \
SETNZ(regs.a)
#define XAS bSlowerOnPagecross = 0; \
val = regs.x & (((base >> 8) + 1) & 0xFF); \
WRITE(val)