mirror of https://github.com/snes9xgit/snes9x.git
Merged with coreupdate branch, so now the master branch has improved IRQ and SA-1. / Remove i386 asm codes.
This commit is contained in:
commit
82435ab5db
c4.cppc4.hcheats2.cppcontrols.cppcpu.cppcpuexec.cppcpuexec.hcpumacro.hcpuops.cppcpuops.hdebug.cppdma.cpp
docs
fxemu.cppfxemu.hfxinst.hgetset.hglobals.cppi386
c4.asmfxemu2.asmfxemu2.macfxemu2b.asmfxemu2b.macfxemu2c.asmfxemu2c.macfxtable.asmmacros.macregs.macregsw.macsfxproc.asmzsnes.asmzsnesc4.asm
memmap.cppmemmap.hppu.cppppu.hsa1.cppsa1.hsa1cpu.cppsnapshot.cppsnapshot.hsnes9x.cppsnes9x.hunix
11
c4.cpp
11
c4.cpp
|
@ -328,14 +328,3 @@ uint8 * S9xGetMemPointerC4 (uint16 Address)
|
|||
return (NULL);
|
||||
return (Memory.C4RAM - 0x6000 + (Address & 0xffff));
|
||||
}
|
||||
|
||||
#ifdef ZSNES_C4
|
||||
START_EXTERN_C
|
||||
|
||||
void C4LoaDMem (char *C4RAM)
|
||||
{
|
||||
memmove(C4RAM + (READ_WORD(C4RAM + 0x1f45) & 0x1fff), C4GetMemPointer(READ_3WORD(C4RAM + 0x1f40)), READ_WORD(C4RAM + 0x1f43));
|
||||
}
|
||||
|
||||
END_EXTERN_C
|
||||
#endif
|
||||
|
|
13
c4.h
13
c4.h
|
@ -178,10 +178,6 @@
|
|||
#ifndef _C4_H_
|
||||
#define _C4_H_
|
||||
|
||||
#ifdef ZSNES_C4
|
||||
START_EXTERN_C
|
||||
#endif
|
||||
|
||||
extern int16 C4WFXVal;
|
||||
extern int16 C4WFYVal;
|
||||
extern int16 C4WFZVal;
|
||||
|
@ -195,10 +191,6 @@ extern int16 C41FAngleRes;
|
|||
extern int16 C41FDist;
|
||||
extern int16 C41FDistVal;
|
||||
|
||||
#ifdef ZSNES_C4
|
||||
extern uint8 *C4Ram;
|
||||
#endif
|
||||
|
||||
void C4TransfWireFrame (void);
|
||||
void C4TransfWireFrame2 (void);
|
||||
void C4CalcWireFrame (void);
|
||||
|
@ -208,11 +200,6 @@ void C4Op1F (void);
|
|||
void S9xInitC4 (void);
|
||||
void S9xSetC4 (uint8, uint16);
|
||||
uint8 S9xGetC4 (uint16);
|
||||
|
||||
#ifdef ZSNES_C4
|
||||
END_EXTERN_C
|
||||
#endif
|
||||
|
||||
uint8 * S9xGetBasePointerC4 (uint16);
|
||||
uint8 * S9xGetMemPointerC4 (uint16);
|
||||
|
||||
|
|
|
@ -186,12 +186,9 @@ static void S9xSetByteFree (uint8, uint32);
|
|||
static uint8 S9xGetByteFree (uint32 address)
|
||||
{
|
||||
uint32 Cycles = CPU.Cycles;
|
||||
uint32 WaitAddress = CPU.WaitAddress;
|
||||
uint8 byte;
|
||||
|
||||
byte = S9xGetByte(address);
|
||||
|
||||
CPU.WaitAddress = WaitAddress;
|
||||
CPU.Cycles = Cycles;
|
||||
|
||||
return (byte);
|
||||
|
@ -200,11 +197,8 @@ static uint8 S9xGetByteFree (uint32 address)
|
|||
static void S9xSetByteFree (uint8 byte, uint32 address)
|
||||
{
|
||||
uint32 Cycles = CPU.Cycles;
|
||||
uint32 WaitAddress = CPU.WaitAddress;
|
||||
|
||||
S9xSetByte(byte, address);
|
||||
|
||||
CPU.WaitAddress = WaitAddress;
|
||||
CPU.Cycles = Cycles;
|
||||
}
|
||||
|
||||
|
|
|
@ -425,7 +425,6 @@ static const int ptrspeeds[4] = { 1, 1, 4, 8 };
|
|||
S(ToggleBG2), \
|
||||
S(ToggleBG3), \
|
||||
S(ToggleEmuTurbo), \
|
||||
S(ToggleHDMA), \
|
||||
S(ToggleSprites), \
|
||||
S(ToggleTransparency) \
|
||||
|
||||
|
@ -2454,11 +2453,6 @@ void S9xApplyCommand (s9xcommand_t cmd, int16 data1, int16 data2)
|
|||
DisplayStateChange("Sprites", !(Settings.BG_Forced & 16));
|
||||
break;
|
||||
|
||||
case ToggleHDMA:
|
||||
Settings.DisableHDMA = !Settings.DisableHDMA;
|
||||
DisplayStateChange("HDMA emulation", !Settings.DisableHDMA);
|
||||
break;
|
||||
|
||||
case ToggleTransparency:
|
||||
Settings.Transparency = !Settings.Transparency;
|
||||
DisplayStateChange("Transparency effects", Settings.Transparency);
|
||||
|
|
14
cpu.cpp
14
cpu.cpp
|
@ -208,12 +208,16 @@ static void S9xResetCPU (void)
|
|||
static void S9xSoftResetCPU (void)
|
||||
{
|
||||
CPU.Cycles = 182; // Or 188. This is the cycle count just after the jump to the Reset Vector.
|
||||
CPU.PrevCycles = -1;
|
||||
CPU.PrevCycles = CPU.Cycles;
|
||||
CPU.V_Counter = 0;
|
||||
CPU.Flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG);
|
||||
CPU.PCBase = NULL;
|
||||
CPU.IRQActive = FALSE;
|
||||
CPU.IRQPending = 0;
|
||||
CPU.NMILine = FALSE;
|
||||
CPU.IRQLine = FALSE;
|
||||
CPU.IRQTransition = FALSE;
|
||||
CPU.IRQLastState = FALSE;
|
||||
CPU.IRQExternal = FALSE;
|
||||
CPU.IRQPending = Timings.IRQPendCount;
|
||||
CPU.MemSpeed = SLOW_ONE_CYCLE;
|
||||
CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2;
|
||||
CPU.FastROMSpeed = SLOW_ONE_CYCLE;
|
||||
|
@ -226,9 +230,6 @@ static void S9xSoftResetCPU (void)
|
|||
CPU.WhichEvent = HC_RENDER_EVENT;
|
||||
CPU.NextEvent = Timings.RenderPos;
|
||||
CPU.WaitingForInterrupt = FALSE;
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
CPU.WaitCounter = 0;
|
||||
CPU.PBPCAtOpcodeStart = 0xffffffff;
|
||||
CPU.AutoSaveTimer = 0;
|
||||
CPU.SRAMModified = FALSE;
|
||||
|
||||
|
@ -261,7 +262,6 @@ static void S9xSoftResetCPU (void)
|
|||
|
||||
ICPU.S9xOpcodes = S9xOpcodesE1;
|
||||
ICPU.S9xOpLengths = S9xOpLengthsM1X1;
|
||||
ICPU.CPUExecuting = TRUE;
|
||||
|
||||
S9xUnpackStatus();
|
||||
}
|
||||
|
|
253
cpuexec.cpp
253
cpuexec.cpp
|
@ -187,102 +187,91 @@
|
|||
#include "missing.h"
|
||||
#endif
|
||||
|
||||
static inline void S9xReschedule (void);
|
||||
|
||||
|
||||
void S9xMainLoop (void)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (CPU.Flags)
|
||||
if (CPU.NMILine)
|
||||
{
|
||||
if (CPU.Flags & NMI_FLAG)
|
||||
if (Timings.NMITriggerPos <= CPU.Cycles)
|
||||
{
|
||||
if (Timings.NMITriggerPos <= CPU.Cycles)
|
||||
CPU.NMILine = FALSE;
|
||||
Timings.NMITriggerPos = 0xffff;
|
||||
if (CPU.WaitingForInterrupt)
|
||||
{
|
||||
CPU.Flags &= ~NMI_FLAG;
|
||||
Timings.NMITriggerPos = 0xffff;
|
||||
if (CPU.WaitingForInterrupt)
|
||||
{
|
||||
CPU.WaitingForInterrupt = FALSE;
|
||||
Registers.PCw++;
|
||||
}
|
||||
|
||||
S9xOpcode_NMI();
|
||||
CPU.WaitingForInterrupt = FALSE;
|
||||
Registers.PCw++;
|
||||
}
|
||||
|
||||
S9xOpcode_NMI();
|
||||
}
|
||||
|
||||
#ifdef DEBUGGER
|
||||
if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG))
|
||||
{
|
||||
for (int Break = 0; Break != 6; Break++)
|
||||
{
|
||||
if (S9xBreakpoint[Break].Enabled &&
|
||||
S9xBreakpoint[Break].Bank == Registers.PB &&
|
||||
S9xBreakpoint[Break].Address == Registers.PCw)
|
||||
{
|
||||
if (S9xBreakpoint[Break].Enabled == 2)
|
||||
S9xBreakpoint[Break].Enabled = TRUE;
|
||||
else
|
||||
CPU.Flags |= DEBUG_MODE_FLAG;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CPU.Flags & IRQ_FLAG)
|
||||
{
|
||||
if (CPU.IRQPending)
|
||||
// FIXME: In case of IRQ during WRAM refresh
|
||||
CPU.IRQPending--;
|
||||
else
|
||||
{
|
||||
if (CPU.WaitingForInterrupt)
|
||||
{
|
||||
CPU.WaitingForInterrupt = FALSE;
|
||||
Registers.PCw++;
|
||||
}
|
||||
|
||||
if (CPU.IRQActive && !Settings.DisableIRQ)
|
||||
{
|
||||
if (!CheckFlag(IRQ))
|
||||
// in IRQ handler $4211 is supposed to be read, so IRQ_FLAG should be cleared.
|
||||
S9xOpcode_IRQ();
|
||||
}
|
||||
else
|
||||
CPU.Flags &= ~IRQ_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
if (CPU.Flags & SCAN_KEYS_FLAG)
|
||||
break;
|
||||
|
||||
#ifdef DEBUGGER
|
||||
if (CPU.Flags & DEBUG_MODE_FLAG)
|
||||
break;
|
||||
|
||||
if (CPU.Flags & TRACE_FLAG)
|
||||
S9xTrace();
|
||||
|
||||
if (CPU.Flags & SINGLE_STEP_FLAG)
|
||||
{
|
||||
CPU.Flags &= ~SINGLE_STEP_FLAG;
|
||||
CPU.Flags |= DEBUG_MODE_FLAG;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.PBPCAtOpcodeStart = Registers.PBPC;
|
||||
if (CPU.IRQTransition || CPU.IRQExternal)
|
||||
{
|
||||
if (CPU.IRQPending)
|
||||
CPU.IRQPending--;
|
||||
else
|
||||
{
|
||||
if (CPU.WaitingForInterrupt)
|
||||
{
|
||||
CPU.WaitingForInterrupt = FALSE;
|
||||
Registers.PCw++;
|
||||
}
|
||||
|
||||
CPU.IRQTransition = FALSE;
|
||||
CPU.IRQPending = Timings.IRQPendCount;
|
||||
|
||||
if (!CheckFlag(IRQ))
|
||||
S9xOpcode_IRQ();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUGGER
|
||||
if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG))
|
||||
{
|
||||
for (int Break = 0; Break != 6; Break++)
|
||||
{
|
||||
if (S9xBreakpoint[Break].Enabled &&
|
||||
S9xBreakpoint[Break].Bank == Registers.PB &&
|
||||
S9xBreakpoint[Break].Address == Registers.PCw)
|
||||
{
|
||||
if (S9xBreakpoint[Break].Enabled == 2)
|
||||
S9xBreakpoint[Break].Enabled = TRUE;
|
||||
else
|
||||
CPU.Flags |= DEBUG_MODE_FLAG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CPU.Flags & DEBUG_MODE_FLAG)
|
||||
break;
|
||||
|
||||
if (CPU.Flags & TRACE_FLAG)
|
||||
S9xTrace();
|
||||
|
||||
if (CPU.Flags & SINGLE_STEP_FLAG)
|
||||
{
|
||||
CPU.Flags &= ~SINGLE_STEP_FLAG;
|
||||
CPU.Flags |= DEBUG_MODE_FLAG;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CPU.Flags & SCAN_KEYS_FLAG)
|
||||
break;
|
||||
|
||||
register uint8 Op;
|
||||
register struct SOpcodes *Opcodes;
|
||||
|
||||
CPU.PrevCycles = CPU.Cycles;
|
||||
|
||||
if (CPU.PCBase)
|
||||
{
|
||||
Op = CPU.PCBase[Registers.PCw];
|
||||
CPU.PrevCycles = CPU.Cycles;
|
||||
CPU.Cycles += CPU.MemSpeed;
|
||||
S9xCheckInterrupts();
|
||||
Opcodes = ICPU.S9xOpcodes;
|
||||
}
|
||||
else
|
||||
|
@ -304,13 +293,8 @@ void S9xMainLoop (void)
|
|||
Registers.PCw++;
|
||||
(*Opcodes[Op].S9xOpcode)();
|
||||
|
||||
if (SA1.Executing)
|
||||
if (Settings.SA1)
|
||||
S9xSA1MainLoop();
|
||||
|
||||
#if (S9X_ACCURACY_LEVEL <= 2)
|
||||
while (CPU.Cycles >= CPU.NextEvent)
|
||||
S9xDoHEventProcessing();
|
||||
#endif
|
||||
}
|
||||
|
||||
S9xPackStatus();
|
||||
|
@ -325,54 +309,54 @@ void S9xMainLoop (void)
|
|||
}
|
||||
}
|
||||
|
||||
void S9xSetIRQ (uint32 source)
|
||||
static inline void S9xReschedule (void)
|
||||
{
|
||||
CPU.IRQActive |= source;
|
||||
CPU.IRQPending = Timings.IRQPendCount;
|
||||
CPU.Flags |= IRQ_FLAG;
|
||||
|
||||
if (CPU.WaitingForInterrupt)
|
||||
switch (CPU.WhichEvent)
|
||||
{
|
||||
// Force IRQ to trigger immediately after WAI -
|
||||
// Final Fantasy Mystic Quest crashes without this.
|
||||
CPU.WaitingForInterrupt = FALSE;
|
||||
Registers.PCw++;
|
||||
case HC_HBLANK_START_EVENT:
|
||||
CPU.WhichEvent = HC_HDMA_START_EVENT;
|
||||
CPU.NextEvent = Timings.HDMAStart;
|
||||
break;
|
||||
|
||||
case HC_HDMA_START_EVENT:
|
||||
CPU.WhichEvent = HC_HCOUNTER_MAX_EVENT;
|
||||
CPU.NextEvent = Timings.H_Max;
|
||||
break;
|
||||
|
||||
case HC_HCOUNTER_MAX_EVENT:
|
||||
CPU.WhichEvent = HC_HDMA_INIT_EVENT;
|
||||
CPU.NextEvent = Timings.HDMAInit;
|
||||
break;
|
||||
|
||||
case HC_HDMA_INIT_EVENT:
|
||||
CPU.WhichEvent = HC_RENDER_EVENT;
|
||||
CPU.NextEvent = Timings.RenderPos;
|
||||
break;
|
||||
|
||||
case HC_RENDER_EVENT:
|
||||
CPU.WhichEvent = HC_WRAM_REFRESH_EVENT;
|
||||
CPU.NextEvent = Timings.WRAMRefreshPos;
|
||||
break;
|
||||
|
||||
case HC_WRAM_REFRESH_EVENT:
|
||||
CPU.WhichEvent = HC_HBLANK_START_EVENT;
|
||||
CPU.NextEvent = Timings.HBlankStart;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUGGER
|
||||
S9xTraceMessage("--- /IRQ low");
|
||||
#endif
|
||||
}
|
||||
|
||||
void S9xClearIRQ (uint32 source)
|
||||
{
|
||||
CPU.IRQActive &= ~source;
|
||||
if (!CPU.IRQActive)
|
||||
CPU.Flags &= ~IRQ_FLAG;
|
||||
|
||||
#ifdef DEBUGGER
|
||||
S9xTraceMessage("--- /IRQ high");
|
||||
#endif
|
||||
}
|
||||
|
||||
void S9xDoHEventProcessing (void)
|
||||
{
|
||||
#ifdef DEBUGGER
|
||||
static char eventname[13][32] =
|
||||
static char eventname[7][32] =
|
||||
{
|
||||
"",
|
||||
"HC_HBLANK_START_EVENT",
|
||||
"HC_IRQ_1_3_EVENT ",
|
||||
"HC_HDMA_START_EVENT ",
|
||||
"HC_IRQ_3_5_EVENT ",
|
||||
"HC_HCOUNTER_MAX_EVENT",
|
||||
"HC_IRQ_5_7_EVENT ",
|
||||
"HC_HDMA_INIT_EVENT ",
|
||||
"HC_IRQ_7_9_EVENT ",
|
||||
"HC_RENDER_EVENT ",
|
||||
"HC_IRQ_9_A_EVENT ",
|
||||
"HC_WRAM_REFRESH_EVENT",
|
||||
"HC_IRQ_A_1_EVENT "
|
||||
"HC_WRAM_REFRESH_EVENT"
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -382,19 +366,13 @@ void S9xDoHEventProcessing (void)
|
|||
eventname[CPU.WhichEvent], CPU.NextEvent, CPU.Cycles);
|
||||
#endif
|
||||
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitCounter++;
|
||||
#endif
|
||||
|
||||
switch (CPU.WhichEvent)
|
||||
{
|
||||
case HC_HBLANK_START_EVENT:
|
||||
S9xCheckMissingHTimerPosition(Timings.HBlankStart);
|
||||
S9xReschedule();
|
||||
break;
|
||||
|
||||
case HC_HDMA_START_EVENT:
|
||||
S9xCheckMissingHTimerPosition(Timings.HDMAStart);
|
||||
S9xReschedule();
|
||||
|
||||
if (PPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
|
||||
|
@ -408,19 +386,16 @@ void S9xDoHEventProcessing (void)
|
|||
break;
|
||||
|
||||
case HC_HCOUNTER_MAX_EVENT:
|
||||
#ifndef ZSNES_FX
|
||||
if (Settings.SuperFX)
|
||||
{
|
||||
if (!SuperFX.oneLineDone)
|
||||
S9xSuperFXExec();
|
||||
SuperFX.oneLineDone = FALSE;
|
||||
}
|
||||
#else
|
||||
S9xSuperFXExec();
|
||||
#endif
|
||||
|
||||
S9xAPUEndScanline();
|
||||
CPU.Cycles -= Timings.H_Max;
|
||||
CPU.PrevCycles -= Timings.H_Max;
|
||||
S9xAPUSetReferenceTime(CPU.Cycles);
|
||||
|
||||
if ((Timings.NMITriggerPos != 0xffff) && (Timings.NMITriggerPos >= Timings.H_Max))
|
||||
|
@ -449,7 +424,7 @@ void S9xDoHEventProcessing (void)
|
|||
|
||||
// FIXME: reading $4210 will wait 2 cycles, then perform reading, then wait 4 more cycles.
|
||||
Memory.FillRAM[0x4210] = Model->_5A22;
|
||||
CPU.Flags &= ~NMI_FLAG;
|
||||
CPU.NMILine = FALSE;
|
||||
Timings.NMITriggerPos = 0xffff;
|
||||
|
||||
ICPU.Frame++;
|
||||
|
@ -481,8 +456,6 @@ void S9xDoHEventProcessing (void)
|
|||
else
|
||||
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v1;
|
||||
|
||||
S9xCheckMissingHTimerPosition(0);
|
||||
|
||||
if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE) // VBlank starts from V=225(240).
|
||||
{
|
||||
S9xEndScreenRefresh();
|
||||
|
@ -517,7 +490,7 @@ void S9xDoHEventProcessing (void)
|
|||
{
|
||||
// FIXME: triggered at HC=6, checked just before the final CPU cycle,
|
||||
// then, when to call S9xOpcode_NMI()?
|
||||
CPU.Flags |= NMI_FLAG;
|
||||
CPU.NMILine = TRUE;
|
||||
Timings.NMITriggerPos = 6 + 6;
|
||||
}
|
||||
|
||||
|
@ -532,13 +505,11 @@ void S9xDoHEventProcessing (void)
|
|||
if (CPU.V_Counter == FIRST_VISIBLE_LINE) // V=1
|
||||
S9xStartScreenRefresh();
|
||||
|
||||
CPU.NextEvent = -1;
|
||||
S9xReschedule();
|
||||
|
||||
break;
|
||||
|
||||
case HC_HDMA_INIT_EVENT:
|
||||
S9xCheckMissingHTimerPosition(Timings.HDMAInit);
|
||||
S9xReschedule();
|
||||
|
||||
if (CPU.V_Counter == 0)
|
||||
|
@ -555,7 +526,6 @@ void S9xDoHEventProcessing (void)
|
|||
if (CPU.V_Counter >= FIRST_VISIBLE_LINE && CPU.V_Counter <= PPU.ScreenHeight)
|
||||
RenderLine((uint8) (CPU.V_Counter - FIRST_VISIBLE_LINE));
|
||||
|
||||
S9xCheckMissingHTimerPosition(Timings.RenderPos);
|
||||
S9xReschedule();
|
||||
|
||||
break;
|
||||
|
@ -565,27 +535,12 @@ void S9xDoHEventProcessing (void)
|
|||
S9xTraceFormattedMessage("*** WRAM Refresh HC:%04d", CPU.Cycles);
|
||||
#endif
|
||||
|
||||
S9xCheckMissingHTimerHalt(Timings.WRAMRefreshPos, SNES_WRAM_REFRESH_CYCLES);
|
||||
CPU.PrevCycles = CPU.Cycles;
|
||||
CPU.Cycles += SNES_WRAM_REFRESH_CYCLES;
|
||||
|
||||
S9xCheckMissingHTimerPosition(Timings.WRAMRefreshPos);
|
||||
S9xReschedule();
|
||||
|
||||
break;
|
||||
|
||||
case HC_IRQ_1_3_EVENT:
|
||||
case HC_IRQ_3_5_EVENT:
|
||||
case HC_IRQ_5_7_EVENT:
|
||||
case HC_IRQ_7_9_EVENT:
|
||||
case HC_IRQ_9_A_EVENT:
|
||||
case HC_IRQ_A_1_EVENT:
|
||||
if (PPU.HTimerEnabled && (!PPU.VTimerEnabled || (CPU.V_Counter == PPU.VTimerPosition)))
|
||||
S9xSetIRQ(PPU_IRQ_SOURCE);
|
||||
else
|
||||
if (PPU.VTimerEnabled && (CPU.V_Counter == PPU.VTimerPosition))
|
||||
S9xSetIRQ(PPU_IRQ_SOURCE);
|
||||
S9xCheckInterrupts();
|
||||
|
||||
S9xReschedule();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
101
cpuexec.h
101
cpuexec.h
|
@ -179,6 +179,9 @@
|
|||
#define _CPUEXEC_H_
|
||||
|
||||
#include "ppu.h"
|
||||
#ifdef DEBUGGER
|
||||
#include "debug.h"
|
||||
#endif
|
||||
|
||||
struct SOpcodes
|
||||
{
|
||||
|
@ -193,7 +196,6 @@ struct SICPU
|
|||
uint8 _Zero;
|
||||
uint8 _Negative;
|
||||
uint8 _Overflow;
|
||||
bool8 CPUExecuting;
|
||||
uint32 ShiftedPB;
|
||||
uint32 ShiftedDB;
|
||||
uint32 Frame;
|
||||
|
@ -217,8 +219,6 @@ void S9xMainLoop (void);
|
|||
void S9xReset (void);
|
||||
void S9xSoftReset (void);
|
||||
void S9xDoHEventProcessing (void);
|
||||
void S9xClearIRQ (uint32);
|
||||
void S9xSetIRQ (uint32);
|
||||
|
||||
static inline void S9xUnpackStatus (void)
|
||||
{
|
||||
|
@ -270,84 +270,43 @@ static inline void S9xFixCycles (void)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void S9xReschedule (void)
|
||||
static inline void S9xCheckInterrupts (void)
|
||||
{
|
||||
uint8 next = 0;
|
||||
int32 hpos = 0;
|
||||
bool8 thisIRQ = PPU.HTimerEnabled || PPU.VTimerEnabled;
|
||||
|
||||
switch (CPU.WhichEvent)
|
||||
if (CPU.IRQLine && thisIRQ)
|
||||
CPU.IRQTransition = TRUE;
|
||||
|
||||
if (PPU.HTimerEnabled)
|
||||
{
|
||||
case HC_HBLANK_START_EVENT:
|
||||
case HC_IRQ_1_3_EVENT:
|
||||
next = HC_HDMA_START_EVENT;
|
||||
hpos = Timings.HDMAStart;
|
||||
break;
|
||||
int32 htimepos = PPU.HTimerPosition;
|
||||
if (CPU.Cycles >= Timings.H_Max)
|
||||
htimepos += Timings.H_Max;
|
||||
|
||||
case HC_HDMA_START_EVENT:
|
||||
case HC_IRQ_3_5_EVENT:
|
||||
next = HC_HCOUNTER_MAX_EVENT;
|
||||
hpos = Timings.H_Max;
|
||||
break;
|
||||
|
||||
case HC_HCOUNTER_MAX_EVENT:
|
||||
case HC_IRQ_5_7_EVENT:
|
||||
next = HC_HDMA_INIT_EVENT;
|
||||
hpos = Timings.HDMAInit;
|
||||
break;
|
||||
|
||||
case HC_HDMA_INIT_EVENT:
|
||||
case HC_IRQ_7_9_EVENT:
|
||||
next = HC_RENDER_EVENT;
|
||||
hpos = Timings.RenderPos;
|
||||
break;
|
||||
|
||||
case HC_RENDER_EVENT:
|
||||
case HC_IRQ_9_A_EVENT:
|
||||
next = HC_WRAM_REFRESH_EVENT;
|
||||
hpos = Timings.WRAMRefreshPos;
|
||||
break;
|
||||
|
||||
case HC_WRAM_REFRESH_EVENT:
|
||||
case HC_IRQ_A_1_EVENT:
|
||||
next = HC_HBLANK_START_EVENT;
|
||||
hpos = Timings.HBlankStart;
|
||||
break;
|
||||
if (CPU.PrevCycles >= htimepos || CPU.Cycles < htimepos)
|
||||
thisIRQ = FALSE;
|
||||
}
|
||||
|
||||
if (((int32) PPU.HTimerPosition > CPU.NextEvent) && ((int32) PPU.HTimerPosition < hpos))
|
||||
if (PPU.VTimerEnabled)
|
||||
{
|
||||
hpos = (int32) PPU.HTimerPosition;
|
||||
int32 vcounter = CPU.V_Counter;
|
||||
if (CPU.Cycles >= Timings.H_Max)
|
||||
vcounter++;
|
||||
|
||||
switch (next)
|
||||
{
|
||||
case HC_HDMA_START_EVENT:
|
||||
next = HC_IRQ_1_3_EVENT;
|
||||
break;
|
||||
|
||||
case HC_HCOUNTER_MAX_EVENT:
|
||||
next = HC_IRQ_3_5_EVENT;
|
||||
break;
|
||||
|
||||
case HC_HDMA_INIT_EVENT:
|
||||
next = HC_IRQ_5_7_EVENT;
|
||||
break;
|
||||
|
||||
case HC_RENDER_EVENT:
|
||||
next = HC_IRQ_7_9_EVENT;
|
||||
break;
|
||||
|
||||
case HC_WRAM_REFRESH_EVENT:
|
||||
next = HC_IRQ_9_A_EVENT;
|
||||
break;
|
||||
|
||||
case HC_HBLANK_START_EVENT:
|
||||
next = HC_IRQ_A_1_EVENT;
|
||||
break;
|
||||
}
|
||||
if (vcounter != PPU.VTimerPosition)
|
||||
thisIRQ = FALSE;
|
||||
}
|
||||
|
||||
CPU.NextEvent = hpos;
|
||||
CPU.WhichEvent = next;
|
||||
if (!CPU.IRQLastState && thisIRQ)
|
||||
{
|
||||
#ifdef DEBUGGER
|
||||
S9xTraceFormattedMessage("--- /IRQ High->Low prev HC:%04d curr HC:%04d HTimer:%d Pos:%04d VTimer:%d Pos:%03d",
|
||||
CPU.PrevCycles, CPU.Cycles, PPU.HTimerEnabled, PPU.HTimerPosition, PPU.VTimerEnabled, PPU.VTimerPosition);
|
||||
#endif
|
||||
CPU.IRQLine = TRUE;
|
||||
}
|
||||
|
||||
CPU.IRQLastState = thisIRQ;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
13
cpumacro.h
13
cpumacro.h
|
@ -280,7 +280,6 @@ static void Op##OP (void) \
|
|||
S9xSetPCBase(ICPU.ShiftedPB + newPC.W); \
|
||||
else \
|
||||
Registers.PCw = newPC.W; \
|
||||
CPUShutdown(); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -515,9 +514,6 @@ static inline void CPY (uint8 val)
|
|||
|
||||
static inline void DEC16 (uint32 OpAddress, s9xwrap_t w)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
uint16 Work16 = S9xGetWord(OpAddress, w) - 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetWord(Work16, OpAddress, w, WRITE_10);
|
||||
|
@ -527,9 +523,6 @@ static inline void DEC16 (uint32 OpAddress, s9xwrap_t w)
|
|||
|
||||
static inline void DEC8 (uint32 OpAddress)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
uint8 Work8 = S9xGetByte(OpAddress) - 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetByte(Work8, OpAddress);
|
||||
|
@ -551,9 +544,6 @@ static inline void EOR (uint8 val)
|
|||
|
||||
static inline void INC16 (uint32 OpAddress, s9xwrap_t w)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
uint16 Work16 = S9xGetWord(OpAddress, w) + 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetWord(Work16, OpAddress, w, WRITE_10);
|
||||
|
@ -563,9 +553,6 @@ static inline void INC16 (uint32 OpAddress, s9xwrap_t w)
|
|||
|
||||
static inline void INC8 (uint32 OpAddress)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
uint8 Work8 = S9xGetByte(OpAddress) + 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetByte(Work8, OpAddress);
|
||||
|
|
169
cpuops.cpp
169
cpuops.cpp
|
@ -188,13 +188,9 @@
|
|||
#endif
|
||||
|
||||
#ifdef SA1_OPCODES
|
||||
#define AddCycles(n) { }
|
||||
#define AddCycles(n) { SA1.Cycles += (n); }
|
||||
#else
|
||||
#if (S9X_ACCURACY_LEVEL >= 3)
|
||||
#define AddCycles(n) { CPU.Cycles += (n); while (CPU.Cycles >= CPU.NextEvent) S9xDoHEventProcessing(); }
|
||||
#else
|
||||
#define AddCycles(n) { CPU.Cycles += (n); }
|
||||
#endif
|
||||
#define AddCycles(n) { CPU.PrevCycles = CPU.Cycles; CPU.Cycles += (n); S9xCheckInterrupts(); while (CPU.Cycles >= CPU.NextEvent) S9xDoHEventProcessing(); }
|
||||
#endif
|
||||
|
||||
#include "cpuaddr.h"
|
||||
|
@ -659,9 +655,6 @@ rOPX (CCSlow, AbsoluteSlow, WRAP_NONE, CPY)
|
|||
static void Op3AM1 (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
Registers.AL--;
|
||||
SetZN(Registers.AL);
|
||||
}
|
||||
|
@ -669,9 +662,6 @@ static void Op3AM1 (void)
|
|||
static void Op3AM0 (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
Registers.A.W--;
|
||||
SetZN(Registers.A.W);
|
||||
}
|
||||
|
@ -679,9 +669,6 @@ static void Op3AM0 (void)
|
|||
static void Op3ASlow (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
|
||||
if (CheckMemory())
|
||||
{
|
||||
|
@ -813,9 +800,6 @@ rOPM (53Slow, StackRelativeIndirectIndexedSlow, WRAP_NONE, EOR)
|
|||
static void Op1AM1 (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
Registers.AL++;
|
||||
SetZN(Registers.AL);
|
||||
}
|
||||
|
@ -823,9 +807,6 @@ static void Op1AM1 (void)
|
|||
static void Op1AM0 (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
Registers.A.W++;
|
||||
SetZN(Registers.A.W);
|
||||
}
|
||||
|
@ -833,9 +814,6 @@ static void Op1AM0 (void)
|
|||
static void Op1ASlow (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
|
||||
if (CheckMemory())
|
||||
{
|
||||
|
@ -1550,54 +1528,6 @@ mOPM (0CSlow, AbsoluteSlow, WRAP_BANK, TSB)
|
|||
|
||||
/* Branch Instructions ***************************************************** */
|
||||
|
||||
#ifdef CPU_SHUTDOWN
|
||||
|
||||
#ifndef SA1_OPCODES
|
||||
|
||||
inline void CPUShutdown (void)
|
||||
{
|
||||
if (Settings.Shutdown && Registers.PBPC == CPU.WaitAddress)
|
||||
{
|
||||
// Don't skip cycles with a pending NMI or IRQ - could cause delayed interrupt.
|
||||
if (CPU.WaitCounter == 0 && !(CPU.Flags & (IRQ_FLAG | NMI_FLAG)))
|
||||
{
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
if (Settings.SA1)
|
||||
S9xSA1ExecuteDuringSleep();
|
||||
CPU.Cycles = CPU.NextEvent;
|
||||
ICPU.CPUExecuting = FALSE;
|
||||
S9xAPUExecute();
|
||||
ICPU.CPUExecuting = TRUE;
|
||||
}
|
||||
else
|
||||
if (CPU.WaitCounter >= 2)
|
||||
CPU.WaitCounter = 1;
|
||||
else
|
||||
CPU.WaitCounter--;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline void CPUShutdown (void)
|
||||
{
|
||||
if (Settings.Shutdown && Registers.PBPC == CPU.WaitAddress)
|
||||
{
|
||||
if (CPU.WaitCounter >= 1)
|
||||
SA1.Executing = FALSE;
|
||||
else
|
||||
CPU.WaitCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define CPUShutdown()
|
||||
|
||||
#endif
|
||||
|
||||
// BCC
|
||||
bOP(90E0, Relative, !CheckCarry(), 0, 0)
|
||||
bOP(90E1, Relative, !CheckCarry(), 0, 1)
|
||||
|
@ -1692,7 +1622,7 @@ static void Op58 (void)
|
|||
{
|
||||
ClearIRQ();
|
||||
AddCycles(ONE_CYCLE);
|
||||
//CHECK_FOR_IRQ();
|
||||
CHECK_FOR_IRQ();
|
||||
}
|
||||
|
||||
// SEI
|
||||
|
@ -1714,9 +1644,6 @@ static void OpB8 (void)
|
|||
static void OpCAX1 (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
Registers.XL--;
|
||||
SetZN(Registers.XL);
|
||||
}
|
||||
|
@ -1724,9 +1651,6 @@ static void OpCAX1 (void)
|
|||
static void OpCAX0 (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
Registers.X.W--;
|
||||
SetZN(Registers.X.W);
|
||||
}
|
||||
|
@ -1734,9 +1658,6 @@ static void OpCAX0 (void)
|
|||
static void OpCASlow (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
|
||||
if (CheckIndex())
|
||||
{
|
||||
|
@ -1753,9 +1674,6 @@ static void OpCASlow (void)
|
|||
static void Op88X1 (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
Registers.YL--;
|
||||
SetZN(Registers.YL);
|
||||
}
|
||||
|
@ -1763,9 +1681,6 @@ static void Op88X1 (void)
|
|||
static void Op88X0 (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
Registers.Y.W--;
|
||||
SetZN(Registers.Y.W);
|
||||
}
|
||||
|
@ -1773,9 +1688,6 @@ static void Op88X0 (void)
|
|||
static void Op88Slow (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
|
||||
if (CheckIndex())
|
||||
{
|
||||
|
@ -1794,9 +1706,6 @@ static void Op88Slow (void)
|
|||
static void OpE8X1 (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
Registers.XL++;
|
||||
SetZN(Registers.XL);
|
||||
}
|
||||
|
@ -1804,9 +1713,6 @@ static void OpE8X1 (void)
|
|||
static void OpE8X0 (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
Registers.X.W++;
|
||||
SetZN(Registers.X.W);
|
||||
}
|
||||
|
@ -1814,9 +1720,6 @@ static void OpE8X0 (void)
|
|||
static void OpE8Slow (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
|
||||
if (CheckIndex())
|
||||
{
|
||||
|
@ -1833,9 +1736,6 @@ static void OpE8Slow (void)
|
|||
static void OpC8X1 (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
Registers.YL++;
|
||||
SetZN(Registers.YL);
|
||||
}
|
||||
|
@ -1843,9 +1743,6 @@ static void OpC8X1 (void)
|
|||
static void OpC8X0 (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
Registers.Y.W++;
|
||||
SetZN(Registers.Y.W);
|
||||
}
|
||||
|
@ -1853,9 +1750,6 @@ static void OpC8X0 (void)
|
|||
static void OpC8Slow (void)
|
||||
{
|
||||
AddCycles(ONE_CYCLE);
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
|
||||
if (CheckIndex())
|
||||
{
|
||||
|
@ -2371,7 +2265,7 @@ static void Op28E1 (void)
|
|||
SetFlags(MemoryFlag | IndexFlag);
|
||||
S9xUnpackStatus();
|
||||
S9xFixCycles();
|
||||
//CHECK_FOR_IRQ();
|
||||
CHECK_FOR_IRQ();
|
||||
}
|
||||
|
||||
static void Op28E0 (void)
|
||||
|
@ -2388,7 +2282,7 @@ static void Op28E0 (void)
|
|||
}
|
||||
|
||||
S9xFixCycles();
|
||||
//CHECK_FOR_IRQ();
|
||||
CHECK_FOR_IRQ();
|
||||
}
|
||||
|
||||
static void Op28Slow (void)
|
||||
|
@ -2416,7 +2310,7 @@ static void Op28Slow (void)
|
|||
}
|
||||
|
||||
S9xFixCycles();
|
||||
//CHECK_FOR_IRQ();
|
||||
CHECK_FOR_IRQ();
|
||||
}
|
||||
|
||||
// PLX
|
||||
|
@ -3069,17 +2963,11 @@ static void Op5CSlow (void)
|
|||
static void Op4C (void)
|
||||
{
|
||||
S9xSetPCBase(ICPU.ShiftedPB + ((uint16) Absolute(JUMP)));
|
||||
#if defined(CPU_SHUTDOWN) && defined(SA1_OPCODES)
|
||||
CPUShutdown();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void Op4CSlow (void)
|
||||
{
|
||||
S9xSetPCBase(ICPU.ShiftedPB + ((uint16) AbsoluteSlow(JUMP)));
|
||||
#if defined(CPU_SHUTDOWN) && defined(SA1_OPCODES)
|
||||
CPUShutdown();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void Op6C (void)
|
||||
|
@ -3425,7 +3313,7 @@ static void OpC2 (void)
|
|||
}
|
||||
|
||||
S9xFixCycles();
|
||||
//CHECK_FOR_IRQ();
|
||||
CHECK_FOR_IRQ();
|
||||
}
|
||||
|
||||
static void OpC2Slow (void)
|
||||
|
@ -3454,7 +3342,7 @@ static void OpC2Slow (void)
|
|||
}
|
||||
|
||||
S9xFixCycles();
|
||||
//CHECK_FOR_IRQ();
|
||||
CHECK_FOR_IRQ();
|
||||
}
|
||||
|
||||
static void OpE2 (void)
|
||||
|
@ -3562,7 +3450,7 @@ static void Op40Slow (void)
|
|||
}
|
||||
|
||||
S9xFixCycles();
|
||||
//CHECK_FOR_IRQ();
|
||||
CHECK_FOR_IRQ();
|
||||
}
|
||||
|
||||
/* STP/WAI ***************************************************************** */
|
||||
|
@ -3570,44 +3458,15 @@ static void Op40Slow (void)
|
|||
// WAI
|
||||
static void OpCB (void)
|
||||
{
|
||||
// Ok, let's just C-ify the ASM versions separately.
|
||||
#ifdef SA1_OPCODES
|
||||
SA1.WaitingForInterrupt = TRUE;
|
||||
Registers.PCw--;
|
||||
#if 0
|
||||
// XXX: FIXME
|
||||
if (Settings.Shutdown)
|
||||
{
|
||||
SA1.Cycles = SA1.NextEvent;
|
||||
SA1.Executing = FALSE;
|
||||
//S9xAPUExecute(); // FIXME
|
||||
SA1.Executing = TRUE;
|
||||
}
|
||||
AddCycles(TWO_CYCLES);
|
||||
#else
|
||||
CPU.WaitingForInterrupt = TRUE;
|
||||
Registers.PCw--;
|
||||
AddCycles(TWO_CYCLES);
|
||||
#endif
|
||||
#else // SA1_OPCODES
|
||||
#if 0
|
||||
if (CPU.IRQActive)
|
||||
AddCycles(TWO_CYCLES);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
CPU.WaitingForInterrupt = TRUE;
|
||||
Registers.PCw--;
|
||||
#ifdef CPU_SHUTDOWN
|
||||
if (Settings.Shutdown)
|
||||
{
|
||||
CPU.Cycles = CPU.NextEvent;
|
||||
ICPU.CPUExecuting = FALSE;
|
||||
S9xAPUExecute();
|
||||
ICPU.CPUExecuting = TRUE;
|
||||
}
|
||||
else
|
||||
AddCycles(TWO_CYCLES);
|
||||
#else
|
||||
AddCycles(TWO_CYCLES);
|
||||
#endif
|
||||
}
|
||||
#endif // SA1_OPCODES
|
||||
}
|
||||
|
||||
// STP
|
||||
|
|
9
cpuops.h
9
cpuops.h
|
@ -181,8 +181,9 @@
|
|||
void S9xOpcode_NMI (void);
|
||||
void S9xOpcode_IRQ (void);
|
||||
|
||||
#define CHECK_FOR_IRQ() \
|
||||
if (CPU.IRQActive && !CheckFlag(IRQ) && !Settings.DisableIRQ) \
|
||||
S9xOpcode_IRQ()
|
||||
|
||||
#ifndef SA1_OPCODES
|
||||
#define CHECK_FOR_IRQ() {} // if (CPU.IRQLine) S9xOpcode_IRQ(); }
|
||||
#else
|
||||
#define CHECK_FOR_IRQ() {}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -872,7 +872,7 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||
break;
|
||||
}
|
||||
|
||||
sprintf(Line, "%-44s A:%04X X:%04X Y:%04X D:%04X DB:%02X S:%04X P:%c%c%c%c%c%c%c%c%c HC:%04ld VC:%03ld FC:%02d %02x",
|
||||
sprintf(Line, "%-44s A:%04X X:%04X Y:%04X D:%04X DB:%02X S:%04X P:%c%c%c%c%c%c%c%c%c HC:%04ld VC:%03ld FC:%02d %03x",
|
||||
Line, Registers.A.W, Registers.X.W, Registers.Y.W,
|
||||
Registers.D.W, Registers.DB, Registers.S.W,
|
||||
CheckEmulation() ? 'E' : 'e',
|
||||
|
@ -887,7 +887,7 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||
(long) CPU.Cycles,
|
||||
(long) CPU.V_Counter,
|
||||
IPPU.FrameCount,
|
||||
CPU.IRQActive);
|
||||
(CPU.IRQExternal ? 0x100 : 0) | (PPU.HTimerEnabled ? 0x10 : 0) | (PPU.VTimerEnabled ? 0x01 : 0));
|
||||
|
||||
return (Size);
|
||||
}
|
||||
|
|
18
dma.cpp
18
dma.cpp
|
@ -185,7 +185,7 @@
|
|||
#include "missing.h"
|
||||
#endif
|
||||
|
||||
#define ADD_CYCLES(n) CPU.Cycles += (n)
|
||||
#define ADD_CYCLES(n) { CPU.PrevCycles = CPU.Cycles; CPU.Cycles += (n); S9xCheckInterrupts(); }
|
||||
|
||||
extern uint8 *HDMAMemPointers[8];
|
||||
extern int HDMA_ModeByteCounts[8];
|
||||
|
@ -741,9 +741,6 @@ bool8 S9xDoDMA (uint8 Channel)
|
|||
break;
|
||||
|
||||
case 0x18: // VMDATAL
|
||||
#ifndef CORRECT_VRAM_READS
|
||||
IPPU.FirstVRAMRead = TRUE;
|
||||
#endif
|
||||
if (!PPU.VMA.FullGraphicCount)
|
||||
{
|
||||
do
|
||||
|
@ -766,9 +763,6 @@ bool8 S9xDoDMA (uint8 Channel)
|
|||
break;
|
||||
|
||||
case 0x19: // VMDATAH
|
||||
#ifndef CORRECT_VRAM_READS
|
||||
IPPU.FirstVRAMRead = TRUE;
|
||||
#endif
|
||||
if (!PPU.VMA.FullGraphicCount)
|
||||
{
|
||||
do
|
||||
|
@ -837,9 +831,6 @@ bool8 S9xDoDMA (uint8 Channel)
|
|||
if (d->BAddress == 0x18)
|
||||
{
|
||||
// VMDATAL
|
||||
#ifndef CORRECT_VRAM_READS
|
||||
IPPU.FirstVRAMRead = TRUE;
|
||||
#endif
|
||||
if (!PPU.VMA.FullGraphicCount)
|
||||
{
|
||||
switch (b)
|
||||
|
@ -1282,7 +1273,7 @@ bool8 S9xDoDMA (uint8 Channel)
|
|||
}
|
||||
}
|
||||
|
||||
if ((CPU.Flags & NMI_FLAG) && (Timings.NMITriggerPos != 0xffff))
|
||||
if (CPU.NMILine && (Timings.NMITriggerPos != 0xffff))
|
||||
{
|
||||
Timings.NMITriggerPos = CPU.Cycles + Timings.NMIDMADelay;
|
||||
if (Timings.NMITriggerPos >= Timings.H_Max)
|
||||
|
@ -1373,10 +1364,7 @@ static inline bool8 HDMAReadLineCount (int d)
|
|||
|
||||
void S9xStartHDMA (void)
|
||||
{
|
||||
if (Settings.DisableHDMA)
|
||||
PPU.HDMA = 0;
|
||||
else
|
||||
PPU.HDMA = Memory.FillRAM[0x420c];
|
||||
PPU.HDMA = Memory.FillRAM[0x420c];
|
||||
|
||||
#ifdef DEBUGGER
|
||||
missing.hdma_this_frame = PPU.HDMA;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<body>
|
||||
<h1 style="text-align:center">How to Port Snes9x to a New Platform</h1>
|
||||
<div style="text-align:right">
|
||||
Version: 1.52<br>
|
||||
Version: 1.53<br>
|
||||
(c) Copyright 1998 Gary Henderson
|
||||
</div>
|
||||
<h2>Introduction</h2>
|
||||
|
@ -56,22 +56,10 @@
|
|||
<p>
|
||||
Define this if your compiler uses shift right arithmetic for signed values. For example, GCC and Visual C++ use shift right arithmetic.
|
||||
</p>
|
||||
<h3><code>CPU_SHUTDOWN</code></h3>
|
||||
<p>
|
||||
This is a speed-up hack. When defined and if <code>Settings.ShutdownMaster</code> is <code>true</code>, Snes9x starts watching for when CPU is in a simply loop waiting for a known event to happen - like the end of the current scanline. If Snes9x spots CPU in such a loop, it simply skips the emulation of its instructions until the event happens. It can be a big win with lots of SNES games, but will break a small number of games. In this case, set <code>Settings.ShutdownMaster</code> to <code>false</code> before you load a ROM image. Note that this hack is forcibly disabled in some games. See <code>Memory.ApplyROMFixes</code> function for the list of such games.
|
||||
</p>
|
||||
<h3><code>CORRECT_VRAM_READS</code></h3>
|
||||
<p>
|
||||
You must define this. It allows correct VRAM reads.
|
||||
</p>
|
||||
<h3><code>ZLIB / UNZIP_SUPPORT / JMA_SUPPORT</code></h3>
|
||||
<p>
|
||||
Define these if you want to support GZIP/ZIP/JMA compressed ROM images and GZIP compressed freeze-game files.
|
||||
</p>
|
||||
<h3><code>ZSNES_FX / ZSNES_C4</code></h3>
|
||||
<p>
|
||||
Define these if your CPU is x86 compatible and you're going to use the ZSNES Super FX and C4 assembler codes.
|
||||
</p>
|
||||
<h3><code>USE_OPENGL</code></h3>
|
||||
<p>
|
||||
Define this and set <code>Settings.OpenGLEnable</code> to <code>true</code>, then you'll get the rendered SNES image as one OpenGL texture.
|
||||
|
@ -81,9 +69,7 @@
|
|||
ZLIB<br>
|
||||
UNZIP_SUPPORT<br>
|
||||
JMA_SUPPORT<br>
|
||||
CPU_SHUTDOWN<br>
|
||||
RIGHTSHIFT_IS_SAR<br>
|
||||
CORRECT_VRAM_READS
|
||||
</code></p>
|
||||
<h2>Editing port.h</h2>
|
||||
<p>
|
||||
|
@ -379,7 +365,7 @@
|
|||
The sound generation rate on a SNES is directly proportional to the video output rate. Displays that synchronize with the vertical refresh but have a slightly lower refresh-rate than the emulated system can experience sound drop-outs. It may be beneficial to provide an option for users to configure <code>Settings.SoundInputRate</code> to suit their own systems. Setting <code>Settings.SoundInputRate</code> to a value that matches the actual output rate (i.e. 31977hz for 59.96hz) or lower will allow the users to eliminate crackling. A range of 31000hz to 33000hz should be inclusive enough for all displays. Use of this setting paired with the <code>S9xSyncSound</code> function can eliminate sound discontinuity.
|
||||
</p>
|
||||
<div style="text-align:right; margin-top:3em">
|
||||
Updated most recently by: 2009/12/20 zones
|
||||
Updated most recently by: 2011/1/16 zones
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -67,8 +67,6 @@ Justifier2Crosshair = 4 MagicPink/Black
|
|||
EnableGameSpecificHacks = TRUE
|
||||
AllowInvalidVRAMAccess = FALSE
|
||||
SpeedHacks = FALSE
|
||||
DisableIRQ = FALSE
|
||||
DisableHDMA = FALSE
|
||||
HDMATiming = 100
|
||||
|
||||
[Netplay]
|
||||
|
@ -231,7 +229,6 @@ K00:4 = ToggleBG3
|
|||
K00:5 = ToggleSprites
|
||||
K00:9 = ToggleTransparency
|
||||
K00:BackSpace = ClipWindows
|
||||
K00:0 = ToggleHDMA
|
||||
K00:A+Escape = Debugger
|
||||
M00:Pointer = Pointer Mouse1+Superscope+Justifier1
|
||||
M00:B0 = {Mouse1 L,Superscope Fire,Justifier1 Trigger}
|
||||
|
|
10
fxemu.cpp
10
fxemu.cpp
|
@ -202,6 +202,7 @@ void S9xResetSuperFX (void)
|
|||
SuperFX.speedPerLine = (uint32) (0.417 * 10.5e6 * ((1.0 / (float) Memory.ROMFramesPerSecond) / ((float) (Timings.V_Max))));
|
||||
SuperFX.oneLineDone = FALSE;
|
||||
SuperFX.vFlags = 0;
|
||||
CPU.IRQExternal = FALSE;
|
||||
FxReset(&SuperFX);
|
||||
}
|
||||
|
||||
|
@ -299,13 +300,10 @@ uint8 S9xGetSuperFX (uint16 address)
|
|||
uint8 byte;
|
||||
|
||||
byte = Memory.FillRAM[address];
|
||||
#ifdef CPU_SHUTDOWN
|
||||
if (address == 0x3030)
|
||||
CPU.WaitAddress = CPU.PBPCAtOpcodeStart;
|
||||
#endif
|
||||
|
||||
if (address == 0x3031)
|
||||
{
|
||||
S9xClearIRQ(GSU_IRQ_SOURCE);
|
||||
CPU.IRQExternal = FALSE;
|
||||
Memory.FillRAM[0x3031] = byte & 0x7f;
|
||||
}
|
||||
|
||||
|
@ -320,7 +318,7 @@ void S9xSuperFXExec (void)
|
|||
|
||||
uint16 GSUStatus = Memory.FillRAM[0x3000 + GSU_SFR] | (Memory.FillRAM[0x3000 + GSU_SFR + 1] << 8);
|
||||
if ((GSUStatus & (FLG_G | FLG_IRQ)) == FLG_IRQ)
|
||||
S9xSetIRQ(GSU_IRQ_SOURCE);
|
||||
CPU.IRQExternal = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
36
fxemu.h
36
fxemu.h
|
@ -178,7 +178,8 @@
|
|||
#ifndef _FXEMU_H_
|
||||
#define _FXEMU_H_
|
||||
|
||||
#ifndef ZSNES_FX
|
||||
#define FX_BREAKPOINT (-1)
|
||||
#define FX_ERROR_ILLEGAL_ADDRESS (-2)
|
||||
|
||||
// The FxInfo_s structure, the link between the FxEmulator and the Snes Emulator
|
||||
struct FxInfo_s
|
||||
|
@ -196,41 +197,12 @@ struct FxInfo_s
|
|||
extern struct FxInfo_s SuperFX;
|
||||
|
||||
void S9xInitSuperFX (void);
|
||||
void S9xResetSuperFX (void);
|
||||
void S9xSuperFXExec (void);
|
||||
void S9xSetSuperFX (uint8, uint16);
|
||||
uint8 S9xGetSuperFX (uint16);
|
||||
void fx_flushCache (void);
|
||||
void fx_computeScreenPointers (void);
|
||||
uint32 fx_run (uint32);
|
||||
|
||||
#define FX_BREAKPOINT (-1)
|
||||
#define FX_ERROR_ILLEGAL_ADDRESS (-2)
|
||||
|
||||
#else
|
||||
|
||||
#define S9xSetSuperFX S9xSuperFXWriteReg
|
||||
#define S9xGetSuperFX S9xSuperFXReadReg
|
||||
|
||||
START_EXTERN_C
|
||||
extern uint8 *SFXPlotTable;
|
||||
|
||||
void S9xSuperFXWriteReg (uint8, uint32);
|
||||
uint8 S9xSuperFXReadReg (uint32);
|
||||
void S9xSuperFXPreSaveState (void);
|
||||
void S9xSuperFXPostSaveState (void);
|
||||
void S9xSuperFXPostLoadState (void);
|
||||
END_EXTERN_C
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ZSNES_FX
|
||||
START_EXTERN_C
|
||||
#endif
|
||||
|
||||
void S9xResetSuperFX (void);
|
||||
void S9xSuperFXExec (void);
|
||||
|
||||
#ifdef ZSNES_FX
|
||||
END_EXTERN_C
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
4
fxinst.h
4
fxinst.h
|
@ -178,8 +178,6 @@
|
|||
#ifndef _FXINST_H_
|
||||
#define _FXINST_H_
|
||||
|
||||
#ifndef ZSNES_FX
|
||||
|
||||
/*
|
||||
* FxChip(GSU) register space specification
|
||||
* (Register address space 3000-32ff)
|
||||
|
@ -542,5 +540,3 @@ extern void (*fx_OpcodeTable[]) (void);
|
|||
#define BRANCH_DELAY_RELATIVE
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
66
getset.h
66
getset.h
|
@ -187,12 +187,12 @@
|
|||
#include "seta.h"
|
||||
#include "bsx.h"
|
||||
|
||||
#if (S9X_ACCURACY_LEVEL >= 2)
|
||||
|
||||
#define addCyclesInMemoryAccess \
|
||||
if (!CPU.InDMAorHDMA) \
|
||||
{ \
|
||||
CPU.PrevCycles = CPU.Cycles; \
|
||||
CPU.Cycles += speed; \
|
||||
S9xCheckInterrupts(); \
|
||||
while (CPU.Cycles >= CPU.NextEvent) \
|
||||
S9xDoHEventProcessing(); \
|
||||
}
|
||||
|
@ -200,23 +200,13 @@
|
|||
#define addCyclesInMemoryAccess_x2 \
|
||||
if (!CPU.InDMAorHDMA) \
|
||||
{ \
|
||||
CPU.PrevCycles = CPU.Cycles; \
|
||||
CPU.Cycles += speed << 1; \
|
||||
S9xCheckInterrupts(); \
|
||||
while (CPU.Cycles >= CPU.NextEvent) \
|
||||
S9xDoHEventProcessing(); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define addCyclesInMemoryAccess \
|
||||
if (!CPU.InDMAorHDMA) \
|
||||
CPU.Cycles += speed;
|
||||
|
||||
#define addCyclesInMemoryAccess_x2 \
|
||||
if (!CPU.InDMAorHDMA) \
|
||||
CPU.Cycles += speed << 1;
|
||||
|
||||
#endif
|
||||
|
||||
extern uint8 OpenBus;
|
||||
|
||||
static inline int32 memory_speed (uint32 address)
|
||||
|
@ -247,10 +237,6 @@ inline uint8 S9xGetByte (uint32 Address)
|
|||
|
||||
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
if (Memory.BlockIsRAM[block])
|
||||
CPU.WaitAddress = CPU.PBPCAtOpcodeStart;
|
||||
#endif
|
||||
byte = *(GetAddress + (Address & 0xffff));
|
||||
addCyclesInMemoryAccess;
|
||||
return (byte);
|
||||
|
@ -379,10 +365,6 @@ inline uint16 S9xGetWord (uint32 Address, enum s9xwrap_t w = WRAP_NONE)
|
|||
|
||||
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
if (Memory.BlockIsRAM[block])
|
||||
CPU.WaitAddress = CPU.PBPCAtOpcodeStart;
|
||||
#endif
|
||||
word = READ_WORD(GetAddress + (Address & 0xffff));
|
||||
addCyclesInMemoryAccess_x2;
|
||||
return (word);
|
||||
|
@ -510,33 +492,14 @@ inline uint16 S9xGetWord (uint32 Address, enum s9xwrap_t w = WRAP_NONE)
|
|||
|
||||
inline void S9xSetByte (uint8 Byte, uint32 Address)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
|
||||
int block = (Address & 0xffffff) >> MEMMAP_SHIFT;
|
||||
uint8 *SetAddress = Memory.WriteMap[block];
|
||||
int32 speed = memory_speed(Address);
|
||||
|
||||
if (SetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
SetAddress += (Address & 0xffff);
|
||||
*SetAddress = Byte;
|
||||
addCyclesInMemoryAccess;
|
||||
|
||||
if (Settings.SA1)
|
||||
{
|
||||
if (SetAddress == SA1.WaitByteAddress1 || SetAddress == SA1.WaitByteAddress2)
|
||||
{
|
||||
SA1.Executing = SA1.S9xOpcodes != NULL;
|
||||
SA1.WaitCounter = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
*(SetAddress + (Address & 0xffff)) = Byte;
|
||||
addCyclesInMemoryAccess;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -593,7 +556,6 @@ inline void S9xSetByte (uint8 Byte, uint32 Address)
|
|||
|
||||
case CMemory::MAP_SA1RAM:
|
||||
*(Memory.SRAM + (Address & 0xffff)) = Byte;
|
||||
SA1.Executing = !SA1.Waiting;
|
||||
addCyclesInMemoryAccess;
|
||||
return;
|
||||
|
||||
|
@ -670,33 +632,14 @@ inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NON
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
|
||||
int block = (Address & 0xffffff) >> MEMMAP_SHIFT;
|
||||
uint8 *SetAddress = Memory.WriteMap[block];
|
||||
int32 speed = memory_speed(Address);
|
||||
|
||||
if (SetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
SetAddress += (Address & 0xffff);
|
||||
WRITE_WORD(SetAddress, Word);
|
||||
addCyclesInMemoryAccess_x2;
|
||||
|
||||
if (Settings.SA1)
|
||||
{
|
||||
if (SetAddress == SA1.WaitByteAddress1 || SetAddress == SA1.WaitByteAddress2)
|
||||
{
|
||||
SA1.Executing = SA1.S9xOpcodes != NULL;
|
||||
SA1.WaitCounter = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
WRITE_WORD(SetAddress + (Address & 0xffff), Word);
|
||||
addCyclesInMemoryAccess_x2;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -806,7 +749,6 @@ inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NON
|
|||
|
||||
case CMemory::MAP_SA1RAM:
|
||||
WRITE_WORD(Memory.SRAM + (Address & 0xffff), Word);
|
||||
SA1.Executing = !SA1.Waiting;
|
||||
addCyclesInMemoryAccess_x2;
|
||||
return;
|
||||
|
||||
|
|
15
globals.cpp
15
globals.cpp
|
@ -209,6 +209,8 @@ struct SDSP3 DSP3;
|
|||
struct SDSP4 DSP4;
|
||||
struct SSA1 SA1;
|
||||
struct SSA1Registers SA1Registers;
|
||||
struct FxRegs_s GSU;
|
||||
struct FxInfo_s SuperFX;
|
||||
struct SST010 ST010;
|
||||
struct SST011 ST011;
|
||||
struct SST018 ST018;
|
||||
|
@ -228,10 +230,6 @@ struct Missing missing;
|
|||
#endif
|
||||
struct SCheatData Cheat;
|
||||
struct Watch watches[16];
|
||||
#ifndef ZSNES_FX
|
||||
struct FxRegs_s GSU;
|
||||
struct FxInfo_s SuperFX;
|
||||
#endif
|
||||
CMemory Memory;
|
||||
|
||||
char String[513];
|
||||
|
@ -244,15 +242,6 @@ SnesModel M1SNES = { 1, 3, 2 };
|
|||
SnesModel M2SNES = { 2, 4, 3 };
|
||||
SnesModel *Model = &M1SNES;
|
||||
|
||||
#if defined(ZSNES_FX) || defined(ZSNES_C4)
|
||||
uint8 *ROM = NULL;
|
||||
uint8 *SRAM = NULL;
|
||||
uint8 *RegRAM = NULL;
|
||||
#endif
|
||||
#ifdef ZSNES_FX
|
||||
uint8 *SFXPlotTable = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef GFX_MULTI_FORMAT
|
||||
uint32 RED_LOW_BIT_MASK = RED_LOW_BIT_MASK_RGB565;
|
||||
uint32 GREEN_LOW_BIT_MASK = GREEN_LOW_BIT_MASK_RGB565;
|
||||
|
|
2390
i386/c4.asm
2390
i386/c4.asm
File diff suppressed because it is too large
Load Diff
2692
i386/fxemu2.asm
2692
i386/fxemu2.asm
File diff suppressed because it is too large
Load Diff
834
i386/fxemu2.mac
834
i386/fxemu2.mac
|
@ -1,834 +0,0 @@
|
|||
;Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com )
|
||||
;
|
||||
;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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
%macro FETCHPIPE 0
|
||||
; mov edx,[SfxPBR]
|
||||
; mov edx,[SfxMemTable+edx*4]
|
||||
; mov edx,[SfxCPB]
|
||||
; mov edx,[SfxR15]
|
||||
mov cl,[ebp]
|
||||
%endmacro
|
||||
|
||||
%macro UpdateR14 0
|
||||
; mov edx,[SfxROMBR]
|
||||
; mov edx,[SfxMemTable+edx*4]
|
||||
mov eax,[SfxCROM]
|
||||
; and dword[SfxR14],0FFFFh
|
||||
add eax,[SfxR14]
|
||||
mov [SfxRomBuffer],eax
|
||||
%endmacro
|
||||
|
||||
%macro UpdateR15 0
|
||||
mov ebp,[SfxCPB]
|
||||
add ebp,[SfxR15]
|
||||
%endmacro
|
||||
|
||||
%macro CLRFLAGS 0
|
||||
;and dword [SfxSFR],0FFFFh-0100h-0200h-1000h ; Clear ALT1,ALT2 and B Flags
|
||||
; xor ch,ch
|
||||
; mov dword [SfxB],0 ; Clear B Flag
|
||||
; mov esi,SfxR0
|
||||
; mov edi,SfxR0
|
||||
%endmacro
|
||||
|
||||
%macro TORN 1 ; V
|
||||
FETCHPIPE
|
||||
mov edi, SfxR0+%1*4
|
||||
inc ebp ; Increase program counter
|
||||
call [FxTable+ecx*4]
|
||||
mov edi,SfxR0
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro WITH 1 ; Verified.
|
||||
FETCHPIPE
|
||||
mov esi,SfxR0+%1*4
|
||||
mov edi,SfxR0+%1*4
|
||||
mov dword [SfxB],1
|
||||
inc ebp ; Increase program counter
|
||||
call [FxTablec+ecx*4]
|
||||
mov esi,SfxR0
|
||||
mov edi,SfxR0
|
||||
mov dword [SfxB],0 ; Clear B Flag
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro STWRN 1 ; V
|
||||
mov eax,[SfxR0+%1*4] ; Read register
|
||||
mov ebx,[SfxRAMMem]
|
||||
mov dword [SfxLastRamAdr],eax ; Save last ram address
|
||||
add dword [SfxLastRamAdr],ebx ; Save last ram address
|
||||
mov edx,[esi] ; Read Source
|
||||
FETCHPIPE
|
||||
mov [ebx+eax],dl ; Store Word
|
||||
xor eax,1
|
||||
inc ebp ; Increase program counter
|
||||
mov [ebx+eax],dh ; Store Word
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro STBRN 1 ; V
|
||||
mov eax,[SfxR0+%1*4] ; Read register
|
||||
FETCHPIPE
|
||||
add eax,[SfxRAMMem]
|
||||
mov dword [SfxLastRamAdr],eax ; Save last ram address
|
||||
mov ebx,[esi] ; Read Source
|
||||
mov byte [eax],bl ; Store Byte
|
||||
CLRFLAGS
|
||||
inc ebp ; Increase program counter
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro LDWRN 1 ; V
|
||||
mov eax,[SfxR0+%1*4] ; Read register
|
||||
mov ebx,[SfxRAMMem]
|
||||
mov dword [SfxLastRamAdr],eax ; Save last ram address
|
||||
FETCHPIPE
|
||||
mov dl,[ebx+eax] ; Store Word
|
||||
add dword [SfxLastRamAdr],ebx ; Save last ram address
|
||||
xor eax,1
|
||||
and edx,0FFFFh
|
||||
inc ebp ; Increase program counter
|
||||
mov dh,[ebx+eax] ; Store Word
|
||||
mov [edi],edx ; Read Source
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro LDBRN 1 ; V
|
||||
mov eax,[SfxR0+%1*4] ; Read register
|
||||
FETCHPIPE
|
||||
add eax,[SfxRAMMem]
|
||||
xor ebx,ebx
|
||||
mov dword [SfxLastRamAdr],eax ; Save last ram address
|
||||
mov bl,[eax] ; Read Byte
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],ebx ; Store Result
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
; test byte[SfxPOR],01h
|
||||
; jnz .nozerocheck
|
||||
; test byte[SfxPOR],02h
|
||||
; jz .nodither
|
||||
|
||||
; **** Can pre-calculate [SfxSCBR] << 10 + [sfxramdata]
|
||||
; Pre-calculate fxbit values from color register
|
||||
|
||||
%macro drawpix4b 0
|
||||
and [eax],edx
|
||||
and [eax+16],edx
|
||||
xor edx,0FFFFFFFFh
|
||||
mov ebx,[fxbit01pcal]
|
||||
and ebx,edx
|
||||
or [eax], ebx
|
||||
and edx,[fxbit23pcal]
|
||||
or [eax+16], edx
|
||||
%endmacro
|
||||
|
||||
%macro drawpix4bd 0
|
||||
and [eax],edx
|
||||
and [eax+16],edx
|
||||
xor edx,0FFFFFFFFh
|
||||
mov ebx,[fxbit45pcal]
|
||||
and ebx,edx
|
||||
or [eax], ebx
|
||||
and edx,[fxbit67pcal]
|
||||
or [eax+16], edx
|
||||
%endmacro
|
||||
|
||||
%macro drawpix2b 0
|
||||
and [eax],edx
|
||||
xor edx,0FFFFFFFFh
|
||||
and edx,[fxbit01pcal]
|
||||
or [eax], edx
|
||||
%endmacro
|
||||
|
||||
%macro drawpix2bd 0
|
||||
and [eax],edx
|
||||
xor edx,0FFFFFFFFh
|
||||
and edx,[fxbit45pcal]
|
||||
or [eax], edx
|
||||
%endmacro
|
||||
|
||||
%macro drawpix8b 0
|
||||
and [eax],edx
|
||||
and [eax+16],edx
|
||||
and [eax+32],edx
|
||||
and [eax+48],edx
|
||||
xor edx,0FFFFFFFFh
|
||||
mov ebx,[fxbit01pcal]
|
||||
and ebx,edx
|
||||
or [eax], ebx
|
||||
mov ebx,[fxbit23pcal]
|
||||
and ebx,edx
|
||||
or [eax+16], ebx
|
||||
mov ebx,[fxbit45pcal]
|
||||
and ebx,edx
|
||||
or [eax+32], ebx
|
||||
and edx,[fxbit67pcal]
|
||||
or [eax+48], edx
|
||||
%endmacro
|
||||
|
||||
%macro drawpix8bd 0
|
||||
and [eax],edx
|
||||
and [eax+16],edx
|
||||
and [eax+32],edx
|
||||
and [eax+48],edx
|
||||
xor edx,0FFFFFFFFh
|
||||
mov ebx,[fxbit45pcal]
|
||||
and ebx,edx
|
||||
or [eax], ebx
|
||||
mov ebx,[fxbit67pcal]
|
||||
and ebx,edx
|
||||
or [eax+16], ebx
|
||||
mov ebx,[fxbit01pcal]
|
||||
and ebx,edx
|
||||
or [eax+32], ebx
|
||||
and edx,[fxbit23pcal]
|
||||
or [eax+48], edx
|
||||
%endmacro
|
||||
|
||||
%macro plotb 5
|
||||
shl eax,%3
|
||||
and ebx,07h
|
||||
add ebx,ebx
|
||||
add eax,ebx
|
||||
add eax,[SCBRrel]
|
||||
mov bl,[SfxR1]
|
||||
mov edx,[fxxand+ebx*4]
|
||||
%2
|
||||
%endmacro
|
||||
|
||||
%macro plotbz 5
|
||||
shl eax,%3
|
||||
and ebx,07h
|
||||
add ebx,ebx
|
||||
add eax,ebx
|
||||
add eax,[SCBRrel]
|
||||
mov bl,[SfxR1]
|
||||
mov edx,[fxxand+ebx*4]
|
||||
test byte[SfxCOLR],%5
|
||||
jz .nodraw
|
||||
%2
|
||||
%endmacro
|
||||
|
||||
%macro plotbd 5
|
||||
shl eax,%3
|
||||
and ebx,07h
|
||||
add ebx,ebx
|
||||
add eax,ebx
|
||||
add eax,[SCBRrel]
|
||||
mov bl,[SfxR1]
|
||||
mov edx,[fxxand+ebx*4]
|
||||
mov bl,[SfxR1]
|
||||
xor bl,[SfxR2]
|
||||
test bl,01h
|
||||
jz near .nodither4b
|
||||
%4
|
||||
inc word [SfxR1]
|
||||
%1
|
||||
.nodither4b
|
||||
%2
|
||||
%endmacro
|
||||
|
||||
%macro plotbzd 5
|
||||
shl eax,%3
|
||||
and ebx,07h
|
||||
add ebx,ebx
|
||||
add eax,ebx
|
||||
add eax,[SCBRrel]
|
||||
mov bl,[SfxR1]
|
||||
mov edx,[fxxand+ebx*4]
|
||||
test byte[SfxCOLR],%5
|
||||
jz near .nodraw
|
||||
mov bl,[SfxR1]
|
||||
xor bl,[SfxR2]
|
||||
test bl,01h
|
||||
jz .nodither4b
|
||||
%4
|
||||
inc word [SfxR1]
|
||||
%1
|
||||
.nodither4b
|
||||
%2
|
||||
%endmacro
|
||||
|
||||
%macro plotlines4b 1
|
||||
mov ebx,[SfxR2]
|
||||
FETCHPIPE
|
||||
mov bh,[SfxR1]
|
||||
mov eax,[sfxclineloc]
|
||||
inc ebp
|
||||
mov eax,[eax+ebx*4]
|
||||
cmp eax,0FFFFFFFFh
|
||||
je near .nodraw
|
||||
%1 ret, drawpix4b, 5, drawpix4bd, 0Fh
|
||||
.nodraw
|
||||
inc word [SfxR1]
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro plotlines4bb 1
|
||||
mov ebx,[SfxR2]
|
||||
FETCHPIPE
|
||||
mov bh,[SfxR1]
|
||||
mov eax,[sfxclineloc]
|
||||
inc ebp
|
||||
mov eax,[eax+ebx*4]
|
||||
cmp eax,0FFFFFFFFh
|
||||
je near .nodraw
|
||||
%1 FXReturn, drawpix4b, 5, drawpix4bd, 0Fh
|
||||
.nodraw
|
||||
inc word [SfxR1]
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro plotlines2b 1
|
||||
mov ebx,[SfxR2]
|
||||
FETCHPIPE
|
||||
mov bh,[SfxR1]
|
||||
mov eax,[sfxclineloc]
|
||||
inc ebp
|
||||
mov eax,[eax+ebx*4]
|
||||
cmp eax,0FFFFFFFFh
|
||||
je near .nodraw
|
||||
%1 ret, drawpix2b, 4, drawpix2bd, 03h
|
||||
.nodraw
|
||||
inc word [SfxR1]
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro plotlines2bb 1
|
||||
mov ebx,[SfxR2]
|
||||
FETCHPIPE
|
||||
mov bh,[SfxR1]
|
||||
mov eax,[sfxclineloc]
|
||||
inc ebp
|
||||
mov eax,[eax+ebx*4]
|
||||
cmp eax,0FFFFFFFFh
|
||||
je near .nodraw
|
||||
%1 FXReturn, drawpix2b, 4, drawpix2bd, 03h
|
||||
.nodraw
|
||||
inc word [SfxR1]
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro plotlines8b 1
|
||||
mov ebx,[SfxR2]
|
||||
FETCHPIPE
|
||||
mov bh,[SfxR1]
|
||||
mov eax,[sfxclineloc]
|
||||
inc ebp
|
||||
mov eax,[eax+ebx*4]
|
||||
cmp eax,0FFFFFFFFh
|
||||
je near .nodraw
|
||||
%1 ret, drawpix8b, 6, drawpix8bd, 0FFh
|
||||
.nodraw
|
||||
inc word [SfxR1]
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro plotlines8bb 1
|
||||
mov ebx,[SfxR2]
|
||||
FETCHPIPE
|
||||
mov bh,[SfxR1]
|
||||
mov eax,[sfxclineloc]
|
||||
inc ebp
|
||||
mov eax,[eax+ebx*4]
|
||||
cmp eax,0FFFFFFFFh
|
||||
je near .nodraw
|
||||
%1 FXReturn, drawpix8b, 6, drawpix8bd, 0FFh
|
||||
.nodraw
|
||||
inc word [SfxR1]
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro plotlines8bl 1
|
||||
mov ebx,[SfxR2]
|
||||
FETCHPIPE
|
||||
mov bh,[SfxR1]
|
||||
mov eax,[sfxclineloc]
|
||||
inc ebp
|
||||
mov eax,[eax+ebx*4]
|
||||
cmp eax,0FFFFFFFFh
|
||||
je near .nodraw
|
||||
%1 ret, drawpix8b, 6, drawpix8bd, 0Fh
|
||||
.nodraw
|
||||
inc word [SfxR1]
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro plotlines8bbl 1
|
||||
mov ebx,[SfxR2]
|
||||
FETCHPIPE
|
||||
mov bh,[SfxR1]
|
||||
mov eax,[sfxclineloc]
|
||||
inc ebp
|
||||
mov eax,[eax+ebx*4]
|
||||
cmp eax,0FFFFFFFFh
|
||||
je near .nodraw
|
||||
%1 FXReturn, drawpix8b, 6, drawpix8bd, 0Fh
|
||||
.nodraw
|
||||
inc word [SfxR1]
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro ADDRN 1 ; V
|
||||
mov eax, [esi] ; Read Source
|
||||
mov ebx, [SfxR0+%1*4]
|
||||
FETCHPIPE
|
||||
add ax,bx
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
mov [SfxSignZero],eax
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro ADCRN 1 ; V
|
||||
FETCHPIPE
|
||||
mov eax, [esi] ; Read Source
|
||||
mov ebx, [SfxR0+%1*4]
|
||||
shr byte[SfxCarry],1
|
||||
adc ax,bx
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
mov [SfxSignZero],eax
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro ADIRN 1 ; V
|
||||
mov eax, [esi] ; Read Source
|
||||
FETCHPIPE
|
||||
add ax,%1
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
mov [SfxSignZero],eax
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro ADCIRN 1 ; V
|
||||
FETCHPIPE
|
||||
mov eax, [esi] ; Read Source
|
||||
shr byte[SfxCarry],1
|
||||
adc ax,%1
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
mov [SfxSignZero],eax
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro SUBRN 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebx,[SfxR0+%1*4]
|
||||
FETCHPIPE
|
||||
sub ax,bx
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
xor byte[SfxCarry],1
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro SBCRN 1 ; V
|
||||
FETCHPIPE
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebx,[SfxR0+%1*4]
|
||||
cmp byte[SfxCarry],1
|
||||
sbb ax,bx
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
xor byte[SfxCarry],1
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro SUBIRN 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
FETCHPIPE
|
||||
sub ax,%1
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
xor byte[SfxCarry],1
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro CMPRN 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebx,[SfxR0+%1*4]
|
||||
FETCHPIPE
|
||||
sub ax,bx
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
xor byte[SfxCarry],1
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
inc ebp ; Increase program counter
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro ANDRN 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebx,[SfxR0+%1*4] ; Read RN
|
||||
FETCHPIPE
|
||||
and eax,ebx
|
||||
inc ebp
|
||||
mov dword [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro BICRN 1 ; V
|
||||
mov ebx,[SfxR0+%1*4] ; Read RN
|
||||
mov eax,[esi] ; Read Source
|
||||
xor ebx,0FFFFh
|
||||
FETCHPIPE
|
||||
and eax,ebx
|
||||
inc ebp
|
||||
mov dword [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro ANDIRN 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
FETCHPIPE
|
||||
and eax,%1
|
||||
inc ebp
|
||||
mov dword [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro BICIRN 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
FETCHPIPE
|
||||
and eax,%1
|
||||
inc ebp
|
||||
mov dword [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro MULTRN 1 ; V
|
||||
mov al,byte [esi] ; Read Source
|
||||
mov bl,byte [SfxR0+%1*4] ; Read RN
|
||||
FETCHPIPE
|
||||
imul bl
|
||||
inc ebp
|
||||
and eax,0FFFFh
|
||||
mov [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro UMULTRN 1 ; V
|
||||
mov al,byte [esi] ; Read Source
|
||||
mov bl,byte [SfxR0+%1*4] ; Read RN
|
||||
FETCHPIPE
|
||||
mul bl
|
||||
inc ebp
|
||||
and eax,0FFFFh
|
||||
mov [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro MULTIRN 1 ; V
|
||||
mov al,byte [esi] ; Read Source
|
||||
mov bl,%1 ; Read RN
|
||||
FETCHPIPE
|
||||
imul bl
|
||||
inc ebp
|
||||
and eax,0FFFFh
|
||||
mov [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro UMULTIRN 1 ; V
|
||||
mov al,byte [esi] ; Read Source
|
||||
mov bl,%1 ; Read RN
|
||||
FETCHPIPE
|
||||
mul bl
|
||||
inc ebp
|
||||
and eax,0FFFFh
|
||||
mov [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro LINK 1 ; Verified.
|
||||
mov eax,ebp
|
||||
sub eax,[SfxCPB]
|
||||
add eax,%1
|
||||
FETCHPIPE
|
||||
mov word [SfxR11],ax
|
||||
CLRFLAGS
|
||||
inc ebp
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro JMPRN 1 ; V
|
||||
FETCHPIPE
|
||||
mov eax,[SfxR0+%1*4] ; Read RN
|
||||
mov ebp,[SfxCPB]
|
||||
add ebp,eax
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro LJMPRN 1 ; V
|
||||
FETCHPIPE
|
||||
mov eax,[SfxR0+%1*4]
|
||||
and eax,07Fh
|
||||
mov byte[SfxPBR],al
|
||||
; mov byte[fxtrace+eax],1
|
||||
mov eax,[SfxMemTable+eax*4]
|
||||
mov [SfxCPB],eax
|
||||
mov ebp,eax
|
||||
add ebp,[esi] ; Read RN
|
||||
mov dword [SfxCacheActive],0
|
||||
push ecx
|
||||
call FxOp02
|
||||
pop ecx
|
||||
dec ebp
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro IBTRN 1 ; V
|
||||
movsx eax,byte[ebp]
|
||||
mov cl,[ebp+1]
|
||||
add ebp,2
|
||||
mov [SfxR0+%1*4],ax
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro LMSRN 1 ; Verified.
|
||||
xor eax,eax
|
||||
mov al,[ebp]
|
||||
add eax,eax
|
||||
inc ebp
|
||||
add eax,[SfxRAMMem]
|
||||
mov cl,[ebp]
|
||||
mov dword [SfxLastRamAdr],eax
|
||||
mov ebx,[eax] ; Read word from ram
|
||||
inc ebp
|
||||
mov [SfxR0+%1*4],bx ; Write data
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro SMSRN 1 ; Verified.
|
||||
xor eax,eax
|
||||
mov al,[ebp]
|
||||
inc ebp
|
||||
add eax,eax
|
||||
mov cl,[ebp]
|
||||
add eax,[SfxRAMMem]
|
||||
mov ebx,[SfxR0+%1*4] ; Read data
|
||||
mov dword [SfxLastRamAdr],eax
|
||||
inc ebp
|
||||
mov [eax],bx ; Write word to ram
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro FROMRN 1 ; V
|
||||
FETCHPIPE
|
||||
mov esi,SfxR0+%1*4
|
||||
inc ebp ; Increase program counter
|
||||
call [FxTable+ecx*4]
|
||||
mov esi,SfxR0
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro ORRN 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebx,[SfxR0+%1*4] ; Read
|
||||
FETCHPIPE
|
||||
or eax,ebx
|
||||
inc ebp
|
||||
mov [edi],eax ; Write DREG
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro XORRN 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebx,[SfxR0+%1*4] ; Read
|
||||
FETCHPIPE
|
||||
xor eax,ebx
|
||||
inc ebp
|
||||
mov [edi],eax ; Write DREG
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro ORI 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
FETCHPIPE
|
||||
or eax,%1
|
||||
inc ebp
|
||||
mov [edi],eax ; Write DREG
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro XORI 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
FETCHPIPE
|
||||
xor eax,%1
|
||||
inc ebp
|
||||
mov [edi],eax ; Write DREG
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro INCRN 1 ; Verified
|
||||
inc word[SfxR0+%1*4]
|
||||
FETCHPIPE
|
||||
mov eax,[SfxR0+%1*4] ; Read Source
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
inc ebp
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro DECRN 1 ; Verified
|
||||
dec word[SfxR0+%1*4]
|
||||
FETCHPIPE
|
||||
mov eax,[SfxR0+%1*4] ; Read Source
|
||||
mov [SfxR0+%1*4],eax
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
inc ebp
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro IWTRN 1 ; aka LEA ; Verified.
|
||||
mov eax,[ebp]
|
||||
mov cl,[ebp+2]
|
||||
and eax,0FFFFh
|
||||
add ebp,3
|
||||
mov [SfxR0+%1*4],eax
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro LMRN 1 ; Verified!
|
||||
xor eax,eax
|
||||
mov cl,[ebp+2]
|
||||
mov ax,[ebp]
|
||||
mov ebx,[SfxRAMMem]
|
||||
mov [SfxLastRamAdr],eax
|
||||
add [SfxLastRamAdr],ebx
|
||||
mov dl,[eax+ebx]
|
||||
xor eax,1
|
||||
add ebp,3
|
||||
mov dh,[eax+ebx]
|
||||
mov word [SfxR0+%1*4],dx ; Store Word
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro SMRN 1 ; Verified
|
||||
mov ebx,[SfxR0+%1*4]
|
||||
mov eax,[ebp]
|
||||
mov cl,[ebp+2]
|
||||
and eax,0FFFFh
|
||||
mov dx,bx
|
||||
mov ebx,[SfxRAMMem]
|
||||
mov [SfxLastRamAdr],eax
|
||||
add [SfxLastRamAdr],ebx
|
||||
mov [eax+ebx],dl
|
||||
xor eax,1
|
||||
add ebp,3
|
||||
mov [eax+ebx],dh
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro PackEsiEdi 0
|
||||
mov eax,[SfxSREG]
|
||||
shl eax,2
|
||||
add eax,SfxR0
|
||||
mov esi,eax
|
||||
mov eax,[SfxDREG]
|
||||
shl eax,2
|
||||
add eax,SfxR0
|
||||
mov edi,eax
|
||||
mov eax,[SfxRAMBR]
|
||||
shl eax,16
|
||||
add eax,[sfxramdata]
|
||||
mov dword [SfxRAMMem],eax
|
||||
%endmacro
|
||||
|
||||
%macro UnPackEsiEdi 0
|
||||
mov eax,esi
|
||||
sub eax,SfxR0
|
||||
shr eax,2
|
||||
mov [SfxSREG],eax
|
||||
mov eax,edi
|
||||
sub eax,SfxR0
|
||||
shr eax,2
|
||||
mov [SfxDREG],eax
|
||||
%endmacro
|
617
i386/fxemu2b.asm
617
i386/fxemu2b.asm
|
@ -1,617 +0,0 @@
|
|||
;Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com )
|
||||
;
|
||||
;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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
%include "macros.mac"
|
||||
|
||||
EXTSYM FxTable,FxTableb,FxTablec,SfxB,SfxCPB,SfxCROM,SfxCarry,SfxOverflow
|
||||
EXTSYM SfxR0,SfxR14,SfxR15,SfxRomBuffer,SfxSignZero,withr15sk
|
||||
|
||||
NEWSYM FxEmu2BAsmStart
|
||||
|
||||
%include "fxemu2.mac"
|
||||
%include "fxemu2b.mac"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
NEWSYM FxOpb05 ; BRA branch always ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
mov cl,[ebp+1]
|
||||
inc ebp
|
||||
add ebp,eax
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb06 ; BGE branch on greater or equals ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
mov ebx,[SfxSignZero]
|
||||
shr ebx,15
|
||||
inc ebp
|
||||
xor bl,[SfxOverflow]
|
||||
mov cl,[ebp]
|
||||
test bl,01h
|
||||
jnz .nojump
|
||||
add ebp,eax
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb07 ; BLT branch on lesss than ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
mov ebx,[SfxSignZero]
|
||||
shr ebx,15
|
||||
inc ebp
|
||||
xor bl,[SfxOverflow]
|
||||
mov cl,[ebp]
|
||||
test bl,01h
|
||||
jz .nojump
|
||||
add ebp,eax
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb08 ; BNE branch on not equal ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test dword[SfxSignZero],0FFFFh
|
||||
mov cl,[ebp]
|
||||
jz .nojump
|
||||
add ebp,eax
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb09 ; BEQ branch on equal (z=1) ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test dword[SfxSignZero],0FFFFh
|
||||
mov cl,[ebp]
|
||||
jnz .nojump
|
||||
add ebp,eax
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb0A ; BPL branch on plus ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test dword[SfxSignZero],088000h
|
||||
mov cl,[ebp]
|
||||
jnz .nojump
|
||||
add ebp,eax
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb0B ; BMI branch on minus ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test dword[SfxSignZero],088000h
|
||||
mov cl,[ebp]
|
||||
jz .nojump
|
||||
add ebp,eax
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb0C ; BCC branch on carry clear ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test byte[SfxCarry],01h
|
||||
mov cl,[ebp]
|
||||
jnz .nojump
|
||||
add ebp,eax
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb0D ; BCS branch on carry set ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test byte[SfxCarry],01h
|
||||
mov cl,[ebp]
|
||||
jz .nojump
|
||||
add ebp,eax
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb0E ; BVC branch on overflow clear ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test byte[SfxOverflow],01h
|
||||
mov cl,[ebp]
|
||||
jnz .nojump
|
||||
add ebp,eax
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb0F ; BVS branch on overflow set ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test byte[SfxOverflow],01h
|
||||
mov cl,[ebp]
|
||||
jz .nojump
|
||||
add ebp,eax
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTableb+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb10 ; TO RN set register n as destination register
|
||||
TORNb 0
|
||||
NEWSYM FxOpb11 ; TO RN set register n as destination register
|
||||
TORNb 1
|
||||
NEWSYM FxOpb12 ; TO RN set register n as destination register
|
||||
TORNb 2
|
||||
NEWSYM FxOpb13 ; TO RN set register n as destination register
|
||||
TORNb 3
|
||||
NEWSYM FxOpb14 ; TO RN set register n as destination register
|
||||
TORNb 4
|
||||
NEWSYM FxOpb15 ; TO RN set register n as destination register
|
||||
TORNb 5
|
||||
NEWSYM FxOpb16 ; TO RN set register n as destination register
|
||||
TORNb 6
|
||||
NEWSYM FxOpb17 ; TO RN set register n as destination register
|
||||
TORNb 7
|
||||
NEWSYM FxOpb18 ; TO RN set register n as destination register
|
||||
TORNb 8
|
||||
NEWSYM FxOpb19 ; TO RN set register n as destination register
|
||||
TORNb 9
|
||||
NEWSYM FxOpb1A ; TO RN set register n as destination register
|
||||
TORNb 10
|
||||
NEWSYM FxOpb1B ; TO RN set register n as destination register
|
||||
TORNb 11
|
||||
NEWSYM FxOpb1C ; TO RN set register n as destination register
|
||||
TORNb 12
|
||||
NEWSYM FxOpb1D ; TO RN set register n as destination register
|
||||
TORNb 13
|
||||
NEWSYM FxOpb1E ; TO RN set register n as destination register
|
||||
FETCHPIPE
|
||||
test dword [SfxB],1
|
||||
jnz .VersionB
|
||||
mov edi,SfxR0+14*4
|
||||
inc ebp
|
||||
mov eax,ebp
|
||||
sub eax,[SfxCPB]
|
||||
mov dword[withr15sk],1
|
||||
mov [SfxR15],eax
|
||||
call [FxTableb+ecx*4]
|
||||
mov edi,SfxR0
|
||||
UpdateR14
|
||||
ret
|
||||
.VersionB
|
||||
mov eax,[esi] ; Read Source
|
||||
mov dword[withr15sk],1
|
||||
mov [SfxR0+14*4],eax ; Write
|
||||
CLRFLAGS
|
||||
UpdateR14
|
||||
inc ebp ; Increase program counter
|
||||
ret
|
||||
NEWSYM FxOpb1F ; TO RN set register n as destination register
|
||||
FETCHPIPE
|
||||
test dword [SfxB],1
|
||||
jnz .VersionB
|
||||
mov edi,SfxR0+15*4
|
||||
inc ebp
|
||||
mov eax,ebp
|
||||
sub eax,[SfxCPB]
|
||||
mov [SfxR15],eax
|
||||
call [FxTableb+ecx*4]
|
||||
mov ebp,[SfxCPB]
|
||||
mov dword[withr15sk],1
|
||||
add ebp,[SfxR15]
|
||||
mov edi,SfxR0
|
||||
ret
|
||||
.VersionB
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebp,[SfxCPB]
|
||||
mov dword[withr15sk],1
|
||||
add ebp,eax
|
||||
CLRFLAGS
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb3D ; ALT1 set alt1 mode ; Verified.
|
||||
FETCHPIPE
|
||||
mov dword [SfxB],0
|
||||
or ch,01h
|
||||
inc ebp
|
||||
mov eax,ebp
|
||||
sub eax,[SfxCPB]
|
||||
mov [SfxR15],eax
|
||||
call [FxTableb+ecx*4]
|
||||
xor ch,ch
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb3E ; ALT2 set alt1 mode ; Verified.
|
||||
FETCHPIPE
|
||||
mov dword [SfxB],0
|
||||
or ch,02h
|
||||
inc ebp
|
||||
mov eax,ebp
|
||||
sub eax,[SfxCPB]
|
||||
mov [SfxR15],eax
|
||||
call [FxTable+ecx*4]
|
||||
xor ch,ch
|
||||
ret
|
||||
|
||||
NEWSYM FxOpb3F ; ALT3 set alt3 mode ; Verified.
|
||||
FETCHPIPE
|
||||
mov dword [SfxB],0
|
||||
or ch,03h
|
||||
inc ebp
|
||||
mov eax,ebp
|
||||
sub eax,[SfxCPB]
|
||||
mov [SfxR15],eax
|
||||
call [FxTable+ecx*4]
|
||||
xor ch,ch
|
||||
ret
|
||||
|
||||
NEWSYM FxOpbB0 ; FROM rn set source register
|
||||
FROMRNb 0
|
||||
NEWSYM FxOpbB1 ; FROM rn set source register
|
||||
FROMRNb 1
|
||||
NEWSYM FxOpbB2 ; FROM rn set source register
|
||||
FROMRNb 2
|
||||
NEWSYM FxOpbB3 ; FROM rn set source register
|
||||
FROMRNb 3
|
||||
NEWSYM FxOpbB4 ; FROM rn set source register
|
||||
FROMRNb 4
|
||||
NEWSYM FxOpbB5 ; FROM rn set source register
|
||||
FROMRNb 5
|
||||
NEWSYM FxOpbB6 ; FROM rn set source register
|
||||
FROMRNb 6
|
||||
NEWSYM FxOpbB7 ; FROM rn set source register
|
||||
FROMRNb 7
|
||||
NEWSYM FxOpbB8 ; FROM rn set source register
|
||||
FROMRNb 8
|
||||
NEWSYM FxOpbB9 ; FROM rn set source register
|
||||
FROMRNb 9
|
||||
NEWSYM FxOpbBA ; FROM rn set source register
|
||||
FROMRNb 10
|
||||
NEWSYM FxOpbBB ; FROM rn set source register
|
||||
FROMRNb 11
|
||||
NEWSYM FxOpbBC ; FROM rn set source register
|
||||
FROMRNb 12
|
||||
NEWSYM FxOpbBD ; FROM rn set source register
|
||||
FROMRNb 13
|
||||
NEWSYM FxOpbBE ; FROM rn set source register
|
||||
FROMRNb 14
|
||||
NEWSYM FxOpbBF ; FROM rn set source register
|
||||
test dword [SfxB],1
|
||||
jnz .VersionB
|
||||
mov esi,SfxR0+15*4
|
||||
inc ebp ; Increase program counter
|
||||
mov eax,ebp
|
||||
sub eax,[SfxCPB]
|
||||
mov [SfxR15],eax
|
||||
call [FxTableb+ecx*4]
|
||||
mov esi,SfxR0
|
||||
ret
|
||||
.VersionB
|
||||
FETCHPIPE
|
||||
mov eax,ebp
|
||||
sub eax,[SfxCPB]
|
||||
inc ebp
|
||||
mov [edi],eax ; Write Destination
|
||||
mov [SfxSignZero],eax
|
||||
shr al,7
|
||||
mov byte[SfxOverflow],al
|
||||
CLRFLAGS
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc05 ; BRA branch always ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
mov cl,[ebp+1]
|
||||
inc ebp
|
||||
add ebp,eax
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc06 ; BGE branch on greater or equals ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
mov ebx,[SfxSignZero]
|
||||
shr ebx,15
|
||||
inc ebp
|
||||
xor bl,[SfxOverflow]
|
||||
mov cl,[ebp]
|
||||
test bl,01h
|
||||
jnz .nojump
|
||||
add ebp,eax
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc07 ; BLT branch on lesss than ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
mov ebx,[SfxSignZero]
|
||||
shr ebx,15
|
||||
inc ebp
|
||||
xor bl,[SfxOverflow]
|
||||
mov cl,[ebp]
|
||||
test bl,01h
|
||||
jz .nojump
|
||||
add ebp,eax
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc08 ; BNE branch on not equal ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test dword[SfxSignZero],0FFFFh
|
||||
mov cl,[ebp]
|
||||
jz .nojump
|
||||
add ebp,eax
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc09 ; BEQ branch on equal (z=1) ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test dword[SfxSignZero],0FFFFh
|
||||
mov cl,[ebp]
|
||||
jnz .nojump
|
||||
add ebp,eax
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc0A ; BPL branch on plus ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test dword[SfxSignZero],088000h
|
||||
mov cl,[ebp]
|
||||
jnz .nojump
|
||||
add ebp,eax
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc0B ; BMI branch on minus ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test dword[SfxSignZero],088000h
|
||||
mov cl,[ebp]
|
||||
jz .nojump
|
||||
add ebp,eax
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc0C ; BCC branch on carry clear ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test byte[SfxCarry],01h
|
||||
mov cl,[ebp]
|
||||
jnz .nojump
|
||||
add ebp,eax
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc0D ; BCS branch on carry set ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test byte[SfxCarry],01h
|
||||
mov cl,[ebp]
|
||||
jz .nojump
|
||||
add ebp,eax
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc0E ; BVC branch on overflow clear ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test byte[SfxOverflow],01h
|
||||
mov cl,[ebp]
|
||||
jnz .nojump
|
||||
add ebp,eax
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc0F ; BVS branch on overflow set ; Verified.
|
||||
movsx eax,byte[ebp]
|
||||
inc ebp
|
||||
test byte[SfxOverflow],01h
|
||||
mov cl,[ebp]
|
||||
jz .nojump
|
||||
add ebp,eax
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
.nojump
|
||||
inc ebp
|
||||
call [FxTablec+ecx*4]
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc10 ; TO RN set register n as destination register
|
||||
TORNc 0
|
||||
NEWSYM FxOpc11 ; TO RN set register n as destination register
|
||||
TORNc 1
|
||||
NEWSYM FxOpc12 ; TO RN set register n as destination register
|
||||
TORNc 2
|
||||
NEWSYM FxOpc13 ; TO RN set register n as destination register
|
||||
TORNc 3
|
||||
NEWSYM FxOpc14 ; TO RN set register n as destination register
|
||||
TORNc 4
|
||||
NEWSYM FxOpc15 ; TO RN set register n as destination register
|
||||
TORNc 5
|
||||
NEWSYM FxOpc16 ; TO RN set register n as destination register
|
||||
TORNc 6
|
||||
NEWSYM FxOpc17 ; TO RN set register n as destination register
|
||||
TORNc 7
|
||||
NEWSYM FxOpc18 ; TO RN set register n as destination register
|
||||
TORNc 8
|
||||
NEWSYM FxOpc19 ; TO RN set register n as destination register
|
||||
TORNc 9
|
||||
NEWSYM FxOpc1A ; TO RN set register n as destination register
|
||||
TORNc 10
|
||||
NEWSYM FxOpc1B ; TO RN set register n as destination register
|
||||
TORNc 11
|
||||
NEWSYM FxOpc1C ; TO RN set register n as destination register
|
||||
TORNc 12
|
||||
NEWSYM FxOpc1D ; TO RN set register n as destination register
|
||||
TORNc 13
|
||||
NEWSYM FxOpc1E ; TO RN set register n as destination register
|
||||
FETCHPIPE
|
||||
mov eax,[esi] ; Read Source
|
||||
mov [SfxR0+14*4],eax ; Write
|
||||
CLRFLAGS
|
||||
UpdateR14
|
||||
inc ebp ; Increase program counter
|
||||
ret
|
||||
NEWSYM FxOpc1F ; TO RN set register n as destination register
|
||||
FETCHPIPE
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebp,[SfxCPB]
|
||||
mov [SfxR15],eax
|
||||
add ebp,eax
|
||||
CLRFLAGS
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc3D ; ALT1 set alt1 mode ; Verified.
|
||||
FETCHPIPE
|
||||
mov dword [SfxB],0
|
||||
or ch,01h
|
||||
inc ebp
|
||||
call [FxTablec+ecx*4]
|
||||
xor ch,ch
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc3E ; ALT2 set alt1 mode ; Verified.
|
||||
FETCHPIPE
|
||||
mov dword [SfxB],0
|
||||
or ch,02h
|
||||
inc ebp
|
||||
call [FxTablec+ecx*4]
|
||||
xor ch,ch
|
||||
ret
|
||||
|
||||
NEWSYM FxOpc3F ; ALT3 set alt3 mode ; Verified.
|
||||
FETCHPIPE
|
||||
mov dword [SfxB],0
|
||||
or ch,03h
|
||||
inc ebp
|
||||
call [FxTablec+ecx*4]
|
||||
xor ch,ch
|
||||
ret
|
||||
|
||||
NEWSYM FxOpcB0 ; FROM rn set source register
|
||||
FROMRNc 0
|
||||
NEWSYM FxOpcB1 ; FROM rn set source register
|
||||
FROMRNc 1
|
||||
NEWSYM FxOpcB2 ; FROM rn set source register
|
||||
FROMRNc 2
|
||||
NEWSYM FxOpcB3 ; FROM rn set source register
|
||||
FROMRNc 3
|
||||
NEWSYM FxOpcB4 ; FROM rn set source register
|
||||
FROMRNc 4
|
||||
NEWSYM FxOpcB5 ; FROM rn set source register
|
||||
FROMRNc 5
|
||||
NEWSYM FxOpcB6 ; FROM rn set source register
|
||||
FROMRNc 6
|
||||
NEWSYM FxOpcB7 ; FROM rn set source register
|
||||
FROMRNc 7
|
||||
NEWSYM FxOpcB8 ; FROM rn set source register
|
||||
FROMRNc 8
|
||||
NEWSYM FxOpcB9 ; FROM rn set source register
|
||||
FROMRNc 9
|
||||
NEWSYM FxOpcBA ; FROM rn set source register
|
||||
FROMRNc 10
|
||||
NEWSYM FxOpcBB ; FROM rn set source register
|
||||
FROMRNc 11
|
||||
NEWSYM FxOpcBC ; FROM rn set source register
|
||||
FROMRNc 12
|
||||
NEWSYM FxOpcBD ; FROM rn set source register
|
||||
FROMRNc 13
|
||||
NEWSYM FxOpcBE ; FROM rn set source register
|
||||
FROMRNc 14
|
||||
NEWSYM FxOpcBF ; FROM rn set source register
|
||||
FETCHPIPE
|
||||
mov eax,ebp
|
||||
sub eax,[SfxCPB]
|
||||
inc ebp
|
||||
mov [edi],eax ; Write Destination
|
||||
mov [SfxSignZero],eax
|
||||
shr al,7
|
||||
mov byte[SfxOverflow],al
|
||||
CLRFLAGS
|
||||
ret
|
||||
|
||||
NEWSYM FxEmu2BAsmEnd
|
|
@ -1,88 +0,0 @@
|
|||
;Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com )
|
||||
;
|
||||
;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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
%macro TORNb 1 ; V
|
||||
FETCHPIPE
|
||||
test dword [SfxB],1
|
||||
jnz .VersionB
|
||||
mov edi, SfxR0+%1*4
|
||||
inc ebp ; Increase program counter
|
||||
mov eax,ebp
|
||||
sub eax,[SfxCPB]
|
||||
mov dword[withr15sk],1
|
||||
mov [SfxR15],eax
|
||||
call [FxTableb+ecx*4]
|
||||
mov edi,SfxR0
|
||||
ret
|
||||
.VersionB
|
||||
mov eax,[esi] ; Read Source
|
||||
mov dword[withr15sk],1
|
||||
inc ebp ; Increase program counter
|
||||
mov [SfxR0+%1*4],eax ; Write
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro FROMRNb 1 ; V
|
||||
FETCHPIPE
|
||||
test dword [SfxB],1
|
||||
jnz .VersionB
|
||||
mov esi,SfxR0+%1*4
|
||||
inc ebp ; Increase program counter
|
||||
call [FxTable+ecx*4]
|
||||
mov esi,SfxR0
|
||||
ret
|
||||
.VersionB
|
||||
mov eax,[SfxR0+%1*4] ; Read
|
||||
inc ebp
|
||||
mov [edi],eax ; Write Destination
|
||||
mov [SfxSignZero],eax
|
||||
shr al,7
|
||||
mov byte[SfxOverflow],al
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro TORNc 1 ; V
|
||||
FETCHPIPE
|
||||
mov eax,[esi] ; Read Source
|
||||
inc ebp ; Increase program counter
|
||||
mov [SfxR0+%1*4],eax ; Write
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
|
||||
%macro FROMRNc 1 ; V
|
||||
FETCHPIPE
|
||||
mov eax,[SfxR0+%1*4] ; Read
|
||||
inc ebp
|
||||
mov [edi],eax ; Write Destination
|
||||
mov [SfxSignZero],eax
|
||||
shr al,7
|
||||
mov byte[SfxOverflow],al
|
||||
CLRFLAGS
|
||||
ret
|
||||
%endmacro
|
2557
i386/fxemu2c.asm
2557
i386/fxemu2c.asm
File diff suppressed because it is too large
Load Diff
528
i386/fxemu2c.mac
528
i386/fxemu2c.mac
|
@ -1,528 +0,0 @@
|
|||
;Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com )
|
||||
;
|
||||
;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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
%macro FXReturn 0
|
||||
dec dword [NumberOfOpcodes]
|
||||
jmp [FxTabled+ecx*4]
|
||||
ALIGN32
|
||||
%endmacro
|
||||
|
||||
%macro FXReturn2 0
|
||||
dec dword [NumberOfOpcodes]
|
||||
js %%endloop
|
||||
jmp [FxTabled+ecx*4]
|
||||
%%endloop
|
||||
jmp FXEndLoop
|
||||
; jmp [FxTabled+ecx*4]
|
||||
ALIGN32
|
||||
%endmacro
|
||||
|
||||
%macro TORNd 1 ; V
|
||||
FETCHPIPE
|
||||
mov edi, SfxR0+%1*4
|
||||
inc ebp ; Increase program counter
|
||||
call [FxTable+ecx*4]
|
||||
mov edi,SfxR0
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro WITHc 1 ; Verified.
|
||||
FETCHPIPE
|
||||
mov esi,SfxR0+%1*4
|
||||
mov edi,SfxR0+%1*4
|
||||
mov dword [SfxB],1
|
||||
inc ebp ; Increase program counter
|
||||
call [FxTablec+ecx*4]
|
||||
mov esi,SfxR0
|
||||
mov edi,SfxR0
|
||||
mov dword [SfxB],0 ; Clear B Flag
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro STWRNc 1 ; V
|
||||
mov eax,[SfxR0+%1*4] ; Read register
|
||||
mov ebx,[SfxRAMMem]
|
||||
mov dword [SfxLastRamAdr],eax ; Save last ram address
|
||||
add dword [SfxLastRamAdr],ebx ; Save last ram address
|
||||
mov edx,[esi] ; Read Source
|
||||
FETCHPIPE
|
||||
mov [ebx+eax],dl ; Store Word
|
||||
xor eax,1
|
||||
inc ebp ; Increase program counter
|
||||
mov [ebx+eax],dh ; Store Word
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro STBRNc 1 ; V
|
||||
mov eax,[SfxR0+%1*4] ; Read register
|
||||
FETCHPIPE
|
||||
add eax,[SfxRAMMem]
|
||||
mov dword [SfxLastRamAdr],eax ; Save last ram address
|
||||
mov ebx,[esi] ; Read Source
|
||||
mov byte [eax],bl ; Store Byte
|
||||
CLRFLAGS
|
||||
inc ebp ; Increase program counter
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro LDWRNc 1 ; V
|
||||
mov eax,[SfxR0+%1*4] ; Read register
|
||||
mov ebx,[SfxRAMMem]
|
||||
mov dword [SfxLastRamAdr],eax ; Save last ram address
|
||||
FETCHPIPE
|
||||
mov dl,[ebx+eax] ; Store Word
|
||||
add dword [SfxLastRamAdr],ebx ; Save last ram address
|
||||
xor eax,1
|
||||
and edx,0FFFFh
|
||||
inc ebp ; Increase program counter
|
||||
mov dh,[ebx+eax] ; Store Word
|
||||
mov [edi],edx ; Read Source
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro LDBRNc 1 ; V
|
||||
mov eax,[SfxR0+%1*4] ; Read register
|
||||
FETCHPIPE
|
||||
add eax,[SfxRAMMem]
|
||||
xor ebx,ebx
|
||||
mov dword [SfxLastRamAdr],eax ; Save last ram address
|
||||
mov bl,[eax] ; Read Byte
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],ebx ; Store Result
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro ADDRNc 1 ; V
|
||||
mov eax, [esi] ; Read Source
|
||||
mov ebx, [SfxR0+%1*4]
|
||||
FETCHPIPE
|
||||
add ax,bx
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
mov [SfxSignZero],eax
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro ADCRNc 1 ; V
|
||||
FETCHPIPE
|
||||
mov eax, [esi] ; Read Source
|
||||
mov ebx, [SfxR0+%1*4]
|
||||
shr byte[SfxCarry],1
|
||||
adc ax,bx
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
mov [SfxSignZero],eax
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro ADIRNc 1 ; V
|
||||
mov eax, [esi] ; Read Source
|
||||
FETCHPIPE
|
||||
add ax,%1
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
mov [SfxSignZero],eax
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro ADCIRNc 1 ; V
|
||||
FETCHPIPE
|
||||
mov eax, [esi] ; Read Source
|
||||
shr byte[SfxCarry],1
|
||||
adc ax,%1
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
mov [SfxSignZero],eax
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro SUBRNc 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebx,[SfxR0+%1*4]
|
||||
FETCHPIPE
|
||||
sub ax,bx
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
xor byte[SfxCarry],1
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro SBCRNc 1 ; V
|
||||
FETCHPIPE
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebx,[SfxR0+%1*4]
|
||||
cmp byte[SfxCarry],1
|
||||
sbb ax,bx
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
xor byte[SfxCarry],1
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro SUBIRNc 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
FETCHPIPE
|
||||
sub ax,%1
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
xor byte[SfxCarry],1
|
||||
inc ebp ; Increase program counter
|
||||
mov [edi],eax ; Write Destination
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro CMPRNc 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebx,[SfxR0+%1*4]
|
||||
FETCHPIPE
|
||||
sub ax,bx
|
||||
seto byte[SfxOverflow]
|
||||
setc byte[SfxCarry]
|
||||
xor byte[SfxCarry],1
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
inc ebp ; Increase program counter
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro ANDRNc 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebx,[SfxR0+%1*4] ; Read RN
|
||||
FETCHPIPE
|
||||
and eax,ebx
|
||||
inc ebp
|
||||
mov dword [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro BICRNc 1 ; V
|
||||
mov ebx,[SfxR0+%1*4] ; Read RN
|
||||
mov eax,[esi] ; Read Source
|
||||
xor ebx,0FFFFh
|
||||
FETCHPIPE
|
||||
and eax,ebx
|
||||
inc ebp
|
||||
mov dword [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro ANDIRNc 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
FETCHPIPE
|
||||
and eax,%1
|
||||
inc ebp
|
||||
mov dword [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro BICIRNc 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
FETCHPIPE
|
||||
and eax,%1
|
||||
inc ebp
|
||||
mov dword [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro MULTRNc 1 ; V
|
||||
mov al,byte [esi] ; Read Source
|
||||
mov bl,byte [SfxR0+%1*4] ; Read RN
|
||||
FETCHPIPE
|
||||
imul bl
|
||||
inc ebp
|
||||
and eax,0FFFFh
|
||||
mov [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro UMULTRNc 1 ; V
|
||||
mov al,byte [esi] ; Read Source
|
||||
mov bl,byte [SfxR0+%1*4] ; Read RN
|
||||
FETCHPIPE
|
||||
mul bl
|
||||
inc ebp
|
||||
and eax,0FFFFh
|
||||
mov [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro MULTIRNc 1 ; V
|
||||
mov al,byte [esi] ; Read Source
|
||||
mov bl,%1 ; Read RN
|
||||
FETCHPIPE
|
||||
imul bl
|
||||
inc ebp
|
||||
and eax,0FFFFh
|
||||
mov [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro UMULTIRNc 1 ; V
|
||||
mov al,byte [esi] ; Read Source
|
||||
mov bl,%1 ; Read RN
|
||||
FETCHPIPE
|
||||
mul bl
|
||||
inc ebp
|
||||
and eax,0FFFFh
|
||||
mov [SfxSignZero],eax
|
||||
mov [edi],eax ; Write Destination
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro LINKc 1 ; Verified.
|
||||
mov eax,ebp
|
||||
sub eax,[SfxCPB]
|
||||
add eax,%1
|
||||
FETCHPIPE
|
||||
mov word [SfxR11],ax
|
||||
CLRFLAGS
|
||||
inc ebp
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro JMPRNc 1 ; V
|
||||
FETCHPIPE
|
||||
mov eax,[SfxR0+%1*4] ; Read RN
|
||||
mov ebp,[SfxCPB]
|
||||
add ebp,eax
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro LJMPRNc 1 ; V
|
||||
FETCHPIPE
|
||||
mov eax,[SfxR0+%1*4]
|
||||
and eax,07Fh
|
||||
mov byte[SfxPBR],al
|
||||
; mov byte[fxtrace+eax],1
|
||||
mov eax,[SfxMemTable+eax*4]
|
||||
mov [SfxCPB],eax
|
||||
mov ebp,eax
|
||||
add ebp,[esi] ; Read RN
|
||||
mov dword [SfxCacheActive],0
|
||||
push ecx
|
||||
call FxOp02
|
||||
pop ecx
|
||||
dec ebp
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro IBTRNc 1 ; V
|
||||
movsx eax,byte[ebp]
|
||||
mov cl,[ebp+1]
|
||||
add ebp,2
|
||||
mov [SfxR0+%1*4],ax
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro LMSRNc 1 ; Verified.
|
||||
xor eax,eax
|
||||
mov al,[ebp]
|
||||
add eax,eax
|
||||
inc ebp
|
||||
add eax,[SfxRAMMem]
|
||||
mov cl,[ebp]
|
||||
mov dword [SfxLastRamAdr],eax
|
||||
mov ebx,[eax] ; Read word from ram
|
||||
inc ebp
|
||||
mov [SfxR0+%1*4],bx ; Write data
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro SMSRNc 1 ; Verified.
|
||||
xor eax,eax
|
||||
mov al,[ebp]
|
||||
inc ebp
|
||||
add eax,eax
|
||||
mov cl,[ebp]
|
||||
add eax,[SfxRAMMem]
|
||||
mov ebx,[SfxR0+%1*4] ; Read data
|
||||
mov dword [SfxLastRamAdr],eax
|
||||
inc ebp
|
||||
mov [eax],bx ; Write word to ram
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro FROMRNd 1 ; V
|
||||
FETCHPIPE
|
||||
mov esi,SfxR0+%1*4
|
||||
inc ebp ; Increase program counter
|
||||
call [FxTable+ecx*4]
|
||||
mov esi,SfxR0
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro ORRNc 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebx,[SfxR0+%1*4] ; Read
|
||||
FETCHPIPE
|
||||
or eax,ebx
|
||||
inc ebp
|
||||
mov [edi],eax ; Write DREG
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro XORRNc 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
mov ebx,[SfxR0+%1*4] ; Read
|
||||
FETCHPIPE
|
||||
xor eax,ebx
|
||||
inc ebp
|
||||
mov [edi],eax ; Write DREG
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro ORIc 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
FETCHPIPE
|
||||
or eax,%1
|
||||
inc ebp
|
||||
mov [edi],eax ; Write DREG
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro XORIc 1 ; V
|
||||
mov eax,[esi] ; Read Source
|
||||
FETCHPIPE
|
||||
xor eax,%1
|
||||
inc ebp
|
||||
mov [edi],eax ; Write DREG
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro INCRNc 1 ; Verified
|
||||
inc word[SfxR0+%1*4]
|
||||
FETCHPIPE
|
||||
mov eax,[SfxR0+%1*4] ; Read Source
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
inc ebp
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro DECRNc 1 ; Verified
|
||||
dec word[SfxR0+%1*4]
|
||||
FETCHPIPE
|
||||
mov eax,[SfxR0+%1*4] ; Read Source
|
||||
mov [SfxR0+%1*4],eax
|
||||
mov [SfxSignZero],eax
|
||||
CLRFLAGS
|
||||
inc ebp
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro IWTRNc 1 ; aka LEA ; Verified.
|
||||
mov eax,[ebp]
|
||||
mov cl,[ebp+2]
|
||||
and eax,0FFFFh
|
||||
add ebp,3
|
||||
mov [SfxR0+%1*4],eax
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro LMRNc 1 ; Verified!
|
||||
xor eax,eax
|
||||
mov cl,[ebp+2]
|
||||
mov ax,[ebp]
|
||||
mov ebx,[SfxRAMMem]
|
||||
mov [SfxLastRamAdr],eax
|
||||
add [SfxLastRamAdr],ebx
|
||||
mov dl,[eax+ebx]
|
||||
xor eax,1
|
||||
add ebp,3
|
||||
mov dh,[eax+ebx]
|
||||
mov word [SfxR0+%1*4],dx ; Store Word
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
||||
|
||||
%macro SMRNc 1 ; Verified
|
||||
mov ebx,[SfxR0+%1*4]
|
||||
mov eax,[ebp]
|
||||
mov cl,[ebp+2]
|
||||
and eax,0FFFFh
|
||||
mov dx,bx
|
||||
mov ebx,[SfxRAMMem]
|
||||
mov [SfxLastRamAdr],eax
|
||||
add [SfxLastRamAdr],ebx
|
||||
mov [eax+ebx],dl
|
||||
xor eax,1
|
||||
add ebp,3
|
||||
mov [eax+ebx],dh
|
||||
CLRFLAGS
|
||||
FXReturn
|
||||
%endmacro
|
3557
i386/fxtable.asm
3557
i386/fxtable.asm
File diff suppressed because it is too large
Load Diff
|
@ -1,80 +0,0 @@
|
|||
;Copyright (C) 1997-2006 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach )
|
||||
;
|
||||
;http://www.zsnes.com
|
||||
;http://sourceforge.net/projects/zsnes
|
||||
;
|
||||
;This program is free software; you can redistribute it and/or
|
||||
;modify it under the terms of the GNU General Public License
|
||||
;version 2 as published by the Free Software Foundation.
|
||||
;
|
||||
;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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
%ifidn __OUTPUT_FORMAT__,elf
|
||||
section .note.GNU-stack noalloc noexec nowrite progbits
|
||||
%endif
|
||||
|
||||
%ifdef __AMD64__
|
||||
bits 64
|
||||
%else
|
||||
bits 32
|
||||
%endif
|
||||
|
||||
section .text
|
||||
; Zsnes required macros
|
||||
|
||||
%define ZVERSION 'Pre 1.43'
|
||||
|
||||
|
||||
%ifdef MACHO
|
||||
section .text align=16
|
||||
section .data align=4
|
||||
section .bss align=4
|
||||
%endif
|
||||
|
||||
%ifdef ELF
|
||||
|
||||
%imacro newsym 1
|
||||
GLOBAL %1
|
||||
%1:
|
||||
%endmacro
|
||||
%imacro newsym 2+
|
||||
GLOBAL %1
|
||||
%1: %2
|
||||
%endmacro
|
||||
%define EXTSYM EXTERN
|
||||
|
||||
%else
|
||||
|
||||
%imacro newsym 1
|
||||
GLOBAL _%1
|
||||
_%1:
|
||||
%1:
|
||||
%endmacro
|
||||
%imacro newsym 2+
|
||||
GLOBAL _%1
|
||||
_%1:
|
||||
%1: %2
|
||||
%endmacro
|
||||
%imacro EXTSYM 1-*
|
||||
%rep %0
|
||||
EXTERN _%1
|
||||
%define %1 _%1
|
||||
%rotate 1
|
||||
%endrep
|
||||
%endmacro
|
||||
%endif
|
||||
|
||||
%macro ALIGN32 0
|
||||
times ($$-$) & 1Fh nop ; Long word alignment
|
||||
%endmacro
|
||||
%macro ALIGN16 0
|
||||
times ($$-$) & 1Fh nop ; Long word alignment
|
||||
%endmacro
|
101
i386/regs.mac
101
i386/regs.mac
|
@ -1,101 +0,0 @@
|
|||
; Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
;
|
||||
; Super FX assembler emulator code
|
||||
; (c) Copyright 1998, 1999 zsKnight and _Demo_.
|
||||
;
|
||||
; 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.
|
||||
;
|
||||
;*******************************************************
|
||||
; InitReg Initializes Registers
|
||||
;*******************************************************
|
||||
|
||||
%macro setreg 2
|
||||
mov edi,%1
|
||||
add edi,[regptr]
|
||||
mov eax,%2
|
||||
mov [edi],eax
|
||||
%endmacro
|
||||
|
||||
;*******************************************************
|
||||
; Registers Note : Remember to restore AH, ECX, & DX
|
||||
;*******************************************************
|
||||
|
||||
%macro checkmultchange 0
|
||||
; execute multiplication
|
||||
cmp byte[multchange],0
|
||||
je .nomult
|
||||
push edx
|
||||
push eax
|
||||
xor bh,bh
|
||||
mov bl,[mode7B+1]
|
||||
mov ax,[mode7A]
|
||||
test bl,80h
|
||||
jz .noneg
|
||||
mov bh,0FFh
|
||||
.noneg
|
||||
imul bx
|
||||
mov [compmult],ax
|
||||
mov [compmult+2],dl
|
||||
pop eax
|
||||
pop edx
|
||||
mov byte[multchange],0
|
||||
.nomult
|
||||
%endmacro
|
||||
|
||||
%macro mouse4016doxA 2
|
||||
cmp byte[JoyAPos],%1
|
||||
jne .nx7
|
||||
mov bx,[mousexpos]
|
||||
shr bx,%2
|
||||
and bx,1
|
||||
mov al,bl
|
||||
.nx7
|
||||
%endmacro
|
||||
|
||||
%macro mouse4016doyA 2
|
||||
cmp byte[JoyAPos],%1
|
||||
jne .ny7
|
||||
mov bx,[mouseypos]
|
||||
shr bx,%2
|
||||
and bx,1
|
||||
mov al,bl
|
||||
.ny7
|
||||
%endmacro
|
||||
|
||||
%macro mouse4017dox 2
|
||||
cmp byte[JoyBPos],%1
|
||||
jne .nx7
|
||||
mov bx,[mousexpos]
|
||||
shr bx,%2
|
||||
and bx,1
|
||||
mov al,bl
|
||||
.nx7
|
||||
%endmacro
|
||||
|
||||
%macro mouse4017doy 2
|
||||
cmp byte[JoyBPos],%1
|
||||
jne .ny7
|
||||
mov bx,[mouseypos]
|
||||
shr bx,%2
|
||||
and bx,1
|
||||
mov al,bl
|
||||
.ny7
|
||||
%endmacro
|
|
@ -1,51 +0,0 @@
|
|||
; Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
;
|
||||
; Super FX assembler emulator code
|
||||
; (c) Copyright 1998, 1999 zsKnight and _Demo_.
|
||||
;
|
||||
; 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.
|
||||
;
|
||||
;*******************************************************
|
||||
; InitRegW Initializes Write Registers
|
||||
;*******************************************************
|
||||
|
||||
%macro reenablespc 0
|
||||
cmp dword[cycpbl],1000000h
|
||||
jb %%enspc
|
||||
mov dword[cycpbl],0
|
||||
test byte[curexecstate],02h
|
||||
jnz %%enspc
|
||||
or byte[curexecstate],02h
|
||||
push ebx
|
||||
xor ebx,ebx
|
||||
mov bl,dl
|
||||
EXTSYM tableadc
|
||||
mov edi,[tableadc+ebx*4]
|
||||
pop ebx
|
||||
%%enspc
|
||||
%endmacro
|
||||
|
||||
%macro setregw 2
|
||||
mov edi,%1
|
||||
add edi,[regptw]
|
||||
mov eax,%2
|
||||
mov [edi],eax
|
||||
%endmacro
|
678
i386/sfxproc.asm
678
i386/sfxproc.asm
|
@ -1,678 +0,0 @@
|
|||
;Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com )
|
||||
;
|
||||
;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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
%include "macros.mac"
|
||||
|
||||
EXTSYM NumberOfOpcodes,SfxB,SfxBRAMR,SfxCBR,SfxCFGR,SfxCLSR,SfxCPB,SfxCROM
|
||||
EXTSYM SfxCarry,SfxMemTable,SfxOverflow,SfxPBR,SfxPIPE,SfxR0,SfxR1,SfxR10
|
||||
EXTSYM SfxR11,SfxR12,SfxR13,SfxR14,SfxR15,SfxR2,SfxR3,SfxR4,SfxR5,SfxR6
|
||||
EXTSYM SfxR7,SfxR8,SfxR9,SfxRAMBR,SfxRAMMem,SfxROMBR,SfxSCBR,SfxSCMR,SfxSFR
|
||||
EXTSYM SfxSignZero,SfxnRamBanks,StartSFX,regptr,regptw,sfxramdata
|
||||
EXTSYM SfxPOR,sfxclineloc,UpdatePORSCMR,UpdateCLSR,UpdateSCBRCOLR,SfxAC
|
||||
EXTSYM sfx128lineloc,sfx160lineloc,sfx192lineloc,sfxobjlineloc
|
||||
|
||||
NEWSYM SfxProcAsmStart
|
||||
|
||||
%include "regs.mac"
|
||||
%include "regsw.mac"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
%macro AssembleSFXFlags 0
|
||||
and word[SfxSFR],8F60h
|
||||
test byte[SfxCarry],1
|
||||
jz .nosfxcarry
|
||||
or word[SfxSFR],04h
|
||||
.nosfxcarry
|
||||
cmp word[SfxSignZero],0
|
||||
jne .nozero
|
||||
or word[SfxSFR],02h
|
||||
.nozero
|
||||
test word[SfxSignZero],8000h
|
||||
jz .noneg
|
||||
or word[SfxSFR],08h
|
||||
.noneg
|
||||
cmp byte[SfxOverflow],0
|
||||
je .noof
|
||||
or word[SfxSFR],10h
|
||||
.noof
|
||||
cmp byte[SfxB],0
|
||||
je .bzero
|
||||
or word[SfxSFR],1000h
|
||||
.bzero
|
||||
%endmacro
|
||||
|
||||
|
||||
NEWSYM initsfxregsr
|
||||
setreg 3000h*4,reg3000r
|
||||
setreg 3001h*4,reg3001r
|
||||
setreg 3002h*4,reg3002r
|
||||
setreg 3003h*4,reg3003r
|
||||
setreg 3004h*4,reg3004r
|
||||
setreg 3005h*4,reg3005r
|
||||
setreg 3006h*4,reg3006r
|
||||
setreg 3007h*4,reg3007r
|
||||
setreg 3008h*4,reg3008r
|
||||
setreg 3009h*4,reg3009r
|
||||
setreg 300Ah*4,reg300Ar
|
||||
setreg 300Bh*4,reg300Br
|
||||
setreg 300Ch*4,reg300Cr
|
||||
setreg 300Dh*4,reg300Dr
|
||||
setreg 300Eh*4,reg300Er
|
||||
setreg 300Fh*4,reg300Fr
|
||||
setreg 3010h*4,reg3010r
|
||||
setreg 3011h*4,reg3011r
|
||||
setreg 3012h*4,reg3012r
|
||||
setreg 3013h*4,reg3013r
|
||||
setreg 3014h*4,reg3014r
|
||||
setreg 3015h*4,reg3015r
|
||||
setreg 3016h*4,reg3016r
|
||||
setreg 3017h*4,reg3017r
|
||||
setreg 3018h*4,reg3018r
|
||||
setreg 3019h*4,reg3019r
|
||||
setreg 301Ah*4,reg301Ar
|
||||
setreg 301Bh*4,reg301Br
|
||||
setreg 301Ch*4,reg301Cr
|
||||
setreg 301Dh*4,reg301Dr
|
||||
setreg 301Eh*4,reg301Er
|
||||
setreg 301Fh*4,reg301Fr
|
||||
setreg 3030h*4,reg3030r
|
||||
setreg 3031h*4,reg3031r
|
||||
setreg 3032h*4,reg3032r
|
||||
setreg 3033h*4,reg3033r
|
||||
setreg 3034h*4,reg3034r
|
||||
setreg 3035h*4,reg3035r
|
||||
setreg 3036h*4,reg3036r
|
||||
setreg 3037h*4,reg3037r
|
||||
setreg 3038h*4,reg3038r
|
||||
setreg 3039h*4,reg3039r
|
||||
setreg 303Ah*4,reg303Ar
|
||||
setreg 303Bh*4,reg303Br
|
||||
setreg 303Ch*4,reg303Cr
|
||||
setreg 303Dh*4,reg303Dr
|
||||
setreg 303Eh*4,reg303Er
|
||||
setreg 303Fh*4,reg303Fr
|
||||
; set 3100-31FF to cacheregr
|
||||
mov edi,3100h*4
|
||||
add edi,[regptr]
|
||||
mov eax,cacheregr
|
||||
mov ecx,200h
|
||||
.loop
|
||||
mov [edi],eax
|
||||
add edi,4
|
||||
dec ecx
|
||||
jnz .loop
|
||||
ret
|
||||
|
||||
NEWSYM initsfxregsw
|
||||
setregw 3000h*4,reg3000w
|
||||
setregw 3001h*4,reg3001w
|
||||
setregw 3002h*4,reg3002w
|
||||
setregw 3003h*4,reg3003w
|
||||
setregw 3004h*4,reg3004w
|
||||
setregw 3005h*4,reg3005w
|
||||
setregw 3006h*4,reg3006w
|
||||
setregw 3007h*4,reg3007w
|
||||
setregw 3008h*4,reg3008w
|
||||
setregw 3009h*4,reg3009w
|
||||
setregw 300Ah*4,reg300Aw
|
||||
setregw 300Bh*4,reg300Bw
|
||||
setregw 300Ch*4,reg300Cw
|
||||
setregw 300Dh*4,reg300Dw
|
||||
setregw 300Eh*4,reg300Ew
|
||||
setregw 300Fh*4,reg300Fw
|
||||
setregw 3010h*4,reg3010w
|
||||
setregw 3011h*4,reg3011w
|
||||
setregw 3012h*4,reg3012w
|
||||
setregw 3013h*4,reg3013w
|
||||
setregw 3014h*4,reg3014w
|
||||
setregw 3015h*4,reg3015w
|
||||
setregw 3016h*4,reg3016w
|
||||
setregw 3017h*4,reg3017w
|
||||
setregw 3018h*4,reg3018w
|
||||
setregw 3019h*4,reg3019w
|
||||
setregw 301Ah*4,reg301Aw
|
||||
setregw 301Bh*4,reg301Bw
|
||||
setregw 301Ch*4,reg301Cw
|
||||
setregw 301Dh*4,reg301Dw
|
||||
setregw 301Eh*4,reg301Ew
|
||||
setregw 301Fh*4,reg301Fw
|
||||
setregw 3030h*4,reg3030w
|
||||
setregw 3031h*4,reg3031w
|
||||
setregw 3032h*4,reg3032w
|
||||
setregw 3033h*4,reg3033w
|
||||
setregw 3034h*4,reg3034w
|
||||
setregw 3035h*4,reg3035w
|
||||
setregw 3036h*4,reg3036w
|
||||
setregw 3037h*4,reg3037w
|
||||
setregw 3038h*4,reg3038w
|
||||
setregw 3039h*4,reg3039w
|
||||
setregw 303Ah*4,reg303Aw
|
||||
setregw 303Bh*4,reg303Bw
|
||||
setregw 303Ch*4,reg303Cw
|
||||
setregw 303Dh*4,reg303Dw
|
||||
setregw 303Eh*4,reg303Ew
|
||||
setregw 303Fh*4,reg303Fw
|
||||
; set 3100-31FF to cacheregw
|
||||
mov edi,3100h*4
|
||||
add edi,[regptw]
|
||||
mov eax,cacheregw
|
||||
mov ecx,200h
|
||||
.loop
|
||||
mov [edi],eax
|
||||
add edi,4
|
||||
dec ecx
|
||||
jnz .loop
|
||||
ret
|
||||
|
||||
NEWSYM cacheregr
|
||||
or byte[cachewarning],1
|
||||
ret
|
||||
|
||||
NEWSYM cacheregw
|
||||
or byte[cachewarning],2
|
||||
ret
|
||||
|
||||
SECTION .bss
|
||||
NEWSYM cachewarning, resb 1
|
||||
NEWSYM SFXProc, resd 1
|
||||
NEWSYM ChangeOps, resd 1
|
||||
|
||||
SECTION .text
|
||||
|
||||
; SFX Registers
|
||||
|
||||
NEWSYM reg3000r
|
||||
mov al,[SfxR0]
|
||||
ret
|
||||
NEWSYM reg3001r
|
||||
mov al,[SfxR0+1]
|
||||
ret
|
||||
NEWSYM reg3002r
|
||||
mov al,[SfxR1]
|
||||
ret
|
||||
NEWSYM reg3003r
|
||||
mov al,[SfxR1+1]
|
||||
ret
|
||||
NEWSYM reg3004r
|
||||
mov al,[SfxR2]
|
||||
ret
|
||||
NEWSYM reg3005r
|
||||
mov al,[SfxR2+1]
|
||||
ret
|
||||
NEWSYM reg3006r
|
||||
mov al,[SfxR3]
|
||||
ret
|
||||
NEWSYM reg3007r
|
||||
mov al,[SfxR3+1]
|
||||
ret
|
||||
NEWSYM reg3008r
|
||||
mov al,[SfxR4]
|
||||
ret
|
||||
NEWSYM reg3009r
|
||||
mov al,[SfxR4+1]
|
||||
ret
|
||||
NEWSYM reg300Ar
|
||||
mov al,[SfxR5]
|
||||
ret
|
||||
NEWSYM reg300Br
|
||||
mov al,[SfxR5+1]
|
||||
ret
|
||||
NEWSYM reg300Cr
|
||||
mov al,[SfxR6]
|
||||
ret
|
||||
NEWSYM reg300Dr
|
||||
mov al,[SfxR6+1]
|
||||
ret
|
||||
NEWSYM reg300Er
|
||||
mov al,[SfxR7]
|
||||
ret
|
||||
NEWSYM reg300Fr
|
||||
mov al,[SfxR7+1]
|
||||
ret
|
||||
NEWSYM reg3010r
|
||||
mov al,[SfxR8]
|
||||
ret
|
||||
NEWSYM reg3011r
|
||||
mov al,[SfxR8+1]
|
||||
ret
|
||||
NEWSYM reg3012r
|
||||
mov al,[SfxR9]
|
||||
ret
|
||||
NEWSYM reg3013r
|
||||
mov al,[SfxR9+1]
|
||||
ret
|
||||
NEWSYM reg3014r
|
||||
mov al,[SfxR10]
|
||||
ret
|
||||
NEWSYM reg3015r
|
||||
mov al,[SfxR10+1]
|
||||
ret
|
||||
NEWSYM reg3016r
|
||||
mov al,[SfxR11]
|
||||
ret
|
||||
NEWSYM reg3017r
|
||||
mov al,[SfxR11+1]
|
||||
ret
|
||||
NEWSYM reg3018r
|
||||
mov al,[SfxR12]
|
||||
ret
|
||||
NEWSYM reg3019r
|
||||
mov al,[SfxR12+1]
|
||||
ret
|
||||
NEWSYM reg301Ar
|
||||
mov al,[SfxR13]
|
||||
ret
|
||||
NEWSYM reg301Br
|
||||
mov al,[SfxR13+1]
|
||||
ret
|
||||
NEWSYM reg301Cr
|
||||
mov al,[SfxR14]
|
||||
ret
|
||||
NEWSYM reg301Dr
|
||||
mov al,[SfxR14+1]
|
||||
ret
|
||||
NEWSYM reg301Er
|
||||
mov al,[SfxR15]
|
||||
ret
|
||||
NEWSYM reg301Fr
|
||||
mov al,[SfxR15+1]
|
||||
ret
|
||||
|
||||
; Other SFX stuff
|
||||
|
||||
NEWSYM reg3030r
|
||||
AssembleSFXFlags
|
||||
mov al,[SfxSFR]
|
||||
ret
|
||||
NEWSYM reg3031r
|
||||
cmp byte[SfxAC],1
|
||||
je .alwaysclear
|
||||
cmp dword[ChangeOps],-350*240
|
||||
jl .noclear
|
||||
.alwaysclear
|
||||
and byte[SfxSFR+1],07fh ; clear IRQ flag
|
||||
jmp .cleared
|
||||
.noclear
|
||||
cmp dword[ChangeOps],-350*240*4
|
||||
jge .clear
|
||||
mov dword[ChangeOps],-350*240*4
|
||||
jmp .cleared
|
||||
.clear
|
||||
add dword[ChangeOps],350*240
|
||||
.cleared
|
||||
mov al,[SfxSFR+1]
|
||||
ret
|
||||
SECTION .bss
|
||||
.test resb 1
|
||||
SECTION .text
|
||||
|
||||
NEWSYM reg3032r ; Unused
|
||||
xor al,al
|
||||
ret
|
||||
NEWSYM reg3033r ; BRAMR Backup Ram Read only on/off (bits 1-15 unused)
|
||||
mov al,[SfxBRAMR]
|
||||
ret
|
||||
NEWSYM reg3034r ; PBR (Program Bank)
|
||||
mov al,[SfxPBR]
|
||||
ret
|
||||
NEWSYM reg3035r ; Unused
|
||||
xor al,al
|
||||
ret
|
||||
NEWSYM reg3036r ; ROMBR (Gamepak Rom Bank Register)
|
||||
mov al,[SfxROMBR]
|
||||
ret
|
||||
NEWSYM reg3037r ; CFGR (Control Flags Register)
|
||||
mov al,[SfxCFGR]
|
||||
ret
|
||||
NEWSYM reg3038r ; SCBR (Screen Bank Register)
|
||||
mov al,[SfxSCBR]
|
||||
ret
|
||||
NEWSYM reg3039r ; CLSR (Clock Speed Register)
|
||||
mov al,[SfxCLSR]
|
||||
ret
|
||||
NEWSYM reg303Ar ; SCMR (Screen Mode Register)
|
||||
mov al,[SfxSCMR]
|
||||
test byte[SfxPOR],10h
|
||||
jnz .objmode
|
||||
mov al,[SfxSCMR]
|
||||
and al,00100100b ; 4 + 32
|
||||
cmp al,4
|
||||
je .lines160
|
||||
cmp al,32
|
||||
je .lines192
|
||||
cmp al,36
|
||||
je .objmode
|
||||
mov eax,[sfx128lineloc]
|
||||
jmp .donelines
|
||||
.lines160
|
||||
mov eax,[sfx160lineloc]
|
||||
jmp .donelines
|
||||
.lines192
|
||||
mov eax,[sfx192lineloc]
|
||||
jmp .donelines
|
||||
.objmode
|
||||
mov eax,[sfxobjlineloc]
|
||||
.donelines
|
||||
mov [sfxclineloc],eax
|
||||
ret
|
||||
NEWSYM reg303Br ; VCR (Version Code Register)
|
||||
mov al,20h
|
||||
ret
|
||||
NEWSYM reg303Cr ; RAMBR (Ram bank register)
|
||||
mov al,[SfxRAMBR]
|
||||
ret
|
||||
NEWSYM reg303Dr ; Unused
|
||||
xor al,al
|
||||
ret
|
||||
NEWSYM reg303Er ; CBR (Cache Base Register), lower byte
|
||||
mov al,[SfxCBR]
|
||||
ret
|
||||
NEWSYM reg303Fr ; CBR (Cache Base Register), upper byte
|
||||
mov al,[SfxCBR+1]
|
||||
ret
|
||||
|
||||
; SFX Write Registers
|
||||
|
||||
NEWSYM reg3000w
|
||||
mov [SfxR0],al
|
||||
ret
|
||||
NEWSYM reg3001w
|
||||
mov [SfxR0+1],al
|
||||
ret
|
||||
NEWSYM reg3002w
|
||||
mov [SfxR1],al
|
||||
ret
|
||||
NEWSYM reg3003w
|
||||
mov [SfxR1+1],al
|
||||
ret
|
||||
NEWSYM reg3004w
|
||||
mov [SfxR2],al
|
||||
ret
|
||||
NEWSYM reg3005w
|
||||
mov [SfxR2+1],al
|
||||
ret
|
||||
NEWSYM reg3006w
|
||||
mov [SfxR3],al
|
||||
ret
|
||||
NEWSYM reg3007w
|
||||
mov [SfxR3+1],al
|
||||
ret
|
||||
NEWSYM reg3008w
|
||||
mov [SfxR4],al
|
||||
ret
|
||||
NEWSYM reg3009w
|
||||
mov [SfxR4+1],al
|
||||
ret
|
||||
NEWSYM reg300Aw
|
||||
mov [SfxR5],al
|
||||
ret
|
||||
NEWSYM reg300Bw
|
||||
mov [SfxR5+1],al
|
||||
ret
|
||||
NEWSYM reg300Cw
|
||||
mov [SfxR6],al
|
||||
ret
|
||||
NEWSYM reg300Dw
|
||||
mov [SfxR6+1],al
|
||||
ret
|
||||
NEWSYM reg300Ew
|
||||
mov [SfxR7],al
|
||||
ret
|
||||
NEWSYM reg300Fw
|
||||
mov [SfxR7+1],al
|
||||
ret
|
||||
NEWSYM reg3010w
|
||||
mov [SfxR8],al
|
||||
ret
|
||||
NEWSYM reg3011w
|
||||
mov [SfxR8+1],al
|
||||
ret
|
||||
NEWSYM reg3012w
|
||||
mov [SfxR9],al
|
||||
ret
|
||||
NEWSYM reg3013w
|
||||
mov [SfxR9+1],al
|
||||
ret
|
||||
NEWSYM reg3014w
|
||||
mov [SfxR10],al
|
||||
ret
|
||||
NEWSYM reg3015w
|
||||
mov [SfxR10+1],al
|
||||
ret
|
||||
NEWSYM reg3016w
|
||||
mov [SfxR11],al
|
||||
ret
|
||||
NEWSYM reg3017w
|
||||
mov [SfxR11+1],al
|
||||
ret
|
||||
NEWSYM reg3018w
|
||||
mov [SfxR12],al
|
||||
ret
|
||||
NEWSYM reg3019w
|
||||
mov [SfxR12+1],al
|
||||
ret
|
||||
NEWSYM reg301Aw
|
||||
mov [SfxR13],al
|
||||
ret
|
||||
NEWSYM reg301Bw
|
||||
mov [SfxR13+1],al
|
||||
ret
|
||||
NEWSYM reg301Cw
|
||||
mov [SfxR14],al
|
||||
ret
|
||||
NEWSYM reg301Dw
|
||||
mov [SfxR14+1],al
|
||||
ret
|
||||
NEWSYM reg301Ew
|
||||
mov [SfxR15],al
|
||||
ret
|
||||
NEWSYM reg301Fw
|
||||
mov [SfxR15+1],al
|
||||
; start execution
|
||||
push edx
|
||||
mov edx,[SfxPBR]
|
||||
mov edx,[SfxMemTable+edx*4]
|
||||
add edx,[SfxR15]
|
||||
mov dl,[edx]
|
||||
mov [SfxPIPE],dl
|
||||
pop edx
|
||||
inc word[SfxR15]
|
||||
or byte[SfxSFR],20h
|
||||
or dword [SfxSFR],08000h ; Set IRQ Flag
|
||||
mov dword[SFXProc],1
|
||||
; call StartSFXret
|
||||
ret
|
||||
|
||||
; Other SFX stuff
|
||||
|
||||
NEWSYM reg3030w
|
||||
mov [SfxSFR],al
|
||||
; mov dh,10
|
||||
; Disassemble Flags
|
||||
test al,20h
|
||||
jz .noexec
|
||||
mov dword [NumberOfOpcodes],100
|
||||
call StartSFX
|
||||
.noexec
|
||||
ret
|
||||
NEWSYM reg3031w
|
||||
mov [SfxSFR+1],al
|
||||
ret
|
||||
NEWSYM reg3032w ; Unused
|
||||
ret
|
||||
NEWSYM reg3033w ; BRAMR Backup Ram Read only on/off (bits 1-15 unused)
|
||||
and al,0FEh
|
||||
mov [SfxBRAMR],al
|
||||
ret
|
||||
NEWSYM reg3034w ; PBR (Program Bank)
|
||||
mov [SfxPBR],al
|
||||
xor ebx,ebx
|
||||
mov bl,al
|
||||
mov ebx,[SfxMemTable+ebx*4]
|
||||
mov [SfxCPB],ebx
|
||||
ret
|
||||
NEWSYM reg3035w ; Unused
|
||||
ret
|
||||
NEWSYM reg3036w ; ROMBR (Gamepak Rom Bank Register)
|
||||
mov [SfxROMBR],al
|
||||
xor ebx,ebx
|
||||
mov bl,al
|
||||
mov ebx,[SfxMemTable+ebx*4]
|
||||
mov [SfxCROM],ebx
|
||||
ret
|
||||
NEWSYM reg3037w ; CFGR (Control Flags Register)
|
||||
mov [SfxCFGR],al
|
||||
ret
|
||||
NEWSYM reg3038w ; SCBR (Screen Bank Register)
|
||||
mov [SfxSCBR],al
|
||||
call UpdateSCBRCOLR
|
||||
ret
|
||||
NEWSYM reg3039w ; CLSR (Clock Speed Register)
|
||||
and al,0FEh
|
||||
mov [SfxCLSR],al
|
||||
call UpdateCLSR
|
||||
ret
|
||||
NEWSYM reg303Aw ; SCMR (Screen Mode Register)
|
||||
mov [SfxSCMR],al
|
||||
call UpdatePORSCMR
|
||||
ret
|
||||
NEWSYM reg303Bw ; VCR (Version Code Register)
|
||||
ret
|
||||
NEWSYM reg303Cw ; RAMBR (Ram bank register)
|
||||
mov bl,[SfxnRamBanks]
|
||||
dec bl
|
||||
and al,bl
|
||||
mov ebx,[SfxnRamBanks]
|
||||
dec ebx
|
||||
and eax,ebx
|
||||
mov [SfxRAMBR],eax
|
||||
xor ebx,ebx
|
||||
mov bl,al
|
||||
shl ebx,16
|
||||
add ebx,[sfxramdata]
|
||||
mov dword [SfxRAMMem],ebx
|
||||
ret
|
||||
NEWSYM reg303Dw ; Unused
|
||||
ret
|
||||
NEWSYM reg303Ew ; CBR (Cache Base Register), lower byte
|
||||
mov [SfxCBR],al
|
||||
ret
|
||||
NEWSYM reg303Fw ; CBR (Cache Base Register), upper byte
|
||||
mov [SfxCBR+1],al
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankr8
|
||||
mov ebx,[sfxramdata]
|
||||
mov al,[ebx+ecx]
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankw8
|
||||
mov ebx,[sfxramdata]
|
||||
mov [ebx+ecx],al
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankr16
|
||||
mov ebx,[sfxramdata]
|
||||
mov ax,[ebx+ecx]
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankw16
|
||||
mov ebx,[sfxramdata]
|
||||
mov [ebx+ecx],ax
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankr8b
|
||||
mov ebx,[sfxramdata]
|
||||
mov al,[ebx+ecx+65536]
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankw8b
|
||||
mov ebx,[sfxramdata]
|
||||
mov [ebx+ecx+65536],al
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankr16b
|
||||
mov ebx,[sfxramdata]
|
||||
mov ax,[ebx+ecx+65536]
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankw16b
|
||||
mov ebx,[sfxramdata]
|
||||
mov [ebx+ecx+65536],ax
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankr8c
|
||||
mov ebx,[sfxramdata]
|
||||
mov al,[ebx+ecx+65536*2]
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankw8c
|
||||
mov ebx,[sfxramdata]
|
||||
mov [ebx+ecx+65536*2],al
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankr16c
|
||||
mov ebx,[sfxramdata]
|
||||
mov ax,[ebx+ecx+65536*2]
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankw16c
|
||||
mov ebx,[sfxramdata]
|
||||
mov [ebx+ecx+65536*2],ax
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankr8d
|
||||
mov ebx,[sfxramdata]
|
||||
mov al,[ebx+ecx+65536*3]
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankw8d
|
||||
mov ebx,[sfxramdata]
|
||||
mov [ebx+ecx+65536*3],al
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankr16d
|
||||
mov ebx,[sfxramdata]
|
||||
mov ax,[ebx+ecx+65536*3]
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM sfxaccessbankw16d
|
||||
mov ebx,[sfxramdata]
|
||||
mov [ebx+ecx+65536*3],ax
|
||||
xor ebx,ebx
|
||||
ret
|
||||
|
||||
NEWSYM SfxProcAsmEnd
|
376
i386/zsnes.asm
376
i386/zsnes.asm
|
@ -1,376 +0,0 @@
|
|||
; Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
;
|
||||
; Super FX assembler emulator code
|
||||
; (c) Copyright 1998, 1999 zsKnight and _Demo_.
|
||||
;
|
||||
; 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.
|
||||
;
|
||||
; ZSNES SuperFX emulation code and wrappers
|
||||
; (C) Copyright 1997-8 zsKnight and _Demo_
|
||||
|
||||
; Used with the kind permission of the copyright holders.
|
||||
;
|
||||
|
||||
%include "macros.mac"
|
||||
|
||||
EXTSYM SfxR1,SfxR2,InitFxTables,SfxSFR,SfxSCMR,initsfxregsw,initsfxregsr
|
||||
EXTSYM SfxPBR,NumberOfOpcodes,SfxCLSR,MainLoop,SfxCROM
|
||||
EXTSYM SfxRomBuffer,SfxRAMMem,SfxLastRamAdr,SfxR0
|
||||
EXTSYM PHnum2writesfxreg, SfxCPB, SfxROMBR, SfxRAMBR, SfxnRamBanks
|
||||
EXTSYM SfxSignZero
|
||||
|
||||
[BITS 32]
|
||||
SECTION .data
|
||||
|
||||
NEWSYM flagnz, dd 0
|
||||
NEWSYM romdata, dd 0 ; rom data (4MB = 4194304)
|
||||
|
||||
NEWSYM regptr, dd 0 ; pointer to registers
|
||||
NEWSYM regptw, dd 0 ; pointer to registers
|
||||
NEWSYM regptra, times 49152 db 0
|
||||
NEWSYM regptwa, times 49152 db 0
|
||||
|
||||
NEWSYM debstop, db 0
|
||||
NEWSYM sfxramdata, dd 0 ; SuperFX Ram Data
|
||||
NEWSYM sfxplottable, dd 0
|
||||
NEWSYM FxTable, times 256 dd 0
|
||||
NEWSYM FxTableA1, times 256 dd 0
|
||||
NEWSYM FxTableA2, times 256 dd 0
|
||||
NEWSYM FxTableA3, times 256 dd 0
|
||||
NEWSYM FxTableb, times 256 dd 0
|
||||
NEWSYM FxTablebA1, times 256 dd 0
|
||||
NEWSYM FxTablebA2, times 256 dd 0
|
||||
NEWSYM FxTablebA3, times 256 dd 0
|
||||
NEWSYM FxTablec, times 256 dd 0
|
||||
NEWSYM FxTablecA1, times 256 dd 0
|
||||
NEWSYM FxTablecA2, times 256 dd 0
|
||||
NEWSYM FxTablecA3, times 256 dd 0
|
||||
NEWSYM FxTabled, times 256 dd 0
|
||||
NEWSYM FxTabledA1, times 256 dd 0
|
||||
NEWSYM FxTabledA2, times 256 dd 0
|
||||
NEWSYM FxTabledA3, times 256 dd 0
|
||||
NEWSYM SfxMemTable, times 256 dd 0
|
||||
NEWSYM fxxand, times 256 dd 0
|
||||
NEWSYM fxbit01, times 256 dd 0
|
||||
NEWSYM fxbit23, times 256 dd 0
|
||||
NEWSYM fxbit45, times 256 dd 0
|
||||
NEWSYM fxbit67, times 256 dd 0
|
||||
NEWSYM PLOTJmpa, times 64 dd 0
|
||||
NEWSYM PLOTJmpb, times 64 dd 0
|
||||
|
||||
NEWSYM NumberOfOpcodes2, dd 350
|
||||
NEWSYM SFXCounter, dd 0
|
||||
NEWSYM SfxAC, dd 0
|
||||
|
||||
;%INCLUDE "fxtable.asm"
|
||||
;%INCLUDE "sfxproc.asm"
|
||||
;%INCLUDE "fxemu2.asm"
|
||||
;%INCLUDE "fxemu2b.asm"
|
||||
;%INCLUDE "fxemu2c.asm"
|
||||
|
||||
;
|
||||
; Snes9x wrapper functions for the zsnes SuperFX code
|
||||
; (C) Copyright 1998 Gary Henderson
|
||||
|
||||
SECTION .data
|
||||
|
||||
EXTSYM SRAM,ROM,RegRAM,SFXPlotTable
|
||||
|
||||
SECTION .text
|
||||
|
||||
NEWSYM StartSFX
|
||||
NEWSYM StartSFXret
|
||||
jmp S9xSuperFXExec
|
||||
|
||||
NEWSYM S9xResetSuperFX
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
push ebp
|
||||
|
||||
mov dword[SfxR1],0
|
||||
mov dword[SfxR2],0
|
||||
mov dword[SfxSignZero],1 ; clear z flag
|
||||
|
||||
mov eax,dword[SRAM]
|
||||
mov dword[sfxramdata],eax
|
||||
mov eax,dword[ROM]
|
||||
mov dword[romdata],eax
|
||||
mov eax,dword[SFXPlotTable]
|
||||
mov dword[sfxplottable],eax
|
||||
|
||||
call InitFxTables
|
||||
|
||||
mov dword[SfxSFR],0
|
||||
mov byte[SfxSCMR],0
|
||||
mov dword[regptr],regptra
|
||||
sub dword[regptr],8000h ; Since register address starts @ 2000h
|
||||
mov dword[regptw],regptwa
|
||||
sub dword[regptw],8000h ; Since register address starts @ 2000h
|
||||
call initsfxregsw
|
||||
call initsfxregsr
|
||||
|
||||
NEWSYM preparesfx
|
||||
mov byte[SFXCounter],0
|
||||
mov esi,[romdata]
|
||||
add esi,07FC0h
|
||||
cmp dword[esi],'FX S'
|
||||
je .yessfxcounter
|
||||
cmp dword[esi],'Stun'
|
||||
jne .nosfxcounter
|
||||
.yessfxcounter
|
||||
mov byte[SFXCounter],1
|
||||
.nosfxcounter
|
||||
|
||||
; make table
|
||||
mov byte[SfxAC],0
|
||||
mov eax,[romdata]
|
||||
cmp dword[eax+02B80h],0AB6CAB6Ch
|
||||
jne .noac
|
||||
mov byte[SfxAC],1
|
||||
.noac
|
||||
call UpdateSFX
|
||||
|
||||
pop ebp
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
NEWSYM S9xSuperFXWriteReg
|
||||
mov eax,dword[esp+4]
|
||||
mov ecx,dword[esp+8]
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
push ebp
|
||||
test dword[regptwa+ecx*4-8000h], ~0
|
||||
jz .skipwrite
|
||||
call dword[regptwa+ecx*4-8000h]
|
||||
.skipwrite:
|
||||
pop ebp
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
NEWSYM S9xSuperFXReadReg
|
||||
mov ecx,dword[esp+4]
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
push ebp
|
||||
test dword[regptra+ecx*4-8000h], ~0
|
||||
jz .skipread
|
||||
call dword[regptra+ecx*4-8000h]
|
||||
.skipread:
|
||||
pop ebp
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
and eax, 255
|
||||
endfx:
|
||||
ret
|
||||
|
||||
EXTSYM SCBRrel,SfxSCBR,SfxCOLR,SfxPOR
|
||||
EXTSYM sfx128lineloc,sfx160lineloc,sfx192lineloc,sfxobjlineloc,sfxclineloc
|
||||
EXTSYM fxbit01pcal,fxbit23pcal,fxbit45pcal,fxbit67pcal
|
||||
|
||||
NEWSYM S9xSuperFXExec
|
||||
test byte[SfxSFR],20h
|
||||
jz endfx
|
||||
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
push ebp
|
||||
|
||||
xor ebx,ebx
|
||||
mov bl,[SfxPBR]
|
||||
mov al,[SfxSCMR]
|
||||
and bl,7Fh
|
||||
cmp bl,70h
|
||||
jae .ram
|
||||
test al,10h
|
||||
jz .noaccess
|
||||
jmp .noram
|
||||
.ram
|
||||
test al,08h
|
||||
jz .noaccess
|
||||
.noram
|
||||
mov eax,[NumberOfOpcodes2]
|
||||
mov [NumberOfOpcodes],eax
|
||||
call MainLoop
|
||||
.noaccess
|
||||
pop ebp
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
ret
|
||||
|
||||
NEWSYM S9xSuperFXPreSaveState
|
||||
mov ecx,dword[SfxCROM]
|
||||
sub dword[SfxRomBuffer],ecx
|
||||
mov ecx,dword[SfxRAMMem]
|
||||
sub dword[SfxLastRamAdr],ecx
|
||||
; Copy num2writesfxreg bytes from SfxR0 to a free area in RegRAM.
|
||||
push ebx
|
||||
mov ecx,SfxR0
|
||||
mov edx,dword[RegRAM]
|
||||
add edx,7000h
|
||||
mov ebx,[PHnum2writesfxreg]
|
||||
.loop
|
||||
mov al,[ecx]
|
||||
mov [edx],al
|
||||
inc ecx
|
||||
inc edx
|
||||
dec ebx
|
||||
jnz .loop
|
||||
pop ebx
|
||||
mov ecx,dword[SfxCROM]
|
||||
add dword[SfxRomBuffer],ecx
|
||||
mov ecx,dword[SfxRAMMem]
|
||||
add dword[SfxLastRamAdr],ecx
|
||||
ret
|
||||
|
||||
NEWSYM S9xSuperFXPostSaveState
|
||||
ret
|
||||
|
||||
NEWSYM S9xSuperFXPostLoadState
|
||||
; Copy num2writesfxreg bytes from a free area in RegRAM to SfxR0
|
||||
push ebx
|
||||
mov ecx,SfxR0
|
||||
mov edx,dword[RegRAM]
|
||||
add edx,7000h
|
||||
mov ebx,[PHnum2writesfxreg]
|
||||
.loop
|
||||
mov al,[edx]
|
||||
mov [ecx],al
|
||||
inc ecx
|
||||
inc edx
|
||||
dec ebx
|
||||
jnz .loop
|
||||
pop ebx
|
||||
xor ecx,ecx
|
||||
mov cl,byte[SfxPBR]
|
||||
mov ecx,dword[SfxMemTable+ecx*4]
|
||||
mov dword[SfxCPB],ecx
|
||||
|
||||
xor ecx,ecx
|
||||
mov cl,byte[SfxROMBR]
|
||||
mov ecx,dword[SfxMemTable+ecx*4]
|
||||
mov dword[SfxCROM],ecx
|
||||
|
||||
xor ecx,ecx
|
||||
mov cl,byte[SfxRAMBR]
|
||||
shl ecx,16
|
||||
add ecx,dword[sfxramdata]
|
||||
mov dword [SfxRAMMem],ecx
|
||||
|
||||
mov ecx,dword[SfxCROM]
|
||||
add dword[SfxRomBuffer],ecx
|
||||
mov ecx,dword[SfxRAMMem]
|
||||
add dword[SfxLastRamAdr],ecx
|
||||
; Fix for mystery zeroing of SfxnRamBanks, allowing junk RAMBR values to be
|
||||
; set in turn causing a crash when the code tries to access the junk RAM bank.
|
||||
mov dword [SfxnRamBanks], 4
|
||||
call UpdateSFX
|
||||
ret
|
||||
|
||||
NEWSYM UpdatePORSCMR
|
||||
push ebx
|
||||
push eax
|
||||
test byte[SfxPOR],10h
|
||||
jnz .objmode
|
||||
mov al,[SfxSCMR]
|
||||
and al,00100100b ; 4 + 32
|
||||
cmp al,4
|
||||
je .lines160
|
||||
cmp al,32
|
||||
je .lines192
|
||||
cmp al,36
|
||||
je .objmode
|
||||
mov eax,[sfx128lineloc]
|
||||
jmp .donelines
|
||||
.lines160
|
||||
mov eax,[sfx160lineloc]
|
||||
jmp .donelines
|
||||
.lines192
|
||||
mov eax,[sfx192lineloc]
|
||||
jmp .donelines
|
||||
.objmode
|
||||
mov eax,[sfxobjlineloc]
|
||||
.donelines
|
||||
mov [sfxclineloc],eax
|
||||
|
||||
mov al,[SfxSCMR]
|
||||
and eax,00000011b
|
||||
mov bl,[SfxPOR]
|
||||
and bl,0Fh
|
||||
shl bl,2
|
||||
or al,bl
|
||||
mov ebx,[PLOTJmpb+eax*4]
|
||||
mov eax,[PLOTJmpa+eax*4]
|
||||
mov dword [FxTable+4Ch*4],eax
|
||||
mov dword [FxTableb+4Ch*4],eax
|
||||
mov dword [FxTablec+4Ch*4],eax
|
||||
mov dword [FxTabled+4Ch*4],ebx
|
||||
pop eax
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
NEWSYM UpdateSCBRCOLR
|
||||
push eax
|
||||
push ebx
|
||||
mov ebx,[SfxSCBR]
|
||||
shl ebx,10
|
||||
add ebx,[sfxramdata]
|
||||
mov [SCBRrel],ebx
|
||||
mov eax,[SfxCOLR]
|
||||
mov ebx,[fxbit01+eax*4]
|
||||
mov [fxbit01pcal],ebx
|
||||
mov ebx,[fxbit23+eax*4]
|
||||
mov [fxbit23pcal],ebx
|
||||
mov ebx,[fxbit45+eax*4]
|
||||
mov [fxbit45pcal],ebx
|
||||
mov ebx,[fxbit67+eax*4]
|
||||
mov [fxbit67pcal],ebx
|
||||
pop ebx
|
||||
pop eax
|
||||
ret
|
||||
|
||||
NEWSYM UpdateCLSR
|
||||
mov dword [NumberOfOpcodes2],350 ; 0FFFFFFFh;350
|
||||
test byte[SfxCLSR],01h
|
||||
jz .nohighsfx
|
||||
mov dword [NumberOfOpcodes2],700 ;700
|
||||
.nohighsfx
|
||||
cmp byte[SFXCounter],1
|
||||
je .noyi
|
||||
mov dword [NumberOfOpcodes2],0FFFFFFFh
|
||||
.noyi
|
||||
ret
|
||||
|
||||
NEWSYM UpdateSFX
|
||||
call UpdatePORSCMR
|
||||
call UpdatePORSCMR
|
||||
call UpdateCLSR
|
||||
ret
|
|
@ -1,92 +0,0 @@
|
|||
; Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
;
|
||||
; Super FX assembler emulator code
|
||||
; (c) Copyright 1998, 1999 zsKnight and _Demo_.
|
||||
;
|
||||
; 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.
|
||||
;
|
||||
; ZSNES SuperFX emulation code and wrappers
|
||||
; (C) Copyright 1997-8 zsKnight and _Demo_
|
||||
|
||||
; Used with the kind permission of the copyright holders.
|
||||
;
|
||||
|
||||
%include "macros.mac"
|
||||
|
||||
EXTSYM InitC4, C4RegFunction, C4ReadReg, C4WriteReg
|
||||
EXTSYM romdata
|
||||
|
||||
[BITS 32]
|
||||
SECTION .data
|
||||
|
||||
NEWSYM C4Ram, dd 0
|
||||
NEWSYM C4RamR, dd 0
|
||||
NEWSYM C4RamW, dd 0
|
||||
|
||||
NEWSYM pressed, dd 0 ; used by C4Edit (unused function)
|
||||
NEWSYM vidbuffer,dd 0 ; used by C4Edit
|
||||
NEWSYM oamram, times 544 db 0 ; Sprite PPU data used by C4 routines
|
||||
|
||||
;
|
||||
; Snes9x wrapper functions for the zsnes C4 code
|
||||
; (C) Copyright 2000 Gary Henderson
|
||||
|
||||
SECTION .data
|
||||
|
||||
EXTSYM ROM,RegRAM
|
||||
|
||||
SECTION .text
|
||||
|
||||
NEWSYM S9xInitC4
|
||||
pushad
|
||||
mov eax,dword[ROM]
|
||||
mov dword[romdata],eax
|
||||
call InitC4
|
||||
; mov eax,dword[RegRAM]
|
||||
; add eax,06000h
|
||||
; mov dword[C4Ram],eax
|
||||
popad
|
||||
ret
|
||||
|
||||
NEWSYM S9xSetC4
|
||||
NEWSYM S9xSetC4RAM
|
||||
mov ecx, dword[esp+8]
|
||||
mov eax, dword[esp+4]
|
||||
and ecx, 0ffffh
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
push ebp
|
||||
sub ecx, 6000h
|
||||
call C4RegFunction
|
||||
pop ebp
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
NEWSYM S9xGetC4
|
||||
NEWSYM S9xGetC4RAM
|
||||
mov ecx, dword[esp+4]
|
||||
xor eax, eax
|
||||
and ecx, 0ffffh
|
||||
sub ecx, 06000h
|
||||
jmp C4ReadReg
|
268
memmap.cpp
268
memmap.cpp
|
@ -1134,21 +1134,11 @@ bool8 CMemory::Init (void)
|
|||
BIOSROM = ROM + 0x300000; // BS
|
||||
BSRAM = ROM + 0x400000; // BS
|
||||
|
||||
#if defined(ZSNES_FX) || defined(ZSNES_C4)
|
||||
::ROM = ROM;
|
||||
::SRAM = SRAM;
|
||||
::RegRAM = FillRAM;
|
||||
#endif
|
||||
|
||||
#ifdef ZSNES_FX
|
||||
SFXPlotTable = ROM + 0x400000;
|
||||
#else
|
||||
SuperFX.pvRegisters = FillRAM + 0x3000;
|
||||
SuperFX.nRamBanks = 2; // Most only use 1. 1=64KB=512Mb, 2=128KB=1024Mb
|
||||
SuperFX.pvRam = SRAM;
|
||||
SuperFX.nRomBanks = (2 * 1024 * 1024) / (32 * 1024);
|
||||
SuperFX.pvRom = (uint8 *) ROM;
|
||||
#endif
|
||||
|
||||
PostRomInitFunc = NULL;
|
||||
|
||||
|
@ -2263,10 +2253,8 @@ void CMemory::InitROM (void)
|
|||
Settings.SETA = 0;
|
||||
Settings.SRTC = FALSE;
|
||||
Settings.BS = FALSE;
|
||||
#ifndef ZSNES_FX
|
||||
|
||||
SuperFX.nRomBanks = CalculatedSize >> 15;
|
||||
#endif
|
||||
SA1.Executing = FALSE;
|
||||
|
||||
//// Parse ROM header and read ROM informatoin
|
||||
|
||||
|
@ -2392,9 +2380,7 @@ void CMemory::InitROM (void)
|
|||
case 0x1520:
|
||||
case 0x1A20:
|
||||
Settings.SuperFX = TRUE;
|
||||
#ifndef ZSNES_FX
|
||||
S9xInitSuperFX();
|
||||
#endif
|
||||
if (ROM[0x7FDA] == 0x33)
|
||||
SRAMSize = ROM[0x7FBD];
|
||||
else
|
||||
|
@ -3493,7 +3479,6 @@ bool8 CMemory::match_id (const char *str)
|
|||
|
||||
void CMemory::ApplyROMFixes (void)
|
||||
{
|
||||
Settings.Shutdown = Settings.ShutdownMaster;
|
||||
Settings.BlockInvalidVRAMAccess = Settings.BlockInvalidVRAMAccessMaster;
|
||||
|
||||
//// Warnings
|
||||
|
@ -3570,6 +3555,7 @@ void CMemory::ApplyROMFixes (void)
|
|||
|
||||
Timings.HDMAStart = SNES_HDMA_START_HC + Settings.HDMATimingHack - 100;
|
||||
Timings.HBlankStart = SNES_HBLANK_START_HC + Timings.HDMAStart - SNES_HDMA_START_HC;
|
||||
Timings.IRQTriggerCycles = 10;
|
||||
|
||||
if (!Settings.DisableGameSpecificHacks)
|
||||
{
|
||||
|
@ -3584,14 +3570,6 @@ void CMemory::ApplyROMFixes (void)
|
|||
|
||||
if (!Settings.DisableGameSpecificHacks)
|
||||
{
|
||||
// Opcode-based emulators cannot escape from "reading $4211/BPL" infinite loop...
|
||||
// The true IRQ can be triggered inside an opcode.
|
||||
if (match_na("TRAVERSE")) // Traverse - Starlight & Prairie
|
||||
{
|
||||
Timings.IRQPendCount = 1;
|
||||
printf("IRQ count hack: %d\n", Timings.IRQPendCount);
|
||||
}
|
||||
|
||||
// An infinite loop reads $4212 and waits V-blank end, whereas VIRQ is set V=0.
|
||||
// If Snes9x succeeds to escape from the loop before jumping into the IRQ handler, the game goes further.
|
||||
// If Snes9x jumps into the IRQ handler before escaping from the loop,
|
||||
|
@ -3601,12 +3579,6 @@ void CMemory::ApplyROMFixes (void)
|
|||
Timings.IRQPendCount = 2;
|
||||
printf("IRQ count hack: %d\n", Timings.IRQPendCount);
|
||||
}
|
||||
|
||||
if (match_na("BATTLE BLAZE"))
|
||||
{
|
||||
Timings.IRQPendCount = 1;
|
||||
printf("IRQ count hack: %d\n", Timings.IRQPendCount);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Settings.DisableGameSpecificHacks)
|
||||
|
@ -3619,242 +3591,6 @@ void CMemory::ApplyROMFixes (void)
|
|||
}
|
||||
}
|
||||
|
||||
//// CPU speed-ups (CPU_Shutdown())
|
||||
|
||||
// Force disabling a speed-up hack
|
||||
// Games which spool sound samples between the SNES and sound CPU using
|
||||
// H-DMA as the sample is playing.
|
||||
if (match_na("EARTHWORM JIM 2") || // Earth Worm Jim 2
|
||||
match_na("PRIMAL RAGE") || // Primal Rage
|
||||
match_na("CLAY FIGHTER") || // Clay Fighter
|
||||
match_na("ClayFighter 2") || // Clay Fighter 2
|
||||
match_na("WeaponLord") || // Weapon Lord
|
||||
match_nn("WAR 2410") || // War 2410
|
||||
match_id("ARF") || // Star Ocean
|
||||
match_id("A4WJ") || // Mini Yonku Shining Scorpion - Let's & Go!!
|
||||
match_nn("NHL") ||
|
||||
match_nc("MADDEN"))
|
||||
{
|
||||
if (Settings.Shutdown)
|
||||
printf("Disabled CPU shutdown hack.\n");
|
||||
Settings.Shutdown = FALSE;
|
||||
}
|
||||
|
||||
// SA-1
|
||||
SA1.WaitAddress = 0xffffffff;
|
||||
SA1.WaitByteAddress1 = NULL;
|
||||
SA1.WaitByteAddress2 = NULL;
|
||||
|
||||
if (Settings.SA1)
|
||||
{
|
||||
// Itoi Shigesato no Bass Tsuri No.1 (J)
|
||||
if (match_id("ZBPJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x0093f1;
|
||||
SA1.WaitByteAddress1 = FillRAM + 0x304a;
|
||||
}
|
||||
|
||||
// Daisenryaku Expert WWII (J)
|
||||
if (match_id("AEVJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x0ed18d;
|
||||
SA1.WaitByteAddress1 = FillRAM + 0x3000;
|
||||
}
|
||||
|
||||
// Derby Jockey 2 (J)
|
||||
if (match_id("A2DJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x008b62;
|
||||
}
|
||||
|
||||
// Dragon Ball Z - Hyper Dimension (J)
|
||||
if (match_id("AZIJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x008083;
|
||||
SA1.WaitByteAddress1 = FillRAM + 0x3020;
|
||||
}
|
||||
|
||||
// SD Gundam G NEXT (J)
|
||||
if (match_id("ZX3J"))
|
||||
{
|
||||
SA1.WaitAddress = 0x0087f2;
|
||||
SA1.WaitByteAddress1 = FillRAM + 0x30c4;
|
||||
}
|
||||
|
||||
// Shougi no Hanamichi (J)
|
||||
if (match_id("AARJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0xc1f85a;
|
||||
SA1.WaitByteAddress1 = SRAM + 0x0c64;
|
||||
SA1.WaitByteAddress2 = SRAM + 0x0c66;
|
||||
}
|
||||
|
||||
// Asahi Shinbun Rensai Katou Hifumi Kudan Shougi Shingiryu (J)
|
||||
if (match_id("A23J"))
|
||||
{
|
||||
SA1.WaitAddress = 0xc25037;
|
||||
SA1.WaitByteAddress1 = SRAM + 0x0c06;
|
||||
SA1.WaitByteAddress2 = SRAM + 0x0c08;
|
||||
}
|
||||
|
||||
// Taikyoku Igo - Idaten (J)
|
||||
if (match_id("AIIJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0xc100be;
|
||||
SA1.WaitByteAddress1 = SRAM + 0x1002;
|
||||
SA1.WaitByteAddress2 = SRAM + 0x1004;
|
||||
}
|
||||
|
||||
// Takemiya Masaki Kudan no Igo Taishou (J)
|
||||
if (match_id("AITJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x0080b7;
|
||||
}
|
||||
|
||||
// J. League '96 Dream Stadium (J)
|
||||
if (match_id("AJ6J"))
|
||||
{
|
||||
SA1.WaitAddress = 0xc0f74a;
|
||||
}
|
||||
|
||||
// Jumpin' Derby (J)
|
||||
if (match_id("AJUJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x00d926;
|
||||
}
|
||||
|
||||
// Kakinoki Shougi (J)
|
||||
if (match_id("AKAJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x00f070;
|
||||
}
|
||||
|
||||
// Hoshi no Kirby 3 (J), Kirby's Dream Land 3 (U)
|
||||
if (match_id("AFJJ") || match_id("AFJE"))
|
||||
{
|
||||
SA1.WaitAddress = 0x0082d4;
|
||||
SA1.WaitByteAddress1 = SRAM + 0x72a4;
|
||||
}
|
||||
|
||||
// Hoshi no Kirby - Super Deluxe (J)
|
||||
if (match_id("AKFJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x008c93;
|
||||
SA1.WaitByteAddress1 = FillRAM + 0x300a;
|
||||
SA1.WaitByteAddress2 = FillRAM + 0x300e;
|
||||
}
|
||||
|
||||
// Kirby Super Star (U)
|
||||
if (match_id("AKFE"))
|
||||
{
|
||||
SA1.WaitAddress = 0x008cb8;
|
||||
SA1.WaitByteAddress1 = FillRAM + 0x300a;
|
||||
SA1.WaitByteAddress2 = FillRAM + 0x300e;
|
||||
}
|
||||
|
||||
// Super Mario RPG (J), (U)
|
||||
if (match_id("ARWJ") || match_id("ARWE"))
|
||||
{
|
||||
SA1.WaitAddress = 0xc0816f;
|
||||
SA1.WaitByteAddress1 = FillRAM + 0x3000;
|
||||
}
|
||||
|
||||
// Marvelous (J)
|
||||
if (match_id("AVRJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x0085f2;
|
||||
SA1.WaitByteAddress1 = FillRAM + 0x3024;
|
||||
}
|
||||
|
||||
// Harukanaru Augusta 3 - Masters New (J)
|
||||
if (match_id("AO3J"))
|
||||
{
|
||||
SA1.WaitAddress = 0x00dddb;
|
||||
SA1.WaitByteAddress1 = FillRAM + 0x37b4;
|
||||
}
|
||||
|
||||
// Jikkyou Oshaberi Parodius (J)
|
||||
if (match_id("AJOJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x8084e5;
|
||||
}
|
||||
|
||||
// Super Bomberman - Panic Bomber W (J)
|
||||
if (match_id("APBJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x00857a;
|
||||
}
|
||||
|
||||
// Pebble Beach no Hatou New - Tournament Edition (J)
|
||||
if (match_id("AONJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x00df33;
|
||||
SA1.WaitByteAddress1 = FillRAM + 0x37b4;
|
||||
}
|
||||
|
||||
// PGA European Tour (U)
|
||||
if (match_id("AEPE"))
|
||||
{
|
||||
SA1.WaitAddress = 0x003700;
|
||||
SA1.WaitByteAddress1 = FillRAM + 0x3102;
|
||||
}
|
||||
|
||||
// PGA Tour 96 (U)
|
||||
if (match_id("A3GE"))
|
||||
{
|
||||
SA1.WaitAddress = 0x003700;
|
||||
SA1.WaitByteAddress1 = FillRAM + 0x3102;
|
||||
}
|
||||
|
||||
// Power Rangers Zeo - Battle Racers (U)
|
||||
if (match_id("A4RE"))
|
||||
{
|
||||
SA1.WaitAddress = 0x009899;
|
||||
SA1.WaitByteAddress1 = FillRAM + 0x3000;
|
||||
}
|
||||
|
||||
// SD F-1 Grand Prix (J)
|
||||
if (match_id("AGFJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x0181bc;
|
||||
}
|
||||
|
||||
// Saikousoku Shikou Shougi Mahjong (J)
|
||||
if (match_id("ASYJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0x00f2cc;
|
||||
SA1.WaitByteAddress1 = SRAM + 0x7ffe;
|
||||
SA1.WaitByteAddress2 = SRAM + 0x7ffc;
|
||||
}
|
||||
|
||||
// Shougi Saikyou II (J)
|
||||
if (match_id("AX2J"))
|
||||
{
|
||||
SA1.WaitAddress = 0x00d675;
|
||||
}
|
||||
|
||||
// Mini Yonku Shining Scorpion - Let's & Go!! (J)
|
||||
if (match_id("A4WJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0xc048be;
|
||||
}
|
||||
|
||||
// Shin Shougi Club (J)
|
||||
if (match_id("AHJJ"))
|
||||
{
|
||||
SA1.WaitAddress = 0xc1002a;
|
||||
SA1.WaitByteAddress1 = SRAM + 0x0806;
|
||||
SA1.WaitByteAddress2 = SRAM + 0x0808;
|
||||
}
|
||||
|
||||
// rest games:
|
||||
// Habu Meijin no Omoshiro Shougi (J)
|
||||
// Hayashi Kaihou Kudan no Igo Taidou (J)
|
||||
// Shougi Saikyou (J)
|
||||
// Super Robot Wars Gaiden (J)
|
||||
// Super Shougi 3 - Kitaihei (J)
|
||||
}
|
||||
|
||||
//// SRAM initial value
|
||||
|
||||
if (!Settings.DisableGameSpecificHacks)
|
||||
|
|
8
memmap.h
8
memmap.h
|
@ -357,14 +357,6 @@ struct SMulti
|
|||
extern CMemory Memory;
|
||||
extern SMulti Multi;
|
||||
|
||||
#if defined(ZSNES_FX) || defined(ZSNES_C4)
|
||||
START_EXTERN_C
|
||||
extern uint8 *ROM;
|
||||
extern uint8 *SRAM;
|
||||
extern uint8 *RegRAM;
|
||||
END_EXTERN_C
|
||||
#endif
|
||||
|
||||
void S9xAutoSaveSRAM (void);
|
||||
bool8 LoadZip(const char *, int32 *, int32 *, uint8 *);
|
||||
|
||||
|
|
282
ppu.cpp
282
ppu.cpp
|
@ -204,9 +204,6 @@ static inline void S9xLatchCounters (bool force)
|
|||
#ifdef DEBUGGER
|
||||
missing.h_v_latch = 1;
|
||||
#endif
|
||||
#if 0 // #ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = CPU.PCAtOpcodeStart;
|
||||
#endif
|
||||
|
||||
PPU.HVBeamCounterLatched = 1;
|
||||
PPU.VBeamPosLatched = (uint16) CPU.V_Counter;
|
||||
|
@ -245,9 +242,6 @@ static inline void S9xTryGunLatch (bool force)
|
|||
#ifdef DEBUGGER
|
||||
missing.h_v_latch = 1;
|
||||
#endif
|
||||
#if 0 // #ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = CPU.PCAtOpcodeStart;
|
||||
#endif
|
||||
|
||||
PPU.HVBeamCounterLatched = 1;
|
||||
PPU.VBeamPosLatched = (uint16) PPU.GunVLatch;
|
||||
|
@ -260,72 +254,16 @@ static inline void S9xTryGunLatch (bool force)
|
|||
}
|
||||
}
|
||||
|
||||
void S9xCheckMissingHTimerPosition (int32 hc)
|
||||
{
|
||||
if (PPU.HTimerPosition == hc)
|
||||
{
|
||||
if (PPU.HTimerEnabled && (!PPU.VTimerEnabled || (CPU.V_Counter == PPU.VTimerPosition)))
|
||||
S9xSetIRQ(PPU_IRQ_SOURCE);
|
||||
else
|
||||
if (PPU.VTimerEnabled && (CPU.V_Counter == PPU.VTimerPosition))
|
||||
S9xSetIRQ(PPU_IRQ_SOURCE);
|
||||
}
|
||||
}
|
||||
|
||||
void S9xCheckMissingHTimerHalt (int32 hc_from, int32 range)
|
||||
{
|
||||
if ((PPU.HTimerPosition >= hc_from) && (PPU.HTimerPosition < (hc_from + range)))
|
||||
{
|
||||
if (PPU.HTimerEnabled && (!PPU.VTimerEnabled || (CPU.V_Counter == PPU.VTimerPosition)))
|
||||
CPU.IRQPending = 1;
|
||||
else
|
||||
if (PPU.VTimerEnabled && (CPU.V_Counter == PPU.VTimerPosition))
|
||||
CPU.IRQPending = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void S9xCheckMissingHTimerRange (int32 hc_from, int32 range)
|
||||
{
|
||||
if ((PPU.HTimerPosition >= hc_from) && (PPU.HTimerPosition < (hc_from + range)))
|
||||
{
|
||||
if (PPU.HTimerEnabled && (!PPU.VTimerEnabled || (CPU.V_Counter == PPU.VTimerPosition)))
|
||||
S9xSetIRQ(PPU_IRQ_SOURCE);
|
||||
else
|
||||
if (PPU.VTimerEnabled && (CPU.V_Counter == PPU.VTimerPosition))
|
||||
S9xSetIRQ(PPU_IRQ_SOURCE);
|
||||
}
|
||||
}
|
||||
|
||||
void S9xUpdateHVTimerPosition (void)
|
||||
{
|
||||
if (PPU.HTimerEnabled)
|
||||
PPU.HTimerPosition = PPU.IRQHBeamPos * ONE_DOT_CYCLE + Timings.IRQTriggerCycles;
|
||||
if (Timings.H_Max == Timings.H_Max_Master) // 1364
|
||||
{
|
||||
#ifdef DEBUGGER
|
||||
missing.hirq_pos = PPU.IRQHBeamPos;
|
||||
#endif
|
||||
if (PPU.IRQHBeamPos != 0)
|
||||
{
|
||||
// IRQ_read
|
||||
PPU.HTimerPosition = PPU.IRQHBeamPos * ONE_DOT_CYCLE;
|
||||
if (Timings.H_Max == Timings.H_Max_Master) // 1364
|
||||
{
|
||||
if (PPU.IRQHBeamPos > 322)
|
||||
PPU.HTimerPosition += (ONE_DOT_CYCLE / 2);
|
||||
if (PPU.IRQHBeamPos > 326)
|
||||
PPU.HTimerPosition += (ONE_DOT_CYCLE / 2);
|
||||
}
|
||||
|
||||
PPU.HTimerPosition += 14;
|
||||
// /IRQ
|
||||
PPU.HTimerPosition += 4;
|
||||
// after CPU executing
|
||||
PPU.HTimerPosition += 6;
|
||||
}
|
||||
else
|
||||
PPU.HTimerPosition = 10 + 4 + 6;
|
||||
if (PPU.IRQHBeamPos > 322)
|
||||
PPU.HTimerPosition += (ONE_DOT_CYCLE / 2);
|
||||
if (PPU.IRQHBeamPos > 326)
|
||||
PPU.HTimerPosition += (ONE_DOT_CYCLE / 2);
|
||||
}
|
||||
else
|
||||
PPU.HTimerPosition = 10 + 4 + 6;
|
||||
|
||||
PPU.VTimerPosition = PPU.IRQVBeamPos;
|
||||
|
||||
|
@ -338,111 +276,9 @@ void S9xUpdateHVTimerPosition (void)
|
|||
PPU.VTimerPosition = 0;
|
||||
}
|
||||
|
||||
if (PPU.HTimerPosition < CPU.Cycles)
|
||||
{
|
||||
switch (CPU.WhichEvent)
|
||||
{
|
||||
case HC_IRQ_1_3_EVENT:
|
||||
CPU.WhichEvent = HC_HDMA_START_EVENT;
|
||||
CPU.NextEvent = Timings.HDMAStart;
|
||||
break;
|
||||
|
||||
case HC_IRQ_3_5_EVENT:
|
||||
CPU.WhichEvent = HC_HCOUNTER_MAX_EVENT;
|
||||
CPU.NextEvent = Timings.H_Max;
|
||||
break;
|
||||
|
||||
case HC_IRQ_5_7_EVENT:
|
||||
CPU.WhichEvent = HC_HDMA_INIT_EVENT;
|
||||
CPU.NextEvent = Timings.HDMAInit;
|
||||
break;
|
||||
|
||||
case HC_IRQ_7_9_EVENT:
|
||||
CPU.WhichEvent = HC_RENDER_EVENT;
|
||||
CPU.NextEvent = Timings.RenderPos;
|
||||
break;
|
||||
|
||||
case HC_IRQ_9_A_EVENT:
|
||||
CPU.WhichEvent = HC_WRAM_REFRESH_EVENT;
|
||||
CPU.NextEvent = Timings.WRAMRefreshPos;
|
||||
break;
|
||||
|
||||
case HC_IRQ_A_1_EVENT:
|
||||
CPU.WhichEvent = HC_HBLANK_START_EVENT;
|
||||
CPU.NextEvent = Timings.HBlankStart;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
if ((PPU.HTimerPosition < CPU.NextEvent) || (!(CPU.WhichEvent & 1) && (PPU.HTimerPosition == CPU.NextEvent)))
|
||||
{
|
||||
CPU.NextEvent = PPU.HTimerPosition;
|
||||
|
||||
switch (CPU.WhichEvent)
|
||||
{
|
||||
case HC_HDMA_START_EVENT:
|
||||
CPU.WhichEvent = HC_IRQ_1_3_EVENT;
|
||||
break;
|
||||
|
||||
case HC_HCOUNTER_MAX_EVENT:
|
||||
CPU.WhichEvent = HC_IRQ_3_5_EVENT;
|
||||
break;
|
||||
|
||||
case HC_HDMA_INIT_EVENT:
|
||||
CPU.WhichEvent = HC_IRQ_5_7_EVENT;
|
||||
break;
|
||||
|
||||
case HC_RENDER_EVENT:
|
||||
CPU.WhichEvent = HC_IRQ_7_9_EVENT;
|
||||
break;
|
||||
|
||||
case HC_WRAM_REFRESH_EVENT:
|
||||
CPU.WhichEvent = HC_IRQ_9_A_EVENT;
|
||||
break;
|
||||
|
||||
case HC_HBLANK_START_EVENT:
|
||||
CPU.WhichEvent = HC_IRQ_A_1_EVENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (CPU.WhichEvent)
|
||||
{
|
||||
case HC_IRQ_1_3_EVENT:
|
||||
CPU.WhichEvent = HC_HDMA_START_EVENT;
|
||||
CPU.NextEvent = Timings.HDMAStart;
|
||||
break;
|
||||
|
||||
case HC_IRQ_3_5_EVENT:
|
||||
CPU.WhichEvent = HC_HCOUNTER_MAX_EVENT;
|
||||
CPU.NextEvent = Timings.H_Max;
|
||||
break;
|
||||
|
||||
case HC_IRQ_5_7_EVENT:
|
||||
CPU.WhichEvent = HC_HDMA_INIT_EVENT;
|
||||
CPU.NextEvent = Timings.HDMAInit;
|
||||
break;
|
||||
|
||||
case HC_IRQ_7_9_EVENT:
|
||||
CPU.WhichEvent = HC_RENDER_EVENT;
|
||||
CPU.NextEvent = Timings.RenderPos;
|
||||
break;
|
||||
|
||||
case HC_IRQ_9_A_EVENT:
|
||||
CPU.WhichEvent = HC_WRAM_REFRESH_EVENT;
|
||||
CPU.NextEvent = Timings.WRAMRefreshPos;
|
||||
break;
|
||||
|
||||
case HC_IRQ_A_1_EVENT:
|
||||
CPU.WhichEvent = HC_HBLANK_START_EVENT;
|
||||
CPU.NextEvent = Timings.HBlankStart;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUGGER
|
||||
S9xTraceFormattedMessage("--- IRQ settings: H:%d V:%d (%04d, %03d)", PPU.HTimerEnabled, PPU.VTimerEnabled, PPU.HTimerPosition, PPU.VTimerPosition);
|
||||
S9xTraceFormattedMessage("--- IRQ Timer set HTimer:%d Pos:%04d VTimer:%d Pos:%03d",
|
||||
PPU.HTimerEnabled, PPU.HTimerPosition, PPU.VTimerEnabled, PPU.VTimerPosition);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -787,7 +623,7 @@ void S9xSetPPU (uint8 Byte, uint16 Address)
|
|||
case 0x2116: // VMADDL
|
||||
PPU.VMA.Address &= 0xff00;
|
||||
PPU.VMA.Address |= Byte;
|
||||
#ifdef CORRECT_VRAM_READS
|
||||
|
||||
if (PPU.VMA.FullGraphicCount)
|
||||
{
|
||||
uint32 addr = PPU.VMA.Address;
|
||||
|
@ -797,15 +633,13 @@ void S9xSetPPU (uint8 Byte, uint16 Address)
|
|||
}
|
||||
else
|
||||
IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & 0xffff));
|
||||
#else
|
||||
IPPU.FirstVRAMRead = TRUE;
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case 0x2117: // VMADDH
|
||||
PPU.VMA.Address &= 0x00ff;
|
||||
PPU.VMA.Address |= Byte << 8;
|
||||
#ifdef CORRECT_VRAM_READS
|
||||
|
||||
if (PPU.VMA.FullGraphicCount)
|
||||
{
|
||||
uint32 addr = PPU.VMA.Address;
|
||||
|
@ -815,22 +649,14 @@ void S9xSetPPU (uint8 Byte, uint16 Address)
|
|||
}
|
||||
else
|
||||
IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & 0xffff));
|
||||
#else
|
||||
IPPU.FirstVRAMRead = TRUE;
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case 0x2118: // VMDATAL
|
||||
#ifndef CORRECT_VRAM_READS
|
||||
IPPU.FirstVRAMRead = TRUE;
|
||||
#endif
|
||||
REGISTER_2118(Byte);
|
||||
break;
|
||||
|
||||
case 0x2119: // VMDATAH
|
||||
#ifndef CORRECT_VRAM_READS
|
||||
IPPU.FirstVRAMRead = TRUE;
|
||||
#endif
|
||||
REGISTER_2119(Byte);
|
||||
break;
|
||||
|
||||
|
@ -1382,7 +1208,6 @@ uint8 S9xGetPPU (uint16 Address)
|
|||
return (PPU.OpenBus1 = byte);
|
||||
|
||||
case 0x2139: // VMDATALREAD
|
||||
#ifdef CORRECT_VRAM_READS
|
||||
byte = IPPU.VRAMReadBuffer & 0xff;
|
||||
if (!PPU.VMA.High)
|
||||
{
|
||||
|
@ -1398,33 +1223,13 @@ uint8 S9xGetPPU (uint16 Address)
|
|||
|
||||
PPU.VMA.Address += PPU.VMA.Increment;
|
||||
}
|
||||
#else
|
||||
if (IPPU.FirstVRAMRead)
|
||||
byte = Memory.VRAM[(PPU.VMA.Address << 1) & 0xffff];
|
||||
else
|
||||
if (PPU.VMA.FullGraphicCount)
|
||||
{
|
||||
uint32 addr = PPU.VMA.Address - 1;
|
||||
uint32 rem = addr & PPU.VMA.Mask1;
|
||||
uint32 address = (addr & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
|
||||
byte = Memory.VRAM[((address << 1) - 2) & 0xffff];
|
||||
}
|
||||
else
|
||||
byte = Memory.VRAM[((PPU.VMA.Address << 1) - 2) & 0xffff];
|
||||
|
||||
if (!PPU.VMA.High)
|
||||
{
|
||||
PPU.VMA.Address += PPU.VMA.Increment;
|
||||
IPPU.FirstVRAMRead = FALSE;
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUGGER
|
||||
missing.vram_read = 1;
|
||||
#endif
|
||||
return (PPU.OpenBus1 = byte);
|
||||
|
||||
case 0x213a: // VMDATAHREAD
|
||||
#ifdef CORRECT_VRAM_READS
|
||||
byte = (IPPU.VRAMReadBuffer >> 8) & 0xff;
|
||||
if (PPU.VMA.High)
|
||||
{
|
||||
|
@ -1440,26 +1245,6 @@ uint8 S9xGetPPU (uint16 Address)
|
|||
|
||||
PPU.VMA.Address += PPU.VMA.Increment;
|
||||
}
|
||||
#else
|
||||
if (IPPU.FirstVRAMRead)
|
||||
byte = Memory.VRAM[((PPU.VMA.Address << 1) + 1) & 0xffff];
|
||||
else
|
||||
if (PPU.VMA.FullGraphicCount)
|
||||
{
|
||||
uint32 addr = PPU.VMA.Address - 1;
|
||||
uint32 rem = addr & PPU.VMA.Mask1;
|
||||
uint32 address = (addr & ~PPU.VMA.Mask1) + (rem >> PPU.VMA.Shift) + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
|
||||
byte = Memory.VRAM[((address << 1) - 1) & 0xffff];
|
||||
}
|
||||
else
|
||||
byte = Memory.VRAM[((PPU.VMA.Address << 1) - 1) & 0xffff];
|
||||
|
||||
if (PPU.VMA.High)
|
||||
{
|
||||
PPU.VMA.Address += PPU.VMA.Increment;
|
||||
IPPU.FirstVRAMRead = FALSE;
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUGGER
|
||||
missing.vram_read = 1;
|
||||
#endif
|
||||
|
@ -1697,14 +1482,14 @@ void S9xSetCPU (uint8 Byte, uint16 Address)
|
|||
else
|
||||
PPU.HTimerEnabled = FALSE;
|
||||
|
||||
S9xUpdateHVTimerPosition();
|
||||
if (CPU.IRQLine && !PPU.HTimerEnabled && PPU.VTimerEnabled)
|
||||
CPU.IRQTransition = TRUE;
|
||||
|
||||
// The case that IRQ will trigger in an instruction such as STA $4200.
|
||||
// FIXME: not true but good enough for Snes9x, I think.
|
||||
S9xCheckMissingHTimerRange(CPU.PrevCycles, CPU.Cycles - CPU.PrevCycles);
|
||||
|
||||
if (!(Byte & 0x30))
|
||||
S9xClearIRQ(PPU_IRQ_SOURCE);
|
||||
if (!PPU.HTimerEnabled && !PPU.VTimerEnabled)
|
||||
{
|
||||
CPU.IRQLine = FALSE;
|
||||
CPU.IRQTransition = FALSE;
|
||||
}
|
||||
|
||||
// NMI can trigger immediately during VBlank as long as NMI_read ($4210) wasn't cleard.
|
||||
if ((Byte & 0x80) && !(Memory.FillRAM[0x4200] & 0x80) &&
|
||||
|
@ -1712,7 +1497,7 @@ void S9xSetCPU (uint8 Byte, uint16 Address)
|
|||
{
|
||||
// FIXME: triggered at HC+=6, checked just before the final CPU cycle,
|
||||
// then, when to call S9xOpcode_NMI()?
|
||||
CPU.Flags |= NMI_FLAG;
|
||||
CPU.NMILine = TRUE;
|
||||
Timings.NMITriggerPos = CPU.Cycles + 6 + 6;
|
||||
}
|
||||
|
||||
|
@ -1826,8 +1611,6 @@ void S9xSetCPU (uint8 Byte, uint16 Address)
|
|||
case 0x420c: // HDMAEN
|
||||
if (CPU.InDMAorHDMA)
|
||||
return;
|
||||
if (Settings.DisableHDMA)
|
||||
Byte = 0;
|
||||
Memory.FillRAM[0x420c] = Byte;
|
||||
// Yoshi's Island, Genjyu Ryodan, Mortal Kombat, Tales of Phantasia
|
||||
PPU.HDMA = Byte & ~PPU.HDMAEnded;
|
||||
|
@ -1854,17 +1637,7 @@ void S9xSetCPU (uint8 Byte, uint16 Address)
|
|||
break;
|
||||
|
||||
case 0x4210: // RDNMI
|
||||
#if 0
|
||||
Memory.FillRAM[0x4210] = Model->_5A22;
|
||||
#endif
|
||||
return;
|
||||
|
||||
case 0x4211: // TIMEUP
|
||||
#if 0
|
||||
S9xClearIRQ(PPU_IRQ_SOURCE);
|
||||
#endif
|
||||
return;
|
||||
|
||||
case 0x4212: // HVBJOY
|
||||
case 0x4213: // RDIO
|
||||
case 0x4214: // RDDIVL
|
||||
|
@ -1980,22 +1753,17 @@ uint8 S9xGetCPU (uint16 Address)
|
|||
switch (Address)
|
||||
{
|
||||
case 0x4210: // RDNMI
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = CPU.PBPCAtOpcodeStart;
|
||||
#endif
|
||||
byte = Memory.FillRAM[0x4210];
|
||||
Memory.FillRAM[0x4210] = Model->_5A22;
|
||||
return ((byte & 0x80) | (OpenBus & 0x70) | Model->_5A22);
|
||||
|
||||
case 0x4211: // TIMEUP
|
||||
byte = (CPU.IRQActive & PPU_IRQ_SOURCE) ? 0x80 : 0;
|
||||
S9xClearIRQ(PPU_IRQ_SOURCE);
|
||||
byte = CPU.IRQLine ? 0x80 : 0;
|
||||
CPU.IRQLine = FALSE;
|
||||
CPU.IRQTransition = FALSE;
|
||||
return (byte | (OpenBus & 0x7f));
|
||||
|
||||
case 0x4212: // HVBJOY
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = CPU.PBPCAtOpcodeStart;
|
||||
#endif
|
||||
return (REGISTER_4212() | (OpenBus & 0x3e));
|
||||
|
||||
case 0x4213: // RDIO
|
||||
|
@ -2189,11 +1957,7 @@ void S9xSoftResetPPU (void)
|
|||
ZeroMemory(IPPU.TileCached[TILE_2BIT_ODD], MAX_2BIT_TILES);
|
||||
ZeroMemory(IPPU.TileCached[TILE_4BIT_EVEN], MAX_4BIT_TILES);
|
||||
ZeroMemory(IPPU.TileCached[TILE_4BIT_ODD], MAX_4BIT_TILES);
|
||||
#ifdef CORRECT_VRAM_READS
|
||||
IPPU.VRAMReadBuffer = 0; // XXX: FIXME: anything better?
|
||||
#else
|
||||
IPPU.FirstVRAMRead = FALSE;
|
||||
#endif
|
||||
IPPU.Interlace = FALSE;
|
||||
IPPU.InterlaceOBJ = FALSE;
|
||||
IPPU.DoubleWidthPixels = FALSE;
|
||||
|
|
12
ppu.h
12
ppu.h
|
@ -197,11 +197,6 @@
|
|||
#define CLIP_XOR 2
|
||||
#define CLIP_XNOR 3
|
||||
|
||||
#define PPU_IRQ_SOURCE (1 << 1)
|
||||
#define GSU_IRQ_SOURCE (1 << 2)
|
||||
#define SA1_IRQ_SOURCE (1 << 7)
|
||||
#define SA1_DMA_IRQ_SOURCE (1 << 5)
|
||||
|
||||
struct ClipData
|
||||
{
|
||||
uint8 Count;
|
||||
|
@ -218,11 +213,7 @@ struct InternalPPU
|
|||
bool8 DirectColourMapsNeedRebuild;
|
||||
uint8 *TileCache[7];
|
||||
uint8 *TileCached[7];
|
||||
#ifdef CORRECT_VRAM_READS
|
||||
uint16 VRAMReadBuffer;
|
||||
#else
|
||||
bool8 FirstVRAMRead;
|
||||
#endif
|
||||
bool8 Interlace;
|
||||
bool8 InterlaceOBJ;
|
||||
bool8 PseudoHires;
|
||||
|
@ -385,9 +376,6 @@ uint8 S9xGetPPU (uint16);
|
|||
void S9xSetCPU (uint8, uint16);
|
||||
uint8 S9xGetCPU (uint16);
|
||||
void S9xUpdateHVTimerPosition (void);
|
||||
void S9xCheckMissingHTimerPosition (int32);
|
||||
void S9xCheckMissingHTimerRange (int32, int32);
|
||||
void S9xCheckMissingHTimerHalt (int32, int32);
|
||||
void S9xFixColourBrightness (void);
|
||||
void S9xDoAutoJoypad (void);
|
||||
|
||||
|
|
559
sa1.cpp
559
sa1.cpp
|
@ -180,7 +180,6 @@
|
|||
|
||||
uint8 SA1OpenBus;
|
||||
|
||||
static void S9xSA1Reset (void);
|
||||
static void S9xSA1SetBWRAMMemMap (uint8);
|
||||
static void S9xSetSA1MemMap (uint32, uint8);
|
||||
static void S9xSA1CharConv2 (void);
|
||||
|
@ -190,31 +189,37 @@ static void S9xSA1ReadVariableLengthData (bool8, bool8);
|
|||
|
||||
void S9xSA1Init (void)
|
||||
{
|
||||
SA1.IRQActive = FALSE;
|
||||
SA1.WaitingForInterrupt = FALSE;
|
||||
SA1.Waiting = FALSE;
|
||||
SA1.Cycles = 0;
|
||||
SA1.PrevCycles = 0;
|
||||
SA1.Flags = 0;
|
||||
SA1.Executing = FALSE;
|
||||
SA1.WaitingForInterrupt = FALSE;
|
||||
|
||||
memset(&Memory.FillRAM[0x2200], 0, 0x200);
|
||||
Memory.FillRAM[0x2200] = 0x20;
|
||||
Memory.FillRAM[0x2220] = 0x00;
|
||||
Memory.FillRAM[0x2221] = 0x01;
|
||||
Memory.FillRAM[0x2222] = 0x02;
|
||||
Memory.FillRAM[0x2223] = 0x03;
|
||||
Memory.FillRAM[0x2228] = 0xff;
|
||||
Memory.FillRAM[0x2228] = 0x0f;
|
||||
|
||||
SA1.in_char_dma = FALSE;
|
||||
SA1.TimerIRQLastState = FALSE;
|
||||
SA1.HTimerIRQPos = 0;
|
||||
SA1.VTimerIRQPos = 0;
|
||||
SA1.HCounter = 0;
|
||||
SA1.VCounter = 0;
|
||||
SA1.PrevHCounter = 0;
|
||||
SA1.arithmetic_op = 0;
|
||||
SA1.op1 = 0;
|
||||
SA1.op2 = 0;
|
||||
SA1.arithmetic_op = 0;
|
||||
SA1.sum = 0;
|
||||
SA1.overflow = FALSE;
|
||||
SA1.S9xOpcodes = NULL;
|
||||
}
|
||||
SA1.VirtualBitmapFormat = 0;
|
||||
SA1.variable_bit_pos = 0;
|
||||
|
||||
static void S9xSA1Reset (void)
|
||||
{
|
||||
SA1Registers.PBPC = 0;
|
||||
SA1Registers.PB = 0;
|
||||
SA1Registers.PCw = Memory.FillRAM[0x2203] | (Memory.FillRAM[0x2204] << 8);
|
||||
SA1Registers.PCw = 0;
|
||||
SA1Registers.D.W = 0;
|
||||
SA1Registers.DB = 0;
|
||||
SA1Registers.SH = 1;
|
||||
|
@ -228,17 +233,20 @@ static void S9xSA1Reset (void)
|
|||
SA1SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation);
|
||||
SA1ClearFlags(Decimal);
|
||||
|
||||
SA1.WaitingForInterrupt = FALSE;
|
||||
SA1.PCBase = NULL;
|
||||
S9xSA1SetPCBase(SA1Registers.PBPC);
|
||||
SA1.MemSpeed = SLOW_ONE_CYCLE;
|
||||
SA1.MemSpeedx2 = SLOW_ONE_CYCLE * 2;
|
||||
|
||||
SA1.S9xOpcodes = S9xSA1OpcodesM1X1;
|
||||
SA1.S9xOpLengths = S9xOpLengthsM1X1;
|
||||
|
||||
S9xSA1SetPCBase(SA1Registers.PBPC);
|
||||
|
||||
S9xSA1UnpackStatus();
|
||||
S9xSA1FixCycles();
|
||||
SA1.Executing = TRUE;
|
||||
|
||||
SA1.BWRAM = Memory.SRAM;
|
||||
Memory.FillRAM[0x2225] = 0;
|
||||
|
||||
CPU.IRQExternal = FALSE;
|
||||
}
|
||||
|
||||
static void S9xSA1SetBWRAMMemMap (uint8 val)
|
||||
|
@ -280,23 +288,6 @@ void S9xSA1PostLoadState (void)
|
|||
SA1.VirtualBitmapFormat = (Memory.FillRAM[0x223f] & 0x80) ? 2 : 4;
|
||||
Memory.BWRAM = Memory.SRAM + (Memory.FillRAM[0x2224] & 7) * 0x2000;
|
||||
S9xSA1SetBWRAMMemMap(Memory.FillRAM[0x2225]);
|
||||
|
||||
SA1.Waiting = (Memory.FillRAM[0x2200] & 0x60) != 0;
|
||||
SA1.Executing = !SA1.Waiting;
|
||||
}
|
||||
|
||||
void S9xSA1ExecuteDuringSleep (void)
|
||||
{
|
||||
#if 0
|
||||
if (SA1.Executing)
|
||||
{
|
||||
while (CPU.Cycles < CPU.NextEvent)
|
||||
{
|
||||
S9xSA1MainLoop();
|
||||
CPU.Cycles += TWO_CYCLES * 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void S9xSetSA1MemMap (uint32 which1, uint8 map)
|
||||
|
@ -326,31 +317,48 @@ uint8 S9xGetSA1 (uint32 address)
|
|||
{
|
||||
switch (address)
|
||||
{
|
||||
case 0x2300:
|
||||
return ((uint8) ((Memory.FillRAM[0x2209] & 0x5f) | (CPU.IRQActive & (SA1_IRQ_SOURCE | SA1_DMA_IRQ_SOURCE))));
|
||||
case 0x2300: // S-CPU flag
|
||||
return ((Memory.FillRAM[0x2209] & 0x5f) | (Memory.FillRAM[0x2300] & 0xa0));
|
||||
|
||||
case 0x2301:
|
||||
return ((Memory.FillRAM[0x2200] & 0xf) | (Memory.FillRAM[0x2301] & 0xf0));
|
||||
case 0x2301: // SA-1 flag
|
||||
return ((Memory.FillRAM[0x2200] & 0x0f) | (Memory.FillRAM[0x2301] & 0xf0));
|
||||
|
||||
case 0x2306:
|
||||
case 0x2302: // H counter (L)
|
||||
SA1.HTimerIRQPos = SA1.HCounter / ONE_DOT_CYCLE;
|
||||
SA1.VTimerIRQPos = SA1.VCounter;
|
||||
return ((uint8) SA1.HTimerIRQPos);
|
||||
|
||||
case 0x2303: // H counter (H)
|
||||
return ((uint8) (SA1.HTimerIRQPos >> 8));
|
||||
|
||||
case 0x2304: // V counter (L)
|
||||
return ((uint8) SA1.VTimerIRQPos);
|
||||
|
||||
case 0x2305: // V counter (H)
|
||||
return ((uint8) (SA1.VTimerIRQPos >> 8));
|
||||
|
||||
case 0x2306: // arithmetic result (LLL)
|
||||
return ((uint8) SA1.sum);
|
||||
|
||||
case 0x2307:
|
||||
case 0x2307: // arithmetic result (LLH)
|
||||
return ((uint8) (SA1.sum >> 8));
|
||||
|
||||
case 0x2308:
|
||||
case 0x2308: // arithmetic result (LHL)
|
||||
return ((uint8) (SA1.sum >> 16));
|
||||
|
||||
case 0x2309:
|
||||
case 0x2309: // arithmetic result (LLH)
|
||||
return ((uint8) (SA1.sum >> 24));
|
||||
|
||||
case 0x230a:
|
||||
case 0x230a: // arithmetic result (HLL)
|
||||
return ((uint8) (SA1.sum >> 32));
|
||||
|
||||
case 0x230c:
|
||||
case 0x230b: // arithmetic overflow
|
||||
return (SA1.overflow ? 0x80 : 0);
|
||||
|
||||
case 0x230c: // variable-length data read port (L)
|
||||
return (Memory.FillRAM[0x230c]);
|
||||
|
||||
case 0x230d:
|
||||
case 0x230d: // variable-length data read port (H)
|
||||
{
|
||||
uint8 byte = Memory.FillRAM[0x230d];
|
||||
|
||||
|
@ -360,8 +368,10 @@ uint8 S9xGetSA1 (uint32 address)
|
|||
return (byte);
|
||||
}
|
||||
|
||||
case 0x230e: // version code register
|
||||
return (0x01);
|
||||
|
||||
default:
|
||||
//printf("R: %04x\n", address);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -372,337 +382,279 @@ void S9xSetSA1 (uint8 byte, uint32 address)
|
|||
{
|
||||
switch (address)
|
||||
{
|
||||
case 0x2200:
|
||||
SA1.Waiting = (byte & 0x60) != 0;
|
||||
//SA1.Executing = !SA1.Waiting && SA1.S9xOpcodes;
|
||||
case 0x2200: // SA-1 control
|
||||
#ifdef DEBUGGER
|
||||
if (byte & 0x60)
|
||||
printf("SA-1 sleep\n");
|
||||
#endif
|
||||
|
||||
if (!(byte & 0x20) && (Memory.FillRAM[0x2200] & 0x20))
|
||||
S9xSA1Reset();
|
||||
// SA-1 reset
|
||||
if (!(byte & 0x80) && (Memory.FillRAM[0x2200] & 0x20))
|
||||
{
|
||||
#ifdef DEBUGGER
|
||||
printf("SA-1 reset\n");
|
||||
#endif
|
||||
SA1Registers.PBPC = 0;
|
||||
SA1Registers.PB = 0;
|
||||
SA1Registers.PCw = Memory.FillRAM[0x2203] | (Memory.FillRAM[0x2204] << 8);
|
||||
S9xSA1SetPCBase(SA1Registers.PBPC);
|
||||
}
|
||||
|
||||
// SA-1 IRQ control
|
||||
if (byte & 0x80)
|
||||
{
|
||||
Memory.FillRAM[0x2301] |= 0x80;
|
||||
if (Memory.FillRAM[0x220a] & 0x80)
|
||||
{
|
||||
SA1.Flags |= IRQ_FLAG;
|
||||
SA1.IRQActive |= SNES_IRQ_SOURCE;
|
||||
SA1.Executing = !SA1.Waiting && SA1.S9xOpcodes;
|
||||
}
|
||||
Memory.FillRAM[0x220b] &= ~0x80;
|
||||
}
|
||||
|
||||
// SA-1 NMI control
|
||||
if (byte & 0x10)
|
||||
{
|
||||
Memory.FillRAM[0x2301] |= 0x10;
|
||||
if (Memory.FillRAM[0x220a] & 0x10)
|
||||
Memory.FillRAM[0x220b] &= ~0x10;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x2201: // S-CPU interrupt enable
|
||||
// S-CPU IRQ enable
|
||||
if (((byte ^ Memory.FillRAM[0x2201]) & 0x80) && (Memory.FillRAM[0x2300] & byte & 0x80))
|
||||
{
|
||||
Memory.FillRAM[0x2202] &= ~0x80;
|
||||
CPU.IRQExternal = TRUE;
|
||||
}
|
||||
|
||||
// S-CPU CHDMA IRQ enable
|
||||
if (((byte ^ Memory.FillRAM[0x2201]) & 0x20) && (Memory.FillRAM[0x2300] & byte & 0x20))
|
||||
{
|
||||
Memory.FillRAM[0x2202] &= ~0x20;
|
||||
CPU.IRQExternal = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x2202: // S-CPU interrupt clear
|
||||
// S-CPU IRQ clear
|
||||
if (byte & 0x80)
|
||||
Memory.FillRAM[0x2300] &= ~0x80;
|
||||
|
||||
// S-CPU CHDMA IRQ clear
|
||||
if (byte & 0x20)
|
||||
Memory.FillRAM[0x2300] &= ~0x20;
|
||||
|
||||
if (!(Memory.FillRAM[0x2300] & 0xa0))
|
||||
CPU.IRQExternal = FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case 0x2203: // SA-1 reset vector (L)
|
||||
case 0x2204: // SA-1 reset vector (H)
|
||||
case 0x2205: // SA-1 NMI vector (L)
|
||||
case 0x2206: // SA-1 NMI vector (H)
|
||||
case 0x2207: // SA-1 IRQ vector (L)
|
||||
case 0x2208: // SA-1 IRQ vector (H)
|
||||
break;
|
||||
|
||||
case 0x2209: // S-CPU control
|
||||
// 0x40: S-CPU IRQ overwrite
|
||||
// 0x20: S-CPU NMI overwrite
|
||||
|
||||
// S-CPU IRQ control
|
||||
if (byte & 0x80)
|
||||
{
|
||||
Memory.FillRAM[0x2300] |= 0x80;
|
||||
if (Memory.FillRAM[0x2201] & 0x80)
|
||||
{
|
||||
SA1.Flags |= NMI_FLAG;
|
||||
SA1.Executing = !SA1.Waiting && SA1.S9xOpcodes;
|
||||
Memory.FillRAM[0x2202] &= ~0x80;
|
||||
CPU.IRQExternal = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x2201:
|
||||
if (((byte ^ Memory.FillRAM[0x2201]) & 0x80) && (Memory.FillRAM[0x2300] & byte & 0x80))
|
||||
S9xSetIRQ(SA1_IRQ_SOURCE);
|
||||
|
||||
if (((byte ^ Memory.FillRAM[0x2201]) & 0x20) && (Memory.FillRAM[0x2300] & byte & 0x20))
|
||||
S9xSetIRQ(SA1_DMA_IRQ_SOURCE);
|
||||
|
||||
break;
|
||||
|
||||
case 0x2202:
|
||||
if (byte & 0x80)
|
||||
{
|
||||
Memory.FillRAM[0x2300] &= ~0x80;
|
||||
S9xClearIRQ(SA1_IRQ_SOURCE);
|
||||
}
|
||||
|
||||
if (byte & 0x20)
|
||||
{
|
||||
Memory.FillRAM[0x2300] &= ~0x20;
|
||||
S9xClearIRQ(SA1_DMA_IRQ_SOURCE);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x2203:
|
||||
//printf("SA1 reset vector: %04x\n", byte | (Memory.FillRAM[0x2204] << 8));
|
||||
break;
|
||||
|
||||
case 0x2204:
|
||||
//printf("SA1 reset vector: %04x\n", (byte << 8) | Memory.FillRAM[0x2203]);
|
||||
break;
|
||||
|
||||
case 0x2205:
|
||||
//printf("SA1 NMI vector: %04x\n", byte | (Memory.FillRAM[0x2206] << 8));
|
||||
break;
|
||||
|
||||
case 0x2206:
|
||||
//printf("SA1 NMI vector: %04x\n", (byte << 8) | Memory.FillRAM[0x2205]);
|
||||
break;
|
||||
|
||||
case 0x2207:
|
||||
//printf("SA1 IRQ vector: %04x\n", byte | (Memory.FillRAM[0x2208] << 8));
|
||||
break;
|
||||
|
||||
case 0x2208:
|
||||
//printf("SA1 IRQ vector: %04x\n", (byte << 8) | Memory.FillRAM[0x2207]);
|
||||
break;
|
||||
|
||||
case 0x2209:
|
||||
Memory.FillRAM[0x2209] = byte;
|
||||
|
||||
if (byte & 0x80)
|
||||
Memory.FillRAM[0x2300] |= 0x80;
|
||||
|
||||
if (byte & Memory.FillRAM[0x2201] & 0x80)
|
||||
S9xSetIRQ(SA1_IRQ_SOURCE);
|
||||
|
||||
break;
|
||||
|
||||
case 0x220a:
|
||||
case 0x220a: // SA-1 interrupt enable
|
||||
// SA-1 IRQ enable
|
||||
if (((byte ^ Memory.FillRAM[0x220a]) & 0x80) && (Memory.FillRAM[0x2301] & byte & 0x80))
|
||||
{
|
||||
SA1.Flags |= IRQ_FLAG;
|
||||
SA1.IRQActive |= SNES_IRQ_SOURCE;
|
||||
//SA1.Executing = !SA1.Waiting;
|
||||
}
|
||||
Memory.FillRAM[0x220b] &= ~0x80;
|
||||
|
||||
// SA-1 timer IRQ enable
|
||||
if (((byte ^ Memory.FillRAM[0x220a]) & 0x40) && (Memory.FillRAM[0x2301] & byte & 0x40))
|
||||
{
|
||||
SA1.Flags |= IRQ_FLAG;
|
||||
SA1.IRQActive |= TIMER_IRQ_SOURCE;
|
||||
//SA1.Executing = !SA1.Waiting;
|
||||
}
|
||||
Memory.FillRAM[0x220b] &= ~0x40;
|
||||
|
||||
// SA-1 DMA IRQ enable
|
||||
if (((byte ^ Memory.FillRAM[0x220a]) & 0x20) && (Memory.FillRAM[0x2301] & byte & 0x20))
|
||||
{
|
||||
SA1.Flags |= IRQ_FLAG;
|
||||
SA1.IRQActive |= DMA_IRQ_SOURCE;
|
||||
//SA1.Executing = !SA1.Waiting;
|
||||
}
|
||||
Memory.FillRAM[0x220b] &= ~0x20;
|
||||
|
||||
// SA-1 NMI enable
|
||||
if (((byte ^ Memory.FillRAM[0x220a]) & 0x10) && (Memory.FillRAM[0x2301] & byte & 0x10))
|
||||
{
|
||||
SA1.Flags |= NMI_FLAG;
|
||||
//SA1.Executing = !SA1.Waiting;
|
||||
}
|
||||
Memory.FillRAM[0x220b] &= ~0x10;
|
||||
|
||||
break;
|
||||
|
||||
case 0x220b:
|
||||
case 0x220b: // SA-1 interrupt clear
|
||||
// SA-1 IRQ clear
|
||||
if (byte & 0x80)
|
||||
{
|
||||
SA1.IRQActive &= ~SNES_IRQ_SOURCE;
|
||||
Memory.FillRAM[0x2301] &= ~0x80;
|
||||
}
|
||||
|
||||
// SA-1 timer IRQ clear
|
||||
if (byte & 0x40)
|
||||
{
|
||||
SA1.IRQActive &= ~TIMER_IRQ_SOURCE;
|
||||
Memory.FillRAM[0x2301] &= ~0x40;
|
||||
}
|
||||
|
||||
// SA-1 DMA IRQ clear
|
||||
if (byte & 0x20)
|
||||
{
|
||||
SA1.IRQActive &= ~DMA_IRQ_SOURCE;
|
||||
Memory.FillRAM[0x2301] &= ~0x20;
|
||||
}
|
||||
|
||||
// SA-1 NMI clear
|
||||
if (byte & 0x10)
|
||||
Memory.FillRAM[0x2301] &= ~0x10;
|
||||
|
||||
if (!SA1.IRQActive)
|
||||
SA1.Flags &= ~IRQ_FLAG;
|
||||
|
||||
break;
|
||||
|
||||
case 0x220c:
|
||||
//printf("SNES NMI vector: %04x\n", byte | (Memory.FillRAM[0x220d] << 8));
|
||||
case 0x220c: // S-CPU NMI vector (L)
|
||||
case 0x220d: // S-CPU NMI vector (H)
|
||||
case 0x220e: // S-CPU IRQ vector (L)
|
||||
case 0x220f: // S-CPU IRQ vector (H)
|
||||
break;
|
||||
|
||||
case 0x220d:
|
||||
//printf("SNES NMI vector: %04x\n", (byte << 8) | Memory.FillRAM[0x220c]);
|
||||
break;
|
||||
|
||||
case 0x220e:
|
||||
//printf("SNES IRQ vector: %04x\n", byte | (Memory.FillRAM[0x220f] << 8));
|
||||
break;
|
||||
|
||||
case 0x220f:
|
||||
//printf("SNES IRQ vector: %04x\n", (byte << 8) | Memory.FillRAM[0x220e]);
|
||||
break;
|
||||
|
||||
case 0x2210:
|
||||
#if 0
|
||||
printf("Timer %s\n", (byte & 0x80) ? "linear" : "HV");
|
||||
printf("Timer H-IRQ %s\n", (byte & 1) ? "enabled" : "disabled");
|
||||
printf("Timer V-IRQ %s\n", (byte & 2) ? "enabled" : "disabled");
|
||||
case 0x2210: // SA-1 timer control
|
||||
// 0x80: mode (linear / HV)
|
||||
// 0x02: V timer enable
|
||||
// 0x01: H timer enable
|
||||
#ifdef DEBUGGER
|
||||
printf("SA-1 timer control write:%02x\n", byte);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x2211:
|
||||
//printf("Timer reset\n");
|
||||
case 0x2211: // SA-1 timer reset
|
||||
SA1.HCounter = 0;
|
||||
SA1.VCounter = 0;
|
||||
break;
|
||||
|
||||
case 0x2212:
|
||||
//printf("H-Timer %04x\n", byte | (Memory.FillRAM[0x2213] << 8));
|
||||
case 0x2212: // SA-1 H-timer (L)
|
||||
SA1.HTimerIRQPos = byte | (Memory.FillRAM[0x2213] << 8);
|
||||
break;
|
||||
|
||||
case 0x2213:
|
||||
//printf("H-Timer %04x\n", (byte << 8) | Memory.FillRAM[0x2212]);
|
||||
case 0x2213: // SA-1 H-timer (H)
|
||||
SA1.HTimerIRQPos = (byte << 8) | Memory.FillRAM[0x2212];
|
||||
break;
|
||||
|
||||
case 0x2214:
|
||||
//printf("V-Timer %04x\n", byte | (Memory.FillRAM[0x2215] << 8));
|
||||
case 0x2214: // SA-1 V-timer (L)
|
||||
SA1.VTimerIRQPos = byte | (Memory.FillRAM[0x2215] << 8);
|
||||
break;
|
||||
|
||||
case 0x2215:
|
||||
//printf("V-Timer %04x\n", (byte << 8) | Memory.FillRAM[0x2214]);
|
||||
case 0x2215: // SA-1 V-timer (H)
|
||||
SA1.VTimerIRQPos = (byte << 8) | Memory.FillRAM[0x2214];
|
||||
break;
|
||||
|
||||
case 0x2220:
|
||||
case 0x2221:
|
||||
case 0x2222:
|
||||
case 0x2223:
|
||||
//printf("MMC: %02x\n", byte);
|
||||
case 0x2220: // MMC bank C
|
||||
case 0x2221: // MMC bank D
|
||||
case 0x2222: // MMC bank E
|
||||
case 0x2223: // MMC bank F
|
||||
S9xSetSA1MemMap(address - 0x2220, byte);
|
||||
break;
|
||||
|
||||
case 0x2224:
|
||||
//printf("BWRAM image SNES %02x -> 0x6000\n", byte);
|
||||
case 0x2224: // S-CPU BW-RAM mapping
|
||||
Memory.BWRAM = Memory.SRAM + (byte & 7) * 0x2000;
|
||||
break;
|
||||
|
||||
case 0x2225:
|
||||
//printf("BWRAM image SA1 %02x -> 0x6000 (%02x)\n", byte, Memory.FillRAM[0x2225]);
|
||||
case 0x2225: // SA-1 BW-RAM mapping
|
||||
if (byte != Memory.FillRAM[0x2225])
|
||||
S9xSA1SetBWRAMMemMap(byte);
|
||||
|
||||
break;
|
||||
|
||||
case 0x2226:
|
||||
//printf("BW-RAM SNES write %s\n", (byte & 0x80) ? "enabled" : "disabled");
|
||||
case 0x2226: // S-CPU BW-RAM write enable
|
||||
case 0x2227: // SA-1 BW-RAM write enable
|
||||
case 0x2228: // BW-RAM write-protected area
|
||||
case 0x2229: // S-CPU I-RAM write protection
|
||||
case 0x222a: // SA-1 I-RAM write protection
|
||||
break;
|
||||
|
||||
case 0x2227:
|
||||
//printf("BW-RAM SA1 write %s\n", (byte & 0x80) ? "enabled" : "disabled");
|
||||
case 0x2230: // DMA control
|
||||
// 0x80: enable
|
||||
// 0x40: priority (DMA / SA-1)
|
||||
// 0x20: character conversion / normal
|
||||
// 0x10: BW-RAM -> I-RAM / SA-1 -> I-RAM
|
||||
// 0x04: destinatin (BW-RAM / I-RAM)
|
||||
// 0x03: source
|
||||
break;
|
||||
|
||||
case 0x2228:
|
||||
//printf("BW-RAM write protect area %02x\n", byte);
|
||||
break;
|
||||
|
||||
case 0x2229:
|
||||
//printf("I-RAM SNES write protect area %02x\n", byte);
|
||||
break;
|
||||
|
||||
case 0x222a:
|
||||
//printf("I-RAM SA1 write protect area %02x\n", byte);
|
||||
break;
|
||||
|
||||
case 0x2230:
|
||||
#if 0
|
||||
printf("SA1 DMA %s\n", (byte & 0x80) ? "enabled" : "disabled");
|
||||
printf("DMA priority %s\n", (byte & 0x40) ? "DMA" : "SA1");
|
||||
printf("DMA %s\n", (byte & 0x20) ? "char conv" : "normal");
|
||||
printf("DMA type %s\n", (byte & 0x10) ? "BW-RAM -> I-RAM" : "SA1 -> I-RAM");
|
||||
printf("DMA distination %s\n", (byte & 4) ? "BW-RAM" : "I-RAM");
|
||||
printf("DMA source %s\n", DMAsource[byte & 3]);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x2231:
|
||||
case 0x2231: // character conversion DMA parameters
|
||||
// 0x80: CHDEND (complete / incomplete)
|
||||
// 0x03: color mode
|
||||
// (byte >> 2) & 7: virtual VRAM width
|
||||
if (byte & 0x80)
|
||||
SA1.in_char_dma = FALSE;
|
||||
#if 0
|
||||
printf("CHDEND %s\n", (byte & 0x80) ? "complete" : "incomplete");
|
||||
printf("DMA colour mode %d\n", byte & 3);
|
||||
printf("virtual VRAM width %d\n", (byte >> 2) & 7);
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case 0x2232:
|
||||
case 0x2233:
|
||||
case 0x2234:
|
||||
Memory.FillRAM[address] = byte;
|
||||
#if 0
|
||||
printf("DMA source start %06x\n", Memory.FillRAM[0x2232] | (Memory.FillRAM[0x2233] << 8) | (Memory.FillRAM[0x2234] << 16));
|
||||
#endif
|
||||
case 0x2232: // DMA source start address (LL)
|
||||
case 0x2233: // DMA source start address (LH)
|
||||
case 0x2234: // DMA source start address (HL)
|
||||
break;
|
||||
|
||||
case 0x2235:
|
||||
Memory.FillRAM[0x2235] = byte;
|
||||
case 0x2235: // DMA destination start address (LL)
|
||||
break;
|
||||
|
||||
case 0x2236:
|
||||
case 0x2236: // DMA destination start address (LH)
|
||||
Memory.FillRAM[0x2236] = byte;
|
||||
|
||||
if ((Memory.FillRAM[0x2230] & 0xa4) == 0x80) // Normal DMA to I-RAM
|
||||
S9xSA1DMA();
|
||||
else
|
||||
if ((Memory.FillRAM[0x2230] & 0xb0) == 0xb0)
|
||||
if ((Memory.FillRAM[0x2230] & 0xb0) == 0xb0) // CC1
|
||||
{
|
||||
SA1.in_char_dma = TRUE;
|
||||
|
||||
Memory.FillRAM[0x2300] |= 0x20;
|
||||
if (Memory.FillRAM[0x2201] & 0x20)
|
||||
S9xSetIRQ(SA1_DMA_IRQ_SOURCE);
|
||||
SA1.in_char_dma = TRUE;
|
||||
{
|
||||
Memory.FillRAM[0x2202] &= ~0x20;
|
||||
CPU.IRQExternal = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x2237:
|
||||
case 0x2237: // DMA destination start address (HL)
|
||||
Memory.FillRAM[0x2237] = byte;
|
||||
|
||||
if ((Memory.FillRAM[0x2230] & 0xa4) == 0x84) // Normal DMA to BW-RAM
|
||||
S9xSA1DMA();
|
||||
#if 0
|
||||
printf("DMA dest address %06x\n", Memory.FillRAM[0x2235] | (Memory.FillRAM[0x2236] << 8) | (Memory.FillRAM[0x2237] << 16));
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case 0x2238:
|
||||
case 0x2239:
|
||||
Memory.FillRAM[address] = byte;
|
||||
#if 0
|
||||
printf("DMA length %04x\n", Memory.FillRAM[0x2238] | (Memory.FillRAM[0x2239] << 8));
|
||||
#endif
|
||||
case 0x2238: // DMA terminal counter (L)
|
||||
case 0x2239: // DMA terminal counter (H)
|
||||
break;
|
||||
|
||||
case 0x223f:
|
||||
//printf("virtual VRAM depth %d\n", (byte & 0x80) ? 2 : 4);
|
||||
case 0x223f: // BW-RAM bitmap format
|
||||
SA1.VirtualBitmapFormat = (byte & 0x80) ? 2 : 4;
|
||||
break;
|
||||
|
||||
case 0x2240:
|
||||
case 0x2241:
|
||||
case 0x2242:
|
||||
case 0x2243:
|
||||
case 0x2244:
|
||||
case 0x2245:
|
||||
case 0x2246:
|
||||
case 0x2247:
|
||||
case 0x2248:
|
||||
case 0x2249:
|
||||
case 0x224a:
|
||||
case 0x224b:
|
||||
case 0x224c:
|
||||
case 0x224d:
|
||||
case 0x224e:
|
||||
#if 0
|
||||
if (!(SA1.Flags & TRACE_FLAG))
|
||||
{
|
||||
TraceSA1();
|
||||
Trace();
|
||||
}
|
||||
#endif
|
||||
Memory.FillRAM[address] = byte;
|
||||
case 0x2240: // bitmap register 0
|
||||
case 0x2241: // bitmap register 1
|
||||
case 0x2242: // bitmap register 2
|
||||
case 0x2243: // bitmap register 3
|
||||
case 0x2244: // bitmap register 4
|
||||
case 0x2245: // bitmap register 5
|
||||
case 0x2246: // bitmap register 6
|
||||
case 0x2247: // bitmap register 7
|
||||
case 0x2248: // bitmap register 8
|
||||
case 0x2249: // bitmap register 9
|
||||
case 0x224a: // bitmap register A
|
||||
case 0x224b: // bitmap register B
|
||||
case 0x224c: // bitmap register C
|
||||
case 0x224d: // bitmap register D
|
||||
case 0x224e: // bitmap register E
|
||||
break;
|
||||
|
||||
case 0x224f:
|
||||
case 0x224f: // bitmap register F
|
||||
Memory.FillRAM[0x224f] = byte;
|
||||
|
||||
if ((Memory.FillRAM[0x2230] & 0xb0) == 0xa0) // Char conversion 2 DMA enabled
|
||||
if ((Memory.FillRAM[0x2230] & 0xb0) == 0xa0) // CC2
|
||||
{
|
||||
memmove(&Memory.ROM[CMemory::MAX_ROM_SIZE - 0x10000] + SA1.in_char_dma * 16, &Memory.FillRAM[0x2240], 16);
|
||||
SA1.in_char_dma = (SA1.in_char_dma + 1) & 7;
|
||||
|
@ -712,58 +664,67 @@ void S9xSetSA1 (uint8 byte, uint32 address)
|
|||
|
||||
break;
|
||||
|
||||
case 0x2250:
|
||||
case 0x2250: // arithmetic control
|
||||
if (byte & 2)
|
||||
SA1.sum = 0;
|
||||
SA1.arithmetic_op = byte & 3;
|
||||
break;
|
||||
|
||||
case 0x2251:
|
||||
SA1.op1 = (SA1.op1 & 0xff00) | byte;
|
||||
case 0x2251: // multiplicand / dividend (L)
|
||||
SA1.op1 = (SA1.op1 & 0xff00) | byte;
|
||||
break;
|
||||
|
||||
case 0x2252:
|
||||
SA1.op1 = (SA1.op1 & 0xff) | (byte << 8);
|
||||
case 0x2252: // multiplicand / dividend (H)
|
||||
SA1.op1 = (SA1.op1 & 0x00ff) | (byte << 8);
|
||||
break;
|
||||
|
||||
case 0x2253:
|
||||
SA1.op2 = (SA1.op2 & 0xff00) | byte;
|
||||
case 0x2253: // multiplier / divisor (L)
|
||||
SA1.op2 = (SA1.op2 & 0xff00) | byte;
|
||||
break;
|
||||
|
||||
case 0x2254:
|
||||
SA1.op2 = (SA1.op2 & 0xff) | (byte << 8);
|
||||
case 0x2254: // multiplier / divisor (H)
|
||||
SA1.op2 = (SA1.op2 & 0x00ff) | (byte << 8);
|
||||
|
||||
switch (SA1.arithmetic_op)
|
||||
{
|
||||
case 0: // multiply
|
||||
SA1.sum = SA1.op1 * SA1.op2;
|
||||
case 0: // signed multiplication
|
||||
SA1.sum = (int16) SA1.op1 * (int16) SA1.op2;
|
||||
SA1.op2 = 0;
|
||||
break;
|
||||
|
||||
case 1: // divide
|
||||
case 1: // unsigned division
|
||||
if (SA1.op2 == 0)
|
||||
SA1.sum = SA1.op1 << 16;
|
||||
SA1.sum = 0;
|
||||
else
|
||||
SA1.sum = (SA1.op1 / (int) ((uint16) SA1.op2)) | ((SA1.op1 % (int) ((uint16) SA1.op2)) << 16);
|
||||
{
|
||||
int16 quotient = (int16) SA1.op1 / (uint16) SA1.op2;
|
||||
uint16 remainder = (int16) SA1.op1 % (uint16) SA1.op2;
|
||||
SA1.sum = (remainder << 16) | quotient;
|
||||
}
|
||||
|
||||
SA1.op1 = 0;
|
||||
SA1.op2 = 0;
|
||||
break;
|
||||
|
||||
case 2: // cumulative sum
|
||||
default:
|
||||
SA1.sum += SA1.op1 * SA1.op2;
|
||||
if (SA1.sum & ((int64) 0xffffff << 32))
|
||||
SA1.overflow = TRUE;
|
||||
SA1.sum += (int16) SA1.op1 * (int16) SA1.op2;
|
||||
SA1.overflow = (SA1.sum >= (1ULL << 40));
|
||||
SA1.sum &= (1ULL << 40) - 1;
|
||||
SA1.op2 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x2258: // Variable bit-field length/auto inc/start.
|
||||
case 0x2258: // variable bit-field length / auto inc / start
|
||||
Memory.FillRAM[0x2258] = byte;
|
||||
S9xSA1ReadVariableLengthData(TRUE, FALSE);
|
||||
return;
|
||||
|
||||
case 0x2259: // Variable bit-field start address
|
||||
case 0x225a:
|
||||
case 0x225b:
|
||||
case 0x2259: // variable bit-field start address (LL)
|
||||
case 0x225a: // variable bit-field start address (LH)
|
||||
case 0x225b: // variable bit-field start address (HL)
|
||||
Memory.FillRAM[address] = byte;
|
||||
// XXX: ???
|
||||
SA1.variable_bit_pos = 0;
|
||||
|
@ -771,7 +732,6 @@ void S9xSetSA1 (uint8 byte, uint32 address)
|
|||
return;
|
||||
|
||||
default:
|
||||
//printf("W: %02x->%04x\n", byte, address);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -890,14 +850,11 @@ static void S9xSA1DMA (void)
|
|||
}
|
||||
|
||||
memmove(d, s, len);
|
||||
Memory.FillRAM[0x2301] |= 0x20;
|
||||
|
||||
// SA-1 DMA IRQ control
|
||||
Memory.FillRAM[0x2301] |= 0x20;
|
||||
if (Memory.FillRAM[0x220a] & 0x20)
|
||||
{
|
||||
SA1.Flags |= IRQ_FLAG;
|
||||
SA1.IRQActive |= DMA_IRQ_SOURCE;
|
||||
//SA1.Executing = !SA1.Waiting;
|
||||
}
|
||||
Memory.FillRAM[0x220b] &= ~0x20;
|
||||
}
|
||||
|
||||
static void S9xSA1ReadVariableLengthData (bool8 inc, bool8 no_shift)
|
||||
|
@ -1096,6 +1053,10 @@ void S9xSA1SetPCBase (uint32 address)
|
|||
SA1Registers.PBPC = address & 0xffffff;
|
||||
SA1.ShiftedPB = address & 0xff0000;
|
||||
|
||||
// FIXME
|
||||
SA1.MemSpeed = memory_speed(address);
|
||||
SA1.MemSpeedx2 = SA1.MemSpeed << 1;
|
||||
|
||||
uint8 *GetAddress = SA1.Map[(address & 0xffffff) >> MEMMAP_SHIFT];
|
||||
|
||||
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||
|
|
32
sa1.h
32
sa1.h
|
@ -198,32 +198,33 @@ struct SSA1
|
|||
uint8 _Zero;
|
||||
uint8 _Negative;
|
||||
uint8 _Overflow;
|
||||
bool8 CPUExecuting;
|
||||
uint32 ShiftedPB;
|
||||
uint32 ShiftedDB;
|
||||
|
||||
uint32 Flags;
|
||||
int32 Cycles;
|
||||
int32 PrevCycles;
|
||||
uint8 *PCBase;
|
||||
bool8 IRQActive;
|
||||
bool8 Waiting;
|
||||
bool8 WaitingForInterrupt;
|
||||
uint32 WaitAddress;
|
||||
uint32 WaitCounter;
|
||||
uint32 PBPCAtOpcodeStart;
|
||||
uint8 *WaitByteAddress1;
|
||||
uint8 *WaitByteAddress2;
|
||||
|
||||
uint8 *Map[MEMMAP_NUM_BLOCKS];
|
||||
uint8 *WriteMap[MEMMAP_NUM_BLOCKS];
|
||||
uint8 *BWRAM;
|
||||
|
||||
bool8 Executing;
|
||||
bool8 overflow;
|
||||
bool8 in_char_dma;
|
||||
int16 op1;
|
||||
int16 op2;
|
||||
bool8 TimerIRQLastState;
|
||||
uint16 HTimerIRQPos;
|
||||
uint16 VTimerIRQPos;
|
||||
int16 HCounter;
|
||||
int16 VCounter;
|
||||
int16 PrevHCounter;
|
||||
int32 MemSpeed;
|
||||
int32 MemSpeedx2;
|
||||
int32 arithmetic_op;
|
||||
int64 sum;
|
||||
uint16 op1;
|
||||
uint16 op2;
|
||||
uint64 sum;
|
||||
bool8 overflow;
|
||||
uint8 VirtualBitmapFormat;
|
||||
uint8 variable_bit_pos;
|
||||
};
|
||||
|
@ -263,13 +264,8 @@ uint8 S9xGetSA1 (uint32);
|
|||
void S9xSetSA1 (uint8, uint32);
|
||||
void S9xSA1Init (void);
|
||||
void S9xSA1MainLoop (void);
|
||||
void S9xSA1ExecuteDuringSleep (void);
|
||||
void S9xSA1PostLoadState (void);
|
||||
|
||||
#define SNES_IRQ_SOURCE (1 << 7)
|
||||
#define TIMER_IRQ_SOURCE (1 << 6)
|
||||
#define DMA_IRQ_SOURCE (1 << 5)
|
||||
|
||||
static inline void S9xSA1UnpackStatus (void)
|
||||
{
|
||||
SA1._Zero = (SA1Registers.PL & Zero) == 0;
|
||||
|
|
147
sa1cpu.cpp
147
sa1cpu.cpp
|
@ -221,59 +221,89 @@
|
|||
#define StackRelative SA1StackRelative
|
||||
#define StackRelativeIndirectIndexed SA1StackRelativeIndirectIndexed
|
||||
|
||||
//#undef CPU_SHUTDOWN
|
||||
#define SA1_OPCODES
|
||||
|
||||
#include "cpuops.cpp"
|
||||
|
||||
static void S9xSA1UpdateTimer (void);
|
||||
|
||||
|
||||
void S9xSA1MainLoop (void)
|
||||
{
|
||||
if (SA1.Flags & NMI_FLAG)
|
||||
if (Memory.FillRAM[0x2200] & 0x60)
|
||||
{
|
||||
if (Memory.FillRAM[0x2200] & 0x10)
|
||||
{
|
||||
SA1.Flags &= ~NMI_FLAG;
|
||||
Memory.FillRAM[0x2301] |= 0x10;
|
||||
|
||||
if (SA1.WaitingForInterrupt)
|
||||
{
|
||||
SA1.WaitingForInterrupt = FALSE;
|
||||
SA1Registers.PCw++;
|
||||
}
|
||||
|
||||
S9xSA1Opcode_NMI();
|
||||
}
|
||||
SA1.Cycles += 6; // FIXME
|
||||
S9xSA1UpdateTimer();
|
||||
return;
|
||||
}
|
||||
|
||||
if (SA1.Flags & IRQ_FLAG)
|
||||
// SA-1 NMI
|
||||
if ((Memory.FillRAM[0x2200] & 0x10) && !(Memory.FillRAM[0x220b] & 0x10))
|
||||
{
|
||||
if (SA1.IRQActive)
|
||||
Memory.FillRAM[0x2301] |= 0x10;
|
||||
Memory.FillRAM[0x220b] |= 0x10;
|
||||
|
||||
if (SA1.WaitingForInterrupt)
|
||||
{
|
||||
SA1.WaitingForInterrupt = FALSE;
|
||||
SA1Registers.PCw++;
|
||||
}
|
||||
|
||||
S9xSA1Opcode_NMI();
|
||||
}
|
||||
else
|
||||
if (!SA1CheckFlag(IRQ))
|
||||
{
|
||||
// SA-1 Timer IRQ
|
||||
if ((Memory.FillRAM[0x220a] & 0x40) && !(Memory.FillRAM[0x220b] & 0x40))
|
||||
{
|
||||
Memory.FillRAM[0x2301] |= 0x40;
|
||||
|
||||
if (SA1.WaitingForInterrupt)
|
||||
{
|
||||
SA1.WaitingForInterrupt = FALSE;
|
||||
SA1Registers.PCw++;
|
||||
}
|
||||
|
||||
if (!SA1CheckFlag(IRQ))
|
||||
S9xSA1Opcode_IRQ();
|
||||
S9xSA1Opcode_IRQ();
|
||||
}
|
||||
else
|
||||
SA1.Flags &= ~IRQ_FLAG;
|
||||
// SA-1 DMA IRQ
|
||||
if ((Memory.FillRAM[0x220a] & 0x20) && !(Memory.FillRAM[0x220b] & 0x20))
|
||||
{
|
||||
Memory.FillRAM[0x2301] |= 0x20;
|
||||
|
||||
if (SA1.WaitingForInterrupt)
|
||||
{
|
||||
SA1.WaitingForInterrupt = FALSE;
|
||||
SA1Registers.PCw++;
|
||||
}
|
||||
|
||||
S9xSA1Opcode_IRQ();
|
||||
}
|
||||
else
|
||||
// SA-1 IRQ
|
||||
if ((Memory.FillRAM[0x2200] & 0x80) && !(Memory.FillRAM[0x220b] & 0x80))
|
||||
{
|
||||
Memory.FillRAM[0x2301] |= 0x80;
|
||||
|
||||
if (SA1.WaitingForInterrupt)
|
||||
{
|
||||
SA1.WaitingForInterrupt = FALSE;
|
||||
SA1Registers.PCw++;
|
||||
}
|
||||
|
||||
S9xSA1Opcode_IRQ();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3 && SA1.Executing; i++)
|
||||
for (int i = 0; i < 3 && !(Memory.FillRAM[0x2200] & 0x60); i++)
|
||||
{
|
||||
#ifdef DEBUGGER
|
||||
if (SA1.Flags & TRACE_FLAG)
|
||||
S9xSA1Trace();
|
||||
#endif
|
||||
|
||||
#ifdef CPU_SHUTDOWN
|
||||
SA1.PBPCAtOpcodeStart = SA1Registers.PBPC;
|
||||
#endif
|
||||
|
||||
register uint8 Op;
|
||||
register struct SOpcodes *Opcodes;
|
||||
|
||||
|
@ -299,4 +329,71 @@ void S9xSA1MainLoop (void)
|
|||
Registers.PCw++;
|
||||
(*Opcodes[Op].S9xOpcode)();
|
||||
}
|
||||
|
||||
S9xSA1UpdateTimer();
|
||||
}
|
||||
|
||||
static void S9xSA1UpdateTimer (void) // FIXME
|
||||
{
|
||||
SA1.PrevHCounter = SA1.HCounter;
|
||||
|
||||
if (Memory.FillRAM[0x2210] & 0x80)
|
||||
{
|
||||
SA1.HCounter += (SA1.Cycles - SA1.PrevCycles);
|
||||
if (SA1.HCounter >= 0x800)
|
||||
{
|
||||
SA1.HCounter -= 0x800;
|
||||
SA1.PrevHCounter -= 0x800;
|
||||
if (++SA1.VCounter >= 0x200)
|
||||
SA1.VCounter = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SA1.HCounter += (SA1.Cycles - SA1.PrevCycles);
|
||||
if (SA1.HCounter >= Timings.H_Max_Master)
|
||||
{
|
||||
SA1.HCounter -= Timings.H_Max_Master;
|
||||
SA1.PrevHCounter -= Timings.H_Max_Master;
|
||||
if (++SA1.VCounter >= Timings.V_Max_Master)
|
||||
SA1.VCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (SA1.Cycles >= Timings.H_Max_Master)
|
||||
SA1.Cycles -= Timings.H_Max_Master;
|
||||
|
||||
SA1.PrevCycles = SA1.Cycles;
|
||||
|
||||
bool8 thisIRQ = Memory.FillRAM[0x2210] & 0x03;
|
||||
|
||||
if (Memory.FillRAM[0x2210] & 0x01)
|
||||
{
|
||||
if (SA1.PrevHCounter >= SA1.HTimerIRQPos * ONE_DOT_CYCLE || SA1.HCounter < SA1.HTimerIRQPos * ONE_DOT_CYCLE)
|
||||
thisIRQ = FALSE;
|
||||
}
|
||||
|
||||
if (Memory.FillRAM[0x2210] & 0x02)
|
||||
{
|
||||
if (SA1.VCounter != SA1.VTimerIRQPos * ONE_DOT_CYCLE)
|
||||
thisIRQ = FALSE;
|
||||
}
|
||||
|
||||
// SA-1 Timer IRQ control
|
||||
if (!SA1.TimerIRQLastState && thisIRQ)
|
||||
{
|
||||
Memory.FillRAM[0x2301] |= 0x40;
|
||||
if (Memory.FillRAM[0x220a] & 0x40)
|
||||
{
|
||||
Memory.FillRAM[0x220b] &= ~0x40;
|
||||
#ifdef DEBUGGER
|
||||
S9xTraceFormattedMessage("--- SA-1 Timer IRQ triggered prev HC:%04d curr HC:%04d HTimer:%d Pos:%04d VTimer:%d Pos:%03d",
|
||||
SA1.PrevHCounter, SA1.HCounter,
|
||||
(Memory.FillRAM[0x2210] & 0x01) ? 1 : 0, SA1.HTimerIRQPos * ONE_DOT_CYCLE,
|
||||
(Memory.FillRAM[0x2210] & 0x02) ? 1 : 0, SA1.VTimerIRQPos);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SA1.TimerIRQLastState = thisIRQ;
|
||||
}
|
||||
|
|
114
snapshot.cpp
114
snapshot.cpp
|
@ -342,7 +342,7 @@ struct SnapshotScreenshotInfo
|
|||
|
||||
static struct Obsolete
|
||||
{
|
||||
uint8 reserved;
|
||||
uint8 CPU_IRQActive;
|
||||
} Obsolete;
|
||||
|
||||
#define STRUCT struct SCPUState
|
||||
|
@ -353,7 +353,7 @@ static FreezeData SnapCPU[] =
|
|||
INT_ENTRY(6, PrevCycles),
|
||||
INT_ENTRY(6, V_Counter),
|
||||
INT_ENTRY(6, Flags),
|
||||
INT_ENTRY(6, IRQActive),
|
||||
OBSOLETE_INT_ENTRY(6, 7, CPU_IRQActive),
|
||||
INT_ENTRY(6, IRQPending),
|
||||
INT_ENTRY(6, MemSpeed),
|
||||
INT_ENTRY(6, MemSpeedx2),
|
||||
|
@ -366,9 +366,14 @@ static FreezeData SnapCPU[] =
|
|||
INT_ENTRY(6, WhichEvent),
|
||||
INT_ENTRY(6, NextEvent),
|
||||
INT_ENTRY(6, WaitingForInterrupt),
|
||||
INT_ENTRY(6, WaitAddress),
|
||||
INT_ENTRY(6, WaitCounter),
|
||||
INT_ENTRY(6, PBPCAtOpcodeStart)
|
||||
DELETED_INT_ENTRY(6, 7, WaitAddress, 4),
|
||||
DELETED_INT_ENTRY(6, 7, WaitCounter, 4),
|
||||
DELETED_INT_ENTRY(6, 7, PBPCAtOpcodeStart, 4),
|
||||
INT_ENTRY(7, NMILine),
|
||||
INT_ENTRY(7, IRQLine),
|
||||
INT_ENTRY(7, IRQTransition),
|
||||
INT_ENTRY(7, IRQLastState),
|
||||
INT_ENTRY(7, IRQExternal)
|
||||
};
|
||||
|
||||
#undef STRUCT
|
||||
|
@ -576,11 +581,11 @@ static FreezeData SnapTimings[] =
|
|||
INT_ENTRY(6, DMACPUSync),
|
||||
INT_ENTRY(6, NMIDMADelay),
|
||||
INT_ENTRY(6, IRQPendCount),
|
||||
INT_ENTRY(6, APUSpeedup)
|
||||
INT_ENTRY(6, APUSpeedup),
|
||||
INT_ENTRY(7, IRQTriggerCycles),
|
||||
INT_ENTRY(7, APUAllowTimeOverflow)
|
||||
};
|
||||
|
||||
#ifndef ZSNES_FX
|
||||
|
||||
#undef STRUCT
|
||||
#define STRUCT struct FxRegs_s
|
||||
|
||||
|
@ -642,24 +647,22 @@ static FreezeData SnapFX[] =
|
|||
INT_ENTRY(6, vSCBRDirty)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#undef STRUCT
|
||||
#define STRUCT struct SSA1
|
||||
|
||||
static FreezeData SnapSA1[] =
|
||||
{
|
||||
INT_ENTRY(6, CPUExecuting),
|
||||
DELETED_INT_ENTRY(6, 7, CPUExecuting, 1),
|
||||
INT_ENTRY(6, ShiftedPB),
|
||||
INT_ENTRY(6, ShiftedDB),
|
||||
INT_ENTRY(6, Flags),
|
||||
INT_ENTRY(6, IRQActive),
|
||||
INT_ENTRY(6, Waiting),
|
||||
DELETED_INT_ENTRY(6, 7, IRQActive, 1),
|
||||
DELETED_INT_ENTRY(6, 7, Waiting, 1),
|
||||
INT_ENTRY(6, WaitingForInterrupt),
|
||||
INT_ENTRY(6, WaitAddress),
|
||||
INT_ENTRY(6, WaitCounter),
|
||||
INT_ENTRY(6, PBPCAtOpcodeStart),
|
||||
INT_ENTRY(6, Executing),
|
||||
DELETED_INT_ENTRY(6, 7, WaitAddress, 4),
|
||||
DELETED_INT_ENTRY(6, 7, WaitCounter, 4),
|
||||
DELETED_INT_ENTRY(6, 7, PBPCAtOpcodeStart, 4),
|
||||
DELETED_INT_ENTRY(6, 7, Executing, 1),
|
||||
INT_ENTRY(6, overflow),
|
||||
INT_ENTRY(6, in_char_dma),
|
||||
INT_ENTRY(6, op1),
|
||||
|
@ -667,7 +670,17 @@ static FreezeData SnapSA1[] =
|
|||
INT_ENTRY(6, arithmetic_op),
|
||||
INT_ENTRY(6, sum),
|
||||
INT_ENTRY(6, VirtualBitmapFormat),
|
||||
INT_ENTRY(6, variable_bit_pos)
|
||||
INT_ENTRY(6, variable_bit_pos),
|
||||
INT_ENTRY(7, Cycles),
|
||||
INT_ENTRY(7, PrevCycles),
|
||||
INT_ENTRY(7, TimerIRQLastState),
|
||||
INT_ENTRY(7, HTimerIRQPos),
|
||||
INT_ENTRY(7, VTimerIRQPos),
|
||||
INT_ENTRY(7, HCounter),
|
||||
INT_ENTRY(7, VCounter),
|
||||
INT_ENTRY(7, PrevHCounter),
|
||||
INT_ENTRY(7, MemSpeed),
|
||||
INT_ENTRY(7, MemSpeedx2)
|
||||
};
|
||||
|
||||
#undef STRUCT
|
||||
|
@ -1255,15 +1268,10 @@ bool8 S9xUnfreezeGame (const char *filename)
|
|||
void S9xFreezeToStream (STREAM stream)
|
||||
{
|
||||
char buffer[1024];
|
||||
uint8 *soundsnapshot = new uint8[SPC_SAVE_STATE_BLOCK_SIZE];
|
||||
uint8 *soundsnapshot = new uint8[SPC_SAVE_STATE_BLOCK_SIZE];
|
||||
|
||||
S9xSetSoundMute(TRUE);
|
||||
|
||||
#ifdef ZSNES_FX
|
||||
if (Settings.SuperFX)
|
||||
S9xSuperFXPreSaveState();
|
||||
#endif
|
||||
|
||||
sprintf(buffer, "%s:%04d\n", SNAPSHOT_MAGIC, SNAPSHOT_VERSION);
|
||||
WRITE_STREAM(buffer, strlen(buffer), stream);
|
||||
|
||||
|
@ -1298,13 +1306,11 @@ void S9xFreezeToStream (STREAM stream)
|
|||
|
||||
FreezeStruct(stream, "TIM", &Timings, SnapTimings, COUNT(SnapTimings));
|
||||
|
||||
#ifndef ZSNES_FX
|
||||
if (Settings.SuperFX)
|
||||
{
|
||||
GSU.avRegAddr = (uint8 *) &GSU.avReg;
|
||||
FreezeStruct(stream, "SFX", &GSU, SnapFX, COUNT(SnapFX));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Settings.SA1)
|
||||
{
|
||||
|
@ -1323,11 +1329,7 @@ void S9xFreezeToStream (STREAM stream)
|
|||
FreezeStruct(stream, "DP4", &DSP4, SnapDSP4, COUNT(SnapDSP4));
|
||||
|
||||
if (Settings.C4)
|
||||
#ifndef ZSNES_C4
|
||||
FreezeBlock (stream, "CX4", Memory.C4RAM, 8192);
|
||||
#else
|
||||
FreezeBlock (stream, "CX4", C4Ram, 8192);
|
||||
#endif
|
||||
|
||||
if (Settings.SETA == ST_010)
|
||||
FreezeStruct(stream, "ST0", &ST010, SnapST010, COUNT(SnapST010));
|
||||
|
@ -1405,11 +1407,6 @@ void S9xFreezeToStream (STREAM stream)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef ZSNES_FX
|
||||
if (Settings.SuperFX)
|
||||
S9xSuperFXPostSaveState();
|
||||
#endif
|
||||
|
||||
S9xSetSoundMute(FALSE);
|
||||
|
||||
delete [] soundsnapshot;
|
||||
|
@ -1510,11 +1507,9 @@ int S9xUnfreezeFromStream (STREAM stream)
|
|||
if (result != SUCCESS)
|
||||
break;
|
||||
|
||||
#ifndef ZSNES_FX
|
||||
result = UnfreezeStructCopy(stream, "SFX", &local_superfx, SnapFX, COUNT(SnapFX), version);
|
||||
if (result != SUCCESS && Settings.SuperFX)
|
||||
break;
|
||||
#endif
|
||||
|
||||
result = UnfreezeStructCopy(stream, "SA1", &local_sa1, SnapSA1, COUNT(SnapSA1), version);
|
||||
if (result != SUCCESS && Settings.SA1)
|
||||
|
@ -1637,13 +1632,11 @@ int S9xUnfreezeFromStream (STREAM stream)
|
|||
|
||||
UnfreezeStructFromCopy(&Timings, SnapTimings, COUNT(SnapTimings), local_timing_data, version);
|
||||
|
||||
#ifndef ZSNES_FX
|
||||
if (local_superfx)
|
||||
{
|
||||
GSU.avRegAddr = (uint8 *) &GSU.avReg;
|
||||
UnfreezeStructFromCopy(&GSU, SnapFX, COUNT(SnapFX), local_superfx, version);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (local_sa1)
|
||||
UnfreezeStructFromCopy(&SA1, SnapSA1, COUNT(SnapSA1), local_sa1, version);
|
||||
|
@ -1661,11 +1654,7 @@ int S9xUnfreezeFromStream (STREAM stream)
|
|||
UnfreezeStructFromCopy(&DSP4, SnapDSP4, COUNT(SnapDSP4), local_dsp4, version);
|
||||
|
||||
if (local_cx4_data)
|
||||
#ifndef ZSNES_C4
|
||||
memcpy(Memory.C4RAM, local_cx4_data, 8192);
|
||||
#else
|
||||
memcpy(C4Ram, local_cx4_data, 8192);
|
||||
#endif
|
||||
|
||||
if (local_st010)
|
||||
UnfreezeStructFromCopy(&ST010, SnapST010, COUNT(SnapST010), local_st010, version);
|
||||
|
@ -1688,6 +1677,40 @@ int S9xUnfreezeFromStream (STREAM stream)
|
|||
if (local_bsx_data)
|
||||
UnfreezeStructFromCopy(&BSX, SnapBSX, COUNT(SnapBSX), local_bsx_data, version);
|
||||
|
||||
if (version < SNAPSHOT_VERSION)
|
||||
{
|
||||
printf("Converting old snapshot version %d to %d\n...", version, SNAPSHOT_VERSION);
|
||||
|
||||
CPU.NMILine = (CPU.Flags & (1 << 7)) ? TRUE : FALSE;
|
||||
CPU.IRQLine = (CPU.Flags & (1 << 11)) ? TRUE : FALSE;
|
||||
CPU.IRQTransition = FALSE;
|
||||
CPU.IRQLastState = FALSE;
|
||||
CPU.IRQExternal = (Obsolete.CPU_IRQActive & ~(1 << 1)) ? TRUE : FALSE;
|
||||
|
||||
switch (CPU.WhichEvent)
|
||||
{
|
||||
case 12: case 1: CPU.WhichEvent = 1; break;
|
||||
case 2: case 3: CPU.WhichEvent = 2; break;
|
||||
case 4: case 5: CPU.WhichEvent = 3; break;
|
||||
case 6: case 7: CPU.WhichEvent = 4; break;
|
||||
case 8: case 9: CPU.WhichEvent = 5; break;
|
||||
case 10: case 11: CPU.WhichEvent = 6; break;
|
||||
}
|
||||
|
||||
if (local_sa1) // FIXME
|
||||
{
|
||||
SA1.Cycles = SA1.PrevCycles = 0;
|
||||
SA1.TimerIRQLastState = FALSE;
|
||||
SA1.HTimerIRQPos = Memory.FillRAM[0x2212] | (Memory.FillRAM[0x2213] << 8);
|
||||
SA1.VTimerIRQPos = Memory.FillRAM[0x2214] | (Memory.FillRAM[0x2215] << 8);
|
||||
SA1.HCounter = 0;
|
||||
SA1.VCounter = 0;
|
||||
SA1.PrevHCounter = 0;
|
||||
SA1.MemSpeed = SLOW_ONE_CYCLE;
|
||||
SA1.MemSpeedx2 = SLOW_ONE_CYCLE * 2;
|
||||
}
|
||||
}
|
||||
|
||||
CPU.Flags |= old_flags & (DEBUG_MODE_FLAG | TRACE_FLAG | SINGLE_STEP_FLAG | FRAME_ADVANCE_FLAG);
|
||||
ICPU.ShiftedPB = Registers.PB << 16;
|
||||
ICPU.ShiftedDB = Registers.DB << 16;
|
||||
|
@ -1711,16 +1734,11 @@ int S9xUnfreezeFromStream (STREAM stream)
|
|||
|
||||
S9xControlPostLoadState(&ctl_snap);
|
||||
|
||||
#ifndef ZSNES_FX
|
||||
if (local_superfx)
|
||||
{
|
||||
GSU.pfPlot = fx_PlotTable[GSU.vMode];
|
||||
GSU.pfRpix = fx_PlotTable[GSU.vMode + 5];
|
||||
}
|
||||
#else
|
||||
if (Settings.SuperFX)
|
||||
S9xSuperFXPostLoadState();
|
||||
#endif
|
||||
|
||||
if (local_sa1 && local_sa1_registers)
|
||||
{
|
||||
|
|
|
@ -179,7 +179,7 @@
|
|||
#define _SNAPSHOT_H_
|
||||
|
||||
#define SNAPSHOT_MAGIC "#!s9xsnp"
|
||||
#define SNAPSHOT_VERSION 6
|
||||
#define SNAPSHOT_VERSION 7
|
||||
|
||||
#define SUCCESS 1
|
||||
#define WRONG_FORMAT (-1)
|
||||
|
|
15
snes9x.cpp
15
snes9x.cpp
|
@ -467,9 +467,6 @@ void S9xLoadConfigFiles (char **argv, int argc)
|
|||
|
||||
Settings.DisableGameSpecificHacks = !conf.GetBool("Hack::EnableGameSpecificHacks", true);
|
||||
Settings.BlockInvalidVRAMAccessMaster = !conf.GetBool("Hack::AllowInvalidVRAMAccess", false);
|
||||
Settings.ShutdownMaster = conf.GetBool("Hack::SpeedHacks", false);
|
||||
Settings.DisableIRQ = conf.GetBool("Hack::DisableIRQ", false);
|
||||
Settings.DisableHDMA = conf.GetBool("Hack::DisableHDMA", false);
|
||||
Settings.HDMATimingHack = conf.GetInt ("Hack::HDMATiming", 100);
|
||||
|
||||
// Netplay
|
||||
|
@ -586,10 +583,7 @@ void S9xUsage (void)
|
|||
S9xMessage(S9X_INFO, S9X_USAGE, "-debug Set the Debugger flag");
|
||||
S9xMessage(S9X_INFO, S9X_USAGE, "-trace Begin CPU instruction tracing");
|
||||
#endif
|
||||
S9xMessage(S9X_INFO, S9X_USAGE, "-noirq (Not recommended) Disable IRQ emulation");
|
||||
S9xMessage(S9X_INFO, S9X_USAGE, "-nohdma (Not recommended) Disable HDMA emulation");
|
||||
S9xMessage(S9X_INFO, S9X_USAGE, "-hdmatiming <1-199> (Not recommended) Changes HDMA transfer timings");
|
||||
S9xMessage(S9X_INFO, S9X_USAGE, "-cpushutdown (Not recommended) Skip emulation until the next");
|
||||
S9xMessage(S9X_INFO, S9X_USAGE, " event comes");
|
||||
S9xMessage(S9X_INFO, S9X_USAGE, "-invalidvramaccess (Not recommended) Allow invalid VRAM access");
|
||||
S9xMessage(S9X_INFO, S9X_USAGE, "");
|
||||
|
@ -851,12 +845,6 @@ char * S9xParseArgs (char **argv, int argc)
|
|||
else
|
||||
#endif
|
||||
|
||||
if (!strcasecmp(argv[i], "-noirq"))
|
||||
Settings.DisableIRQ = TRUE;
|
||||
else
|
||||
if (!strcasecmp(argv[i], "-nohdma"))
|
||||
Settings.DisableHDMA = TRUE;
|
||||
else
|
||||
if (!strcasecmp(argv[i], "-hdmatiming"))
|
||||
{
|
||||
if (i + 1 < argc)
|
||||
|
@ -869,9 +857,6 @@ char * S9xParseArgs (char **argv, int argc)
|
|||
S9xUsage();
|
||||
}
|
||||
else
|
||||
if (!strcasecmp(argv[i], "-cpushutdown"))
|
||||
Settings.ShutdownMaster = TRUE;
|
||||
else
|
||||
if (!strcasecmp(argv[i], "-invalidvramaccess"))
|
||||
Settings.BlockInvalidVRAMAccessMaster = FALSE;
|
||||
else
|
||||
|
|
38
snes9x.h
38
snes9x.h
|
@ -186,8 +186,6 @@
|
|||
#include "65c816.h"
|
||||
#include "messages.h"
|
||||
|
||||
#define S9X_ACCURACY_LEVEL 3
|
||||
|
||||
#ifdef ZLIB
|
||||
#include <zlib.h>
|
||||
#define STREAM gzFile
|
||||
|
@ -263,8 +261,6 @@
|
|||
#define TRACE_FLAG (1 << 1) // debugger
|
||||
#define SINGLE_STEP_FLAG (1 << 2) // debugger
|
||||
#define BREAK_FLAG (1 << 3) // debugger
|
||||
#define NMI_FLAG (1 << 7) // CPU
|
||||
#define IRQ_FLAG (1 << 11) // CPU
|
||||
#define SCAN_KEYS_FLAG (1 << 4) // CPU
|
||||
#define HALTED_FLAG (1 << 12) // APU
|
||||
#define FRAME_ADVANCE_FLAG (1 << 9)
|
||||
|
@ -274,12 +270,16 @@
|
|||
|
||||
struct SCPUState
|
||||
{
|
||||
uint32 Flags;
|
||||
int32 Cycles;
|
||||
int32 PrevCycles;
|
||||
int32 V_Counter;
|
||||
uint32 Flags;
|
||||
uint8 *PCBase;
|
||||
bool8 IRQActive;
|
||||
bool8 NMILine;
|
||||
bool8 IRQLine;
|
||||
bool8 IRQTransition;
|
||||
bool8 IRQLastState;
|
||||
bool8 IRQExternal;
|
||||
int32 IRQPending;
|
||||
int32 MemSpeed;
|
||||
int32 MemSpeedx2;
|
||||
|
@ -293,9 +293,6 @@ struct SCPUState
|
|||
uint8 WhichEvent;
|
||||
int32 NextEvent;
|
||||
bool8 WaitingForInterrupt;
|
||||
uint32 WaitAddress;
|
||||
uint32 WaitCounter;
|
||||
uint32 PBPCAtOpcodeStart;
|
||||
uint32 AutoSaveTimer;
|
||||
bool8 SRAMModified;
|
||||
};
|
||||
|
@ -303,17 +300,11 @@ struct SCPUState
|
|||
enum
|
||||
{
|
||||
HC_HBLANK_START_EVENT = 1,
|
||||
HC_IRQ_1_3_EVENT = 2,
|
||||
HC_HDMA_START_EVENT = 3,
|
||||
HC_IRQ_3_5_EVENT = 4,
|
||||
HC_HCOUNTER_MAX_EVENT = 5,
|
||||
HC_IRQ_5_7_EVENT = 6,
|
||||
HC_HDMA_INIT_EVENT = 7,
|
||||
HC_IRQ_7_9_EVENT = 8,
|
||||
HC_RENDER_EVENT = 9,
|
||||
HC_IRQ_9_A_EVENT = 10,
|
||||
HC_WRAM_REFRESH_EVENT = 11,
|
||||
HC_IRQ_A_1_EVENT = 12
|
||||
HC_HDMA_START_EVENT = 2,
|
||||
HC_HCOUNTER_MAX_EVENT = 3,
|
||||
HC_HDMA_INIT_EVENT = 4,
|
||||
HC_RENDER_EVENT = 5,
|
||||
HC_WRAM_REFRESH_EVENT = 6
|
||||
};
|
||||
|
||||
struct STimings
|
||||
|
@ -327,12 +318,13 @@ struct STimings
|
|||
int32 HDMAInit;
|
||||
int32 HDMAStart;
|
||||
int32 NMITriggerPos;
|
||||
int32 IRQTriggerCycles;
|
||||
int32 WRAMRefreshPos;
|
||||
int32 RenderPos;
|
||||
bool8 InterlaceField;
|
||||
int32 DMACPUSync; // The cycles to synchronize DMA and CPU. Snes9x cannot emulate correctly.
|
||||
int32 NMIDMADelay; // The delay of NMI trigger after DMA transfers. Snes9x cannot emulate correctly.
|
||||
int32 IRQPendCount; // This value is just a hack, because Snes9x cannot emulate any events in an opcode.
|
||||
int32 IRQPendCount; // This value is just a hack.
|
||||
int32 APUSpeedup;
|
||||
bool8 APUAllowTimeOverflow;
|
||||
};
|
||||
|
@ -405,12 +397,8 @@ struct SSettings
|
|||
char CartBName[PATH_MAX + 1];
|
||||
|
||||
bool8 DisableGameSpecificHacks;
|
||||
bool8 ShutdownMaster;
|
||||
bool8 Shutdown;
|
||||
bool8 BlockInvalidVRAMAccessMaster;
|
||||
bool8 BlockInvalidVRAMAccess;
|
||||
bool8 DisableIRQ;
|
||||
bool8 DisableHDMA;
|
||||
int32 HDMATimingHack;
|
||||
|
||||
bool8 ForcedPause;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
@S9XZSNESFX@
|
||||
@S9XZSNESC4@
|
||||
@S9XDEBUGGER@
|
||||
@S9XNETPLAY@
|
||||
@S9XZIP@
|
||||
|
@ -9,26 +7,11 @@
|
|||
OS = `uname -s -r -m|sed \"s/ /-/g\"|tr \"[A-Z]\" \"[a-z]\"|tr \"/()\" \"___\"`
|
||||
BUILDDIR = .
|
||||
|
||||
OBJECTS = ../apu/apu.o ../apu/SNES_SPC.o ../apu/SNES_SPC_misc.o ../apu/SNES_SPC_state.o ../apu/SPC_DSP.o ../apu/SPC_Filter.o ../bsx.o ../cheats.o ../cheats2.o ../clip.o ../conffile.o ../controls.o ../cpu.o ../cpuexec.o ../cpuops.o ../crosshairs.o ../dma.o ../dsp.o ../dsp1.o ../dsp2.o ../dsp3.o ../dsp4.o ../gfx.o ../globals.o ../logger.o ../memmap.o ../movie.o ../obc1.o ../ppu.o ../reader.o ../sa1.o ../sa1cpu.o ../screenshot.o ../sdd1.o ../sdd1emu.o ../seta.o ../seta010.o ../seta011.o ../seta018.o ../snapshot.o ../snes9x.o ../spc7110.o ../srtc.o ../tile.o ../filter/2xsai.o ../filter/blit.o ../filter/epx.o ../filter/hq2x.o ../filter/snes_ntsc.o unix.o x11.o
|
||||
DEFS = -DMITSHM -DCPU_SHUTDOWN -DSPC700_SHUTDOWN -DCORRECT_VRAM_READS
|
||||
|
||||
ifdef S9XZSNESFX
|
||||
OBJECTS += ../i386/fxemu2.o ../i386/fxemu2b.o ../i386/fxemu2c.o ../i386/fxtable.o ../i386/sfxproc.o ../i386/zsnes.o
|
||||
else
|
||||
OBJECTS += ../fxinst.o ../fxemu.o
|
||||
ifdef S9XDEBUGGER
|
||||
OBJECTS += ../fxdbg.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef S9XZSNESC4
|
||||
OBJECTS += ../i386/c4.o ../i386/zsnesc4.o ../c4.o
|
||||
else
|
||||
OBJECTS += ../c4.o ../c4emu.o
|
||||
endif
|
||||
OBJECTS = ../apu/apu.o ../apu/SNES_SPC.o ../apu/SNES_SPC_misc.o ../apu/SNES_SPC_state.o ../apu/SPC_DSP.o ../apu/SPC_Filter.o ../bsx.o ../c4.o ../c4emu.o ../cheats.o ../cheats2.o ../clip.o ../conffile.o ../controls.o ../cpu.o ../cpuexec.o ../cpuops.o ../crosshairs.o ../dma.o ../dsp.o ../dsp1.o ../dsp2.o ../dsp3.o ../dsp4.o ../fxinst.o ../fxemu.o ../gfx.o ../globals.o ../logger.o ../memmap.o ../movie.o ../obc1.o ../ppu.o ../reader.o ../sa1.o ../sa1cpu.o ../screenshot.o ../sdd1.o ../sdd1emu.o ../seta.o ../seta010.o ../seta011.o ../seta018.o ../snapshot.o ../snes9x.o ../spc7110.o ../srtc.o ../tile.o ../filter/2xsai.o ../filter/blit.o ../filter/epx.o ../filter/hq2x.o ../filter/snes_ntsc.o unix.o x11.o
|
||||
DEFS = -DMITSHM
|
||||
|
||||
ifdef S9XDEBUGGER
|
||||
OBJECTS += ../debug.o
|
||||
OBJECTS += ../debug.o ../fxdbg.o
|
||||
endif
|
||||
|
||||
ifdef S9XNETPLAY
|
||||
|
@ -45,14 +28,13 @@ endif
|
|||
|
||||
CCC = @CXX@
|
||||
CC = @CC@
|
||||
NASM = @S9XNASM@
|
||||
GASM = @CXX@
|
||||
INCLUDES = -I. -I.. -I../apu/ -I../unzip/ -I../jma/ -I../filter/
|
||||
|
||||
CCFLAGS = @S9XFLGS@ @S9XDEFS@ $(DEFS)
|
||||
CFLAGS = $(CCFLAGS)
|
||||
|
||||
.SUFFIXES: .o .cpp .c .cc .h .m .i .s .asm .obj
|
||||
.SUFFIXES: .o .cpp .c .cc .h .m .i .s .obj
|
||||
|
||||
all: Makefile configure snes9x
|
||||
|
||||
|
@ -108,9 +90,6 @@ snes9x: $(OBJECTS)
|
|||
@echo Compiling $*.s
|
||||
sh-elf-as -little $*.s -o $@
|
||||
|
||||
.asm.o:
|
||||
$(NASM) -f elf -DELF @S9XDEFS@ -i../i386/ -o $@ $*.asm
|
||||
|
||||
.obj.o:
|
||||
cp $*.obj $*.o
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
AC_PREREQ([2.60])
|
||||
AC_INIT([Snes9x], [1.52], [], [snes9x])
|
||||
AC_REVISION([$Revision: 1.52 $])
|
||||
AC_INIT([Snes9x], [1.53], [], [snes9x])
|
||||
AC_REVISION([$Revision: 1.53 $])
|
||||
|
||||
AC_CONFIG_SRCDIR([unix.cpp])
|
||||
|
||||
|
@ -106,52 +106,6 @@ AC_S9X_COMPILER_FLAG([-Wall], [Wall])
|
|||
AC_S9X_COMPILER_FLAG([-W], [W])
|
||||
AC_S9X_COMPILER_FLAG([-Wno-unused-parameter], [Wno_unused_parameter])
|
||||
|
||||
# Check if the CPU is x86.
|
||||
|
||||
AC_MSG_CHECKING([whether the CPU is x86])
|
||||
|
||||
AC_CACHE_VAL([snes9x_cv_x86_cpu],
|
||||
[
|
||||
case "$target" in
|
||||
i686-*-* | i586-*-* | i486-*-* | i386-*-*)
|
||||
snes9x_cv_x86_cpu="yes"
|
||||
;;
|
||||
*)
|
||||
snes9x_cv_x86_cpu="no"
|
||||
;;
|
||||
esac
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([$snes9x_cv_x86_cpu])
|
||||
|
||||
# Enable ZSNES C4 and SuperFX assembler cores if CPU is x86.
|
||||
|
||||
S9XZSNESFX="#S9XZSNESFX=1"
|
||||
S9XZSNESC4="#S9XZSNESC4=1"
|
||||
S9XNASM=""
|
||||
|
||||
AC_ARG_ENABLE([zsnes_asm],
|
||||
[AS_HELP_STRING([--enable-zsnes-asm],
|
||||
[build with ZSNES C4 and SuperFX assembler cores if available (default: no)])],
|
||||
[], [enable_zsnes_asm="no"])
|
||||
|
||||
if test "x$enable_zsnes_asm" = "xyes"; then
|
||||
if test "x$snes9x_cv_x86_cpu" = "xyes"; then
|
||||
AC_PATH_PROG([S9XNASM], [nasm], [no])
|
||||
if test "x$S9XNASM" != "xno"; then
|
||||
S9XZSNESFX="S9XZSNESFX=1"
|
||||
S9XZSNESC4="S9XZSNESC4=1"
|
||||
S9XDEFS="$S9XDEFS -DZSNES_FX -DZSNES_C4"
|
||||
else
|
||||
AC_MSG_WARN([nasm not found. Build without ZSNES assembler cores.])
|
||||
enable_zsnes_asm="no"
|
||||
fi
|
||||
else
|
||||
AC_MSG_WARN([Your CPU is not x86. Build without ZSNES assembler cores.])
|
||||
enable_zsnes_asm="no"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if the OS is Linux.
|
||||
|
||||
AC_MSG_CHECKING([whether the OS is Linux])
|
||||
|
@ -464,9 +418,6 @@ S9XLIBS="`echo \"$S9XLIBS\" | sed -e 's/^ *//'`"
|
|||
AC_SUBST(S9XFLGS)
|
||||
AC_SUBST(S9XDEFS)
|
||||
AC_SUBST(S9XLIBS)
|
||||
AC_SUBST(S9XZSNESFX)
|
||||
AC_SUBST(S9XZSNESC4)
|
||||
AC_SUBST(S9XNASM)
|
||||
AC_SUBST(S9XDEBUGGER)
|
||||
AC_SUBST(S9XNETPLAY)
|
||||
AC_SUBST(S9XZIP)
|
||||
|
@ -491,7 +442,6 @@ gamepad support...... $enable_gamepad
|
|||
GZIP support......... $enable_gzip
|
||||
ZIP support.......... $enable_zip
|
||||
JMA support.......... $enable_jma
|
||||
using ZSNES asm...... $enable_zsnes_asm
|
||||
debugger............. $enable_debugger
|
||||
|
||||
EOF
|
||||
|
|
|
@ -451,7 +451,6 @@ const char * S9xParseDisplayConfig (ConfigFile &conf, int pass)
|
|||
keymaps.push_back(strpair_t("K00:3", "ToggleBG2"));
|
||||
keymaps.push_back(strpair_t("K00:4", "ToggleBG3"));
|
||||
keymaps.push_back(strpair_t("K00:5", "ToggleSprites"));
|
||||
keymaps.push_back(strpair_t("K00:0", "ToggleHDMA"));
|
||||
keymaps.push_back(strpair_t("K00:9", "ToggleTransparency"));
|
||||
keymaps.push_back(strpair_t("K00:BackSpace", "ClipWindows"));
|
||||
keymaps.push_back(strpair_t("K00:A+Escape", "Debugger"));
|
||||
|
|
Loading…
Reference in New Issue