📄 fxinst.cpp
字号:
/* * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. * * (c) Copyright 1996 - 2001 Gary Henderson (gary@daniver.demon.co.uk) and * Jerremy Koot (jkoot@snes9x.com) * * Super FX C emulator code * (c) Copyright 1997 - 1999 Ivar (Ivar@snes9x.com) and * Gary Henderson. * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. * * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. * C4 C code (c) Copyright 2001 Gary Henderson (gary@daniver.demon.co.uk). * * DOS port code contains the works of other authors. See headers in * individual files. * * Snes9x homepage: 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 = (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); uint32 y = USEX8(R2); uint8 *a; uint8 v,c; R15++; CLRFLAGS; R1++;#ifdef CHECK_LIMITS if(y >= GSU.vScreenHeight) return;#endif if(GSU.vPlotOptionReg & 0x02) c = (x^y)&1 ? (uint8)(GSU.vColorReg>>4) : (uint8)GSU.vColorReg; else c = (uint8)GSU.vColorReg; if( !(GSU.vPlotOptionReg & 0x01) && !(c & 0xf)) return; a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); v = 128 >> (x&7); if(c & 0x01) a[0] |= v; else a[0] &= ~v; if(c & 0x02) a[1] |= v; else a[1] &= ~v;}/* 2c(ALT1) - rpix - read color of the pixel with R1,R2 as x,y */static void fx_rpix_2bit(){ uint32 x = USEX8(R1); uint32 y = USEX8(R2); uint8 *a; uint8 v; R15++; CLRFLAGS;#ifdef CHECK_LIMITS if(y >= GSU.vScreenHeight) return;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -