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

📄 spc700.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * 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. */#include "snes9x.h"#include "spc700.h"#include "memmap.h"#include "display.h"#include "cpuexec.h"#include "apu.h"// SPC700/Sound DSP chips have a 24.57MHz crystal on their PCB.#ifdef NO_INLINE_SET_GETuint8 S9xAPUGetByteZ (uint8 address);uint8 S9xAPUGetByte (uint32 address);void S9xAPUSetByteZ (uint8, uint8 address);void S9xAPUSetByte (uint8, uint32 address);#else#undef INLINE#define INLINE inline#include "apumem.h"#endifSTART_EXTERN_Cextern uint8 Work8;extern uint16 Work16;extern uint32 Work32;extern signed char Int8;extern short Int16;extern long Int32;extern short Int16;extern uint8 W1;extern uint8 W2;END_EXTERN_C#define OP1 (*(IAPU.PC + 1))#define OP2 (*(IAPU.PC + 2))#ifdef SPC700_SHUTDOWN#define APUShutdown() \    if (Settings.Shutdown && (IAPU.PC == IAPU.WaitAddress1 || IAPU.PC == IAPU.WaitAddress2)) \    { \	if (IAPU.WaitCounter == 0) \	{ \	    if (!ICPU.CPUExecuting) \		APU.Cycles = CPU.Cycles = CPU.NextEvent; \	    else \		IAPU.APUExecuting = FALSE; \	} \	else \	if (IAPU.WaitCounter >= 2) \	    IAPU.WaitCounter = 1; \	else \	    IAPU.WaitCounter--; \    }#else#define APUShutdown()#endif#define APUSetZN8(b)\    IAPU._Zero = (b);#define APUSetZN16(w)\    IAPU._Zero = ((w) != 0) | ((w) >> 8);void STOP (char *s){    char buffer[100];#ifdef DEBUGGER    S9xAPUOPrint (buffer, IAPU.PC - IAPU.RAM);#endif    sprintf (String, "Sound CPU in unknown state executing %s at %04X\n%s\n", s, IAPU.PC - IAPU.RAM, buffer);    S9xMessage (S9X_ERROR, S9X_APU_STOPPED, String);    APU.TimerEnabled[0] = APU.TimerEnabled[1] = APU.TimerEnabled[2] = FALSE;    IAPU.APUExecuting = FALSE;#ifdef DEBUGGER    CPU.Flags |= DEBUG_MODE_FLAG;#else    S9xExit ();#endif}#define TCALL(n)\{\    PushW (IAPU.PC - IAPU.RAM + 1); \    IAPU.PC = IAPU.RAM + (APU.ExtraRAM [((15 - n) << 1)] + \	     (APU.ExtraRAM [((15 - n) << 1) + 1] << 8)); \}// XXX: HalfCarry#define SBC(a,b)\Int16 = (short) (a) - (short) (b) + (short) (APUCheckCarry ()) - 1;\APUClearHalfCarry ();\IAPU._Carry = Int16 >= 0;\if ((((a) ^ (b)) & 0x80) && (((a) ^ (uint8) Int16) & 0x80))\    APUSetOverflow ();\else \    APUClearOverflow (); \(a) = (uint8) Int16;\APUSetZN8 ((uint8) Int16);// XXX: HalfCarry#define ADC(a,b)\Work16 = (a) + (b) + APUCheckCarry();\APUClearHalfCarry ();\IAPU._Carry = Work16 >= 0x100; \if (~((a) ^ (b)) & ((b) ^ (uint8) Work16) & 0x80)\    APUSetOverflow ();\else \    APUClearOverflow (); \(a) = (uint8) Work16;\APUSetZN8 ((uint8) Work16);#define CMP(a,b)\Int16 = (short) (a) - (short) (b);\IAPU._Carry = Int16 >= 0;\APUSetZN8 ((uint8) Int16);#define ASL(b)\    IAPU._Carry = ((b) & 0x80) != 0; \    (b) <<= 1;\    APUSetZN8 (b);#define LSR(b)\    IAPU._Carry = (b) & 1;\    (b) >>= 1;\    APUSetZN8 (b);#define ROL(b)\    Work16 = ((b) << 1) | APUCheckCarry (); \    IAPU._Carry = Work16 >= 0x100; \    (b) = (uint8) Work16; \    APUSetZN8 (b);#define ROR(b)\    Work16 = (b) | ((uint16) APUCheckCarry () << 8); \    IAPU._Carry = (uint8) Work16 & 1; \    Work16 >>= 1; \    (b) = (uint8) Work16; \    APUSetZN8 (b);#define Push(b)\    *(IAPU.RAM + 0x100 + APURegisters.S) = b;\    APURegisters.S--;#define Pop(b)\    APURegisters.S++;\    (b) = *(IAPU.RAM + 0x100 + APURegisters.S);#ifdef FAST_LSB_WORD_ACCESS#define PushW(w)\    *(uint16 *) (IAPU.RAM + 0xff + APURegisters.S) = w;\    APURegisters.S -= 2;#define PopW(w)\    APURegisters.S += 2;\    w = *(uint16 *) (IAPU.RAM + 0xff + APURegisters.S);#else#define PushW(w)\    *(IAPU.RAM + 0xff + APURegisters.S) = w;\    *(IAPU.RAM + 0x100 + APURegisters.S) = (w >> 8);\    APURegisters.S -= 2;#define PopW(w)\    APURegisters.S += 2; \    (w) = *(IAPU.RAM + 0xff + APURegisters.S) + (*(IAPU.RAM + 0x100 + APURegisters.S) << 8);#endif#define Relative()\    Int8 = OP1;\    Int16 = (int) (IAPU.PC + 2 - IAPU.RAM) + Int8;#define Relative2()\    Int8 = OP2;\    Int16 = (int) (IAPU.PC + 3 - IAPU.RAM) + Int8;#ifdef FAST_LSB_WORD_ACCESS#define IndexedXIndirect()\    IAPU.Address = *(uint16 *) (IAPU.DirectPage + ((OP1 + APURegisters.X) & 0xff));#define Absolute()\    IAPU.Address = *(uint16 *) (IAPU.PC + 1);#define AbsoluteX()\    IAPU.Address = *(uint16 *) (IAPU.PC + 1) + APURegisters.X;#define AbsoluteY()\    IAPU.Address = *(uint16 *) (IAPU.PC + 1) + APURegisters.YA.B.Y;#define MemBit()\    IAPU.Address = *(uint16 *) (IAPU.PC + 1);\    IAPU.Bit = (uint8)(IAPU.Address >> 13);\    IAPU.Address &= 0x1fff;#define IndirectIndexedY()\    IAPU.Address = *(uint16 *) (IAPU.DirectPage + OP1) + APURegisters.YA.B.Y;#else#define IndexedXIndirect()\    IAPU.Address = *(IAPU.DirectPage + ((OP1 + APURegisters.X) & 0xff)) + \		  (*(IAPU.DirectPage + ((OP1 + APURegisters.X + 1) & 0xff)) << 8);#define Absolute()\    IAPU.Address = OP1 + (OP2 << 8);#define AbsoluteX()\    IAPU.Address = OP1 + (OP2 << 8) + APURegisters.X;#define AbsoluteY()\    IAPU.Address = OP1 + (OP2 << 8) + APURegisters.YA.B.Y;#define MemBit()\    IAPU.Address = OP1 + (OP2 << 8);\    IAPU.Bit = (int8) (IAPU.Address >> 13);\    IAPU.Address &= 0x1fff;#define IndirectIndexedY()\    IAPU.Address = *(IAPU.DirectPage + OP1) + \		  (*(IAPU.DirectPage + OP1 + 1) << 8) + \		  APURegisters.YA.B.Y;#endifvoid Apu00 (){// NOP    IAPU.PC++;}void Apu01 () { TCALL (0) }void Apu11 () { TCALL (1) }void Apu21 () { TCALL (2) }void Apu31 () { TCALL (3) }void Apu41 () { TCALL (4) }void Apu51 () { TCALL (5) }void Apu61 () { TCALL (6) }void Apu71 () { TCALL (7) }void Apu81 () { TCALL (8) }void Apu91 () { TCALL (9) }void ApuA1 () { TCALL (10) }void ApuB1 () { TCALL (11) }void ApuC1 () { TCALL (12) }void ApuD1 () { TCALL (13) }void ApuE1 () { TCALL (14) }void ApuF1 () { TCALL (15) }void Apu3F () // CALL absolute{    Absolute ();    PushW (IAPU.PC + 3 - IAPU.RAM);    IAPU.PC = IAPU.RAM + IAPU.Address;}void Apu4F () // PCALL $XX{    Work8 = OP1;    PushW (IAPU.PC + 2 - IAPU.RAM);    IAPU.PC = IAPU.RAM + 0xff00 + Work8;}#define SET(b) \S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1 ) | (1 << (b))), OP1); \IAPU.PC += 2void Apu02 (){    SET (0);}void Apu22 (){    SET (1);}void Apu42 (){    SET (2);}void Apu62 (){    SET (3);}void Apu82 (){    SET (4);}void ApuA2 (){    SET (5);}void ApuC2 (){    SET (6);}void ApuE2 (){    SET (7);}#define CLR(b) \S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1) & ~(1 << (b))), OP1); \IAPU.PC += 2;void Apu12 (){    CLR (0);}void Apu32 (){    CLR (1);}void Apu52 (){    CLR (2);}void Apu72 (){    CLR (3);}void Apu92 (){    CLR (4);}void ApuB2 (){    CLR (5);}void ApuD2 (){    CLR (6);}void ApuF2 (){    CLR (7);}#define BBS(b) \Work8 = OP1; \Relative2 (); \if (S9xAPUGetByteZ (Work8) & (1 << (b))) \{ \    IAPU.PC = IAPU.RAM + (uint16) Int16; \    APU.Cycles += IAPU.TwoCycles; \} \else \    IAPU.PC += 3void Apu03 (){    BBS (0);}void Apu23 (){    BBS (1);}void Apu43 (){    BBS (2);}void Apu63 (){    BBS (3);}void Apu83 (){    BBS (4);}void ApuA3 (){    BBS (5);}void ApuC3 (){    BBS (6);}void ApuE3 (){    BBS (7);}#define BBC(b) \Work8 = OP1; \Relative2 (); \if (!(S9xAPUGetByteZ (Work8) & (1 << (b)))) \{ \    IAPU.PC = IAPU.RAM + (uint16) Int16; \    APU.Cycles += IAPU.TwoCycles; \} \else \    IAPU.PC += 3void Apu13 (){    BBC (0);}void Apu33 (){    BBC (1);}void Apu53 (){    BBC (2);}void Apu73 (){    BBC (3);}void Apu93 (){    BBC (4);}void ApuB3 (){    BBC (5);}void ApuD3 (){    BBC (6);}void ApuF3 (){    BBC (7);}void Apu04 (){// OR A,dp    APURegisters.YA.B.A |= S9xAPUGetByteZ (OP1);    APUSetZN8 (APURegisters.YA.B.A);    IAPU.PC += 2;}void Apu05 (){// OR A,abs    Absolute ();    APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address);    APUSetZN8 (APURegisters.YA.B.A);    IAPU.PC += 3;}void Apu06 (){// OR A,(X)    APURegisters.YA.B.A |= S9xAPUGetByteZ (APURegisters.X);    APUSetZN8 (APURegisters.YA.B.A);    IAPU.PC++;}void Apu07 (){// OR A,(dp+X)    IndexedXIndirect ();    APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address);    APUSetZN8 (APURegisters.YA.B.A);    IAPU.PC += 2;}void Apu08 (){// OR A,#00    APURegisters.YA.B.A |= OP1;    APUSetZN8 (APURegisters.YA.B.A);    IAPU.PC += 2;}void Apu09 (){// OR dp(dest),dp(src)    Work8 = S9xAPUGetByteZ (OP1);    Work8 |= S9xAPUGetByteZ (OP2);    S9xAPUSetByteZ (Work8, OP2);    APUSetZN8 (Work8);    IAPU.PC += 3;}void Apu14 (){// OR A,dp+X    APURegisters.YA.B.A |= S9xAPUGetByteZ (OP1 + APURegisters.X);    APUSetZN8 (APURegisters.YA.B.A);    IAPU.PC += 2;}void Apu15 (){// OR A,abs+X    AbsoluteX ();    APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address);    APUSetZN8 (APURegisters.YA.B.A);    IAPU.PC += 3;}void Apu16 (){// OR A,abs+Y    AbsoluteY ();    APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address);    APUSetZN8 (APURegisters.YA.B.A);    IAPU.PC += 3;}void Apu17 (){// OR A,(dp)+Y    IndirectIndexedY ();    APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address);    APUSetZN8 (APURegisters.YA.B.A);    IAPU.PC += 2;}void Apu18 (){// OR dp,#00    Work8 = OP1;    Work8 |= S9xAPUGetByteZ (OP2);    S9xAPUSetByteZ (Work8, OP2);    APUSetZN8 (Work8);    IAPU.PC += 3;}void Apu19 (){// OR (X),(Y)    Work8 = S9xAPUGetByteZ (APURegisters.X) | S9xAPUGetByteZ (APURegisters.YA.B.Y);    APUSetZN8 (Work8);    S9xAPUSetByteZ (Work8, APURegisters.X);    IAPU.PC++;}void Apu0A (){// OR1 C,membit    MemBit ();    if (!APUCheckCarry ())    {	if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))	    APUSetCarry ();    }    IAPU.PC += 3;}void Apu2A (){// OR1 C,not membit    MemBit ();    if (!APUCheckCarry ())    {	if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))	    APUSetCarry ();    }    IAPU.PC += 3;}void Apu4A (){// AND1 C,membit    MemBit ();    if (APUCheckCarry ())    {	if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))	    APUClearCarry ();    }    IAPU.PC += 3;}void Apu6A (){// AND1 C, not membit    MemBit ();    if (APUCheckCarry ())    {	if ((S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))	    APUClearCarry ();    }    IAPU.PC += 3;}void Apu8A (){// EOR1 C, membit    MemBit ();    if (APUCheckCarry ())    {	if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))	    APUClearCarry ();    }    else    {	if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))	    APUSetCarry ();    }    IAPU.PC += 3;}void ApuAA (){// MOV1 C,membit    MemBit ();    if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))	APUSetCarry ();    else	APUClearCarry ();    IAPU.PC += 3;}void ApuCA (){// MOV1 membit,C    MemBit ();    if (APUCheckCarry ())    {	S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) | (1 << IAPU.Bit), IAPU.Address);    }    else    {	S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) & ~(1 << IAPU.Bit), IAPU.Address);    }    IAPU.PC += 3;}void ApuEA (){// NOT1 membit    MemBit ();    S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) ^ (1 << IAPU.Bit), IAPU.Address);    IAPU.PC += 3;}void Apu0B (){// ASL dp    Work8 = S9xAPUGetByteZ (OP1);    ASL (Work8);    S9xAPUSetByteZ (Work8, OP1);    IAPU.PC += 2;}void Apu0C (){// ASL abs    Absolute ();    Work8 = S9xAPUGetByte (IAPU.Address);    ASL (Work8);    S9xAPUSetByte (Work8, IAPU.Address);    IAPU.PC += 3;}void Apu1B (){// ASL dp+X    Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X);    ASL (Work8);    S9xAPUSetByteZ (Work8, OP1 + APURegisters.X);    IAPU.PC += 2;}void Apu1C (){// ASL A    ASL (APURegisters.YA.B.A);    IAPU.PC++;}void Apu0D (){// PUSH PSW    S9xAPUPackStatus ();    Push (APURegisters.P);    IAPU.PC++;}void Apu2D (){// PUSH A    Push (APURegisters.YA.B.A);    IAPU.PC++;}void Apu4D (){// PUSH X    Push (APURegisters.X);    IAPU.PC++;}void Apu6D (){// PUSH Y    Push (APURegisters.YA.B.Y);    IAPU.PC++;}void Apu8E (){// POP PSW    Pop (APURegisters.P);    S9xAPUUnpackStatus ();    if (APUCheckDirectPage ())	IAPU.DirectPage = IAPU.RAM + 0x100;    else	IAPU.DirectPage = IAPU.RAM;    IAPU.PC++;}void ApuAE (){// POP A    Pop (APURegisters.YA.B.A);    IAPU.PC++;}void ApuCE (){// POP X    Pop (APURegisters.X);    IAPU.PC++;}void ApuEE (){// POP Y    Pop (APURegisters.YA.B.Y);    IAPU.PC++;}void Apu0E (){// TSET1 abs    Absolute ();    Work8 = S9xAPUGetByte (IAPU.Address);    S9xAPUSetByte (Work8 | APURegisters.YA.B.A, IAPU.Address);    Work8 &= APURegisters.YA.B.A;    APUSetZN8 (Work8);    IAPU.PC += 3;}void Apu4E (){// TCLR1 abs    Absolute ();    Work8 = S9xAPUGetByte (IAPU.Address);    S9xAPUSetByte (Work8 & ~APURegisters.YA.B.A, IAPU.Address);    Work8 &= APURegisters.YA.B.A;    APUSetZN8 (Work8);    IAPU.PC += 3;}void Apu0F (){// BRK#if 0    STOP ("BRK");#else    PushW (IAPU.PC + 1 - IAPU.RAM);    S9xAPUPackStatus ();

⌨️ 快捷键说明

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