diff --git a/AppleWin/source/Applewin.cpp b/AppleWin/source/Applewin.cpp index e1411763..95d63fa5 100644 --- a/AppleWin/source/Applewin.cpp +++ b/AppleWin/source/Applewin.cpp @@ -46,9 +46,6 @@ bool g_bFullSpeed = false; // Win32 HINSTANCE g_hInstance = (HINSTANCE)0; -static DWORD lastfastpaging = 0; -static DWORD lasttrimimages = 0; - AppMode_e g_nAppMode = MODE_LOGO; static int lastmode = MODE_LOGO; @@ -70,21 +67,6 @@ bool g_bDisableDirectSound = false; //=========================================================================== -void CheckFastPaging () -{ - if ((pages >= 10) && CpuSupportsFastPaging()) - { - lastfastpaging = cumulativecycles; - if (cpuemtype == CPU_COMPILING) - { - lasttrimimages = cumulativecycles; - MemSetFastPaging(1); - } - } -} - -//=========================================================================== - #define DBG_CALC_FREQ 0 #if DBG_CALC_FREQ const UINT MAX_CNT = 256; @@ -145,7 +127,6 @@ void ContinueExecution() cyclenum = dwExecutedCycles; - CheckFastPaging(); DiskUpdatePosition(dwExecutedCycles); JoyUpdatePosition(); VideoUpdateVbl(g_dwCyclesThisFrame); @@ -155,21 +136,6 @@ void ContinueExecution() // - if (cpuemtype == CPU_FASTPAGING) //? - { - if ((!pages) && (cumulativecycles-lastfastpaging > 500000)) - { - MemSetFastPaging(0); - } - else if (cumulativecycles-lasttrimimages > 500000) - { - MemTrimImages(); - lasttrimimages = cumulativecycles; - } - } - - // - const DWORD CLKS_PER_MS = (DWORD)g_fCurrentCLK6502 / 1000; emulmsec_frac += dwExecutedCycles; @@ -179,8 +145,6 @@ void ContinueExecution() emulmsec_frac %= CLKS_PER_MS; } - pages = 0; //? - // // DETERMINE WHETHER THE SCREEN WAS UPDATED, THE DISK WAS SPINNING, // OR THE KEYBOARD I/O PORTS WERE BEING EXCESSIVELY QUERIED THIS CLOCKTICK diff --git a/AppleWin/source/CPU.cpp b/AppleWin/source/CPU.cpp index 07bfd728..0d14481b 100644 --- a/AppleWin/source/CPU.cpp +++ b/AppleWin/source/CPU.cpp @@ -99,33 +99,20 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define SHORTOPCODES 22 #define BENCHOPCODES 33 -typedef DWORD (__stdcall *cpuexecutetype)(DWORD); -typedef void (__stdcall *cpugetcodetype)(WORD,LPBYTE *,DWORD *); -typedef void (__stdcall *cpuinittype )(LPBYTE,LPBYTE *,LPBYTE *,DWORD,DWORD, - LPVOID,iofunction *,iofunction *,LPBYTE, - cxfunction, cxfunction); -typedef DWORD (__stdcall *cpuversiontype)(void); - +// What is this 6502 code? static BYTE benchopcode[BENCHOPCODES] = {0x06,0x16,0x24,0x45,0x48,0x65,0x68,0x76, 0x84,0x85,0x86,0x91,0x94,0xA4,0xA5,0xA6, 0xB1,0xB4,0xC0,0xC4,0xC5,0xE6, 0x19,0x6D,0x8D,0x99,0x9D,0xAD,0xB9,0xBD, 0xDD,0xED,0xEE}; -DWORD cpuemtype = CPU_COMPILING; -static cpuexecutetype cpuexecutefunc[3] = {NULL,NULL,NULL}; -static cpugetcodetype cpugetcodefunc[3] = {NULL,NULL,NULL}; -static cpuinittype cpuinitfunc[3] = {NULL,NULL,NULL}; -static cpuversiontype cpuversionfunc[3] = {NULL,NULL,NULL}; -static HINSTANCE cpulibrary[3] = {(HINSTANCE)0,(HINSTANCE)0,(HINSTANCE)0}; - regsrec regs; unsigned __int64 g_nCumulativeCycles = 0; static ULONG g_nCyclesSubmitted; // Number of cycles submitted to CpuExecute() static ULONG g_nCyclesExecuted; -static signed long nInternalCyclesLeft; +static signed long g_uInternalExecutedCycles; // @@ -156,17 +143,17 @@ static volatile BOOL g_bNmiFlank = FALSE; // Positive going flank on NMI line | (flagz ? AF_ZERO : 0) \ | AF_RESERVED | AF_BREAK; // CYC(a): This can be optimised, as only certain opcodes will affect uExtraCycles -#define CYC(a) cycles += (a)+uExtraCycles; MB_UpdateCycles((a)+uExtraCycles); +#define CYC(a) uExecutedCycles += (a)+uExtraCycles; MB_UpdateCycles((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 & 0xFF00) == 0xC000) \ - ? ioread[addr & 0xFF](regs.pc,(BYTE)addr,0,0,nInternalCyclesLeft) \ + ? ioread[addr & 0xFF](regs.pc,(BYTE)addr,0,0,uExecutedCycles) \ : ( \ (((addr & 0xFF00) == 0xC400) || ((addr & 0xFF00) == 0xC500)) \ - ? CxReadFunc(regs.pc, addr, 0, 0, nInternalCyclesLeft) \ + ? CxReadFunc(regs.pc, addr, 0, 0, uExecutedCycles) \ : *(mem+addr) \ ) \ ) @@ -181,9 +168,9 @@ static volatile BOOL g_bNmiFlank = FALSE; // Positive going flank on NMI line if (page) \ *(page+(addr & 0xFF)) = (BYTE)(a); \ else if ((addr & 0xFF00) == 0xC000) \ - iowrite[addr & 0xFF](regs.pc,(BYTE)addr,1,(BYTE)(a),nInternalCyclesLeft); \ + iowrite[addr & 0xFF](regs.pc,(BYTE)addr,1,(BYTE)(a),uExecutedCycles); \ else if(((addr & 0xFF00) == 0xC400) || ((addr & 0xFF00) == 0xC500)) \ - CxWriteFunc(regs.pc, addr, 1, (BYTE)(a), nInternalCyclesLeft); \ + CxWriteFunc(regs.pc, addr, 1, (BYTE)(a), uExecutedCycles); \ } // @@ -802,13 +789,13 @@ UINT g_nMean = 0; UINT g_nMin = 0xFFFFFFFF; UINT g_nMax = 0; -static inline void DoIrqProfiling(DWORD cycles) +static inline void DoIrqProfiling(DWORD uCycles) { #ifdef _DEBUG if(regs.ps & AF_INTERRUPT) return; // Still in Apple's ROM - g_nCycleIrqEnd = g_nCumulativeCycles + cycles; + g_nCycleIrqEnd = g_nCumulativeCycles + uCycles; g_nCycleIrqTime = (UINT) (g_nCycleIrqEnd - g_nCycleIrqStart); if(g_nCycleIrqTime > g_nMax) g_nMax = g_nCycleIrqTime; @@ -832,7 +819,8 @@ static inline void DoIrqProfiling(DWORD cycles) } //=========================================================================== -static DWORD InternalCpuExecute (DWORD totalcycles) + +static DWORD Cpu65C02 (DWORD uTotalCycles) { WORD addr; BOOL flagc; // must always be 0 or 1, no other values allowed @@ -843,624 +831,651 @@ static DWORD InternalCpuExecute (DWORD totalcycles) WORD temp2; WORD val; AF_TO_EF - DWORD cycles = 0; + DWORD uExecutedCycles = 0; BOOL bSlowerOnPagecross; // Set if opcode writes to memory (eg. ASL, STA) WORD base; bool bBreakOnInvalid = false; + do + { + g_uInternalExecutedCycles = uExecutedCycles; + USHORT uExtraCycles = 0; + + BYTE iOpcode = *(mem+regs.pc); + if (CheckDebugBreak( iOpcode )) + break; + + regs.pc++; + + switch (iOpcode) + { + case 0x00: BRK CYC(7) break; + case 0x01: INDX 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: ASLA 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: INDY ORA CYC(5) break; + case 0x12: IZPG ORA CYC(5) break; + case 0x13: INV NOP CYC(2) break; + case 0x14: ZPG TRB CYC(5) break; + case 0x15: ZPGX ORA CYC(4) break; + case 0x16: ZPGX ASL_CMOS CYC(6) break; + case 0x17: INV NOP CYC(2) break; + case 0x18: CLC CYC(2) break; + case 0x19: ABSY 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: ABSX ORA CYC(4) break; + case 0x1E: ABSX ASL_CMOS CYC(6) break; + case 0x1F: INV NOP CYC(2) break; + case 0x20: ABS JSR CYC(6) break; + case 0x21: INDX 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: ROLA 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: INDY AND CYC(5) break; + case 0x32: IZPG AND CYC(5) break; + case 0x33: INV NOP CYC(2) break; + case 0x34: ZPGX BIT CYC(4) break; + case 0x35: ZPGX AND CYC(4) break; + case 0x36: ZPGX ROL_CMOS CYC(6) break; + case 0x37: INV NOP CYC(2) break; + case 0x38: SEC CYC(2) break; + case 0x39: ABSY AND CYC(4) break; + case 0x3A: DEA CYC(2) break; + case 0x3B: INV NOP CYC(2) break; + case 0x3C: ABSX BIT CYC(4) break; + case 0x3D: ABSX AND CYC(4) break; + case 0x3E: ABSX ROL_CMOS CYC(6) break; + case 0x3F: INV NOP CYC(2) break; + case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; + case 0x41: INDX 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: LSRA 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: INDY EOR CYC(5) break; + case 0x52: IZPG EOR CYC(5) break; + case 0x53: INV NOP CYC(2) break; + case 0x54: INV ZPGX NOP CYC(4) break; + case 0x55: ZPGX EOR CYC(4) break; + case 0x56: ZPGX LSR_CMOS CYC(6) break; + case 0x57: INV NOP CYC(2) break; + case 0x58: CLI CYC(2) break; + case 0x59: ABSY EOR CYC(4) break; + case 0x5A: PHY CYC(3) break; + case 0x5B: INV NOP CYC(2) break; + case 0x5C: INV ABSX NOP CYC(8) break; + case 0x5D: ABSX EOR CYC(4) break; + case 0x5E: ABSX LSR_CMOS CYC(6) break; + case 0x5F: INV NOP CYC(2) break; + case 0x60: RTS CYC(6) break; + case 0x61: INDX 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: RORA CYC(2) break; + case 0x6B: INV NOP CYC(2) break; + case 0x6C: IABSCMOS JMP CYC(6) break; + 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: INDY ADC_CMOS CYC(5) break; + case 0x72: IZPG ADC_CMOS CYC(5) break; + case 0x73: INV NOP CYC(2) break; + case 0x74: ZPGX STZ CYC(4) break; + case 0x75: ZPGX ADC_CMOS CYC(4) break; + case 0x76: ZPGX ROR_CMOS CYC(6) break; + case 0x77: INV NOP CYC(2) break; + case 0x78: SEI CYC(2) break; + case 0x79: ABSY 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; + case 0x7D: ABSX ADC_CMOS CYC(4) break; + case 0x7E: ABSX ROR_CMOS CYC(6) break; + case 0x7F: INV NOP CYC(2) break; + case 0x80: REL BRA CYC(2) break; + case 0x81: INDX 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: INDY STA CYC(6) break; + case 0x92: IZPG STA CYC(5) break; + case 0x93: INV NOP CYC(2) break; + case 0x94: ZPGX STY CYC(4) break; + case 0x95: ZPGX STA CYC(4) break; + case 0x96: ZPGY STX CYC(4) break; + case 0x97: INV NOP CYC(2) break; + case 0x98: TYA CYC(2) break; + case 0x99: ABSY 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: ABSX STA CYC(5) break; + case 0x9E: ABSX STZ CYC(5) break; + case 0x9F: INV NOP CYC(2) break; + case 0xA0: IMM LDY CYC(2) break; + case 0xA1: INDX 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: INDY LDA CYC(5) break; + case 0xB2: IZPG LDA CYC(5) break; + case 0xB3: INV NOP CYC(2) break; + case 0xB4: ZPGX LDY CYC(4) break; + case 0xB5: ZPGX LDA CYC(4) break; + case 0xB6: ZPGY LDX CYC(4) break; + case 0xB7: INV NOP CYC(2) break; + case 0xB8: CLV CYC(2) break; + case 0xB9: ABSY LDA CYC(4) break; + case 0xBA: TSX CYC(2) break; + case 0xBB: INV NOP CYC(2) break; + case 0xBC: ABSX LDY CYC(4) break; + case 0xBD: ABSX LDA CYC(4) break; + case 0xBE: ABSY LDX CYC(4) break; + case 0xBF: INV NOP CYC(2) break; + case 0xC0: IMM CPY CYC(2) break; + case 0xC1: INDX 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: INDY CMP CYC(5) break; + case 0xD2: IZPG CMP CYC(5) break; + case 0xD3: INV NOP CYC(2) break; + case 0xD4: INV ZPGX NOP CYC(4) break; + case 0xD5: ZPGX CMP CYC(4) break; + case 0xD6: ZPGX DEC_CMOS CYC(6) break; + case 0xD7: INV NOP CYC(2) break; + case 0xD8: CLD CYC(2) break; + case 0xD9: ABSY CMP CYC(4) break; + case 0xDA: PHX CYC(3) break; + case 0xDB: INV NOP CYC(2) break; + case 0xDC: INV ABSX NOP CYC(4) break; + case 0xDD: ABSX CMP CYC(4) break; + case 0xDE: ABSX DEC_CMOS CYC(6) break; + case 0xDF: INV NOP CYC(2) break; + case 0xE0: IMM CPX CYC(2) break; + case 0xE1: INDX 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: INDY SBC_CMOS CYC(5) break; + case 0xF2: IZPG SBC_CMOS CYC(5) break; + case 0xF3: INV NOP CYC(2) break; + case 0xF4: INV ZPGX NOP CYC(4) break; + case 0xF5: ZPGX SBC_CMOS CYC(4) break; + case 0xF6: ZPGX INC_CMOS CYC(6) break; + case 0xF7: INV NOP CYC(2) break; + case 0xF8: SED CYC(2) break; + case 0xF9: ABSY SBC_CMOS CYC(4) break; + case 0xFA: PLX CYC(4) break; + case 0xFB: INV NOP CYC(2) break; + case 0xFC: INV ABSX NOP CYC(4) break; + case 0xFD: ABSX SBC_CMOS CYC(4) break; + case 0xFE: ABSX INC_CMOS CYC(6) break; + case 0xFF: INV NOP CYC(2) break; + } + + if(g_bNmiFlank) + { + // NMI signals are only serviced once + g_bNmiFlank = FALSE; + g_nCycleIrqStart = g_nCumulativeCycles + uExecutedCycles; + PUSH(regs.pc >> 8) + PUSH(regs.pc & 0xFF) + EF_TO_AF + PUSH(regs.ps & ~AF_BREAK) + regs.ps = regs.ps | AF_INTERRUPT & ~AF_DECIMAL; + regs.pc = * (WORD*) (mem+0xFFFA); + CYC(7) + } + + if(g_bmIRQ && !(regs.ps & AF_INTERRUPT)) + { + // IRQ signals are deasserted when a specific r/w operation is done on device + g_nCycleIrqStart = g_nCumulativeCycles + uExecutedCycles; + PUSH(regs.pc >> 8) + PUSH(regs.pc & 0xFF) + EF_TO_AF + PUSH(regs.ps & ~AF_BREAK) + regs.ps = regs.ps | AF_INTERRUPT & ~AF_DECIMAL; + regs.pc = * (WORD*) (mem+0xFFFE); + CYC(7) + } + + if (bBreakOnInvalid) + break; + + } while (uExecutedCycles < uTotalCycles); + + EF_TO_AF + return uExecutedCycles; +} + +//=========================================================================== + +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 + DWORD uExecutedCycles = 0; + BOOL bSlowerOnPagecross; // Set if opcode writes to memory (eg. ASL, STA) + WORD base; + bool bBreakOnInvalid = false; + + do + { + g_uInternalExecutedCycles = uExecutedCycles; + USHORT uExtraCycles = 0; + + BYTE iOpcode = *(mem+regs.pc); + if (CheckDebugBreak( iOpcode )) + break; + + regs.pc++; + + switch (iOpcode) + { + case 0x00: BRK CYC(7) break; + case 0x01: INDX ORA CYC(6) break; + case 0x02: INV HLT CYC(2) break; + case 0x03: INV INDX ASO CYC(8) break; + case 0x04: INV ZPG NOP CYC(3) break; + case 0x05: ZPG ORA CYC(3) break; + case 0x06: ZPG ASL_NMOS CYC(5) break; + case 0x07: INV ZPG ASO CYC(5) break; + case 0x08: PHP CYC(3) break; + case 0x09: IMM ORA CYC(2) break; + case 0x0A: ASLA CYC(2) break; + case 0x0B: INV IMM ANC CYC(2) break; + case 0x0C: INV ABSX NOP CYC(4) break; + case 0x0D: ABS ORA CYC(4) break; + case 0x0E: ABS ASL_NMOS CYC(6) break; + case 0x0F: INV ABS ASO CYC(6) break; + case 0x10: REL BPL CYC(2) break; + case 0x11: INDY ORA CYC(5) break; + case 0x12: INV HLT CYC(2) break; + case 0x13: INV INDY ASO CYC(8) break; + case 0x14: INV ZPGX NOP CYC(4) break; + case 0x15: ZPGX ORA CYC(4) break; + case 0x16: ZPGX ASL_NMOS CYC(6) break; + case 0x17: INV ZPGX ASO CYC(6) break; + case 0x18: CLC CYC(2) break; + case 0x19: ABSY ORA CYC(4) break; + case 0x1A: INV NOP CYC(2) break; + case 0x1B: INV ABSY ASO CYC(7) break; + case 0x1C: INV ABSX NOP CYC(4) break; + case 0x1D: ABSX ORA CYC(4) break; + case 0x1E: ABSX ASL_NMOS CYC(6) break; + case 0x1F: INV ABSX ASO CYC(7) break; + case 0x20: ABS JSR CYC(6) break; + case 0x21: INDX AND CYC(6) break; + case 0x22: INV HLT CYC(2) break; + case 0x23: INV INDX RLA CYC(8) break; + case 0x24: ZPG BIT CYC(3) break; + case 0x25: ZPG AND CYC(3) break; + case 0x26: ZPG ROL_NMOS CYC(5) break; + case 0x27: INV ZPG RLA CYC(5) break; + case 0x28: PLP CYC(4) break; + case 0x29: IMM AND CYC(2) break; + case 0x2A: ROLA CYC(2) break; + case 0x2B: INV IMM ANC CYC(2) break; + case 0x2C: ABS BIT CYC(4) break; + case 0x2D: ABS AND CYC(2) break; + case 0x2E: ABS ROL_NMOS CYC(6) break; + case 0x2F: INV ABS RLA CYC(6) break; + case 0x30: REL BMI CYC(2) break; + case 0x31: INDY AND CYC(5) break; + case 0x32: INV HLT CYC(2) break; + case 0x33: INV INDY RLA CYC(8) break; + case 0x34: INV ZPGX NOP CYC(4) break; + case 0x35: ZPGX AND CYC(4) break; + case 0x36: ZPGX ROL_NMOS CYC(6) break; + case 0x37: INV ZPGX RLA CYC(6) break; + case 0x38: SEC CYC(2) break; + case 0x39: ABSY AND CYC(4) break; + case 0x3A: INV NOP CYC(2) break; + case 0x3B: INV ABSY RLA CYC(7) break; + case 0x3C: INV ABSX NOP CYC(4) break; + case 0x3D: ABSX AND CYC(4) break; + case 0x3E: ABSX ROL_NMOS CYC(6) break; + case 0x3F: INV ABSX RLA CYC(7) break; + case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; + case 0x41: INDX EOR CYC(6) break; + case 0x42: INV HLT CYC(2) break; + case 0x43: INV INDX LSE CYC(8) break; + case 0x44: INV ZPG NOP CYC(3) break; + case 0x45: ZPG EOR CYC(3) break; + case 0x46: ZPG LSR_NMOS CYC(5) break; + case 0x47: INV ZPG LSE CYC(5) break; + case 0x48: PHA CYC(3) break; + case 0x49: IMM EOR CYC(2) break; + case 0x4A: LSRA CYC(2) break; + case 0x4B: INV IMM ALR CYC(2) break; + case 0x4C: ABS JMP CYC(3) break; + case 0x4D: ABS EOR CYC(4) break; + case 0x4E: ABS LSR_NMOS CYC(6) break; + case 0x4F: INV ABS LSE CYC(6) break; + case 0x50: REL BVC CYC(2) break; + case 0x51: INDY EOR CYC(5) break; + case 0x52: INV HLT CYC(2) break; + case 0x53: INV INDY LSE CYC(8) break; + case 0x54: INV ZPGX NOP CYC(4) break; + case 0x55: ZPGX EOR CYC(4) break; + case 0x56: ZPGX LSR_NMOS CYC(6) break; + case 0x57: INV ZPGX LSE CYC(6) break; + case 0x58: CLI CYC(2) break; + case 0x59: ABSY EOR CYC(4) break; + case 0x5A: INV NOP CYC(2) break; + case 0x5B: INV ABSY LSE CYC(7) break; + case 0x5C: INV ABSX NOP CYC(4) break; + case 0x5D: ABSX EOR CYC(4) break; + case 0x5E: ABSX LSR_NMOS CYC(6) break; + case 0x5F: INV ABSX LSE CYC(7) break; + case 0x60: RTS CYC(6) break; + case 0x61: INDX ADC_NMOS CYC(6) break; + case 0x62: INV HLT CYC(2) break; + case 0x63: INV INDX RRA CYC(8) break; + case 0x64: INV ZPG NOP CYC(3) break; + case 0x65: ZPG ADC_NMOS CYC(3) break; + case 0x66: ZPG ROR_NMOS CYC(5) break; + case 0x67: INV ZPG RRA CYC(5) break; + case 0x68: PLA CYC(4) break; + case 0x69: IMM ADC_NMOS CYC(2) break; + case 0x6A: RORA CYC(2) break; + case 0x6B: INV IMM ARR CYC(2) break; + case 0x6C: IABSNMOS JMP CYC(6) break; + case 0x6D: ABS ADC_NMOS CYC(4) break; + case 0x6E: ABS ROR_NMOS CYC(6) break; + case 0x6F: INV ABS RRA CYC(6) break; + case 0x70: REL BVS CYC(2) break; + case 0x71: INDY ADC_NMOS CYC(5) break; + case 0x72: INV HLT CYC(2) break; + case 0x73: INV INDY RRA CYC(8) break; + case 0x74: INV ZPGX NOP CYC(4) break; + case 0x75: ZPGX ADC_NMOS CYC(4) break; + case 0x76: ZPGX ROR_NMOS CYC(6) break; + case 0x77: INV ZPGX RRA CYC(6) break; + case 0x78: SEI CYC(2) break; + case 0x79: ABSY ADC_NMOS CYC(4) break; + case 0x7A: INV NOP CYC(2) break; + case 0x7B: INV ABSY RRA CYC(7) break; + case 0x7C: INV ABSX NOP CYC(4) break; + case 0x7D: ABSX ADC_NMOS CYC(4) break; + case 0x7E: ABSX ROR_NMOS CYC(6) break; + case 0x7F: INV ABSX RRA CYC(7) break; + case 0x80: INV IMM NOP CYC(2) break; + case 0x81: INDX STA CYC(6) break; + case 0x82: INV IMM NOP CYC(2) break; + case 0x83: INV INDX AXS CYC(6) 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 ZPG AXS CYC(3) break; + case 0x88: DEY CYC(2) break; + case 0x89: INV IMM NOP CYC(2) break; + case 0x8A: TXA CYC(2) break; + case 0x8B: INV IMM XAA 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 ABS AXS CYC(4) break; + case 0x90: REL BCC CYC(2) break; + case 0x91: INDY STA CYC(6) break; + case 0x92: INV HLT CYC(2) break; + case 0x93: INV INDY AXA CYC(6) break; + case 0x94: ZPGX STY CYC(4) break; + case 0x95: ZPGX STA CYC(4) break; + case 0x96: ZPGY STX CYC(4) break; + case 0x97: INV ZPGY AXS CYC(4) break; + case 0x98: TYA CYC(2) break; + case 0x99: ABSY STA CYC(5) break; + case 0x9A: TXS CYC(2) break; + case 0x9B: INV ABSY TAS CYC(5) break; + case 0x9C: INV ABSX SAY CYC(5) break; + case 0x9D: ABSX STA CYC(5) break; + case 0x9E: INV ABSY XAS CYC(5) break; + case 0x9F: INV ABSY AXA CYC(5) break; + case 0xA0: IMM LDY CYC(2) break; + case 0xA1: INDX LDA CYC(6) break; + case 0xA2: IMM LDX CYC(2) break; + case 0xA3: INV INDX LAX CYC(6) 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 ZPG LAX CYC(3) break; + case 0xA8: TAY CYC(2) break; + case 0xA9: IMM LDA CYC(2) break; + case 0xAA: TAX CYC(2) break; + case 0xAB: INV IMM OAL 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 ABS LAX CYC(4) break; + case 0xB0: REL BCS CYC(2) break; + case 0xB1: INDY LDA CYC(5) break; + case 0xB2: INV HLT CYC(2) break; + case 0xB3: INV INDY LAX CYC(5) break; + case 0xB4: ZPGX LDY CYC(4) break; + case 0xB5: ZPGX LDA CYC(4) break; + case 0xB6: ZPGY LDX CYC(4) break; + case 0xB7: INV ZPGY LAX CYC(4) break; + case 0xB8: CLV CYC(2) break; + case 0xB9: ABSY LDA CYC(4) break; + case 0xBA: TSX CYC(2) break; + case 0xBB: INV ABSY LAS CYC(4) break; + case 0xBC: ABSX LDY CYC(4) break; + case 0xBD: ABSX LDA CYC(4) break; + case 0xBE: ABSY LDX CYC(4) break; + case 0xBF: INV ABSY LAX CYC(4) break; + case 0xC0: IMM CPY CYC(2) break; + case 0xC1: INDX CMP CYC(6) break; + case 0xC2: INV IMM NOP CYC(2) break; + case 0xC3: INV INDX DCM CYC(8) break; + case 0xC4: ZPG CPY CYC(3) break; + case 0xC5: ZPG CMP CYC(3) break; + case 0xC6: ZPG DEC_NMOS CYC(5) break; + case 0xC7: INV ZPG DCM CYC(5) break; + case 0xC8: INY CYC(2) break; + case 0xC9: IMM CMP CYC(2) break; + case 0xCA: DEX CYC(2) break; + case 0xCB: INV IMM SAX CYC(2) break; + case 0xCC: ABS CPY CYC(4) break; + case 0xCD: ABS CMP CYC(4) break; + case 0xCE: ABS DEC_NMOS CYC(5) break; + case 0xCF: INV ABS DCM CYC(6) break; + case 0xD0: REL BNE CYC(2) break; + case 0xD1: INDY CMP CYC(5) break; + case 0xD2: INV HLT CYC(2) break; + case 0xD3: INV INDY DCM CYC(8) break; + case 0xD4: INV ZPGX NOP CYC(4) break; + case 0xD5: ZPGX CMP CYC(4) break; + case 0xD6: ZPGX DEC_NMOS CYC(6) break; + case 0xD7: INV ZPGX DCM CYC(6) break; + case 0xD8: CLD CYC(2) break; + case 0xD9: ABSY CMP CYC(4) break; + case 0xDA: INV NOP CYC(2) break; + case 0xDB: INV ABSY DCM CYC(7) break; + case 0xDC: INV ABSX NOP CYC(4) break; + case 0xDD: ABSX CMP CYC(4) break; + case 0xDE: ABSX DEC_NMOS CYC(6) break; + case 0xDF: INV ABSX DCM CYC(7) break; + case 0xE0: IMM CPX CYC(2) break; + case 0xE1: INDX SBC_NMOS CYC(6) break; + case 0xE2: INV IMM NOP CYC(2) break; + case 0xE3: INV INDX INS CYC(8) break; + case 0xE4: ZPG CPX CYC(3) break; + case 0xE5: ZPG SBC_NMOS CYC(3) break; + case 0xE6: ZPG INC_NMOS CYC(5) break; + case 0xE7: INV ZPG INS CYC(5) break; + case 0xE8: INX CYC(2) break; + case 0xE9: IMM SBC_NMOS CYC(2) break; + case 0xEA: NOP CYC(2) break; + case 0xEB: INV IMM SBC_NMOS CYC(2) break; + case 0xEC: ABS CPX CYC(4) break; + case 0xED: ABS SBC_NMOS CYC(4) break; + case 0xEE: ABS INC_NMOS CYC(6) break; + case 0xEF: INV ABS INS CYC(6) break; + case 0xF0: REL BEQ CYC(2) break; + case 0xF1: INDY SBC_NMOS CYC(5) break; + case 0xF2: INV HLT CYC(2) break; + case 0xF3: INV INDY INS CYC(8) break; + case 0xF4: INV ZPGX NOP CYC(4) break; + case 0xF5: ZPGX SBC_NMOS CYC(4) break; + case 0xF6: ZPGX INC_NMOS CYC(6) break; + case 0xF7: INV ZPGX INS CYC(6) break; + case 0xF8: SED CYC(2) break; + case 0xF9: ABSY SBC_NMOS CYC(4) break; + case 0xFA: INV NOP CYC(2) break; + case 0xFB: INV ABSY INS CYC(7) break; + case 0xFC: INV ABSX NOP CYC(4) break; + case 0xFD: ABSX SBC_NMOS CYC(4) break; + case 0xFE: ABSX INC_NMOS CYC(6) break; + case 0xFF: INV ABSX INS CYC(7) break; + } + + if(g_bNmiFlank && !regs.bJammed) + { + // NMI signals are only serviced once + g_bNmiFlank = FALSE; + g_nCycleIrqStart = g_nCumulativeCycles + uExecutedCycles; + PUSH(regs.pc >> 8) + PUSH(regs.pc & 0xFF) + EF_TO_AF + PUSH(regs.ps & ~AF_BREAK) + regs.ps = regs.ps | AF_INTERRUPT; + regs.pc = * (WORD*) (mem+0xFFFA); + CYC(7) + } + + if(g_bmIRQ && !(regs.ps & AF_INTERRUPT) && !regs.bJammed) + { + // IRQ signals are deasserted when a specific r/w operation is done on device + g_nCycleIrqStart = g_nCumulativeCycles + uExecutedCycles; + PUSH(regs.pc >> 8) + PUSH(regs.pc & 0xFF) + EF_TO_AF + PUSH(regs.ps & ~AF_BREAK) + regs.ps = regs.ps | AF_INTERRUPT; + regs.pc = * (WORD*) (mem+0xFFFE); + CYC(7) + } + + if (bBreakOnInvalid) + break; + + } while (uExecutedCycles < uTotalCycles); + + EF_TO_AF + return uExecutedCycles; +} + +//=========================================================================== + +static DWORD InternalCpuExecute (DWORD uTotalCycles) +{ if (g_bApple2e) - { - do - { - nInternalCyclesLeft = (totalcycles<<8) - (cycles<<8); - USHORT uExtraCycles = 0; - - BYTE iOpcode = *(mem+regs.pc); - if (CheckDebugBreak( iOpcode )) - break; - - regs.pc++; - - switch (iOpcode) - { - case 0x00: BRK CYC(7) break; - case 0x01: INDX 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: ASLA 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: INDY ORA CYC(5) break; - case 0x12: IZPG ORA CYC(5) break; - case 0x13: INV NOP CYC(2) break; - case 0x14: ZPG TRB CYC(5) break; - case 0x15: ZPGX ORA CYC(4) break; - case 0x16: ZPGX ASL_CMOS CYC(6) break; - case 0x17: INV NOP CYC(2) break; - case 0x18: CLC CYC(2) break; - case 0x19: ABSY 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: ABSX ORA CYC(4) break; - case 0x1E: ABSX ASL_CMOS CYC(6) break; - case 0x1F: INV NOP CYC(2) break; - case 0x20: ABS JSR CYC(6) break; - case 0x21: INDX 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: ROLA 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: INDY AND CYC(5) break; - case 0x32: IZPG AND CYC(5) break; - case 0x33: INV NOP CYC(2) break; - case 0x34: ZPGX BIT CYC(4) break; - case 0x35: ZPGX AND CYC(4) break; - case 0x36: ZPGX ROL_CMOS CYC(6) break; - case 0x37: INV NOP CYC(2) break; - case 0x38: SEC CYC(2) break; - case 0x39: ABSY AND CYC(4) break; - case 0x3A: DEA CYC(2) break; - case 0x3B: INV NOP CYC(2) break; - case 0x3C: ABSX BIT CYC(4) break; - case 0x3D: ABSX AND CYC(4) break; - case 0x3E: ABSX ROL_CMOS CYC(6) break; - case 0x3F: INV NOP CYC(2) break; - case 0x40: RTI CYC(6) DoIrqProfiling(cycles); break; - case 0x41: INDX 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: LSRA 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: INDY EOR CYC(5) break; - case 0x52: IZPG EOR CYC(5) break; - case 0x53: INV NOP CYC(2) break; - case 0x54: INV ZPGX NOP CYC(4) break; - case 0x55: ZPGX EOR CYC(4) break; - case 0x56: ZPGX LSR_CMOS CYC(6) break; - case 0x57: INV NOP CYC(2) break; - case 0x58: CLI CYC(2) break; - case 0x59: ABSY EOR CYC(4) break; - case 0x5A: PHY CYC(3) break; - case 0x5B: INV NOP CYC(2) break; - case 0x5C: INV ABSX NOP CYC(8) break; - case 0x5D: ABSX EOR CYC(4) break; - case 0x5E: ABSX LSR_CMOS CYC(6) break; - case 0x5F: INV NOP CYC(2) break; - case 0x60: RTS CYC(6) break; - case 0x61: INDX 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: RORA CYC(2) break; - case 0x6B: INV NOP CYC(2) break; - case 0x6C: IABSCMOS JMP CYC(6) break; - 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: INDY ADC_CMOS CYC(5) break; - case 0x72: IZPG ADC_CMOS CYC(5) break; - case 0x73: INV NOP CYC(2) break; - case 0x74: ZPGX STZ CYC(4) break; - case 0x75: ZPGX ADC_CMOS CYC(4) break; - case 0x76: ZPGX ROR_CMOS CYC(6) break; - case 0x77: INV NOP CYC(2) break; - case 0x78: SEI CYC(2) break; - case 0x79: ABSY 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; - case 0x7D: ABSX ADC_CMOS CYC(4) break; - case 0x7E: ABSX ROR_CMOS CYC(6) break; - case 0x7F: INV NOP CYC(2) break; - case 0x80: REL BRA CYC(2) break; - case 0x81: INDX 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: INDY STA CYC(6) break; - case 0x92: IZPG STA CYC(5) break; - case 0x93: INV NOP CYC(2) break; - case 0x94: ZPGX STY CYC(4) break; - case 0x95: ZPGX STA CYC(4) break; - case 0x96: ZPGY STX CYC(4) break; - case 0x97: INV NOP CYC(2) break; - case 0x98: TYA CYC(2) break; - case 0x99: ABSY 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: ABSX STA CYC(5) break; - case 0x9E: ABSX STZ CYC(5) break; - case 0x9F: INV NOP CYC(2) break; - case 0xA0: IMM LDY CYC(2) break; - case 0xA1: INDX 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: INDY LDA CYC(5) break; - case 0xB2: IZPG LDA CYC(5) break; - case 0xB3: INV NOP CYC(2) break; - case 0xB4: ZPGX LDY CYC(4) break; - case 0xB5: ZPGX LDA CYC(4) break; - case 0xB6: ZPGY LDX CYC(4) break; - case 0xB7: INV NOP CYC(2) break; - case 0xB8: CLV CYC(2) break; - case 0xB9: ABSY LDA CYC(4) break; - case 0xBA: TSX CYC(2) break; - case 0xBB: INV NOP CYC(2) break; - case 0xBC: ABSX LDY CYC(4) break; - case 0xBD: ABSX LDA CYC(4) break; - case 0xBE: ABSY LDX CYC(4) break; - case 0xBF: INV NOP CYC(2) break; - case 0xC0: IMM CPY CYC(2) break; - case 0xC1: INDX 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: INDY CMP CYC(5) break; - case 0xD2: IZPG CMP CYC(5) break; - case 0xD3: INV NOP CYC(2) break; - case 0xD4: INV ZPGX NOP CYC(4) break; - case 0xD5: ZPGX CMP CYC(4) break; - case 0xD6: ZPGX DEC_CMOS CYC(6) break; - case 0xD7: INV NOP CYC(2) break; - case 0xD8: CLD CYC(2) break; - case 0xD9: ABSY CMP CYC(4) break; - case 0xDA: PHX CYC(3) break; - case 0xDB: INV NOP CYC(2) break; - case 0xDC: INV ABSX NOP CYC(4) break; - case 0xDD: ABSX CMP CYC(4) break; - case 0xDE: ABSX DEC_CMOS CYC(6) break; - case 0xDF: INV NOP CYC(2) break; - case 0xE0: IMM CPX CYC(2) break; - case 0xE1: INDX 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: INDY SBC_CMOS CYC(5) break; - case 0xF2: IZPG SBC_CMOS CYC(5) break; - case 0xF3: INV NOP CYC(2) break; - case 0xF4: INV ZPGX NOP CYC(4) break; - case 0xF5: ZPGX SBC_CMOS CYC(4) break; - case 0xF6: ZPGX INC_CMOS CYC(6) break; - case 0xF7: INV NOP CYC(2) break; - case 0xF8: SED CYC(2) break; - case 0xF9: ABSY SBC_CMOS CYC(4) break; - case 0xFA: PLX CYC(4) break; - case 0xFB: INV NOP CYC(2) break; - case 0xFC: INV ABSX NOP CYC(4) break; - case 0xFD: ABSX SBC_CMOS CYC(4) break; - case 0xFE: ABSX INC_CMOS CYC(6) break; - case 0xFF: INV NOP CYC(2) break; - } - - if(g_bNmiFlank) - { - // NMI signals are only serviced once - g_bNmiFlank = FALSE; - g_nCycleIrqStart = g_nCumulativeCycles + cycles; - PUSH(regs.pc >> 8) - PUSH(regs.pc & 0xFF) - EF_TO_AF - PUSH(regs.ps & ~AF_BREAK) - regs.ps = regs.ps | AF_INTERRUPT & ~AF_DECIMAL; - regs.pc = * (WORD*) (mem+0xFFFA); - CYC(7) - } - - if(g_bmIRQ && !(regs.ps & AF_INTERRUPT)) - { - // IRQ signals are deasserted when a specific r/w operation is done on device - g_nCycleIrqStart = g_nCumulativeCycles + cycles; - PUSH(regs.pc >> 8) - PUSH(regs.pc & 0xFF) - EF_TO_AF - PUSH(regs.ps & ~AF_BREAK) - regs.ps = regs.ps | AF_INTERRUPT & ~AF_DECIMAL; - regs.pc = * (WORD*) (mem+0xFFFE); - CYC(7) - } - - if (bBreakOnInvalid) - break; - } while (cycles < totalcycles); - EF_TO_AF - return cycles; - } + return Cpu65C02(uTotalCycles); else // Apple ][ - { - do - { - nInternalCyclesLeft = (totalcycles<<8) - (cycles<<8); - USHORT uExtraCycles = 0; - - BYTE iOpcode = *(mem+regs.pc); - if (CheckDebugBreak( iOpcode )) - break; - - regs.pc++; - - switch (iOpcode) - { - case 0x00: BRK CYC(7) break; - case 0x01: INDX ORA CYC(6) break; - case 0x02: INV HLT CYC(2) break; - case 0x03: INV INDX ASO CYC(8) break; - case 0x04: INV ZPG NOP CYC(3) break; - case 0x05: ZPG ORA CYC(3) break; - case 0x06: ZPG ASL_NMOS CYC(5) break; - case 0x07: INV ZPG ASO CYC(5) break; - case 0x08: PHP CYC(3) break; - case 0x09: IMM ORA CYC(2) break; - case 0x0A: ASLA CYC(2) break; - case 0x0B: INV IMM ANC CYC(2) break; - case 0x0C: INV ABSX NOP CYC(4) break; - case 0x0D: ABS ORA CYC(4) break; - case 0x0E: ABS ASL_NMOS CYC(6) break; - case 0x0F: INV ABS ASO CYC(6) break; - case 0x10: REL BPL CYC(2) break; - case 0x11: INDY ORA CYC(5) break; - case 0x12: INV HLT CYC(2) break; - case 0x13: INV INDY ASO CYC(8) break; - case 0x14: INV ZPGX NOP CYC(4) break; - case 0x15: ZPGX ORA CYC(4) break; - case 0x16: ZPGX ASL_NMOS CYC(6) break; - case 0x17: INV ZPGX ASO CYC(6) break; - case 0x18: CLC CYC(2) break; - case 0x19: ABSY ORA CYC(4) break; - case 0x1A: INV NOP CYC(2) break; - case 0x1B: INV ABSY ASO CYC(7) break; - case 0x1C: INV ABSX NOP CYC(4) break; - case 0x1D: ABSX ORA CYC(4) break; - case 0x1E: ABSX ASL_NMOS CYC(6) break; - case 0x1F: INV ABSX ASO CYC(7) break; - case 0x20: ABS JSR CYC(6) break; - case 0x21: INDX AND CYC(6) break; - case 0x22: INV HLT CYC(2) break; - case 0x23: INV INDX RLA CYC(8) break; - case 0x24: ZPG BIT CYC(3) break; - case 0x25: ZPG AND CYC(3) break; - case 0x26: ZPG ROL_NMOS CYC(5) break; - case 0x27: INV ZPG RLA CYC(5) break; - case 0x28: PLP CYC(4) break; - case 0x29: IMM AND CYC(2) break; - case 0x2A: ROLA CYC(2) break; - case 0x2B: INV IMM ANC CYC(2) break; - case 0x2C: ABS BIT CYC(4) break; - case 0x2D: ABS AND CYC(2) break; - case 0x2E: ABS ROL_NMOS CYC(6) break; - case 0x2F: INV ABS RLA CYC(6) break; - case 0x30: REL BMI CYC(2) break; - case 0x31: INDY AND CYC(5) break; - case 0x32: INV HLT CYC(2) break; - case 0x33: INV INDY RLA CYC(8) break; - case 0x34: INV ZPGX NOP CYC(4) break; - case 0x35: ZPGX AND CYC(4) break; - case 0x36: ZPGX ROL_NMOS CYC(6) break; - case 0x37: INV ZPGX RLA CYC(6) break; - case 0x38: SEC CYC(2) break; - case 0x39: ABSY AND CYC(4) break; - case 0x3A: INV NOP CYC(2) break; - case 0x3B: INV ABSY RLA CYC(7) break; - case 0x3C: INV ABSX NOP CYC(4) break; - case 0x3D: ABSX AND CYC(4) break; - case 0x3E: ABSX ROL_NMOS CYC(6) break; - case 0x3F: INV ABSX RLA CYC(7) break; - case 0x40: RTI CYC(6) DoIrqProfiling(cycles); break; - case 0x41: INDX EOR CYC(6) break; - case 0x42: INV HLT CYC(2) break; - case 0x43: INV INDX LSE CYC(8) break; - case 0x44: INV ZPG NOP CYC(3) break; - case 0x45: ZPG EOR CYC(3) break; - case 0x46: ZPG LSR_NMOS CYC(5) break; - case 0x47: INV ZPG LSE CYC(5) break; - case 0x48: PHA CYC(3) break; - case 0x49: IMM EOR CYC(2) break; - case 0x4A: LSRA CYC(2) break; - case 0x4B: INV IMM ALR CYC(2) break; - case 0x4C: ABS JMP CYC(3) break; - case 0x4D: ABS EOR CYC(4) break; - case 0x4E: ABS LSR_NMOS CYC(6) break; - case 0x4F: INV ABS LSE CYC(6) break; - case 0x50: REL BVC CYC(2) break; - case 0x51: INDY EOR CYC(5) break; - case 0x52: INV HLT CYC(2) break; - case 0x53: INV INDY LSE CYC(8) break; - case 0x54: INV ZPGX NOP CYC(4) break; - case 0x55: ZPGX EOR CYC(4) break; - case 0x56: ZPGX LSR_NMOS CYC(6) break; - case 0x57: INV ZPGX LSE CYC(6) break; - case 0x58: CLI CYC(2) break; - case 0x59: ABSY EOR CYC(4) break; - case 0x5A: INV NOP CYC(2) break; - case 0x5B: INV ABSY LSE CYC(7) break; - case 0x5C: INV ABSX NOP CYC(4) break; - case 0x5D: ABSX EOR CYC(4) break; - case 0x5E: ABSX LSR_NMOS CYC(6) break; - case 0x5F: INV ABSX LSE CYC(7) break; - case 0x60: RTS CYC(6) break; - case 0x61: INDX ADC_NMOS CYC(6) break; - case 0x62: INV HLT CYC(2) break; - case 0x63: INV INDX RRA CYC(8) break; - case 0x64: INV ZPG NOP CYC(3) break; - case 0x65: ZPG ADC_NMOS CYC(3) break; - case 0x66: ZPG ROR_NMOS CYC(5) break; - case 0x67: INV ZPG RRA CYC(5) break; - case 0x68: PLA CYC(4) break; - case 0x69: IMM ADC_NMOS CYC(2) break; - case 0x6A: RORA CYC(2) break; - case 0x6B: INV IMM ARR CYC(2) break; - case 0x6C: IABSNMOS JMP CYC(6) break; - case 0x6D: ABS ADC_NMOS CYC(4) break; - case 0x6E: ABS ROR_NMOS CYC(6) break; - case 0x6F: INV ABS RRA CYC(6) break; - case 0x70: REL BVS CYC(2) break; - case 0x71: INDY ADC_NMOS CYC(5) break; - case 0x72: INV HLT CYC(2) break; - case 0x73: INV INDY RRA CYC(8) break; - case 0x74: INV ZPGX NOP CYC(4) break; - case 0x75: ZPGX ADC_NMOS CYC(4) break; - case 0x76: ZPGX ROR_NMOS CYC(6) break; - case 0x77: INV ZPGX RRA CYC(6) break; - case 0x78: SEI CYC(2) break; - case 0x79: ABSY ADC_NMOS CYC(4) break; - case 0x7A: INV NOP CYC(2) break; - case 0x7B: INV ABSY RRA CYC(7) break; - case 0x7C: INV ABSX NOP CYC(4) break; - case 0x7D: ABSX ADC_NMOS CYC(4) break; - case 0x7E: ABSX ROR_NMOS CYC(6) break; - case 0x7F: INV ABSX RRA CYC(7) break; - case 0x80: INV IMM NOP CYC(2) break; - case 0x81: INDX STA CYC(6) break; - case 0x82: INV IMM NOP CYC(2) break; - case 0x83: INV INDX AXS CYC(6) 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 ZPG AXS CYC(3) break; - case 0x88: DEY CYC(2) break; - case 0x89: INV IMM NOP CYC(2) break; - case 0x8A: TXA CYC(2) break; - case 0x8B: INV IMM XAA 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 ABS AXS CYC(4) break; - case 0x90: REL BCC CYC(2) break; - case 0x91: INDY STA CYC(6) break; - case 0x92: INV HLT CYC(2) break; - case 0x93: INV INDY AXA CYC(6) break; - case 0x94: ZPGX STY CYC(4) break; - case 0x95: ZPGX STA CYC(4) break; - case 0x96: ZPGY STX CYC(4) break; - case 0x97: INV ZPGY AXS CYC(4) break; - case 0x98: TYA CYC(2) break; - case 0x99: ABSY STA CYC(5) break; - case 0x9A: TXS CYC(2) break; - case 0x9B: INV ABSY TAS CYC(5) break; - case 0x9C: INV ABSX SAY CYC(5) break; - case 0x9D: ABSX STA CYC(5) break; - case 0x9E: INV ABSY XAS CYC(5) break; - case 0x9F: INV ABSY AXA CYC(5) break; - case 0xA0: IMM LDY CYC(2) break; - case 0xA1: INDX LDA CYC(6) break; - case 0xA2: IMM LDX CYC(2) break; - case 0xA3: INV INDX LAX CYC(6) 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 ZPG LAX CYC(3) break; - case 0xA8: TAY CYC(2) break; - case 0xA9: IMM LDA CYC(2) break; - case 0xAA: TAX CYC(2) break; - case 0xAB: INV IMM OAL 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 ABS LAX CYC(4) break; - case 0xB0: REL BCS CYC(2) break; - case 0xB1: INDY LDA CYC(5) break; - case 0xB2: INV HLT CYC(2) break; - case 0xB3: INV INDY LAX CYC(5) break; - case 0xB4: ZPGX LDY CYC(4) break; - case 0xB5: ZPGX LDA CYC(4) break; - case 0xB6: ZPGY LDX CYC(4) break; - case 0xB7: INV ZPGY LAX CYC(4) break; - case 0xB8: CLV CYC(2) break; - case 0xB9: ABSY LDA CYC(4) break; - case 0xBA: TSX CYC(2) break; - case 0xBB: INV ABSY LAS CYC(4) break; - case 0xBC: ABSX LDY CYC(4) break; - case 0xBD: ABSX LDA CYC(4) break; - case 0xBE: ABSY LDX CYC(4) break; - case 0xBF: INV ABSY LAX CYC(4) break; - case 0xC0: IMM CPY CYC(2) break; - case 0xC1: INDX CMP CYC(6) break; - case 0xC2: INV IMM NOP CYC(2) break; - case 0xC3: INV INDX DCM CYC(8) break; - case 0xC4: ZPG CPY CYC(3) break; - case 0xC5: ZPG CMP CYC(3) break; - case 0xC6: ZPG DEC_NMOS CYC(5) break; - case 0xC7: INV ZPG DCM CYC(5) break; - case 0xC8: INY CYC(2) break; - case 0xC9: IMM CMP CYC(2) break; - case 0xCA: DEX CYC(2) break; - case 0xCB: INV IMM SAX CYC(2) break; - case 0xCC: ABS CPY CYC(4) break; - case 0xCD: ABS CMP CYC(4) break; - case 0xCE: ABS DEC_NMOS CYC(5) break; - case 0xCF: INV ABS DCM CYC(6) break; - case 0xD0: REL BNE CYC(2) break; - case 0xD1: INDY CMP CYC(5) break; - case 0xD2: INV HLT CYC(2) break; - case 0xD3: INV INDY DCM CYC(8) break; - case 0xD4: INV ZPGX NOP CYC(4) break; - case 0xD5: ZPGX CMP CYC(4) break; - case 0xD6: ZPGX DEC_NMOS CYC(6) break; - case 0xD7: INV ZPGX DCM CYC(6) break; - case 0xD8: CLD CYC(2) break; - case 0xD9: ABSY CMP CYC(4) break; - case 0xDA: INV NOP CYC(2) break; - case 0xDB: INV ABSY DCM CYC(7) break; - case 0xDC: INV ABSX NOP CYC(4) break; - case 0xDD: ABSX CMP CYC(4) break; - case 0xDE: ABSX DEC_NMOS CYC(6) break; - case 0xDF: INV ABSX DCM CYC(7) break; - case 0xE0: IMM CPX CYC(2) break; - case 0xE1: INDX SBC_NMOS CYC(6) break; - case 0xE2: INV IMM NOP CYC(2) break; - case 0xE3: INV INDX INS CYC(8) break; - case 0xE4: ZPG CPX CYC(3) break; - case 0xE5: ZPG SBC_NMOS CYC(3) break; - case 0xE6: ZPG INC_NMOS CYC(5) break; - case 0xE7: INV ZPG INS CYC(5) break; - case 0xE8: INX CYC(2) break; - case 0xE9: IMM SBC_NMOS CYC(2) break; - case 0xEA: NOP CYC(2) break; - case 0xEB: INV IMM SBC_NMOS CYC(2) break; - case 0xEC: ABS CPX CYC(4) break; - case 0xED: ABS SBC_NMOS CYC(4) break; - case 0xEE: ABS INC_NMOS CYC(6) break; - case 0xEF: INV ABS INS CYC(6) break; - case 0xF0: REL BEQ CYC(2) break; - case 0xF1: INDY SBC_NMOS CYC(5) break; - case 0xF2: INV HLT CYC(2) break; - case 0xF3: INV INDY INS CYC(8) break; - case 0xF4: INV ZPGX NOP CYC(4) break; - case 0xF5: ZPGX SBC_NMOS CYC(4) break; - case 0xF6: ZPGX INC_NMOS CYC(6) break; - case 0xF7: INV ZPGX INS CYC(6) break; - case 0xF8: SED CYC(2) break; - case 0xF9: ABSY SBC_NMOS CYC(4) break; - case 0xFA: INV NOP CYC(2) break; - case 0xFB: INV ABSY INS CYC(7) break; - case 0xFC: INV ABSX NOP CYC(4) break; - case 0xFD: ABSX SBC_NMOS CYC(4) break; - case 0xFE: ABSX INC_NMOS CYC(6) break; - case 0xFF: INV ABSX INS CYC(7) break; - } - - if(g_bNmiFlank && !regs.bJammed) - { - // NMI signals are only serviced once - g_bNmiFlank = FALSE; - g_nCycleIrqStart = g_nCumulativeCycles + cycles; - PUSH(regs.pc >> 8) - PUSH(regs.pc & 0xFF) - EF_TO_AF - PUSH(regs.ps & ~AF_BREAK) - regs.ps = regs.ps | AF_INTERRUPT; - regs.pc = * (WORD*) (mem+0xFFFA); - CYC(7) - } - - if(g_bmIRQ && !(regs.ps & AF_INTERRUPT) && !regs.bJammed) - { - // IRQ signals are deasserted when a specific r/w operation is done on device - g_nCycleIrqStart = g_nCumulativeCycles + cycles; - PUSH(regs.pc >> 8) - PUSH(regs.pc & 0xFF) - EF_TO_AF - PUSH(regs.ps & ~AF_BREAK) - regs.ps = regs.ps | AF_INTERRUPT; - regs.pc = * (WORD*) (mem+0xFFFE); - CYC(7) - } - - if (bBreakOnInvalid) - break; - } while (cycles < totalcycles); - - EF_TO_AF - return cycles; - } + return Cpu6502(uTotalCycles); } // @@ -1468,16 +1483,9 @@ static DWORD InternalCpuExecute (DWORD totalcycles) // //=========================================================================== -void CpuDestroy () { - int loop = 3; - while (loop--) { - if (cpulibrary[loop]) - FreeLibrary(cpulibrary[loop]); - cpuexecutefunc[loop] = NULL; - cpugetcodefunc[loop] = NULL; - cpulibrary[loop] = (HINSTANCE)0; - } +void CpuDestroy () +{ if (g_bCritSectionValid) { DeleteCriticalSection(&g_CriticalSection); @@ -1492,211 +1500,94 @@ void CpuDestroy () { // g_nCyclesExecuted // g_nCumulativeCycles // -void CpuCalcCycles(ULONG nCyclesLeft) +void CpuCalcCycles(ULONG nCyclesExecuted) { - ULONG nCycles; - - if((nCyclesLeft & 0x80000000) == 0) - { - nCyclesLeft >>= 8; - nCycles = g_nCyclesSubmitted - (g_nCyclesExecuted + nCyclesLeft); // Always +ve - _ASSERT(!(nCycles & 0x8000000)); - } - else - { - nCyclesLeft = ~nCyclesLeft; - nCyclesLeft >>= 8; - nCycles = nCyclesLeft + 1; - nCycles = (g_nCyclesSubmitted + nCycles) - g_nCyclesExecuted; - } + // Calc # of cycles executed since this func was last called + ULONG nCycles = nCyclesExecuted - g_nCyclesExecuted; g_nCyclesExecuted += nCycles; g_nCumulativeCycles += nCycles; - - if (cpuexecutefunc[cpuemtype]) - MB_UpdateCycles((USHORT) nCycles); // OLD: Support external dll emulator } //=========================================================================== + ULONG CpuGetCyclesThisFrame() { - CpuCalcCycles(nInternalCyclesLeft); // TODO: simplify the whole cycle system! + CpuCalcCycles(g_uInternalExecutedCycles); return g_dwCyclesThisFrame + g_nCyclesExecuted; } //=========================================================================== -DWORD CpuExecute (DWORD cycles) + +DWORD CpuExecute (DWORD uCycles) { - static BOOL laststep = 0; - DWORD result = 0; + DWORD uExecutedCycles = 0; - g_nCyclesSubmitted = cycles; - g_nCyclesExecuted = 0; + g_nCyclesSubmitted = uCycles; + g_nCyclesExecuted = 0; - // IF WE ARE SINGLE STEPPING, USE THE INTERPRETIVE EMULATOR - if (!cycles) - { - laststep = 1; - if (cpuexecutefunc[1]) - result=cpuexecutefunc[1](0); - else - result=InternalCpuExecute(0); - } + if (uCycles == 0) // Do single step + uExecutedCycles = InternalCpuExecute(0); + else // Do multi-opcode emulation + uExecutedCycles = InternalCpuExecute(uCycles); - // OTHERWISE, USE THE CURRENT EMULATOR. - else - { - if (laststep) - { - CpuResetCompilerData(); - laststep = 0; - } - // Don't break into 0xFFFF chunks, as at 4Mhz, /cycles/ > 0xFFFF (Spkr code ASSERTs) - // DLLs accept a 23-bit number for cycles. - if (cpuexecutefunc[cpuemtype]) - result=cpuexecutefunc[cpuemtype](cycles); - else - result=InternalCpuExecute(cycles); - } + UINT nRemainingCycles = uExecutedCycles - g_nCyclesExecuted; + g_nCumulativeCycles += nRemainingCycles; - // IF WE ARE USING THE EXTERNAL 6502 64K EMULATOR, MARK PAGES $40-$BF AS - // DIRTY, BECAUSE IT DOES NOT KEEP TRACK OF DIRTY PAGES IN THAT RANGE. - if ((!g_bApple2e) && cpuexecutefunc[1]) - { - int page = 0xC0; - while (page-- > 0x40) - *(memdirty+page) = 0xFF; - } - - UINT nRemainingCycles = result - g_nCyclesExecuted; - g_nCumulativeCycles += nRemainingCycles; - - if (cpuexecutefunc[cpuemtype]) - MB_UpdateCycles((USHORT) nRemainingCycles); // OLD: Support external dll emulator - - return result; + return uExecutedCycles; } //=========================================================================== -void CpuGetCode (WORD address, LPBYTE *codeptr, DWORD *codelength) { - *codeptr = NULL; - *codelength = 0; - if (cpugetcodefunc[0]) - cpugetcodefunc[0](address,codeptr,codelength); -} -//=========================================================================== -#define MIN_DLL_VERSION 1 - -void CpuInitialize () { - CpuDestroy(); - regs.a = regs.x = regs.y = regs.ps = 0xFF; - regs.sp = 0x01FF; - CpuReset(); // Init's ps & pc. Updates sp +void CpuInitialize () +{ + CpuDestroy(); + regs.a = regs.x = regs.y = regs.ps = 0xFF; + regs.sp = 0x01FF; + CpuReset(); // Init's ps & pc. Updates sp InitializeCriticalSection(&g_CriticalSection); g_bCritSectionValid = true; CpuIrqReset(); CpuNmiReset(); +} -#ifdef _X86_ - // TO DO: - // . FreeLibrary isn't being called if DLLs' version is too low - // . This code is going to get ditched, so ignore this! +//=========================================================================== - if (mem) { - TCHAR filename[MAX_PATH]; - _tcscpy(filename,g_sProgramDir); - _tcscat(filename,TEXT("65C02C.DLL")); - cpulibrary[CPU_COMPILING] = LoadLibrary(filename); - _tcscpy(filename,g_sProgramDir); - _tcscat(filename,g_bApple2e ? TEXT("65C02.DLL") : TEXT("6502.DLL")); - cpulibrary[CPU_INTERPRETIVE] = LoadLibrary(filename); - if (!cpulibrary[CPU_INTERPRETIVE]) { - _tcscpy(filename,g_sProgramDir); - _tcscat(filename,TEXT("65C02.DLL")); - cpulibrary[CPU_INTERPRETIVE] = LoadLibrary(filename); - } - _tcscpy(filename,g_sProgramDir); - _tcscat(filename,TEXT("65C02P.DLL")); - cpulibrary[CPU_FASTPAGING] = LoadLibrary(filename); - if (!cpulibrary[CPU_COMPILING]) - cpulibrary[CPU_COMPILING] = cpulibrary[CPU_INTERPRETIVE]; - int loop = 3; - while (loop--) - if (cpulibrary[loop]) { - cpuversionfunc[loop] = (cpuversiontype)GetProcAddress(cpulibrary[loop], - TEXT("CpuVersion")); - if (cpuversionfunc[loop] && (cpuversionfunc[loop]()>=MIN_DLL_VERSION)) +void CpuSetupBenchmark () +{ + regs.a = 0; + regs.x = 0; + regs.y = 0; + regs.pc = 0x300; + regs.sp = 0x1FF; + + // CREATE CODE SEGMENTS CONSISTING OF GROUPS OF COMMONLY-USED OPCODES + { + int addr = 0x300; + int opcode = 0; + do { - cpuexecutefunc[loop] = (cpuexecutetype)GetProcAddress(cpulibrary[loop], - TEXT("CpuExecute")); - cpugetcodefunc[loop] = (cpugetcodetype)GetProcAddress(cpulibrary[loop], - TEXT("CpuGetCode")); - cpuinitfunc[loop] = (cpuinittype)GetProcAddress(cpulibrary[loop], - TEXT("CpuInitialize")); - if (cpuinitfunc[loop]) - cpuinitfunc[loop](mem,memshadow[0],memwrite[0], - image,lastimage, - ®s,ioread,iowrite,memdirty, - CxReadFunc,CxWriteFunc); - } - } - } -#endif + *(mem+addr++) = benchopcode[opcode]; + *(mem+addr++) = benchopcode[opcode]; + + if (opcode >= SHORTOPCODES) + *(mem+addr++) = 0; + + if ((++opcode >= BENCHOPCODES) || ((addr & 0x0F) >= 0x0B)) + { + *(mem+addr++) = 0x4C; + *(mem+addr++) = (opcode >= BENCHOPCODES) ? 0x00 : ((addr >> 4)+1) << 4; + *(mem+addr++) = 0x03; + while (addr & 0x0F) + ++addr; + } + } while (opcode < BENCHOPCODES); + } } //=========================================================================== -void CpuReinitialize () { - if (cpulibrary[cpuemtype] && cpuinitfunc[cpuemtype]) - cpuinitfunc[cpuemtype](mem,memshadow[0],memwrite[0], - image,lastimage, - ®s,ioread,iowrite,memdirty, - CxReadFunc,CxWriteFunc); -} -//=========================================================================== -void CpuResetCompilerData () { - if (cpulibrary[CPU_COMPILING] && - (cpulibrary[CPU_COMPILING] != cpulibrary[CPU_INTERPRETIVE])) - ZeroMemory(mem+0x10000,0x20000); -} - -//=========================================================================== -void CpuSetupBenchmark () { - regs.a = 0; - regs.x = 0; - regs.y = 0; - regs.pc = 0x300; - regs.sp = 0x1FF; - - // CREATE CODE SEGMENTS CONSISTING OF GROUPS OF COMMONLY-USED OPCODES - { - int addr = 0x300; - int opcode = 0; - do { - *(mem+addr++) = benchopcode[opcode]; - *(mem+addr++) = benchopcode[opcode]; - if (opcode >= SHORTOPCODES) - *(mem+addr++) = 0; - if ((++opcode >= BENCHOPCODES) || ((addr & 0x0F) >= 0x0B)) { - *(mem+addr++) = 0x4C; - *(mem+addr++) = (opcode >= BENCHOPCODES) ? 0x00 - : ((addr >> 4)+1) << 4; - *(mem+addr++) = 0x03; - while (addr & 0x0F) - ++addr; - } - } while (opcode < BENCHOPCODES); - } -} - -//=========================================================================== -BOOL CpuSupportsFastPaging () { - return (cpulibrary[CPU_FASTPAGING] != (HINSTANCE)0); -} - -//=========================================================================== void CpuIrqReset() { _ASSERT(g_bCritSectionValid); @@ -1722,6 +1613,7 @@ void CpuIrqDeassert(eIRQSRC Device) } //=========================================================================== + void CpuNmiReset() { _ASSERT(g_bCritSectionValid); @@ -1750,6 +1642,7 @@ void CpuNmiDeassert(eIRQSRC Device) } //=========================================================================== + void CpuReset() { // 7 cycles @@ -1761,6 +1654,7 @@ void CpuReset() } //=========================================================================== + DWORD CpuGetSnapshot(SS_CPU6502* pSS) { pSS->A = regs.a; diff --git a/AppleWin/source/CPU.h b/AppleWin/source/CPU.h index 159d1773..e6f3303c 100644 --- a/AppleWin/source/CPU.h +++ b/AppleWin/source/CPU.h @@ -1,9 +1,5 @@ #pragma once -#define CPU_COMPILING 0 -#define CPU_INTERPRETIVE 1 -#define CPU_FASTPAGING 2 - typedef struct _regsrec { BYTE a; // accumulator BYTE x; // index X @@ -14,20 +10,15 @@ typedef struct _regsrec { BYTE bJammed; // CPU has crashed (NMOS 6502 only) } regsrec, *regsptr; -extern DWORD cpuemtype; extern regsrec regs; extern unsigned __int64 g_nCumulativeCycles; void CpuDestroy (); void CpuCalcCycles(ULONG nCyclesLeft); DWORD CpuExecute (DWORD); -void CpuGetCode (WORD,LPBYTE *,DWORD *); ULONG CpuGetCyclesThisFrame(); void CpuInitialize (); -void CpuReinitialize (); -void CpuResetCompilerData (); void CpuSetupBenchmark (); -BOOL CpuSupportsFastPaging (); void CpuIrqReset(); void CpuIrqAssert(eIRQSRC Device); void CpuIrqDeassert(eIRQSRC Device); diff --git a/AppleWin/source/Debug.cpp b/AppleWin/source/Debug.cpp index fedc5a02..ec3f0f85 100644 --- a/AppleWin/source/Debug.cpp +++ b/AppleWin/source/Debug.cpp @@ -8147,11 +8147,6 @@ void DebugBegin () // This is called every time the emulator is reset. // And everytime the debugger is entered. - if (cpuemtype == CPU_FASTPAGING) - { - MemSetFastPaging(0); - } - g_nAppMode = MODE_DEBUG; FrameRefreshStatus(DRAW_TITLE); diff --git a/AppleWin/source/Memory.cpp b/AppleWin/source/Memory.cpp index 8a7c55b4..c05f046c 100644 --- a/AppleWin/source/Memory.cpp +++ b/AppleWin/source/Memory.cpp @@ -581,7 +581,7 @@ static DWORD imagemode[MAXIMAGES]; LPBYTE memshadow[MAXIMAGES][0x100]; LPBYTE memwrite[MAXIMAGES][0x100]; -static BOOL fastpaging = 0; +static BOOL fastpaging = 0; // Redundant: only ever set to 0, by MemSetFastPaging(0) DWORD image = 0; DWORD lastimage = 0; static BOOL lastwriteram = 0; @@ -593,7 +593,6 @@ static LPBYTE memmain = NULL; static DWORD memmode = MF_BANK2 | MF_SLOTCXROM | MF_WRITERAM; static LPBYTE memrom = NULL; static BOOL modechanging = 0; -DWORD pages = 0; MemoryInitPattern_e g_eMemoryInitPattern = MIP_FF_FF_00_00; @@ -672,7 +671,6 @@ void UpdateFastPaging () { mem = memimage+(image << 16); UpdatePaging(1,0); } - CpuReinitialize(); } //=========================================================================== @@ -1049,10 +1047,6 @@ void MemSetFastPaging (BOOL on) { imagemode[0] = memmode; if (!fastpaging) UpdatePaging(1,0); - cpuemtype = fastpaging ? CPU_FASTPAGING : CPU_COMPILING; - CpuReinitialize(); - if (cpuemtype == CPU_COMPILING) - CpuResetCompilerData(); } //=========================================================================== @@ -1108,8 +1102,6 @@ BYTE __stdcall MemSetPaging (WORD programcounter, BYTE address, BYTE write, BYTE else { UpdatePaging(0,0); - if (cpuemtype == CPU_COMPILING) - CpuResetCompilerData(); } } break; @@ -1136,7 +1128,6 @@ BYTE __stdcall MemSetPaging (WORD programcounter, BYTE address, BYTE write, BYTE // WRITE TABLES. if ((lastmemmode != memmode) || modechanging) { modechanging = 0; - ++pages; // IF FAST PAGING IS ACTIVE, WE KEEP MULTIPLE COMPLETE MEMORY IMAGES // AND WRITE TABLES, AND SWITCH BETWEEN THEM. THE FAST PAGING VERSION @@ -1148,8 +1139,6 @@ BYTE __stdcall MemSetPaging (WORD programcounter, BYTE address, BYTE write, BYTE // WRITE TABLE, AND UPDATE THEM EVERY TIME PAGING IS CHANGED. else { UpdatePaging(0,0); - if (cpuemtype == CPU_COMPILING) - CpuResetCompilerData(); } } @@ -1181,7 +1170,6 @@ void MemTrimImages () { image = realimage; mem = memimage+(image << 16); memmode = imagemode[image]; - CpuReinitialize(); } if (++trimnumber >= lastimage) trimnumber = 0; @@ -1270,7 +1258,6 @@ DWORD MemSetSnapshot(SS_BaseMemory* pSS) // - pages = 0; modechanging = 0; UpdatePaging(1,0); // Initialize=1, UpdateWriteOnly=0 diff --git a/AppleWin/source/Memory.h b/AppleWin/source/Memory.h index c5a97aeb..97ab21f5 100644 --- a/AppleWin/source/Memory.h +++ b/AppleWin/source/Memory.h @@ -17,7 +17,6 @@ extern DWORD image; extern DWORD lastimage; extern LPBYTE mem; extern LPBYTE memdirty; -extern DWORD pages; #ifdef RAMWORKS extern UINT g_uMaxExPages; // user requested ram pages (from cmd line) diff --git a/AppleWin/source/Video.cpp b/AppleWin/source/Video.cpp index 724e7847..b2c87c06 100644 --- a/AppleWin/source/Video.cpp +++ b/AppleWin/source/Video.cpp @@ -986,7 +986,7 @@ void SetLastDrawnImage () { memcpy(vidlastmem+0x2000,g_pHiresBank0,0x2000); if (SW_DHIRES && SW_HIRES) memcpy(vidlastmem,g_pHiresBank1,0x2000); - if (SW_80COL && !SW_HIRES) + else if (SW_80COL) // Don't test for !SW_HIRES, as some 80-col text routines have SW_HIRES set (Bug #8300) memcpy(vidlastmem,g_pTextBank1,0x400); int loop; for (loop = 0; loop < 256; loop++) @@ -2079,10 +2079,7 @@ BYTE __stdcall VideoSetMode (WORD, BYTE address, BYTE write, BYTE, ULONG) { } if (oldpage2 != SW_PAGE2) { static DWORD lastrefresh = 0; - BOOL fastvideoslowcpu = 0; - if ((cpuemtype == CPU_FASTPAGING) && (emulmsec-lastrefresh >= 20)) - fastvideoslowcpu = 1; - if ((displaypage2 && !SW_PAGE2) || (!behind) || fastvideoslowcpu) { + if ((displaypage2 && !SW_PAGE2) || (!behind)) { displaypage2 = (SW_PAGE2 != 0); if (!redrawfull) { VideoRefreshScreen();