From 3ac1cc0b221c10cd9a82ba3c12d111597dc554e7 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 30 Sep 2012 21:13:26 +0300 Subject: [PATCH] merge x6502 code FCEUX --- fce.c | 28 +- ncpu.S | 18 +- ops.h | 969 ++++++++++++++++++++++++++++--------------------------- ppu098.c | 28 -- sound.c | 25 ++ sound.h | 1 + x6502.c | 629 ++++++++++++++++++------------------ x6502.h | 8 +- 8 files changed, 841 insertions(+), 865 deletions(-) diff --git a/fce.c b/fce.c index 282a264..f3d5abb 100644 --- a/fce.c +++ b/fce.c @@ -115,32 +115,6 @@ static int RWWrap=0; #ifdef ASM_6502 #ifdef DEBUG_ASM_6502 extern uint8 nes_internal_ram[0x800]; -#else -static void asmcpu_update(int32 cycles) -{ - // some code from x6502.c - fhcnt-=cycles; - if(fhcnt<=0) - { - FrameSoundUpdate(); - fhcnt+=fhinc; - } - - if(PCMIRQCount>0) - { - PCMIRQCount-=cycles; - if(PCMIRQCount<=0) - { - vdis=1; - if((PSG[0x10]&0x80) && !(PSG[0x10]&0x40)) - { - extern uint8 SIRQStat; - SIRQStat|=0x80; - X6502_IRQBegin(FCEU_IQDPCM); - } - } - } -} #endif void asmcpu_unpack(void) @@ -1263,6 +1237,8 @@ int FCEUI_Initialize(void) FCEUI_Initialize098(); FCEUI_SetEmuMode(0); + X6502_Init(); + return 1; } diff --git a/ncpu.S b/ncpu.S index e7b07a6..5723f39 100644 --- a/ncpu.S +++ b/ncpu.S @@ -2649,7 +2649,7 @@ op9F: @ SHA/AXA $nnnn, Y opAB: @ LXA/ATX/OAL #$nn IMM_VALUE - orr REG_A, REG_A, #0xee000000 + orr REG_A, REG_A, #0xff000000 OP_AND mov REG_X, REG_A, lsr #24 CYCLE_NEXT 2 @@ -2756,8 +2756,8 @@ op00: @ BRK ldr r0, [REG_OP_TABLE, #OTOFFS_PC_BASE] sub r0, REG_PC, r0 PUSH_WORD - orr REG_P_REST, REG_P_REST, #P_REST_B_FLAG SAVE_P + orr r0, r0, #P_B_FLAG PUSH_BYTE orr REG_P_REST, REG_P_REST, #P_REST_I_FLAG mov REG_ADDR, #0x10000 @@ -2809,12 +2809,13 @@ do_int: sub REG_PC, REG_PC, #1 sub r0, REG_PC, r0 PUSH_WORD - bic REG_P_REST, REG_P_REST, #P_REST_B_FLAG SAVE_P + bic r0, r0, #P_B_FLAG PUSH_BYTE tst REG_P_REST, #FCEU_IQNMI<<8 - orreq REG_P_REST, REG_P_REST, #P_REST_I_FLAG - bic REG_P_REST, REG_P_REST, #((FCEU_IQNMI|FCEU_IQTEMP)<<8) + orr REG_P_REST, REG_P_REST, #P_REST_I_FLAG + biceq REG_P_REST, REG_P_REST, #FCEU_IQTEMP<<8 + bicne REG_P_REST, REG_P_REST, #FCEU_IQNMI<<8 mov REG_ADDR, #0x10000 subeq REG_ADDR, REG_ADDR, #IRQ_VECTOR subne REG_ADDR, REG_ADDR, #NMI_VECTOR @@ -2825,12 +2826,7 @@ do_int: subs REG_CYCLE, REG_CYCLE, #7*48<<16 ble cpu_exec_end ldrb r0, [REG_PC], #1 - tst REG_P_REST, #0xff<<8 - ldreq pc, [REG_OP_TABLE, r0, lsl #2] - - tst REG_P_REST, #P_REST_I_FLAG - ldrne pc, [REG_OP_TABLE, r0, lsl #2] - b do_int + ldr pc, [REG_OP_TABLE, r0, lsl #2] @@@ diff --git a/ops.h b/ops.h index c5004d8..1524d61 100644 --- a/ops.h +++ b/ops.h @@ -1,483 +1,486 @@ -/* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2002 Ben Parnell - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -case 0x00: /* BRK */ - _PC++; - PUSH(_PC>>8); - PUSH(_PC); - _P|=B_FLAG; - PUSH(_P|U_FLAG); - _P|=I_FLAG; - _PC=RdMem(0xFFFE); - _PC|=RdMem(0xFFFF)<<8; - break; - -case 0x40: /* RTI */ - _P=POP(); - _PI=_P; - _PC=POP(); - _PC|=POP()<<8; - break; - -case 0x60: /* RTS */ - _PC=POP(); - _PC|=POP()<<8; - _PC++; - break; - -case 0x48: /* PHA */ - PUSH(_A); - break; -case 0x08: /* PHP */ - PUSH(_P|U_FLAG|B_FLAG); - break; -case 0x68: /* PLA */ - _A=POP(); - X_ZN(_A); - break; -case 0x28: /* PLP */ - _P=POP(); - break; -case 0x4C: - { - unsigned int npc; -/* - uint16 ptmp=_PC; - npc=RdMem(ptmp); - ptmp++; - npc|=RdMem(ptmp)<<8; -*/ - npc=RdMem(_PC++); - npc|=RdMem(_PC++)<<8; - _PC=npc; - } - break; /* JMP ABSOLUTE */ -case 0x6C: - { - uint32 tmp; - GetAB(tmp); - _PC=RdMem(tmp); - _PC|=RdMem( ((tmp+1)&0x00FF) | (tmp&0xFF00))<<8; - } - break; -case 0x20: /* JSR */ - { - uint32 npc; - npc=RdMem(_PC++); - PUSH(_PC>>8); - PUSH(_PC); - npc|=RdMem(_PC++)<<8; - _PC=npc; - } - break; - -case 0xAA: /* TAX */ - _X=_A; - X_ZN(_A); - break; - -case 0x8A: /* TXA */ - _A=_X; - X_ZN(_A); - break; - -case 0xA8: /* TAY */ - _Y=_A; - X_ZN(_A); - break; -case 0x98: /* TYA */ - _A=_Y; - X_ZN(_A); - break; - -case 0xBA: /* TSX */ - _X=_S; - X_ZN(_X); - break; -case 0x9A: /* TXS */ - _S=_X; - break; - -case 0xCA: /* DEX */ - _X--; - X_ZN(_X); - break; -case 0x88: /* DEY */ - _Y--; - X_ZN(_Y); - break; - -case 0xE8: /* INX */ - _X++; - X_ZN(_X); - break; -case 0xC8: /* INY */ - _Y++; - X_ZN(_Y); - break; - -case 0x18: /* CLC */ - _P&=~C_FLAG; - break; -case 0xD8: /* CLD */ - _P&=~D_FLAG; - break; -case 0x58: /* CLI */ - _P&=~I_FLAG; - break; -case 0xB8: /* CLV */ - _P&=~V_FLAG; - break; - -case 0x38: /* SEC */ - _P|=C_FLAG; - break; -case 0xF8: /* SED */ - _P|=D_FLAG; - break; -case 0x78: /* SEI */ - _P|=I_FLAG; - break; - -case 0xEA: /* NOP */ - break; - -case 0x0A: RMW_A(ASL); -case 0x06: RMW_ZP(ASL); -case 0x16: RMW_ZPX(ASL); -case 0x0E: RMW_AB(ASL); -case 0x1E: RMW_ABX(ASL); - -case 0xC6: RMW_ZP(DEC); -case 0xD6: RMW_ZPX(DEC); -case 0xCE: RMW_AB(DEC); -case 0xDE: RMW_ABX(DEC); - -case 0xE6: RMW_ZP(INC); -case 0xF6: RMW_ZPX(INC); -case 0xEE: RMW_AB(INC); -case 0xFE: RMW_ABX(INC); - -case 0x4A: RMW_A(LSR); -case 0x46: RMW_ZP(LSR); -case 0x56: RMW_ZPX(LSR); -case 0x4E: RMW_AB(LSR); -case 0x5E: RMW_ABX(LSR); - -case 0x2A: RMW_A(ROL); -case 0x26: RMW_ZP(ROL); -case 0x36: RMW_ZPX(ROL); -case 0x2E: RMW_AB(ROL); -case 0x3E: RMW_ABX(ROL); - -case 0x6A: RMW_A(ROR); -case 0x66: RMW_ZP(ROR); -case 0x76: RMW_ZPX(ROR); -case 0x6E: RMW_AB(ROR); -case 0x7E: RMW_ABX(ROR); - -case 0x69: LD_IM(ADC); -case 0x65: LD_ZP(ADC); -case 0x75: LD_ZPX(ADC); -case 0x6D: LD_AB(ADC); -case 0x7D: LD_ABX(ADC); -case 0x79: LD_ABY(ADC); -case 0x61: LD_IX(ADC); -case 0x71: LD_IY(ADC); - -case 0x29: LD_IM(AND); -case 0x25: LD_ZP(AND); -case 0x35: LD_ZPX(AND); -case 0x2D: LD_AB(AND); -case 0x3D: LD_ABX(AND); -case 0x39: LD_ABY(AND); -case 0x21: LD_IX(AND); -case 0x31: LD_IY(AND); - -case 0x24: LD_ZP(BIT); -case 0x2C: LD_AB(BIT); - -case 0xC9: LD_IM(CMP); -case 0xC5: LD_ZP(CMP); -case 0xD5: LD_ZPX(CMP); -case 0xCD: LD_AB(CMP); -case 0xDD: LD_ABX(CMP); -case 0xD9: LD_ABY(CMP); -case 0xC1: LD_IX(CMP); -case 0xD1: LD_IY(CMP); - -case 0xE0: LD_IM(CPX); -case 0xE4: LD_ZP(CPX); -case 0xEC: LD_AB(CPX); - -case 0xC0: LD_IM(CPY); -case 0xC4: LD_ZP(CPY); -case 0xCC: LD_AB(CPY); - -case 0x49: LD_IM(EOR); -case 0x45: LD_ZP(EOR); -case 0x55: LD_ZPX(EOR); -case 0x4D: LD_AB(EOR); -case 0x5D: LD_ABX(EOR); -case 0x59: LD_ABY(EOR); -case 0x41: LD_IX(EOR); -case 0x51: LD_IY(EOR); - -case 0xA9: LD_IM(LDA); -case 0xA5: LD_ZP(LDA); -case 0xB5: LD_ZPX(LDA); -case 0xAD: LD_AB(LDA); -case 0xBD: LD_ABX(LDA); -case 0xB9: LD_ABY(LDA); -case 0xA1: LD_IX(LDA); -case 0xB1: LD_IY(LDA); - -case 0xA2: LD_IM(LDX); -case 0xA6: LD_ZP(LDX); -case 0xB6: LD_ZPY(LDX); -case 0xAE: LD_AB(LDX); -case 0xBE: LD_ABY(LDX); - -case 0xA0: LD_IM(LDY); -case 0xA4: LD_ZP(LDY); -case 0xB4: LD_ZPX(LDY); -case 0xAC: LD_AB(LDY); -case 0xBC: LD_ABX(LDY); - -case 0x09: LD_IM(ORA); -case 0x05: LD_ZP(ORA); -case 0x15: LD_ZPX(ORA); -case 0x0D: LD_AB(ORA); -case 0x1D: LD_ABX(ORA); -case 0x19: LD_ABY(ORA); -case 0x01: LD_IX(ORA); -case 0x11: LD_IY(ORA); - -case 0xEB: /* (undocumented) */ -case 0xE9: LD_IM(SBC); -case 0xE5: LD_ZP(SBC); -case 0xF5: LD_ZPX(SBC); -case 0xED: LD_AB(SBC); -case 0xFD: LD_ABX(SBC); -case 0xF9: LD_ABY(SBC); -case 0xE1: LD_IX(SBC); -case 0xF1: LD_IY(SBC); - -case 0x85: ST_ZP(_A); -case 0x95: ST_ZPX(_A); -case 0x8D: ST_AB(_A); -case 0x9D: ST_ABX(_A); -case 0x99: ST_ABY(_A); -case 0x81: ST_IX(_A); -case 0x91: ST_IY(_A); - -case 0x86: ST_ZP(_X); -case 0x96: ST_ZPY(_X); -case 0x8E: ST_AB(_X); - -case 0x84: ST_ZP(_Y); -case 0x94: ST_ZPX(_Y); -case 0x8C: ST_AB(_Y); - -/* BCC */ -case 0x90: if(_P&C_FLAG) _PC++; else {JR();} break; - -/* BCS */ -case 0xB0: if(_P&C_FLAG) {JR();} else _PC++; break; - -/* BEQ */ -case 0xF0: if(_P&Z_FLAG) {JR();} else _PC++; break; - -/* BNE */ -case 0xD0: if(_P&Z_FLAG) _PC++; else {JR();} break; - -/* BMI */ -case 0x30: if(_P&N_FLAG) {JR();} else _PC++; break; - -/* BPL */ -case 0x10: if(_P&N_FLAG) _PC++; else {JR();} break; - -/* BVC */ -case 0x50: if(_P&V_FLAG) _PC++; else {JR();} break; - -/* BVS */ -case 0x70: if(_P&V_FLAG) {JR();} else _PC++; break; - -/* Here comes the undocumented instructions. Note that this implementation - may be "wrong". If so, please tell me. -*/ - -/* AAC */ -case 0x2B: -case 0x0B: LD_IM(AND;_P&=~C_FLAG;_P|=_A>>7); - -/* AAX */ -case 0x87: ST_ZP(_A&_X); -case 0x97: ST_ZPY(_A&_X); -case 0x8F: ST_AB(_A&_X); -case 0x83: ST_IX(_A&_X); - -/* ARR - ARGH, MATEY! */ -case 0x6B: { - uint8 arrtmp; - LD_IM(AND;_P&=~V_FLAG;_P|=(_A^(_A>>1))&0x40;arrtmp=_A>>7;_A>>=1;_A|=(_P&C_FLAG)<<7;_P&=~C_FLAG;_P|=arrtmp;X_ZN(_A)); - } -/* ASR */ -case 0x4B: LD_IM(AND;LSRA); - -/* ATX(OAL) Is this(OR with $EE) correct? */ -case 0xAB: LD_IM(_A|=0xEE;AND;_X=_A); - -/* AXS */ -case 0xCB: LD_IM(AXS); - -/* DCP */ -case 0xC7: RMW_ZP(DEC;CMP); -case 0xD7: RMW_ZPX(DEC;CMP); -case 0xCF: RMW_AB(DEC;CMP); -case 0xDF: RMW_ABX(DEC;CMP); -case 0xDB: RMW_ABY(DEC;CMP); -case 0xC3: RMW_IX(DEC;CMP); -case 0xD3: RMW_IY(DEC;CMP); - -/* ISC */ -case 0xE7: RMW_ZP(INC;SBC); -case 0xF7: RMW_ZPX(INC;SBC); -case 0xEF: RMW_AB(INC;SBC); -case 0xFF: RMW_ABX(INC;SBC); -case 0xFB: RMW_ABY(INC;SBC); -case 0xE3: RMW_IX(INC;SBC); -case 0xF3: RMW_IY(INC;SBC); - -/* DOP */ - -case 0x04: _PC++;break; -case 0x14: _PC++;break; -case 0x34: _PC++;break; -case 0x44: _PC++;break; -case 0x54: _PC++;break; -case 0x64: _PC++;break; -case 0x74: _PC++;break; - -case 0x80: _PC++;break; -case 0x82: _PC++;break; -case 0x89: _PC++;break; -case 0xC2: _PC++;break; -case 0xD4: _PC++;break; -case 0xE2: _PC++;break; -case 0xF4: _PC++;break; - -/* KIL */ - -case 0x02: -case 0x12: -case 0x22: -case 0x32: -case 0x42: -case 0x52: -case 0x62: -case 0x72: -case 0x92: -case 0xB2: -case 0xD2: -case 0xF2:ADDCYC(0xFF); - _jammed=1; - _PC--; - break; - -/* LAR */ -case 0xBB: RMW_ABY(_S&=x;_A=_X=_S;X_ZN(_X)); - -/* LAX */ -case 0xA7: LD_ZP(LDA;LDX); -case 0xB7: LD_ZPY(LDA;LDX); -case 0xAF: LD_AB(LDA;LDX); -case 0xBF: LD_ABY(LDA;LDX); -case 0xA3: LD_IX(LDA;LDX); -case 0xB3: LD_IY(LDA;LDX); - -/* NOP */ -case 0x1A: -case 0x3A: -case 0x5A: -case 0x7A: -case 0xDA: -case 0xFA: break; - -/* RLA */ -case 0x27: RMW_ZP(ROL;AND); -case 0x37: RMW_ZPX(ROL;AND); -case 0x2F: RMW_AB(ROL;AND); -case 0x3F: RMW_ABX(ROL;AND); -case 0x3B: RMW_ABY(ROL;AND); -case 0x23: RMW_IX(ROL;AND); -case 0x33: RMW_IY(ROL;AND); - -/* RRA */ -case 0x67: RMW_ZP(ROR;ADC); -case 0x77: RMW_ZPX(ROR;ADC); -case 0x6F: RMW_AB(ROR;ADC); -case 0x7F: RMW_ABX(ROR;ADC); -case 0x7B: RMW_ABY(ROR;ADC); -case 0x63: RMW_IX(ROR;ADC); -case 0x73: RMW_IY(ROR;ADC); - -/* SLO */ -case 0x07: RMW_ZP(ASL;ORA); -case 0x17: RMW_ZPX(ASL;ORA); -case 0x0F: RMW_AB(ASL;ORA); -case 0x1F: RMW_ABX(ASL;ORA); -case 0x1B: RMW_ABY(ASL;ORA); -case 0x03: RMW_IX(ASL;ORA); -case 0x13: RMW_IY(ASL;ORA); - -/* SRE */ -case 0x47: RMW_ZP(LSR;EOR); -case 0x57: RMW_ZPX(LSR;EOR); -case 0x4F: RMW_AB(LSR;EOR); -case 0x5F: RMW_ABX(LSR;EOR); -case 0x5B: RMW_ABY(LSR;EOR); -case 0x43: RMW_IX(LSR;EOR); -case 0x53: RMW_IY(LSR;EOR); - -/* AXA - SHA */ -case 0x93: ST_IY(_A&_X&(((A-_Y)>>8)+1)); -case 0x9F: ST_ABY(_A&_X&(((A-_Y)>>8)+1)); - -/* SYA */ -case 0x9C: ST_ABX(_Y&(((A-_X)>>8)+1)); - -/* SXA */ -case 0x9E: ST_ABY(_X&(((A-_Y)>>8)+1)); - -/* XAS */ -case 0x9B: _S=_A&_X;ST_ABY(_S& (((A-_Y)>>8)+1) ); - -/* TOP */ -case 0x0C: LD_AB(;); -case 0x1C: -case 0x3C: -case 0x5C: -case 0x7C: -case 0xDC: -case 0xFC: LD_ABX(;); - -/* XAA - BIG QUESTION MARK HERE */ -case 0x8B: _A|=0xEE; _A&=_X; LD_IM(AND); +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2002 Xodnizel + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +case 0x00: /* BRK */ + _PC++; + PUSH(_PC>>8); + PUSH(_PC); + PUSH(_P|U_FLAG|B_FLAG); + _P|=I_FLAG; + _PI|=I_FLAG; + _PC=RdMem(0xFFFE); + _PC|=RdMem(0xFFFF)<<8; + break; + +case 0x40: /* RTI */ + _P=POP(); + /* _PI=_P; This is probably incorrect, so it's commented out. */ + _PI = _P; + _PC=POP(); + _PC|=POP()<<8; + break; + +case 0x60: /* RTS */ + _PC=POP(); + _PC|=POP()<<8; + _PC++; + break; + +case 0x48: /* PHA */ + PUSH(_A); + break; +case 0x08: /* PHP */ + PUSH(_P|U_FLAG|B_FLAG); + break; +case 0x68: /* PLA */ + _A=POP(); + X_ZN(_A); + break; +case 0x28: /* PLP */ + _P=POP(); + break; +case 0x4C: + { + uint16 ptmp=_PC; + unsigned int npc; + + npc=RdMem(ptmp); + ptmp++; + npc|=RdMem(ptmp)<<8; + _PC=npc; + } + break; /* JMP ABSOLUTE */ +case 0x6C: + { + uint32 tmp; + GetAB(tmp); + _PC=RdMem(tmp); + _PC|=RdMem( ((tmp+1)&0x00FF) | (tmp&0xFF00))<<8; + } + break; +case 0x20: /* JSR */ + { + uint8 npc; + npc=RdMem(_PC); + _PC++; + PUSH(_PC>>8); + PUSH(_PC); + _PC=RdMem(_PC)<<8; + _PC|=npc; + } + break; + +case 0xAA: /* TAX */ + _X=_A; + X_ZN(_A); + break; + +case 0x8A: /* TXA */ + _A=_X; + X_ZN(_A); + break; + +case 0xA8: /* TAY */ + _Y=_A; + X_ZN(_A); + break; +case 0x98: /* TYA */ + _A=_Y; + X_ZN(_A); + break; + +case 0xBA: /* TSX */ + _X=_S; + X_ZN(_X); + break; +case 0x9A: /* TXS */ + _S=_X; + break; + +case 0xCA: /* DEX */ + _X--; + X_ZN(_X); + break; +case 0x88: /* DEY */ + _Y--; + X_ZN(_Y); + break; + +case 0xE8: /* INX */ + _X++; + X_ZN(_X); + break; +case 0xC8: /* INY */ + _Y++; + X_ZN(_Y); + break; + +case 0x18: /* CLC */ + _P&=~C_FLAG; + break; +case 0xD8: /* CLD */ + _P&=~D_FLAG; + break; +case 0x58: /* CLI */ + _P&=~I_FLAG; + break; +case 0xB8: /* CLV */ + _P&=~V_FLAG; + break; + +case 0x38: /* SEC */ + _P|=C_FLAG; + break; +case 0xF8: /* SED */ + _P|=D_FLAG; + break; +case 0x78: /* SEI */ + _P|=I_FLAG; + break; + +case 0xEA: /* NOP */ + break; + +case 0x0A: RMW_A(ASL); +case 0x06: RMW_ZP(ASL); +case 0x16: RMW_ZPX(ASL); +case 0x0E: RMW_AB(ASL); +case 0x1E: RMW_ABX(ASL); + +case 0xC6: RMW_ZP(DEC); +case 0xD6: RMW_ZPX(DEC); +case 0xCE: RMW_AB(DEC); +case 0xDE: RMW_ABX(DEC); + +case 0xE6: RMW_ZP(INC); +case 0xF6: RMW_ZPX(INC); +case 0xEE: RMW_AB(INC); +case 0xFE: RMW_ABX(INC); + +case 0x4A: RMW_A(LSR); +case 0x46: RMW_ZP(LSR); +case 0x56: RMW_ZPX(LSR); +case 0x4E: RMW_AB(LSR); +case 0x5E: RMW_ABX(LSR); + +case 0x2A: RMW_A(ROL); +case 0x26: RMW_ZP(ROL); +case 0x36: RMW_ZPX(ROL); +case 0x2E: RMW_AB(ROL); +case 0x3E: RMW_ABX(ROL); + +case 0x6A: RMW_A(ROR); +case 0x66: RMW_ZP(ROR); +case 0x76: RMW_ZPX(ROR); +case 0x6E: RMW_AB(ROR); +case 0x7E: RMW_ABX(ROR); + +case 0x69: LD_IM(ADC); +case 0x65: LD_ZP(ADC); +case 0x75: LD_ZPX(ADC); +case 0x6D: LD_AB(ADC); +case 0x7D: LD_ABX(ADC); +case 0x79: LD_ABY(ADC); +case 0x61: LD_IX(ADC); +case 0x71: LD_IY(ADC); + +case 0x29: LD_IM(AND); +case 0x25: LD_ZP(AND); +case 0x35: LD_ZPX(AND); +case 0x2D: LD_AB(AND); +case 0x3D: LD_ABX(AND); +case 0x39: LD_ABY(AND); +case 0x21: LD_IX(AND); +case 0x31: LD_IY(AND); + +case 0x24: LD_ZP(BIT); +case 0x2C: LD_AB(BIT); + +case 0xC9: LD_IM(CMP); +case 0xC5: LD_ZP(CMP); +case 0xD5: LD_ZPX(CMP); +case 0xCD: LD_AB(CMP); +case 0xDD: LD_ABX(CMP); +case 0xD9: LD_ABY(CMP); +case 0xC1: LD_IX(CMP); +case 0xD1: LD_IY(CMP); + +case 0xE0: LD_IM(CPX); +case 0xE4: LD_ZP(CPX); +case 0xEC: LD_AB(CPX); + +case 0xC0: LD_IM(CPY); +case 0xC4: LD_ZP(CPY); +case 0xCC: LD_AB(CPY); + +case 0x49: LD_IM(EOR); +case 0x45: LD_ZP(EOR); +case 0x55: LD_ZPX(EOR); +case 0x4D: LD_AB(EOR); +case 0x5D: LD_ABX(EOR); +case 0x59: LD_ABY(EOR); +case 0x41: LD_IX(EOR); +case 0x51: LD_IY(EOR); + +case 0xA9: LD_IM(LDA); +case 0xA5: LD_ZP(LDA); +case 0xB5: LD_ZPX(LDA); +case 0xAD: LD_AB(LDA); +case 0xBD: LD_ABX(LDA); +case 0xB9: LD_ABY(LDA); +case 0xA1: LD_IX(LDA); +case 0xB1: LD_IY(LDA); + +case 0xA2: LD_IM(LDX); +case 0xA6: LD_ZP(LDX); +case 0xB6: LD_ZPY(LDX); +case 0xAE: LD_AB(LDX); +case 0xBE: LD_ABY(LDX); + +case 0xA0: LD_IM(LDY); +case 0xA4: LD_ZP(LDY); +case 0xB4: LD_ZPX(LDY); +case 0xAC: LD_AB(LDY); +case 0xBC: LD_ABX(LDY); + +case 0x09: LD_IM(ORA); +case 0x05: LD_ZP(ORA); +case 0x15: LD_ZPX(ORA); +case 0x0D: LD_AB(ORA); +case 0x1D: LD_ABX(ORA); +case 0x19: LD_ABY(ORA); +case 0x01: LD_IX(ORA); +case 0x11: LD_IY(ORA); + +case 0xEB: /* (undocumented) */ +case 0xE9: LD_IM(SBC); +case 0xE5: LD_ZP(SBC); +case 0xF5: LD_ZPX(SBC); +case 0xED: LD_AB(SBC); +case 0xFD: LD_ABX(SBC); +case 0xF9: LD_ABY(SBC); +case 0xE1: LD_IX(SBC); +case 0xF1: LD_IY(SBC); + +case 0x85: ST_ZP(_A); +case 0x95: ST_ZPX(_A); +case 0x8D: ST_AB(_A); +case 0x9D: ST_ABX(_A); +case 0x99: ST_ABY(_A); +case 0x81: ST_IX(_A); +case 0x91: ST_IY(_A); + +case 0x86: ST_ZP(_X); +case 0x96: ST_ZPY(_X); +case 0x8E: ST_AB(_X); + +case 0x84: ST_ZP(_Y); +case 0x94: ST_ZPX(_Y); +case 0x8C: ST_AB(_Y); + +/* BCC */ +case 0x90: JR(!(_P&C_FLAG)); break; + +/* BCS */ +case 0xB0: JR(_P&C_FLAG); break; + +/* BEQ */ +case 0xF0: JR(_P&Z_FLAG); break; + +/* BNE */ +case 0xD0: JR(!(_P&Z_FLAG)); break; + +/* BMI */ +case 0x30: JR(_P&N_FLAG); break; + +/* BPL */ +case 0x10: JR(!(_P&N_FLAG)); break; + +/* BVC */ +case 0x50: JR(!(_P&V_FLAG)); break; + +/* BVS */ +case 0x70: JR(_P&V_FLAG); break; + +//default: printf("Bad %02x at $%04x\n",b1,X.PC);break; +//ifdef moo +/* Here comes the undocumented instructions block. Note that this implementation + may be "wrong". If so, please tell me. +*/ + +/* AAC */ +case 0x2B: +case 0x0B: LD_IM(AND;_P&=~C_FLAG;_P|=_A>>7); + +/* AAX */ +case 0x87: ST_ZP(_A&_X); +case 0x97: ST_ZPY(_A&_X); +case 0x8F: ST_AB(_A&_X); +case 0x83: ST_IX(_A&_X); + +/* ARR - ARGH, MATEY! */ +case 0x6B: { + uint8 arrtmp; + LD_IM(AND;_P&=~V_FLAG;_P|=(_A^(_A>>1))&0x40;arrtmp=_A>>7;_A>>=1;_A|=(_P&C_FLAG)<<7;_P&=~C_FLAG;_P|=arrtmp;X_ZN(_A)); + } +/* ASR */ +case 0x4B: LD_IM(AND;LSRA); + +/* ATX(OAL) Is this(OR with $EE) correct? Blargg did some test + and found the constant to be OR with is $FF for NES */ +case 0xAB: LD_IM(_A|=0xFF;AND;_X=_A); + +/* AXS */ +case 0xCB: LD_IM(AXS); + +/* DCP */ +case 0xC7: RMW_ZP(DEC;CMP); +case 0xD7: RMW_ZPX(DEC;CMP); +case 0xCF: RMW_AB(DEC;CMP); +case 0xDF: RMW_ABX(DEC;CMP); +case 0xDB: RMW_ABY(DEC;CMP); +case 0xC3: RMW_IX(DEC;CMP); +case 0xD3: RMW_IY(DEC;CMP); + +/* ISB */ +case 0xE7: RMW_ZP(INC;SBC); +case 0xF7: RMW_ZPX(INC;SBC); +case 0xEF: RMW_AB(INC;SBC); +case 0xFF: RMW_ABX(INC;SBC); +case 0xFB: RMW_ABY(INC;SBC); +case 0xE3: RMW_IX(INC;SBC); +case 0xF3: RMW_IY(INC;SBC); + +/* DOP */ + +case 0x04: _PC++;break; +case 0x14: _PC++;break; +case 0x34: _PC++;break; +case 0x44: _PC++;break; +case 0x54: _PC++;break; +case 0x64: _PC++;break; +case 0x74: _PC++;break; + +case 0x80: _PC++;break; +case 0x82: _PC++;break; +case 0x89: _PC++;break; +case 0xC2: _PC++;break; +case 0xD4: _PC++;break; +case 0xE2: _PC++;break; +case 0xF4: _PC++;break; + +/* KIL */ + +case 0x02: +case 0x12: +case 0x22: +case 0x32: +case 0x42: +case 0x52: +case 0x62: +case 0x72: +case 0x92: +case 0xB2: +case 0xD2: +case 0xF2:ADDCYC(0xFF); + _jammed=1; + _PC--; + break; + +/* LAR */ +case 0xBB: RMW_ABY(_S&=x;_A=_X=_S;X_ZN(_X)); + +/* LAX */ +case 0xA7: LD_ZP(LDA;LDX); +case 0xB7: LD_ZPY(LDA;LDX); +case 0xAF: LD_AB(LDA;LDX); +case 0xBF: LD_ABY(LDA;LDX); +case 0xA3: LD_IX(LDA;LDX); +case 0xB3: LD_IY(LDA;LDX); + +/* NOP */ +case 0x1A: +case 0x3A: +case 0x5A: +case 0x7A: +case 0xDA: +case 0xFA: break; + +/* RLA */ +case 0x27: RMW_ZP(ROL;AND); +case 0x37: RMW_ZPX(ROL;AND); +case 0x2F: RMW_AB(ROL;AND); +case 0x3F: RMW_ABX(ROL;AND); +case 0x3B: RMW_ABY(ROL;AND); +case 0x23: RMW_IX(ROL;AND); +case 0x33: RMW_IY(ROL;AND); + +/* RRA */ +case 0x67: RMW_ZP(ROR;ADC); +case 0x77: RMW_ZPX(ROR;ADC); +case 0x6F: RMW_AB(ROR;ADC); +case 0x7F: RMW_ABX(ROR;ADC); +case 0x7B: RMW_ABY(ROR;ADC); +case 0x63: RMW_IX(ROR;ADC); +case 0x73: RMW_IY(ROR;ADC); + +/* SLO */ +case 0x07: RMW_ZP(ASL;ORA); +case 0x17: RMW_ZPX(ASL;ORA); +case 0x0F: RMW_AB(ASL;ORA); +case 0x1F: RMW_ABX(ASL;ORA); +case 0x1B: RMW_ABY(ASL;ORA); +case 0x03: RMW_IX(ASL;ORA); +case 0x13: RMW_IY(ASL;ORA); + +/* SRE */ +case 0x47: RMW_ZP(LSR;EOR); +case 0x57: RMW_ZPX(LSR;EOR); +case 0x4F: RMW_AB(LSR;EOR); +case 0x5F: RMW_ABX(LSR;EOR); +case 0x5B: RMW_ABY(LSR;EOR); +case 0x43: RMW_IX(LSR;EOR); +case 0x53: RMW_IY(LSR;EOR); + +/* AXA - SHA */ +case 0x93: ST_IY(_A&_X&(((A-_Y)>>8)+1)); +case 0x9F: ST_ABY(_A&_X&(((A-_Y)>>8)+1)); + +/* SYA */ +case 0x9C: ST_ABX(_Y&(((A-_X)>>8)+1)); + +/* SXA */ +case 0x9E: ST_ABY(_X&(((A-_Y)>>8)+1)); + +/* XAS */ +case 0x9B: _S=_A&_X;ST_ABY(_S& (((A-_Y)>>8)+1) ); + +/* TOP */ +case 0x0C: LD_AB(;); +case 0x1C: +case 0x3C: +case 0x5C: +case 0x7C: +case 0xDC: +case 0xFC: LD_ABX(;); + +/* XAA - BIG QUESTION MARK HERE */ +case 0x8B: _A|=0xEE; _A&=_X; LD_IM(AND); +//endif diff --git a/ppu098.c b/ppu098.c index 65bdafc..7591282 100644 --- a/ppu098.c +++ b/ppu098.c @@ -86,34 +86,6 @@ static void makeppulut(void) } } -#if defined(ASM_6502) && !defined(DEBUG_ASM_6502) -static void asmcpu_update(int32 cycles) -{ - // some code from x6502.c - fhcnt-=cycles; - if(fhcnt<=0) - { - FrameSoundUpdate(); - fhcnt+=fhinc; - } - - if(PCMIRQCount>0) - { - PCMIRQCount-=cycles; - if(PCMIRQCount<=0) - { - vdis=1; - if((PSG[0x10]&0x80) && !(PSG[0x10]&0x40)) - { - extern uint8 SIRQStat; - SIRQStat|=0x80; - X6502_IRQBegin(FCEU_IQDPCM); - } - } - } -} -#endif - extern int ppudead; extern int kook; diff --git a/sound.c b/sound.c index 70ce2d4..f0eeaf8 100644 --- a/sound.c +++ b/sound.c @@ -555,6 +555,31 @@ static void FASTAPASS(1) CalcRectAmp(int P) *b=V; } +void FCEU_SoundCPUHook(int cycles48) +{ + fhcnt-=cycles48; + if(fhcnt<=0) + { + FrameSoundUpdate(); + fhcnt+=fhinc; + } + + if(PCMIRQCount>0) + { + PCMIRQCount-=cycles48; + if(PCMIRQCount<=0) + { + vdis=1; + if((PSG[0x10]&0x80) && !(PSG[0x10]&0x40)) + { + extern uint8 SIRQStat; + SIRQStat|=0x80; + X6502_IRQBegin(FCEU_IQDPCM); + } + } + } +} + static void RDoPCM(int32 end) { int32 V; diff --git a/sound.h b/sound.h index 223aa6d..90a534d 100644 --- a/sound.h +++ b/sound.h @@ -84,4 +84,5 @@ void SetNESSoundMap(void); void FrameSoundUpdate(void); void FixOldSaveStateSFreq(void); +void FCEU_SoundCPUHook(int cycles48); DECLFW(Write_IRQFM); diff --git a/x6502.c b/x6502.c index c20edf9..d77d8a0 100644 --- a/x6502.c +++ b/x6502.c @@ -26,8 +26,6 @@ #include "sound.h" #include "cart.h" -#include "dprintf.h" - #ifdef DEBUG_ASM_6502 #include #include @@ -46,6 +44,14 @@ void FP_FASTAPASS(1) (*MapIRQHook)(int a); X6502 X; uint32 timestamp; +#define ADDCYC(x) \ +{ \ + int __x=x; \ + _tcount+=__x; \ + _count-=__x*48; \ + timestamp+=__x; \ +} + #define _PC X.PC #define _A X.A #define _X X.X @@ -112,233 +118,234 @@ static INLINE void WrRAM(unsigned int A, uint8 V) RAM[A]=V; } -static INLINE void ADDCYC(int x) +uint8 X6502_DMR(uint32 A) { - _tcount+=x; - _count-=x*48; - timestamp+=x; + ADDCYC(1); + return(X.DB=ARead[A](A)); } -void FASTAPASS(1) X6502_AddCycles_c(int x) +void X6502_DMW(uint32 A, uint8 V) { - ADDCYC(x); + ADDCYC(1); + BWrite[A](A,V); + #ifdef _S9XLUA_H + CallRegisteredLuaMemHook(A, 1, V, LUAMEMHOOK_WRITE); + #endif } -static INLINE void PUSH(uint8 V) +void FASTAPASS(1) X6502_AddCycles_c(int x) { - WrRAM(0x100+_S,V); - _S--; + ADDCYC(x); } -static INLINE uint8 POP(void) -{ - _S++; - return(RdRAM(0x100+_S)); -} +#define PUSH(V) \ +{ \ + uint8 VTMP=V; \ + WrRAM(0x100+_S,VTMP); \ + _S--; \ +} -#if 0 -static uint8 ZNTable[256] = { - Z_FLAG,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG, - N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG, - N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG, - N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG, - N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG, - N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG, - N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG, - N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG -}; -#endif +#define POP() RdRAM(0x100+(++_S)) + +static uint8 ZNTable[256]; /* Some of these operations will only make sense if you know what the flag constants are. */ -//#define X_ZN(zort) _P&=~(Z_FLAG|N_FLAG);_P|=ZNTable[zort] -//#define X_ZNT(zort) _P|=ZNTable[zort] -#define X_ZN(zort) _P&=~(Z_FLAG|N_FLAG);if(!zort) _P|=Z_FLAG;else _P|=zort&N_FLAG -#define X_ZNT(zort) if(!zort) _P|=Z_FLAG;else _P|=(zort&N_FLAG) - -/* Care must be taken if you want to turn this into a macro. Use { and }. */ -#define JR(); \ -{ \ - uint32 tmp; \ - int8 disp; \ - disp=RdMem(_PC++); \ - ADDCYC(1); \ - tmp=_PC; \ - _PC+=disp; \ - if((tmp^_PC)&0x100) \ - ADDCYC(1); \ + +#define X_ZN(zort) _P&=~(Z_FLAG|N_FLAG);_P|=ZNTable[zort] +#define X_ZNT(zort) _P|=ZNTable[zort] + +#define JR(cond); \ +{ \ + if(cond) \ + { \ + uint32 tmp; \ + int32 disp; \ + disp=(int8)RdMem(_PC); \ + _PC++; \ + ADDCYC(1); \ + tmp=_PC; \ + _PC+=disp; \ + if((tmp^_PC)&0x100) \ + ADDCYC(1); \ + } \ + else _PC++; \ } -#define LDA _A=x;X_ZN(_A) -#define LDX _X=x;X_ZN(_X) -#define LDY _Y=x;X_ZN(_Y) + +#define LDA _A=x;X_ZN(_A) +#define LDX _X=x;X_ZN(_X) +#define LDY _Y=x;X_ZN(_Y) /* All of the freaky arithmetic operations. */ -#define AND _A&=x;X_ZN(_A) -//#define BIT _P&=~(Z_FLAG|V_FLAG|N_FLAG);_P|=ZNTable[x&_A]&Z_FLAG;_P|=x&(V_FLAG|N_FLAG) -#define BIT _P&=~(Z_FLAG|V_FLAG|N_FLAG);if(!(x&_A)) _P|=Z_FLAG;_P|=x&(V_FLAG|N_FLAG) -#define EOR _A^=x;X_ZN(_A) -#define ORA _A|=x;X_ZN(_A) - -#define ADC { \ - uint32 l=_A+x+(_P&1); \ - _P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \ - _P|=((((_A^x)&0x80)^0x80) & ((_A^l)&0x80))>>1; \ - _P|=(l>>8)&C_FLAG; \ - _A=l; \ - X_ZNT(_A); \ - } -#define SBC { \ - uint32 l=_A-x-((_P&1)^1); \ - _P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \ - _P|=((_A^l)&(_A^x)&0x80)>>1; \ - _P|=((l>>8)&C_FLAG)^C_FLAG; \ - _A=l; \ - X_ZNT(_A); \ - } - -#define CMPL(a1,a2) { \ - uint32 t=a1-a2; \ - X_ZN(t&0xFF); \ - _P&=~C_FLAG; \ - _P|=((t>>8)&C_FLAG)^C_FLAG; \ +#define AND _A&=x;X_ZN(_A) +#define BIT _P&=~(Z_FLAG|V_FLAG|N_FLAG);_P|=ZNTable[x&_A]&Z_FLAG;_P|=x&(V_FLAG|N_FLAG) +#define EOR _A^=x;X_ZN(_A) +#define ORA _A|=x;X_ZN(_A) + +#define ADC { \ + uint32 l=_A+x+(_P&1); \ + _P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \ + _P|=((((_A^x)&0x80)^0x80) & ((_A^l)&0x80))>>1; \ + _P|=(l>>8)&C_FLAG; \ + _A=l; \ + X_ZNT(_A); \ + } + +#define SBC { \ + uint32 l=_A-x-((_P&1)^1); \ + _P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \ + _P|=((_A^l)&(_A^x)&0x80)>>1; \ + _P|=((l>>8)&C_FLAG)^C_FLAG; \ + _A=l; \ + X_ZNT(_A); \ + } + +#define CMPL(a1,a2) { \ + uint32 t=a1-a2; \ + X_ZN(t&0xFF); \ + _P&=~C_FLAG; \ + _P|=((t>>8)&C_FLAG)^C_FLAG; \ } /* Special undocumented operation. Very similar to CMP. */ -#define AXS { \ +#define AXS { \ uint32 t=(_A&_X)-x; \ X_ZN(t&0xFF); \ _P&=~C_FLAG; \ - _P|=((t>>8)&C_FLAG)^C_FLAG; \ - _X=t; \ - } + _P|=((t>>8)&C_FLAG)^C_FLAG; \ + _X=t; \ + } -#define CMP CMPL(_A,x) -#define CPX CMPL(_X,x) -#define CPY CMPL(_Y,x) +#define CMP CMPL(_A,x) +#define CPX CMPL(_X,x) +#define CPY CMPL(_Y,x) /* The following operations modify the byte being worked on. */ -#define DEC x--;X_ZN(x) -#define INC x++;X_ZN(x) +#define DEC x--;X_ZN(x) +#define INC x++;X_ZN(x) -#define ASL _P&=~C_FLAG;_P|=x>>7;x<<=1;X_ZN(x) -#define LSR _P&=~(C_FLAG|N_FLAG|Z_FLAG);_P|=x&1;x>>=1;X_ZNT(x) +#define ASL _P&=~C_FLAG;_P|=x>>7;x<<=1;X_ZN(x) +#define LSR _P&=~(C_FLAG|N_FLAG|Z_FLAG);_P|=x&1;x>>=1;X_ZNT(x) /* For undocumented instructions, maybe for other things later... */ -#define LSRA _P&=~(C_FLAG|N_FLAG|Z_FLAG);_P|=_A&1;_A>>=1;X_ZNT(_A) - -#define ROL { \ - uint8 l=x>>7; \ - x<<=1; \ - x|=_P&C_FLAG; \ - _P&=~(Z_FLAG|N_FLAG|C_FLAG); \ - _P|=l; \ - X_ZNT(x); \ +#define LSRA _P&=~(C_FLAG|N_FLAG|Z_FLAG);_P|=_A&1;_A>>=1;X_ZNT(_A) + +#define ROL { \ + uint8 l=x>>7; \ + x<<=1; \ + x|=_P&C_FLAG; \ + _P&=~(Z_FLAG|N_FLAG|C_FLAG); \ + _P|=l; \ + X_ZNT(x); \ + } +#define ROR { \ + uint8 l=x&1; \ + x>>=1; \ + x|=(_P&C_FLAG)<<7; \ + _P&=~(Z_FLAG|N_FLAG|C_FLAG); \ + _P|=l; \ + X_ZNT(x); \ } -#define ROR { \ - uint8 l=x&1; \ - x>>=1; \ - x|=(_P&C_FLAG)<<7; \ - _P&=~(Z_FLAG|N_FLAG|C_FLAG); \ - _P|=l; \ - X_ZNT(x); \ - } - + /* Icky icky thing for some undocumented instructions. Can easily be broken if names of local variables are changed. */ /* Absolute */ -#define GetAB(target) \ -{ \ - target=RdMem(_PC++); \ - target|=RdMem(_PC++)<<8; \ +#define GetAB(target) \ +{ \ + target=RdMem(_PC); \ + _PC++; \ + target|=RdMem(_PC)<<8; \ + _PC++; \ } /* Absolute Indexed(for reads) */ -#define GetABIRD(target, i) \ -{ \ - unsigned int tmp; \ - GetAB(tmp); \ - target=tmp; \ - target+=i; \ - if((target^tmp)&0x100) \ - { \ - target&=0xFFFF; \ - DummyRdMem(target^0x100); \ - ADDCYC(1); \ - } \ +#define GetABIRD(target, i) \ +{ \ + unsigned int tmp; \ + GetAB(tmp); \ + target=tmp; \ + target+=i; \ + if((target^tmp)&0x100) \ + { \ + target&=0xFFFF; \ + DummyRdMem(target^0x100); \ + ADDCYC(1); \ + } \ } /* Absolute Indexed(for writes and rmws) */ -#define GetABIWR(target, i) \ -{ \ - unsigned int rt; \ - GetAB(rt); \ - target=rt; \ - target+=i; \ - target&=0xFFFF; \ - DummyRdMem((target&0x00FF)|(rt&0xFF00)); \ +#define GetABIWR(target, i) \ +{ \ + unsigned int rt; \ + GetAB(rt); \ + target=rt; \ + target+=i; \ + target&=0xFFFF; \ + DummyRdMem((target&0x00FF)|(rt&0xFF00)); \ } /* Zero Page */ -#define GetZP(target) \ -{ \ - target=RdMem(_PC++); \ +#define GetZP(target) \ +{ \ + target=RdMem(_PC); \ + _PC++; \ } /* Zero Page Indexed */ -#define GetZPI(target,i) \ -{ \ - target=i+RdMem(_PC++); \ +#define GetZPI(target,i) \ +{ \ + target=i+RdMem(_PC); \ + _PC++; \ } /* Indexed Indirect */ -#define GetIX(target) \ -{ \ - uint8 tmp; \ - tmp=RdMem(_PC++); \ - tmp+=_X; \ - target=RdRAM(tmp++); \ - target|=RdRAM(tmp)<<8; \ +#define GetIX(target) \ +{ \ + uint8 tmp; \ + tmp=RdMem(_PC); \ + _PC++; \ + tmp+=_X; \ + target=RdRAM(tmp); \ + tmp++; \ + target|=RdRAM(tmp)<<8; \ } /* Indirect Indexed(for reads) */ -#define GetIYRD(target) \ -{ \ - unsigned int rt; \ - uint8 tmp; \ - tmp=RdMem(_PC++); \ - rt=RdRAM(tmp++); \ - rt|=RdRAM(tmp)<<8; \ - target=rt; \ - target+=_Y; \ - if((target^rt)&0x100) \ - { \ - target&=0xFFFF; \ - DummyRdMem(target^0x100); \ - ADDCYC(1); \ - } \ +#define GetIYRD(target) \ +{ \ + unsigned int rt; \ + uint8 tmp; \ + tmp=RdMem(_PC); \ + _PC++; \ + rt=RdRAM(tmp); \ + tmp++; \ + rt|=RdRAM(tmp)<<8; \ + target=rt; \ + target+=_Y; \ + if((target^rt)&0x100) \ + { \ + target&=0xFFFF; \ + DummyRdMem(target^0x100); \ + ADDCYC(1); \ + } \ } /* Indirect Indexed(for writes and rmws) */ -#define GetIYWR(target) \ -{ \ - unsigned int rt; \ - uint8 tmp; \ - tmp=RdMem(_PC++); \ - rt=RdRAM(tmp++); \ - rt|=RdRAM(tmp)<<8; \ - target=rt; \ - target+=_Y; \ - DummyRdMem((target&0x00FF)|(rt&0xFF00)); \ +#define GetIYWR(target) \ +{ \ + unsigned int rt; \ + uint8 tmp; \ + tmp=RdMem(_PC); \ + _PC++; \ + rt=RdRAM(tmp); \ + tmp++; \ + rt|=RdRAM(tmp)<<8; \ + target=rt; \ + target+=_Y; \ + target&=0xFFFF; \ + DummyRdMem((target&0x00FF)|(rt&0xFF00)); \ } /* Now come the macros to wrap up all of the above stuff addressing mode functions @@ -349,33 +356,33 @@ static uint8 ZNTable[256] = { #define RMW_A(op) {uint8 x=_A; op; _A=x; break; } /* Meh... */ #define RMW_AB(op) {unsigned int A; uint8 x; GetAB(A); x=RdMem(A); WrMem(A,x); op; WrMem(A,x); break; } #define RMW_ABI(reg,op) {unsigned int A; uint8 x; GetABIWR(A,reg); x=RdMem(A); WrMem(A,x); op; WrMem(A,x); break; } -#define RMW_ABX(op) RMW_ABI(_X,op) -#define RMW_ABY(op) RMW_ABI(_Y,op) +#define RMW_ABX(op) RMW_ABI(_X,op) +#define RMW_ABY(op) RMW_ABI(_Y,op) #define RMW_IX(op) {unsigned int A; uint8 x; GetIX(A); x=RdMem(A); WrMem(A,x); op; WrMem(A,x); break; } #define RMW_IY(op) {unsigned int A; uint8 x; GetIYWR(A); x=RdMem(A); WrMem(A,x); op; WrMem(A,x); break; } #define RMW_ZP(op) {uint8 A; uint8 x; GetZP(A); x=RdRAM(A); op; WrRAM(A,x); break; } #define RMW_ZPX(op) {uint8 A; uint8 x; GetZPI(A,_X); x=RdRAM(A); op; WrRAM(A,x); break;} -#define LD_IM(op) {uint8 x; x=RdMem(_PC++); op; break;} -#define LD_ZP(op) {uint8 A; uint8 x; GetZP(A); x=RdRAM(A); op; break;} +#define LD_IM(op) {uint8 x; x=RdMem(_PC); _PC++; op; break;} +#define LD_ZP(op) {uint8 A; uint8 x; GetZP(A); x=RdRAM(A); op; break;} #define LD_ZPX(op) {uint8 A; uint8 x; GetZPI(A,_X); x=RdRAM(A); op; break;} #define LD_ZPY(op) {uint8 A; uint8 x; GetZPI(A,_Y); x=RdRAM(A); op; break;} -#define LD_AB(op) {unsigned int A; uint8 x; GetAB(A); x=RdMem(A); op; break; } +#define LD_AB(op) {unsigned int A; uint8 x; GetAB(A); x=RdMem(A); op; break; } #define LD_ABI(reg,op) {unsigned int A; uint8 x; GetABIRD(A,reg); x=RdMem(A); op; break;} -#define LD_ABX(op) LD_ABI(_X,op) -#define LD_ABY(op) LD_ABI(_Y,op) -#define LD_IX(op) {unsigned int A; uint8 x; GetIX(A); x=RdMem(A); op; break;} -#define LD_IY(op) {unsigned int A; uint8 x; GetIYRD(A); x=RdMem(A); op; break;} - -#define ST_ZP(r) {uint8 A; GetZP(A); WrRAM(A,r); break;} -#define ST_ZPX(r) {uint8 A; GetZPI(A,_X); WrRAM(A,r); break;} -#define ST_ZPY(r) {uint8 A; GetZPI(A,_Y); WrRAM(A,r); break;} -#define ST_AB(r) {unsigned int A; GetAB(A); WrMem(A,r); break;} -#define ST_ABI(reg,r) {unsigned int A; GetABIWR(A,reg); WrMem(A,r); break; } -#define ST_ABX(r) ST_ABI(_X,r) -#define ST_ABY(r) ST_ABI(_Y,r) -#define ST_IX(r) {unsigned int A; GetIX(A); WrMem(A,r); break; } -#define ST_IY(r) {unsigned int A; GetIYWR(A); WrMem(A,r); break; } +#define LD_ABX(op) LD_ABI(_X,op) +#define LD_ABY(op) LD_ABI(_Y,op) +#define LD_IX(op) {unsigned int A; uint8 x; GetIX(A); x=RdMem(A); op; break;} +#define LD_IY(op) {unsigned int A; uint8 x; GetIYRD(A); x=RdMem(A); op; break;} + +#define ST_ZP(r) {uint8 A; GetZP(A); WrRAM(A,r); break;} +#define ST_ZPX(r) {uint8 A; GetZPI(A,_X); WrRAM(A,r); break;} +#define ST_ZPY(r) {uint8 A; GetZPI(A,_Y); WrRAM(A,r); break;} +#define ST_AB(r) {unsigned int A; GetAB(A); WrMem(A,r); break;} +#define ST_ABI(reg,r) {unsigned int A; GetABIWR(A,reg); WrMem(A,r); break; } +#define ST_ABX(r) ST_ABI(_X,r) +#define ST_ABY(r) ST_ABI(_Y,r) +#define ST_IX(r) {unsigned int A; GetIX(A); WrMem(A,r); break; } +#define ST_IY(r) {unsigned int A; GetIYWR(A); WrMem(A,r); break; } static uint8 CycTable[256] = { @@ -400,13 +407,11 @@ static uint8 CycTable[256] = void FASTAPASS(1) X6502_IRQBegin_c(int w) { - dprintf("IRQB %02x",w); _IRQlow|=w; } void FASTAPASS(1) X6502_IRQEnd_c(int w) { - dprintf("IRQE %02x",w); _IRQlow&=~w; } @@ -420,53 +425,48 @@ void TriggerNMI_c(void) _IRQlow|=FCEU_IQNMI; } -static void TriggerNMIReal(void) -{ - if(!_jammed) - { - dprintf("NMI"); - ADDCYC(7); - PUSH(_PC>>8); - PUSH(_PC); - _P&=~B_FLAG; - PUSH(_P|U_FLAG); - _PC=RdMem(0xFFFA); - _PC|=RdMem(0xFFFB)<<8; -#ifdef DEBUG_ASM_6502 - PC_prev = _PC; - OP_prev = 0x100; -#endif - } -} - -void TriggerIRQReal(void) -{ - if(!(_PI&I_FLAG) && !_jammed) - { - dprintf("IRQ"); - ADDCYC(7); - PUSH(_PC>>8); - PUSH(_PC); - _P&=~B_FLAG; - PUSH(_P|U_FLAG); - _P|=I_FLAG; - _PC=RdMem(0xFFFE); - _PC|=RdMem(0xFFFF)<<8; -#ifdef DEBUG_ASM_6502 - PC_prev = _PC; - OP_prev = 0x101; -#endif - } +void TriggerNMI2(void) +{ + //_IRQlow|=FCEU_IQNMI2; + _IRQlow|=FCEU_IQNMI; } void X6502_Reset_c(void) { + //_IRQlow=FCEU_IQRESET; _PC=RdMem(0xFFFC); _PC|=RdMem(0xFFFD)<<8; _jammed=0; _PI=_P=I_FLAG; } +/** +* Initializes the 6502 CPU +**/ +void X6502_Init_c(void) +{ + unsigned int i; + + // Initialize the CPU structure + memset((void *)&X,0,sizeof(X)); + + for(i = 0; i < sizeof(ZNTable); i++) + { + if(!i) + { + ZNTable[i] = Z_FLAG; + } + else if ( i & 0x80 ) + { + ZNTable[i] = N_FLAG; + } + else + { + ZNTable[i] = 0; + } + } +} + void X6502_Power_c(void) { memset((void *)&X,0,sizeof(X)); @@ -474,103 +474,102 @@ void X6502_Power_c(void) X6502_Reset_c(); } - -//int asdc = 0; void X6502_Run_c(void/*int32 cycles*/) { -/* - if(PAL) - cycles*=15; // 15*4=60 - else - cycles*=16; // 16*4=64 - - _count+=cycles; -*/ -// if (_count <= 0) asdc++; +#if 0 + if(PAL) + cycles*=15; // 15*4=60 + else + cycles*=16; // 16*4=64 - while(_count>0) - { - int32 temp; - uint8 b1; - - if(_IRQlow) - { - if(_IRQlow&FCEU_IQNMI) - TriggerNMIReal(); - else - TriggerIRQReal(); - - _IRQlow&=~(FCEU_IQTEMP|FCEU_IQNMI); - if(_count<=0) - { + _count+=cycles; +#endif + while(_count>0) + { + int32 temp; + uint8 b1; + + if(_IRQlow) + { + if(_IRQlow&FCEU_IQNMI) + { + if(!_jammed) + { + ADDCYC(7); + PUSH(_PC>>8); + PUSH(_PC); + PUSH((_P&~B_FLAG)|(U_FLAG)); + _P|=I_FLAG; + _PC=RdMem(0xFFFA); + _PC|=RdMem(0xFFFB)<<8; + _IRQlow&=~FCEU_IQNMI; #ifdef DEBUG_ASM_6502 - if(MapIRQHook) mapirq_cyc_c = _tcount; - _tcount=0; + PC_prev = _PC; + OP_prev = 0x100; #endif - _PI=_P; - return; /* Should increase accuracy without a major speed hit. */ - } - } - _PI=_P; + } + } + else + { + if(!(_PI&I_FLAG) && !_jammed) + { + ADDCYC(7); + PUSH(_PC>>8); + PUSH(_PC); + PUSH((_P&~B_FLAG)|(U_FLAG)); + _P|=I_FLAG; + _PC=RdMem(0xFFFE); + _PC|=RdMem(0xFFFF)<<8; #ifdef DEBUG_ASM_6502 - b1=RdMem(_PC++); _PC--; -#else - b1=RdMem(_PC); + PC_prev = _PC; + OP_prev = 0x101; #endif - ADDCYC(CycTable[b1]); - temp=_tcount; - - temp*=48; - - fhcnt-=temp; - if(fhcnt<=0) - { - FrameSoundUpdate(); - fhcnt+=fhinc; - } - - if(PCMIRQCount>0) - { - PCMIRQCount-=temp; - if(PCMIRQCount<=0) - { - vdis=1; - if((PSG[0x10]&0x80) && !(PSG[0x10]&0x40)) - { - extern uint8 SIRQStat; - SIRQStat|=0x80; - X6502_IRQBegin(FCEU_IQDPCM); - } - } - } + } + } + _IRQlow&=~(FCEU_IQTEMP); + if(_count<=0) + { +#ifdef DEBUG_ASM_6502 + if(MapIRQHook) mapirq_cyc_c = _tcount; + _tcount=0; +#endif + _PI=_P; + return; + } //Should increase accuracy without a + //major speed hit. + } + _PI=_P; #ifdef DEBUG_ASM_6502 - PC_prev = _PC; - OP_prev = b1; + b1=RdMem(_PC++); _PC--; +#else + b1=RdMem(_PC); #endif - //printf("$%04x:$%02x\n",_PC,b1); - //_PC++; - //printf("$%02x\n",b1); - _PC++; - switch(b1) - { - #include "ops.h" - } - - temp=_tcount; /* Gradius II (J) glitches if _tcount is not used */ - _tcount=0; - - if(MapIRQHook) { + + ADDCYC(CycTable[b1]); + + temp=_tcount; /* Gradius II (J) glitches if _tcount is not used */ + _tcount=0; + if(MapIRQHook) { #ifdef DEBUG_ASM_6502 - mapirq_cyc_c = temp; + mapirq_cyc_c = temp; #endif - MapIRQHook(temp); - } + MapIRQHook(temp); + } + FCEU_SoundCPUHook(temp*48); #ifdef DEBUG_ASM_6502 - _PI=_P; + PC_prev = _PC; + OP_prev = b1; #endif - } + _PC++; + switch(b1) + { + #include "ops.h" + } +#ifdef DEBUG_ASM_6502 + _PI=_P; +#endif + } } - diff --git a/x6502.h b/x6502.h index 56d9448..31216f4 100644 --- a/x6502.h +++ b/x6502.h @@ -58,6 +58,7 @@ extern void FP_FASTAPASS(1) (*MapIRQHook)(int a); #if defined(DEBUG_ASM_6502) #define TriggerIRQ TriggerIRQ_d #define TriggerNMI TriggerNMI_d +#define X6502_Init X6502_Init_c #define X6502_Run X6502_Run_d #define X6502_Reset X6502_Reset_d #define X6502_Power X6502_Power_d @@ -73,6 +74,7 @@ extern void FP_FASTAPASS(1) (*MapIRQHook)(int a); #elif defined(ASM_6502) #define TriggerIRQ TriggerIRQ_a #define TriggerNMI TriggerNMI_a +#define X6502_Init() #define X6502_Reset X6502_Reset_a #define X6502_Power X6502_Power_a #define X6502_AddCycles X6502_AddCycles_a @@ -93,13 +95,14 @@ extern void FP_FASTAPASS(1) (*MapIRQHook)(int a); if (cycles > 0) { \ X6502_Run_a(); \ cycles -= (int32)nes_registers[7]>>16; \ - asmcpu_update(cycles); \ + FCEU_SoundCPUHook(cycles); \ } \ } #else #define TriggerIRQ TriggerIRQ_c #define TriggerNMI TriggerNMI_c +#define X6502_Init X6502_Init_c #define X6502_Reset X6502_Reset_c #define X6502_Power X6502_Power_c #define X6502_AddCycles X6502_AddCycles_c @@ -121,9 +124,9 @@ extern void FP_FASTAPASS(1) (*MapIRQHook)(int a); // c #ifdef X6502_C -extern int32 g_cnt; void TriggerIRQ_c(void); void TriggerNMI_c(void); +void X6502_Init_c(void); void X6502_Run_c(void); void X6502_Reset_c(void); void X6502_Power_c(void); @@ -149,6 +152,7 @@ void X6502_Rebase_a(void); // debug #ifdef X6502_D +extern int32 g_cnt; void TriggerIRQ_d(void); void TriggerNMI_d(void); void X6502_Run_d(int32 c); -- 2.39.5