⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nes6502.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 4 页
字号:
/* undocumented */#define ISB(cycles, read_func, write_func, addr) \{ \   read_func(addr, data); \   data++; \   write_func(addr, data); \   SBC(cycles, NO_READ); \}#ifdef NES6502_TESTOPS#define JAM() \{ \   cpu_Jam(); \}#elif defined(NSF_PLAYER)#define JAM() \{ \}#else#define JAM() \{ \   char jambuf[20]; \   sprintf(jambuf, "JAM: PC=$%04X", PC); \   ASSERT_MSG(jambuf); \   ADD_CYCLES(2); \}#endif /* NES6502_TESTOPS */#define JMP_INDIRECT() \{ \   temp = bank_readaddress(PC); \   /* bug in crossing page boundaries */ \   if (0xFF == (uint8) temp) \      PC = (bank_readbyte(temp & ~0xFF) << 8) | bank_readbyte(temp); \   else \      JUMP(temp); \   ADD_CYCLES(5); \}#define JMP_ABSOLUTE() \{ \   JUMP(PC); \   ADD_CYCLES(3); \}#define JSR() \{ \   PC++; \   PUSH(PC >> 8); \   PUSH(PC & 0xFF); \   JUMP(PC - 1); \   ADD_CYCLES(6); \}/* undocumented */#define LAS(cycles, read_func) \{ \   read_func(data); \   A = X = S = (S & data); \   SET_NZ_FLAGS(A); \   ADD_CYCLES(cycles); \}/* undocumented */#define LAX(cycles, read_func) \{ \   read_func(A); \   X = A; \   SET_NZ_FLAGS(A); \   ADD_CYCLES(cycles); \}#define LDA(cycles, read_func) \{ \   read_func(A); \   SET_NZ_FLAGS(A); \   ADD_CYCLES(cycles); \}#define LDX(cycles, read_func) \{ \   read_func(X); \   SET_NZ_FLAGS(X);\   ADD_CYCLES(cycles); \}#define LDY(cycles, read_func) \{ \   read_func(Y); \   SET_NZ_FLAGS(Y);\   ADD_CYCLES(cycles); \}#define LSR(cycles, read_func, write_func, addr) \{ \   read_func(addr, data); \   TEST_AND_FLAG(data & 0x01, C_FLAG); \   data >>= 1; \   write_func(addr, data); \   SET_NZ_FLAGS(data); \   ADD_CYCLES(cycles); \}#define LSR_A() \{ \   TEST_AND_FLAG(A & 0x01, C_FLAG); \   A >>= 1; \   SET_NZ_FLAGS(A); \   ADD_CYCLES(2); \}/* undocumented */#define LXA(cycles, read_func) \{ \   read_func(data); \   A = X = ((A | 0xEE) & data); \   SET_NZ_FLAGS(A); \   ADD_CYCLES(cycles); \}#define NOP() \{ \   ADD_CYCLES(2); \}#define ORA(cycles, read_func) \{ \   read_func(data); \   A |= data; \   SET_NZ_FLAGS(A);\   ADD_CYCLES(cycles); \}#define PHA() \{ \   PUSH(A); \   ADD_CYCLES(3); \}#define PHP() \{ \   /* B flag is pushed on stack as well */ \   PUSH((P | B_FLAG)); \   ADD_CYCLES(3); \}#define PLA() \{ \   A = PULL(); \   SET_NZ_FLAGS(A); \   ADD_CYCLES(4); \}#define PLP() \{ \   P = PULL(); \   SET_FLAG(R_FLAG); /* ensure reserved flag is set */ \   ADD_CYCLES(4); \}/* undocumented */#define RLA(cycles, read_func, write_func, addr) \{ \   read_func(addr, data); \   if (P & C_FLAG) \   { \      TEST_AND_FLAG(data & 0x80, C_FLAG); \      data = (data << 1) | 1; \   } \   else \   { \      TEST_AND_FLAG(data & 0x80, C_FLAG); \      data <<= 1; \   } \   write_func(addr, data); \   A &= data; \   SET_NZ_FLAGS(A); \   ADD_CYCLES(cycles); \}/* 9-bit rotation (carry flag used for rollover) */#define ROL(cycles, read_func, write_func, addr) \{ \   read_func(addr, data); \   if (P & C_FLAG) \   { \      TEST_AND_FLAG(data & 0x80, C_FLAG); \      data = (data << 1) | 1; \   } \   else \   { \      TEST_AND_FLAG(data & 0x80, C_FLAG); \      data <<= 1; \   } \   write_func(addr, data); \   SET_NZ_FLAGS(data); \   ADD_CYCLES(cycles); \}#define ROL_A() \{ \   if (P & C_FLAG) \   { \      TEST_AND_FLAG(A & 0x80, C_FLAG); \      A = (A << 1) | 1; \   } \   else \   { \      TEST_AND_FLAG(A & 0x80, C_FLAG); \      A <<= 1; \   } \   SET_NZ_FLAGS(A); \   ADD_CYCLES(2); \}#define ROR(cycles, read_func, write_func, addr) \{ \   read_func(addr, data); \   if (P & C_FLAG) \   { \      TEST_AND_FLAG(data & 1, C_FLAG); \      data = (data >> 1) | 0x80; \   } \   else \   { \      TEST_AND_FLAG(data & 1, C_FLAG); \      data >>= 1; \   } \   write_func(addr, data); \   SET_NZ_FLAGS(data); \   ADD_CYCLES(cycles); \}#define ROR_A() \{ \   if (P & C_FLAG) \   { \      TEST_AND_FLAG(A & 1, C_FLAG); \      A = (A >> 1) | 0x80; \   } \   else \   { \      TEST_AND_FLAG(A & 1, C_FLAG); \      A >>= 1; \   } \   SET_NZ_FLAGS(A); \   ADD_CYCLES(2); \}/* undocumented */#define RRA(cycles, read_func, write_func, addr) \{ \   read_func(addr, data); \   if (P & C_FLAG) \   { \      TEST_AND_FLAG(data & 1, C_FLAG); \      data = (data >> 1) | 0x80; \   } \   else \   { \      TEST_AND_FLAG(data & 1, C_FLAG); \      data >>= 1; \   } \   write_func(addr, data); \   ADC(cycles, NO_READ); \}#define RTI() \{ \   P = PULL(); \   SET_FLAG(R_FLAG); /* ensure reserved flag is set */ \   PC = PULL(); \   PC |= PULL() << 8; \   ADD_CYCLES(6); \}#define RTS() \{ \   PC = PULL(); \   PC = (PC | (PULL() << 8)) + 1; \   ADD_CYCLES(6); \}/* undocumented */#define SAX(cycles, read_func, write_func, addr) \{ \   read_func(addr); \   data = A & X; \   write_func(addr, data); \   ADD_CYCLES(cycles); \}/* Warning! NES CPU has no decimal mode, so by default this does no BCD! */#ifdef NES6502_DECIMAL#define SBC(cycles, read_func) \{ \   read_func(data); \   /* NOT(C) is considered borrow */ \   temp = A - data - ((P & C_FLAG) ^ C_FLAG); \   if (P & D_FLAG) \   { \      uint8 al, ah; \      al = (A & 0x0F) - (data & 0x0F) - ((P & C_FLAG) ^ C_FLAG); \      ah = (A >> 4) - (data >> 4); \      if (al & 0x10) \      { \         al -= 6; \         ah--; \      } \      if (ah & 0x10) \         ah -= 6; \      TEST_AND_FLAG(temp < 0x100, C_FLAG); \      TEST_AND_FLAG(((A ^ temp) & 0x80) && ((A ^ data) & 0x80), V_FLAG); \      SET_NZ_FLAGS(temp & 0xFF); \      A = (ah << 4) | (al & 0x0F); \   } \   else \   { \      TEST_AND_FLAG(((A ^ temp) & 0x80) && ((A ^ data) & 0x80), V_FLAG); \      TEST_AND_FLAG(temp < 0x100, C_FLAG); \      A = (uint8) temp; \      SET_NZ_FLAGS(A & 0xFF); \   } \   ADD_CYCLES(cycles); \}#else#define SBC(cycles, read_func) \{ \   read_func(data); \   temp = A - data - ((P & C_FLAG) ^ C_FLAG); \   TEST_AND_FLAG(((A ^ data) & (A ^ temp) & 0x80), V_FLAG); \   TEST_AND_FLAG(temp < 0x100, C_FLAG); \   A = (uint8) temp; \   SET_NZ_FLAGS(A); \   ADD_CYCLES(cycles); \}#endif /* NES6502_DECIMAL *//* undocumented */#define SBX(cycles, read_func) \{ \   read_func(data); \   temp = (A & X) - data; \   TEST_AND_FLAG(temp < 0x100, C_FLAG); \   X = temp & 0xFF; \   SET_NZ_FLAGS(X); \   ADD_CYCLES(cycles); \}#define SEC() \{ \   SET_FLAG(C_FLAG); \   ADD_CYCLES(2); \}#define SED() \{ \   SET_FLAG(D_FLAG); \   ADD_CYCLES(2); \}#define SEI() \{ \   SET_FLAG(I_FLAG); \   ADD_CYCLES(2); \}/* undocumented */#define SHA(cycles, read_func, write_func, addr) \{ \   read_func(addr); \   data = A & X & ((uint8) ((addr >> 8) + 1)); \   write_func(addr, data); \   ADD_CYCLES(cycles); \}/* undocumented */#define SHS(cycles, read_func, write_func, addr) \{ \   read_func(addr); \   S = A & X; \   data = S & ((uint8) ((addr >> 8) + 1)); \   write_func(addr, data); \   ADD_CYCLES(cycles); \}/* undocumented */#define SHX(cycles, read_func, write_func, addr) \{ \   read_func(addr); \   data = X & ((uint8) ((addr >> 8) + 1)); \   write_func(addr, data); \   ADD_CYCLES(cycles); \}/* undocumented */#define SHY(cycles, read_func, write_func, addr) \{ \   read_func(addr); \   data = Y & ((uint8) ((addr >> 8 ) + 1)); \   write_func(addr, data); \   ADD_CYCLES(cycles); \}/* undocumented */#define SLO(cycles, read_func, write_func, addr) \{ \   read_func(addr, data); \   TEST_AND_FLAG(data & 0x80, C_FLAG); \   data <<= 1; \   write_func(addr, data); \   A |= data; \   SET_NZ_FLAGS(A); \   ADD_CYCLES(cycles); \}/* unoffical */#define SRE(cycles, read_func, write_func, addr) \{ \   read_func(addr, data); \   TEST_AND_FLAG(data & 1, C_FLAG); \   data >>= 1; \   write_func(addr, data); \   A ^= data; \   SET_NZ_FLAGS(A); \   ADD_CYCLES(cycles); \}#define STA(cycles, read_func, write_func, addr) \{ \   read_func(addr); \   write_func(addr, A); \   ADD_CYCLES(cycles); \}#define STX(cycles, read_func, write_func, addr) \{ \   read_func(addr); \   write_func(addr, X); \   ADD_CYCLES(cycles); \}#define STY(cycles, read_func, write_func, addr) \{ \   read_func(addr); \   write_func(addr, Y); \   ADD_CYCLES(cycles); \}#define TAX() \{ \   X = A; \   SET_NZ_FLAGS(X);\   ADD_CYCLES(2); \}#define TAY() \{ \   Y = A; \   SET_NZ_FLAGS(Y);\   ADD_CYCLES(2); \}/* undocumented (triple-NOP) */#define TOP() \{ \   PC += 2; \   ADD_CYCLES(4); \}#define TSX() \{ \   X = S; \   SET_NZ_FLAGS(X);\   ADD_CYCLES(2); \}#define TXA() \{ \   A = X; \   SET_NZ_FLAGS(A);\   ADD_CYCLES(2); \}#define TXS() \{ \   S = X; \   ADD_CYCLES(2); \}#define TYA() \{ \   A = Y; \   SET_NZ_FLAGS(A); \   ADD_CYCLES(2); \}/*** Stack and data fetching macros*//* Set/clear/test bits in the flags register */#define  SET_FLAG(mask)          P |= (mask)#define  CLEAR_FLAG(mask)        P &= ~(mask)#define  IS_FLAG_SET(mask)       (P & (mask))#define  IS_FLAG_CLEAR(mask)     (0 == IS_FLAG_SET((mask)))#define  TEST_AND_FLAG(test, mask) \{ \   if ((test)) \      SET_FLAG((mask)); \   else \      CLEAR_FLAG((mask)); \}/*** flag register helper macros*//* register push/pull */#define  PUSH(value)             stack_page[S--] = (uint8) (value)#define  PULL()                  stack_page[++S]/* Sets the Z and N flags based on given data, taken from precomputed table */#define  SET_NZ_FLAGS(value)     P &= ~(N_FLAG | Z_FLAG); \                                 P |= flag_table[(value)]#define  GET_GLOBAL_REGS() \{ \   PC = reg_PC; \   A = reg_A; \   X = reg_X; \   Y = reg_Y; \   P = reg_P; \   S = reg_S; \}#define SET_LOCAL_REGS() \{ \   reg_PC = PC; \   reg_A = A; \   reg_X = X; \   reg_Y = Y; \   reg_P = P; \   reg_S = S; \}/* static data */static nes6502_memread *pmem_read, *pmr;static nes6502_memwrite *pmem_write, *pmw;/* lookup table for N/Z flags */static uint8 flag_table[256];/* internal critical CPU vars */static uint32 reg_PC;static uint8 reg_A, reg_P, reg_X, reg_Y, reg_S;static uint8 int_pending;static int dma_cycles;/* execution cycle count (can be reset by user) */static uint32 total_cycles = 0;/* memory region pointers */static uint8 *nes6502_banks[NES6502_NUMBANKS];static uint8 *ram = NULL;static uint8 *stack_page = NULL;/*** Zero-page helper macros*/#define  ZP_READ(addr)           ram[(addr)]#define  ZP_WRITE(addr, value)   ram[(addr)] = (uint8) (value)INLINE uint8 bank_readbyte(register uint32 address){   ASSERT(nes6502_banks[address >> NES6502_BANKSHIFT]);   return nes6502_banks[address >> NES6502_BANKSHIFT][address & NES6502_BANKMASK];}INLINE void bank_writebyte(register uint32 address, register uint8 value){   ASSERT(nes6502_banks[address >> NES6502_BANKSHIFT]);   nes6502_banks[address >> NES6502_BANKSHIFT][address & NES6502_BANKMASK] = value;}INLINE uint32 zp_address(register uint8 address){   uint8 *x = ram + address;   return (x[1] << 8) | x[0];}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -