📄 fxinst.cpp
字号:
/******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), funkyass (funkyass@spam.shaw.ca), Joel Yliluoma (http://iki.fi/bisqwit/) Kris Bleakley (codeviolation@hotmail.com), Matthew Kendora, Nach (n-a-c-h@users.sourceforge.net), Peter Bortas (peter@bortas.org) and zones (kasumitokoduck@yahoo.com) C4 x86 assembler and some C emulation code (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), _Demo_ (_demo_@zsnes.com), and Nach C4 C++ code (c) Copyright 2003 Brad Jorsch DSP-1 emulator code (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, John Weidman, neviksti (neviksti@hotmail.com), Kris Bleakley, Andreas Naive DSP-2 emulator code (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and Lord Nightmare (lord_nightmare@users.sourceforge.net OBC1 emulator code (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and Kris Bleakley Ported from x86 assembler to C by sanmaiwashi SPC7110 and RTC C++ emulator code (c) Copyright 2002 Matthew Kendora with research by zsKnight, John Weidman, and Dark Force S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman S-RTC C emulator code (c) Copyright 2001 John Weidman ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora Super FX x86 assembler emulator code (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) Specific ports contains the works of other authors. See headers in individual files. Snes9x homepage: http://www.snes9x.com Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies.*******************************************************************************/#define FX_DO_ROMBUFFER#include "fxemu.h"#include "fxinst.h"#include <string.h>#include <stdio.h>extern struct FxRegs_s GSU;int gsu_bank [512] = {0};/* Set this define if you wish the plot instruction to check for y-pos limits *//* (I don't think it's nessecary) */#define CHECK_LIMITS/* Codes used: * * rn = a GSU register (r0-r15) * #n = 4 bit immediate value * #pp = 8 bit immediate value * (yy) = 8 bit word address (0x0000 - 0x01fe) * #xx = 16 bit immediate value * (xx) = 16 bit address (0x0000 - 0xffff) * *//* 00 - stop - stop GSU execution (and maybe generate an IRQ) */static void fx_stop(){ CF(G); GSU.vCounter = 0; GSU.vInstCount = GSU.vCounter; /* Check if we need to generate an IRQ */ if(!(GSU.pvRegisters[GSU_CFGR] & 0x80)) SF(IRQ); GSU.vPlotOptionReg = 0; GSU.vPipe = 1; CLRFLAGS; R15++;}/* 01 - nop - no operation */static void fx_nop() { CLRFLAGS; R15++; }extern void fx_flushCache();/* 02 - cache - reintialize GSU cache */static void fx_cache(){ uint32 c = R15 & 0xfff0; if(GSU.vCacheBaseReg != c || !GSU.bCacheActive) { fx_flushCache(); GSU.vCacheBaseReg = c; GSU.bCacheActive = TRUE;#if 0 if(c < (0x10000-512)) { uint8 const* t = &ROM(c); memcpy(GSU.pvCache,t,512); } else { uint8 const* t1; uint8 const* t2; uint32 i = 0x10000 - c; t1 = &ROM(c); t2 = &ROM(0); memcpy(GSU.pvCache,t1,i); memcpy(&GSU.pvCache[i],t2,512-i); }#endif } R15++; CLRFLAGS;}/* 03 - lsr - logic shift right */static void fx_lsr(){ uint32 v; GSU.vCarry = SREG & 1; v = USEX16(SREG) >> 1; R15++; DREG = v; GSU.vSign = v; GSU.vZero = v; TESTR14; CLRFLAGS;}/* 04 - rol - rotate left */static void fx_rol(){ uint32 v = USEX16((SREG << 1) + GSU.vCarry); GSU.vCarry = (SREG >> 15) & 1; R15++; DREG = v; GSU.vSign = v; GSU.vZero = v; TESTR14; CLRFLAGS;}/* 05 - bra - branch always */static void fx_bra() { uint8 v = PIPE; R15++; FETCHPIPE; R15 += SEX8(v); }/* Branch on condition */#define BRA_COND(cond) uint8 v = PIPE; R15++; FETCHPIPE; if(cond) R15 += SEX8(v); else R15++;#define TEST_S (GSU.vSign & 0x8000)#define TEST_Z (USEX16(GSU.vZero) == 0)#define TEST_OV (GSU.vOverflow >= 0x8000 || GSU.vOverflow < -0x8000)#define TEST_CY (GSU.vCarry & 1)/* 06 - blt - branch on less than */static void fx_blt() { BRA_COND( (TEST_S!=0) != (TEST_OV!=0) ); }/* 07 - bge - branch on greater or equals */static void fx_bge() { BRA_COND( (TEST_S!=0) == (TEST_OV!=0)); }/* 08 - bne - branch on not equal */static void fx_bne() { BRA_COND( !TEST_Z ); }/* 09 - beq - branch on equal */static void fx_beq() { BRA_COND( TEST_Z ); }/* 0a - bpl - branch on plus */static void fx_bpl() { BRA_COND( !TEST_S ); }/* 0b - bmi - branch on minus */static void fx_bmi() { BRA_COND( TEST_S ); }/* 0c - bcc - branch on carry clear */static void fx_bcc() { BRA_COND( !TEST_CY ); }/* 0d - bcs - branch on carry set */static void fx_bcs() { BRA_COND( TEST_CY ); }/* 0e - bvc - branch on overflow clear */static void fx_bvc() { BRA_COND( !TEST_OV ); }/* 0f - bvs - branch on overflow set */static void fx_bvs() { BRA_COND( TEST_OV ); }/* 10-1f - to rn - set register n as destination register *//* 10-1f(B) - move rn - move one register to another (if B flag is set) */#define FX_TO(reg) \if(TF(B)) { GSU.avReg[(reg)] = SREG; CLRFLAGS; } \else { GSU.pvDreg = &GSU.avReg[reg]; } R15++;#define FX_TO_R14(reg) \if(TF(B)) { GSU.avReg[(reg)] = SREG; CLRFLAGS; READR14; } \else { GSU.pvDreg = &GSU.avReg[reg]; } R15++;#define FX_TO_R15(reg) \if(TF(B)) { GSU.avReg[(reg)] = SREG; CLRFLAGS; } \else { GSU.pvDreg = &GSU.avReg[reg]; R15++; }static void fx_to_r0() { FX_TO(0); }static void fx_to_r1() { FX_TO(1); }static void fx_to_r2() { FX_TO(2); }static void fx_to_r3() { FX_TO(3); }static void fx_to_r4() { FX_TO(4); }static void fx_to_r5() { FX_TO(5); }static void fx_to_r6() { FX_TO(6); }static void fx_to_r7() { FX_TO(7); }static void fx_to_r8() { FX_TO(8); }static void fx_to_r9() { FX_TO(9); }static void fx_to_r10() { FX_TO(10); }static void fx_to_r11() { FX_TO(11); }static void fx_to_r12() { FX_TO(12); }static void fx_to_r13() { FX_TO(13); }static void fx_to_r14() { FX_TO_R14(14); }static void fx_to_r15() { FX_TO_R15(15); }/* 20-2f - to rn - set register n as source and destination register */#define FX_WITH(reg) SF(B); GSU.pvSreg = GSU.pvDreg = &GSU.avReg[reg]; R15++;static void fx_with_r0() { FX_WITH(0); }static void fx_with_r1() { FX_WITH(1); }static void fx_with_r2() { FX_WITH(2); }static void fx_with_r3() { FX_WITH(3); }static void fx_with_r4() { FX_WITH(4); }static void fx_with_r5() { FX_WITH(5); }static void fx_with_r6() { FX_WITH(6); }static void fx_with_r7() { FX_WITH(7); }static void fx_with_r8() { FX_WITH(8); }static void fx_with_r9() { FX_WITH(9); }static void fx_with_r10() { FX_WITH(10); }static void fx_with_r11() { FX_WITH(11); }static void fx_with_r12() { FX_WITH(12); }static void fx_with_r13() { FX_WITH(13); }static void fx_with_r14() { FX_WITH(14); }static void fx_with_r15() { FX_WITH(15); }/* 30-3b - stw (rn) - store word */#define FX_STW(reg) \GSU.vLastRamAdr = GSU.avReg[reg]; \RAM(GSU.avReg[reg]) = (uint8)SREG; \RAM(GSU.avReg[reg]^1) = (uint8)(SREG>>8); \CLRFLAGS; R15++static void fx_stw_r0() { FX_STW(0); }static void fx_stw_r1() { FX_STW(1); }static void fx_stw_r2() { FX_STW(2); }static void fx_stw_r3() { FX_STW(3); }static void fx_stw_r4() { FX_STW(4); }static void fx_stw_r5() { FX_STW(5); }static void fx_stw_r6() { FX_STW(6); }static void fx_stw_r7() { FX_STW(7); }static void fx_stw_r8() { FX_STW(8); }static void fx_stw_r9() { FX_STW(9); }static void fx_stw_r10() { FX_STW(10); }static void fx_stw_r11() { FX_STW(11); }/* 30-3b(ALT1) - stb (rn) - store byte */#define FX_STB(reg) \GSU.vLastRamAdr = GSU.avReg[reg]; \RAM(GSU.avReg[reg]) = (uint8)SREG; \CLRFLAGS; R15++static void fx_stb_r0() { FX_STB(0); }static void fx_stb_r1() { FX_STB(1); }static void fx_stb_r2() { FX_STB(2); }static void fx_stb_r3() { FX_STB(3); }static void fx_stb_r4() { FX_STB(4); }static void fx_stb_r5() { FX_STB(5); }static void fx_stb_r6() { FX_STB(6); }static void fx_stb_r7() { FX_STB(7); }static void fx_stb_r8() { FX_STB(8); }static void fx_stb_r9() { FX_STB(9); }static void fx_stb_r10() { FX_STB(10); }static void fx_stb_r11() { FX_STB(11); }/* 3c - loop - decrement loop counter, and branch on not zero */static void fx_loop(){ GSU.vSign = GSU.vZero = --R12; if( (uint16) R12 != 0 ) R15 = R13; else R15++; CLRFLAGS;}/* 3d - alt1 - set alt1 mode */static void fx_alt1() { SF(ALT1); CF(B); R15++; }/* 3e - alt2 - set alt2 mode */static void fx_alt2() { SF(ALT2); CF(B); R15++; }/* 3f - alt3 - set alt3 mode */static void fx_alt3() { SF(ALT1); SF(ALT2); CF(B); R15++; } /* 40-4b - ldw (rn) - load word from RAM */#define FX_LDW(reg) uint32 v; \GSU.vLastRamAdr = GSU.avReg[reg]; \v = (uint32)RAM(GSU.avReg[reg]); \v |= ((uint32)RAM(GSU.avReg[reg]^1))<<8; \R15++; DREG = v; \TESTR14; \CLRFLAGSstatic void fx_ldw_r0() { FX_LDW(0); }static void fx_ldw_r1() { FX_LDW(1); }static void fx_ldw_r2() { FX_LDW(2); }static void fx_ldw_r3() { FX_LDW(3); }static void fx_ldw_r4() { FX_LDW(4); }static void fx_ldw_r5() { FX_LDW(5); }static void fx_ldw_r6() { FX_LDW(6); }static void fx_ldw_r7() { FX_LDW(7); }static void fx_ldw_r8() { FX_LDW(8); }static void fx_ldw_r9() { FX_LDW(9); }static void fx_ldw_r10() { FX_LDW(10); }static void fx_ldw_r11() { FX_LDW(11); }/* 40-4b(ALT1) - ldb (rn) - load byte */#define FX_LDB(reg) uint32 v; \GSU.vLastRamAdr = GSU.avReg[reg]; \v = (uint32)RAM(GSU.avReg[reg]); \R15++; DREG = v; \TESTR14; \CLRFLAGSstatic void fx_ldb_r0() { FX_LDB(0); }static void fx_ldb_r1() { FX_LDB(1); }static void fx_ldb_r2() { FX_LDB(2); }static void fx_ldb_r3() { FX_LDB(3); }static void fx_ldb_r4() { FX_LDB(4); }static void fx_ldb_r5() { FX_LDB(5); }static void fx_ldb_r6() { FX_LDB(6); }static void fx_ldb_r7() { FX_LDB(7); }static void fx_ldb_r8() { FX_LDB(8); }static void fx_ldb_r9() { FX_LDB(9); }static void fx_ldb_r10() { FX_LDB(10); }static void fx_ldb_r11() { FX_LDB(11); }/* 4c - plot - plot pixel with R1,R2 as x,y and the color register as the color */static void fx_plot_2bit(){ uint32 x = USEX8(R1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -